From 5ed73504d7409a449ec4e0c0de421a93c4570e3b Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Wed, 18 Jan 2012 17:23:52 +0100 Subject: erts: Use several addresses in each Export --- erts/emulator/beam/beam_bif_load.c | 6 ++--- erts/emulator/beam/beam_debug.c | 2 +- erts/emulator/beam/beam_emu.c | 21 ++++++++-------- erts/emulator/beam/beam_load.c | 8 +++---- erts/emulator/beam/bif.c | 5 +++- erts/emulator/beam/bif.h | 18 +++++++------- erts/emulator/beam/dist.c | 16 ++++++------- erts/emulator/beam/erl_bif_trace.c | 30 +++++++++++------------ erts/emulator/beam/export.c | 49 +++++++++++++++++++++++++++++++------- erts/emulator/beam/export.h | 4 ++-- 10 files changed, 98 insertions(+), 61 deletions(-) (limited to 'erts/emulator/beam') diff --git a/erts/emulator/beam/beam_bif_load.c b/erts/emulator/beam/beam_bif_load.c index 4858859c2d..346b64033b 100644 --- a/erts/emulator/beam/beam_bif_load.c +++ b/erts/emulator/beam/beam_bif_load.c @@ -366,7 +366,7 @@ BIF_RETTYPE finish_after_on_load_2(BIF_ALIST_2) if (ep != NULL && ep->code[0] == BIF_ARG_1 && ep->code[4] != 0) { - ep->address = (void *) ep->code[4]; + ep->addressv[code_ix] = (void *) ep->code[4]; ep->code[4] = 0; } } @@ -779,11 +779,11 @@ delete_export_references(Eterm module) for (i = 0; i < export_list_size(code_ix); i++) { Export *ep = export_list(i, code_ix); if (ep != NULL && (ep->code[0] == module)) { - if (ep->address == ep->code+3 && + if (ep->addressv[code_ix] == ep->code+3 && (ep->code[3] == (BeamInstr) em_apply_bif)) { continue; } - ep->address = ep->code+3; + ep->addressv[code_ix] = ep->code+3; ep->code[3] = (BeamInstr) em_call_error_handler; ep->code[4] = 0; MatchSetUnref(ep->match_prog_set); diff --git a/erts/emulator/beam/beam_debug.c b/erts/emulator/beam/beam_debug.c index ff47b26e13..608303cf4b 100644 --- a/erts/emulator/beam/beam_debug.c +++ b/erts/emulator/beam/beam_debug.c @@ -242,7 +242,7 @@ erts_debug_disassemble_1(BIF_ALIST_1) * But this code_ptr will point to the start of the Export, * not the function's func_info instruction. BOOM !? */ - code_ptr = ((BeamInstr *) ep->address) - 5; + code_ptr = ((BeamInstr *) ep->addressv[code_ix]) - 5; funcinfo = code_ptr+2; } else if (modp == NULL || (code_base = modp->curr.code) == NULL) { BIF_RET(am_undef); diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c index 177dd397f1..4bb4885cbb 100644 --- a/erts/emulator/beam/beam_emu.c +++ b/erts/emulator/beam/beam_emu.c @@ -541,7 +541,7 @@ extern int count_instructions; do { \ if (FCALLS > 0) { \ Eterm* dis_next; \ - SET_I(((Export *) Arg(0))->address); \ + SET_I(((Export *) Arg(0))->addressv[erts_active_code_ix()]); \ dis_next = (Eterm *) *I; \ FCALLS--; \ CHECK_ARGS(I); \ @@ -550,7 +550,7 @@ extern int count_instructions; && FCALLS > neg_o_reds) { \ goto save_calls1; \ } else { \ - SET_I(((Export *) Arg(0))->address); \ + SET_I(((Export *) Arg(0))->addressv[erts_active_code_ix()]); \ CHECK_ARGS(I); \ goto context_switch; \ } \ @@ -5065,7 +5065,7 @@ void process_main(void) save_calls(c_p, (Export *) Arg(0)); - SET_I(((Export *) Arg(0))->address); + SET_I(((Export *) Arg(0))->addressv[erts_active_code_ix()]); dis_next = (Eterm *) *I; FCALLS--; @@ -5773,7 +5773,7 @@ call_error_handler(Process* p, BeamInstr* fi, Eterm* reg, Eterm func) reg[0] = fi[0]; reg[1] = fi[1]; reg[2] = args; - return ep->address; + return ep->addressv[erts_active_code_ix()]; } @@ -5900,7 +5900,7 @@ apply(Process* p, Eterm module, Eterm function, Eterm args, Eterm* reg) save_calls(p, ep); } - return ep->address; + return ep->addressv[erts_active_code_ix()]; } static BeamInstr* @@ -5949,7 +5949,7 @@ fixed_apply(Process* p, Eterm* reg, Uint arity) save_calls(p, ep); } - return ep->address; + return ep->addressv[erts_active_code_ix()]; } int @@ -6154,7 +6154,7 @@ call_fun(Process* p, /* Current process. */ reg[1] = fun; reg[2] = args; reg[3] = NIL; - return ep->address; + return ep->addressv[erts_active_code_ix()]; } } } else if (is_export_header(hdr)) { @@ -6165,7 +6165,7 @@ call_fun(Process* p, /* Current process. */ actual_arity = (int) ep->code[2]; if (arity == actual_arity) { - return ep->address; + return ep->addressv[erts_active_code_ix()]; } else { /* * Wrong arity. First build a list of the arguments. @@ -6240,7 +6240,7 @@ call_fun(Process* p, /* Current process. */ reg[1] = function; reg[2] = args; } - return ep->address; + return ep->addressv[erts_active_code_ix()]; } else { badfun: p->current = NULL; @@ -6345,7 +6345,8 @@ erts_is_builtin(Eterm Mod, Eterm Name, int arity) if ((ep = export_get(&e)) == NULL) { return 0; } - return ep->address == ep->code+3 && (ep->code[3] == (BeamInstr) em_apply_bif); + return ep->addressv[erts_active_code_ix()] == ep->code+3 + && (ep->code[3] == (BeamInstr) em_apply_bif); } diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c index 7768438dd0..c35841af9d 100644 --- a/erts/emulator/beam/beam_load.c +++ b/erts/emulator/beam/beam_load.c @@ -4303,13 +4303,13 @@ final_touch(LoaderState* stp) ep = erts_export_put(stp->module, stp->export[i].function, stp->export[i].arity); if (!on_load) { - ep->address = address; + ep->addressv[erts_loader_code_ix()] = address; } else { /* * Don't make any of the exported functions * callable yet. */ - ep->address = ep->code+3; + ep->addressv[erts_loader_code_ix()] = ep->code+3; ep->code[4] = (BeamInstr) address; } } @@ -5203,7 +5203,7 @@ exported_from_module(Process* p, /* Process whose heap to use. */ if (ep->code[0] == mod) { Eterm tuple; - if (ep->address == ep->code+3 && + if (ep->addressv[code_ix] == ep->code+3 && ep->code[3] == (BeamInstr) em_call_error_handler) { /* There is a call to the function, but it does not exist. */ continue; @@ -5692,7 +5692,7 @@ stub_final_touch(LoaderState* stp, BeamInstr* fp) for (i = 0; i < n; i++) { if (stp->export[i].function == function && stp->export[i].arity == arity) { Export* ep = erts_export_put(mod, function, arity); - ep->address = fp+5; + ep->addressv[erts_loader_code_ix()] = fp+5; return; } } diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c index cb99c1381c..9b2394d92f 100644 --- a/erts/emulator/beam/bif.c +++ b/erts/emulator/beam/bif.c @@ -4438,8 +4438,11 @@ Export bif_return_trap_export; void erts_init_trap_export(Export* ep, Eterm m, Eterm f, Uint a, Eterm (*bif)(BIF_ALIST_0)) { + int i; sys_memset((void *) ep, 0, sizeof(Export)); - ep->address = &ep->code[3]; + for (i=0; iaddressv[i] = &ep->code[3]; + } ep->code[0] = m; ep->code[1] = f; ep->code[2] = a; diff --git a/erts/emulator/beam/bif.h b/erts/emulator/beam/bif.h index d20089a9fb..7cb2c78815 100644 --- a/erts/emulator/beam/bif.h +++ b/erts/emulator/beam/bif.h @@ -125,7 +125,7 @@ do { \ #define ERTS_BIF_PREP_TRAP0(Ret, Trap, Proc) \ do { \ (Proc)->arity = 0; \ - (Proc)->i = (BeamInstr*) ((Trap)->address); \ + (Proc)->i = (BeamInstr*) ((Trap)->addressv[erts_active_code_ix()]); \ (Proc)->freason = TRAP; \ (Ret) = THE_NON_VALUE; \ } while (0) @@ -135,7 +135,7 @@ do { \ Eterm* reg = ERTS_PROC_GET_SCHDATA((Proc))->x_reg_array; \ (Proc)->arity = 1; \ reg[0] = (Eterm) (A0); \ - (Proc)->i = (BeamInstr*) ((Trap)->address); \ + (Proc)->i = (BeamInstr*) ((Trap)->addressv[erts_active_code_ix()]); \ (Proc)->freason = TRAP; \ (Ret) = THE_NON_VALUE; \ } while (0) @@ -146,7 +146,7 @@ do { \ (Proc)->arity = 2; \ reg[0] = (Eterm) (A0); \ reg[1] = (Eterm) (A1); \ - (Proc)->i = (BeamInstr*) ((Trap)->address); \ + (Proc)->i = (BeamInstr*) ((Trap)->addressv[erts_active_code_ix()]); \ (Proc)->freason = TRAP; \ (Ret) = THE_NON_VALUE; \ } while (0) @@ -158,7 +158,7 @@ do { \ reg[0] = (Eterm) (A0); \ reg[1] = (Eterm) (A1); \ reg[2] = (Eterm) (A2); \ - (Proc)->i = (BeamInstr*) ((Trap)->address); \ + (Proc)->i = (BeamInstr*) ((Trap)->addressv[erts_active_code_ix()]); \ (Proc)->freason = TRAP; \ (Ret) = THE_NON_VALUE; \ } while (0) @@ -170,13 +170,13 @@ do { \ reg[0] = (Eterm) (A0); \ reg[1] = (Eterm) (A1); \ reg[2] = (Eterm) (A2); \ - (Proc)->i = (BeamInstr*) ((Trap)->address); \ + (Proc)->i = (BeamInstr*) ((Trap)->addressv[erts_active_code_ix()]); \ (Proc)->freason = TRAP; \ } while (0) #define BIF_TRAP0(p, Trap_) do { \ (p)->arity = 0; \ - (p)->i = (BeamInstr*) ((Trap_)->address); \ + (p)->i = (BeamInstr*) ((Trap_)->addressv[erts_active_code_ix()]); \ (p)->freason = TRAP; \ return THE_NON_VALUE; \ } while(0) @@ -185,7 +185,7 @@ do { \ Eterm* reg = ERTS_PROC_GET_SCHDATA((p))->x_reg_array; \ (p)->arity = 1; \ reg[0] = (A0); \ - (p)->i = (BeamInstr*) ((Trap_)->address); \ + (p)->i = (BeamInstr*) ((Trap_)->addressv[erts_active_code_ix()]); \ (p)->freason = TRAP; \ return THE_NON_VALUE; \ } while(0) @@ -195,7 +195,7 @@ do { \ (p)->arity = 2; \ reg[0] = (A0); \ reg[1] = (A1); \ - (p)->i = (BeamInstr*) ((Trap_)->address); \ + (p)->i = (BeamInstr*) ((Trap_)->addressv[erts_active_code_ix()]); \ (p)->freason = TRAP; \ return THE_NON_VALUE; \ } while(0) @@ -206,7 +206,7 @@ do { \ reg[0] = (A0); \ reg[1] = (A1); \ reg[2] = (A2); \ - (p)->i = (BeamInstr*) ((Trap_)->address); \ + (p)->i = (BeamInstr*) ((Trap_)->addressv[erts_active_code_ix()]); \ (p)->freason = TRAP; \ return THE_NON_VALUE; \ } while(0) diff --git a/erts/emulator/beam/dist.c b/erts/emulator/beam/dist.c index bee61e7273..00d57ceab5 100644 --- a/erts/emulator/beam/dist.c +++ b/erts/emulator/beam/dist.c @@ -2295,15 +2295,15 @@ BIF_RETTYPE setnode_2(BIF_ALIST_2) goto error; /* Check that all trap functions are defined !! */ - if (dsend2_trap->address == NULL || - dsend3_trap->address == NULL || + if (dsend2_trap->addressv[0] == NULL || + dsend3_trap->addressv[0] == NULL || /* dsend_nosuspend_trap->address == NULL ||*/ - dlink_trap->address == NULL || - dunlink_trap->address == NULL || - dmonitor_node_trap->address == NULL || - dgroup_leader_trap->address == NULL || - dmonitor_p_trap->address == NULL || - dexit_trap->address == NULL) { + dlink_trap->addressv[0] == NULL || + dunlink_trap->addressv[0] == NULL || + dmonitor_node_trap->addressv[0] == NULL || + dgroup_leader_trap->addressv[0] == NULL || + dmonitor_p_trap->addressv[0] == NULL || + dexit_trap->addressv[0] == NULL) { goto error; } diff --git a/erts/emulator/beam/erl_bif_trace.c b/erts/emulator/beam/erl_bif_trace.c index 7db764280a..cb43069fa9 100644 --- a/erts/emulator/beam/erl_bif_trace.c +++ b/erts/emulator/beam/erl_bif_trace.c @@ -60,8 +60,8 @@ static Eterm trace_info_pid(Process* p, Eterm pid_spec, Eterm key); static Eterm trace_info_func(Process* p, Eterm pid_spec, Eterm key); static Eterm trace_info_on_load(Process* p, Eterm key); -static int setup_func_trace(Export* ep, void* match_prog); -static int reset_func_trace(Export* ep); +static int setup_func_trace(Export* ep, void* match_prog, ErtsCodeIndex); +static int reset_func_trace(Export* ep, ErtsCodeIndex); static void reset_bif_trace(int bif_index); static void setup_bif_trace(int bif_index); static void set_trace_bif(int bif_index, void* match_prog); @@ -991,7 +991,7 @@ static int function_is_traced(Process *p, e.code[1] = mfa[1]; e.code[2] = mfa[2]; if ((ep = export_get(&e)) != NULL) { - if (ep->address == ep->code+3 && + if (ep->addressv[erts_active_code_ix()] == ep->code+3 && ep->code[3] != (BeamInstr) em_call_error_handler) { if (ep->code[3] == (BeamInstr) em_call_traced_function) { *ms = ep->match_prog_set; @@ -1357,11 +1357,11 @@ erts_set_trace_pattern(Eterm* mfa, int specified, if (j == specified) { if (on) { if (! flags.breakpoint) - matches += setup_func_trace(ep, match_prog_set); + matches += setup_func_trace(ep, match_prog_set, code_ix); else - reset_func_trace(ep); + reset_func_trace(ep, code_ix); } else if (! flags.breakpoint) { - matches += reset_func_trace(ep); + matches += reset_func_trace(ep, code_ix); } } } @@ -1524,9 +1524,9 @@ erts_set_trace_pattern(Eterm* mfa, int specified, */ static int -setup_func_trace(Export* ep, void* match_prog) +setup_func_trace(Export* ep, void* match_prog, ErtsCodeIndex code_ix) { - if (ep->address == ep->code+3) { + if (ep->addressv[code_ix] == ep->code+3) { if (ep->code[3] == (BeamInstr) em_call_error_handler) { return 0; } else if (ep->code[3] == (BeamInstr) em_call_traced_function) { @@ -1545,13 +1545,13 @@ setup_func_trace(Export* ep, void* match_prog) /* * Currently no trace support for native code. */ - if (erts_is_native_break(ep->address)) { + if (erts_is_native_break(ep->addressv[code_ix])) { return 0; } ep->code[3] = (BeamInstr) em_call_traced_function; - ep->code[4] = (BeamInstr) ep->address; - ep->address = ep->code+3; + ep->code[4] = (BeamInstr) ep->addressv[code_ix]; + ep->addressv[code_ix] = ep->code+3; ep->match_prog_set = match_prog; MatchSetRef(ep->match_prog_set); return 1; @@ -1586,13 +1586,13 @@ static void set_trace_bif(int bif_index, void* match_prog) { */ static int -reset_func_trace(Export* ep) +reset_func_trace(Export* ep, ErtsCodeIndex code_ix) { - if (ep->address == ep->code+3) { + if (ep->addressv[code_ix] == ep->code+3) { if (ep->code[3] == (BeamInstr) em_call_error_handler) { return 0; } else if (ep->code[3] == (BeamInstr) em_call_traced_function) { - ep->address = (Uint *) ep->code[4]; + ep->addressv[code_ix] = (Uint *) ep->code[4]; MatchSetUnref(ep->match_prog_set); ep->match_prog_set = NULL; return 1; @@ -1607,7 +1607,7 @@ reset_func_trace(Export* ep) /* * Currently no trace support for native code. */ - if (erts_is_native_break(ep->address)) { + if (erts_is_native_break(ep->addressv[code_ix])) { return 0; } diff --git a/erts/emulator/beam/export.c b/erts/emulator/beam/export.c index 6a71b09472..51d0116110 100644 --- a/erts/emulator/beam/export.c +++ b/erts/emulator/beam/export.c @@ -127,12 +127,13 @@ export_alloc(struct export_entry* tmpl_e) obj->code[0] = tmpl->code[0]; obj->code[1] = tmpl->code[1]; obj->code[2] = tmpl->code[2]; - obj->address = obj->code+3; obj->code[3] = (BeamInstr) em_call_error_handler; obj->code[4] = 0; obj->match_prog_set = NULL; for (i=0; iaddressv[i] = obj->code+3; + blob->entryv[i].slot.index = -1; blob->entryv[i].ep = &blob->exp; } @@ -191,6 +192,9 @@ erts_active_export_entry(Eterm m, Eterm f, unsigned int a) return erts_find_export_entry(m, f, a, erts_active_code_ix()); } +static void sverk_break(void) +{ +} Export* erts_find_export_entry(Eterm m, Eterm f, unsigned int a, @@ -200,6 +204,10 @@ erts_find_export_entry(Eterm m, Eterm f, unsigned int a, int ix; HashBucket* b; + if (ERTS_IS_ATOM_STR("gen_event",m) && ERTS_IS_ATOM_STR("add_handler",f)) { + sverk_break(); + } + ix = hval % export_tables[code_ix].htable.size; b = export_tables[code_ix].htable.bucket[ix]; @@ -246,8 +254,12 @@ erts_find_function(Eterm m, Eterm f, unsigned int a, ErtsCodeIndex code_ix) struct export_templ templ; struct export_entry* ee; + if (ERTS_IS_ATOM_STR("gen_event",m) && ERTS_IS_ATOM_STR("add_handler",f)) { + sverk_break(); + } + ee = hash_get(&export_tables[code_ix].htable, init_template(&templ, m, f, a)); - if (ee == NULL || (ee->ep->address == ee->ep->code+3 && + if (ee == NULL || (ee->ep->addressv[code_ix] == ee->ep->code+3 && ee->ep->code[3] != (BeamInstr) em_call_traced_function)) { return NULL; } @@ -270,6 +282,10 @@ erts_export_put(Eterm mod, Eterm func, unsigned int arity) struct export_templ templ; int ix; + if (ERTS_IS_ATOM_STR("gen_event",mod) && ERTS_IS_ATOM_STR("add_handler",func)) { + sverk_break(); + } + ASSERT(is_atom(mod)); ASSERT(is_atom(func)); ix = index_put(&export_tables[code_ix], init_template(&templ, mod, func, arity)); @@ -361,6 +377,10 @@ Export *export_get(Export *e) { struct export_entry ee; struct export_entry* entry; + + if (ERTS_IS_ATOM_STR("gen_event",e->code[0]) && ERTS_IS_ATOM_STR("add_handler",e->code[1])) { + sverk_break(); + } ee.ep = e; entry = (struct export_entry*)hash_get(&export_tables[erts_active_code_ix()].htable, &ee); return entry ? entry->ep : NULL; @@ -386,23 +406,36 @@ void export_start_load(void) ErtsCodeIndex src_ix = erts_active_code_ix(); IndexTable* dst = &export_tables[dst_ix]; IndexTable* src = &export_tables[src_ix]; + struct export_entry* src_entry; + struct export_entry* dst_entry; + struct export_blob* blob; int i; ASSERT(dst_ix != src_ix); + ASSERT(dst->entries <= src->entries); ASSERT(debug_start_load_ix == -1); - /* Trick hash_put (called by index_put below) - * to insert an already allocated entry. */ + /* + * Make sure our existing entries are up to date + */ + for (i = 0; i < dst->entries; i++) { + src_entry = (struct export_entry*) erts_index_lookup(src, i); + blob = entry_to_blob(src_entry); + blob->exp.addressv[dst_ix] = blob->exp.addressv[src_ix]; + } + + /* + * Insert all new entries from active table + */ + + /* Trick hash_put (called by index_put) to insert existing entries. */ dst->htable.fun.alloc = (HALLOC_FUN) &export_dummy_alloc; for (i = dst->entries; i < src->entries; i++) { - struct export_entry* src_entry; - struct export_entry* dst_entry; - struct export_blob* blob; - src_entry = (struct export_entry*) erts_index_lookup(src, i); blob = entry_to_blob(src_entry); dst_entry = &blob->entryv[++blob->top_ix]; + blob->exp.addressv[dst_ix] = blob->exp.addressv[src_ix]; ASSERT(blob->top_ix < ERTS_NUM_CODE_IX); ASSERT(dst_entry->ep == &blob->exp); ASSERT(dst_entry->slot.index == -1); diff --git a/erts/emulator/beam/export.h b/erts/emulator/beam/export.h index 0aad921b2d..db27606c49 100644 --- a/erts/emulator/beam/export.h +++ b/erts/emulator/beam/export.h @@ -36,7 +36,7 @@ typedef struct export { - void* address; /* Pointer to code for function. */ + void* addressv[ERTS_NUM_CODE_IX]; /* Pointer to code for function. */ struct binary* match_prog_set; /* Match program for tracing. */ BeamInstr fake_op_func_info_for_hipe[2]; /* MUST be just before code[] */ @@ -78,7 +78,7 @@ void export_end_load(int commit); #include "beam_load.h" /* For em_* extern declarations */ #define ExportIsBuiltIn(EntryPtr) \ -(((EntryPtr)->address == (EntryPtr)->code + 3) && \ +(((EntryPtr)->addressv[erts_active_code_ix()] == (EntryPtr)->code + 3) && \ ((EntryPtr)->code[3] == (BeamInstr) em_apply_bif)) #endif -- cgit v1.2.3