diff options
author | Paul Guyot <[email protected]> | 2010-07-04 15:08:47 +0200 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2010-07-29 09:11:52 +0200 |
commit | 173d1fd1c3fef385f73accc4b2bbb1b6f92ac3f5 (patch) | |
tree | 830f6e894ef2aba363ee7147ac2fd6a55d8eebac /lib/compiler/src/beam_dict.erl | |
parent | 6ec6250f8ad4fd13318d13e566602dccc9f6746f (diff) | |
download | otp-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.erl | 30 |
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. |