diff options
author | José Valim <[email protected]> | 2016-07-16 22:24:50 +0200 |
---|---|---|
committer | José Valim <[email protected]> | 2016-08-04 13:22:14 +0200 |
commit | a5fcd4f26969a768950dc643eeed2fdb41a5dc41 (patch) | |
tree | c20bcd4a5dfeea6ccdc6a05ebd0eeaaeb0854a4d /lib/debugger/src | |
parent | ddfae156c2b21d5266bd6eb82bf9ca7c508226fd (diff) | |
download | otp-a5fcd4f26969a768950dc643eeed2fdb41a5dc41.tar.gz otp-a5fcd4f26969a768950dc643eeed2fdb41a5dc41.tar.bz2 otp-a5fcd4f26969a768950dc643eeed2fdb41a5dc41.zip |
Move expansion of strings in binaries to v3_core
This speeds up the compilation of binary literals
with string values in them. For example, compiling
a file with a ~340kB binary would yield the following
times by the compiler:
Compiling "foo"
parse_module : 0.130 s 5327.6 kB
transform_module : 0.000 s 5327.6 kB
lint_module : 0.011 s 5327.8 kB
expand_module : 0.508 s 71881.2 kB
v3_core : 0.463 s 11.5 kB
Notice the increase in memory and processing time
in expand_module and v3_core. This happened because
expand_module would expand the string in binaries
into chars. For example, the binary <<"foo">>, which
is represented as
{bin, 1, [
{bin_element, 1, {string, 1, "foo"}, default, default}
]}
would be converted to
{bin, 1, [
{bin_element, 1, {char, 1, $f}, default, default},
{bin_element, 1, {char, 1, $o}, default, default},
{bin_element, 1, {char, 1, $o}, default, default}
]}
However, v3_core would then traverse all of those
characters and convert it into an actual binary, as it
is a literal value.
This patch addresses this issue by moving the expansion
of string into chars to v3_core and only if a literal
value cannot not be built. This reduces the compilation
time of the file mentioned above to the values below:
Compiling "bar"
parse_module : 0.134 s 5327.6 kB
transform_module : 0.000 s 5327.6 kB
lint_module : 0.005 s 5327.8 kB
expand_module : 0.000 s 5328.7 kB
v3_core : 0.013 s 11.2 kB
Diffstat (limited to 'lib/debugger/src')
-rw-r--r-- | lib/debugger/src/dbg_iload.erl | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/lib/debugger/src/dbg_iload.erl b/lib/debugger/src/dbg_iload.erl index 369b456524..f83684b605 100644 --- a/lib/debugger/src/dbg_iload.erl +++ b/lib/debugger/src/dbg_iload.erl @@ -216,7 +216,7 @@ pattern({op,_,'-',{float,Anno,I}}) -> pattern({op,_,'+',{float,Anno,I}}) -> {value,ln(Anno),I}; pattern({bin,Anno,Grp}) -> - Grp1 = pattern_list(Grp), + Grp1 = pattern_list(bin_expand_strings(Grp)), {bin,ln(Anno),Grp1}; pattern({bin_element,Anno,Expr,Size,Type}) -> Expr1 = pattern(Expr), @@ -297,7 +297,7 @@ gexpr({map,Anno,E0,Fs0}) -> Fs1 = map_fields(Fs0, fun gexpr/1), {map,ln(Anno),E1,Fs1}; gexpr({bin,Anno,Flds0}) -> - Flds = gexpr_list(Flds0), + Flds = gexpr_list(bin_expand_strings(Flds0)), {bin,ln(Anno),Flds}; gexpr({bin_element,Anno,Expr0,Size0,Type}) -> Expr = gexpr(Expr0), @@ -506,7 +506,7 @@ expr({op,Anno,Op,L0,R0}, _Lc) -> R1 = expr(R0, false), %They see the same variables {op,ln(Anno),Op,[L1,R1]}; expr({bin,Anno,Grp}, _Lc) -> - Grp1 = expr_list(Grp), + Grp1 = expr_list(bin_expand_strings(Grp)), {bin,ln(Anno),Grp1}; expr({bin_element,Anno,Expr,Size,Type}, _Lc) -> Expr1 = expr(Expr, false), @@ -519,6 +519,19 @@ consify([A|As]) -> {cons,0,A,consify(As)}; consify([]) -> {value,0,[]}. +%% The debugger converts both strings "abc" and lists [67, 68, 69] +%% into {value, Line, [67, 68, 69]}, making it impossible to later +%% distingish one or the other inside binaries when evaluating. To +%% avoid <<[67, 68, 69]>> from evaluating, we convert strings into +%% chars to avoid the ambiguity. +bin_expand_strings(Es) -> + lists:foldr(fun ({bin_element,Line,{string,_,S},Sz,Ts}, Es1) -> + lists:foldr(fun (C, Es2) -> + [{bin_element,Line,{char,Line,C},Sz,Ts}|Es2] + end, Es1, S); + (E, Es1) -> [E|Es1] + end, [], Es). + %% -type expr_list([Expression]) -> [Expression]. %% These expressions are processed "in parallel" for purposes of variable %% definition etc. |