Skip to content

Commit 3fdb072

Browse files
Hongbo Zhangbobzhang
authored andcommitted
generate slots beforehand (+1 squashed commits)
Squashed commits: [b1e23bc] tweak [6b9806e] wip
1 parent c8508ae commit 3fdb072

31 files changed

+243
-131
lines changed

jscomp/core.mllib

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
type_int_to_string
12
type_util
23
ident_map
3-
4+
ocaml_stdlib_slots
45
ident_util
56
idents_analysis
67
config_util

jscomp/gen_slots.ml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#directory "+compiler-libs";;
2+
#load "ocamlcommon.cma";;
3+
#mod_use "type_int_to_string.ml"
4+
5+
let slots_of_stdlib_cmi filename : string list =
6+
let info = Cmi_format.read_cmi (Filename.concat Config.standard_library filename) in
7+
List.map (fun x -> Ident.name (Type_int_to_string.name_of_signature_item x)) @@
8+
List.filter Type_int_to_string.serializable_signature info.cmi_sign
9+
10+
11+
12+
13+
let code_of_array files =
14+
let code =
15+
List.map (fun file ->
16+
let codes = slots_of_stdlib_cmi file in
17+
Printf.sprintf "let %s = [| %s |]"
18+
(Filename.chop_extension file )
19+
(String.concat ";" (List.map (Printf.sprintf "%S") codes)) ) files in
20+
String.concat "\n" code
21+
22+
(** Generate fixed slots
23+
ATTENTION: we need re-run the code when we upgrade the compiler
24+
We do this to avoid dependencies
25+
*)
26+
let _ = print_endline (code_of_array ["pervasives.cmi"; "camlinternalOO.cmi"; "camlinternalMod.cmi"])

jscomp/gen_slots.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#!/bin/sh
2+
set -e
3+
ocaml -w -40 gen_slots.ml > ocaml_stdlib_slots.ml

jscomp/js_cmj_format.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131

3232
(* TODO: add a magic number *)
3333
type cmj_value = {
34-
arity : Lam_stats.function_arities ;
34+
arity : Lam.function_arities ;
3535
closed_lambda : Lam.t option ;
3636
(** Either constant or closed functor *)
3737
}

jscomp/js_cmj_format.mli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
*)
5454

5555
type cmj_value = {
56-
arity : Lam_stats.function_arities ;
56+
arity : Lam.function_arities ;
5757
closed_lambda : Lam.t option ;
5858
(* Either constant or closed functor *)
5959
}

jscomp/lam.ml

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ type field_dbg_info = Lambda.field_dbg_info
3535
type set_field_dbg_info = Lambda.set_field_dbg_info
3636

3737
type ident = Ident.t
38+
39+
type function_arities =
40+
| Determin of bool * (int * Ident.t list option) list * bool
41+
| NA
42+
3843
type primitive =
3944
| Pbytes_to_string
4045
| Pbytes_of_string
@@ -73,6 +78,7 @@ type primitive =
7378
| Pstringlength
7479
| Pstringrefu
7580
| Pstringrefs
81+
| Pstringadd
7682
| Pbyteslength
7783
| Pbytesrefu
7884
| Pbytessetu
@@ -142,7 +148,8 @@ type primitive =
142148
| Pjs_fn_make of int
143149
| Pjs_fn_run of int
144150
| Pjs_fn_method of int
145-
| Pjs_fn_runmethod of int
151+
| Pjs_fn_runmethod of int
152+
146153
type switch =
147154
{ sw_numconsts: int;
148155
sw_consts: (int * t) list;
@@ -680,28 +687,34 @@ let rec convert (lam : Lambda.lambda) : t =
680687
]
681688
) -> (* replace all {!CamlinternalMod} function *)
682689
let args = List.map convert args in
683-
if id = 0 then
684-
match args with
685-
| [_loc ; shape] ->
690+
begin match Ocaml_stdlib_slots.camlinternalMod.(id), args with
691+
| "init_mod" , [_loc ; shape] ->
686692
begin match shape with
687693
| Lconst (Const_block (0, _, [Const_block (0, _, [])]))
688694
-> unit (* see {!Translmod.init_shape}*)
689695
| _ -> prim ~primitive:Pinit_mod ~args
690696
end
691-
| _ -> assert false
692-
else
693-
begin
694-
assert (id = 1);
695-
match args with
696-
| [shape ; _obj1; _obj2] ->
697+
| "update_mod", [shape ; _obj1; _obj2] ->
697698
(* here array access will have side effect .. *)
698699
begin match shape with
699700
| Lconst (Const_block (0, _, [Const_block (0, _, [])]))
700701
-> unit (* see {!Translmod.init_shape}*)
701702
| _ -> prim ~primitive:Pupdate_mod ~args
702703
end
703-
| _ -> assert false
704-
end
704+
| _ -> assert false
705+
end
706+
707+
| Lprim ( Pfield (id, _),
708+
[Lprim (Pgetglobal ({name = "Pervasives"} ), _)]
709+
)
710+
->
711+
let args = List.map convert args in
712+
begin match Ocaml_stdlib_slots.pervasives.(id) , args with
713+
| "^", [ l; r ]
714+
->
715+
prim ~primitive:Pstringadd ~args:[l;r]
716+
| _ -> apply (convert fn) args loc App_na
717+
end
705718
| _ ->
706719
apply (convert fn) (List.map convert args)
707720
loc App_na

