Skip to content

Commit c3dd400

Browse files
author
José Valim
committed
Reduce atom footprint when compiling an elixir module
1 parent e05448a commit c3dd400

File tree

7 files changed

+41
-35
lines changed

7 files changed

+41
-35
lines changed

lib/elixir/lib/module.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -613,11 +613,11 @@ defmodule Module do
613613
end
614614

615615
defp function_table_for(module) do
616-
list_to_atom :lists.concat([:f, module])
616+
:elixir_def.table(module)
617617
end
618618

619619
defp docs_table_for(module) do
620-
list_to_atom :lists.concat([:o, module])
620+
:elixir_module.docs_table(module)
621621
end
622622

623623
defp assert_not_compiled!(fun, module) do

lib/elixir/src/elixir_def.erl

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,22 @@
1616
format_error/1]).
1717
-include("elixir.hrl").
1818

19+
-define(attr, '__def_table').
20+
-define(clauses_attr, '__clauses_table').
21+
1922
%% Table management functions. Called internally.
2023

21-
table(Module) -> ?atom_concat([f, Module]).
22-
clauses_table(Module) -> ?atom_concat([c, Module]).
24+
table(Module) ->
25+
ets:lookup_element(Module, ?attr, 2).
26+
27+
clauses_table(Module) ->
28+
ets:lookup_element(Module, ?clauses_attr, 2).
2329

2430
setup(Module) ->
25-
FunctionsTable = table(Module),
26-
ClausesTable = clauses_table(Module),
27-
ets:new(FunctionsTable, [set, named_table, public]),
28-
ets:new(ClausesTable, [bag, named_table, public]),
31+
ets:insert(Module, { ?attr, ets:new(Module, [set, public]) }),
32+
ets:insert(Module, { ?clauses_attr, ets:new(Module, [bag, public]) }),
2933
reset_last(Module),
30-
{ FunctionsTable, ClausesTable }.
34+
ok.
3135

3236
cleanup(Module) ->
3337
ets:delete(table(Module)),

lib/elixir/src/elixir_dispatch.erl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ import_function(Meta, Name, Arity, S) ->
4141
{ import, Receiver } ->
4242
require_function(Meta, Receiver, Name, Arity, S);
4343
nomatch ->
44-
elixir_def_local:record(Tuple, S),
44+
elixir_locals:record(Tuple, S),
4545
{ { 'fun', ?line(Meta), { function, Name, Arity } }, S }
4646
end.
4747

@@ -124,7 +124,7 @@ do_expand_import(Meta, { Name, Arity } = Tuple, Args, Module, S, Result) ->
124124
expand_require(Meta, Receiver, Tuple, Args, Module, S);
125125
_ ->
126126
Fun = (S#elixir_scope.function /= Tuple) andalso
127-
elixir_def_local:macro_for(Tuple, true, S),
127+
elixir_locals:macro_for(Tuple, true, S),
128128
case Fun of
129129
false -> { error, noexpansion };
130130
_ ->
@@ -144,7 +144,7 @@ expand_require(Meta, ?BUILTIN, { Name, Arity } = Tuple, Args, Module, S) ->
144144

145145
expand_require(Meta, Receiver, { Name, Arity } = Tuple, Args, Module, S) ->
146146
Fun = (Module == Receiver) andalso (S#elixir_scope.function /= Tuple) andalso
147-
elixir_def_local:macro_for(Tuple, false, S),
147+
elixir_locals:macro_for(Tuple, false, S),
148148

149149
case Fun of
150150
false ->

lib/elixir/src/elixir_import.erl

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
setup/1, cleanup/1, record/3]).
99
-include("elixir.hrl").
1010

11+
-define(attr, '__imports_table').
12+
1113
%% This table keeps:
1214
%%
1315
%% * Invoked imports and requires in the format
@@ -16,10 +18,11 @@
1618
%% * The current warn status imports and requires
1719
%% in the format { Module, Line :: integer }
1820
%%
19-
table(Module) -> ?atom_concat([i, Module]).
21+
table(Module) ->
22+
ets:lookup_element(Module, ?attr, 2).
2023

2124
setup(Module) ->
22-
ets:new(table(Module), [bag, named_table, public]).
25+
ets:insert(Module, { ?attr, ets:new(Module, [bag, public]) }).
2326

2427
cleanup(Module) ->
2528
ets:delete(table(Module)).
@@ -169,8 +172,7 @@ get_optional_macros(Module) ->
169172
%% VALIDATION HELPERS
170173

171174
%% Check if any of the locals defined conflicts with an invoked
172-
%% Elixir "implemented in Erlang" macro. Checking if a local
173-
%% conflicts with an import is automatically done by Erlang.
175+
%% Elixir "implemented in Erlang" macro.
174176

175177
ensure_no_local_conflict(Meta, File, Module, AllDefined) ->
176178
ensure_no_special_form_conflict(Meta, File, Module, AllDefined, local_conflict).

