Browse Source

Merge branch 'master' into bill/utf16-strings

gingerBill 4 days ago
parent
commit
eae43f1225

+ 3 - 3
core/os/os2/file_windows.odin

@@ -249,9 +249,9 @@ _destroy :: proc(f: ^File_Impl) -> Error {
 	a := f.allocator
 	err0 := free(rawptr(f.wname), a)
 	err1 := delete(f.name, a)
-	err2 := free(f, a)
-	err3 := delete(f.r_buf, a)
-	err4 := delete(f.w_buf, a)
+	err2 := delete(f.r_buf, a)
+	err3 := delete(f.w_buf, a)
+	err4 := free(f, a)
 	err0 or_return
 	err1 or_return
 	err2 or_return

+ 4 - 0
core/prof/spall/spall.odin

@@ -103,6 +103,7 @@ context_create_with_sleep :: proc(filename: string, sleep := 2 * time.Second) ->
 
 context_create :: proc{context_create_with_scale, context_create_with_sleep}
 
+@(no_instrumentation)
 context_destroy :: proc(ctx: ^Context) {
 	if ctx == nil {
 		return
@@ -146,6 +147,7 @@ buffer_flush :: proc "contextless" (ctx: ^Context, buffer: ^Buffer) #no_bounds_c
 	buffer.first_ts = end
 }
 
+@(no_instrumentation)
 buffer_destroy :: proc(ctx: ^Context, buffer: ^Buffer) {
 	buffer_flush(ctx, buffer)
 
@@ -155,12 +157,14 @@ buffer_destroy :: proc(ctx: ^Context, buffer: ^Buffer) {
 
 
 @(deferred_in=_scoped_buffer_end)
+@(no_instrumentation)
 SCOPED_EVENT :: proc(ctx: ^Context, buffer: ^Buffer, name: string, args: string = "", location := #caller_location) -> bool {
 	_buffer_begin(ctx, buffer, name, args, location)
 	return true
 }
 
 @(private)
+@(no_instrumentation)
 _scoped_buffer_end :: proc(ctx: ^Context, buffer: ^Buffer, _, _: string, _ := #caller_location) {
 	_buffer_end(ctx, buffer)
 }

+ 6 - 1
core/thread/thread_unix.odin

@@ -81,8 +81,13 @@ _create :: proc(procedure: Thread_Proc, priority: Thread_Priority) -> ^Thread {
 	}
 	defer posix.pthread_attr_destroy(&attrs)
 
-	// NOTE(tetra, 2019-11-01): These only fail if their argument is invalid.
+	stacksize: posix.rlimit
+	if res := posix.getrlimit(.STACK, &stacksize); res == .OK && stacksize.rlim_cur > 0 {
+		_ = posix.pthread_attr_setstacksize(&attrs, uint(stacksize.rlim_cur))
+	}
+
 	res: posix.Errno
+	// NOTE(tetra, 2019-11-01): These only fail if their argument is invalid.
 	res = posix.pthread_attr_setdetachstate(&attrs, .CREATE_JOINABLE)
 	assert(res == nil)
 	when ODIN_OS != .Haiku && ODIN_OS != .NetBSD {

+ 2 - 0
src/check_builtin.cpp

@@ -33,6 +33,7 @@ gb_global BuiltinTypeIsProc *builtin_type_is_procs[BuiltinProc__type_simple_bool
 	is_type_sliceable,
 	is_type_comparable,
 	is_type_simple_compare,
+	is_type_nearly_simple_compare,
 	is_type_dereferenceable,
 	is_type_valid_for_keys,
 	is_type_valid_for_matrix_elems,
@@ -6159,6 +6160,7 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
 	case BuiltinProc_type_is_sliceable:
 	case BuiltinProc_type_is_comparable:
 	case BuiltinProc_type_is_simple_compare:
+	case BuiltinProc_type_is_nearly_simple_compare:
 	case BuiltinProc_type_is_dereferenceable:
 	case BuiltinProc_type_is_valid_map_key:
 	case BuiltinProc_type_is_valid_matrix_elements:

+ 1 - 1
src/check_expr.cpp

@@ -6621,7 +6621,7 @@ gb_internal bool evaluate_where_clauses(CheckerContext *ctx, Ast *call_expr, Sco
 							Entity *e = entry.value;
 							switch (e->kind) {
 							case Entity_TypeName: {
-								if (print_count == 0) error_line("\n\tWith the following definitions:\n");
+								// if (print_count == 0) error_line("\n\tWith the following definitions:\n");
 
 								gbString str = type_to_string(e->type);
 								error_line("\t\t%.*s :: %s;\n", LIT(e->token.string), str);

+ 5 - 1
src/checker.cpp

@@ -6804,7 +6804,11 @@ gb_internal void check_parsed_files(Checker *c) {
 	for_array(i, c->info.definitions) {
 		Entity *e = c->info.definitions[i];
 		if (e->kind == Entity_TypeName && e->type != nullptr && is_type_typed(e->type)) {
-			(void)type_align_of(e->type);
+			if (e->TypeName.is_type_alias) {
+				// Ignore for the time being
+			} else {
+				(void)type_align_of(e->type);
+			}
 		} else if (e->kind == Entity_Procedure) {
 			DeclInfo *decl = e->decl_info;
 			ast_node(pl, ProcLit, decl->proc_lit);

+ 2 - 0
src/checker_builtin_procs.hpp

@@ -265,6 +265,7 @@ BuiltinProc__type_simple_boolean_begin,
 	BuiltinProc_type_is_sliceable,
 	BuiltinProc_type_is_comparable,
 	BuiltinProc_type_is_simple_compare, // easily compared using memcmp
+	BuiltinProc_type_is_nearly_simple_compare, // easily compared using memcmp (including floats)
 	BuiltinProc_type_is_dereferenceable,
 	BuiltinProc_type_is_valid_map_key,
 	BuiltinProc_type_is_valid_matrix_elements,
@@ -623,6 +624,7 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = {
 	{STR_LIT("type_is_sliceable"),         1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
 	{STR_LIT("type_is_comparable"),        1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
 	{STR_LIT("type_is_simple_compare"),    1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
+	{STR_LIT("type_is_nearly_simple_compare"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
 	{STR_LIT("type_is_dereferenceable"),   1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
 	{STR_LIT("type_is_valid_map_key"),     1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
 	{STR_LIT("type_is_valid_matrix_elements"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},

+ 69 - 9
src/types.cpp

@@ -157,10 +157,11 @@ struct TypeStruct {
 
 	bool            is_polymorphic;
 	bool            are_offsets_set             : 1;
-	bool            are_offsets_being_processed : 1;
 	bool            is_packed                   : 1;
 	bool            is_raw_union                : 1;
 	bool            is_poly_specialized         : 1;
+
+	std::atomic<bool> are_offsets_being_processed;
 };
 
 struct TypeUnion {
@@ -259,7 +260,7 @@ struct TypeProc {
 		Slice<Entity *> variables; /* Entity_Variable */  \
 		i64 *           offsets;                          \
 		BlockingMutex   mutex; /* for settings offsets */ \
-		bool            are_offsets_being_processed;      \
+		std::atomic<bool> are_offsets_being_processed;    \
 		bool            are_offsets_set;                  \
 		bool            is_packed;                        \
 	})                                                        \
@@ -2633,6 +2634,62 @@ gb_internal bool is_type_simple_compare(Type *t) {
 	return false;
 }
 
+// NOTE(bill): type can be easily compared using memcmp or contains a float
+gb_internal bool is_type_nearly_simple_compare(Type *t) {
+	t = core_type(t);
+	switch (t->kind) {
+	case Type_Array:
+		return is_type_nearly_simple_compare(t->Array.elem);
+
+	case Type_EnumeratedArray:
+		return is_type_nearly_simple_compare(t->EnumeratedArray.elem);
+
+	case Type_Basic:
+		if (t->Basic.flags & (BasicFlag_SimpleCompare|BasicFlag_Numeric)) {
+			return true;
+		}
+		if (t->Basic.kind == Basic_typeid) {
+			return true;
+		}
+		return false;
+
+	case Type_Pointer:
+	case Type_MultiPointer:
+	case Type_SoaPointer:
+	case Type_Proc:
+	case Type_BitSet:
+		return true;
+
+	case Type_Matrix:
+		return is_type_nearly_simple_compare(t->Matrix.elem);
+
+	case Type_Struct:
+		for_array(i, t->Struct.fields) {
+			Entity *f = t->Struct.fields[i];
+			if (!is_type_nearly_simple_compare(f->type)) {
+				return false;
+			}
+		}
+		return true;
+
+	case Type_Union:
+		for_array(i, t->Union.variants) {
+			Type *v = t->Union.variants[i];
+			if (!is_type_nearly_simple_compare(v)) {
+				return false;
+			}
+		}
+		// make it dumb on purpose
+		return t->Union.variants.count == 1;
+
+	case Type_SimdVector:
+		return is_type_nearly_simple_compare(t->SimdVector.elem);
+
+	}
+
+	return false;
+}
+
 gb_internal bool is_type_load_safe(Type *type) {
 	GB_ASSERT(type != nullptr);
 	type = core_type(core_array_type(type));
@@ -4121,18 +4178,18 @@ gb_internal bool type_set_offsets(Type *t) {
 	if (t->kind == Type_Struct) {
 		MUTEX_GUARD(&t->Struct.offset_mutex);
 		if (!t->Struct.are_offsets_set) {
-			t->Struct.are_offsets_being_processed = true;
+			t->Struct.are_offsets_being_processed.store(true);
 			t->Struct.offsets = type_set_offsets_of(t->Struct.fields, t->Struct.is_packed, t->Struct.is_raw_union, t->Struct.custom_min_field_align, t->Struct.custom_max_field_align);
-			t->Struct.are_offsets_being_processed = false;
+			t->Struct.are_offsets_being_processed.store(false);
 			t->Struct.are_offsets_set = true;
 			return true;
 		}
 	} else if (is_type_tuple(t)) {
 		MUTEX_GUARD(&t->Tuple.mutex);
 		if (!t->Tuple.are_offsets_set) {
-			t->Tuple.are_offsets_being_processed = true;
+			t->Tuple.are_offsets_being_processed.store(true);
 			t->Tuple.offsets = type_set_offsets_of(t->Tuple.variables, t->Tuple.is_packed, false, 1, 0);
-			t->Tuple.are_offsets_being_processed = false;
+			t->Tuple.are_offsets_being_processed.store(false);
 			t->Tuple.are_offsets_set = true;
 			return true;
 		}
@@ -4317,9 +4374,12 @@ gb_internal i64 type_size_of_internal(Type *t, TypePath *path) {
 			if (path->failure) {
 				return FAILURE_SIZE;
 			}
-			if (t->Struct.are_offsets_being_processed && t->Struct.offsets == nullptr) {
-				type_path_print_illegal_cycle(path, path->path.count-1);
-				return FAILURE_SIZE;
+			{
+				MUTEX_GUARD(&t->Struct.offset_mutex);
+				if (t->Struct.are_offsets_being_processed.load() && t->Struct.offsets == nullptr) {
+					type_path_print_illegal_cycle(path, path->path.count-1);
+					return FAILURE_SIZE;
+				}
 			}
 			type_set_offsets(t);
 			GB_ASSERT(t->Struct.fields.count == 0 || t->Struct.offsets != nullptr);