فهرست منبع

forward declare locals in texpr

way less Hashtbling
Simon Krajewski 1 سال پیش
والد
کامیت
bd89477c49
2فایلهای تغییر یافته به همراه80 افزوده شده و 46 حذف شده
  1. 39 26
      src/compiler/hxb/hxbReader.ml
  2. 41 20
      src/compiler/hxb/hxbWriter.ml

+ 39 - 26
src/compiler/hxb/hxbReader.ml

@@ -25,11 +25,13 @@ let print_stacktrace () =
 type field_reader_context = {
 	t_pool : Type.t DynArray.t;
 	pos : pos ref;
+	vars : tvar Array.t;
 }
 
-let create_field_reader_context p = {
+let create_field_reader_context p vars = {
 	t_pool = DynArray.create ();
 	pos = ref p;
+	vars = vars;
 }
 
 class hxb_reader
@@ -55,7 +57,6 @@ class hxb_reader
 	val mutable class_fields = Array.make 0 null_field
 	val mutable enum_fields = Array.make 0 null_enum_field
 
-	val vars = Hashtbl.create 0
 	val mutable type_type_parameters = Array.make 0 (mk_type_param null_class TPHType None None)
 	val mutable field_type_parameters = Array.make 0 (mk_type_param null_class TPHMethod None None)
 	val mutable local_type_parameters = Array.make 0 (mk_type_param null_class TPHLocal None None)
@@ -833,21 +834,9 @@ class hxb_reader
 			| 10 -> VAbstractThis
 			| _ -> assert false
 
-	method read_var fctx =
+	method read_var =
 		let id = IO.read_i32 ch in
 		let name = self#read_string in
-		let extra = self#read_option (fun () ->
-			let params = self#read_list (fun () ->
-				let i = self#read_uleb128 in
-				local_type_parameters.(i)
-			) in
-			let vexpr = self#read_option (fun () -> self#read_texpr fctx) in
-			{
-				v_params = params;
-				v_expr = vexpr;
-			};
-		) in
-		let t = self#read_type_instance in
 		let kind = self#read_var_kind in
 		let flags = IO.read_i32 ch in
 		let meta = self#read_metadata in
@@ -855,17 +844,33 @@ class hxb_reader
 		let v = {
 			v_id = id;
 			v_name = name;
-			v_type = t;
+			v_type = t_dynamic;
 			v_kind = kind;
 			v_meta = meta;
 			v_pos = pos;
-			v_extra = extra;
+			v_extra = None;
 			v_flags = flags;
 		} in
-		Hashtbl.add vars id v;
 		v
 
 	method read_texpr fctx =
+
+		let declare_local () =
+			let v = fctx.vars.(self#read_uleb128) in
+			v.v_extra <- self#read_option (fun () ->
+				let params = self#read_list (fun () ->
+					let i = self#read_uleb128 in
+					local_type_parameters.(i)
+				) in
+				let vexpr = self#read_option (fun () -> self#read_texpr fctx) in
+				{
+					v_params = params;
+					v_expr = vexpr;
+				};
+			);
+			v.v_type <- self#read_type_instance;
+			v
+		in
 		let rec loop () =
 			let t = match self#read_u8 with
 				| 0 ->
