diff options
author | John Högberg <john@erlang.org> | 2020-06-12 09:51:26 +0200 |
---|---|---|
committer | Lukas Larsson <lukas@erlang.org> | 2020-09-21 16:40:30 +0200 |
commit | e53f65f3474eba59962f02d031bea1d9582ad3cc (patch) | |
tree | 5a0f67118f83fa3cb877ca9a52400312caaa1398 /erts/emulator | |
parent | b15d68592a7da7e9386152e506700c28fcaecd88 (diff) | |
download | erlang-e53f65f3474eba59962f02d031bea1d9582ad3cc.tar.gz |
erts: Break out module-info related functions from beam_load.c
Diffstat (limited to 'erts/emulator')
-rw-r--r-- | erts/emulator/beam/beam_load.c | 341 | ||||
-rw-r--r-- | erts/emulator/beam/bif.c | 21 | ||||
-rw-r--r-- | erts/emulator/beam/erl_bif_info.c | 338 | ||||
-rw-r--r-- | erts/emulator/beam/global.h | 2 |
4 files changed, 338 insertions, 364 deletions
diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c index fb36a1f054..b2adf4852a 100644 --- a/erts/emulator/beam/beam_load.c +++ b/erts/emulator/beam/beam_load.c @@ -233,17 +233,6 @@ static int get_tag_and_value(LoaderState* stp, Uint len_code, unsigned tag, BeamInstr* result); static void new_literal_patch(LoaderState* stp, int pos); static void new_string_patch(LoaderState* stp, int pos); -static Eterm get_module_info(Process* p, ErtsCodeIndex code_ix, - BeamCodeHeader*, Eterm module, Eterm what); -static Eterm exported_from_module(Process* p, ErtsCodeIndex code_ix, - Eterm mod); -static Eterm functions_in_module(Process* p, BeamCodeHeader*); -static Eterm nifs_in_module(Process* p, Eterm module); -static Eterm attributes_for_module(Process* p, BeamCodeHeader*); -static Eterm compilation_info_for_module(Process* p, BeamCodeHeader*); -static Eterm md5_of_module(Process* p, BeamCodeHeader*); -static Eterm has_native(BeamCodeHeader*); -static Eterm native_addresses(Process* p, BeamCodeHeader*); static int must_swap_floats; @@ -3453,195 +3442,6 @@ beam_load_find_literal(LoaderState* stp, Eterm needle, Uint *idx) return 0; } -Eterm -erts_module_info_0(Process* p, Eterm module) -{ - Module* modp; - ErtsCodeIndex code_ix = erts_active_code_ix(); - BeamCodeHeader* code_hdr; - Eterm *hp; - Eterm list = NIL; - Eterm tup; - - if (is_not_atom(module)) { - return THE_NON_VALUE; - } - - modp = erts_get_module(module, code_ix); - if (modp == NULL) { - return THE_NON_VALUE; - } - - code_hdr = modp->curr.code_hdr; - if (code_hdr == NULL) { - return THE_NON_VALUE; - } - -#define BUILD_INFO(What) \ - tup = get_module_info(p, code_ix, code_hdr, module, What); \ - hp = HAlloc(p, 5); \ - tup = TUPLE2(hp, What, tup); \ - hp += 3; \ - list = CONS(hp, tup, list) - - BUILD_INFO(am_md5); -#ifdef HIPE - BUILD_INFO(am_native); -#endif - BUILD_INFO(am_compile); - BUILD_INFO(am_attributes); - BUILD_INFO(am_exports); - BUILD_INFO(am_module); -#undef BUILD_INFO - return list; -} - -Eterm -erts_module_info_1(Process* p, Eterm module, Eterm what) -{ - Module* modp; - ErtsCodeIndex code_ix = erts_active_code_ix(); - BeamCodeHeader* code_hdr; - - if (is_not_atom(module)) { - return THE_NON_VALUE; - } - - modp = erts_get_module(module, code_ix); - if (modp == NULL) { - return THE_NON_VALUE; - } - - code_hdr = modp->curr.code_hdr; - if (code_hdr == NULL) { - return THE_NON_VALUE; - } - - return get_module_info(p, code_ix, code_hdr, module, what); -} - -static Eterm -get_module_info(Process* p, ErtsCodeIndex code_ix, BeamCodeHeader* code_hdr, - Eterm module, Eterm what) -{ - if (what == am_module) { - return module; - } else if (what == am_md5) { - return md5_of_module(p, code_hdr); - } else if (what == am_exports) { - return exported_from_module(p, code_ix, module); - } else if (what == am_functions) { - return functions_in_module(p, code_hdr); - } else if (what == am_nifs) { - return nifs_in_module(p, module); - } else if (what == am_attributes) { - return attributes_for_module(p, code_hdr); - } else if (what == am_compile) { - return compilation_info_for_module(p, code_hdr); - } else if (what == am_native_addresses) { - return native_addresses(p, code_hdr); - } else if (what == am_native) { - return has_native(code_hdr); - } - return THE_NON_VALUE; -} - -/* - * Builds a list of all functions in the given module: - * [{Name, Arity},...] - */ - -Eterm -functions_in_module(Process* p, /* Process whose heap to use. */ - BeamCodeHeader* code_hdr) -{ - int i; - Uint num_functions; - Uint need; - Eterm* hp; - Eterm* hp_end; - Eterm result = NIL; - - num_functions = code_hdr->num_functions; - need = 5*num_functions; - hp = HAlloc(p, need); - hp_end = hp + need; - for (i = num_functions-1; i >= 0 ; i--) { - ErtsCodeInfo* ci = code_hdr->functions[i]; - Eterm tuple; - - /* - * If the function name is [], this entry is a stub for - * a BIF that should be ignored. - */ - ASSERT(is_atom(ci->mfa.function) || is_nil(ci->mfa.function)); - if (is_atom(ci->mfa.function)) { - tuple = TUPLE2(hp, ci->mfa.function, make_small(ci->mfa.arity)); - hp += 3; - result = CONS(hp, tuple, result); - hp += 2; - } - } - HRelease(p, hp_end, hp); - return result; -} - -/* - * Builds a list of all NIFs in the given module: - * [{Name, Arity},...] - */ -Eterm -nifs_in_module(Process* p, Eterm module) -{ - Eterm nif_list, *hp; - Module *mod; - - mod = erts_get_module(module, erts_active_code_ix()); - nif_list = NIL; - - if (mod->curr.nif != NULL) { - int func_count, func_ix; - ErlNifFunc *funcs; - - func_count = erts_nif_get_funcs(mod->curr.nif, &funcs); - hp = HAlloc(p, func_count * 5); - - for (func_ix = func_count - 1; func_ix >= 0; func_ix--) { - Eterm name, arity, pair; - ErlNifFunc *func; - - func = &funcs[func_ix]; - - name = am_atom_put(func->name, sys_strlen(func->name)); - arity = make_small(func->arity); - - pair = TUPLE2(hp, name, arity); - hp += 3; - - nif_list = CONS(hp, pair, nif_list); - hp += 2; - } - } - - return nif_list; -} - -/* - * Returns 'true' if mod has any native compiled functions, otherwise 'false' - */ - -static Eterm -has_native(BeamCodeHeader *code_hdr) -{ - Eterm result = am_false; -#ifdef HIPE - if (erts_is_module_native(code_hdr)) { - result = am_true; - } -#endif - return result; -} - void erts_release_literal_area(ErtsLiteralArea* literal_area) { @@ -3718,147 +3518,6 @@ erts_is_function_native(ErtsCodeInfo *ci) } /* - * Builds a list of all functions including native addresses. - * [{Name,Arity,NativeAddress},...] - */ - -static Eterm -native_addresses(Process* p, BeamCodeHeader* code_hdr) -{ - Eterm result = NIL; -#ifdef HIPE - int i; - Eterm* hp; - Uint num_functions; - Uint need; - Eterm* hp_end; - - num_functions = code_hdr->num_functions; - need = (6+BIG_UINT_HEAP_SIZE)*num_functions; - hp = HAlloc(p, need); - hp_end = hp + need; - for (i = num_functions-1; i >= 0 ; i--) { - ErtsCodeInfo *ci = code_hdr->functions[i]; - Eterm tuple; - - ASSERT(is_atom(ci->mfa.function) - || is_nil(ci->mfa.function)); /* [] if BIF stub */ - if (ci->u.ncallee != NULL) { - Eterm addr; - ASSERT(is_atom(ci->mfa.function)); - addr = erts_bld_uint(&hp, NULL, (Uint)ci->u.ncallee); - tuple = erts_bld_tuple(&hp, NULL, 3, ci->mfa.function, - make_small(ci->mfa.arity), addr); - result = erts_bld_cons(&hp, NULL, tuple, result); - } - } - HRelease(p, hp_end, hp); -#endif - return result; -} - -/* - * Builds a list of all exported functions in the given module: - * [{Name, Arity},...] - */ - -Eterm -exported_from_module(Process* p, /* Process whose heap to use. */ - ErtsCodeIndex code_ix, - Eterm mod) /* Tagged atom for module. */ -{ - int i, num_exps; - Eterm* hp = NULL; - Eterm* hend = NULL; - Eterm result = NIL; - - num_exps = export_list_size(code_ix); - for (i = 0; i < num_exps; i++) { - Export* ep = export_list(i,code_ix); - - if (ep->info.mfa.module == mod) { - Eterm tuple; - - if (ep->addressv[code_ix] == ep->trampoline.raw && - BeamIsOpCode(ep->trampoline.op, op_call_error_handler)) { - /* There is a call to the function, but it does not exist. */ - continue; - } - - if (hp == hend) { - int need = 10 * 5; - hp = HAlloc(p, need); - hend = hp + need; - } - tuple = TUPLE2(hp, ep->info.mfa.function, - make_small(ep->info.mfa.arity)); - hp += 3; - result = CONS(hp, tuple, result); - hp += 2; - } - } - HRelease(p,hend,hp); - return result; -} - -/* - * Returns a list of all attributes for the module. - */ - -Eterm -attributes_for_module(Process* p, /* Process whose heap to use. */ - BeamCodeHeader* code_hdr) -{ - byte* ext; - Eterm result = NIL; - - ext = code_hdr->attr_ptr; - if (ext != NULL) { - ErtsHeapFactory factory; - erts_factory_proc_prealloc_init(&factory, p, code_hdr->attr_size_on_heap); - result = erts_decode_ext(&factory, &ext, 0); - if (is_value(result)) { - erts_factory_close(&factory); - } - } - return result; -} - -/* - * Returns a list containing compilation information. - */ - -Eterm -compilation_info_for_module(Process* p, /* Process whose heap to use. */ - BeamCodeHeader* code_hdr) -{ - byte* ext; - Eterm result = NIL; - - ext = code_hdr->compile_ptr; - if (ext != NULL) { - ErtsHeapFactory factory; - erts_factory_proc_prealloc_init(&factory, p, code_hdr->compile_size_on_heap); - result = erts_decode_ext(&factory, &ext, 0); - if (is_value(result)) { - erts_factory_close(&factory); - } - } - return result; -} - -/* - * Returns the MD5 checksum for a module - */ - -Eterm -md5_of_module(Process* p, /* Process whose heap to use. */ - BeamCodeHeader* code_hdr) -{ - return new_binary(p, code_hdr->md5_ptr, MD5_SIZE); -} - -/* * Read a specific chunk from a Beam binary. */ diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c index b0a80effb9..7418d2fb78 100644 --- a/erts/emulator/beam/bif.c +++ b/erts/emulator/beam/bif.c @@ -5376,27 +5376,6 @@ erts_call_dirty_bif(ErtsSchedulerData *esdp, Process *c_p, BeamInstr *I, Eterm * return exiting; } -BIF_RETTYPE get_module_info_1(BIF_ALIST_1) -{ - Eterm ret = erts_module_info_0(BIF_P, BIF_ARG_1); - - if (is_non_value(ret)) { - BIF_ERROR(BIF_P, BADARG); - } - BIF_RET(ret); -} - - -BIF_RETTYPE get_module_info_2(BIF_ALIST_2) -{ - Eterm ret = erts_module_info_1(BIF_P, BIF_ARG_1, BIF_ARG_2); - - if (is_non_value(ret)) { - BIF_ERROR(BIF_P, BADARG); - } - BIF_RET(ret); -} - BIF_RETTYPE dt_put_tag_1(BIF_ALIST_1) { #ifdef USE_VM_PROBES diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c index 0479f4c80c..1566fe0bc3 100644 --- a/erts/emulator/beam/erl_bif_info.c +++ b/erts/emulator/beam/erl_bif_info.c @@ -5097,6 +5097,344 @@ BIF_RETTYPE erts_internal_gather_carrier_info_1(BIF_ALIST_1) erts_alcu_gather_carrier_info); } + +/* Builds a list of all functions in the given module: + * [{Name, Arity},...] */ +static Eterm +functions_in_module(Process* p, BeamCodeHeader* code_hdr) +{ + int i; + Uint num_functions; + Uint need; + Eterm* hp; + Eterm* hp_end; + Eterm result = NIL; + + num_functions = code_hdr->num_functions; + need = 5*num_functions; + hp = HAlloc(p, need); + hp_end = hp + need; + for (i = num_functions-1; i >= 0 ; i--) { + ErtsCodeInfo* ci = code_hdr->functions[i]; + Eterm tuple; + + /* + * If the function name is [], this entry is a stub for + * a BIF that should be ignored. + */ + ASSERT(is_atom(ci->mfa.function) || is_nil(ci->mfa.function)); + if (is_atom(ci->mfa.function)) { + tuple = TUPLE2(hp, ci->mfa.function, make_small(ci->mfa.arity)); + hp += 3; + + result = CONS(hp, tuple, result); + hp += 2; + } + } + HRelease(p, hp_end, hp); + return result; +} + +/* Builds a list of all NIFs in the given module: + * [{Name, Arity},...] */ +static Eterm +nifs_in_module(Process* p, Eterm module) +{ + Eterm nif_list, *hp; + Module *mod; + + mod = erts_get_module(module, erts_active_code_ix()); + nif_list = NIL; + + if (mod->curr.nif != NULL) { + int func_count, func_ix; + ErlNifFunc *funcs; + + func_count = erts_nif_get_funcs(mod->curr.nif, &funcs); + hp = HAlloc(p, func_count * 5); + + for (func_ix = func_count - 1; func_ix >= 0; func_ix--) { + Eterm name, arity, pair; + ErlNifFunc *func; + + func = &funcs[func_ix]; + + name = am_atom_put(func->name, sys_strlen(func->name)); + arity = make_small(func->arity); + + pair = TUPLE2(hp, name, arity); + hp += 3; + + nif_list = CONS(hp, pair, nif_list); + hp += 2; + } + } + + return nif_list; +} + +/* Returns 'true' if mod has any native compiled functions, otherwise 'false' */ +static Eterm +has_native(BeamCodeHeader *code_hdr) +{ + Eterm result = am_false; +#ifdef HIPE + if (erts_is_module_native(code_hdr)) { + result = am_true; + } +#endif + return result; +} + +/* Builds a list of all functions including native addresses. + * [{Name,Arity,NativeAddress},...] */ +static Eterm +native_addresses(Process* p, BeamCodeHeader* code_hdr) +{ + Eterm result = NIL; +#ifdef HIPE + int i; + Eterm* hp; + Uint num_functions; + Uint need; + Eterm* hp_end; + + num_functions = code_hdr->num_functions; + need = (6+BIG_UINT_HEAP_SIZE)*num_functions; + hp = HAlloc(p, need); + hp_end = hp + need; + for (i = num_functions-1; i >= 0 ; i--) { + ErtsCodeInfo *ci = code_hdr->functions[i]; + Eterm tuple; + + ASSERT(is_atom(ci->mfa.function) + || is_nil(ci->mfa.function)); /* [] if BIF stub */ + if (ci->u.ncallee != NULL) { + Eterm addr; + ASSERT(is_atom(ci->mfa.function)); + addr = erts_bld_uint(&hp, NULL, (Uint)ci->u.ncallee); + tuple = erts_bld_tuple(&hp, NULL, 3, ci->mfa.function, + make_small(ci->mfa.arity), addr); + result = erts_bld_cons(&hp, NULL, tuple, result); + } + } + HRelease(p, hp_end, hp); +#endif + return result; +} + +/* Builds a list of all exported functions in the given module: + * [{Name, Arity},...] */ +static Eterm +exported_from_module(Process* p, ErtsCodeIndex code_ix, Eterm mod) +{ + int i, num_exps; + Eterm* hp = NULL; + Eterm* hend = NULL; + Eterm result = NIL; + + num_exps = export_list_size(code_ix); + for (i = 0; i < num_exps; i++) { + Export* ep = export_list(i,code_ix); + + if (ep->info.mfa.module == mod) { + Eterm tuple; + + if (ep->addressv[code_ix] == ep->trampoline.raw && + BeamIsOpCode(ep->trampoline.op, op_call_error_handler)) { + /* There is a call to the function, but it does not exist. */ + continue; + } + + if (hp == hend) { + int need = 10 * 5; + hp = HAlloc(p, need); + hend = hp + need; + } + + tuple = TUPLE2(hp, ep->info.mfa.function, + make_small(ep->info.mfa.arity)); + hp += 3; + + result = CONS(hp, tuple, result); + hp += 2; + } + } + + HRelease(p, hend,hp); + return result; +} + +/* Returns a list of all attributes for the module. */ +static Eterm +attributes_for_module(Process* p, BeamCodeHeader* code_hdr) +{ + const byte* ext; + Eterm result = NIL; + + ext = code_hdr->attr_ptr; + if (ext != NULL) { + ErtsHeapFactory factory; + + erts_factory_proc_prealloc_init(&factory, p, + code_hdr->attr_size_on_heap); + + result = erts_decode_ext(&factory, &ext, 0); + + if (is_value(result)) { + erts_factory_close(&factory); + } + } + return result; +} + +/* Returns a list containing compilation information. */ +static Eterm +compilation_info_for_module(Process* p, BeamCodeHeader* code_hdr) +{ + const byte* ext; + Eterm result = NIL; + + ext = code_hdr->compile_ptr; + if (ext != NULL) { + ErtsHeapFactory factory; + + erts_factory_proc_prealloc_init(&factory, p, + code_hdr->compile_size_on_heap); + + result = erts_decode_ext(&factory, &ext, 0); + + if (is_value(result)) { + erts_factory_close(&factory); + } + } + + return result; +} + +/* Returns the MD5 checksum for a module */ +static Eterm +md5_of_module(Process* p, BeamCodeHeader* code_hdr) +{ + return new_binary(p, code_hdr->md5_ptr, MD5_SIZE); +} + +static Eterm +get_module_info(Process* p, ErtsCodeIndex code_ix, BeamCodeHeader* code_hdr, + Eterm module, Eterm what) +{ + if (what == am_module) { + return module; + } else if (what == am_md5) { + return md5_of_module(p, code_hdr); + } else if (what == am_exports) { + return exported_from_module(p, code_ix, module); + } else if (what == am_functions) { + return functions_in_module(p, code_hdr); + } else if (what == am_nifs) { + return nifs_in_module(p, module); + } else if (what == am_attributes) { + return attributes_for_module(p, code_hdr); + } else if (what == am_compile) { + return compilation_info_for_module(p, code_hdr); + } else if (what == am_native_addresses) { + return native_addresses(p, code_hdr); + } else if (what == am_native) { + return has_native(code_hdr); + } + + return THE_NON_VALUE; +} + +static Eterm +module_info_0(Process* p, Eterm module) +{ + Module* modp; + ErtsCodeIndex code_ix = erts_active_code_ix(); + BeamCodeHeader* code_hdr; + Eterm *hp; + Eterm list = NIL; + Eterm tup; + + if (is_not_atom(module)) { + return THE_NON_VALUE; + } + + modp = erts_get_module(module, code_ix); + if (modp == NULL) { + return THE_NON_VALUE; + } + + code_hdr = modp->curr.code_hdr; + if (code_hdr == NULL) { + return THE_NON_VALUE; + } + +#define BUILD_INFO(What) \ + tup = get_module_info(p, code_ix, code_hdr, module, What); \ + hp = HAlloc(p, 5); \ + tup = TUPLE2(hp, What, tup); \ + hp += 3; \ + list = CONS(hp, tup, list) + + BUILD_INFO(am_md5); +#ifdef HIPE + BUILD_INFO(am_native); +#endif + BUILD_INFO(am_compile); + BUILD_INFO(am_attributes); + BUILD_INFO(am_exports); + BUILD_INFO(am_module); +#undef BUILD_INFO + return list; +} + +static Eterm +module_info_1(Process* p, Eterm module, Eterm what) +{ + Module* modp; + ErtsCodeIndex code_ix = erts_active_code_ix(); + BeamCodeHeader* code_hdr; + + if (is_not_atom(module)) { + return THE_NON_VALUE; + } + + modp = erts_get_module(module, code_ix); + if (modp == NULL) { + return THE_NON_VALUE; + } + + code_hdr = modp->curr.code_hdr; + if (code_hdr == NULL) { + return THE_NON_VALUE; + } + + return get_module_info(p, code_ix, code_hdr, module, what); +} + +BIF_RETTYPE get_module_info_1(BIF_ALIST_1) +{ + Eterm ret = module_info_0(BIF_P, BIF_ARG_1); + + if (is_non_value(ret)) { + BIF_ERROR(BIF_P, BADARG); + } + + BIF_RET(ret); +} + +BIF_RETTYPE get_module_info_2(BIF_ALIST_2) +{ + Eterm ret = module_info_1(BIF_P, BIF_ARG_1, BIF_ARG_2); + + if (is_non_value(ret)) { + BIF_ERROR(BIF_P, BADARG); + } + + BIF_RET(ret); +} + #ifdef ERTS_ENABLE_LOCK_COUNT typedef struct { diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h index 0fe98246de..83d00564fa 100644 --- a/erts/emulator/beam/global.h +++ b/erts/emulator/beam/global.h @@ -965,8 +965,6 @@ ErtsCodeMFA* erts_find_function_from_pc(BeamInstr* pc); Eterm* erts_build_mfa_item(FunctionInfo* fi, Eterm* hp, Eterm args, Eterm* mfa_p); void erts_set_current_function(FunctionInfo* fi, ErtsCodeMFA* mfa); -Eterm erts_module_info_0(Process* p, Eterm module); -Eterm erts_module_info_1(Process* p, Eterm module, Eterm what); Eterm erts_make_stub_module(Process* p, Eterm Mod, Eterm Beam, Eterm Info); int erts_commit_hipe_patch_load(Eterm hipe_magic_bin); |