Skip to content

Commit 1316312

Browse files
committed
Only translate or dwarf-emit items or stubs locally defined or used. Avoids instantiating O(sizeof(standard-library)) worth of imports stubs on each 'use std'. Closes issue 13.
1 parent 7045526 commit 1316312

File tree

7 files changed

+269
-36
lines changed

7 files changed

+269
-36
lines changed

src/boot/fe/item.ml

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -876,17 +876,31 @@ and parse_mod_item (ps:pstate) : (Ast.ident * Ast.mod_item) =
876876
and parse_mod_items_from_signature
877877
(ps:pstate)
878878
: (Ast.mod_view * Ast.mod_items) =
879-
let mis = Hashtbl.create 0 in
880-
expect ps LBRACE;
881-
while not (peek ps = RBRACE)
882-
do
879+
let exports = Hashtbl.create 0 in
880+
let mis = Hashtbl.create 0 in
881+
let in_view = ref true in
882+
expect ps LBRACE;
883+
while not (peek ps = RBRACE)
884+
do
885+
if !in_view
886+
then
887+
match peek ps with
888+
EXPORT ->
889+
bump ps;
890+
parse_export ps exports;
891+
expect ps SEMI;
892+
| _ ->
893+
in_view := false
894+
else
883895
let (ident, mti) = ctxt "mod items from sig: mod item"
884896
parse_mod_item_from_signature ps
885897
in
886898
Hashtbl.add mis ident mti;
887-
done;
888-
expect ps RBRACE;
889-
(empty_view, mis)
899+
done;
900+
if (Hashtbl.length exports) = 0
901+
then Hashtbl.add exports Ast.EXPORT_all_decls ();
902+
expect ps RBRACE;
903+
({empty_view with Ast.view_exports = exports}, mis)
890904

891905

892906
and parse_mod_item_from_signature (ps:pstate)

src/boot/me/dwarf.ml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2517,11 +2517,12 @@ let process_crate
25172517

25182518
let passes =
25192519
[|
2520-
dwarf_visitor cx Walk.empty_visitor path
2521-
cx.ctxt_debug_info_fixup
2522-
cu_aranges cu_pubnames
2523-
cu_infos cu_abbrevs
2524-
cu_lines cu_frames
2520+
unreferenced_required_item_ignoring_visitor cx
2521+
(dwarf_visitor cx Walk.empty_visitor path
2522+
cx.ctxt_debug_info_fixup
2523+
cu_aranges cu_pubnames
2524+
cu_infos cu_abbrevs
2525+
cu_lines cu_frames)
25252526
|];
25262527
in
25272528

src/boot/me/resolve.ml

