aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/beam')
-rw-r--r--erts/emulator/beam/beam_bif_load.c46
-rw-r--r--erts/emulator/beam/erl_bif_trace.c12
-rw-r--r--erts/emulator/beam/module.c2
-rw-r--r--erts/emulator/beam/module.h1
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 {