@@ -890,12 +895,13 @@ class hxb_reader
 					| 7 -> TConst (TString self#read_string)
 
 					(* vars 20-29 *)
-					| 20 -> TLocal (Hashtbl.find vars (IO.read_i32 ch))
+					| 20 ->
+						TLocal (fctx.vars.(self#read_uleb128))
 					| 21 ->
-						let v = self#read_var fctx in
+						let v = declare_local () in
 						TVar (v,None)
 					| 22 ->
-							let v = self#read_var fctx in
+							let v = declare_local () in
 							let e = loop () in
 							TVar (v, Some e)
 
@@ -921,7 +927,7 @@ class hxb_reader
 					(* function 50-59 *)
 					| 50 ->
 						let read_tfunction_arg () =
-							let v = self#read_var fctx in
+							let v = declare_local () in
 							let cto = self#read_option loop in
 							(v,cto)
 						in
@@ -991,7 +997,7 @@ class hxb_reader
 					| 83 ->
 						let e1 = loop () in
 						let catches = self#read_list (fun () ->
-							let v = self#read_var fctx in
+							let v = declare_local () in
 							let e = loop () in
 							(v,e)
 						) in
@@ -1005,7 +1011,7 @@ class hxb_reader
 						let e2 = loop () in
 						TWhile(e1,e2,DoWhile)
 					| 86 ->
-						let v  = self#read_var fctx in
+						let v  = declare_local () in
 						let e1 = loop () in
 						let e2 = loop () in
 						TFor(v,e1,e2)
@@ -1145,6 +1151,13 @@ class hxb_reader
 		let overloads = self#read_list (fun () -> self#read_class_field_forward) in
 		{ null_field with cf_name = name; cf_pos = pos; cf_name_pos = name_pos; cf_overloads = overloads }
 
+	method start_texpr =
+		let l = self#read_uleb128 in
+		let a = Array.init l (fun _ ->
+			self#read_var
+		) in
+		create_field_reader_context self#read_pos a
+
 	method read_class_field_data (nested : bool) (cf : tclass_field) : unit =
 		current_field <- cf;
 
@@ -1168,7 +1181,7 @@ class hxb_reader
 			| 0 ->
 				None,None
 			| _ ->
-				let fctx = create_field_reader_context self#read_pos in
+				let fctx = self#start_texpr in
 				let e = self#read_texpr fctx in
 				let e_unopt = self#read_option (fun () -> self#read_texpr fctx) in
 				(Some e,e_unopt)
@@ -1227,7 +1240,7 @@ class hxb_reader
 		in
 		loop CfrMember (self#read_uleb128) c.cl_ordered_fields;
 		loop CfrStatic (self#read_uleb128) c.cl_ordered_statics;
-		c.cl_init <- self#read_option (fun () -> self#read_texpr (create_field_reader_context self#read_pos));
+		c.cl_init <- self#read_option (fun () -> self#read_texpr self#start_texpr);
 		(match c.cl_kind with KModuleFields md -> md.m_statics <- Some c; | _ -> ());
 
 	method read_enum_fields (e : tenum) =

+ 41 - 20
src/compiler/hxb/hxbWriter.ml

@@ -13,9 +13,6 @@ let c_dim = if no_color then "" else "\x1b[2m"
 let todo = "\x1b[33m[TODO]" ^ c_reset
 let todo_error = "\x1b[31m[TODO] error:" ^ c_reset
 
-let unopt_write_counter = ref 0
-let unopt_skip_counter = ref 0
-
 let t_pool_hits = ref 0
 let t_pool_misses = ref 0
 
@@ -294,11 +291,13 @@ end
 type field_writer_context = {
 	t_pool : (bytes,unit) pool;
 	pos_writer : pos_writer;
+	vars : (int,tvar) pool;
 }
 
 let create_field_writer_context pos_writer = {
 	t_pool = new pool;
 	pos_writer = pos_writer;
+	vars = new pool;
 }
 
 class ['a] hxb_writer
@@ -947,20 +946,23 @@ class ['a] hxb_writer
 	method write_var fctx v =
 		chunk#write_i32 v.v_id;
 		chunk#write_string v.v_name;
-		chunk#write_option v.v_extra (fun ve ->
-			chunk#write_list ve.v_params (fun ttp ->
-				let index = local_type_parameters#add ttp () in
-				chunk#write_uleb128 index
-			);
-			chunk#write_option ve.v_expr (self#write_texpr fctx);
-		);
-		self#write_type_instance v.v_type;
 		self#write_var_kind v.v_kind;
 		chunk#write_i32 v.v_flags;
 		self#write_metadata v.v_meta;
 		self#write_pos v.v_pos
 
 	method write_texpr fctx (e : texpr) =
+		let declare_var v =
+			chunk#write_uleb128 (fctx.vars#add v.v_id v);
+			chunk#write_option v.v_extra (fun ve ->
+				chunk#write_list ve.v_params (fun ttp ->
+					let index = local_type_parameters#add ttp () in
+					chunk#write_uleb128 index
+				);
+				chunk#write_option ve.v_expr (self#write_texpr fctx);
+			);
+			self#write_type_instance v.v_type;
+		in
 		let rec loop e =
 			let restore = self#start_temporary_chunk in
 			self#write_type_instance e.etype;
@@ -1005,13 +1007,13 @@ class ['a] hxb_writer
 			(* vars 20-29 *)
 			| TLocal v ->
 				chunk#write_byte 20;
-				chunk#write_i32 v.v_id;
+				chunk#write_uleb128 (fctx.vars#get v.v_id)
 			| TVar(v,None) ->
 				chunk#write_byte 21;
-				self#write_var fctx v
+				declare_var v;
 			| TVar(v,Some e1) ->
 				chunk#write_byte 22;
-				self#write_var fctx v;
+				declare_var v;
 				loop e1;
 			(* blocks 30-49 *)
 			| TBlock [] ->
@@ -1041,7 +1043,7 @@ class ['a] hxb_writer
 			| TFunction tf ->
 				chunk#write_byte 50;
 				chunk#write_list tf.tf_args (fun (v,eo) ->
-					self#write_var fctx v;
+					declare_var v;
 					chunk#write_option eo loop;
 				);
 				self#write_type_instance tf.tf_type;
@@ -1098,7 +1100,7 @@ class ['a] hxb_writer
 				chunk#write_byte 83;
 				loop e1;
 				chunk#write_list catches  (fun (v,e) ->
-					self#write_var fctx v;
+					declare_var v;
 					loop e
 				);
 			| TWhile(e1,e2,flag) ->
@@ -1107,7 +1109,7 @@ class ['a] hxb_writer
 				loop e2;
 			| TFor(v,e1,e2) ->
 				chunk#write_byte 86;
-				self#write_var fctx v;
+				declare_var v;
 				loop e1;
 				loop e2;
 			(* control flow 90-99 *)
@@ -1304,6 +1306,20 @@ class ['a] hxb_writer
 			close()
 		);
 
+	method start_texpr (p: pos) =
+		let restore = self#start_temporary_chunk in
+		let fctx = create_field_writer_context (new pos_writer chunk p false) in
+		fctx,(fun () ->
+			restore(fun chunk new_chunk ->
+				let items = fctx.vars#items in
+				chunk#write_uleb128 (DynArray.length items);
+				DynArray.iter (fun v ->
+					self#write_var fctx v;
+				) items;
+				new_chunk#export_data chunk#ch
+			)
+		)
+
 	method write_class_field_data cf =
 		let restore = self#start_temporary_chunk in
 		(try self#write_type_instance cf.cf_type with e -> begin
@@ -1319,9 +1335,10 @@ class ['a] hxb_writer
 				chunk#write_byte 0
 			| Some e ->
 				chunk#write_byte 1;
-				let fctx = create_field_writer_context (new pos_writer chunk e.epos false) in
+				let fctx,close = self#start_texpr e.epos in
 				self#write_texpr fctx e;
-				chunk#write_option cf.cf_expr_unoptimized (self#write_texpr fctx)
+				chunk#write_option cf.cf_expr_unoptimized (self#write_texpr fctx);
+				close();
 		end;
 		chunk#write_list cf.cf_overloads (fun f ->
 			let close = self#open_field_scope false f in
@@ -1583,7 +1600,11 @@ class ['a] hxb_writer
 				chunk#write_option c.cl_constructor (write_field CfrConstructor);
 				chunk#write_list c.cl_ordered_fields (write_field CfrMember);
 				chunk#write_list c.cl_ordered_statics (write_field CfrStatic);
-				chunk#write_option c.cl_init (fun e -> self#write_texpr (create_field_writer_context (new pos_writer chunk e.epos false)) e);
+				chunk#write_option c.cl_init (fun e ->
+					let fctx,close = self#start_texpr e.epos in
+					self#write_texpr fctx e;
+					close()
+				);
 			)
 		end;
 		begin match own_enums#to_list with