lib/elixir/src/elixir_def_local.erl renamed to lib/elixir/src/elixir_locals.erl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
%% Module responsible for local invocation of macros and functions.
2-
-module(elixir_def_local).
2+
-module(elixir_locals).
33
-export([
44
setup/1, cleanup/1,
55
record/2, record_root/2,

lib/elixir/src/elixir_module.erl

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
-module(elixir_module).
2-
-export([translate/4, compile/5, data_table/1, eval_quoted/4,
3-
format_error/1, eval_callbacks/5]).
2+
-export([translate/4, compile/5, data_table/1, docs_table/1,
3+
eval_quoted/4, format_error/1, eval_callbacks/5]).
44
-include("elixir.hrl").
55

6+
-define(docs_attr, '__docs_table').
7+
-define(acc_attr, '__acc_attributes').
8+
-define(persisted_attr, '__persisted_attributes').
9+
610
eval_quoted(Module, Quoted, RawBinding, Opts) ->
711
Binding = binding_for_eval(Module, RawBinding),
812
Scope = scope_for_eval(Module, Opts),
@@ -31,7 +35,7 @@ data_table(Module) ->
3135
Module.
3236

3337
docs_table(Module) ->
34-
?atom_concat([o, Module]).
38+
ets:lookup_element(Module, ?docs_attr, 2).
3539

3640
%% TRANSFORMATION FUNCTIONS
3741

@@ -73,10 +77,10 @@ compile(Line, Module, Block, Vars, #elixir_scope{context_modules=FileModules} =
7377
case ets:lookup(data_table(Module), 'on_load') of
7478
[] -> ok;
7579
[{on_load,OnLoad}] ->
76-
[elixir_def_local:record_root(Module, Tuple) || Tuple <- OnLoad]
80+
[elixir_locals:record_root(Module, Tuple) || Tuple <- OnLoad]
7781
end,
7882

79-
elixir_def_local:check_unused_local(File, Module, Private),
83+
elixir_locals:check_unused_local(File, Module, Private),
8084

8185
elixir_import:ensure_all_imports_used(Line, File, Module),
8286
elixir_import:ensure_no_local_conflict(Line, File, Module, All),
@@ -90,11 +94,11 @@ compile(Line, Module, Block, Vars, #elixir_scope{context_modules=FileModules} =
9094
Binary = load_form(Line, Final, S),
9195
{ module, Module, Binary, Result }
9296
after
93-
elixir_def_local:cleanup(Module),
94-
elixir_def:cleanup(Module),
9597
elixir_import:cleanup(Module),
96-
ets:delete(data_table(Module)),
97-
ets:delete(docs_table(Module))
98+
elixir_locals:cleanup(Module),
99+
elixir_def:cleanup(Module),
100+
ets:delete(docs_table(Module)),
101+
ets:delete(data_table(Module))
98102
end;
99103

100104
compile(Line, Other, _Block, _Vars, #elixir_scope{file=File}) ->
@@ -127,17 +131,13 @@ build(Line, File, Module) ->
127131
end,
128132

129133
Attributes = [behavior, behaviour, on_load, spec, type, export_type, opaque, callback, compile],
130-
ets:insert(DataTable, { '__acc_attributes', [before_compile,after_compile,on_definition|Attributes] }),
131-
ets:insert(DataTable, { '__persisted_attributes', [vsn|Attributes] }),
132-
133-
%% Keep docs in another table since we don't want to pull out
134-
%% all the binaries every time a new documentation is stored.
135-
DocsTable = docs_table(Module),
136-
ets:new(DocsTable, [ordered_set, named_table, public]),
134+
ets:insert(DataTable, { ?acc_attr, [before_compile,after_compile,on_definition|Attributes] }),
135+
ets:insert(DataTable, { ?persisted_attr, [vsn|Attributes] }),
136+
ets:insert(DataTable, { ?docs_attr, ets:new(DataTable, [ordered_set, public]) }),
137137

138138
%% Setup other modules
139-
elixir_def_local:setup(Module),
140139
elixir_def:setup(Module),
140+
elixir_locals:setup(Module),
141141
elixir_import:setup(Module).
142142

143143
%% Receives the module representation and evaluates it.

lib/elixir/src/elixir_translator.erl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -578,7 +578,7 @@ translate_fn(Meta, Clauses, S) ->
578578
%% Locals
579579

580580
translate_local(Meta, Name, Args, #elixir_scope{local=nil} = S) ->
581-
elixir_def_local:record({ Name, length(Args) }, S),
581+
elixir_locals:record({ Name, length(Args) }, S),
582582
Line = ?line(Meta),
583583
{ TArgs, NS } = translate_args(Args, S),
584584
{ { call, Line, { atom, Line, Name }, TArgs }, NS };

0 commit comments

Comments
 (0)