aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src/beam_dict.erl
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2019-06-04 12:52:34 +0200
committerBjörn Gustavsson <[email protected]>2019-06-17 10:36:19 +0200
commitfccac1598cc13fcd9a3d7e85e2c4cae722f1bfc4 (patch)
treedec5d5fe89a38825b00435337d5983521099a6e5 /lib/compiler/src/beam_dict.erl
parent5943ff2cfb38f7ad572bb76abf425dd128dab72d (diff)
downloadotp-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.erl22
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'}