@@ -41,18 +41,29 @@ let values_of_export =
4141 Lam_call_summary. Direct_external
4242 { dynamic_import; id; name; arity; relocatable }
4343 in
44+ (* Preserve sharing in the lambda graph when building recursive CMJ data. *)
45+ let memoize cache key f =
46+ match Ident.Hashtbl. find cache key with
47+ | value -> value
48+ | exception Not_found ->
49+ let value = f () in
50+ Ident.Hashtbl. replace cache ~key ~data: value;
51+ value
52+ in
53+ let arity_cache = Ident.Hashtbl. create 32 in
4454 let rec arity_of_lambda (meta : Lam_stats.t ) seen = function
45- | (Lam. Lvar v | Lmutvar v ) as lam -> (
46- if Ident.Set. mem v seen then Js_cmj_format. single_na
47- else
48- let seen = Ident.Set. add v seen in
49- match Ident.Hashtbl. find meta.ident_tbl v with
50- | ImmutableBlock elems ->
51- Js_cmj_format. Submodule
52- (Array. map elems ~f: (arity_of_element meta seen))
53- | FunctionId { arity; _ } -> Js_cmj_format. Single arity
54- | _ | (exception Not_found) ->
55- Js_cmj_format. Single (Lam_arity_analysis. get_arity meta lam))
55+ | (Lam. Lvar v | Lmutvar v ) as lam ->
56+ memoize arity_cache v (fun () ->
57+ if Ident.Set. mem v seen then Js_cmj_format. single_na
58+ else
59+ let seen = Ident.Set. add v seen in
60+ match Ident.Hashtbl. find meta.ident_tbl v with
61+ | ImmutableBlock elems ->
62+ Js_cmj_format. Submodule
63+ (Array. map elems ~f: (arity_of_element meta seen))
64+ | FunctionId { arity; _ } -> Js_cmj_format. Single arity
65+ | _ | (exception Not_found) ->
66+ Js_cmj_format. Single (Lam_arity_analysis. get_arity meta lam))
5667 | Lam. Lprim { primitive = Pmakeblock (_ , _ , Immutable); args; _ } ->
5768 Js_cmj_format. Submodule
5869 (Array. of_list_map args ~f: (arity_of_lambda meta seen))
@@ -105,19 +116,22 @@ let values_of_export =
105116 (if Lam_call_summary. is_relocatable summary then summary
106117 else Lam_call_summary. Unknown )
107118 in
119+ let nested_call_summary_cache = Ident.Hashtbl. create 32 in
108120 let rec nested_call_summary_of_lambda (meta : Lam_stats.t ) seen = function
109- | (Lam. Lvar v | Lmutvar v ) as lam -> (
110- if Ident.Set. mem v seen then Js_cmj_format. call_summary_unknown
111- else
112- let seen = Ident.Set. add v seen in
113- match Ident.Hashtbl. find meta.ident_tbl v with
114- | ImmutableBlock elems ->
115- Js_cmj_format. Call_summary_submodule
116- (Array. map elems ~f: (nested_call_summary_of_element meta seen))
117- | FunctionId { call_summary; _ } ->
118- nested_call_summary_of_summary call_summary
119- | _ | (exception Not_found) ->
120- Js_cmj_format. Call_summary (summarize meta lam))
121+ | (Lam. Lvar v | Lmutvar v ) as lam ->
122+ memoize nested_call_summary_cache v (fun () ->
123+ if Ident.Set. mem v seen then Js_cmj_format. call_summary_unknown
124+ else
125+ let seen = Ident.Set. add v seen in
126+ match Ident.Hashtbl. find meta.ident_tbl v with
127+ | ImmutableBlock elems ->
128+ Js_cmj_format. Call_summary_submodule
129+ (Array. map elems
130+ ~f: (nested_call_summary_of_element meta seen))
131+ | FunctionId { call_summary; _ } ->
132+ nested_call_summary_of_summary call_summary
133+ | _ | (exception Not_found) ->
134+ Js_cmj_format. Call_summary (summarize meta lam))
121135 | Lam. Lprim { primitive = Pmakeblock (_ , _ , Immutable); args; _ } ->
122136 Js_cmj_format. Call_summary_submodule
123137 (Array. of_list_map args ~f: (nested_call_summary_of_lambda meta seen))
@@ -134,22 +148,26 @@ let values_of_export =
134148 :
135149 Js_cmj_format. cmj_value String.Map. t
136150 ->
151+ Ident.Hashtbl. clear arity_cache;
152+ Ident.Hashtbl. clear nested_call_summary_cache;
137153 List. fold_left meta.exports ~init: String.Map. empty ~f: (fun acc x ->
138154 let arity =
139- match Ident.Hashtbl. find meta.ident_tbl x with
140- | FunctionId { arity; _ } -> Js_cmj_format. Single arity
141- | ImmutableBlock elems ->
142- (* FIXME: field name for dumping *)
143- Submodule
144- (Array. map elems
145- ~f: (arity_of_element meta (Ident.Set. singleton x)))
146- | _ | (exception Not_found) -> (
147- match Ident.Map. find x export_map with
148- | Lprim { primitive = Pmakeblock (_ , _ , Immutable); args; _ } ->
155+ memoize arity_cache x (fun () ->
156+ match Ident.Hashtbl. find meta.ident_tbl x with
157+ | FunctionId { arity; _ } -> Js_cmj_format. Single arity
158+ | ImmutableBlock elems ->
159+ (* FIXME: field name for dumping *)
149160 Submodule
150- (Array. of_list_map args
151- ~f: (arity_of_lambda meta (Ident.Set. singleton x)))
152- | _ | (exception Not_found) -> Js_cmj_format. single_na)
161+ (Array. map elems
162+ ~f: (arity_of_element meta (Ident.Set. singleton x)))
163+ | _ | (exception Not_found) -> (
164+ match Ident.Map. find x export_map with
165+ | Lprim { primitive = Pmakeblock (_, _, Immutable ); args; _ }
166+ ->
167+ Submodule
168+ (Array. of_list_map args
169+ ~f: (arity_of_lambda meta (Ident.Set. singleton x)))
170+ | _ | (exception Not_found) -> Js_cmj_format. single_na))
153171 in
154172 let persistent_closed_lambda =
155173 match Ident.Map. find x export_map with
@@ -206,25 +224,27 @@ let values_of_export =
206224 | exception Not_found -> Lam_call_summary. Unknown
207225 in
208226 let nested_call_summary =
209- match Ident.Hashtbl. find meta.ident_tbl x with
210- | FunctionId { call_summary; _ } ->
211- nested_call_summary_of_summary call_summary
212- | ImmutableBlock elems ->
213- Js_cmj_format. Call_summary_submodule
214- (Array. map elems
215- ~f:
216- (nested_call_summary_of_element meta
217- (Ident.Set. singleton x)))
218- | _ | (exception Not_found) -> (
219- match Ident.Map. find x export_map with
220- | Lprim { primitive = Pmakeblock (_ , _ , Immutable); args; _ } ->
227+ memoize nested_call_summary_cache x (fun () ->
228+ match Ident.Hashtbl. find meta.ident_tbl x with
229+ | FunctionId { call_summary; _ } ->
230+ nested_call_summary_of_summary call_summary
231+ | ImmutableBlock elems ->
221232 Js_cmj_format. Call_summary_submodule
222- (Array. of_list_map args
233+ (Array. map elems
223234 ~f:
224- (nested_call_summary_of_lambda meta
235+ (nested_call_summary_of_element meta
225236 (Ident.Set. singleton x)))
226- | lambda -> Js_cmj_format. Call_summary (summarize meta lambda)
227- | exception Not_found -> Js_cmj_format. call_summary_unknown)
237+ | _ | (exception Not_found) -> (
238+ match Ident.Map. find x export_map with
239+ | Lprim { primitive = Pmakeblock (_, _, Immutable ); args; _ }
240+ ->
241+ Js_cmj_format. Call_summary_submodule
242+ (Array. of_list_map args
243+ ~f:
244+ (nested_call_summary_of_lambda meta
245+ (Ident.Set. singleton x)))
246+ | lambda -> Js_cmj_format. Call_summary (summarize meta lambda)
247+ | exception Not_found -> Js_cmj_format. call_summary_unknown))
228248 in
229249 match (arity, persistent_closed_lambda, call_summary) with
230250 | Single Arity_na , (None | Some (Lconst Const_module_alias , _)), summary
0 commit comments