Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: erlang/otp
base: maint
...
head fork: sverker/otp
Checking mergeability… Don’t worry, you can still create the pull request.
  • 8 commits
  • 32 files changed
  • 0 commit comments
  • 1 contributor
Showing with 822 additions and 118 deletions.
  1. +56 −3 erts/emulator/beam/beam_bif_load.c
  2. +1 −1  erts/emulator/beam/beam_load.c
  3. +3 −1 erts/emulator/beam/erl_alloc.c
  4. +23 −0 erts/emulator/beam/erl_bif_info.c
  5. +4 −3 erts/emulator/beam/erl_db_util.c
  6. +33 −0 erts/emulator/beam/erl_fun.c
  7. +2 −0  erts/emulator/beam/erl_fun.h
  8. +190 −3 erts/emulator/beam/erl_gc.c
  9. +4 −3 erts/emulator/beam/erl_message.c
  10. +5 −0 erts/emulator/beam/erl_process.c
  11. +6 −0 erts/emulator/beam/erl_process.h
  12. +4 −0 erts/emulator/beam/module.c
  13. +4 −0 erts/emulator/beam/module.h
  14. +1 −0  erts/emulator/beam/sys.h
  15. +60 −0 erts/emulator/hipe/hipe_amd64.c
  16. +16 −4 erts/emulator/hipe/hipe_amd64_bifs.m4
  17. +198 −83 erts/emulator/hipe/hipe_bif0.c
  18. +9 −0 erts/emulator/hipe/hipe_bif0.h
  19. +3 −2 erts/emulator/hipe/hipe_bif0.tab
  20. +17 −6 erts/emulator/hipe/hipe_bif2.c
  21. +48 −0 erts/emulator/hipe/hipe_gc.c
  22. +12 −3 erts/emulator/hipe/hipe_mkliterals.c
  23. +13 −0 erts/emulator/hipe/hipe_mode_switch.c
  24. +3 −0  erts/emulator/hipe/hipe_process.h
  25. +2 −0  erts/emulator/test/code_SUITE.erl
  26. +7 −2 lib/hipe/rtl/Makefile
  27. +2 −2 lib/hipe/rtl/hipe_tagscheme.erl
  28. +1 −0  lib/kernel/src/code_server.erl
  29. +22 −2 lib/kernel/src/hipe_unified_loader.erl
  30. +17 −0 sverk.erl
  31. +45 −0 sverk_hipe.erl
  32. +11 −0 sverk_hipe2.erl
