aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--erts/emulator/beam/erl_db_util.c52
-rw-r--r--erts/emulator/beam/erl_db_util.h1
-rw-r--r--lib/stdlib/test/ets_SUITE.erl87
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.