File tree Expand file tree Collapse file tree 1 file changed +37
-1
lines changed Expand file tree Collapse file tree 1 file changed +37
-1
lines changed Original file line number Diff line number Diff line change @@ -82,9 +82,45 @@ struct Outbuffer
8282 */
8383 void reserve (size_t nbytes)
8484 {
85+ pragma (inline, true ); // inline fast path
86+
87+ // non-inline function for the heavy/infrequent reallocation case
88+ @trusted static void enlarge(ref Outbuffer b, size_t nbytes)
89+ {
90+ pragma (inline, false ); // do not inline slow path
91+
92+ if (b.buf is null )
93+ {
94+ // Special-case the overwhelmingly most frequent situation
95+ if (nbytes < 64 ) nbytes = 64 ;
96+ b.p = b.buf = cast (ubyte * ) malloc(nbytes);
97+ b.pend = b.buf + nbytes;
98+ }
99+ else
100+ {
101+ const size_t used = b.p - b.buf;
102+ const size_t oldlen = b.pend - b.buf;
103+ // Ensure exponential growth, oldlen * 2 for small sizes, oldlen * 1.5 for big sizes
104+ const size_t minlen = oldlen + (oldlen >> (oldlen > 1024 * 64 ));
105+
106+ size_t len = used + nbytes;
107+ if (len < minlen)
108+ len = minlen;
109+ // Round up to cache line size
110+ len = (len + 63 ) & ~ 63 ;
111+
112+ b.buf = cast (ubyte * ) realloc(b.buf, len);
113+
114+ b.pend = b.buf + len;
115+ b.p = b.buf + used;
116+ }
117+ if (! b.buf)
118+ err_nomem();
119+ }
120+
85121 // Keep small so it is inlined
86122 if (pend - p < nbytes)
87- enlarge(nbytes);
123+ enlarge(this , nbytes);
88124 }
89125
90126 // Reserve nbytes in buffer
You can’t perform that action at this time.
0 commit comments