aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam
diff options
context:
space:
mode:
authorSverker Eriksson <[email protected]>2012-01-18 17:23:52 +0100
committerSverker Eriksson <[email protected]>2012-02-21 12:22:58 +0100
commit5ed73504d7409a449ec4e0c0de421a93c4570e3b (patch)
treef4112eb5bb8b0616d3207635fcc0c55e9ae05c31 /erts/emulator/beam
parent90209e4d57dd9b5ff27729b582f02c3d9e383f72 (diff)
downloadotp-5ed73504d7409a449ec4e0c0de421a93c4570e3b.tar.gz
otp-5ed73504d7409a449ec4e0c0de421a93c4570e3b.tar.bz2
otp-5ed73504d7409a449ec4e0c0de421a93c4570e3b.zip
erts: Use several addresses in each Export
Diffstat (limited to 'erts/emulator/beam')
-rw-r--r--erts/emulator/beam/beam_bif_load.c6
-rw-r--r--erts/emulator/beam/beam_debug.c2
-rw-r--r--erts/emulator/beam/beam_emu.c21
-rw-r--r--erts/emulator/beam/beam_load.c8
-rw-r--r--erts/emulator/beam/bif.c5
-rw-r--r--erts/emulator/beam/bif.h18
-rw-r--r--erts/emulator/beam/dist.c16
-rw-r--r--erts/emulator/beam/erl_bif_trace.c30
-rw-r--r--erts/emulator/beam/export.c49
-rw-r--r--erts/emulator/beam/export.h4
10 files changed, 98 insertions, 61 deletions
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; i<ERTS_NUM_CODE_IX; i++) {
+ ep->addressv[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; i<ERTS_NUM_CODE_IX; i++) {
+ obj->addressv[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