diff options
-rw-r--r-- | erts/emulator/beam/erl_db_util.c | 52 | ||||
-rw-r--r-- | erts/emulator/beam/erl_db_util.h | 1 | ||||
-rw-r--r-- | lib/stdlib/test/ets_SUITE.erl | 87 |
3 files changed, 82 insertions, 58 deletions
diff --git a/erts/emulator/beam/erl_db_util.c b/erts/emulator/beam/erl_db_util.c index 2b7e0bcac3..7f17d1212f 100644 --- a/erts/emulator/beam/erl_db_util.c +++ b/erts/emulator/beam/erl_db_util.c @@ -336,7 +336,6 @@ typedef struct dmc_context { Eterm *bodyexpr; int num_match; int current_match; - int eheap_need; Uint cflags; int is_guard; /* 1 if in guard, 0 if in body */ int special; /* 1 if the head in the match was a single expression */ @@ -1289,7 +1288,6 @@ Binary *db_match_compile(Eterm *matchexpr, int structure_checked; DMCRet res; int current_try_label; - Uint max_eheap_need; Binary *bp = NULL; unsigned clause_start; @@ -1302,7 +1300,6 @@ Binary *db_match_compile(Eterm *matchexpr, context.matchexpr = matchexpr; context.guardexpr = guards; context.bodyexpr = body; - context.eheap_need = 0; context.err_info = err_info; context.cflags = flags; @@ -1314,7 +1311,6 @@ Binary *db_match_compile(Eterm *matchexpr, */ restart: heap.vars_used = 0; - max_eheap_need = 0; for (context.current_match = 0; context.current_match < num_progs; ++context.current_match) { /* This loop is long, @@ -1322,7 +1318,6 @@ restart: memset(heap.vars, 0, heap.size * sizeof(*heap.vars)); t = context.matchexpr[context.current_match]; context.stack_used = 0; - context.eheap_need = 0; structure_checked = 0; if (context.current_match < num_progs - 1) { DMC_PUSH(text,matchTryMeElse); @@ -1494,10 +1489,6 @@ restart: if (current_try_label >= 0) { DMC_POKE(text, current_try_label, DMC_STACK_NUM(text)); } - /* So, how much eheap did this part of the match program need? */ - if (context.eheap_need > max_eheap_need) { - max_eheap_need = context.eheap_need; - } } /* for (context.current_match = 0 ...) */ @@ -1537,8 +1528,7 @@ restart: ret->single_variable = context.special; sys_memcpy(ret->text, DMC_STACK_DATA(text), DMC_STACK_NUM(text) * sizeof(UWord)); - ret->eheap_offset = heap.vars_used*sizeof(MatchVariable) + FENCE_PATTERN_SIZE; - ret->stack_offset = ret->eheap_offset + max_eheap_need*sizeof(Eterm) + FENCE_PATTERN_SIZE; + ret->stack_offset = heap.vars_used*sizeof(MatchVariable) + FENCE_PATTERN_SIZE; ret->heap_size = ret->stack_offset + context.stack_need * sizeof(Eterm*) + FENCE_PATTERN_SIZE; #ifdef DMC_DEBUG @@ -1613,7 +1603,6 @@ static Eterm dpm_array_to_list(Process *psp, Eterm *arr, int arity) return ret; } -//void heap_consistency_check(Process*); // SVERK #if HALFWORD_HEAP struct heap_checkpoint_t @@ -1720,16 +1709,10 @@ Eterm db_prog_match(Process *c_p, Binary *bprog, #endif #ifdef DMC_DEBUG Uint *heap_fence; - Uint *eheap_fence; Uint *stack_fence; Uint save_op; #endif /* DMC_DEBUG */ -// if (base == NULL) { -// erts_fprintf(stderr, "SVERK prog_match = %T\r\n", term); -// } else { -// erts_fprintf(stderr, "SVERK prog_match = REL-TERM\r\n"); -// } ASSERT(base==NULL || HALFWORD_HEAP); mpsp = get_match_pseudo_process(c_p, prog->heap_size); @@ -1763,11 +1746,9 @@ Eterm db_prog_match(Process *c_p, Binary *bprog, #ifdef DMC_DEBUG save_op = 0; - heap_fence = (Eterm*)((char*) mpsp->u.heap + prog->eheap_offset) - 1; - eheap_fence = (Eterm*)((char*) mpsp->u.heap + prog->stack_offset) - 1; + heap_fence = (Eterm*)((char*) mpsp->u.heap + prog->stack_offset) - 1; stack_fence = (Eterm*)((char*) mpsp->u.heap + prog->heap_size) - 1; *heap_fence = FENCE_PATTERN; - *eheap_fence = FENCE_PATTERN; *stack_fence = FENCE_PATTERN; #endif /* DMC_DEBUG */ @@ -1790,7 +1771,6 @@ restart: ep = &term; esp = (Eterm*)((char*)mpsp->u.heap + prog->stack_offset); sp = (Eterm **) esp; - //ehp = (char*)mpsp->u.heap + prog->eheap_offset; ret = am_true; do_catch = 0; fail_label = -1; @@ -1814,11 +1794,6 @@ restart: erl_exit(1, "Heap fence overwritten in db_prog_match after op " "0x%08x, overwritten with 0x%08x.", save_op, *heap_fence); } - if (*eheap_fence != FENCE_PATTERN) { - erl_exit(1, "Eheap fence overwritten in db_prog_match after op " - "0x%08x, overwritten with 0x%08x.", save_op, - *eheap_fence); - } if (*stack_fence != FENCE_PATTERN) { erl_exit(1, "Stack fence overwritten in db_prog_match after op " "0x%08x, overwritten with 0x%08x.", save_op, @@ -1957,14 +1932,12 @@ restart: CDR(ehp) = *--esp; CAR(ehp) = esp[-1]; esp[-1] = make_list(ehp); - //ehp += 2; break; case matchConsB: ehp = HAlloc(build_proc, 2); CAR(ehp) = *--esp; CDR(ehp) = esp[-1]; esp[-1] = make_list(ehp); - //ehp += 2; break; case matchMkTuple: n = *pc++; @@ -2303,7 +2276,6 @@ restart: ehp[1] = cp[0]; ehp[2] = cp[1]; ehp[3] = make_small((Uint) cp[2]); - //ehp += 4; } break; case matchSilent: @@ -2417,11 +2389,6 @@ success: erl_exit(1, "Heap fence overwritten in db_prog_match after op " "0x%08x, overwritten with 0x%08x.", save_op, *heap_fence); } - if (*eheap_fence != FENCE_PATTERN) { - erl_exit(1, "Eheap fence overwritten in db_prog_match after op " - "0x%08x, overwritten with 0x%08x.", save_op, - *eheap_fence); - } if (*stack_fence != FENCE_PATTERN) { erl_exit(1, "Stack fence overwritten in db_prog_match after op " "0x%08x, overwritten with 0x%08x.", save_op, @@ -2433,9 +2400,6 @@ success: END_ATOMIC_TRACE(c_p); - #ifdef DEBUG - //heap_consistency_check(c_p); // SVERK - #endif return ret; #undef FAIL #undef FAIL_TERM @@ -3501,7 +3465,6 @@ static DMCRet dmc_list(DMCContext *context, DMC_PUSH(*text, matchConsB); } --context->stack_used; /* Two objects on stack becomes one */ - context->eheap_need += 2; return retOk; } @@ -3560,7 +3523,6 @@ static DMCRet dmc_tuple(DMCContext *context, DMC_PUSH(*text, matchMkTuple); DMC_PUSH(*text, nelems); context->stack_used -= (nelems - 1); - context->eheap_need += (nelems + 1); *constant = 0; return retOk; } @@ -3578,9 +3540,6 @@ static DMCRet dmc_whole_expression(DMCContext *context, } else { ASSERT(is_tuple(context->matchexpr [context->current_match])); - context->eheap_need += - arityval(*(tuple_val(context->matchexpr - [context->current_match]))) * 2; DMC_PUSH(*text, matchPushArrayAsList); } } else { @@ -3670,7 +3629,6 @@ static DMCRet dmc_all_bindings(DMCContext *context, ++context->stack_used; if ((context->stack_used + 1) > context->stack_need) context->stack_need = (context->stack_used + 1); - context->eheap_need += heap_used; *constant = 0; return retOk; } @@ -4073,10 +4031,6 @@ static DMCRet dmc_get_seq_token(DMCContext *context, *constant = 0; DMC_PUSH(*text, matchGetSeqToken); - context->eheap_need += (6 /* A 5-tuple is built */ - + EXTERNAL_THING_HEAD_SIZE + 2 /* Sender can - be an external - pid */); if (++context->stack_used > context->stack_need) context->stack_need = context->stack_used; return retOk; @@ -4373,7 +4327,6 @@ static DMCRet dmc_caller(DMCContext *context, } *constant = 0; DMC_PUSH(*text, matchCaller); /* Creates binary */ - context->eheap_need += 4; /* A 3-tuple is built */ if (++context->stack_used > context->stack_need) context->stack_need = context->stack_used; return retOk; @@ -5412,7 +5365,6 @@ void db_match_dis(Binary *bp) erts_printf("}\n"); erts_printf("num_bindings: %d\n", prog->num_bindings); erts_printf("heap_size: %bpu\n", prog->heap_size); - erts_printf("eheap_offset: %bpu\n", prog->eheap_offset); erts_printf("stack_offset: %bpu\n", prog->stack_offset); erts_printf("text: 0x%08x\n", (unsigned long) prog->text); erts_printf("stack_size: %d (words)\n", prog->heap_size-prog->stack_offset); diff --git a/erts/emulator/beam/erl_db_util.h b/erts/emulator/beam/erl_db_util.h index 4cb5a457ef..bb1751d309 100644 --- a/erts/emulator/beam/erl_db_util.h +++ b/erts/emulator/beam/erl_db_util.h @@ -360,7 +360,6 @@ typedef struct match_prog { struct erl_heap_fragment *saved_program_buf; Eterm saved_program; Uint heap_size; /* size of: heap + eheap + stack */ - Uint eheap_offset; Uint stack_offset; #ifdef DMC_DEBUG UWord* prog_end; /* End of program */ diff --git a/lib/stdlib/test/ets_SUITE.erl b/lib/stdlib/test/ets_SUITE.erl index 1661aa0217..5eed767dfe 100644 --- a/lib/stdlib/test/ets_SUITE.erl +++ b/lib/stdlib/test/ets_SUITE.erl @@ -92,7 +92,8 @@ misc1_do/1, safe_fixtable_do/1, info_do/1, dups_do/1, heavy_lookup_do/1, heavy_lookup_element_do/1, member_do/1, otp_5340_do/1, otp_7665_do/1, meta_wb_do/1, do_heavy_concurrent/1, tab2file2_do/2, exit_large_table_owner_do/2, - types_do/1, sleeper/0, rpc_externals/0, memory_do/1 + types_do/1, sleeper/0, rpc_externals/0, memory_do/1, + ms_tracee_dummy/1, ms_tracee_dummy/2, ms_tracee_dummy/3, ms_tracee_dummy/4 ]). -export([t_select_reverse/1]). @@ -265,7 +266,7 @@ t_match_spec_run(Config) when is_list(Config) -> repeat_for_permutations(F, N_MS) end, - test_terms(Fun), + test_terms(Fun, skip_refc_check), ?line verify_etsmem(EtsMem). @@ -280,7 +281,73 @@ t_match_spec_run_test(List, MS, Result) -> ets:insert(Tab, List), SRes = lists:sort(Result), ?m(SRes, lists:sort(ets:select(Tab, MS))), - ets:delete(Tab). + ets:delete(Tab), + + %% Check that tracing agree + Self = self(), + {Tracee, MonRef} = spawn_monitor(fun() -> ms_tracee(Self, List) end), + receive {Tracee, ready} -> ok end, + + MST = lists:map(fun(Clause) -> ms_clause_ets_to_trace(Clause) end, MS), + + %%io:format("MS = ~p\nMST= ~p\n",[MS,MST]), + + erlang:trace_pattern({?MODULE,ms_tracee_dummy,'_'}, MST , [local]), + erlang:trace(Tracee, true, [call]), + Tracee ! start, + TRes = ms_tracer_collect(Tracee, MonRef, []), + %erlang:trace(Tracee, false, [call]), + %Tracee ! stop, + case TRes of + SRes -> ok; + _ -> + io:format("TRACE MATCH FAILED\n"), + io:format("Input = ~p\nMST = ~p\nExpected = ~p\nGot = ~p\n", [List, MST, SRes, TRes]), + ?t:fail("TRACE MATCH FAILED") + end, + ok. + + + +ms_tracer_collect(Tracee, Ref, Acc) -> + receive + {trace, Tracee, call, Args, [Msg]} -> + %io:format("trace Args=~p Msg=~p\n", [Args, Msg]), + ms_tracer_collect(Tracee, Ref, [Msg | Acc]); + + {'DOWN', Ref, process, Tracee, _} -> + %io:format("monitor DOWN for ~p\n", [Tracee]), + TDRef = erlang:trace_delivered(Tracee), + ms_tracer_collect(Tracee, TDRef, Acc); + + {trace_delivered, Tracee, Ref} -> + %%io:format("trace delivered for ~p\n", [Tracee]), + lists:sort(Acc); + + Other -> + io:format("Unexpected message = ~p\n", [Other]), + ?t:fail("Unexpected tracer msg") + end. + + +ms_tracee(Parent, CallArgList) -> + %io:format("ms_tracee ~p started with ArgList = ~p\n", [self(), CallArgList]), + Parent ! {self(), ready}, + receive start -> ok end, + lists:foreach(fun(Args) -> + erlang:apply(?MODULE, ms_tracee_dummy, tuple_to_list(Args)) + end, CallArgList). + %%receive stop -> ok end. + + + +ms_tracee_dummy(_) -> ok. +ms_tracee_dummy(_,_) -> ok. +ms_tracee_dummy(_,_,_) -> ok. +ms_tracee_dummy(_,_,_,_) -> ok. + +ms_clause_ets_to_trace({Head, Guard, Body}) -> + {tuple_to_list(Head), Guard, [{message, Body}]}. assert_eq(A,A) -> ok; assert_eq(A,B) -> @@ -5339,7 +5406,7 @@ types_do(Opts) -> ets:delete_all_objects(T), ?line 0 = ets:info(T,size) end, - test_terms(Fun), + test_terms(Fun, strict), ets:delete(T), ?line verify_etsmem(EtsMem). @@ -5654,7 +5721,7 @@ only_if_smp(Schedulers, Func) -> %% Copy-paste from emulator/test/binary_SUITE.erl -define(heap_binary_size, 64). -test_terms(Test_Func) -> +test_terms(Test_Func, Mode) -> garbage_collect(), ?line Pib0 = process_info(self(),binary), @@ -5731,7 +5798,10 @@ test_terms(Test_Func) -> Pib = process_info(self(),binary), ?line Test_Func(Bin3), garbage_collect(), - ?line Pib = process_info(self(),binary), + case Mode of + strict -> ?line Pib = process_info(self(),binary); + skip_refc_check -> ok + end, ?line Test_Func(make_unaligned_sub_binary(Bin0)), ?line Test_Func(make_unaligned_sub_binary(Bin1)), @@ -5775,7 +5845,10 @@ test_terms(Test_Func) -> ?line Test_Func(lists:duplicate(32, FF)), garbage_collect(), - ?line Pib0 = process_info(self(),binary), + case Mode of + strict -> ?line Pib0 = process_info(self(),binary); + skip_refc_check -> ok + end, ok. |