aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator')
-rw-r--r--erts/emulator/beam/beam_bif_load.c1
-rw-r--r--erts/emulator/beam/beam_load.c11
-rw-r--r--erts/emulator/beam/module.c6
-rw-r--r--erts/emulator/beam/module.h4
-rw-r--r--erts/emulator/hipe/hipe_bif0.c150
-rw-r--r--erts/emulator/hipe/hipe_bif0.tab2
-rw-r--r--erts/emulator/hipe/hipe_load.c3
-rw-r--r--erts/emulator/hipe/hipe_load.h3
-rw-r--r--erts/emulator/hipe/hipe_module.h3
9 files changed, 100 insertions, 83 deletions
diff --git a/erts/emulator/beam/beam_bif_load.c b/erts/emulator/beam/beam_bif_load.c
index ec1db8d9c2..f5d1ca7e54 100644
--- a/erts/emulator/beam/beam_bif_load.c
+++ b/erts/emulator/beam/beam_bif_load.c
@@ -1798,7 +1798,6 @@ delete_code(Module* modp)
ASSERT(modp->curr.num_breakpoints == 0);
ASSERT(modp->curr.num_traced_exports == 0);
- DBG_TRACE_MFA(make_atom(modp->module), 0, 0, "delete_code old.first_hipe_ref=%p", modp->curr.first_hipe_ref);
modp->old = modp->curr;
erts_module_instance_init(&modp->curr);
}
diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c
index 7d29f393e5..0eb390bf4c 100644
--- a/erts/emulator/beam/beam_load.c
+++ b/erts/emulator/beam/beam_load.c
@@ -1126,11 +1126,8 @@ stub_insert_new_code(Process *c_p, ErtsProcLocks c_p_locks,
modp->curr.code_length = size;
modp->curr.catches = BEAM_CATCHES_NIL; /* Will be filled in later. */
#if defined(HIPE)
- DBG_TRACE_MFA(make_atom(modp->module), 0, 0, "insert_new_code new_hipe_refs = %p", modp->new_hipe_refs);
- modp->curr.first_hipe_ref = modp->new_hipe_refs;
- modp->curr.first_hipe_sdesc = modp->new_hipe_sdesc;
- modp->new_hipe_refs = NULL;
- modp->new_hipe_sdesc = NULL;
+ DBG_TRACE_MFA(make_atom(modp->module), 0, 0, "insert_new_code "
+ "first_hipe_ref = %p", hipe_code->first_hipe_ref);
modp->curr.hipe_code = hipe_code;
#endif
@@ -6498,6 +6495,8 @@ erts_make_stub_module(Process* p, Eterm hipe_magic_bin, Eterm Beam, Eterm Info)
hipe_code->text_segment = hipe_stp->text_segment;
hipe_code->text_segment_size = hipe_stp->text_segment_size;
hipe_code->data_segment = hipe_stp->data_segment;
+ hipe_code->first_hipe_ref = hipe_stp->new_hipe_refs;
+ hipe_code->first_hipe_sdesc = hipe_stp->new_hipe_sdesc;
/*
* Insert the module in the module table.
@@ -6524,6 +6523,8 @@ erts_make_stub_module(Process* p, Eterm hipe_magic_bin, Eterm Beam, Eterm Info)
/* Prevent code from being freed */
hipe_stp->text_segment = 0;
hipe_stp->data_segment = 0;
+ hipe_stp->new_hipe_refs = NULL;
+ hipe_stp->new_hipe_sdesc = NULL;
erts_free_aligned_binary_bytes(temp_alloc);
free_loader_state(magic);
diff --git a/erts/emulator/beam/module.c b/erts/emulator/beam/module.c
index 5c56ad20df..e9b18ba525 100644
--- a/erts/emulator/beam/module.c
+++ b/erts/emulator/beam/module.c
@@ -77,8 +77,6 @@ void erts_module_instance_init(struct erl_module_instance* modi)
modi->num_breakpoints = 0;
modi->num_traced_exports = 0;
#ifdef HIPE
- modi->first_hipe_ref = NULL;
- modi->first_hipe_sdesc = NULL;
modi->hipe_code = NULL;
#endif
}
@@ -95,8 +93,6 @@ static Module* module_alloc(Module* tmpl)
obj->on_load = 0;
#ifdef HIPE
obj->first_hipe_mfa = NULL;
- obj->new_hipe_refs = NULL;
- obj->new_hipe_sdesc = NULL;
#endif
DBG_TRACE_MFA(make_atom(obj->module), 0, 0, "module_alloc");
return obj;
@@ -214,8 +210,6 @@ static ERTS_INLINE void copy_module(Module* dst_mod, Module* src_mod)
dst_mod->on_load = src_mod->on_load;
#ifdef HIPE
dst_mod->first_hipe_mfa = src_mod->first_hipe_mfa;
- dst_mod->new_hipe_refs = src_mod->new_hipe_refs;
- dst_mod->new_hipe_sdesc = src_mod->new_hipe_sdesc;
#endif
}
diff --git a/erts/emulator/beam/module.h b/erts/emulator/beam/module.h
index c3adaf12fc..9de610ccf7 100644
--- a/erts/emulator/beam/module.h
+++ b/erts/emulator/beam/module.h
@@ -35,8 +35,6 @@ struct erl_module_instance {
int num_breakpoints;
int num_traced_exports;
#ifdef HIPE
- struct hipe_ref* first_hipe_ref; /* all external hipe calls from this module */
- struct hipe_sdesc* first_hipe_sdesc; /* all stack descriptors for this module */
HipeModule *hipe_code;
#endif
};
@@ -51,8 +49,6 @@ typedef struct erl_module {
struct erl_module_instance* on_load;
#ifdef HIPE
struct hipe_mfa_info* first_hipe_mfa;
- struct hipe_ref* new_hipe_refs;
- struct hipe_sdesc* new_hipe_sdesc;
#endif
} Module;
diff --git a/erts/emulator/hipe/hipe_bif0.c b/erts/emulator/hipe/hipe_bif0.c
index 46d4378f21..da895e4e8b 100644
--- a/erts/emulator/hipe/hipe_bif0.c
+++ b/erts/emulator/hipe/hipe_bif0.c
@@ -685,12 +685,17 @@ BIF_RETTYPE hipe_bifs_set_native_address_3(BIF_ALIST_3)
BIF_RET(am_false);
}
-BIF_RETTYPE hipe_bifs_enter_sdesc_1(BIF_ALIST_1)
+BIF_RETTYPE hipe_bifs_enter_sdesc_2(BIF_ALIST_2)
{
struct hipe_sdesc *sdesc;
+ HipeLoaderState* stp;
Module* modp;
int do_commit;
+ stp = get_loader_state(BIF_ARG_2);
+ if (!stp)
+ BIF_ERROR(BIF_P, BADARG);
+
sdesc = hipe_decode_sdesc(BIF_ARG_1, &do_commit);
if (!sdesc) {
fprintf(stderr, "%s: bad sdesc!\r\n", __FUNCTION__);
@@ -707,12 +712,13 @@ BIF_RETTYPE hipe_bifs_enter_sdesc_1(BIF_ALIST_1)
modp = erts_put_active_module(make_atom(sdesc->m_aix));
ASSERT(modp);
if (do_commit) { /* Direct "hipe-patching" of early loaded module */
- sdesc->next_in_modi = modp->curr.first_hipe_sdesc;
- modp->curr.first_hipe_sdesc = sdesc;
+ ASSERT(modp->curr.hipe_code);
+ sdesc->next_in_modi = modp->curr.hipe_code->first_hipe_sdesc;
+ modp->curr.hipe_code->first_hipe_sdesc = sdesc;
}
else { /* Normal module loading/upgrade */
- sdesc->next_in_modi = modp->new_hipe_sdesc;
- modp->new_hipe_sdesc = sdesc;
+ sdesc->next_in_modi = stp->new_hipe_sdesc;
+ stp->new_hipe_sdesc = sdesc;
}
BIF_RET(NIL);
@@ -1491,13 +1497,14 @@ BIF_RETTYPE hipe_bifs_add_ref_2(BIF_ALIST_2)
struct hipe_ref *ref;
Module* modp;
int do_commit;
+ HipeLoaderState* stp;
if (!term_to_mfa(BIF_ARG_1, &callee))
goto badarg;
if (is_not_tuple(BIF_ARG_2))
goto badarg;
tuple = tuple_val(BIF_ARG_2);
- if (tuple[0] != make_arityval(5))
+ if (tuple[0] != make_arityval(6))
goto badarg;
if (!term_to_mfa(tuple[1], &caller))
goto badarg;
@@ -1526,6 +1533,10 @@ BIF_RETTYPE hipe_bifs_add_ref_2(BIF_ALIST_2)
case am_false: do_commit = 0; break;
default: goto badarg;
}
+ stp = get_loader_state(tuple[6]);
+ if (!stp)
+ goto badarg;
+
hipe_mfa_info_table_rwlock();
callee_mfa = hipe_mfa_info_table_put_rwlocked(callee.mod, callee.fun, callee.ari);
@@ -1550,12 +1561,13 @@ BIF_RETTYPE hipe_bifs_add_ref_2(BIF_ALIST_2)
modp = erts_put_active_module(caller.mod);
ASSERT(modp);
if (do_commit) { /* Direct "hipe-patching" of early loaded module */
- ref->next_from_modi = modp->curr.first_hipe_ref;
- modp->curr.first_hipe_ref = ref;
+ ASSERT(modp->curr.hipe_code);
+ ref->next_from_modi = modp->curr.hipe_code->first_hipe_ref;
+ modp->curr.hipe_code->first_hipe_ref = ref;
}
else { /* Normal module loading/upgrade */
- ref->next_from_modi = modp->new_hipe_refs;
- modp->new_hipe_refs = ref;
+ ref->next_from_modi = stp->new_hipe_refs;
+ stp->new_hipe_refs = ref;
}
#if defined(DEBUG)
@@ -1653,9 +1665,12 @@ BIF_RETTYPE hipe_bifs_remove_refs_from_1(BIF_ALIST_1)
int hipe_purge_need_blocking(Module* modp)
{
/* SVERK: Verify if this is really necessary */
- return (modp->old.first_hipe_ref ||
- modp->old.first_hipe_sdesc ||
- (!modp->curr.code_hdr && modp->first_hipe_mfa));
+ if (modp->old.hipe_code) {
+ if (modp->old.hipe_code->first_hipe_ref ||
+ modp->old.hipe_code->first_hipe_sdesc)
+ return 1;
+ }
+ return !modp->curr.code_hdr && modp->first_hipe_mfa;
}
void hipe_purge_module(Module* modp)
@@ -1667,68 +1682,75 @@ void hipe_purge_module(Module* modp)
DBG_TRACE_MFA(make_atom(modp->module), 0, 0, "hipe_purge_module");
- /*
- * Remove all hipe_ref's (external calls) from the old module instance
- */
- ref = modp->old.first_hipe_ref;
-
- while (ref) {
- struct hipe_ref* free_ref = ref;
-
- ERTS_SMP_LC_ASSERT(erts_smp_thr_progress_is_blocking());
-
- DBG_TRACE_MFA(ref->caller_m, ref->caller_f, ref->caller_a, "PURGE ref at %p to %T:%T/%u", ref,
- ref->callee->m, ref->callee->f, ref->callee->a);
- DBG_TRACE_MFA(ref->callee->m, ref->callee->f, ref->callee->a, "PURGE ref at %p from %T:%T/%u", ref,
- ref->caller_m, ref->caller_f, ref->caller_a);
- ASSERT(ref->caller_m == make_atom(modp->module));
-
+ if (modp->old.hipe_code) {
/*
- * Unlink from other refs to same callee
+ * Remove all hipe_ref's (external calls) from the old module instance
*/
- ASSERT(ref->head.next->prev == &ref->head);
- ASSERT(ref->head.prev->next == &ref->head);
- ASSERT(ref->head.next != &ref->head);
- ASSERT(ref->head.prev != &ref->head);
- ref->head.next->prev = ref->head.prev;
- ref->head.prev->next = ref->head.next;
+ ref = modp->old.hipe_code->first_hipe_ref;
+
+ while (ref) {
+ struct hipe_ref* free_ref = ref;
+
+ ERTS_SMP_LC_ASSERT(erts_smp_thr_progress_is_blocking());
+
+ DBG_TRACE_MFA(ref->caller_m, ref->caller_f, ref->caller_a, "PURGE ref at %p to %T:%T/%u", ref,
+ ref->callee->m, ref->callee->f, ref->callee->a);
+ DBG_TRACE_MFA(ref->callee->m, ref->callee->f, ref->callee->a, "PURGE ref at %p from %T:%T/%u", ref,
+ ref->caller_m, ref->caller_f, ref->caller_a);
+ ASSERT(ref->caller_m == make_atom(modp->module));
+
+ /*
+ * Unlink from other refs to same callee
+ */
+ ASSERT(ref->head.next->prev == &ref->head);
+ ASSERT(ref->head.prev->next == &ref->head);
+ ASSERT(ref->head.next != &ref->head);
+ ASSERT(ref->head.prev != &ref->head);
+ ref->head.next->prev = ref->head.prev;
+ ref->head.prev->next = ref->head.next;
+
+ /*
+ * Was this the last ref to that callee?
+ */
+ if (ref->head.next == ref->head.prev) {
+ struct hipe_mfa_info* p = ErtsContainerStruct(ref->head.next, struct hipe_mfa_info, callers);
+ if (p->is_stub) {
+ unlink_mfa_from_mod(p);
+ purge_mfa(p);
+ }
+ }
- /*
- * Was this the last ref to that callee?
- */
- if (ref->head.next == ref->head.prev) {
- struct hipe_mfa_info* p = ErtsContainerStruct(ref->head.next, struct hipe_mfa_info, callers);
- if (p->is_stub) {
- unlink_mfa_from_mod(p);
- purge_mfa(p);
- }
+ ref = ref->next_from_modi;
+ erts_free(ERTS_ALC_T_HIPE, free_ref);
}
+ modp->old.hipe_code->first_hipe_ref = NULL;
- ref = ref->next_from_modi;
- erts_free(ERTS_ALC_T_HIPE, free_ref);
- }
- modp->old.first_hipe_ref = NULL;
+ /*
+ * Remove all hipe_sdesc's for the old module instance
+ */
+ sdesc = modp->old.hipe_code->first_hipe_sdesc;
- /*
- * Remove all hipe_sdesc's for the old module instance
- */
- sdesc = modp->old.first_hipe_sdesc;
+ while (sdesc) {
+ struct hipe_sdesc* free_sdesc = sdesc;
- while (sdesc) {
- struct hipe_sdesc* free_sdesc = sdesc;
+ ERTS_SMP_LC_ASSERT(erts_smp_thr_progress_is_blocking());
- ERTS_SMP_LC_ASSERT(erts_smp_thr_progress_is_blocking());
+ DBG_TRACE_MFA(make_atom(sdesc->m_aix), make_atom(sdesc->f_aix), sdesc->a, "PURGE sdesc at %p", (void*)sdesc->bucket.hvalue);
+ ASSERT(sdesc->m_aix == modp->module);
- DBG_TRACE_MFA(make_atom(sdesc->m_aix), make_atom(sdesc->f_aix), sdesc->a, "PURGE sdesc at %p", (void*)sdesc->bucket.hvalue);
- ASSERT(sdesc->m_aix == modp->module);
+ sdesc = sdesc->next_in_modi;
+ hipe_destruct_sdesc(free_sdesc);
+ }
+ modp->old.hipe_code->first_hipe_sdesc = NULL;
- sdesc = sdesc->next_in_modi;
- hipe_destruct_sdesc(free_sdesc);
+ hipe_free_module(modp->old.hipe_code);
+ modp->old.hipe_code = NULL;
}
- modp->old.first_hipe_sdesc = NULL;
+
/*
- * Remove unreferred hipe_mfa_info's
+ * Remove unreferred hipe_mfa_info's
+ * when all module instances are removed (like in init:restart)
*/
if (modp->curr.code_hdr == NULL) {
struct hipe_mfa_info** prevp = &modp->first_hipe_mfa;
@@ -1743,10 +1765,6 @@ void hipe_purge_module(Module* modp)
prevp = &p->next_in_mod;
}
}
- if (modp->old.hipe_code) {
- hipe_free_module(modp->old.hipe_code);
- modp->old.hipe_code = NULL;
- }
}
diff --git a/erts/emulator/hipe/hipe_bif0.tab b/erts/emulator/hipe/hipe_bif0.tab
index 1e4bde5ef2..8475b8ce76 100644
--- a/erts/emulator/hipe/hipe_bif0.tab
+++ b/erts/emulator/hipe/hipe_bif0.tab
@@ -56,7 +56,7 @@ bif hipe_bifs:set_native_address/3
bif hipe_bifs:set_funinfo_native_address/3
#bif hipe_bifs:invalidate_funinfo_native_addresses/1
-bif hipe_bifs:enter_sdesc/1
+bif hipe_bifs:enter_sdesc/2
bif hipe_bifs:bif_address/3
bif hipe_bifs:primop_address/1
diff --git a/erts/emulator/hipe/hipe_load.c b/erts/emulator/hipe/hipe_load.c
index 5bce3f1aee..cebbbafdd3 100644
--- a/erts/emulator/hipe/hipe_load.c
+++ b/erts/emulator/hipe/hipe_load.c
@@ -79,6 +79,9 @@ Binary *hipe_alloc_loader_state(Eterm module)
stp->data_segment = NULL;
stp->data_segment_size = 0;
+ stp->new_hipe_refs = NULL;
+ stp->new_hipe_sdesc = NULL;
+
return magic;
}
diff --git a/erts/emulator/hipe/hipe_load.h b/erts/emulator/hipe/hipe_load.h
index 9e24e915ed..17dd3c3c05 100644
--- a/erts/emulator/hipe/hipe_load.h
+++ b/erts/emulator/hipe/hipe_load.h
@@ -36,6 +36,9 @@ typedef struct hipe_loader_state {
void *data_segment;
Uint data_segment_size;
+ struct hipe_ref* new_hipe_refs;
+ struct hipe_sdesc* new_hipe_sdesc;
+
} HipeLoaderState;
extern Binary *hipe_alloc_loader_state(Eterm module);
diff --git a/erts/emulator/hipe/hipe_module.h b/erts/emulator/hipe/hipe_module.h
index 1e1302fc0a..b489f567cb 100644
--- a/erts/emulator/hipe/hipe_module.h
+++ b/erts/emulator/hipe/hipe_module.h
@@ -35,6 +35,9 @@ struct hipe_module {
void *text_segment;
Uint text_segment_size;
void *data_segment;
+
+ struct hipe_ref* first_hipe_ref; /* all external hipe calls from this module */
+ struct hipe_sdesc* first_hipe_sdesc; /* all stack descriptors for this module */
};
extern void hipe_free_module(HipeModule *mod);