Lines changed: 83 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -730,11 +730,33 @@ let lval_base_resolving_visitor
730730
(int_of_node nb.id) (int_of_node referent_id));
731731
htab_put cx.ctxt_lval_to_referent nb.id referent_id
732732
in
733+
734+
(*
735+
* The point here is just to tickle the reference-a-name machinery in
736+
* lookup that makes sure that all and only those items referenced get
737+
* processed by later stages. An lval that happens to be an item will
738+
* mark the item in question here.
739+
*)
740+
let reference_any_name lv =
741+
let rec lval_is_name lv =
742+
match lv with
743+
Ast.LVAL_base {node = Ast.BASE_ident _}
744+
| Ast.LVAL_base {node = Ast.BASE_app _} -> true
745+
| Ast.LVAL_ext (lv', Ast.COMP_named (Ast.COMP_ident _))
746+
| Ast.LVAL_ext (lv', Ast.COMP_named (Ast.COMP_app _))
747+
-> lval_is_name lv'
748+
| _ -> false
749+
in
750+
if lval_is_name lv && lval_is_item cx lv
751+
then ignore (lookup_by_name cx (!scopes) (lval_to_name lv))
752+
in
753+
733754
lookup_lval lv;
755+
reference_any_name lv;
734756
inner.Walk.visit_lval_pre lv
735757
in
736758
{ inner with
737-
Walk.visit_lval_pre = visit_lval_pre }
759+
Walk.visit_lval_pre = visit_lval_pre };
738760
;;
739761

740762

@@ -868,7 +890,8 @@ let resolve_recursion
868890

869891
let pattern_resolving_visitor
870892
(cx:ctxt)
871-
(inner:Walk.visitor) : Walk.visitor =
893+
(inner:Walk.visitor)
894+
: Walk.visitor =
872895

873896
let not_tag_ctor nm id : unit =
874897
err (Some id) "'%s' is not a tag constructor" (string_of_name nm)
@@ -934,6 +957,43 @@ let pattern_resolving_visitor
934957
{ inner with Walk.visit_stmt_pre = visit_stmt_pre }
935958
;;
936959

960+
let export_referencing_visitor
961+
(cx:ctxt)
962+
(inner:Walk.visitor)
963+
: Walk.visitor =
964+
let visit_mod_item_pre id params item =
965+
begin
966+
match item.node.Ast.decl_item with
967+
Ast.MOD_ITEM_mod (view, items) ->
968+
let is_defining_mod =
969+
(* auto-ref the default-export cases only if
970+
* the containing mod is 'defining', meaning
971+
* not-native / not-use
972+
*)
973+
not (Hashtbl.mem cx.ctxt_required_items item.id)
974+
in
975+
let reference _ item =
976+
Hashtbl.replace cx.ctxt_node_referenced item.id ();
977+
in
978+
let reference_export e _ =
979+
match e with
980+
Ast.EXPORT_ident ident ->
981+
let item = Hashtbl.find items ident in
982+
reference ident item
983+
| Ast.EXPORT_all_decls ->
984+
if is_defining_mod
985+
then Hashtbl.iter reference items
986+
in
987+
Hashtbl.iter reference_export view.Ast.view_exports
988+
| _ -> ()
989+
end;
990+
inner.Walk.visit_mod_item_pre id params item
991+
in
992+
{ inner with Walk.visit_mod_item_pre = visit_mod_item_pre }
993+
994+
995+
;;
996+
937997
let process_crate
938998
(cx:ctxt)
939999
(crate:Ast.crate)
@@ -957,6 +1017,7 @@ let process_crate
9571017
Walk.empty_visitor))
9581018
|]
9591019
in
1020+
9601021
let passes_1 =
9611022
[|
9621023
(scope_stack_managing_visitor scopes
@@ -966,20 +1027,38 @@ let process_crate
9661027
Walk.empty_visitor)));
9671028
|]
9681029
in
1030+
9691031
let passes_2 =
9701032
[|
9711033
(scope_stack_managing_visitor scopes
9721034
(pattern_resolving_visitor cx
973-
Walk.empty_visitor))
1035+
Walk.empty_visitor));
1036+
export_referencing_visitor cx Walk.empty_visitor
9741037
|]
9751038
in
1039+
9761040
log cx "running primary resolve passes";
9771041
run_passes cx "resolve collect" path passes_0 (log cx "%s") crate;
9781042
resolve_recursion cx node_to_references recursive_tag_groups;
9791043
log cx "running secondary resolve passes";
9801044
run_passes cx "resolve bind" path passes_1 (log cx "%s") crate;
9811045
log cx "running tertiary resolve passes";
982-
run_passes cx "resolve patterns" path passes_2 (log cx "%s") crate
1046+
run_passes cx "resolve patterns" path passes_2 (log cx "%s") crate;
1047+
1048+
iflog cx
1049+
begin
1050+
fun _ ->
1051+
Hashtbl.iter
1052+
begin
1053+
fun n _ ->
1054+
if referent_is_item cx n
1055+
then
1056+
log cx "referenced: %a"
1057+
Ast.sprintf_name
1058+
(Hashtbl.find cx.ctxt_all_item_names n)
1059+
end
1060+
cx.ctxt_node_referenced;
1061+
end
9831062
;;
9841063

9851064
(*

0 commit comments

Comments
 (0)