Skip to content

Commit d586a14

Browse files
authored
Merge pull request #34 from bitdotgames/loader_less_alloc
Loader less alloc
2 parents 47fcc9e + 8da2667 commit d586a14

File tree

3 files changed

+74
-19
lines changed

3 files changed

+74
-19
lines changed

src/vm/compiled.cs

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Buffers;
23
using System.IO;
34
using System.Collections.Generic;
45
using bhl.marshall;
@@ -41,6 +42,12 @@ int Search(int ip, int l, int r)
4142
}
4243
return -1;
4344
}
45+
46+
public void EnsureCapacity(int capacity)
47+
{
48+
ips.Capacity = capacity;
49+
lines.Capacity = capacity;
50+
}
4451
}
4552

4653
public class CompiledModule
@@ -158,10 +165,12 @@ static public Module FromStream(
158165
type_refs_offsets.Add(r.ReadInt32());
159166

160167
int type_refs_len = r.ReadInt32();
161-
type_refs_bytes = r.ReadBytes(type_refs_len);
168+
type_refs_bytes = ArrayPool<byte>.Shared.Rent(type_refs_len);
169+
r.Read(type_refs_bytes, 0, type_refs_len);
162170

163171
int symb_len = r.ReadInt32();
164-
symb_bytes = r.ReadBytes(symb_len);
172+
symb_bytes = ArrayPool<byte>.Shared.Rent(symb_len);
173+
r.Read(symb_bytes, 0, symb_len);
165174

166175
int initcode_len = r.ReadInt32();
167176
if(initcode_len > 0)
@@ -173,12 +182,16 @@ static public Module FromStream(
173182

174183
constants_len = r.ReadInt32();
175184
if(constants_len > 0)
176-
constant_bytes = r.ReadBytes(constants_len);
185+
{
186+
constant_bytes = ArrayPool<byte>.Shared.Rent(constants_len);
187+
r.Read(constant_bytes, 0, constants_len);
188+
}
177189

178190
total_gvars_num = r.ReadInt32();
179191
local_gvars_num = r.ReadInt32();
180192

181193
int ip2src_line_len = r.ReadInt32();
194+
ip2src_line.EnsureCapacity(ip2src_line_len);
182195
for(int i=0;i<ip2src_line_len;++i)
183196
ip2src_line.Add(r.ReadInt32(), r.ReadInt32());
184197
}
@@ -200,10 +213,18 @@ static public Module FromStream(
200213
module.ns.Link(types.ns);
201214
module.local_gvars_mark = local_gvars_num;
202215

203-
var constants = new Const[constants_len];
204-
216+
Const[] constants;
217+
205218
if(constants_len > 0)
206-
ReadConstants(constant_bytes, constants);
219+
{
220+
ReadConstants(constant_bytes, out constants);
221+
ArrayPool<byte>.Shared.Return(constant_bytes);
222+
}
223+
else
224+
constants = Array.Empty<Const>();
225+
226+
ArrayPool<byte>.Shared.Return(symb_bytes);
227+
ArrayPool<byte>.Shared.Return(type_refs_bytes);
207228

208229
var compiled = new CompiledModule(
209230
init_func_idx,
@@ -221,12 +242,13 @@ static public Module FromStream(
221242
return module;
222243
}
223244

224-
static void ReadConstants(byte[] constant_bytes, Const[] constants)
245+
static void ReadConstants(byte[] constant_bytes, out Const[] constants)
225246
{
226247
var src = new MemoryStream(constant_bytes);
227248
using(BinaryReader r = new BinaryReader(src, System.Text.Encoding.UTF8))
228249
{
229250
int constants_num = r.ReadInt32();
251+
constants = new Const[constants_num];
230252
for(int i=0;i<constants_num;++i)
231253
{
232254
Const cn = null;

src/vm/msgpack/MsgPackReader.cs

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,18 @@
1515
//
1616

1717
using System;
18+
using System.Buffers;
1819
using System.IO;
1920
using System.Text;
2021

2122
namespace bhl.MsgPack
2223
{
2324
public class MsgPackReader
2425
{
25-
Stream _strm;
26+
readonly Stream _strm;
2627
byte[] _tmp0 = new byte[8];
2728
byte[] _tmp1 = new byte[8];
29+
readonly byte[] _singleByte = new byte[1];
2830

2931
Encoding _encoding = Encoding.UTF8;
3032
//Decoder _decoder = Encoding.UTF8.GetDecoder ();
@@ -83,7 +85,9 @@ public bool IsUnsigned64 ()
8385

8486
public bool IsRaw ()
8587
{
86-
return this.Type == TypePrefixes.FixRaw || this.Type == TypePrefixes.Raw16 || this.Type == TypePrefixes.Raw32;
88+
return this.Type == TypePrefixes.FixRaw || this.Type == TypePrefixes.Raw8 || this.Type == TypePrefixes.Raw16 || this.Type == TypePrefixes.Raw32 ||
89+
this.Type == TypePrefixes.Bin8 || this.Type == TypePrefixes.Bin16 || this.Type == TypePrefixes.Bin32
90+
;
8791
}
8892

8993
public bool IsArray ()
@@ -99,7 +103,7 @@ public bool IsMap ()
99103
public bool Read ()
100104
{
101105
byte[] tmp0 = _tmp0, tmp1 = _tmp1;
102-
int x = _strm.ReadByte ();
106+
int x = ReadStreamByteNoAlloc();
103107
if (x < 0)
104108
return false; // EOS
105109

@@ -162,7 +166,7 @@ public bool Read ()
162166
ValueUnsigned = (uint)ValueSigned;
163167
break;
164168
case TypePrefixes.UInt8:
165-
x = _strm.ReadByte ();
169+
x = ReadStreamByteNoAlloc();
166170
if (x < 0)
167171
throw new FormatException ();
168172
ValueUnsigned = (uint)x;
@@ -183,7 +187,7 @@ public bool Read ()
183187
ValueUnsigned64 = ((ulong)tmp0[0] << 56) | ((ulong)tmp0[1] << 48) | ((ulong)tmp0[2] << 40) | ((ulong)tmp0[3] << 32) | ((ulong)tmp0[4] << 24) | ((ulong)tmp0[5] << 16) | ((ulong)tmp0[6] << 8) | (ulong)tmp0[7];
184188
break;
185189
case TypePrefixes.Int8:
186-
x = _strm.ReadByte ();
190+
x = ReadStreamByteNoAlloc();
187191
if (x < 0)
188192
throw new FormatException ();
189193
ValueSigned = (sbyte)x;
@@ -210,14 +214,22 @@ public bool Read ()
210214
case TypePrefixes.FixMap:
211215
Length = (uint)(x & 0xf);
212216
break;
217+
case TypePrefixes.Raw8:
218+
case TypePrefixes.Bin8:
219+
if (_strm.Read (tmp0, 0, 1) != 1)
220+
throw new FormatException ();
221+
Length = (uint)tmp0[0];
222+
break;
213223
case TypePrefixes.Raw16:
224+
case TypePrefixes.Bin16:
214225
case TypePrefixes.Array16:
215226
case TypePrefixes.Map16:
216227
if (_strm.Read (tmp0, 0, 2) != 2)
217228
throw new FormatException ();
218229
Length = ((uint)tmp0[0] << 8) | (uint)tmp0[1];
219230
break;
220231
case TypePrefixes.Raw32:
232+
case TypePrefixes.Bin32:
221233
case TypePrefixes.Array32:
222234
case TypePrefixes.Map32:
223235
if (_strm.Read (tmp0, 0, 4) != 4)
@@ -242,17 +254,33 @@ public string ReadRawString ()
242254

243255
public string ReadRawString (byte[] buf)
244256
{
245-
if (this.Length < buf.Length) {
246-
if (ReadValueRaw (buf, 0, (int)this.Length) != this.Length)
257+
int length = (int)this.Length;
258+
if (length < buf.Length) {
259+
if (ReadValueRaw (buf, 0, length) != length)
247260
throw new FormatException ();
248-
return _encoding.GetString (buf, 0, (int)this.Length);
261+
return _encoding.GetString (buf, 0, length);
249262
}
250263

251264
// Poor implementation
252-
byte[] tmp = new byte[(int)this.Length];
253-
if (ReadValueRaw (tmp, 0, tmp.Length) != tmp.Length)
254-
throw new FormatException ();
255-
return _encoding.GetString (tmp);
265+
byte[] tmp = ArrayPool<byte>.Shared.Rent(length);
266+
try
267+
{
268+
if (ReadValueRaw (tmp, 0, length) != length)
269+
throw new FormatException ();
270+
return _encoding.GetString (tmp, 0, length);
271+
}
272+
finally
273+
{
274+
ArrayPool<byte>.Shared.Return(tmp);
275+
}
276+
}
277+
278+
int ReadStreamByteNoAlloc()
279+
{
280+
int bytesRead = _strm.Read(_singleByte, 0, 1);
281+
if(bytesRead < 1)
282+
return -1;
283+
return _singleByte[0];
256284
}
257285
}
258286
}

src/vm/msgpack/TypePrefixes.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ public enum TypePrefixes : byte
3434
Int16 = 0xd1,
3535
Int32 = 0xd2,
3636
Int64 = 0xd3,
37+
Raw8 = 0xd9,
3738
Raw16 = 0xda,
3839
Raw32 = 0xdb,
3940
Array16 = 0xdc,
@@ -44,5 +45,9 @@ public enum TypePrefixes : byte
4445
FixRaw = 0xa0, // 0xa0 - 0xbf
4546
FixArray = 0x90, // 0x90 - 0x9f
4647
FixMap = 0x80, // 0x80 - 0x8f
48+
49+
Bin8 = 0xc4,
50+
Bin16 = 0xc5,
51+
Bin32 = 0xc6,
4752
}
4853
}

0 commit comments

Comments
 (0)