Browse Source

Fix race condition with -use-separate-modules due to type determination

gingerBill 2 years ago
parent
commit
843eaf8893
3 changed files with 18 additions and 3 deletions
  1. 5 3
      src/llvm_backend.hpp
  2. 6 0
      src/llvm_backend_general.cpp
  3. 7 0
      src/llvm_backend_utility.cpp

+ 5 - 3
src/llvm_backend.hpp

@@ -139,9 +139,11 @@ struct lbModule {
 	AstPackage *pkg; // possibly associated
 	AstFile *file;   // possibly associated
 
-	PtrMap<Type *, LLVMTypeRef> types;
-	PtrMap<Type *, LLVMTypeRef> func_raw_types;
-	PtrMap<void *, lbStructFieldRemapping> struct_field_remapping; // Key: LLVMTypeRef or Type *
+	PtrMap<Type *, LLVMTypeRef> types;                             // mutex: types_mutex
+	PtrMap<void *, lbStructFieldRemapping> struct_field_remapping; // Key: LLVMTypeRef or Type *, mutex: types_mutex
+	PtrMap<Type *, LLVMTypeRef> func_raw_types;                    // mutex: func_raw_types_mutex
+	RecursiveMutex              types_mutex;
+	RecursiveMutex              func_raw_types_mutex;
 	i32 internal_type_level;
 
 	RwMutex values_mutex;

+ 6 - 0
src/llvm_backend_general.cpp

@@ -1498,6 +1498,9 @@ gb_internal LLVMTypeRef lb_type_internal_for_procedures_raw(lbModule *m, Type *t
 	type = base_type(original_type);
 	GB_ASSERT(type->kind == Type_Proc);
 
+	mutex_lock(&m->func_raw_types_mutex);
+	defer (mutex_unlock(&m->func_raw_types_mutex));
+
 	LLVMTypeRef *found = map_get(&m->func_raw_types, type);
 	if (found) {
 		return *found;
@@ -2157,6 +2160,9 @@ gb_internal LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
 gb_internal LLVMTypeRef lb_type(lbModule *m, Type *type) {
 	type = default_type(type);
 
+	mutex_lock(&m->types_mutex);
+	defer (mutex_unlock(&m->types_mutex));
+
 	LLVMTypeRef *found = map_get(&m->types, type);
 	if (found) {
 		return *found;

+ 7 - 0
src/llvm_backend_utility.cpp

@@ -910,11 +910,18 @@ gb_internal lbValue lb_address_from_load_if_readonly_parameter(lbProcedure *p, l
 
 gb_internal lbStructFieldRemapping lb_get_struct_remapping(lbModule *m, Type *t) {
 	t = base_type(t);
+
 	LLVMTypeRef struct_type = lb_type(m, t);
+
+	mutex_lock(&m->types_mutex);
+
 	auto *field_remapping = map_get(&m->struct_field_remapping, cast(void *)struct_type);
 	if (field_remapping == nullptr) {
 		field_remapping = map_get(&m->struct_field_remapping, cast(void *)t);
 	}
+
+	mutex_unlock(&m->types_mutex);
+
 	GB_ASSERT_MSG(field_remapping != nullptr, "%s", type_to_string(t));
 	return *field_remapping;
 }