Skip to content

Commit 0d4cd2d

Browse files
author
Fabrice Bellard
committed
faster and safer dbuf functions (#443)
1 parent 2a53de0 commit 0d4cd2d

5 files changed

Lines changed: 77 additions & 35 deletions

File tree

cutils.c

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -100,15 +100,20 @@ void dbuf_init(DynBuf *s)
100100
dbuf_init2(s, NULL, NULL);
101101
}
102102

103-
/* return < 0 if error */
104-
int dbuf_realloc(DynBuf *s, size_t new_size)
103+
/* Try to allocate 'len' more bytes. return < 0 if error */
104+
int dbuf_claim(DynBuf *s, size_t len)
105105
{
106-
size_t size;
106+
size_t new_size, size;
107107
uint8_t *new_buf;
108+
new_size = s->size + len;
109+
if (new_size < len)
110+
return -1; /* overflow case */
108111
if (new_size > s->allocated_size) {
109112
if (s->error)
110113
return -1;
111-
size = s->allocated_size * 3 / 2;
114+
size = s->allocated_size + (s->allocated_size / 2);
115+
if (size < s->allocated_size)
116+
return -1; /* overflow case */
112117
if (size > new_size)
113118
new_size = size;
114119
new_buf = s->realloc_func(s->opaque, s->buf, new_size);
@@ -122,22 +127,10 @@ int dbuf_realloc(DynBuf *s, size_t new_size)
122127
return 0;
123128
}
124129

125-
int dbuf_write(DynBuf *s, size_t offset, const uint8_t *data, size_t len)
126-
{
127-
size_t end;
128-
end = offset + len;
129-
if (dbuf_realloc(s, end))
130-
return -1;
131-
memcpy(s->buf + offset, data, len);
132-
if (end > s->size)
133-
s->size = end;
134-
return 0;
135-
}
136-
137130
int dbuf_put(DynBuf *s, const uint8_t *data, size_t len)
138131
{
139-
if (unlikely((s->size + len) > s->allocated_size)) {
140-
if (dbuf_realloc(s, s->size + len))
132+
if (unlikely((s->allocated_size - s->size) < len)) {
133+
if (dbuf_claim(s, len))
141134
return -1;
142135
}
143136
memcpy_no_ub(s->buf + s->size, data, len);
@@ -147,20 +140,35 @@ int dbuf_put(DynBuf *s, const uint8_t *data, size_t len)
147140

148141
int dbuf_put_self(DynBuf *s, size_t offset, size_t len)
149142
{
150-
if (unlikely((s->size + len) > s->allocated_size)) {
151-
if (dbuf_realloc(s, s->size + len))
143+
if (unlikely((s->allocated_size - s->size) < len)) {
144+
if (dbuf_claim(s, len))
152145
return -1;
153146
}
154147
memcpy(s->buf + s->size, s->buf + offset, len);
155148
s->size += len;
156149
return 0;
157150
}
158151

159-
int dbuf_putc(DynBuf *s, uint8_t c)
152+
int __dbuf_putc(DynBuf *s, uint8_t c)
160153
{
161154
return dbuf_put(s, &c, 1);
162155
}
163156

157+
int __dbuf_put_u16(DynBuf *s, uint16_t val)
158+
{
159+
return dbuf_put(s, (uint8_t *)&val, 2);
160+
}
161+
162+
int __dbuf_put_u32(DynBuf *s, uint32_t val)
163+
{
164+
return dbuf_put(s, (uint8_t *)&val, 4);
165+
}
166+
167+
int __dbuf_put_u64(DynBuf *s, uint64_t val)
168+
{
169+
return dbuf_put(s, (uint8_t *)&val, 8);
170+
}
171+
164172
int dbuf_putstr(DynBuf *s, const char *str)
165173
{
166174
return dbuf_put(s, (const uint8_t *)str, strlen(str));
@@ -182,7 +190,7 @@ int __attribute__((format(printf, 2, 3))) dbuf_printf(DynBuf *s,
182190
/* fast case */
183191
return dbuf_put(s, (uint8_t *)buf, len);
184192
} else {
185-
if (dbuf_realloc(s, s->size + len + 1))
193+
if (dbuf_claim(s, len + 1))
186194
return -1;
187195
va_start(ap, fmt);
188196
vsnprintf((char *)(s->buf + s->size), s->allocated_size - s->size,

cutils.h

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -264,24 +264,58 @@ typedef struct DynBuf {
264264

265265
void dbuf_init(DynBuf *s);
266266
void dbuf_init2(DynBuf *s, void *opaque, DynBufReallocFunc *realloc_func);
267-
int dbuf_realloc(DynBuf *s, size_t new_size);
268-
int dbuf_write(DynBuf *s, size_t offset, const uint8_t *data, size_t len);
267+
int dbuf_claim(DynBuf *s, size_t len);
269268
int dbuf_put(DynBuf *s, const uint8_t *data, size_t len);
270269
int dbuf_put_self(DynBuf *s, size_t offset, size_t len);
271-
int dbuf_putc(DynBuf *s, uint8_t c);
272270
int dbuf_putstr(DynBuf *s, const char *str);
271+
int __dbuf_putc(DynBuf *s, uint8_t c);
272+
int __dbuf_put_u16(DynBuf *s, uint16_t val);
273+
int __dbuf_put_u32(DynBuf *s, uint32_t val);
274+
int __dbuf_put_u64(DynBuf *s, uint64_t val);
275+
276+
static inline int dbuf_putc(DynBuf *s, uint8_t val)
277+
{
278+
if (unlikely((s->allocated_size - s->size) < 1)) {
279+
return __dbuf_putc(s, val);
280+
} else {
281+
s->buf[s->size++] = val;
282+
return 0;
283+
}
284+
}
285+
273286
static inline int dbuf_put_u16(DynBuf *s, uint16_t val)
274287
{
275-
return dbuf_put(s, (uint8_t *)&val, 2);
288+
if (unlikely((s->allocated_size - s->size) < 2)) {
289+
return __dbuf_put_u16(s, val);
290+
} else {
291+
put_u16(s->buf + s->size, val);
292+
s->size += 2;
293+
return 0;
294+
}
276295
}
296+
277297
static inline int dbuf_put_u32(DynBuf *s, uint32_t val)
278298
{
279-
return dbuf_put(s, (uint8_t *)&val, 4);
299+
if (unlikely((s->allocated_size - s->size) < 4)) {
300+
return __dbuf_put_u32(s, val);
301+
} else {
302+
put_u32(s->buf + s->size, val);
303+
s->size += 4;
304+
return 0;
305+
}
280306
}
307+
281308
static inline int dbuf_put_u64(DynBuf *s, uint64_t val)
282309
{
283-
return dbuf_put(s, (uint8_t *)&val, 8);
310+
if (unlikely((s->allocated_size - s->size) < 8)) {
311+
return __dbuf_put_u64(s, val);
312+
} else {
313+
put_u64(s->buf + s->size, val);
314+
s->size += 8;
315+
return 0;
316+
}
284317
}
318+
285319
int __attribute__((format(printf, 2, 3))) dbuf_printf(DynBuf *s,
286320
const char *fmt, ...);
287321
void dbuf_free(DynBuf *s);

libregexp.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ static inline int is_digit(int c) {
117117
/* insert 'len' bytes at position 'pos'. Return < 0 if error. */
118118
static int dbuf_insert(DynBuf *s, int pos, int len)
119119
{
120-
if (dbuf_realloc(s, s->size + len))
120+
if (dbuf_claim(s, len))
121121
return -1;
122122
memmove(s->buf + pos + len, s->buf + pos, s->size - pos);
123123
s->size += len;
@@ -2340,7 +2340,7 @@ static int re_parse_alternative(REParseState *s, BOOL is_backward_dir)
23402340
speed is not really critical here) */
23412341
end = s->byte_code.size;
23422342
term_size = end - term_start;
2343-
if (dbuf_realloc(&s->byte_code, end + term_size))
2343+
if (dbuf_claim(&s->byte_code, term_size))
23442344
return -1;
23452345
memmove(s->byte_code.buf + start + term_size,
23462346
s->byte_code.buf + start,

libunicode.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1179,7 +1179,7 @@ int unicode_normalize(uint32_t **pdst, const uint32_t *src, int src_len,
11791179
is_compat = n_type >> 1;
11801180

11811181
dbuf_init2(dbuf, opaque, realloc_func);
1182-
if (dbuf_realloc(dbuf, sizeof(int) * src_len))
1182+
if (dbuf_claim(dbuf, sizeof(int) * src_len))
11831183
goto fail;
11841184

11851185
/* common case: latin1 is unaffected by NFC */

quickjs.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22835,7 +22835,7 @@ static void emit_op(JSParseState *s, uint8_t val)
2283522835
static void emit_atom(JSParseState *s, JSAtom name)
2283622836
{
2283722837
DynBuf *bc = &s->cur_func->byte_code;
22838-
if (dbuf_realloc(bc, bc->size + 4))
22838+
if (dbuf_claim(bc, 4))
2283922839
return; /* not enough memory : don't duplicate the atom */
2284022840
put_u32(bc->buf + bc->size, JS_DupAtom(s->ctx, name));
2284122841
bc->size += 4;
@@ -27751,7 +27751,7 @@ static __exception int js_parse_for_in_of(JSParseState *s, int label_name,
2775127751
int chunk_size = pos_expr - pos_next;
2775227752
int offset = bc->size - pos_next;
2775327753
int i;
27754-
dbuf_realloc(bc, bc->size + chunk_size);
27754+
dbuf_claim(bc, chunk_size);
2775527755
dbuf_put(bc, bc->buf + pos_next, chunk_size);
2775627756
memset(bc->buf + pos_next, OP_nop, chunk_size);
2775727757
/* `next` part ends with a goto */
@@ -28157,7 +28157,7 @@ static __exception int js_parse_statement_or_decl(JSParseState *s,
2815728157
int chunk_size = pos_body - pos_cont;
2815828158
int offset = bc->size - pos_cont;
2815928159
int i;
28160-
dbuf_realloc(bc, bc->size + chunk_size);
28160+
dbuf_claim(bc, chunk_size);
2816128161
dbuf_put(bc, bc->buf + pos_cont, chunk_size);
2816228162
memset(bc->buf + pos_cont, OP_nop, chunk_size);
2816328163
/* increment part ends with a goto */
@@ -37097,7 +37097,7 @@ static int JS_WriteObjectAtoms(BCWriterState *s)
3709737097
/* XXX: could just append dbuf1 data, but it uses more memory if
3709837098
dbuf1 is larger than dbuf */
3709937099
atoms_size = s->dbuf.size;
37100-
if (dbuf_realloc(&dbuf1, dbuf1.size + atoms_size))
37100+
if (dbuf_claim(&dbuf1, atoms_size))
3710137101
goto fail;
3710237102
memmove(dbuf1.buf + atoms_size, dbuf1.buf, dbuf1.size);
3710337103
memcpy(dbuf1.buf, s->dbuf.buf, atoms_size);

0 commit comments

Comments
 (0)