瀏覽代碼

put all texpr type instances in an array

Simon Krajewski 1 年之前
父節點
當前提交
f36dcc4db4
共有 2 個文件被更改,包括 30 次插入35 次删除
  1. 10 13
      src/compiler/hxb/hxbReader.ml
  2. 20 22
      src/compiler/hxb/hxbWriter.ml

+ 10 - 13
src/compiler/hxb/hxbReader.ml

@@ -24,13 +24,13 @@ let print_stacktrace () =
 		| _ -> die "" __LOC__
 
 type field_reader_context = {
-	t_pool : Type.t DynArray.t;
+	t_pool : Type.t Array.t;
 	pos : pos ref;
 	vars : tvar Array.t;
 }
 
-let create_field_reader_context p vars = {
-	t_pool = DynArray.create ();
+let create_field_reader_context p ts vars = {
+	t_pool = ts;
 	pos = ref p;
 	vars = vars;
 }
@@ -859,14 +859,7 @@ class hxb_reader
 			v
 		in
 		let rec loop () =
-			let t = match self#read_u8 with
-				| 0 ->
-					DynArray.get fctx.t_pool self#read_uleb128
-				| i ->
-					let t = self#process_type_instance i in
-					DynArray.add fctx.t_pool t;
-					t
-			in
+			let t = fctx.t_pool.(self#read_uleb128) in
 			let rec loop2 () =
 				match IO.read_byte ch with
 					(* values 0-19 *)
@@ -1132,10 +1125,14 @@ class hxb_reader
 
 	method start_texpr =
 		let l = self#read_uleb128 in
-		let a = Array.init l (fun _ ->
+		let ts = Array.init l (fun _ ->
+			self#read_type_instance
+		) in
+		let l = self#read_uleb128 in
+		let vars = Array.init l (fun _ ->
 			self#read_var
 		) in
-		create_field_reader_context self#read_pos a
+		create_field_reader_context self#read_pos ts vars
 
 	method read_field_type_parameters kind =
 		let num_params = self#read_uleb128 in

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

@@ -391,7 +391,7 @@ end
 let dummy_rings = new t_rings 0
 
 type field_writer_context = {
-	t_pool : (bytes,unit) pool;
+	t_pool : (bytes,bytes) pool;
 	t_rings : t_rings;
 	pos_writer : pos_writer;
 	vars : (int,tvar) pool;
@@ -1107,45 +1107,37 @@ class hxb_writer
 		self#write_pos v.v_pos
 
 	method write_texpr_type_instance (fctx : field_writer_context) (t: Type.t) =
-		match
-			(* First we see if the type instance is simple (just byte + reference). In this case no caching
-			   mechanism is going to improve anything, so we write we value immediately. *)
-			self#write_type_instance_simple fctx.t_rings t
-		with
+		let restore = self#start_temporary_chunk in
+		let r = self#write_type_instance_simple fctx.t_rings t in
+		let index = match r with
 		| None ->
-			(* A bit tricky: The reader pushes any immediate value onto its cache, so we have to advance
-			   our pool here to make sure the indices align. *)
-			fctx.t_pool#advance ();
+			let t_bytes = restore (fun new_chunk -> new_chunk#get_bytes) in
 			incr stats.type_instance_immediate;
-		| Some (t,ring) ->
+			fctx.t_pool#get_or_add t_bytes t_bytes
+		| Some(t,ring) ->
+			ignore(restore (fun new_chunk -> new_chunk#get_bytes));
 			try
-				(* Next we check if we find the type in our small ring cache. The correct ring is given to
-				   us by write_type_instance_simple because it already checks the type instance kinds anyway. *)
 				let index = fctx.t_rings#find ring t in
 				incr stats.type_instance_ring_hits;
-				chunk#write_u8 0;
-				chunk#write_uleb128 index;
+				index
 			with Not_found ->
-				(* Now we write the type into a temporary chunk in order to identify it. *)
 				let restore = self#start_temporary_chunk in
 				self#write_type_instance_not_simple t;
 				let t_bytes = restore (fun new_chunk ->
 					new_chunk#get_bytes
 				) in
 				let index = try
-					(* If we find it in the cache, write the reference accordingly. *)
 					let index = fctx.t_pool#get t_bytes in
 					incr stats.type_instance_cache_hits;
-					chunk#write_u8 0;
-					chunk#write_uleb128 index;
 					index
 				with Not_found ->
-					(* Otherwise write the full type by copying the bytes into the output. *)
 					incr stats.type_instance_cache_misses;
-					chunk#write_bytes t_bytes;
-					fctx.t_pool#add t_bytes ()
+					fctx.t_pool#add t_bytes t_bytes
 				in
-				Ring.push ring (t,index)
+				Ring.push ring (t,index);
+				index
+		in
+		chunk#write_uleb128 index
 
 	method write_texpr (fctx : field_writer_context) (e : texpr) =
 		let declare_var v =
@@ -1495,6 +1487,12 @@ class hxb_writer
 		let fctx = create_field_writer_context (new pos_writer chunk stats p false) in
 		fctx,(fun () ->
 			restore(fun new_chunk ->
+				let items = fctx.t_pool#items in
+				chunk#write_uleb128 (DynArray.length items);
+				DynArray.iter (fun bytes ->
+					chunk#write_bytes bytes
+				) items;
+
 				let items = fctx.vars#items in
 				chunk#write_uleb128 (DynArray.length items);
 				DynArray.iter (fun v ->