diff options
author | Björn Gustavsson <[email protected]> | 2019-06-04 12:52:34 +0200 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2019-06-17 10:36:19 +0200 |
commit | fccac1598cc13fcd9a3d7e85e2c4cae722f1bfc4 (patch) | |
tree | dec5d5fe89a38825b00435337d5983521099a6e5 /lib/compiler/src/beam_dict.erl | |
parent | 5943ff2cfb38f7ad572bb76abf425dd128dab72d (diff) | |
download | otp-fccac1598cc13fcd9a3d7e85e2c4cae722f1bfc4.tar.gz otp-fccac1598cc13fcd9a3d7e85e2c4cae722f1bfc4.tar.bz2 otp-fccac1598cc13fcd9a3d7e85e2c4cae722f1bfc4.zip |
Create a shared wrapper function for all occurrences of 'fun F/A'
If the `fun F/A` syntax is used multiple times with the same `F/A`,
(for examle, `fun foo/2`), there would a wrapper function and fun
entry generated for each occurrence.
Using the new support in the OTP 23 runtime system, generate a single
wrapper function and fun entry for each `F/A`. Since there is only one
wrapper function, it can be named based on the name of the function it
calls to faciliate debugging, not based on the function that defines
the fun. For example, the wrapper function for `fun foo/0` will now be
named `-fun.foo/0-'.
Diffstat (limited to 'lib/compiler/src/beam_dict.erl')
-rw-r--r-- | lib/compiler/src/beam_dict.erl | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/lib/compiler/src/beam_dict.erl b/lib/compiler/src/beam_dict.erl index b2056332e6..4d0cec857d 100644 --- a/lib/compiler/src/beam_dict.erl +++ b/lib/compiler/src/beam_dict.erl @@ -40,6 +40,7 @@ -type lambda_info() :: {label(),{index(),label(),non_neg_integer()}}. -type lambda_tab() :: {non_neg_integer(),[lambda_info()]}. +-type wrapper() :: #{label() => index()}. -record(asm, {atoms = #{} :: atom_tab(), @@ -48,6 +49,7 @@ imports = gb_trees:empty() :: import_tab(), strings = <<>> :: binary(), %String pool lambdas = {0,[]} :: lambda_tab(), + wrappers = #{} :: wrapper(), literals = dict:new() :: literal_tab(), fnames = #{} :: fname_tab(), lines = #{} :: line_tab(), @@ -147,11 +149,21 @@ string(BinString, Dict) when is_binary(BinString) -> -spec lambda(label(), non_neg_integer(), bdict()) -> {non_neg_integer(), bdict()}. -lambda(Lbl, NumFree, #asm{lambdas={OldIndex,Lambdas0}}=Dict) -> - %% Set Index the same as OldIndex. - Index = OldIndex, - Lambdas = [{Lbl,{Index,Lbl,NumFree}}|Lambdas0], - {OldIndex,Dict#asm{lambdas={OldIndex+1,Lambdas}}}. +lambda(Lbl, NumFree, #asm{wrappers=Wrappers0, + lambdas={OldIndex,Lambdas0}}=Dict) -> + case Wrappers0 of + #{Lbl:=Index} -> + %% OTP 23: There old is a fun entry for this wrapper function. + %% Share the fun entry. + {Index,Dict}; + #{} -> + %% Set Index the same as OldIndex. + Index = OldIndex, + Wrappers = Wrappers0#{Lbl=>Index}, + Lambdas = [{Lbl,{Index,Lbl,NumFree}}|Lambdas0], + {OldIndex,Dict#asm{wrappers=Wrappers, + lambdas={OldIndex+1,Lambdas}}} + end. %% Returns the index for a literal (adding it to the literal table if necessary). %% literal(Literal, Dict) -> {Index,Dict'} |