View
59 erts/emulator/beam/beam_bif_load.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1999-2010. All Rights Reserved.
+ * Copyright Ericsson AB 1999-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -34,6 +34,8 @@
#include "erl_binary.h"
#include "erl_nif.h"
+#include "hipe_bif0.h" // SVERK
+
static void set_default_trace_pattern(Eterm module);
static Eterm check_process_code(Process* rp, Module* modp);
static void delete_code(Process *c_p, ErtsProcLocks c_p_locks, Module* modp);
@@ -142,7 +144,7 @@ BIF_RETTYPE code_is_module_native_1(BIF_ALIST_1)
if ((modp = erts_get_module(BIF_ARG_1)) == NULL) {
return am_undefined;
}
- return (is_native(modp->code) ||
+ return ((modp->code && is_native(modp->code)) ||
(modp->old_code != 0 && is_native(modp->old_code))) ?
am_true : am_false;
}
@@ -180,6 +182,9 @@ check_process_code_2(BIF_ALIST_2)
if (!rp) {
BIF_RET(am_false);
}
+ if (rp->id == 755 && ERTS_IS_ATOM_STR("qlc_pt", BIF_ARG_2)) {
+ sverk_break();
+ }
if (rp == ERTS_PROC_LOCK_BUSY) {
ERTS_BIF_YIELD2(bif_export[BIF_check_process_code_2], BIF_P,
BIF_ARG_1, BIF_ARG_2);
@@ -227,6 +232,10 @@ BIF_RETTYPE delete_module_1(BIF_ALIST_1)
else {
delete_export_references(BIF_ARG_1);
delete_code(BIF_P, 0, modp);
+ {
+ extern void hipe_delete_code(Process*,Eterm mod); // SVERK
+ hipe_delete_code(BIF_P, BIF_ARG_1);
+ }
res = am_true;
}
}
@@ -409,6 +418,9 @@ check_process_code(Process* rp, Module* modp)
if (modp == NULL) { /* Doesn't exist. */
return am_false;
} else if (modp->old_code == NULL) { /* No old code. */
+#ifdef HIPE
+ ASSERT(modp->old_hipe_code == NULL);
+#endif
return am_false;
}
@@ -463,6 +475,18 @@ check_process_code(Process* rp, Module* modp)
}
}
+#ifdef HIPE
+ /*
+ * Check all return addresses on native stack
+ */
+ if (modp->old_hipe_code && rp->hipe.nstack) {
+ extern int check_nstack_process_code(Process*, Module*); // SVERK
+
+ if (check_nstack_process_code(rp, modp))
+ return am_true;
+ }
+#endif
+
/*
* See if there are funs that refer to the old version of the module.
*/
@@ -473,10 +497,18 @@ check_process_code(Process* rp, Module* modp)
if (thing_subtag(oh->thing_word) == FUN_SUBTAG) {
ErlFunThing* funp = (ErlFunThing*) oh;
BeamInstr* fun_code;
+ #ifdef HIPE
+ extern int hipe_is_old_code(void*, Module*); // SVERK
+ #endif
fun_code = funp->fe->address;
- if (INSIDE((BeamInstr *) funp->fe->address)) {
+ if (INSIDE((BeamInstr *) funp->fe->address)
+# ifdef HIPE
+ || hipe_is_old_code(funp->fe->native_address, modp)
+# endif
+ ) {
+
if (done_gc) {
return am_true;
} else {
@@ -662,6 +694,23 @@ purge_module(int module)
modp->old_code_length = 0;
modp->old_catches = BEAM_CATCHES_NIL;
remove_from_address_table(code);
+
+#ifdef HIPE
+ /*
+ * Remove hipe code
+ */
+ {
+ struct hipe_code_header* ch;
+
+ for (ch = modp->old_hipe_code; ch; ch = ch->next) {
+ // SVERK: Fill with bad code
+ fprintf(stderr, "SVERK: Kill hipe code at %p -> %p\r\n",
+ &ch->code, (char*)&ch->code + ch->code_size);
+ sys_memset(&ch->code, 0xff, ch->code_size);
+ //hipe_flush_icache_range(&ch->code, ch->code_size);
+ }
+ }
+#endif
return 0;
}
@@ -722,6 +771,10 @@ delete_code(Process *c_p, ErtsProcLocks c_p_locks, Module* modp)
modp->code_length = 0;
modp->catches = BEAM_CATCHES_NIL;
modp->nif = NULL;
+#ifdef HIPE
+ modp->old_hipe_code = modp->hipe_code;
+ modp->hipe_code = NULL;
+#endif
}
View
2  erts/emulator/beam/beam_load.c
@@ -3948,7 +3948,7 @@ final_touch(LoaderState* stp)
/*
* We are hiding a pointer into older code.
*/
- erts_refc_dec(&fe->refc, 1);
+ erts_refc_dec(&fe->refc, 1);
}
fe->address = code_ptr;
#ifdef HIPE
View
4 erts/emulator/beam/erl_alloc.c
@@ -3306,7 +3306,9 @@ debug_free(ErtsAlcType_t n, void *extra, void *ptr)
dptr = check_memory_fence(ptr, &size, n, ERTS_ALC_O_FREE);
- sys_memset((void *) dptr, n, size + FENCE_SZ);
+ if ((n & 255) != 0x94) { // SVERK
+ sys_memset((void *) dptr, n, size + FENCE_SZ);
+ }
(*real_af->free)(n, real_af->extra, dptr);
View
23 erts/emulator/beam/erl_bif_info.c
@@ -3127,12 +3127,35 @@ BIF_RETTYPE error_logger_warning_map_0(BIF_ALIST_0)
static erts_smp_atomic_t available_internal_state;
+void sverk_break(void)
+{
+ fprintf(stderr, "sverk_break_fun %lu\r\n", (long)pthread_self());
+}
+
BIF_RETTYPE erts_debug_get_internal_state_1(BIF_ALIST_1)
{
/*
* NOTE: Only supposed to be used for testing, and debugging.
*/
+ Eterm sverk = BIF_ARG_1, sverk_tail;
+ if (is_list(BIF_ARG_1)) {
+ sverk = CAR(list_val(BIF_ARG_1));
+ sverk_tail = CDR(list_val(BIF_ARG_1));
+ }
+ if (ERTS_IS_ATOM_STR("heap_consistency_check", sverk)) {
+ extern void heap_consistency_check(Process*);
+ if (is_list(BIF_ARG_1)) {
+ erts_fprintf(stderr, "SVERK: %T\r\n", BIF_ARG_1);
+ }
+ heap_consistency_check(BIF_P);
+ if (is_list(BIF_ARG_1) && is_list(sverk_tail)
+ && ERTS_IS_ATOM_STR("break",CAR(list_val(sverk_tail)))) {
+ erts_fprintf(stderr, "SVERK: calling break point\r\n");
+ sverk_break();
+ }
+ BIF_RET(am_ok);
+ }
if (!erts_smp_atomic_read(&available_internal_state)) {
BIF_ERROR(BIF_P, EXC_UNDEF);
}
View
7 erts/emulator/beam/erl_db_util.c
@@ -3017,9 +3017,10 @@ void db_cleanup_offheap_comp(DbTerm* obj)
break;
case FUN_SUBTAG:
ASSERT(u.pb != &tmp);
- if (erts_refc_dectest(&u.fun->fe->refc, 0) == 0) {
- erts_erase_fun_entry(u.fun->fe);
- }
+ erts_deref_fun_entry(u.fun->fe, "ETS", u.fun);
+// if (erts_refc_dectest(&u.fun->fe->refc, 0) == 0) {
+// erts_erase_fun_entry(u.fun->fe);
+// }
break;
default:
ASSERT(is_external_header(u.hdr->thing_word));
View
33 erts/emulator/beam/erl_fun.c
@@ -92,6 +92,12 @@ int erts_fun_table_sz(void)
return sz;
}
+#ifdef DEBUG
+# define SVERK_HVAL 108140978
+#else
+# define SVERK_HVAL 108140980
+#endif
+
ErlFunEntry*
erts_put_fun_entry(Eterm mod, int uniq, int index)
{
@@ -104,6 +110,9 @@ erts_put_fun_entry(Eterm mod, int uniq, int index)
template.module = mod;
erts_fun_write_lock();
fe = (ErlFunEntry *) hash_put(&erts_fun_table, (void*) &template);
+ if (fe->bucket.hvalue == SVERK_HVAL) {
+ sverk_break();
+ }
sys_memset(fe->uniq, 0, sizeof(fe->uniq));
fe->index = 0;
refc = erts_refc_inctest(&fe->refc, 0);
@@ -127,6 +136,9 @@ erts_put_fun_entry2(Eterm mod, int old_uniq, int old_index,
template.module = mod;
erts_fun_write_lock();
fe = (ErlFunEntry *) hash_put(&erts_fun_table, (void*) &template);
+ if (fe->bucket.hvalue == SVERK_HVAL) {
+ sverk_break();
+ }
sys_memcpy(fe->uniq, uniq, sizeof(fe->uniq));
fe->index = index;
fe->arity = arity;
@@ -172,6 +184,24 @@ erts_erase_fun_entry_unlocked(ErlFunEntry* fe)
}
void
+erts_deref_fun_entry(ErlFunEntry* fe, const char* text, void* owner)
+{
+ erts_aint_t c;
+ if ((c=erts_refc_dectest(&fe->refc, 0)) == 0) {
+ if (fe->bucket.hvalue == SVERK_HVAL) {
+ fprintf(stderr, "%lu: FunEntry @ %p: FREE (%s %p)\r\n",
+ (long)pthread_self(), fe, text, owner);
+ //abort();
+ }
+ erts_erase_fun_entry(fe);
+ }
+ else if (fe->bucket.hvalue == SVERK_HVAL) {
+ fprintf(stderr, "%lu: FunEntry @ %p: dec to %li (%s %p)\r\n",
+ (long)pthread_self(), fe, (long)c, text, owner);
+ }
+}
+
+void
erts_erase_fun_entry(ErlFunEntry* fe)
{
erts_fun_write_lock();
@@ -214,7 +244,9 @@ erts_cleanup_funs_on_purge(BeamInstr* start, BeamInstr* end)
if (start <= addr && addr < end) {
fe->address = unloaded_fun;
+ fe->sverk_was_unloaded = 1;
if (erts_refc_dectest(&fe->refc, 0) == 0) {
+ fe->sverk_was_unloaded = 2;
fe->address = (void *) to_delete;
to_delete = fe;
}
@@ -293,6 +325,7 @@ fun_alloc(ErlFunEntry* template)
#ifdef HIPE
obj->native_address = NULL;
#endif
+ obj->sverk_was_unloaded = 0;
return obj;
}
View
2  erts/emulator/beam/erl_fun.h
@@ -43,6 +43,7 @@ typedef struct erl_fun_entry {
Eterm module; /* Tagged atom for module. */
erts_refc_t refc; /* Reference count: One for code + one for each
fun object in each process. */
+ int sverk_was_unloaded;
} ErlFunEntry;
/*
@@ -82,6 +83,7 @@ ErlFunEntry* erts_put_fun_entry2(Eterm mod, int old_uniq, int old_index,
ErlFunEntry* erts_get_fun_entry2(Eterm mod, int old_uniq, int old_index,
byte* uniq, int index, int arity);
+void erts_deref_fun_entry(ErlFunEntry* fe, const char* text, void* owner);
void erts_erase_fun_entry(ErlFunEntry* fe);
#ifndef HYBRID /* FIND ME! */
void erts_cleanup_funs(ErlFunThing* funp);
View
193 erts/emulator/beam/erl_gc.c
@@ -36,6 +36,9 @@
#include "hipe_mode_switch.h"
#endif
+void heap_consistency_check(Process* p); // SVERK
+void heap_consistency_check_incr(Process* p);
+
#define ERTS_INACT_WR_PB_LEAVE_MUCH_LIMIT 1
#define ERTS_INACT_WR_PB_LEAVE_MUCH_PERCENTAGE 20
#define ERTS_INACT_WR_PB_LEAVE_LIMIT 10
@@ -345,6 +348,8 @@ erts_garbage_collect(Process* p, int need, Eterm* objv, int nobj)
int done = 0;
Uint ms1, s1, us1;
+ heap_consistency_check(p); // SVERK
+
if (IS_TRACED_FL(p, F_TRACE_GC)) {
trace_gc(p, am_gc_start);
}
@@ -2152,9 +2157,10 @@ sweep_off_heap(Process *p, int fullsweep)
case FUN_SUBTAG:
{
ErlFunEntry* fe = ((ErlFunThing*)ptr)->fe;
- if (erts_refc_dectest(&fe->refc, 0) == 0) {
- erts_erase_fun_entry(fe);
- }
+ erts_deref_fun_entry(fe, "GC", ptr);
+// if (erts_refc_dectest(&fe->refc, 0) == 0) {
+// erts_erase_fun_entry(fe);
+// }
break;
}
default:
@@ -2519,3 +2525,184 @@ erts_check_off_heap(Process *p)
}
#endif
+
+//#ifdef DEBUG
+static void heap_consistency_check_fail(Process* p, Eterm term)
+{
+#ifdef INCREMENTAL_HEAP_CONSISTENCY_CHECK
+ if (p->last_check_htop || p->last_check_old_htop) {
+ erts_fprintf(stderr, "SVERK: heap_consistency_check_incr FAILED, trying full check...");
+ heap_consistency_check(p);
+ erts_fprintf(stderr, "OK\r\n");
+ return;
+ }
+#endif
+ erts_fprintf(stderr, "heap_consistency_check FAILED(%u): %T\r\n",
+ (int)getpid() + (int)pthread_self(), term);
+ abort();
+}
+
+
+static int heap_consistency_check_ptr_old(Process* p, Eterm* ptr, Eterm term)
+{
+ unsigned i;
+ if (in_area(ptr, p->old_heap, (p->old_htop - p->old_heap)*sizeof(Eterm))) {
+ return 1;
+ }
+
+ for (i = 0; i < module_code_size(); i++) {
+ Module* mod = module_code(i);
+ if (mod != NULL) {
+ Eterm* literals;
+ Uint lit_sz;
+
+ if (mod->code_length != 0) {
+ literals = (Eterm *) mod->code[MI_LITERALS_START];
+ lit_sz = (Eterm *) mod->code[MI_LITERALS_END] - literals;
+ if (in_area(ptr, literals, lit_sz*sizeof(Eterm))) return 1;
+ }
+ if (mod->old_code_length != 0) {
+ literals = (Eterm *) mod->old_code[MI_LITERALS_START];
+ lit_sz = (Eterm *) mod->old_code[MI_LITERALS_END] - literals;
+ if (in_area(ptr, literals, lit_sz*sizeof(Eterm))) return 1;
+ }
+ }
+ }
+#ifdef HIPE
+ {
+ extern int hipe_is_constant(Eterm*); /* hipe_bif0.c */
+ if (hipe_is_constant(ptr)) {
+ return 1;
+ }
+ }
+#endif
+ heap_consistency_check_fail(p, term);
+ return 0;
+}
+
+static int heap_consistency_check_ptr_new(Process* p, Eterm* ptr, Eterm term)
+{
+ if (in_area(ptr, p->heap, (p->htop - p->heap)*sizeof(Eterm))) {
+ return 1;
+ }
+ return heap_consistency_check_ptr_old(p, ptr, term);
+}
+
+void heap_consistency_check(Process* p)
+{
+#ifdef INCREMENTAL_HEAP_CONSISTENCY_CHECK
+ p->last_check_htop = NULL;
+ p->last_check_old_htop = NULL;
+#endif
+ heap_consistency_check_incr(p);
+}
+
+void heap_consistency_check_incr(Process* p)
+{
+ Eterm* hp;
+ Eterm* htop;
+ const unsigned hist_len = 16;
+ Eterm* hp_hist[hist_len];
+ unsigned ix = 0;
+
+ ErtsGcQuickSanityCheck(p);
+
+ /* New heap */
+ htop = p->htop;
+#ifdef INCREMENTAL_HEAP_CONSISTENCY_CHECK
+ hp = p->last_check_htop;
+ if (!in_area(hp, p->heap, (p->htop - p->heap)*sizeof(Eterm) + 1)) {
+ hp = p->heap;
+ p->last_check_htop = NULL;
+ }
+#else
+ hp = p->heap;
+#endif
+
+ while (hp < htop) {
+ Eterm* ptr;
+ Eterm val;
+
+ hp_hist[(ix++) % hist_len] = hp;
+ val = *hp;
+ switch (primary_tag(val)) {
+ case TAG_PRIMARY_BOXED:
+ ptr = boxed_val(val);
+ if (!heap_consistency_check_ptr_new(p, ptr, val)) return;
+ hp++;
+ break;
+ case TAG_PRIMARY_LIST:
+ ptr = list_val(val);
+ if (!heap_consistency_check_ptr_new(p, ptr, val)) return;
+ hp++;
+ break;
+ case TAG_PRIMARY_HEADER:
+ if (header_is_thing(val)) {
+ Eterm* next_hp = hp + 1 + thing_arityval(val);
+ if (next_hp > htop) {
+ heap_consistency_check_fail(p, am_atom_put("thingy_new",10));
+ return;
+ }
+ hp = next_hp;
+ }
+ else hp++;
+ break;
+ default:
+ hp++;
+ }
+ }
+ ASSERT(hp == htop);
+
+ /* Old heap */
+ htop = p->old_htop;
+#ifdef INCREMENTAL_HEAP_CONSISTENCY_CHECK
+ hp = p->last_check_old_htop;
+ if (!in_area(hp, p->old_heap, (p->old_htop - p->old_heap)*sizeof(Eterm) + 1)) {
+ hp = p->old_heap;
+ p->last_check_old_htop = NULL;
+ }
+#else
+ hp = p->old_heap;
+#endif
+
+ ix = 0;
+ while (hp < htop) {
+ Eterm* ptr;
+ Eterm val;
+
+ hp_hist[(ix++) % hist_len] = hp;
+ val = *hp;
+ switch (primary_tag(val)) {
+ case TAG_PRIMARY_BOXED:
+ ptr = boxed_val(val);
+ if (!heap_consistency_check_ptr_old(p, ptr, val)) return;
+ hp++;
+ break;
+ case TAG_PRIMARY_LIST:
+ ptr = list_val(val);
+ if (!heap_consistency_check_ptr_old(p, ptr, val)) return;
+ hp++;
+ break;
+ case TAG_PRIMARY_HEADER:
+ if (header_is_thing(val)) {
+ Eterm* next_hp = hp + 1 + thing_arityval(val);
+ if (next_hp > htop) {
+ heap_consistency_check_fail(p, am_atom_put("thingy_old",10));
+ return;
+ }
+ hp = next_hp;
+ }
+ else hp++;
+ break;
+ default:
+ hp++;
+ }
+ }
+ ASSERT(hp == htop);
+
+#ifdef INCREMENTAL_HEAP_CONSISTENCY_CHECK
+ p->last_check_htop = p->htop;
+ p->last_check_old_htop = p->old_htop;
+#endif
+}
+//#endif /* DEBUG */
View
7 erts/emulator/beam/erl_message.c
@@ -175,9 +175,10 @@ erts_cleanup_offheap(ErlOffHeap *offheap)
}
break;
case FUN_SUBTAG:
- if (erts_refc_dectest(&u.fun->fe->refc, 0) == 0) {
- erts_erase_fun_entry(u.fun->fe);
- }
+ erts_deref_fun_entry(u.fun->fe, "MSG", u.fun);
+// if (erts_refc_dectest(&u.fun->fe->refc, 0) == 0) {
+// erts_erase_fun_entry(u.fun->fe);
+// }
break;
default:
ASSERT(is_external_header(u.hdr->thing_word));
View
5 erts/emulator/beam/erl_process.c
@@ -6255,6 +6255,11 @@ erl_create_process(Process* parent, /* Parent of process (default group leader).
p->fp_exception = 0;
#endif
+#ifdef INCREMENTAL_HEAP_CONSISTENCY_CHECK
+ p->last_check_htop = NULL;
+ p->last_check_old_htop = NULL;
+#endif
+
/*
* Schedule process for execution.
*/
View
6 erts/emulator/beam/erl_process.h
@@ -1,3 +1,4 @@
+#define INCREMENTAL_HEAP_CONSISTENCY_CHECK // SVERK
/*
* %CopyrightBegin%
*
@@ -737,6 +738,11 @@ struct process {
Uint space_verified; /* Avoid HAlloc forcing heap fragments when */
Eterm* space_verified_from; /* we rely on available heap space (TestHeap) */
#endif
+
+#ifdef INCREMENTAL_HEAP_CONSISTENCY_CHECK
+ Eterm* last_check_htop;
+ Eterm* last_check_old_htop;
+#endif
};
#ifdef CHECK_FOR_HOLES
View
4 erts/emulator/beam/module.c
@@ -68,6 +68,10 @@ static Module* module_alloc(Module* tmpl)
obj->slot.index = -1;
obj->nif = NULL;
obj->old_nif = NULL;
+#ifdef HIPE
+ obj->hipe_code = NULL;
+ obj->old_hipe_code = NULL;
+#endif
return obj;
}
View
4 erts/emulator/beam/module.h
@@ -36,6 +36,10 @@ typedef struct erl_module {
unsigned catches, old_catches;
struct erl_module_nif* nif;
struct erl_module_nif* old_nif;
+#ifdef HIPE
+ struct hipe_code_header* hipe_code;
+ struct hipe_code_header* old_hipe_code;
+#endif
} Module;
Module* erts_get_module(Eterm mod);
View
1  erts/emulator/beam/sys.h
@@ -1,3 +1,4 @@
+#define ERTS_REFC_DEBUG // SVERK
/*
* %CopyrightBegin%
*
View
60 erts/emulator/hipe/hipe_amd64.c
@@ -374,3 +374,63 @@ BIF_RETTYPE hipe_bifs_write_u64_2(BIF_ALIST_2)
hipe_flush_icache_word(address);
BIF_RET(NIL);
}
+
+#if defined(ERTS_ENABLE_LOCK_CHECK) && defined(ERTS_SMP)
+
+BIF_RETTYPE hipe_debug_bif_wrapper_1(BIF_ALIST_1);
+BIF_RETTYPE hipe_debug_bif_wrapper_2(BIF_ALIST_2);
+BIF_RETTYPE hipe_debug_bif_wrapper_3(BIF_ALIST_3);
+
+# define ERTS_SMP_REQ_PROC_MAIN_LOCK(P) \
+ if ((P)) erts_proc_lc_require_lock((P), ERTS_PROC_LOCK_MAIN)
+# define ERTS_SMP_UNREQ_PROC_MAIN_LOCK(P) \
+ if ((P)) erts_proc_lc_unrequire_lock((P), ERTS_PROC_LOCK_MAIN)
+
+# ifdef HARD_DEBUG
+void heap_consistency_check_incr(Process* p);
+# define HEAP_CHECK(P) heap_consistency_check_incr(P)
+# else
+# define HEAP_CHECK(P)
+# endif
+
+BIF_RETTYPE hipe_debug_bif_wrapper_1(BIF_ALIST_1)
+{
+ typedef BIF_RETTYPE Bif1(Process*, Eterm);
+ Bif1* fp = (Bif1*)BIF_P->hipe.bif_callee;
+ BIF_RETTYPE res;
+ HEAP_CHECK(BIF_P);
+ ERTS_SMP_UNREQ_PROC_MAIN_LOCK(BIF_P);
+ res = (*fp)(BIF_P, BIF_ARG_1);
+ ERTS_SMP_REQ_PROC_MAIN_LOCK(BIF_P);
+ HEAP_CHECK(BIF_P);
+ return res;
+}
+
+BIF_RETTYPE hipe_debug_bif_wrapper_2(BIF_ALIST_2)
+{
+ typedef BIF_RETTYPE Bif2(Process*, Eterm, Eterm);
+ Bif2* fp = (Bif2*) BIF_P->hipe.bif_callee;
+ BIF_RETTYPE res;
+ HEAP_CHECK(BIF_P);
+ ERTS_SMP_UNREQ_PROC_MAIN_LOCK(BIF_P);
+ res = (*fp)(BIF_P, BIF_ARG_1, BIF_ARG_2);
+ ERTS_SMP_REQ_PROC_MAIN_LOCK(BIF_P);
+ HEAP_CHECK(BIF_P);
+ return res;
+}
+
+BIF_RETTYPE hipe_debug_bif_wrapper_3(BIF_ALIST_3)
+{
+ typedef BIF_RETTYPE Bif3(Process*, Eterm, Eterm, Eterm);
+ Bif3* fp = (Bif3*)BIF_P->hipe.bif_callee;
+ BIF_RETTYPE res;
+ HEAP_CHECK(BIF_P);
+ ERTS_SMP_UNREQ_PROC_MAIN_LOCK(BIF_P);
+ res = (*fp)(BIF_P, BIF_ARG_1, BIF_ARG_2, BIF_ARG_3);
+ ERTS_SMP_REQ_PROC_MAIN_LOCK(BIF_P);
+ HEAP_CHECK(BIF_P);
+ return res;
+}
+
+#endif /* ERTS_ENABLE_LOCK_CHECK && ERTS_SMP */
+
View
20 erts/emulator/hipe/hipe_amd64_bifs.m4
@@ -30,7 +30,19 @@ include(`hipe/hipe_amd64_asm.m4')
#define TEST_GOT_EXN cmpq $THE_NON_VALUE, %rax
#endif'
-`#define TEST_GOT_MBUF movq P_MBUF(P), %rdx; testq %rdx, %rdx; jnz 3f; 2:
+`#if defined(DEBUG) && defined(USE_THREADS) && !defined(ERTS_ENABLE_LOCK_CHECK)
+# define ERTS_ENABLE_LOCK_CHECK
+#endif
+#if defined(ERTS_ENABLE_LOCK_CHECK) && defined(ERTS_SMP)
+# define CALL_BIF_1(F) movq $F, P_BIF_CALLEE(P); call CSYM(hipe_debug_bif_wrapper_1)
+# define CALL_BIF_2(F) movq $F, P_BIF_CALLEE(P); call CSYM(hipe_debug_bif_wrapper_2)
+# define CALL_BIF_3(F) movq $F, P_BIF_CALLEE(P); call CSYM(hipe_debug_bif_wrapper_3)
+#else
+# define CALL_BIF_1(F) call CSYM(F)
+# define CALL_BIF_2(F) call CSYM(F)
+# define CALL_BIF_3(F) call CSYM(F)
+#endif
+#define TEST_GOT_MBUF movq P_MBUF(P), %rdx; testq %rdx, %rdx; jnz 3f; 2:
#define JOIN3(A,B,C) A##B##C
#define HANDLE_GOT_MBUF(ARITY) 3: call JOIN3(nbif_,ARITY,_gc_after_bif); jmp 2b'
@@ -56,7 +68,7 @@ ASYM($1):
/* make the call on the C stack */
SWITCH_ERLANG_TO_C
- call CSYM($2)
+ CALL_BIF_1($2)
TEST_GOT_MBUF
SWITCH_C_TO_ERLANG
@@ -84,7 +96,7 @@ ASYM($1):
/* make the call on the C stack */
SWITCH_ERLANG_TO_C
- call CSYM($2)
+ CALL_BIF_2($2)
TEST_GOT_MBUF
SWITCH_C_TO_ERLANG
@@ -113,7 +125,7 @@ ASYM($1):
/* make the call on the C stack */
SWITCH_ERLANG_TO_C
- call CSYM($2)
+ CALL_BIF_3($2)
TEST_GOT_MBUF
SWITCH_C_TO_ERLANG
View
281 erts/emulator/hipe/hipe_bif0.c
@@ -292,7 +292,7 @@ BIF_RETTYPE hipe_bifs_bitarray_sub_2(BIF_ALIST_2)
* BIFs for SML-like mutable arrays and reference cells.
* For now, limited to containing immediate data.
*/
-#if 1 /* use bignums as carriers, easier on the gc */
+#if 1
#define make_array_header(sz) make_pos_bignum_header((sz))
#define array_header_arity(h) header_arity((h))
#define make_array(hp) make_big((hp))
@@ -389,37 +389,46 @@ BIF_RETTYPE hipe_bifs_ref_set_2(BIF_ALIST_2)
BIF_RET(BIF_ARG_1);
}
+
/*
* Allocate memory and copy machine code to it.
*/
BIF_RETTYPE hipe_bifs_enter_code_2(BIF_ALIST_2)
{
- Uint nrbytes;
+ Uint code_size;
+ Uint tot_size;
void *bytes;
void *address;
Uint bitoffs;
Uint bitsize;
Eterm trampolines;
Eterm *hp;
+ struct hipe_code_header* hdr;
if (is_not_binary(BIF_ARG_1))
BIF_ERROR(BIF_P, BADARG);
- nrbytes = binary_size(BIF_ARG_1);
+ code_size = binary_size(BIF_ARG_1);
ERTS_GET_BINARY_BYTES(BIF_ARG_1, bytes, bitoffs, bitsize);
ASSERT(bitoffs == 0);
ASSERT(bitsize == 0);
trampolines = NIL;
+ tot_size = code_size + offsetof(struct hipe_code_header, code);
#ifdef HIPE_ALLOC_CODE
- address = HIPE_ALLOC_CODE(nrbytes, BIF_ARG_2, &trampolines, BIF_P);
- if (!address)
+ hdr = (struct hipe_code_header*) HIPE_ALLOC_CODE(tot_size, BIF_ARG_2,
+ &trampolines, BIF_P);
+ if (!hdr)
BIF_ERROR(BIF_P, BADARG);
#else
if (is_not_nil(BIF_ARG_2))
BIF_ERROR(BIF_P, BADARG);
- address = erts_alloc(ERTS_ALC_T_HIPE, nrbytes);
+ hdr = (struct hipe_code_header*) erts_alloc(ERTS_ALC_T_HIPE, tot_size);
#endif
- memcpy(address, bytes, nrbytes);
- hipe_flush_icache_range(address, nrbytes);
+ fprintf(stderr, "SVERK: ALLOC native code at %p -> %p\r\n", hdr, (char*)hdr + tot_size);
+ hdr->next = NULL; /* set later in add_native_code */
+ hdr->code_size = code_size;
+ address = &hdr->code;
+ memcpy(address, bytes, code_size);
+ hipe_flush_icache_range(hdr, tot_size);
hp = HAlloc(BIF_P, 3);
hp[0] = make_arityval(2);
hp[1] = address_to_term(address, BIF_P);
@@ -505,6 +514,9 @@ BIF_RETTYPE hipe_bifs_constants_size_0(BIF_ALIST_0)
*/
struct const_term {
HashBucket bucket;
+//#ifdef DEBUG
+ Eterm* mem_end;
+//#endif
Eterm val; /* tagged pointer to mem[0] */
Eterm mem[1]; /* variable size */
};
@@ -534,6 +546,9 @@ static void *const_term_alloc(void *tmpl)
size = size_object(obj);
p = (struct const_term*)constants_alloc(size + (offsetof(struct const_term, mem)/sizeof(Eterm)));
+//#ifdef DEBUG
+ p->mem_end = p->mem + size;
+//#endif
/* I have absolutely no idea if having a private 'off_heap'
works or not. _Some_ off_heap object is required for
@@ -573,6 +588,38 @@ BIF_RETTYPE hipe_bifs_merge_term_1(BIF_ALIST_1)
BIF_RET(val);
}
+//#ifdef DEBUG
+struct hipe_is_constant_iter
+{
+ Eterm* termp;
+ int was_found;
+};
+
+static void hipe_is_constant_callback(void* bucket, void* arg)
+{
+ struct const_term* ct = (struct const_term*)bucket;
+ struct hipe_is_constant_iter* iter = (struct hipe_is_constant_iter*)arg;
+ if (ct->mem <= iter->termp && iter->termp < ct->mem_end) {
+ iter->was_found = 1;
+ }
+}
+
+int hipe_is_constant(Eterm* termp)
+{
+ int is1, is2;
+ struct hipe_is_constant_iter iter;
+ iter.termp = termp;
+ iter.was_found = 0;
+ hash_foreach(&const_term_table, hipe_is_constant_callback, &iter);
+ is1 = iter.was_found;
+
+ is2 = (hipe_constants_start <= termp && termp < hipe_constants_next);
+ ASSERT(is1 == is2);
+
+ return is1;
+}
+//#endif /* DEBUG */
+
struct mfa {
Eterm mod;
Eterm fun;
@@ -1140,8 +1187,9 @@ BIF_RETTYPE hipe_bifs_make_fe_3(BIF_ALIST_3)
BIF_ERROR(BIF_P, BADARG);
}
fe->native_address = native_address;
- if (erts_refc_dectest(&fe->refc, 0) == 0)
- erts_erase_fun_entry(fe);
+ erts_deref_fun_entry(fe, "HIPE", NULL);
+// if (erts_refc_dectest(&fe->refc, 0) == 0)
+// erts_erase_fun_entry(fe);
BIF_RET(address_to_term((void *)fe, BIF_P));
}
@@ -1849,8 +1897,10 @@ BIF_RETTYPE hipe_bifs_check_crc_1(BIF_ALIST_1)
if (!term_to_Uint(BIF_ARG_1, &crc))
BIF_ERROR(BIF_P, BADARG);
+
if (crc == HIPE_SYSTEM_CRC)
BIF_RET(am_true);
+
BIF_RET(am_false);
}
@@ -1861,6 +1911,7 @@ BIF_RETTYPE hipe_bifs_system_crc_1(BIF_ALIST_1)
if (!term_to_Uint(BIF_ARG_1, &crc))
BIF_ERROR(BIF_P, BADARG);
crc ^= (HIPE_SYSTEM_CRC ^ HIPE_LITERALS_CRC);
+
BIF_RET(Uint_to_term(crc, BIF_P));
}
@@ -1896,85 +1947,111 @@ void hipe_patch_address(Uint *address, Eterm patchtype, Uint value)
}
}
-struct modinfo {
- HashBucket bucket; /* bucket.hvalue == atom_val(the module name) */
- unsigned int code_size;
-};
-
-static Hash modinfo_table;
-
-static HashValue modinfo_hash(void *tmpl)
-{
- Eterm mod = (Eterm)tmpl;
- return atom_val(mod);
-}
-
-static int modinfo_cmp(void *tmpl, void *bucket)
-{
- /* bucket->hvalue == modinfo_hash(tmpl), so just return 0 (match) */
- return 0;
-}
-
-static void *modinfo_alloc(void *tmpl)
-{
- struct modinfo *p;
-
- p = (struct modinfo*)erts_alloc(ERTS_ALC_T_HIPE, sizeof(*p));
- p->code_size = 0;
- return &p->bucket;
-}
-
-static void init_modinfo_table(void)
-{
- HashFunctions f;
- static int init_done = 0;
-
- if (init_done)
- return;
- init_done = 1;
- f.hash = (H_FUN) modinfo_hash;
- f.cmp = (HCMP_FUN) modinfo_cmp;
- f.alloc = (HALLOC_FUN) modinfo_alloc;
- f.free = (HFREE_FUN) NULL;
- hash_init(ERTS_ALC_T_HIPE, &modinfo_table, "modinfo_table", 11, f);
-}
-
-BIF_RETTYPE hipe_bifs_update_code_size_3(BIF_ALIST_3)
-{
- struct modinfo *p;
- Sint code_size;
-
- init_modinfo_table();
-
- if (is_not_atom(BIF_ARG_1) ||
- is_not_small(BIF_ARG_3) ||
- (code_size = signed_val(BIF_ARG_3)) < 0)
+//struct modinfo {
+// HashBucket bucket; /* bucket.hvalue == atom_val(the module name) */
+// unsigned int code_size;
+//};
+//
+//static Hash modinfo_table;
+//
+//static HashValue modinfo_hash(void *tmpl)
+//{
+// Eterm mod = (Eterm)tmpl;
+// return atom_val(mod);
+//}
+//
+//static int modinfo_cmp(void *tmpl, void *bucket)
+//{
+// /* bucket->hvalue == modinfo_hash(tmpl), so just return 0 (match) */
+// return 0;
+//}
+//
+//static void *modinfo_alloc(void *tmpl)
+//{
+// struct modinfo *p;
+//
+// p = (struct modinfo*)erts_alloc(ERTS_ALC_T_HIPE, sizeof(*p));
+// p->code_size = 0;
+// return &p->bucket;
+//}
+//
+//static void init_modinfo_table(void)
+//{
+// HashFunctions f;
+// static int init_done = 0;
+//
+// if (init_done)
+// return;
+// init_done = 1;
+// f.hash = (H_FUN) modinfo_hash;
+// f.cmp = (HCMP_FUN) modinfo_cmp;
+// f.alloc = (HALLOC_FUN) modinfo_alloc;
+// f.free = (HFREE_FUN) NULL;
+// hash_init(ERTS_ALC_T_HIPE, &modinfo_table, "modinfo_table", 11, f);
+//}
+//
+//BIF_RETTYPE hipe_bifs_update_code_size_3(BIF_ALIST_3)
+//{
+// struct modinfo *p;
+// Sint code_size;
+//
+// init_modinfo_table();
+//
+// if (is_not_atom(BIF_ARG_1) ||
+// is_not_small(BIF_ARG_3) ||
+// (code_size = signed_val(BIF_ARG_3)) < 0)
+// BIF_ERROR(BIF_P, BADARG);
+//
+// p = (struct modinfo*)hash_put(&modinfo_table, (void*)BIF_ARG_1);
+//
+// if (is_nil(BIF_ARG_2)) /* some MFAs, not whole module */
+// p->code_size += code_size;
+// else /* whole module */
+// p->code_size = code_size;
+// BIF_RET(NIL);
+//}
+//
+//
+//BIF_RETTYPE hipe_bifs_code_size_1(BIF_ALIST_1)
+//{
+// struct modinfo *p;
+// unsigned int code_size;
+//
+// init_modinfo_table();
+//
+// if (is_not_atom(BIF_ARG_1))
+// BIF_ERROR(BIF_P, BADARG);
+//
+// p = (struct modinfo*)hash_get(&modinfo_table, (void*)BIF_ARG_1);
+//
+// code_size = p ? p->code_size : 0;
+// BIF_RET(make_small(code_size));
+//}
+
+BIF_RETTYPE hipe_bifs_add_native_code_3(BIF_ALIST_3)
+{ /* (Mod, CodeAddr, CodeSize) */
+ Uint code_size;
+ void* code_start = term_to_address(BIF_ARG_2);
+ Module* modp;
+ struct hipe_code_header* hdr;
+
+ if (is_not_atom(BIF_ARG_1) || !(modp = erts_get_module(BIF_ARG_1))
+ || !code_start
+ || !term_to_Uint(BIF_ARG_3, &code_size)) {
BIF_ERROR(BIF_P, BADARG);
+ }
- p = (struct modinfo*)hash_put(&modinfo_table, (void*)BIF_ARG_1);
+ hdr = (struct hipe_code_header*)((char*)code_start -
+ offsetof(struct hipe_code_header, code));
+ hdr->next = modp->hipe_code;
+ modp->hipe_code = hdr;
+
+ erts_fprintf(stderr, "SVERK: ADD native code to '%T' at %p -> %p\r\n",
+ BIF_ARG_1, hdr, (char*)hdr->code + hdr->code_size);
- if (is_nil(BIF_ARG_2)) /* some MFAs, not whole module */
- p->code_size += code_size;
- else /* whole module */
- p->code_size = code_size;
BIF_RET(NIL);
}
-BIF_RETTYPE hipe_bifs_code_size_1(BIF_ALIST_1)
-{
- struct modinfo *p;
- unsigned int code_size;
-
- init_modinfo_table();
-
- if (is_not_atom(BIF_ARG_1))
- BIF_ERROR(BIF_P, BADARG);
-
- p = (struct modinfo*)hash_get(&modinfo_table, (void*)BIF_ARG_1);
-
- code_size = p ? p->code_size : 0;
- BIF_RET(make_small(code_size));
-}
BIF_RETTYPE hipe_bifs_patch_insn_3(BIF_ALIST_3)
{
@@ -2011,3 +2088,41 @@ BIF_RETTYPE hipe_bifs_patch_call_3(BIF_ALIST_3)
BIF_ERROR(BIF_P, BADARG);
BIF_RET(NIL);
}
+
+
+void hipe_delete_code(Process* p, Eterm module)
+{
+ DeclareTmpHeap(tmp,4+2,p);
+ Eterm mfa, mfa_cons, res;
+ int i;
+ UseTmpHeap(4+2, p); /* mfa-tuple + cons */
+
+ tmp[0] = make_arityval(3);
+ tmp[1] = module;
+ mfa = make_tuple(&tmp[0]);
+ CAR(&tmp[4]) = mfa;
+ CDR(&tmp[4]) = NIL;
+ mfa_cons = make_list(&tmp[4]);
+
+ for (i = 0; i < export_list_size(); i++) {
+ Export *ep = export_list(i);
+ if (ep != NULL && (ep->code[0] == module)) {
+ if (ep->address == ep->code+3 &&
+ (ep->code[3] == (BeamInstr) em_apply_bif)) {
+ continue;
+ }
+ tmp[2] = ep->code[1]; /* func */
+ tmp[3] = make_small(ep->code[2]); /* arity */
+ res = hipe_bifs_invalidate_funinfo_native_addresses_1(p, mfa_cons);
+ ASSERT(res == NIL);
+ res = hipe_bifs_mark_referred_from_1(p, mfa);
+ ASSERT(res == NIL);
+ res = hipe_bifs_remove_refs_from_1(p, mfa);
+ ASSERT(res == NIL);
+ res = hipe_bifs_redirect_referred_from_1(p, mfa);
+ ASSERT(res == NIL);
+ }
+ }
+ UnUseTmpHeap(4+2, p);
+}
+
View
9 erts/emulator/hipe/hipe_bif0.h
@@ -24,6 +24,15 @@
#ifndef HIPE_BIF0_H
#define HIPE_BIF0_H
+/*
+** Header of allocated native code
+*/
+struct hipe_code_header {
+ struct hipe_code_header* next; /* for same module instance */
+ Uint code_size; /* in bytes */
+ UWord code[1]; /* The actual native machine code follows */
+};
+
extern Uint *hipe_bifs_find_pc_from_mfa(Eterm mfa);
/* shared with ggc.c -- NOT an official API */
View
5 erts/emulator/hipe/hipe_bif0.tab
@@ -56,8 +56,9 @@ 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:update_code_size/3
-bif hipe_bifs:code_size/1
+#bif hipe_bifs:update_code_size/3
+#bif hipe_bifs:code_size/1
+bif hipe_bifs:add_native_code/3
bif hipe_bifs:enter_sdesc/1
View
23 erts/emulator/hipe/hipe_bif2.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2001-2009. All Rights Reserved.
+ * Copyright Ericsson AB 2001-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -37,14 +37,25 @@
#include "hipe_arch.h"
#include "hipe_stack.h"
-BIF_RETTYPE hipe_bifs_show_estack_1(BIF_ALIST_1)
+static void proc_unlock(Process* c_p, Process* rp)
{
+ ErtsProcLocks locks = ERTS_PROC_LOCKS_ALL;
+ if (rp == c_p) {
+ locks &= ~ERTS_PROC_LOCK_MAIN;
+ }
+ if (rp && locks) {
+ erts_smp_proc_unlock(rp, locks);
+ }
+}
+
+BIF_RETTYPE hipe_bifs_show_estack_1(BIF_ALIST_1)
+{
Process *rp = erts_pid2proc(BIF_P, ERTS_PROC_LOCK_MAIN,
BIF_ARG_1, ERTS_PROC_LOCKS_ALL);
if (!rp)
BIF_ERROR(BIF_P, BADARG);
hipe_print_estack(rp);
- erts_smp_proc_unlock(rp, ERTS_PROC_LOCKS_ALL);
+ proc_unlock(BIF_P, rp);
BIF_RET(am_true);
}
@@ -55,7 +66,7 @@ BIF_RETTYPE hipe_bifs_show_heap_1(BIF_ALIST_1)
if (!rp)
BIF_ERROR(BIF_P, BADARG);
hipe_print_heap(rp);
- erts_smp_proc_unlock(rp, ERTS_PROC_LOCKS_ALL);
+ proc_unlock(BIF_P, rp);
BIF_RET(am_true);
}
@@ -66,7 +77,7 @@ BIF_RETTYPE hipe_bifs_show_nstack_1(BIF_ALIST_1)
if (!rp)
BIF_ERROR(BIF_P, BADARG);
hipe_print_nstack(rp);
- erts_smp_proc_unlock(rp, ERTS_PROC_LOCKS_ALL);
+ proc_unlock(BIF_P, rp);
BIF_RET(am_true);
}
@@ -82,7 +93,7 @@ BIF_RETTYPE hipe_bifs_show_pcb_1(BIF_ALIST_1)
if (!rp)
BIF_ERROR(BIF_P, BADARG);
hipe_print_pcb(rp);
- erts_smp_proc_unlock(rp, ERTS_PROC_LOCKS_ALL);
+ proc_unlock(BIF_P, rp);
BIF_RET(am_true);
}
View
48 erts/emulator/hipe/hipe_gc.c
@@ -30,6 +30,54 @@
#include "hipe_gc.h"
#include "hipe_bif0.h" /* for hipe_constants_{start,next} */
+// SVERK: Maybe not the right place
+int hipe_is_old_code(void* code_addr, Module* modp)
+{
+ struct hipe_code_header* ch;
+ for (ch = modp->old_hipe_code; ch; ch = ch->next) {
+ if (in_area(code_addr, &ch->code, ch->code_size)) {
+ extern void sverk_break(void);
+ erts_fprintf(stderr, "SVERK: Found old hipe code in %T\r\n",
+ make_atom(modp->module));
+ sverk_break();
+ return 1;
+ }
+ }
+ return 0;
+}
+// SVERK: Maybe not the right place
+int check_nstack_process_code(Process *p, Module* modp)
+{
+ Eterm *nsp;
+ Eterm *nsp_end;
+ const struct sdesc *sdesc;
+ unsigned int sdesc_size;
+ void* ra; /* return addr */
+ struct nstack_walk_state walk_state;
+
+ if (!nstack_walk_init_check(p))
+ return 0;
+
+ nsp = nstack_walk_nsp_begin(p);
+ nsp_end = nstack_walk_nsp_end(p);
+
+ sdesc = nstack_walk_init_sdesc(p, &walk_state);
+
+ while (!nstack_walk_nsp_reached_end(nsp, nsp_end)) {
+ sdesc_size = nstack_walk_frame_size(sdesc);
+ ra = (void*) nstack_walk_frame_ra(nsp, sdesc);
+ if (hipe_is_old_code(ra, modp)) {
+ return 1;
+ }
+ sdesc = hipe_find_sdesc((unsigned long)ra);
+ nsp = nstack_walk_next_frame(nsp, sdesc_size);
+ }
+ ASSERT(nsp == nsp_end);
+
+ return hipe_is_old_code(p->hipe.ngra, modp);
+}
+
+
Eterm *fullsweep_nstack(Process *p, Eterm *n_htop)
{
/* known nstack walk state */
View
15 erts/emulator/hipe/hipe_mkliterals.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2001-2009. All Rights Reserved.
+ * Copyright Ericsson AB 2001-2011. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
@@ -289,6 +289,9 @@ static const struct literal {
{ "P_NRA", offsetof(struct process, hipe.nra) },
#endif
{ "P_NARITY", offsetof(struct process, hipe.narity) },
+# if defined(ERTS_ENABLE_LOCK_CHECK) && defined(ERTS_SMP)
+ { "P_BIF_CALLEE", offsetof(struct process, hipe.bif_callee) },
+# endif
#endif /* HIPE */
/* process flags bits */
@@ -576,7 +579,12 @@ static void c_case_param(FILE *fp, const struct rts_param *param)
static void e_define_param(FILE *fp, const struct rts_param *param)
{
- fprintf(fp, "-define(%s, hipe_bifs:get_rts_param(%u)).\n", param->name, param->nr);
+ //fprintf(fp, "-define(%s, hipe_bifs:get_rts_param(%u)).\n", param->name, param->nr);
+
+ if (param->is_defined)
+ fprintf(fp, "-define(%s, %u).\n", param->name, param->value);
+ else
+ fprintf(fp, "-define(%s, []).\n", param->name);
}
static void print_params(FILE *fp, void (*print_param)(FILE*,const struct rts_param*))
@@ -613,7 +621,8 @@ static int do_e(FILE *fp)
fprintf(fp, "\n");
print_params(fp, e_define_param);
fprintf(fp, "\n");
- fprintf(fp, "-define(HIPE_SYSTEM_CRC, hipe_bifs:system_crc(%u)).\n", literals_crc);
+ //fprintf(fp, "-define(HIPE_SYSTEM_CRC, hipe_bifs:system_crc(%u)).\n", literals_crc);
+ fprintf(fp, "-define(HIPE_SYSTEM_CRC, %u).\n", system_crc);
return 0;
}
View
13 erts/emulator/hipe/hipe_mode_switch.c
@@ -34,6 +34,17 @@
#include "hipe_stack.h"
#include "hipe_bif0.h" /* hipe_mfa_info_table_init() */
+#if defined(ERTS_ENABLE_LOCK_CHECK) && defined(ERTS_SMP)
+# define ERTS_SMP_REQ_PROC_MAIN_LOCK(P) \
+ if ((P)) erts_proc_lc_require_lock((P), ERTS_PROC_LOCK_MAIN)
+# define ERTS_SMP_UNREQ_PROC_MAIN_LOCK(P) \
+ if ((P)) erts_proc_lc_unrequire_lock((P), ERTS_PROC_LOCK_MAIN)
+#else
+# define ERTS_SMP_REQ_PROC_MAIN_LOCK(P)
+# define ERTS_SMP_UNREQ_PROC_MAIN_LOCK(P)
+#endif
+
+
/*
* Internal debug support.
* #define HIPE_DEBUG to the desired debug level:
@@ -464,7 +475,9 @@ Process *hipe_mode_switch(Process *p, unsigned cmd, Eterm reg[])
#if !(NR_ARG_REGS > 5)
int reds_in = p->def_arg_reg[5];
#endif
+ ERTS_SMP_UNREQ_PROC_MAIN_LOCK(p);
p = schedule(p, reds_in - p->fcalls);
+ ERTS_SMP_REQ_PROC_MAIN_LOCK(p);
#ifdef ERTS_SMP
p->hipe_smp.have_receive_locks = 0;
reg = p->scheduler_data->save_reg;
View
3  erts/emulator/hipe/hipe_process.h
@@ -42,6 +42,9 @@ struct hipe_process_state {
void (*nra)(void); /* Native code return address. */
#endif
unsigned int narity; /* Arity of BIF call, for stack walks. */
+#if defined(ERTS_ENABLE_LOCK_CHECK) && defined(ERTS_SMP)
+ void (*bif_callee)(void);
+#endif
};
extern void hipe_arch_print_pcb(struct hipe_process_state *p);
View
2  erts/emulator/test/code_SUITE.erl
@@ -498,7 +498,9 @@ do_false_dependency(Init, Code) ->
?line unlink(Pid), exit(Pid, kill),
?line true = erlang:purge_module(cpbugx),
?line true = erlang:delete_module(cpbugx),
+ ?line code:is_module_native(cpbugx), % test is_module_native on deleted code
?line true = erlang:purge_module(cpbugx),
+ ?line code:is_module_native(cpbugx), % test is_module_native on purged code
ok.
false_dependency_loop(Parent, Init) ->
View
9 lib/hipe/rtl/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2001-2010. All Rights Reserved.
+# Copyright Ericsson AB 2001-2011. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
@@ -108,7 +108,12 @@ release_spec: opt
release_docs_spec:
-HIPE_MKLITERALS=$(ERL_TOP)/bin/$(TARGET)/hipe_mkliterals
+ifeq ($(TYPE),debug)
+HIPE_MKLITERALS=$(ERL_TOP)/bin/$(TARGET)/hipe_mkliterals.debug.smp
+else
+HIPE_MKLITERALS=$(ERL_TOP)/bin/$(TARGET)/hipe_mkliterals.smp
+endif
+
hipe_literals.hrl: $(HIPE_MKLITERALS)
$(HIPE_MKLITERALS) -e > hipe_literals.hrl
View
4 lib/hipe/rtl/hipe_tagscheme.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -1045,7 +1045,7 @@ convert_matchstate(Ms) ->
build_sub_binary(Ms, ByteSize, ByteOffset, BitSize, BitOffset,
hipe_rtl:mk_imm(0), Orig),
size_from_header(SizeInWords, Header),
- hipe_rtl:mk_alu(Hole, SizeInWords, sub, hipe_rtl:mk_imm(?SUB_BIN_WORDSIZE-1)),
+ hipe_rtl:mk_alu(Hole, SizeInWords, sub, hipe_rtl:mk_imm(?SUB_BIN_WORDSIZE)),
mk_var_header(BigIntHeader, Hole, ?TAG_HEADER_POS_BIG),
hipe_rtl:mk_store(Ms, hipe_rtl:mk_imm(?SUB_BIN_WORDSIZE*WordSize-?TAG_PRIMARY_BOXED),
BigIntHeader)].
View
1  lib/kernel/src/code_server.erl
@@ -344,6 +344,7 @@ handle_call({delete,Mod0}, {_From,_Tag}, S) ->
case catch erlang:delete_module(M) of
true ->
ets:delete(St#state.moddb, M),
+ post_beam_load(M), %% SVERK Can this work maybe
{reply,true,St};
_ ->
{reply,false,St}
View
24 lib/kernel/src/hipe_unified_loader.erl
@@ -125,6 +125,7 @@ load_native_code(Mod, Bin) when is_atom(Mod), is_binary(Bin) ->
-spec post_beam_load(atom()) -> 'ok'.
post_beam_load(Mod) when is_atom(Mod) ->
+ %%SVERK erlang:display({"post_beam_load",Mod}),
Architecture = erlang:system_info(hipe_architecture),
try chunk_name(Architecture) of
_ChunkTag ->
@@ -217,11 +218,21 @@ load_common(Mod, Bin, Beam, OldReferencesToPatch) ->
TrampolineMap = mk_trampoline_map(CalleeMFAs, Trampolines),
%% Patch references to code labels in data seg.
patch_consts(LabelMap, ConstAddr, CodeAddress),
+
%% Find out which functions are being loaded (and where).
%% Note: Addresses are sorted descending.
{MFAs,Addresses} = exports(ExportMap, CodeAddress),
+
+ if Mod =:= sverk_hipe; Mod =:= sverk_hipe2 ->
+ erlang:display({"SVERK ExportMap=",ExportMap,"MFAs=",MFAs,"Addresses=",Addresses});
+ true ->
+ ok
+ end,
+
%% Remove references to old versions of the module.
+ %% SVERK: Tag all callers as PENDING_REDIRECT
ReferencesToPatch = get_refs_from(MFAs, []),
+
remove_refs_from(MFAs),
%% Patch all dynamic references in the code.
%% Function calls, Atoms, Constants, System calls
@@ -245,6 +256,7 @@ load_common(Mod, Bin, Beam, OldReferencesToPatch) ->
%% The call to export_funs/1 above updated the native addresses
%% for the targets, so passing 'Addresses' is not needed.
redirect(ReferencesToPatch),
+ hipe_bifs:add_native_code(Mod, CodeAddress, CodeSize),
?debug_msg("****************Loader Finished****************\n", []),
{module,Mod} % for compatibility with code:load_file/1
end.
@@ -586,6 +598,7 @@ patch_load_mfa(CodeAddress, DestMFA, Addresses, RemoteOrLocal) ->
%% Patch references to code labels in the data segment.
%%
patch_consts(Labels, DataAddress, CodeAddress) ->
+ %%erlang:display({"SVERK patch_consts Labels=",Labels}),
lists:foreach(fun (L) ->
patch_label_or_labels(L, DataAddress, CodeAddress)
end, Labels).
@@ -915,10 +928,17 @@ assert_local_patch(Address) when is_integer(Address) ->
%% Beam: nil() | binary() (used as a flag)
-enter_code(CodeSize, CodeBinary, CalleeMFAs, Mod, Beam) ->
+enter_code(CodeSize, CodeBinary, CalleeMFAs, Mod, _Beam) ->
true = byte_size(CodeBinary) =:= CodeSize,
- hipe_bifs:update_code_size(Mod, Beam, CodeSize),
+ %%hipe_bifs:update_code_size(Mod, Beam, CodeSize),
{CodeAddress,Trampolines} = hipe_bifs:enter_code(CodeBinary, CalleeMFAs),
?init_assert_patch(CodeAddress, byte_size(CodeBinary)),
+
+ if Mod =:= sverk_hipe; Mod =:= sverk_hipe2 ->
+ erlang:display({"SVERK enter_code() IN: CalleeMFAs=",CalleeMFAs,"OUT: {CodeAddr=",
+ CodeAddress,"Trampolines=", Trampolines});
+ true ->
+ ok
+ end,
{CodeAddress,Trampolines}.
View
17 sverk.erl
@@ -0,0 +1,17 @@
+-module(sverk).
+
+-export([go/0]).
+
+go() ->
+ Bin = <<0, 0, 0, 4, 1, 2, 3>>,
+ erts_debug:get_internal_state([heap_consistency_check,break,Bin]), %% OK
+ foo(Bin).
+
+foo(<<Size:4/unit:8, _B:Size/bytes, _Rest/bytes>>) ->
+ ok;
+foo(Bin) ->
+ erts_debug:get_internal_state([heap_consistency_check,?LINE]), %% CRASH
+ Bin.
+
+
+
View
45 sverk_hipe.erl
@@ -0,0 +1,45 @@
+-module(sverk_hipe).
+
+-export([go/0, exp_func/2]).
+
+-export([purge_test/0]).
+
+go() ->
+ erts_debug:get_internal_state([heap_consistency_check,break]),
+
+ loc_func(1,2),
+
+ exp_func(3,4),
+
+ ?MODULE:exp_func(5,6),
+
+ sverk_beam:exported_func(7,8),
+
+ ok.
+
+loc_func(A,B) ->
+ sverk_beam:exported_func(A,B) + 3.
+
+exp_func(A,B) ->
+ loc_func(A,B) + 992.
+
+purge_test()->
+ spawn(fun() -> purge_test_proc() end).
+
+purge_test_proc() ->
+ receive
+ foo ->
+ sverk_hipe2:foo();
+ bar ->
+ erts_debug:get_internal_state([heap_consistency_check,break]),
+ sverk_hipe2:bar();
+ delete ->
+ Del = code:delete(sverk_hipe2),
+ io:format("SVERK: code:delete -> ~p\n",[Del]);
+ purge ->
+ Purg = code:purge(sverk_hipe2),
+ io:format("SVERK: code:purge -> ~p\n",[Purg]);
+ Other ->
+ io:format("SVERK: Uknown msg ~p\n",[Other])
+ end,
+ purge_test_proc().
View
11 sverk_hipe2.erl
@@ -0,0 +1,11 @@
+-module(sverk_hipe2).
+
+%-export([foo/0, bar/0]).
+-export([foo/0]).
+
+foo() ->
+ io:format("sverk_hipe2:foo() called\n").
+
+bar() ->
+ 1717.
+ %%io:format("sverk_hipe2:bar() called\n").

No commit comments for this range

Something went wrong with that request. Please try again.