@@ -212,6 +212,34 @@ let record_primitive = function
212
212
primitive_declarations := p :: ! primitive_declarations
213
213
| _ -> ()
214
214
215
+ (* Helper for compiling value "let rec". This is only used for Flambda 2
216
+ at present, which uses the new [Dissect_letrec] module, planned to be
217
+ upstreamed. At that point this helper can move into that module. *)
218
+
219
+ let preallocate_letrec ~bindings ~body =
220
+ assert Config. flambda2;
221
+ let caml_update_dummy_prim =
222
+ Primitive. simple ~name: " caml_update_dummy" ~arity: 2 ~alloc: true
223
+ in
224
+ let update_dummy var expr =
225
+ Lprim (Pccall caml_update_dummy_prim, [Lvar var; expr], Loc_unknown )
226
+ in
227
+ let bindings = List. rev bindings in
228
+ let body_with_initialization =
229
+ List. fold_left
230
+ (fun body (id , def , _size ) -> Lsequence (update_dummy id def, body))
231
+ body bindings
232
+ in
233
+ List. fold_left
234
+ (fun body (id , _def , size ) ->
235
+ let desc =
236
+ Primitive. simple ~name: " caml_alloc_dummy" ~arity: 1 ~alloc: true
237
+ in
238
+ let size : lambda = Lconst (Const_base (Const_int size)) in
239
+ Llet (Strict , Pgenval , id,
240
+ Lprim (Pccall desc, [size], Loc_unknown ), body))
241
+ body_with_initialization bindings
242
+
215
243
(* Utilities for compiling "module rec" definitions *)
216
244
217
245
let mod_prim = Lambda. transl_prim " CamlinternalMod"
@@ -419,12 +447,14 @@ let compile_recmodule ~scopes compile_rhs bindings cont =
419
447
420
448
(* Code to translate class entries in a structure *)
421
449
450
+ let class_block_size = 4
451
+
422
452
let transl_class_bindings ~scopes cl_list =
423
453
let ids = List. map (fun (ci , _ ) -> ci.ci_id_class) cl_list in
424
454
(ids,
425
455
List. map
426
456
(fun ({ci_id_class =id ; ci_expr =cl ; ci_virt =vf } , meths ) ->
427
- (id, transl_class ~scopes ids id meths cl vf))
457
+ (id, transl_class ~scopes ids id meths cl vf, class_block_size ))
428
458
cl_list)
429
459
430
460
(* Compile one or more functors, merging curried functors to produce
@@ -709,7 +739,13 @@ and transl_structure ~scopes loc fields cc rootpath final_env = function
709
739
transl_structure ~scopes loc (List. rev_append ids fields)
710
740
cc rootpath final_env rem
711
741
in
712
- Lletrec (class_bindings, body), size
742
+ if Config. flambda2 then
743
+ preallocate_letrec ~bindings: class_bindings ~body , size
744
+ else
745
+ let class_bindings =
746
+ List. map (fun (id , lam , _ ) -> id, lam) class_bindings
747
+ in
748
+ Lletrec (class_bindings, body), size
713
749
| Tstr_include incl ->
714
750
let ids = bound_value_identifiers incl.incl_type in
715
751
let modl = incl.incl_mod in
@@ -1155,8 +1191,17 @@ let transl_store_structure ~scopes glob map prims aliases str =
1155
1191
(add_idents true ids subst) cont rem))
1156
1192
| Tstr_class cl_list ->
1157
1193
let (ids, class_bindings) = transl_class_bindings ~scopes cl_list in
1194
+ let body = store_idents Loc_unknown ids in
1158
1195
let lam =
1159
- Lletrec (class_bindings, store_idents Loc_unknown ids)
1196
+ if Config. flambda2 then
1197
+ preallocate_letrec
1198
+ ~bindings: class_bindings
1199
+ ~body
1200
+ else
1201
+ let class_bindings =
1202
+ List. map (fun (id , lam , _ ) -> id, lam) class_bindings
1203
+ in
1204
+ Lletrec (class_bindings, body)
1160
1205
in
1161
1206
Lsequence (Lambda. subst no_env_update subst lam,
1162
1207
transl_store ~scopes rootpath (add_idents false ids subst)
@@ -1524,7 +1569,14 @@ let transl_toplevel_item ~scopes item =
1524
1569
be a value named identically *)
1525
1570
let (ids, class_bindings) = transl_class_bindings ~scopes cl_list in
1526
1571
List. iter set_toplevel_unique_name ids;
1527
- Lletrec (class_bindings, make_sequence toploop_setvalue_id ids)
1572
+ let body = make_sequence toploop_setvalue_id ids in
1573
+ if Config. flambda2 then
1574
+ preallocate_letrec ~bindings: class_bindings ~body
1575
+ else
1576
+ let class_bindings =
1577
+ List. map (fun (id , lam , _ ) -> id, lam) class_bindings
1578
+ in
1579
+ Lletrec (class_bindings, body)
1528
1580
| Tstr_include incl ->
1529
1581
let ids = bound_value_identifiers incl.incl_type in
1530
1582
let modl = incl.incl_mod in
0 commit comments