jscomp/lam.mli

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,16 @@ type set_field_dbg_info = Lambda.set_field_dbg_info
3636

3737
type ident = Ident.t
3838

39+
type function_arities =
40+
| Determin of bool * (int * Ident.t list option) list * bool
41+
(** when the first argument is true, it is for sure
42+
43+
approximation sound but not complete
44+
the last one means it can take any params later,
45+
for an exception: it is (Determin (true,[], true))
46+
*)
47+
| NA
48+
3949
type primitive =
4050
| Pbytes_to_string
4151
| Pbytes_of_string
@@ -64,6 +74,7 @@ type primitive =
6474
| Pstringlength
6575
| Pstringrefu
6676
| Pstringrefs
77+
| Pstringadd
6778
| Pbyteslength
6879
| Pbytesrefu
6980
| Pbytessetu

jscomp/lam_analysis.ml

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ let rec no_side_effects (lam : Lam.t) : bool =
127127
(* Integer to external pointer *)
128128

129129
| Poffsetint _
130-
130+
| Pstringadd
131131
-> true
132132
| Pinit_mod
133133
| Pupdate_mod
@@ -279,9 +279,18 @@ and size_constant x =
279279

280280
and size_lams acc (lams : Lam.t list) =
281281
List.fold_left (fun acc l -> acc + size l ) acc lams
282-
282+
let args_all_const args =
283+
List.for_all (fun x -> match x with Lam.Lconst _ -> true | _ -> false) args
284+
283285
let exit_inline_size = 7
284286
let small_inline_size = 5
287+
288+
(** Hints to inlining *)
289+
let ok_to_inline fn args =
290+
let s = size fn in
291+
s < small_inline_size (* || *)
292+
(* (args_all_const args && s < 10 && no_side_effects fn) *)
293+
285294
(* compared two lambdas in case analysis, note that we only compare some small lambdas
286295
Actually this patten is quite common in GADT, people have to write duplicated code
287296
due to the type system restriction

jscomp/lam_analysis.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ val no_side_effects : Lam.t -> bool
3434

3535
val size : Lam.t -> int
3636

37+
val ok_to_inline : Lam.t -> Lam.t list -> bool
3738
val eq_lambda : Lam.t -> Lam.t -> bool
3839
(** a conservative version of comparing two lambdas, mostly
3940
for looking for similar cases in switch

jscomp/lam_compile.ml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -190,15 +190,13 @@ and get_exp_with_args (cxt : Lam_compile_defs.cxt) lam args_lambda
190190
| _ ->
191191
Js_output.handle_block_return cxt.st cxt.should_return lam args_code @@
192192
(match id, name, args with
193-
| {name = "Pervasives"; _}, "^", [ e0 ; e1] ->
194-
E.string_append e0 e1
195193
| {name = "Pervasives"; _}, "print_endline", ([ _ ] as args) ->
196194
E.seq (E.dump Log args) E.unit
197195
| {name = "Pervasives"; _}, "prerr_endline", ([ _ ] as args) ->
198196
E.seq (E.dump Error args) E.unit
199197
| _ ->
200198
let rec aux (acc : J.expression)
201-
(arity : Lam_stats.function_arities) args (len : int) =
199+
(arity : Lam.function_arities) args (len : int) =
202200
match arity, len with
203201
| _, 0 ->
204202
acc (** All arguments consumed so far *)

0 commit comments

Comments
 (0)