aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src/beam_dict.erl
diff options
context:
space:
mode:
authorPaul Guyot <[email protected]>2010-07-04 15:08:47 +0200
committerBjörn Gustavsson <[email protected]>2010-07-29 09:11:52 +0200
commit173d1fd1c3fef385f73accc4b2bbb1b6f92ac3f5 (patch)
tree830f6e894ef2aba363ee7147ac2fd6a55d8eebac /lib/compiler/src/beam_dict.erl
parent6ec6250f8ad4fd13318d13e566602dccc9f6746f (diff)
downloadotp-173d1fd1c3fef385f73accc4b2bbb1b6f92ac3f5.tar.gz
otp-173d1fd1c3fef385f73accc4b2bbb1b6f92ac3f5.tar.bz2
otp-173d1fd1c3fef385f73accc4b2bbb1b6f92ac3f5.zip
beam_asm: Simplify string table generation for beams
The code for generating the string table (which is now only used for bit syntax matching) in a BEAM file is quite complicated and potentially expensive when compiling modules with many thousands of clauses doing bit syntax matching. Simplify and optimize the code using bit syntax and binary:match/2 instead of the list operations in the original code.
Diffstat (limited to 'lib/compiler/src/beam_dict.erl')
-rw-r--r--lib/compiler/src/beam_dict.erl30
1 files changed, 14 insertions, 16 deletions
diff --git a/lib/compiler/src/beam_dict.erl b/lib/compiler/src/beam_dict.erl
index 9164259a94..a1f994dfbd 100644
--- a/lib/compiler/src/beam_dict.erl
+++ b/lib/compiler/src/beam_dict.erl
@@ -33,7 +33,7 @@
exports = [] :: [{label(), arity(), label()}],
locals = [] :: [{label(), arity(), label()}],
imports = gb_trees:empty() :: gb_tree(), %{{M,F,A},Index}
- strings = [] :: string(), %String pool
+ strings = <<>> :: binary(), %String pool
lambdas = [], %[{...}]
literals = dict:new() :: dict(), %Format: {Literal,Number}
next_atom = 1 :: pos_integer(),
@@ -119,10 +119,11 @@ import(Mod0, Name0, Arity, #asm{imports=Imp0,next_import=NextIndex}=D0)
string(Str, Dict) when is_list(Str) ->
#asm{strings=Strings,string_offset=NextOffset} = Dict,
- case old_string(Str, Strings) of
+ StrBin = list_to_binary(Str),
+ case old_string(StrBin, Strings) of
none ->
- NewDict = Dict#asm{strings=Strings++Str,
- string_offset=NextOffset+length(Str)},
+ NewDict = Dict#asm{strings = <<Strings/binary,StrBin/binary>>,
+ string_offset=NextOffset+byte_size(StrBin)},
{NextOffset,NewDict};
Offset when is_integer(Offset) ->
{NextOffset-Offset,Dict}
@@ -187,7 +188,7 @@ import_table(#asm{imports=Imp,next_import=NumImports}) ->
ImpTab = [MFA || {MFA,_} <- Sorted],
{NumImports,ImpTab}.
--spec string_table(bdict()) -> {non_neg_integer(), [string()]}.
+-spec string_table(bdict()) -> {non_neg_integer(), binary()}.
string_table(#asm{strings=Strings,string_offset=Size}) ->
{Size,Strings}.
@@ -217,15 +218,12 @@ literal_table(#asm{literals=Tab,next_literal=NumLiterals}) ->
my_term_to_binary(Term) ->
term_to_binary(Term, [{minor_version,1}]).
-%% Search for string Str in the string pool Pool.
+%% Search for binary string Str in the binary string pool Pool.
%% old_string(Str, Pool) -> none | Index
--spec old_string(string(), string()) -> 'none' | pos_integer().
-
-old_string([C|Str]=Str0, [C|Pool]) ->
- case lists:prefix(Str, Pool) of
- true -> length(Pool)+1;
- false -> old_string(Str0, Pool)
- end;
-old_string([_|_]=Str, [_|Pool]) ->
- old_string(Str, Pool);
-old_string([_|_], []) -> none.
+-spec old_string(binary(), binary()) -> 'none' | pos_integer().
+
+old_string(Str, Pool) ->
+ case binary:match(Pool, Str) of
+ nomatch -> none;
+ {Start,_Length} -> byte_size(Pool) - Start
+ end.