@@ -740,8 +740,10 @@ let transl_structured_constant cst =
740
740
741
741
(* Translate constant closures *)
742
742
743
+ type is_global = Global | Not_global
744
+
743
745
let constant_closures =
744
- ref ([] : (string * ufunction list * uconstant list ) list )
746
+ ref ([] : (( string * is_global ) * ufunction list * uconstant list ) list )
745
747
746
748
(* Boxed integers *)
747
749
@@ -1423,7 +1425,7 @@ let rec transl env e =
1423
1425
transl_constant sc
1424
1426
| Uclosure (fundecls , [] ) ->
1425
1427
let lbl = Compilenv. new_const_symbol() in
1426
- constant_closures := (lbl, fundecls, [] ) :: ! constant_closures;
1428
+ constant_closures := (( lbl, Not_global ) , fundecls, [] ) :: ! constant_closures;
1427
1429
List. iter (fun f -> Queue. add f functions) fundecls;
1428
1430
Cconst_symbol lbl
1429
1431
| Uclosure (fundecls , clos_vars ) ->
@@ -2426,14 +2428,19 @@ let rec transl_all_functions already_translated cont =
2426
2428
with Queue. Empty ->
2427
2429
cont, already_translated
2428
2430
2431
+ let cdefine_symbol (symb , global ) =
2432
+ match global with
2433
+ | Global -> [Cglobal_symbol symb; Cdefine_symbol symb]
2434
+ | Not_global -> [Cdefine_symbol symb]
2435
+
2429
2436
(* Emit structured constants *)
2430
2437
2431
2438
let rec emit_structured_constant symb cst cont =
2432
2439
let emit_block white_header symb cont =
2433
2440
(* Headers for structured constants must be marked black in case we
2434
2441
are in no-naked-pointers mode. See [caml_darken]. *)
2435
2442
let black_header = Nativeint. logor white_header caml_black in
2436
- Cint black_header :: Cdefine_symbol symb :: cont
2443
+ Cint black_header :: cdefine_symbol symb @ cont
2437
2444
in
2438
2445
match cst with
2439
2446
| Uconst_float s ->
@@ -2457,7 +2464,8 @@ let rec emit_structured_constant symb cst cont =
2457
2464
emit_block (floatarray_header (List. length fields)) symb
2458
2465
(Misc. map_end (fun f -> Cdouble f) fields cont)
2459
2466
| Uconst_closure (fundecls , lbl , fv ) ->
2460
- constant_closures := (lbl, fundecls, fv) :: ! constant_closures;
2467
+ assert (lbl = fst symb);
2468
+ constant_closures := (symb, fundecls, fv) :: ! constant_closures;
2461
2469
List. iter (fun f -> Queue. add f functions) fundecls;
2462
2470
cont
2463
2471
@@ -2518,7 +2526,7 @@ let emit_constant_closure symb fundecls clos_vars cont =
2518
2526
emit_others (pos + 4 ) rem in
2519
2527
Cint (black_closure_header (fundecls_size fundecls
2520
2528
+ List. length clos_vars)) ::
2521
- Cdefine_symbol symb ::
2529
+ cdefine_symbol symb @
2522
2530
if f1.arity = 1 || f1.arity = 0 then
2523
2531
Csymbol_address f1.label ::
2524
2532
cint_const f1.arity ::
@@ -2531,24 +2539,26 @@ let emit_constant_closure symb fundecls clos_vars cont =
2531
2539
2532
2540
(* Emit all structured constants *)
2533
2541
2534
- let emit_all_constants cont =
2542
+ let emit_constants cont ( constants :Clambda.preallocated_constant list ) =
2535
2543
let c = ref cont in
2536
2544
List. iter
2537
- (fun (lbl , global , cst ) ->
2538
- let cst = emit_structured_constant lbl cst [] in
2539
- let cst = if global then
2540
- Cglobal_symbol lbl :: cst
2541
- else cst in
2545
+ (fun { symbol = lbl ; exported; definition = cst } ->
2546
+ let global = if exported then Global else Not_global in
2547
+ let cst = emit_structured_constant (lbl, global) cst [] in
2542
2548
c:= Cdata (cst):: ! c)
2543
- ( Compilenv. structured_constants () ) ;
2549
+ constants ;
2544
2550
List. iter
2545
2551
(fun (symb , fundecls , clos_vars ) ->
2546
2552
c := Cdata (emit_constant_closure symb fundecls clos_vars [] ) :: ! c)
2547
2553
! constant_closures;
2548
2554
constant_closures := [] ;
2549
- Compilenv. clear_structured_constants () ;
2550
2555
! c
2551
2556
2557
+ let emit_all_constants cont =
2558
+ let constants = Compilenv. structured_constants () in
2559
+ Compilenv. clear_structured_constants () ;
2560
+ emit_constants cont constants
2561
+
2552
2562
let transl_all_functions_and_emit_all_constants cont =
2553
2563
let rec aux already_translated cont =
2554
2564
if Compilenv. structured_constants () = [] &&
@@ -2571,17 +2581,10 @@ let emit_module_roots_table ~symbols cont =
2571
2581
[Cint 0n ])
2572
2582
:: cont
2573
2583
2574
- (* Translate a compilation unit *)
2584
+ (* Build preallocated blocks (used for Flambda [Initialize_symbol]
2585
+ constructs, and Clambda global module) *)
2575
2586
2576
- let compunit size ulam =
2577
- let glob = Compilenv. make_symbol None in
2578
- let init_code = transl empty_env ulam in
2579
- let c1 = [Cfunction {fun_name = Compilenv. make_symbol (Some " entry" );
2580
- fun_args = [] ;
2581
- fun_body = init_code; fun_fast = false ;
2582
- fun_dbg = Debuginfo. none }] in
2583
- let c2 = transl_all_functions_and_emit_all_constants c1 in
2584
- let c3 = emit_module_roots_table ~symbols: [glob] c2 in
2587
+ let preallocate_block cont { Clambda. symbol; exported; tag; size } =
2585
2588
let space =
2586
2589
(* These words will be registered as roots and as such must contain
2587
2590
valid values, in case we are in no-naked-pointers mode. Likewise
@@ -2591,9 +2594,35 @@ let compunit size ulam =
2591
2594
(Array. init size (fun _index ->
2592
2595
Cint (Nativeint. of_int 1 (* Val_unit *) )))
2593
2596
in
2594
- Cdata ([Cint (black_block_header 0 size);
2595
- Cglobal_symbol glob;
2596
- Cdefine_symbol glob] @ space) :: c3
2597
+ let data =
2598
+ Cint (black_block_header tag size) ::
2599
+ if exported then
2600
+ Cglobal_symbol symbol ::
2601
+ Cdefine_symbol symbol :: space
2602
+ else
2603
+ Cdefine_symbol symbol :: space
2604
+ in
2605
+ Cdata data :: cont
2606
+
2607
+ let emit_preallocated_blocks preallocated_blocks cont =
2608
+ let symbols =
2609
+ List. map (fun ({ Clambda. symbol } :Clambda.preallocated_block ) -> symbol)
2610
+ preallocated_blocks
2611
+ in
2612
+ let c1 = emit_module_roots_table ~symbols cont in
2613
+ List. fold_left preallocate_block c1 preallocated_blocks
2614
+
2615
+ (* Translate a compilation unit *)
2616
+
2617
+ let compunit (ulam , preallocated_blocks , constants ) =
2618
+ let init_code = transl empty_env ulam in
2619
+ let c1 = [Cfunction {fun_name = Compilenv. make_symbol (Some " entry" );
2620
+ fun_args = [] ;
2621
+ fun_body = init_code; fun_fast = false ;
2622
+ fun_dbg = Debuginfo. none }] in
2623
+ let c2 = emit_constants c1 constants in
2624
+ let c3 = transl_all_functions_and_emit_all_constants c2 in
2625
+ emit_preallocated_blocks preallocated_blocks c3
2597
2626
2598
2627
(*
2599
2628
CAMLprim value caml_cache_public_method (value meths, value tag, value *cache)
@@ -2938,8 +2967,7 @@ let reference_symbols namelist =
2938
2967
Cdata (List. map mksym namelist)
2939
2968
2940
2969
let global_data name v =
2941
- Cdata (Cglobal_symbol name ::
2942
- emit_structured_constant name
2970
+ Cdata (emit_structured_constant (name, Global )
2943
2971
(Uconst_string (Marshal. to_string v [] )) [] )
2944
2972
2945
2973
let globals_map v = global_data " caml_globals_map" v
@@ -2979,9 +3007,8 @@ let predef_exception i name =
2979
3007
let symname = " caml_exn_" ^ name in
2980
3008
let cst = Uconst_string name in
2981
3009
let label = Compilenv. new_const_symbol () in
2982
- let cont = emit_structured_constant label cst [] in
2983
- Cdata (Cglobal_symbol symname ::
2984
- emit_structured_constant symname
3010
+ let cont = emit_structured_constant (label, Not_global ) cst [] in
3011
+ Cdata (emit_structured_constant (symname, Global )
2985
3012
(Uconst_block (Obj. object_tag,
2986
3013
[
2987
3014
Uconst_ref (label, Some cst);
0 commit comments