Fix possible race and correct linkage _after_ generation

This commit is contained in:
gingerBill
2024-07-15 11:49:07 +01:00
parent 664a71454b
commit c5decd3eae
4 changed files with 39 additions and 17 deletions

View File

@@ -1,13 +1,11 @@
#define MULTITHREAD_OBJECT_GENERATION 1
#ifndef USE_SEPARATE_MODULES
#define USE_SEPARATE_MODULES build_context.use_separate_modules
#endif
#ifndef MULTITHREAD_OBJECT_GENERATION
#define MULTITHREAD_OBJECT_GENERATION 0
#endif
#ifndef USE_SEPARATE_MODULES
#define USE_SEPARATE_MODULES build_context.use_separate_modules
#endif
#ifndef LLVM_IGNORE_VERIFICATION
#define LLVM_IGNORE_VERIFICATION 0
@@ -137,17 +135,18 @@ gb_internal void lb_set_entity_from_other_modules_linkage_correctly(lbModule *ot
if (other_module == nullptr) {
return;
}
char const *cname = alloc_cstring(temporary_allocator(), name);
char const *cname = alloc_cstring(permanent_allocator(), name);
mpsc_enqueue(&other_module->gen->entities_to_correct_linkage, lbEntityCorrection{other_module, e, cname});
LLVMValueRef other_global = nullptr;
if (e->kind == Entity_Variable) {
other_global = LLVMGetNamedGlobal(other_module->mod, cname);
} else if (e->kind == Entity_Procedure) {
other_global = LLVMGetNamedFunction(other_module->mod, cname);
}
if (other_global) {
LLVMSetLinkage(other_global, LLVMExternalLinkage);
}
// LLVMValueRef other_global = nullptr;
// if (e->kind == Entity_Variable) {
// other_global = LLVMGetNamedGlobal(other_module->mod, cname);
// } else if (e->kind == Entity_Procedure) {
// other_global = LLVMGetNamedFunction(other_module->mod, cname);
// }
// if (other_global) {
// LLVMSetLinkage(other_global, LLVMExternalLinkage);
// }
}
gb_internal void lb_emit_init_context(lbProcedure *p, lbAddr addr) {
@@ -3431,6 +3430,19 @@ gb_internal bool lb_generate_code(lbGenerator *gen) {
TIME_SECTION("LLVM Add Foreign Library Paths");
lb_add_foreign_library_paths(gen);
TIME_SECTION("LLVM Correct Entity Linkage");
for (lbEntityCorrection ec = {}; mpsc_dequeue(&gen->entities_to_correct_linkage, &ec); /**/) {
LLVMValueRef other_global = nullptr;
if (ec.e->kind == Entity_Variable) {
other_global = LLVMGetNamedGlobal(ec.other_module->mod, ec.cname);
} else if (ec.e->kind == Entity_Procedure) {
other_global = LLVMGetNamedFunction(ec.other_module->mod, ec.cname);
}
if (other_global) {
LLVMSetLinkage(other_global, LLVMExternalLinkage);
}
}
////////////////////////////////////////////
for (auto const &entry: gen->modules) {

View File

@@ -200,6 +200,12 @@ struct lbModule {
LLVMPassManagerRef function_pass_managers[lbFunctionPassManager_COUNT];
};
struct lbEntityCorrection {
lbModule * other_module;
Entity * e;
char const *cname;
};
struct lbGenerator : LinkerData {
CheckerInfo *info;
@@ -218,6 +224,8 @@ struct lbGenerator : LinkerData {
lbProcedure *startup_runtime;
lbProcedure *cleanup_runtime;
lbProcedure *objc_names;
MPSCQueue<lbEntityCorrection> entities_to_correct_linkage;
};

View File

@@ -71,7 +71,7 @@ gb_internal void lb_init_module(lbModule *m, Checker *c) {
map_init(&m->hasher_procs);
map_init(&m->map_get_procs);
map_init(&m->map_set_procs);
if (build_context.use_separate_modules) {
if (USE_SEPARATE_MODULES) {
array_init(&m->procedures_to_generate, a, 0, 1<<10);
map_init(&m->procedure_values, 1<<11);
} else {
@@ -151,6 +151,8 @@ gb_internal bool lb_init_generator(lbGenerator *gen, Checker *c) {
map_set(&gen->modules_through_ctx, ctx, m);
}
mpsc_init(&gen->entities_to_correct_linkage, heap_allocator());
return true;
}

View File

@@ -16,7 +16,7 @@ struct MPSCQueue {
std::atomic<isize> count;
};
template <typename T> gb_internal void mpsc_init (MPSCQueue<T> *q);
template <typename T> gb_internal void mpsc_init (MPSCQueue<T> *q, gbAllocator const &allocator);
template <typename T> gb_internal void mpsc_destroy(MPSCQueue<T> *q);
template <typename T> gb_internal isize mpsc_enqueue(MPSCQueue<T> *q, T const &value);
template <typename T> gb_internal bool mpsc_dequeue(MPSCQueue<T> *q, T *value_);