diff options
Diffstat (limited to 'erts')
-rw-r--r-- | erts/emulator/beam/beam_bif_load.c | 46 | ||||
-rw-r--r-- | erts/emulator/beam/erl_bif_trace.c | 12 | ||||
-rw-r--r-- | erts/emulator/beam/module.c | 2 | ||||
-rw-r--r-- | erts/emulator/beam/module.h | 1 |
4 files changed, 33 insertions, 28 deletions
diff --git a/erts/emulator/beam/beam_bif_load.c b/erts/emulator/beam/beam_bif_load.c index 4265f139df..6694f3ae87 100644 --- a/erts/emulator/beam/beam_bif_load.c +++ b/erts/emulator/beam/beam_bif_load.c @@ -38,8 +38,7 @@ static void set_default_trace_pattern(Eterm module, ErtsCodeIndex); static Eterm check_process_code(Process* rp, Module* modp); static void ensure_no_breakpoints(Process *, ErtsProcLocks, Eterm module); -static void delete_code(Process *c_p, ErtsProcLocks c_p_locks, Module* modp); -static void delete_export_references(Eterm module); +static void delete_code(Module* modp); static int purge_module(Process*, int module); static void decrement_refc(BeamInstr* code); static int is_native(BeamInstr* code); @@ -309,8 +308,7 @@ BIF_RETTYPE delete_module_1(BIF_ALIST_1) res = am_badarg; } else { - delete_export_references(BIF_ARG_1); - delete_code(BIF_P, 0, modp); + delete_code(modp); res = am_true; } } @@ -848,32 +846,16 @@ static void ensure_no_breakpoints(Process *c_p, ErtsProcLocks c_p_locks, } /* - * Move code from current to old. + * Move code from current to old and null all export entries for the module */ static void -delete_code(Process *c_p, ErtsProcLocks c_p_locks, Module* modp) -{ - ASSERT(modp->curr.num_breakpoints == 0); - modp->old = modp->curr; - modp->curr.code = NULL; - modp->curr.code_length = 0; - modp->curr.catches = BEAM_CATCHES_NIL; - modp->curr.nif = NULL; -} - - -/* null all references on the export table for the module called with the - atom index below */ - -static void -delete_export_references(Eterm module) +delete_code(Module* modp) { ErtsCodeIndex code_ix = erts_staging_code_ix(); + Eterm module = make_atom(modp->module); int i; - ASSERT(is_atom(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)) { @@ -882,15 +864,26 @@ delete_export_references(Eterm module) continue; } ep->addressv[code_ix] = ep->code+3; - ASSERT(ep->code[3] != (BeamInstr) em_call_traced_function); /*SVERK What to do now? */ + if (ep->code[3] == (BeamInstr) em_call_traced_function) { + ASSERT(modp->curr.num_traced_exports > 0); + --modp->curr.num_traced_exports; + } ep->code[3] = (BeamInstr) em_call_error_handler; ep->code[4] = 0; MatchSetUnref(ep->match_prog_set); ep->match_prog_set = NULL; } } + + ASSERT(modp->curr.num_breakpoints == 0); + ASSERT(modp->curr.num_traced_exports == 0); + modp->old = modp->curr; + modp->curr.code = NULL; + modp->curr.code_length = 0; + modp->curr.catches = BEAM_CATCHES_NIL; + modp->curr.nif = NULL; } - + Eterm beam_make_current_old(Process *c_p, ErtsProcLocks c_p_locks, Eterm module) @@ -905,8 +898,7 @@ beam_make_current_old(Process *c_p, ErtsProcLocks c_p_locks, Eterm module) if (modp->curr.code != NULL && modp->old.code != NULL) { return am_not_purged; } else if (modp->old.code == NULL) { /* Make the current version old. */ - delete_code(c_p, c_p_locks, modp); - delete_export_references(module); + delete_code(modp); } return NIL; } diff --git a/erts/emulator/beam/erl_bif_trace.c b/erts/emulator/beam/erl_bif_trace.c index cb43069fa9..24b16b9679 100644 --- a/erts/emulator/beam/erl_bif_trace.c +++ b/erts/emulator/beam/erl_bif_trace.c @@ -1526,6 +1526,8 @@ erts_set_trace_pattern(Eterm* mfa, int specified, static int setup_func_trace(Export* ep, void* match_prog, ErtsCodeIndex code_ix) { + Module* modp; + if (ep->addressv[code_ix] == ep->code+3) { if (ep->code[3] == (BeamInstr) em_call_error_handler) { return 0; @@ -1548,12 +1550,16 @@ setup_func_trace(Export* ep, void* match_prog, ErtsCodeIndex code_ix) if (erts_is_native_break(ep->addressv[code_ix])) { return 0; } - + ep->code[3] = (BeamInstr) em_call_traced_function; 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); + + modp = erts_get_module(ep->code[0], code_ix); + ASSERT(modp); + modp->curr.num_traced_exports++; return 1; } @@ -1592,6 +1598,10 @@ reset_func_trace(Export* ep, ErtsCodeIndex code_ix) if (ep->code[3] == (BeamInstr) em_call_error_handler) { return 0; } else if (ep->code[3] == (BeamInstr) em_call_traced_function) { + Module* modp = erts_get_module(ep->code[0], code_ix); + ASSERT(modp); + modp->curr.num_traced_exports--; + ep->addressv[code_ix] = (Uint *) ep->code[4]; MatchSetUnref(ep->match_prog_set); ep->match_prog_set = NULL; diff --git a/erts/emulator/beam/module.c b/erts/emulator/beam/module.c index 4174f59446..26c73fff1a 100644 --- a/erts/emulator/beam/module.c +++ b/erts/emulator/beam/module.c @@ -76,6 +76,8 @@ static Module* module_alloc(Module* tmpl) obj->old.nif = NULL; obj->curr.num_breakpoints = 0; obj->old.num_breakpoints = 0; + obj->curr.num_traced_exports = 0; + obj->old.num_traced_exports = 0; return obj; } diff --git a/erts/emulator/beam/module.h b/erts/emulator/beam/module.h index 8c09b3628d..d63cf56778 100644 --- a/erts/emulator/beam/module.h +++ b/erts/emulator/beam/module.h @@ -30,6 +30,7 @@ struct erl_module_instance { unsigned catches; struct erl_module_nif* nif; int num_breakpoints; + int num_traced_exports; }; typedef struct erl_module { |