aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src/beam_bs.erl
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2019-01-12 15:57:32 +0100
committerBjörn Gustavsson <[email protected]>2019-01-16 13:06:00 +0100
commiteb0b8da6e816afde020e3f229803045f8b2bdb89 (patch)
tree1b59ad3c0dc45ea34138495d1e0a98a5bc565ff2 /lib/compiler/src/beam_bs.erl
parentc865abfcd396957e3c831a9f3dbe7922f63795be (diff)
downloadotp-eb0b8da6e816afde020e3f229803045f8b2bdb89.tar.gz
otp-eb0b8da6e816afde020e3f229803045f8b2bdb89.tar.bz2
otp-eb0b8da6e816afde020e3f229803045f8b2bdb89.zip
Refactor string operands
There are two instructions that take string operands: {bs_put_string,Fail,NumberOfBytes,{string,String}} {bs_match_string,Fail,Register,NumberOfBits,{string,String}} In the canonical BEAM code that is passed to beam_asm, string String is currently represented as a list. (The string in bs_match_string is a bitstring before the beam_z compiler pass.) That is wasteful, because there will be unnecessary conversions between lists and binaries. Change the representation of String to be a binary. Furthermore, bs_put_string is an optimization of a bs_put_binary instruction with a literal binary operand. Currently, the bs_put_string instruction is introduced in beam_bs. Delay the introduction of bs_put_string to the beam_z pass. That will simplify optimizations and allow us to do the optimization currently done in beam_bs in a SSA pass in a future commit.
Diffstat (limited to 'lib/compiler/src/beam_bs.erl')
-rw-r--r--lib/compiler/src/beam_bs.erl20
1 files changed, 13 insertions, 7 deletions
diff --git a/lib/compiler/src/beam_bs.erl b/lib/compiler/src/beam_bs.erl
index eea0cfcd02..9cf12be1b6 100644
--- a/lib/compiler/src/beam_bs.erl
+++ b/lib/compiler/src/beam_bs.erl
@@ -117,17 +117,23 @@ eval_put_float(Src, Sz, Flags) when Sz =< 256 ->
value({integer,I}) -> I;
value({float,F}) -> F.
-bs_collect_string(Is, [{bs_put,_,{bs_put_string,Len,{string,Str}},[]}|Acc]) ->
- bs_coll_str_1(Is, Len, reverse(Str), Acc);
+bs_collect_string(Is, [{bs_put,_,{bs_put_binary,1,_},
+ [{atom,all},{literal,BinString}]}|Acc]) ->
+ bs_coll_str_1(Is, BinString, Acc);
bs_collect_string(Is, Acc) ->
- bs_coll_str_1(Is, 0, [], Acc).
+ bs_coll_str_1(Is, <<>>, Acc).
+bs_coll_str_1([{bs_put,_,{bs_put_binary,1,_},
+ [{atom,all},{literal,BinString}]}|Is],
+ StrAcc, IsAcc) when is_binary(BinString) ->
+ bs_coll_str_1(Is, <<StrAcc/binary,BinString/binary>>, IsAcc);
bs_coll_str_1([{bs_put,_,{bs_put_integer,U,_},[{integer,Sz},{integer,V}]}|Is],
- Len, StrAcc, IsAcc) when U*Sz =:= 8 ->
+ StrAcc, IsAcc) when U*Sz =:= 8 ->
Byte = V band 16#FF,
- bs_coll_str_1(Is, Len+1, [Byte|StrAcc], IsAcc);
-bs_coll_str_1(Is, Len, StrAcc, IsAcc) ->
- {Is,[{bs_put,{f,0},{bs_put_string,Len,{string,reverse(StrAcc)}},[]}|IsAcc]}.
+ bs_coll_str_1(Is, <<StrAcc/binary,Byte>>, IsAcc);
+bs_coll_str_1(Is, StrAcc, IsAcc) ->
+ {Is,[{bs_put,{f,0},{bs_put_binary,1,{field_flags,[unsigned,big]}},
+ [{atom,all},{literal,StrAcc}]}|IsAcc]}.
field_endian({field_flags,F}) -> field_endian_1(F).