From c591f7b2a78b44ab321d0b99c100b349c8606c15 Mon Sep 17 00:00:00 2001 From: Patrik Nyblom Date: Tue, 9 Feb 2010 17:21:28 +0100 Subject: Make tracing and distribution work Rewrite trace code and external coding. Also slightly correct the interface to the match-spec engine to make tracing work. That will make the test suites runnable. --- erts/emulator/beam/beam_emu.c | 9 +++++++-- erts/emulator/beam/bif.c | 8 +++++--- erts/emulator/beam/erl_db.c | 2 +- erts/emulator/beam/erl_db_hash.c | 12 ++++++------ erts/emulator/beam/erl_db_tree.c | 8 ++++---- erts/emulator/beam/erl_db_util.c | 21 +++++++++++---------- erts/emulator/beam/erl_db_util.h | 2 +- erts/emulator/beam/erl_term.h | 5 +++++ erts/emulator/beam/external.c | 18 +++++++++++------- 9 files changed, 51 insertions(+), 34 deletions(-) (limited to 'erts/emulator') diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c index 8113e78583..1078478ed9 100644 --- a/erts/emulator/beam/beam_emu.c +++ b/erts/emulator/beam/beam_emu.c @@ -2621,6 +2621,7 @@ void process_main(void) SWAPOUT; reg[0] = r(0); + next = call_fun(c_p, Arg(0), reg, THE_NON_VALUE); SWAPIN; if (next != NULL) { @@ -6049,8 +6050,12 @@ call_fun(Process* p, /* Current process. */ } } } else if (is_export_header(hdr)) { - Export* ep = *((Export **) (export_val(fun) + 1)); - int actual_arity = (int) ep->code[2]; + Export *ep; + int actual_arity; + + ep = *((Export **) (export_val(fun) + 1)); + actual_arity = (int) ep->code[2]; + if (arity == actual_arity) { return ep->address; } else { diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c index c06d92ed45..85bf584337 100644 --- a/erts/emulator/beam/bif.c +++ b/erts/emulator/beam/bif.c @@ -3468,12 +3468,14 @@ BIF_RETTYPE make_fun_3(BIF_ALIST_3) if (arity < 0) { goto error; } - hp = HAlloc(BIF_P, 2); - hp[0] = HEADER_EXPORT; #if HALFWORD_HEAP + hp = HAlloc(BIF_P, 3); + hp[0] = HEADER_EXPORT; /* Yes, May be misaligned, but X86_64 will fix it... */ - memcpy(hp+1,erts_export_get_or_make_stub(BIF_ARG_1, BIF_ARG_2, (Uint) arity),sizeof(Export *)); + *((Export **) (hp+1)) = erts_export_get_or_make_stub(BIF_ARG_1, BIF_ARG_2, (Uint) arity); #else + hp = HAlloc(BIF_P, 2); + hp[0] = HEADER_EXPORT; hp[1] = (Eterm) erts_export_get_or_make_stub(BIF_ARG_1, BIF_ARG_2, (Uint) arity); #endif BIF_RET(make_export(hp)); diff --git a/erts/emulator/beam/erl_db.c b/erts/emulator/beam/erl_db.c index 88a9e56854..4c75659246 100644 --- a/erts/emulator/beam/erl_db.c +++ b/erts/emulator/beam/erl_db.c @@ -2597,7 +2597,7 @@ BIF_RETTYPE ets_match_spec_run_r_3(BIF_ALIST_3) BIF_TRAP3(bif_export[BIF_ets_match_spec_run_r_3], BIF_P,lst,BIF_ARG_2,ret); } - res = db_prog_match(BIF_P, mp, CAR(list_val(lst)), 0, &dummy); + res = db_prog_match(BIF_P, mp, CAR(list_val(lst)), NULL, 0, &dummy); if (is_value(res)) { sz = size_object(res); hp = HAlloc(BIF_P, sz + 2); diff --git a/erts/emulator/beam/erl_db_hash.c b/erts/emulator/beam/erl_db_hash.c index 4141f9766b..124129a371 100644 --- a/erts/emulator/beam/erl_db_hash.c +++ b/erts/emulator/beam/erl_db_hash.c @@ -1284,7 +1284,7 @@ static int db_select_continue_hash(Process *p, (match_res = db_prog_match(p,mp, make_tuple(current->dbterm.tpl), - 0,&dummy), + NULL,0,&dummy), is_value(match_res))) { if (all_objects) { hp = HAlloc(p, current->dbterm.size + 2); @@ -1462,7 +1462,7 @@ static int db_select_chunk_hash(Process *p, DbTable *tbl, if (current->hvalue != INVALID_HASH) { match_res = db_prog_match(p,mpi.mp, make_tuple(current->dbterm.tpl), - 0,&dummy); + NULL,0,&dummy); if (is_value(match_res)) { if (mpi.all_objects) { hp = HAlloc(p, current->dbterm.size + 2); @@ -1641,7 +1641,7 @@ static int db_select_count_hash(Process *p, if (current != NULL) { if (current->hvalue != INVALID_HASH) { if (db_prog_match(p, mpi.mp, make_tuple(current->dbterm.tpl), - 0, &dummy) == am_true) { + NULL,0, &dummy) == am_true) { ++got; } --num_left; @@ -1792,7 +1792,7 @@ static int db_select_delete_hash(Process *p, int did_erase = 0; if ((db_prog_match(p,mpi.mp, make_tuple((*current)->dbterm.tpl), - 0,&dummy)) == am_true) { + NULL,0,&dummy)) == am_true) { if (NFIXED(tb) > fixated_by_me) { /* fixated by others? */ if (slot_ix != last_pseudo_delete) { add_fixed_deletion(tb, slot_ix); @@ -1904,7 +1904,7 @@ static int db_select_delete_continue_hash(Process *p, else { int did_erase = 0; if ((db_prog_match(p,mp,make_tuple((*current)->dbterm.tpl), - 0,&dummy)) == am_true) { + NULL,0,&dummy)) == am_true) { if (NFIXED(tb) > fixated_by_me) { /* fixated by others? */ if (slot_ix != last_pseudo_delete) { add_fixed_deletion(tb, slot_ix); @@ -2005,7 +2005,7 @@ static int db_select_count_continue_hash(Process *p, continue; } if (db_prog_match(p, mp, make_tuple(current->dbterm.tpl), - 0,&dummy) == am_true) { + NULL,0,&dummy) == am_true) { ++got; } --num_left; diff --git a/erts/emulator/beam/erl_db_tree.c b/erts/emulator/beam/erl_db_tree.c index f9ed5fe292..b6b3cabafe 100644 --- a/erts/emulator/beam/erl_db_tree.c +++ b/erts/emulator/beam/erl_db_tree.c @@ -3023,7 +3023,7 @@ static int doit_select(DbTableTree *tb, TreeDbTerm *this, void *ptr, } ret = db_prog_match(sc->p, sc->mp, make_tuple(this->dbterm.tpl), - 0, &dummy); + NULL,0, &dummy); if (is_value(ret)) { Uint sz; Eterm *hp; @@ -3072,7 +3072,7 @@ static int doit_select_count(DbTableTree *tb, TreeDbTerm *this, void *ptr, } ret = db_prog_match(sc->p, sc->mp, make_tuple(this->dbterm.tpl), - 0, &dummy); + NULL,0, &dummy); if (ret == am_true) { ++(sc->got); } @@ -3105,7 +3105,7 @@ static int doit_select_chunk(DbTableTree *tb, TreeDbTerm *this, void *ptr, ret = db_prog_match(sc->p, sc->mp, make_tuple(this->dbterm.tpl), - 0, &dummy); + NULL,0, &dummy); if (is_value(ret)) { Uint sz; Eterm *hp; @@ -3158,7 +3158,7 @@ static int doit_select_delete(DbTableTree *tb, TreeDbTerm *this, void *ptr, return 0; ret = db_prog_match(sc->p, sc->mp, make_tuple(this->dbterm.tpl), - 0, &dummy); + NULL,0, &dummy); if (ret == am_true) { key = GETKEY(sc->tb, this->dbterm.tpl); linkout_tree(sc->tb, key); diff --git a/erts/emulator/beam/erl_db_util.c b/erts/emulator/beam/erl_db_util.c index f8baf44e10..165c56cbf1 100644 --- a/erts/emulator/beam/erl_db_util.c +++ b/erts/emulator/beam/erl_db_util.c @@ -1185,7 +1185,7 @@ Eterm erts_match_set_run(Process *p, Binary *mpsp, Eterm ret; ret = db_prog_match(p, mpsp, - (Eterm) COMPRESS_POINTER(args), + NIL, args, num_args, return_flags); #if defined(HARDDEBUG) if (is_non_value(ret)) { @@ -1380,7 +1380,7 @@ restart: /* ** There is one single top variable in the match expression - ** iff the text is tho Uint's and the single instruction + ** iff the text is two Uint's and the single instruction ** is 'matchBind' or it is only a skip. */ context.special = @@ -1591,6 +1591,7 @@ static Eterm dpm_array_to_list(Process *psp, Eterm *arr, int arity) ** i.e. 'DCOMP_TRACE' was specified */ Eterm db_prog_match(Process *c_p, Binary *bprog, Eterm term, + Eterm *termp, int arity, Uint32 *return_flags) { @@ -1710,12 +1711,12 @@ restart: n = *pc++; if ((int) n != arity) FAIL(); - ep = (Eterm *) EXPAND_POINTER(*ep); + ep = termp; break; case matchArrayBind: /* When the array size is unknown. */ /* XXX:PaN - where does this array come from? */ n = *pc++; - hp[n] = dpm_array_to_list(psp, (Eterm *) EXPAND_POINTER(term), arity); + hp[n] = dpm_array_to_list(psp, termp, arity); break; case matchTuple: /* *ep is a tuple of arity n */ if (!is_tuple(*ep)) @@ -2101,13 +2102,13 @@ restart: *esp++ = am_undefined; } else { *esp++ = make_tuple(ehp); - ehp[0] = make_arityval(3); + ehp[0] = make_arityval(3); ehp[1] = cp[0]; ehp[2] = cp[1]; - ehp[3] = make_small((Uint) hp[2]); - ehp += 4; - } - break; + ehp[3] = make_small((Uint) cp[2]); + ehp += 4; + } + break; case matchSilent: --esp; if (*esp == am_true) { @@ -4278,7 +4279,7 @@ static Eterm match_spec_test(Process *p, Eterm against, Eterm spec, int trace) } } else { n = 0; - arr = (Eterm *) EXPAND_POINTER(against); + arr = tuple_val(against); } /* We are in the context of a BIF, diff --git a/erts/emulator/beam/erl_db_util.h b/erts/emulator/beam/erl_db_util.h index fbc25aaf2b..5959e62025 100644 --- a/erts/emulator/beam/erl_db_util.h +++ b/erts/emulator/beam/erl_db_util.h @@ -366,7 +366,7 @@ Binary *db_match_compile(Eterm *matchexpr, Eterm *guards, Uint flags, DMCErrInfo *err_info); /* Returns newly allocated MatchProg binary with refc == 0*/ -Eterm db_prog_match(Process *p, Binary *prog, Eterm term, int arity, +Eterm db_prog_match(Process *p, Binary *prog, Eterm term, Eterm *termp, int arity, Uint32 *return_flags /* Zeroed on enter */); /* returns DB_ERROR_NONE if matches, 1 if not matches and some db error on error. */ diff --git a/erts/emulator/beam/erl_term.h b/erts/emulator/beam/erl_term.h index 25d12bf16e..3a8c30fe6a 100644 --- a/erts/emulator/beam/erl_term.h +++ b/erts/emulator/beam/erl_term.h @@ -849,6 +849,11 @@ _ET_DECLARE_CHECKED(struct erl_node_*,internal_ref_node,Eterm) * */ +/* XXX:PaN - this structure is not perfect for halfword heap, it takes + a lot of memory due to padding, and the array will not begin at the end of the + structure, as otherwise expected. Be sure to access data.ui32 array and not try + to do pointer manipulation on an Eterm * to reach the actual data... */ + typedef struct external_thing_ { /* ----+ */ Eterm header; /* | */ diff --git a/erts/emulator/beam/external.c b/erts/emulator/beam/external.c index 7f39f8eb12..ac8dd27b15 100644 --- a/erts/emulator/beam/external.c +++ b/erts/emulator/beam/external.c @@ -2260,18 +2260,25 @@ dec_term_atom_common: node = erts_find_or_insert_node(sysname, cre); if(node == erts_this_node) { RefThing *rtp = (RefThing *) hp; - hp += REF_THING_HEAD_SIZE; + ref_num = (Uint32 *) (hp + REF_THING_HEAD_SIZE); + #if defined(ARCH_64) && !HALFWORD_HEAP + hp += REF_THING_HEAD_SIZE + ref_words/2 + 1; rtp->header = make_ref_thing_header(ref_words/2 + 1); #else + hp += REF_THING_HEAD_SIZE + ref_words; rtp->header = make_ref_thing_header(ref_words); #endif *objp = make_internal_ref(rtp); } else { ExternalThing *etp = (ExternalThing *) hp; - hp += EXTERNAL_THING_HEAD_SIZE; - +#if defined(ARCH_64) && !HALFWORD_HEAP + hp += EXTERNAL_THING_HEAD_SIZE + ref_words/2 + 1; +#else + hp += EXTERNAL_THING_HEAD_SIZE + ref_words; +#endif + #if defined(ARCH_64) && !HALFWORD_HEAP etp->header = make_external_ref_header(ref_words/2 + 1); #else @@ -2282,9 +2289,9 @@ dec_term_atom_common: off_heap->externals = etp; *objp = make_external_ref(etp); + ref_num = &(etp->data.ui32[0]); } - ref_num = (Uint32 *) hp; #if defined(ARCH_64) && !HALFWORD_HEAP *(ref_num++) = ref_words /* 32-bit arity */; #endif @@ -2296,9 +2303,6 @@ dec_term_atom_common: #if defined(ARCH_64) && !HALFWORD_HEAP if ((1 + ref_words) % 2) ref_num[ref_words] = 0; - hp += ref_words/2 + 1; -#else - hp += ref_words; #endif break; } -- cgit v1.2.3