@@ -28,9 +28,9 @@ struct Outbuffer
2828{
2929 @safe :
3030
31- ubyte * buf; // the buffer itself
32- ubyte * pend; // pointer past the end of the buffer
33- private ubyte * p; // current position in buffer
31+ private ubyte * buf; // the buffer itself
32+ private ubyte * pend; // pointer past the end of the buffer
33+ private ubyte * p; // current position in buffer
3434
3535 nothrow :
3636 this (size_t initialSize)
@@ -43,26 +43,16 @@ struct Outbuffer
4343 @trusted
4444 void dtor ()
4545 {
46- if ( auto slice = this .extractSlice())
47- free(slice.ptr) ;
46+ free(buf);
47+ buf = p = pend = null ;
4848 }
4949
50- void reset ()
50+ private void reset ()
5151 {
5252 p = buf;
5353 }
5454
5555 // Returns: A slice to the data written so far
56- extern (D ) inout (ubyte )[] opSlice (size_t from, size_t to) inout
57- @trusted pure nothrow @nogc
58- {
59- assert (this .buf, " Attempt to dereference a null pointer" );
60- assert (from < to, " First index must be smaller than the second one" );
61- assert (this .length() <= (to - from), " Out of bound access" );
62- return this .buf[from .. to];
63- }
64-
65- // / Ditto
6656 extern (D ) inout (ubyte )[] opSlice () inout @trusted pure nothrow @nogc
6757 {
6858 return this .buf[0 .. this .p - this .buf];
@@ -75,13 +65,22 @@ struct Outbuffer
7565 return ret;
7666 }
7767
68+ private extern (D ) inout (ubyte )[] opSlice (size_t from, size_t to) inout
69+ @trusted pure nothrow @nogc
70+ {
71+ assert (this .buf, " Attempt to dereference a null pointer" );
72+ assert (from < to, " First index must be smaller than the second one" );
73+ assert (this .length() <= (to - from), " Out of bound access" );
74+ return this .buf[from .. to];
75+ }
76+
7877 /* *******************
7978 * Make sure we have at least `nbytes` available for writing,
8079 * allocate more if necessary.
8180 * This is the inlinable fast path. Prefer `enlarge` if allocation
8281 * will always happen.
8382 */
84- void reserve (size_t nbytes)
83+ private void reserve (size_t nbytes)
8584 {
8685 // Keep small so it is inlined
8786 if (pend - p < nbytes)
@@ -90,34 +89,45 @@ struct Outbuffer
9089
9190 // Reserve nbytes in buffer
9291 @trusted
93- void enlarge (size_t nbytes)
92+ private void enlarge (size_t nbytes)
9493 {
9594 pragma (inline, false ); // do not inline slow path
96- const size_t oldlen = pend - buf;
97- const size_t used = p - buf;
98-
99- size_t len = used + nbytes;
100- // No need to reallocate
101- if (nbytes < (pend - p))
102- return ;
10395
104- const size_t newlen = oldlen + (oldlen >> 1 ); // oldlen * 1.5
105- if (len < newlen)
106- len = newlen;
107- len = (len + 15 ) & ~ 15 ;
96+ debug assert (nbytes > pend - p, " You should call this function from reserve() only." );
10897
109- buf = cast (ubyte * ) realloc(buf,len);
98+ if (buf is null )
99+ {
100+ // Special-case the overwhelmingly most frequent situation
101+ if (nbytes < 64 ) nbytes = 64 ;
102+ p = buf = cast (ubyte * ) malloc(nbytes);
103+ pend = buf + nbytes;
104+ }
105+ else
106+ {
107+ const size_t used = p - buf;
108+ const size_t oldlen = pend - buf;
109+ // Ensure exponential growth, oldlen * 2 for small sizes, oldlen * 1.5 for big sizes
110+ const size_t minlen = oldlen + (oldlen >> (oldlen > 1024 * 64 ));
111+
112+ size_t len = used + nbytes;
113+ if (len < minlen)
114+ len = minlen;
115+ // Round to cache line size
116+ len = (len + 63 ) & ~ 63 ;
117+
118+ auto newbuf = cast (ubyte * ) realloc(buf, len);
119+
120+ pend = newbuf + len;
121+ p = newbuf + used;
122+ buf = newbuf;
123+ }
110124 if (! buf)
111125 err_nomem();
112-
113- pend = buf + len;
114- p = buf + used;
115126 }
116127
117-
118128 // Write n zeros; return pointer to start of zeros
119129 @trusted
120- void * writezeros(size_t n)
130+ private void * writezeros(size_t n)
121131 {
122132 reserve (n);
123133 void * pstart = memset(p,0 ,n);
@@ -127,7 +137,7 @@ struct Outbuffer
127137
128138 // Position buffer to accept the specified number of bytes at offset
129139 @trusted
130- void position (size_t offset, size_t nbytes)
140+ private void position (size_t offset, size_t nbytes)
131141 {
132142 if (offset + nbytes > pend - buf)
133143 {
@@ -142,7 +152,7 @@ struct Outbuffer
142152
143153 // Write an array to the buffer, no reserve check
144154 @trusted
145- void writen (const void * b, size_t len)
155+ private void writen (const void * b, size_t len)
146156 {
147157 memcpy(p,b,len);
148158 p += len;
@@ -151,15 +161,15 @@ struct Outbuffer
151161 // Write an array to the buffer.
152162 @trusted
153163 extern (D )
154- void write (const (void )[] b)
164+ private void write (const (void )[] b)
155165 {
156166 reserve (b.length);
157167 memcpy(p, b.ptr, b.length);
158168 p += b.length;
159169 }
160170
161171 @trusted
162- void write (const (void )* b, size_t len)
172+ private void write (const (void )* b, size_t len)
163173 {
164174 write(b[0 .. len]);
165175 }
@@ -168,7 +178,7 @@ struct Outbuffer
168178 * Writes an 8 bit byte, no reserve check.
169179 */
170180 @trusted
171- void writeByten (int v)
181+ private void writeByten (int v)
172182 {
173183 * p++ = cast (ubyte )v;
174184 }
@@ -177,7 +187,7 @@ struct Outbuffer
177187 * Writes an 8 bit byte.
178188 */
179189 @trusted
180- void writeByte (int v)
190+ private void writeByte (int v)
181191 {
182192 reserve (1 );
183193 writeByten(v);
@@ -187,7 +197,7 @@ struct Outbuffer
187197 * Writes a 16 bit value, no reserve check.
188198 */
189199 @trusted
190- void write16n (int v)
200+ private void write16n (int v)
191201 {
192202 * (cast (ushort * ) p) = cast (ushort )v;
193203 p += 2 ;
@@ -197,7 +207,7 @@ struct Outbuffer
197207 /**
198208 * Writes a 16 bit value.
199209 */
200- void write16 (int v)
210+ private void write16 (int v)
201211 {
202212 reserve (2 );
203213 write16n(v);
@@ -207,7 +217,7 @@ struct Outbuffer
207217 * Writes a 32 bit int, no reserve check.
208218 */
209219 @trusted
210- void write32n (int v)
220+ private void write32n (int v)
211221 {
212222 * cast (int * )p = v;
213223 p += 4 ;
@@ -216,7 +226,7 @@ struct Outbuffer
216226 /**
217227 * Writes a 32 bit int.
218228 */
219- void write32 (int v)
229+ private void write32 (int v)
220230 {
221231 reserve (4 );
222232 write32n(v);
@@ -226,7 +236,7 @@ struct Outbuffer
226236 * Writes a 64 bit long, no reserve check
227237 */
228238 @trusted
229- void write64n (long v)
239+ private void write64n (long v)
230240 {
231241 * cast (long * )p = v;
232242 p += 8 ;
@@ -235,7 +245,7 @@ struct Outbuffer
235245 /**
236246 * Writes a 64 bit long.
237247 */
238- void write64 (long v)
248+ private void write64 (long v)
239249 {
240250 reserve (8 );
241251 write64n(v);
@@ -245,7 +255,7 @@ struct Outbuffer
245255 * Writes a 32 bit float.
246256 */
247257 @trusted
248- void writeFloat (float v)
258+ private void writeFloat (float v)
249259 {
250260 reserve (float .sizeof);
251261 * cast (float * )p = v;
@@ -256,7 +266,7 @@ struct Outbuffer
256266 * Writes a 64 bit double.
257267 */
258268 @trusted
259- void writeDouble (double v)
269+ private void writeDouble (double v)
260270 {
261271 reserve (double .sizeof);
262272 * cast (double * )p = v;
@@ -267,7 +277,7 @@ struct Outbuffer
267277 * Writes a String as a sequence of bytes.
268278 */
269279 @trusted
270- void write (const (char )* s)
280+ private void write (const (char )* s)
271281 {
272282 write(s[0 .. strlen(s)]);
273283 }
@@ -276,20 +286,20 @@ struct Outbuffer
276286 * Writes a 0 terminated String
277287 */
278288 @trusted
279- void writeString (const (char )* s)
289+ private void writeString (const (char )* s)
280290 {
281291 write(s[0 .. strlen(s)+ 1 ]);
282292 }
283293
284294 // / Ditto
285- extern (D ) void writeString(const (char )[] s)
295+ private extern (D) void writeString(const (char )[] s)
286296 {
287297 write(s);
288298 writeByte(0 );
289299 }
290300
291301 // / Disembiguation for `string`
292- extern (D ) void writeString(string s)
302+ private extern (D) void writeString(string s)
293303 {
294304 writeString(cast (const (char )[])(s));
295305 }
@@ -298,7 +308,7 @@ struct Outbuffer
298308 * Inserts string at beginning of buffer.
299309 */
300310 @trusted
301- void prependBytes (const (char )* s)
311+ private void prependBytes (const (char )* s)
302312 {
303313 prepend(s, strlen (s));
304314 }
@@ -307,7 +317,7 @@ struct Outbuffer
307317 * Inserts bytes at beginning of buffer.
308318 */
309319 @trusted
310- void prepend (const (void )* b, size_t len)
320+ private void prepend (const (void )* b, size_t len)
311321 {
312322 reserve (len);
313323 memmove(buf + len,buf,p - buf);
@@ -319,7 +329,7 @@ struct Outbuffer
319329 * Bracket buffer contents with c1 and c2.
320330 */
321331 @trusted
322- void bracket (char c1,char c2)
332+ private void bracket (char c1,char c2)
323333 {
324334 reserve (2 );
325335 memmove(buf + 1 ,buf,p - buf);
@@ -331,7 +341,7 @@ struct Outbuffer
331341 /**
332342 * Returns the number of bytes written.
333343 */
334- size_t length () const @safe pure nothrow @nogc
344+ private size_t length () const @safe pure nothrow @nogc
335345 {
336346 return p - buf;
337347 }
@@ -340,14 +350,14 @@ struct Outbuffer
340350 * Set current size of buffer.
341351 */
342352 @trusted
343- void setsize (size_t size)
353+ private void setsize (size_t size)
344354 {
345355 p = buf + size;
346356 // debug assert(buf <= p);
347357 // debug assert(p <= pend);
348358 }
349359
350- void writesLEB128 (int value)
360+ private void writesLEB128 (int value)
351361 {
352362 while (1 )
353363 {
@@ -364,7 +374,7 @@ struct Outbuffer
364374 }
365375 }
366376
367- void writeuLEB128 (uint value)
377+ private void writeuLEB128 (uint value)
368378 {
369379 do
370380 {
0 commit comments