aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2015-05-06 10:20:11 +0200
committerBjörn Gustavsson <[email protected]>2015-05-06 10:20:11 +0200
commita1b62b45b5c78e23b1b3fab5285ae13219a96e37 (patch)
treebde36c58924bc4d9acca67b7867448d42bdb861a
parentdcffa010ef304c4dbb2e830103b7ca87fb7b62b0 (diff)
parent541e87f3597523cb7d71f75fe0381fddb2af0ee0 (diff)
downloadotp-a1b62b45b5c78e23b1b3fab5285ae13219a96e37.tar.gz
otp-a1b62b45b5c78e23b1b3fab5285ae13219a96e37.tar.bz2
otp-a1b62b45b5c78e23b1b3fab5285ae13219a96e37.zip
Merge branch 'bjorn/debugger'
* bjorn/debugger: debugger: Optimize evaluation of new map creation dbg_iload: Correct translation of generators debugger test suite: Scale down t_frequency_table/1
-rw-r--r--lib/debugger/src/dbg_ieval.erl32
-rw-r--r--lib/debugger/src/dbg_iload.erl34
-rw-r--r--lib/debugger/test/map_SUITE.erl2
3 files changed, 48 insertions, 20 deletions
diff --git a/lib/debugger/src/dbg_ieval.erl b/lib/debugger/src/dbg_ieval.erl
index 0e176b243f..e6da8409d4 100644
--- a/lib/debugger/src/dbg_ieval.erl
+++ b/lib/debugger/src/dbg_ieval.erl
@@ -650,11 +650,10 @@ expr({tuple,Line,Es0}, Bs0, Ieval) ->
{value,list_to_tuple(Vs),Bs};
%% Map
-expr({map,Line,Fs0}, Bs0, Ieval) ->
- {Fs,Bs} = eval_map_fields(Fs0, Bs0, Ieval#ieval{line=Line,top=false}),
- Value = lists:foldl(fun ({map_assoc,K,V}, Mi) -> maps:put(K,V,Mi) end,
- #{}, Fs),
- {value,Value,Bs};
+expr({map,Line,Fs}, Bs0, Ieval) ->
+ {Map,Bs} = eval_new_map_fields(Fs, Bs0, Ieval#ieval{line=Line,top=false},
+ fun expr/3),
+ {value,Map,Bs};
expr({map,Line,E0,Fs0}, Bs0, Ieval0) ->
Ieval = Ieval0#ieval{line=Line,top=false},
{value,E,Bs1} = expr(E0, Bs0, Ieval),
@@ -1473,11 +1472,13 @@ guard_expr({cons,_,H0,T0}, Bs) ->
guard_expr({tuple,_,Es0}, Bs) ->
{values,Es} = guard_exprs(Es0, Bs),
{value,list_to_tuple(Es)};
-guard_expr({map,_,Fs0}, Bs) ->
- Fs = eval_map_fields_guard(Fs0, Bs),
- Value = lists:foldl(fun ({map_assoc,K,V}, Mi) -> maps:put(K,V,Mi) end,
- #{}, Fs),
- {value,Value};
+guard_expr({map,_,Fs}, Bs0) ->
+ F = fun (G0, B0, _) ->
+ {value,G} = guard_expr(G0, B0),
+ {value,G,B0}
+ end,
+ {Map,_} = eval_new_map_fields(Fs, Bs0, #ieval{top=false}, F),
+ {value,Map};
guard_expr({map,_,E0,Fs0}, Bs) ->
{value,E} = guard_expr(E0, Bs),
Fs = eval_map_fields_guard(Fs0, Bs),
@@ -1526,6 +1527,17 @@ eval_map_fields([{map_field_exact,Line,K0,V0}|Fs], Bs0, Ieval0, F, Acc) ->
eval_map_fields([], Bs, _Ieval, _F, Acc) ->
{lists:reverse(Acc),Bs}.
+eval_new_map_fields(Fs, Bs0, Ieval, F) ->
+ eval_new_map_fields(Fs, Bs0, Ieval, F, []).
+
+eval_new_map_fields([{Line,K0,V0}|Fs], Bs0, Ieval0, F, Acc) ->
+ Ieval = Ieval0#ieval{line=Line},
+ {value,K,Bs1} = F(K0, Bs0, Ieval),
+ {value,V,Bs2} = F(V0, Bs1, Ieval),
+ eval_new_map_fields(Fs, Bs2, Ieval0, F, [{K,V}|Acc]);
+eval_new_map_fields([], Bs, _, _, Acc) ->
+ {maps:from_list(lists:reverse(Acc)),Bs}.
+
%% match(Pattern,Term,Bs) -> {match,Bs} | nomatch
match(Pat, Term, Bs) ->
try match1(Pat, Term, Bs, Bs)
diff --git a/lib/debugger/src/dbg_iload.erl b/lib/debugger/src/dbg_iload.erl
index f1a85e8e71..379ffe8ce4 100644
--- a/lib/debugger/src/dbg_iload.erl
+++ b/lib/debugger/src/dbg_iload.erl
@@ -290,8 +290,7 @@ gexpr({tuple,Anno,Es0}) ->
Es1 = gexpr_list(Es0),
{tuple,ln(Anno),Es1};
gexpr({map,Anno,Fs0}) ->
- Fs1 = map_fields(Fs0, fun gexpr/1),
- {map,ln(Anno),Fs1};
+ new_map(Fs0, Anno, fun gexpr/1);
gexpr({map,Anno,E0,Fs0}) ->
E1 = gexpr(E0),
Fs1 = map_fields(Fs0, fun gexpr/1),
@@ -358,9 +357,8 @@ expr({cons,Anno,H0,T0}, _Lc) ->
expr({tuple,Anno,Es0}, _Lc) ->
Es1 = expr_list(Es0),
{tuple,ln(Anno),Es1};
-expr({map,Anno,Fs0}, _Lc) ->
- Fs1 = map_fields(Fs0),
- {map,ln(Anno),Fs1};
+expr({map,Anno,Fs}, _Lc) ->
+ new_map(Fs, Anno, fun (E) -> expr(E, false) end);
expr({map,Anno,E0,Fs0}, _Lc) ->
E1 = expr(E0, false),
Fs1 = map_fields(Fs0),
@@ -457,9 +455,9 @@ expr({'try',Anno,Es0,CaseCs0,CatchCs0,As0}, Lc) ->
{'try',ln(Anno),Es,CaseCs,CatchCs,As};
expr({lc,Anno,E0,Gs0}, _Lc) -> %R8.
Gs = lists:map(fun ({generate,L,P0,Qs}) ->
- {generate,L,expr(P0, false),expr(Qs, false)};
+ {generate,L,pattern(P0),expr(Qs, false)};
({b_generate,L,P0,Qs}) -> %R12.
- {b_generate,L,expr(P0, false),expr(Qs, false)};
+ {b_generate,L,pattern(P0),expr(Qs, false)};
(Expr) ->
case erl_lint:is_guard_test(Expr) of
true -> {guard,guard([[Expr]])};
@@ -469,9 +467,9 @@ expr({lc,Anno,E0,Gs0}, _Lc) -> %R8.
{lc,ln(Anno),expr(E0, false),Gs};
expr({bc,Anno,E0,Gs0}, _Lc) -> %R12.
Gs = lists:map(fun ({generate,L,P0,Qs}) ->
- {generate,L,expr(P0, false),expr(Qs, false)};
+ {generate,L,pattern(P0),expr(Qs, false)};
({b_generate,L,P0,Qs}) -> %R12.
- {b_generate,L,expr(P0, false),expr(Qs, false)};
+ {b_generate,L,pattern(P0),expr(Qs, false)};
(Expr) ->
case erl_lint:is_guard_test(Expr) of
true -> {guard,guard([[Expr]])};
@@ -538,6 +536,24 @@ fun_clauses([{clause,A,H,G,B}|Cs]) ->
[{clause,ln(A),head(H),guard(G),exprs(B, true)}|fun_clauses(Cs)];
fun_clauses([]) -> [].
+
+new_map(Fs0, Anno, F) ->
+ Line = ln(Anno),
+ Fs1 = map_fields(Fs0, F),
+ Fs2 = [{ln(A),K,V} || {map_field_assoc,A,K,V} <- Fs1],
+ try
+ {value,Line,map_literal(Fs2, #{})}
+ catch
+ throw:not_literal ->
+ {map,Line,Fs2}
+ end.
+
+map_literal([{_,{value,_,K},{value,_,V}}|T], M) ->
+ map_literal(T, maps:put(K, V, M));
+map_literal([_|_], _) ->
+ throw(not_literal);
+map_literal([], M) -> M.
+
map_fields(Fs) ->
map_fields(Fs, fun (E) -> expr(E, false) end).
diff --git a/lib/debugger/test/map_SUITE.erl b/lib/debugger/test/map_SUITE.erl
index 457863d982..12fdd184b8 100644
--- a/lib/debugger/test/map_SUITE.erl
+++ b/lib/debugger/test/map_SUITE.erl
@@ -2219,7 +2219,7 @@ map_guard_sequence_mixed(K1,K2,M) ->
t_frequency_table(Config) when is_list(Config) ->
random:seed({13,1337,54}), % pseudo random
- N = 100000,
+ N = 1000,
Ts = rand_terms(N),
#{ n:=N, tf := Tf } = frequency_table(Ts,#{ n=>0, tf => #{}}),
ok = check_frequency(Ts,Tf),