From 003a549f8a58cbe5c784bcaed92eededa0e99bd0 Mon Sep 17 00:00:00 2001 From: Paul Guyot Date: Sun, 20 Aug 2023 18:24:10 +0200 Subject: [PATCH] Reduce lock contention on GlobalContext.module_locks Cache last module in scheduler loop to reduce lookups of modules by index Also fix a bug in stacktraces where the lock was not held Also remove pointer to GlobalContext from modules This optimization, in addition to PRs #766, #770, #771 and #772, bring an additional gain of 2-3% on Sudoku benchmark Signed-off-by: Paul Guyot --- src/libAtomVM/globalcontext.c | 2 +- src/libAtomVM/module.c | 49 +++++++++-------- src/libAtomVM/module.h | 19 +++---- src/libAtomVM/nifs.c | 4 +- src/libAtomVM/opcodesswitch.h | 84 +++++++++++++++-------------- src/libAtomVM/stacktrace.c | 10 ++-- src/platforms/emscripten/src/main.c | 2 +- 7 files changed, 89 insertions(+), 81 deletions(-) diff --git a/src/libAtomVM/globalcontext.c b/src/libAtomVM/globalcontext.c index bed0522c3..dc5b2a89a 100644 --- a/src/libAtomVM/globalcontext.c +++ b/src/libAtomVM/globalcontext.c @@ -460,7 +460,7 @@ term globalcontext_existing_term_from_atom_string(GlobalContext *glb, AtomString int globalcontext_insert_module(GlobalContext *global, Module *module) { SMP_RWLOCK_WRLOCK(global->modules_lock); - AtomString module_name_atom = module_get_atom_string_by_id(module, 1); + AtomString module_name_atom = module_get_atom_string_by_id(module, 1, global); if (!atomshashtable_insert(global->modules_table, module_name_atom, TO_ATOMSHASHTABLE_VALUE(module))) { SMP_RWLOCK_UNLOCK(global->modules_lock); return -1; diff --git a/src/libAtomVM/module.c b/src/libAtomVM/module.c index 00be19372..579a9167b 100644 --- a/src/libAtomVM/module.c +++ b/src/libAtomVM/module.c @@ -61,7 +61,7 @@ #endif static struct LiteralEntry *module_build_literals_table(const void *literalsBuf); static void module_add_label(Module *mod, int index, void *ptr); -static enum ModuleLoadResult module_build_imported_functions_table(Module *this_module, uint8_t *table_data); +static enum ModuleLoadResult module_build_imported_functions_table(Module *this_module, uint8_t *table_data, GlobalContext *glb); static void parse_line_table(uint16_t **line_refs, struct ModuleFilename **filenames, uint8_t *data, size_t len); #define IMPL_CODE_LOADER 1 @@ -69,7 +69,7 @@ static void parse_line_table(uint16_t **line_refs, struct ModuleFilename **filen #undef TRACE #undef IMPL_CODE_LOADER -static enum ModuleLoadResult module_populate_atoms_table(Module *this_module, uint8_t *table_data) +static enum ModuleLoadResult module_populate_atoms_table(Module *this_module, uint8_t *table_data, GlobalContext *glb) { int atoms_count = READ_32_ALIGNED(table_data + 8); const char *current_atom = (const char *) table_data + 12; @@ -86,7 +86,7 @@ static enum ModuleLoadResult module_populate_atoms_table(Module *this_module, ui int atom_len = *current_atom; atom = current_atom; - int global_atom_id = globalcontext_insert_atom(this_module->global, (AtomString) atom); + int global_atom_id = globalcontext_insert_atom(glb, (AtomString) atom); if (UNLIKELY(global_atom_id < 0)) { fprintf(stderr, "Cannot allocate memory while loading module (line: %i).\n", __LINE__); return MODULE_ERROR_FAILED_ALLOCATION; @@ -100,7 +100,7 @@ static enum ModuleLoadResult module_populate_atoms_table(Module *this_module, ui return MODULE_LOAD_OK; } -static enum ModuleLoadResult module_build_imported_functions_table(Module *this_module, uint8_t *table_data) +static enum ModuleLoadResult module_build_imported_functions_table(Module *this_module, uint8_t *table_data, GlobalContext *glb) { int functions_count = READ_32_ALIGNED(table_data + 8); @@ -113,8 +113,8 @@ static enum ModuleLoadResult module_build_imported_functions_table(Module *this_ for (int i = 0; i < functions_count; i++) { int local_module_atom_index = READ_32_ALIGNED(table_data + i * 12 + 12); int local_function_atom_index = READ_32_ALIGNED(table_data + i * 12 + 4 + 12); - AtomString module_atom = module_get_atom_string_by_id(this_module, local_module_atom_index); - AtomString function_atom = module_get_atom_string_by_id(this_module, local_function_atom_index); + AtomString module_atom = module_get_atom_string_by_id(this_module, local_module_atom_index, glb); + AtomString function_atom = module_get_atom_string_by_id(this_module, local_function_atom_index, glb); uint32_t arity = READ_32_ALIGNED(table_data + i * 12 + 8 + 12); const struct ExportedFunction *bif = bif_registry_get_handler(module_atom, function_atom, arity); @@ -144,7 +144,7 @@ static enum ModuleLoadResult module_build_imported_functions_table(Module *this_ } #ifdef ENABLE_ADVANCED_TRACE -void module_get_imported_function_module_and_name(const Module *this_module, int index, AtomString *module_atom, AtomString *function_atom) +void module_get_imported_function_module_and_name(const Module *this_module, int index, AtomString *module_atom, AtomString *function_atom, GlobalContext *glb) { const uint8_t *table_data = (const uint8_t *) this_module->import_table; int functions_count = READ_32_ALIGNED(table_data + 8); @@ -154,12 +154,12 @@ void module_get_imported_function_module_and_name(const Module *this_module, int } int local_module_atom_index = READ_32_ALIGNED(table_data + index * 12 + 12); int local_function_atom_index = READ_32_ALIGNED(table_data + index * 12 + 4 + 12); - *module_atom = module_get_atom_string_by_id(this_module, local_module_atom_index); - *function_atom = module_get_atom_string_by_id(this_module, local_function_atom_index); + *module_atom = module_get_atom_string_by_id(this_module, local_module_atom_index, glb); + *function_atom = module_get_atom_string_by_id(this_module, local_function_atom_index, glb); } #endif -bool module_get_function_from_label(Module *this_module, int label, AtomString *function_name, int *arity) +bool module_get_function_from_label(Module *this_module, int label, AtomString *function_name, int *arity, GlobalContext *glb) { int best_label = -1; const uint8_t *export_table_data = (const uint8_t *) this_module->export_table; @@ -171,7 +171,7 @@ bool module_get_function_from_label(Module *this_module, int label, AtomString * if (fun_label <= label && best_label < fun_label) { best_label = fun_label; *arity = fun_arity; - *function_name = module_get_atom_string_by_id(this_module, fun_atom_index); + *function_name = module_get_atom_string_by_id(this_module, fun_atom_index, glb); } } @@ -184,7 +184,7 @@ bool module_get_function_from_label(Module *this_module, int label, AtomString * if (fun_label <= label && best_label < fun_label) { best_label = fun_label; *arity = fun_arity; - *function_name = module_get_atom_string_by_id(this_module, fun_atom_index); + *function_name = module_get_atom_string_by_id(this_module, fun_atom_index, glb); } } if (UNLIKELY(best_label == -1)) { @@ -201,13 +201,13 @@ size_t module_get_exported_functions_count(Module *this_module) return functions_count; } -uint32_t module_search_exported_function(Module *this_module, AtomString func_name, int func_arity) +uint32_t module_search_exported_function(Module *this_module, AtomString func_name, int func_arity, GlobalContext *glb) { size_t functions_count = module_get_exported_functions_count(this_module); const uint8_t *table_data = (const uint8_t *) this_module->export_table; for (unsigned int i = 0; i < functions_count; i++) { - AtomString function_atom = module_get_atom_string_by_id(this_module, READ_32_ALIGNED(table_data + i * 12 + 12)); + AtomString function_atom = module_get_atom_string_by_id(this_module, READ_32_ALIGNED(table_data + i * 12 + 12), glb); int32_t arity = READ_32_ALIGNED(table_data + i * 12 + 4 + 12); if ((func_arity == arity) && atom_are_equals(func_name, function_atom)) { uint32_t label = READ_32_ALIGNED(table_data + i * 12 + 8 + 12); @@ -218,17 +218,17 @@ uint32_t module_search_exported_function(Module *this_module, AtomString func_na return 0; } -term module_get_exported_functions(Module *this_module, Heap *heap, GlobalContext *global) +term module_get_exported_functions(Module *this_module, Heap *heap, GlobalContext *glb) { size_t functions_count = module_get_exported_functions_count(this_module); term result_list = term_nil(); const uint8_t *table_data = (const uint8_t *) this_module->export_table; for (unsigned int i = 0; i < functions_count; i++) { - AtomString function_atom = module_get_atom_string_by_id(this_module, READ_32_ALIGNED(table_data + i * 12 + 12)); + AtomString function_atom = module_get_atom_string_by_id(this_module, READ_32_ALIGNED(table_data + i * 12 + 12), glb); int32_t arity = READ_32_ALIGNED(table_data + i * 12 + 4 + 12); term function_tuple = term_alloc_tuple(2, heap); - term_put_tuple_element(function_tuple, 0, globalcontext_existing_term_from_atom_string(global, function_atom)); + term_put_tuple_element(function_tuple, 0, globalcontext_existing_term_from_atom_string(glb, function_atom)); term_put_tuple_element(function_tuple, 1, term_from_int(arity)); result_list = term_list_prepend(function_tuple, result_list, heap); } @@ -256,19 +256,18 @@ Module *module_new_from_iff_binary(GlobalContext *global, const void *iff_binary memset(mod, 0, sizeof(Module)); mod->module_index = -1; - mod->global = global; #ifndef AVM_NO_SMP mod->mutex = smp_mutex_create(); #endif - if (UNLIKELY(module_populate_atoms_table(mod, beam_file + offsets[AT8U]) != MODULE_LOAD_OK)) { + if (UNLIKELY(module_populate_atoms_table(mod, beam_file + offsets[AT8U], global) != MODULE_LOAD_OK)) { fprintf(stderr, "Error: Failed to populate atoms table: %s:%i.\n", __FILE__, __LINE__); module_destroy(mod); return NULL; } - if (UNLIKELY(module_build_imported_functions_table(mod, beam_file + offsets[IMPT]) != MODULE_LOAD_OK)) { + if (UNLIKELY(module_build_imported_functions_table(mod, beam_file + offsets[IMPT], global) != MODULE_LOAD_OK)) { fprintf(stderr, "Error: Failed to build imported functions table: %s:%i.\n", __FILE__, __LINE__); module_destroy(mod); return NULL; @@ -410,17 +409,17 @@ term module_load_literal(Module *mod, int index, Context *ctx) return t; } -const struct ExportedFunction *module_resolve_function0(Module *mod, int import_table_index, struct UnresolvedFunctionCall *unresolved) +const struct ExportedFunction *module_resolve_function0(Module *mod, int import_table_index, struct UnresolvedFunctionCall *unresolved, GlobalContext *glb) { - AtomString module_name_atom = (AtomString) valueshashtable_get_value(mod->global->atoms_ids_table, unresolved->module_atom_index, (unsigned long) NULL); - AtomString function_name_atom = (AtomString) valueshashtable_get_value(mod->global->atoms_ids_table, unresolved->function_atom_index, (unsigned long) NULL); + AtomString module_name_atom = (AtomString) valueshashtable_get_value(glb->atoms_ids_table, unresolved->module_atom_index, (unsigned long) NULL); + AtomString function_name_atom = (AtomString) valueshashtable_get_value(glb->atoms_ids_table, unresolved->function_atom_index, (unsigned long) NULL); int arity = unresolved->arity; - Module *found_module = globalcontext_get_module(mod->global, module_name_atom); + Module *found_module = globalcontext_get_module(glb, module_name_atom); if (LIKELY(found_module != NULL)) { - int exported_label = module_search_exported_function(found_module, function_name_atom, arity); + int exported_label = module_search_exported_function(found_module, function_name_atom, arity, glb); if (exported_label == 0) { char buf[256]; atom_write_mfa(buf, 256, module_name_atom, function_name_atom, arity); diff --git a/src/libAtomVM/module.h b/src/libAtomVM/module.h index da966274d..16266306a 100644 --- a/src/libAtomVM/module.h +++ b/src/libAtomVM/module.h @@ -96,8 +96,6 @@ struct LineRefOffset struct Module { - GlobalContext *global; - #ifdef ENABLE_ADVANCED_TRACE void *import_table; #endif @@ -179,8 +177,9 @@ size_t module_get_exported_functions_count(Module *this_module); * @param this_module the module on which the function will be searched. * @param func_name function name atom string. * @param func_arity function arity. + * @param glb the global context */ -uint32_t module_search_exported_function(Module *this_module, AtomString func_name, int func_arity); +uint32_t module_search_exported_function(Module *this_module, AtomString func_name, int func_arity, GlobalContext *glb); /** * @brief Determine heap size of exported functions list. @@ -242,10 +241,10 @@ term module_load_literal(Module *mod, int index, Context *ctx); * @param local_atom_id module atom table index. * @return the AtomString for the given module atom index. */ -static inline AtomString module_get_atom_string_by_id(const Module *mod, int local_atom_id) +static inline AtomString module_get_atom_string_by_id(const Module *mod, int local_atom_id, GlobalContext *glb) { int global_id = mod->local_atoms_to_global_table[local_atom_id]; - return (AtomString) valueshashtable_get_value(mod->global->atoms_ids_table, global_id, (unsigned long) NULL); + return (AtomString) valueshashtable_get_value(glb->atoms_ids_table, global_id, (unsigned long) NULL); } /** @@ -262,7 +261,7 @@ static inline term module_get_atom_term_by_id(const Module *mod, int local_atom_ return term_from_atom_index(global_id); } -const struct ExportedFunction *module_resolve_function0(Module *mod, int import_table_index, struct UnresolvedFunctionCall *unresolved); +const struct ExportedFunction *module_resolve_function0(Module *mod, int import_table_index, struct UnresolvedFunctionCall *unresolved, GlobalContext *glb); /** * @brief Get the module name, as an atom term. @@ -284,8 +283,9 @@ static inline term module_get_name(const Module *mod) * also it loads the referenced module if it hasn't been loaded yet. * @param mod the module containing the function to resolve. * @param import_table_index the unresolved function index. + * @param glb the global context */ -static inline const struct ExportedFunction *module_resolve_function(Module *mod, int import_table_index) +static inline const struct ExportedFunction *module_resolve_function(Module *mod, int import_table_index, GlobalContext *glb) { SMP_MODULE_LOCK(mod); // We cannot optimistically read the unresolved function call. @@ -297,7 +297,7 @@ static inline const struct ExportedFunction *module_resolve_function(Module *mod return func; } struct UnresolvedFunctionCall *unresolved = EXPORTED_FUNCTION_TO_UNRESOLVED_FUNCTION_CALL(func); - const struct ExportedFunction *result = module_resolve_function0(mod, import_table_index, unresolved); + const struct ExportedFunction *result = module_resolve_function0(mod, import_table_index, unresolved, glb); SMP_MODULE_UNLOCK(mod); return result; } @@ -370,8 +370,9 @@ static inline const uint8_t *module_get_str(Module *mod, size_t offset, size_t * * @param label the current label used to look up the function/arity * @param function_name (output) the function name, as an AtomString. * @param arity (output) the function arity + * @param glb the global context */ -bool module_get_function_from_label(Module *this_module, int label, AtomString *function_name, int *arity); +bool module_get_function_from_label(Module *this_module, int label, AtomString *function_name, int *arity, GlobalContext *glb); /* * @brief Insert the instruction offset for a given module at a line reference instruction. diff --git a/src/libAtomVM/nifs.c b/src/libAtomVM/nifs.c index 89812d9f0..a234fcf8c 100644 --- a/src/libAtomVM/nifs.c +++ b/src/libAtomVM/nifs.c @@ -1182,7 +1182,7 @@ static term nif_erlang_spawn(Context *ctx, int argc, term argv[]) if (UNLIKELY(!proper)) { RAISE_ERROR(BADARG_ATOM); } - int label = module_search_exported_function(found_module, function_string, args_len); + int label = module_search_exported_function(found_module, function_string, args_len, ctx->global); //TODO: fail here if no function has been found if (UNLIKELY(label == 0)) { AVM_ABORT(); @@ -3091,7 +3091,7 @@ static term nif_erlang_function_exported(Context *ctx, int argc, term argv[]) return FALSE_ATOM; } - int target_label = module_search_exported_function(target_module, function_name, arity); + int target_label = module_search_exported_function(target_module, function_name, arity, ctx->global); if (target_label == 0) { return FALSE_ATOM; } diff --git a/src/libAtomVM/opcodesswitch.h b/src/libAtomVM/opcodesswitch.h index 859ac9884..71714a6af 100644 --- a/src/libAtomVM/opcodesswitch.h +++ b/src/libAtomVM/opcodesswitch.h @@ -685,11 +685,19 @@ typedef union #define NEXT_INSTRUCTION(operands_size) \ i += operands_size +#define JUMP_TO_LABEL(module, label) \ + if (module != mod) { \ + prev_mod = mod; \ + mod = module; \ + code = mod->code->code; \ + } \ + JUMP_TO_ADDRESS(mod->labels[label]) + #ifndef TRACE_JUMP #define JUMP_TO_ADDRESS(address) \ i = ((uint8_t *) (address)) - code #else - #define JUMP_TO_ADDRESS(address) \ + #define JUMP_TO_ADDRESS(address) \ i = ((uint8_t *) (address)) - code; \ fprintf(stderr, "going to jump to %i\n", i) #endif @@ -804,10 +812,21 @@ typedef union #define INSTRUCTION_POINTER() \ ((const void *) &code[i]) -#define DO_RETURN() \ - mod = globalcontext_get_module_by_index(mod->global, ctx->cp >> 24); \ - code = mod->code->code; \ - i = (ctx->cp & 0xFFFFFF) >> 2; +#define DO_RETURN() \ + { \ + int module_index = ctx->cp >> 24; \ + if (module_index == prev_mod->module_index) { \ + Module *t = mod; \ + mod = prev_mod; \ + prev_mod = t; \ + code = mod->code->code; \ + } else if (module_index != mod->module_index) { \ + prev_mod = mod; \ + mod = globalcontext_get_module_by_index(glb, module_index); \ + code = mod->code->code; \ + } \ + i = (ctx->cp & 0xFFFFFF) >> 2; \ + } #define POINTER_TO_II(instruction_pointer) \ (((uint8_t *) (instruction_pointer)) - code) @@ -856,8 +875,8 @@ typedef union if (term_is_atom(index_or_function)) { \ term module = boxed_value[1]; \ fun_arity = term_to_int(boxed_value[3]); \ - AtomString module_name = globalcontext_atomstring_from_term(mod->global, module); \ - AtomString function_name = globalcontext_atomstring_from_term(mod->global, index_or_function); \ + AtomString module_name = globalcontext_atomstring_from_term(glb, module); \ + AtomString function_name = globalcontext_atomstring_from_term(glb, index_or_function); \ struct Nif *nif = (struct Nif *) nifs_get(module_name, function_name, fun_arity); \ if (!IS_NULL_PTR(nif)) { \ term return_value = nif->nif_ptr(ctx, fun_arity, ctx->x); \ @@ -875,7 +894,7 @@ typedef union if (IS_NULL_PTR(fun_module)) { \ HANDLE_ERROR(); \ } \ - label = module_search_exported_function(fun_module, function_name, fun_arity); \ + label = module_search_exported_function(fun_module, function_name, fun_arity, glb); \ if (UNLIKELY(label == 0)) { \ HANDLE_ERROR(); \ } \ @@ -896,9 +915,7 @@ typedef union } \ NEXT_INSTRUCTION(next_off); \ ctx->cp = module_address(mod->module_index, i); \ - mod = fun_module; \ - code = mod->code->code; \ - JUMP_TO_ADDRESS(mod->labels[label]); + JUMP_TO_LABEL(fun_module, label); #define DECODE_FLAGS_LIST(flags_value, flags, opcode) \ flags_value = 0; \ @@ -1441,7 +1458,7 @@ static bool maybe_call_native(Context *ctx, AtomString module_name, AtomString f tmp_atom_name[0] = function_len; memcpy(tmp_atom_name + 1, function_name, function_len); - int label = module_search_exported_function(mod, tmp_atom_name, arity); + int label = module_search_exported_function(mod, tmp_atom_name, arity, ctx->global); free(tmp_atom_name); if (UNLIKELY(!label)) { @@ -1481,6 +1498,7 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb) #ifdef IMPL_EXECUTE_LOOP uint8_t *code; Module *mod; + Module *prev_mod; term *x_regs; uintptr_t i; int remaining_reductions; @@ -1492,6 +1510,7 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb) TRACE("scheduling in, ctx = %p\n", ctx); if (ctx == NULL) return 0; mod = ctx->saved_module; + prev_mod = mod; code = mod->code->code; x_regs = ctx->x; JUMP_TO_ADDRESS(ctx->saved_ip); @@ -1695,7 +1714,7 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb) TRACE_CALL_EXT(ctx, mod, "call_ext", index, arity); - const struct ExportedFunction *func = module_resolve_function(mod, index); + const struct ExportedFunction *func = module_resolve_function(mod, index, glb); if (IS_NULL_PTR(func)) { RAISE_ERROR(UNDEF_ATOM); } @@ -1717,9 +1736,7 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb) const struct ModuleFunction *jump = EXPORTED_FUNCTION_TO_MODULE_FUNCTION(func); ctx->cp = module_address(mod->module_index, i); - mod = jump->target; - code = mod->code->code; - JUMP_TO_ADDRESS(mod->labels[jump->label]); + JUMP_TO_LABEL(jump->target, jump->label); break; } @@ -1775,7 +1792,7 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb) TRACE_CALL_EXT(ctx, mod, "call_ext_last", index, arity); - const struct ExportedFunction *func = module_resolve_function(mod, index); + const struct ExportedFunction *func = module_resolve_function(mod, index, glb); if (IS_NULL_PTR(func)) { RAISE_ERROR(UNDEF_ATOM); } @@ -1812,10 +1829,7 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb) ctx->e += (n_words + 1); const struct ModuleFunction *jump = EXPORTED_FUNCTION_TO_MODULE_FUNCTION(func); - - mod = jump->target; - code = mod->code->code; - JUMP_TO_ADDRESS(mod->labels[jump->label]); + JUMP_TO_LABEL(jump->target, jump->label); break; } @@ -3480,7 +3494,7 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb) TRACE_CALL_EXT(ctx, mod, "call_ext_only", index, arity); - const struct ExportedFunction *func = module_resolve_function(mod, index); + const struct ExportedFunction *func = module_resolve_function(mod, index, glb); if (IS_NULL_PTR(func)) { RAISE_ERROR(UNDEF_ATOM); } @@ -3507,11 +3521,7 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb) } case ModuleFunction: { const struct ModuleFunction *jump = EXPORTED_FUNCTION_TO_MODULE_FUNCTION(func); - - mod = jump->target; - code = mod->code->code; - - JUMP_TO_ADDRESS(mod->labels[jump->label]); + JUMP_TO_LABEL(jump->target, jump->label); break; } @@ -5197,8 +5207,8 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb) RAISE_ERROR(BADARG_ATOM); } - AtomString module_name = globalcontext_atomstring_from_term(mod->global, module); - AtomString function_name = globalcontext_atomstring_from_term(mod->global, function); + AtomString module_name = globalcontext_atomstring_from_term(glb, module); + AtomString function_name = globalcontext_atomstring_from_term(glb, function); TRACE_APPLY(ctx, "apply", module_name, function_name, arity); @@ -5213,15 +5223,13 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb) i = orig_i; HANDLE_ERROR(); } - int target_label = module_search_exported_function(target_module, function_name, arity); + int target_label = module_search_exported_function(target_module, function_name, arity, glb); if (target_label == 0) { i = orig_i; HANDLE_ERROR(); } ctx->cp = module_address(mod->module_index, i); - mod = target_module; - code = mod->code->code; - JUMP_TO_ADDRESS(mod->labels[target_label]); + JUMP_TO_LABEL(target_module, target_label); } #endif #ifdef IMPL_CODE_LOADER @@ -5254,8 +5262,8 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb) RAISE_ERROR(BADARG_ATOM); } - AtomString module_name = globalcontext_atomstring_from_term(mod->global, module); - AtomString function_name = globalcontext_atomstring_from_term(mod->global, function); + AtomString module_name = globalcontext_atomstring_from_term(glb, module); + AtomString function_name = globalcontext_atomstring_from_term(glb, function); TRACE_APPLY(ctx, "apply_last", module_name, function_name, arity); @@ -5270,13 +5278,11 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb) if (IS_NULL_PTR(target_module)) { HANDLE_ERROR(); } - int target_label = module_search_exported_function(target_module, function_name, arity); + int target_label = module_search_exported_function(target_module, function_name, arity, glb); if (target_label == 0) { HANDLE_ERROR(); } - mod = target_module; - code = mod->code->code; - JUMP_TO_ADDRESS(mod->labels[target_label]); + JUMP_TO_LABEL(target_module, target_label); } #endif #ifdef IMPL_CODE_LOADER diff --git a/src/libAtomVM/stacktrace.c b/src/libAtomVM/stacktrace.c index 883996dc8..228362a25 100644 --- a/src/libAtomVM/stacktrace.c +++ b/src/libAtomVM/stacktrace.c @@ -20,6 +20,7 @@ #include "stacktrace.h" #include "defaultatoms.h" +#include "globalcontext.h" #ifndef AVM_CREATE_STACKTRACES @@ -47,7 +48,8 @@ term stacktrace_exception_class(term stack_info) static void cp_to_mod_lbl_off(term cp, Context *ctx, Module **cp_mod, int *label, int *l_off, long *mod_offset) { - Module *mod = ctx->global->modules_by_index[cp >> 24]; + int module_index = cp >> 24; + Module *mod = globalcontext_get_module_by_index(ctx->global, module_index); *mod_offset = (cp & 0xFFFFFF) >> 2; *cp_mod = mod; @@ -127,7 +129,7 @@ term stacktrace_create_raw(Context *ctx, Module *mod, int current_offset, term e int module_index; int label = term_to_catch_label_and_module(*ct, &module_index); - Module *cl_mod = ctx->global->modules_by_index[module_index]; + Module *cl_mod = globalcontext_get_module_by_index(ctx->global, module_index); uint8_t *code = &cl_mod->code->code[0]; int mod_offset = ((uint8_t *) cl_mod->labels[label] - code); @@ -201,7 +203,7 @@ term stacktrace_create_raw(Context *ctx, Module *mod, int current_offset, term e int module_index; int label = term_to_catch_label_and_module(*ct, &module_index); - Module *cl_mod = ctx->global->modules_by_index[module_index]; + Module *cl_mod = globalcontext_get_module_by_index(ctx->global, module_index); uint8_t *code = &cl_mod->code->code[0]; int mod_offset = ((uint8_t *) cl_mod->labels[label] - code); @@ -331,7 +333,7 @@ term stacktrace_build(Context *ctx, term *stack_info) AtomString function_name = NULL; int arity = 0; - bool result = module_get_function_from_label(cp_mod, label, &function_name, &arity); + bool result = module_get_function_from_label(cp_mod, label, &function_name, &arity, glb); if (LIKELY(result)) { term_put_tuple_element(frame_i, 1, globalcontext_make_atom(glb, function_name)); diff --git a/src/platforms/emscripten/src/main.c b/src/platforms/emscripten/src/main.c index 8b3036884..7d7656277 100644 --- a/src/platforms/emscripten/src/main.c +++ b/src/platforms/emscripten/src/main.c @@ -74,7 +74,7 @@ static int load_module(const char *path) } else if (ext && strcmp(ext, ".beam") == 0) { Module *module = sys_load_module_from_file(global, path); globalcontext_insert_module(global, module); - if (IS_NULL_PTR(main_module) && module_search_exported_function(module, ATOM_STR("\5", "start"), 0) != 0) { + if (IS_NULL_PTR(main_module) && module_search_exported_function(module, ATOM_STR("\5", "start"), 0, global) != 0) { main_module = module; } } else {