Mercurial
comparison third_party/luajit/src/lj_buf.c @ 178:94705b5986b3
[ThirdParty] Added WRK and luajit for load testing.
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Thu, 22 Jan 2026 20:10:30 -0800 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 177:24fe8ff94056 | 178:94705b5986b3 |
|---|---|
| 1 /* | |
| 2 ** Buffer handling. | |
| 3 ** Copyright (C) 2005-2023 Mike Pall. See Copyright Notice in luajit.h | |
| 4 */ | |
| 5 | |
| 6 #define lj_buf_c | |
| 7 #define LUA_CORE | |
| 8 | |
| 9 #include "lj_obj.h" | |
| 10 #include "lj_gc.h" | |
| 11 #include "lj_err.h" | |
| 12 #include "lj_buf.h" | |
| 13 #include "lj_str.h" | |
| 14 #include "lj_tab.h" | |
| 15 #include "lj_strfmt.h" | |
| 16 | |
| 17 /* -- Buffer management --------------------------------------------------- */ | |
| 18 | |
| 19 static void buf_grow(SBuf *sb, MSize sz) | |
| 20 { | |
| 21 MSize osz = sbufsz(sb), len = sbuflen(sb), nsz = osz; | |
| 22 char *b; | |
| 23 GCSize flag; | |
| 24 if (nsz < LJ_MIN_SBUF) nsz = LJ_MIN_SBUF; | |
| 25 while (nsz < sz) nsz += nsz; | |
| 26 flag = sbufflag(sb); | |
| 27 if ((flag & SBUF_FLAG_COW)) { /* Copy-on-write semantics. */ | |
| 28 lj_assertG_(G(sbufL(sb)), sb->w == sb->e, "bad SBuf COW"); | |
| 29 b = (char *)lj_mem_new(sbufL(sb), nsz); | |
| 30 setsbufflag(sb, flag & ~(GCSize)SBUF_FLAG_COW); | |
| 31 setgcrefnull(sbufX(sb)->cowref); | |
| 32 memcpy(b, sb->b, osz); | |
| 33 } else { | |
| 34 b = (char *)lj_mem_realloc(sbufL(sb), sb->b, osz, nsz); | |
| 35 } | |
| 36 if ((flag & SBUF_FLAG_EXT)) { | |
| 37 sbufX(sb)->r = sbufX(sb)->r - sb->b + b; /* Adjust read pointer, too. */ | |
| 38 } | |
| 39 /* Adjust buffer pointers. */ | |
| 40 sb->b = b; | |
| 41 sb->w = b + len; | |
| 42 sb->e = b + nsz; | |
| 43 if ((flag & SBUF_FLAG_BORROW)) { /* Adjust borrowed buffer pointers. */ | |
| 44 SBuf *bsb = mref(sbufX(sb)->bsb, SBuf); | |
| 45 bsb->b = b; | |
| 46 bsb->w = b + len; | |
| 47 bsb->e = b + nsz; | |
| 48 } | |
| 49 } | |
| 50 | |
| 51 LJ_NOINLINE char *LJ_FASTCALL lj_buf_need2(SBuf *sb, MSize sz) | |
| 52 { | |
| 53 lj_assertG_(G(sbufL(sb)), sz > sbufsz(sb), "SBuf overflow"); | |
| 54 if (LJ_UNLIKELY(sz > LJ_MAX_BUF)) | |
| 55 lj_err_mem(sbufL(sb)); | |
| 56 buf_grow(sb, sz); | |
| 57 return sb->b; | |
| 58 } | |
| 59 | |
| 60 LJ_NOINLINE char *LJ_FASTCALL lj_buf_more2(SBuf *sb, MSize sz) | |
| 61 { | |
| 62 if (sbufisext(sb)) { | |
| 63 SBufExt *sbx = (SBufExt *)sb; | |
| 64 MSize len = sbufxlen(sbx); | |
| 65 if (LJ_UNLIKELY(sz > LJ_MAX_BUF || len + sz > LJ_MAX_BUF)) | |
| 66 lj_err_mem(sbufL(sbx)); | |
| 67 if (len + sz > sbufsz(sbx)) { /* Must grow. */ | |
| 68 buf_grow((SBuf *)sbx, len + sz); | |
| 69 } else if (sbufiscow(sb) || sbufxslack(sbx) < (sbufsz(sbx) >> 3)) { | |
| 70 /* Also grow to avoid excessive compactions, if slack < size/8. */ | |
| 71 buf_grow((SBuf *)sbx, sbuflen(sbx) + sz); /* Not sbufxlen! */ | |
| 72 return sbx->w; | |
| 73 } | |
| 74 if (sbx->r != sbx->b) { /* Compact by moving down. */ | |
| 75 memmove(sbx->b, sbx->r, len); | |
| 76 sbx->r = sbx->b; | |
| 77 sbx->w = sbx->b + len; | |
| 78 lj_assertG_(G(sbufL(sbx)), len + sz <= sbufsz(sbx), "bad SBuf compact"); | |
| 79 } | |
| 80 } else { | |
| 81 MSize len = sbuflen(sb); | |
| 82 lj_assertG_(G(sbufL(sb)), sz > sbufleft(sb), "SBuf overflow"); | |
| 83 if (LJ_UNLIKELY(sz > LJ_MAX_BUF || len + sz > LJ_MAX_BUF)) | |
| 84 lj_err_mem(sbufL(sb)); | |
| 85 buf_grow(sb, len + sz); | |
| 86 } | |
| 87 return sb->w; | |
| 88 } | |
| 89 | |
| 90 void LJ_FASTCALL lj_buf_shrink(lua_State *L, SBuf *sb) | |
| 91 { | |
| 92 char *b = sb->b; | |
| 93 MSize osz = (MSize)(sb->e - b); | |
| 94 if (osz > 2*LJ_MIN_SBUF) { | |
| 95 MSize n = (MSize)(sb->w - b); | |
| 96 b = lj_mem_realloc(L, b, osz, (osz >> 1)); | |
| 97 sb->b = b; | |
| 98 sb->w = b + n; | |
| 99 sb->e = b + (osz >> 1); | |
| 100 } | |
| 101 lj_assertG_(G(sbufL(sb)), !sbufisext(sb), "YAGNI shrink SBufExt"); | |
| 102 } | |
| 103 | |
| 104 char * LJ_FASTCALL lj_buf_tmp(lua_State *L, MSize sz) | |
| 105 { | |
| 106 SBuf *sb = &G(L)->tmpbuf; | |
| 107 setsbufL(sb, L); | |
| 108 return lj_buf_need(sb, sz); | |
| 109 } | |
| 110 | |
| 111 #if LJ_HASBUFFER && LJ_HASJIT | |
| 112 void lj_bufx_set(SBufExt *sbx, const char *p, MSize len, GCobj *ref) | |
| 113 { | |
| 114 lua_State *L = sbufL(sbx); | |
| 115 lj_bufx_free(L, sbx); | |
| 116 lj_bufx_set_cow(L, sbx, p, len); | |
| 117 setgcref(sbx->cowref, ref); | |
| 118 lj_gc_objbarrier(L, (GCudata *)sbx - 1, ref); | |
| 119 } | |
| 120 | |
| 121 #if LJ_HASFFI | |
| 122 MSize LJ_FASTCALL lj_bufx_more(SBufExt *sbx, MSize sz) | |
| 123 { | |
| 124 lj_buf_more((SBuf *)sbx, sz); | |
| 125 return sbufleft(sbx); | |
| 126 } | |
| 127 #endif | |
| 128 #endif | |
| 129 | |
| 130 /* -- Low-level buffer put operations ------------------------------------- */ | |
| 131 | |
| 132 SBuf *lj_buf_putmem(SBuf *sb, const void *q, MSize len) | |
| 133 { | |
| 134 char *w = lj_buf_more(sb, len); | |
| 135 w = lj_buf_wmem(w, q, len); | |
| 136 sb->w = w; | |
| 137 return sb; | |
| 138 } | |
| 139 | |
| 140 #if LJ_HASJIT || LJ_HASFFI | |
| 141 static LJ_NOINLINE SBuf * LJ_FASTCALL lj_buf_putchar2(SBuf *sb, int c) | |
| 142 { | |
| 143 char *w = lj_buf_more2(sb, 1); | |
| 144 *w++ = (char)c; | |
| 145 sb->w = w; | |
| 146 return sb; | |
| 147 } | |
| 148 | |
| 149 SBuf * LJ_FASTCALL lj_buf_putchar(SBuf *sb, int c) | |
| 150 { | |
| 151 char *w = sb->w; | |
| 152 if (LJ_LIKELY(w < sb->e)) { | |
| 153 *w++ = (char)c; | |
| 154 sb->w = w; | |
| 155 return sb; | |
| 156 } | |
| 157 return lj_buf_putchar2(sb, c); | |
| 158 } | |
| 159 #endif | |
| 160 | |
| 161 SBuf * LJ_FASTCALL lj_buf_putstr(SBuf *sb, GCstr *s) | |
| 162 { | |
| 163 MSize len = s->len; | |
| 164 char *w = lj_buf_more(sb, len); | |
| 165 w = lj_buf_wmem(w, strdata(s), len); | |
| 166 sb->w = w; | |
| 167 return sb; | |
| 168 } | |
| 169 | |
| 170 /* -- High-level buffer put operations ------------------------------------ */ | |
| 171 | |
| 172 SBuf * LJ_FASTCALL lj_buf_putstr_reverse(SBuf *sb, GCstr *s) | |
| 173 { | |
| 174 MSize len = s->len; | |
| 175 char *w = lj_buf_more(sb, len), *e = w+len; | |
| 176 const char *q = strdata(s)+len-1; | |
| 177 while (w < e) | |
| 178 *w++ = *q--; | |
| 179 sb->w = w; | |
| 180 return sb; | |
| 181 } | |
| 182 | |
| 183 SBuf * LJ_FASTCALL lj_buf_putstr_lower(SBuf *sb, GCstr *s) | |
| 184 { | |
| 185 MSize len = s->len; | |
| 186 char *w = lj_buf_more(sb, len), *e = w+len; | |
| 187 const char *q = strdata(s); | |
| 188 for (; w < e; w++, q++) { | |
| 189 uint32_t c = *(unsigned char *)q; | |
| 190 #if LJ_TARGET_PPC | |
| 191 *w = c + ((c >= 'A' && c <= 'Z') << 5); | |
| 192 #else | |
| 193 if (c >= 'A' && c <= 'Z') c += 0x20; | |
| 194 *w = c; | |
| 195 #endif | |
| 196 } | |
| 197 sb->w = w; | |
| 198 return sb; | |
| 199 } | |
| 200 | |
| 201 SBuf * LJ_FASTCALL lj_buf_putstr_upper(SBuf *sb, GCstr *s) | |
| 202 { | |
| 203 MSize len = s->len; | |
| 204 char *w = lj_buf_more(sb, len), *e = w+len; | |
| 205 const char *q = strdata(s); | |
| 206 for (; w < e; w++, q++) { | |
| 207 uint32_t c = *(unsigned char *)q; | |
| 208 #if LJ_TARGET_PPC | |
| 209 *w = c - ((c >= 'a' && c <= 'z') << 5); | |
| 210 #else | |
| 211 if (c >= 'a' && c <= 'z') c -= 0x20; | |
| 212 *w = c; | |
| 213 #endif | |
| 214 } | |
| 215 sb->w = w; | |
| 216 return sb; | |
| 217 } | |
| 218 | |
| 219 SBuf *lj_buf_putstr_rep(SBuf *sb, GCstr *s, int32_t rep) | |
| 220 { | |
| 221 MSize len = s->len; | |
| 222 if (rep > 0 && len) { | |
| 223 uint64_t tlen = (uint64_t)rep * len; | |
| 224 char *w; | |
| 225 if (LJ_UNLIKELY(tlen > LJ_MAX_STR)) | |
| 226 lj_err_mem(sbufL(sb)); | |
| 227 w = lj_buf_more(sb, (MSize)tlen); | |
| 228 if (len == 1) { /* Optimize a common case. */ | |
| 229 uint32_t c = strdata(s)[0]; | |
| 230 do { *w++ = c; } while (--rep > 0); | |
| 231 } else { | |
| 232 const char *e = strdata(s) + len; | |
| 233 do { | |
| 234 const char *q = strdata(s); | |
| 235 do { *w++ = *q++; } while (q < e); | |
| 236 } while (--rep > 0); | |
| 237 } | |
| 238 sb->w = w; | |
| 239 } | |
| 240 return sb; | |
| 241 } | |
| 242 | |
| 243 SBuf *lj_buf_puttab(SBuf *sb, GCtab *t, GCstr *sep, int32_t i, int32_t e) | |
| 244 { | |
| 245 MSize seplen = sep ? sep->len : 0; | |
| 246 if (i <= e) { | |
| 247 for (;;) { | |
| 248 cTValue *o = lj_tab_getint(t, i); | |
| 249 char *w; | |
| 250 if (!o) { | |
| 251 badtype: /* Error: bad element type. */ | |
| 252 sb->w = (char *)(intptr_t)i; /* Store failing index. */ | |
| 253 return NULL; | |
| 254 } else if (tvisstr(o)) { | |
| 255 MSize len = strV(o)->len; | |
| 256 w = lj_buf_wmem(lj_buf_more(sb, len + seplen), strVdata(o), len); | |
| 257 } else if (tvisint(o)) { | |
| 258 w = lj_strfmt_wint(lj_buf_more(sb, STRFMT_MAXBUF_INT+seplen), intV(o)); | |
| 259 } else if (tvisnum(o)) { | |
| 260 w = lj_buf_more(lj_strfmt_putfnum(sb, STRFMT_G14, numV(o)), seplen); | |
| 261 } else { | |
| 262 goto badtype; | |
| 263 } | |
| 264 if (i++ == e) { | |
| 265 sb->w = w; | |
| 266 break; | |
| 267 } | |
| 268 if (seplen) w = lj_buf_wmem(w, strdata(sep), seplen); | |
| 269 sb->w = w; | |
| 270 } | |
| 271 } | |
| 272 return sb; | |
| 273 } | |
| 274 | |
| 275 /* -- Miscellaneous buffer operations ------------------------------------- */ | |
| 276 | |
| 277 GCstr * LJ_FASTCALL lj_buf_tostr(SBuf *sb) | |
| 278 { | |
| 279 return lj_str_new(sbufL(sb), sb->b, sbuflen(sb)); | |
| 280 } | |
| 281 | |
| 282 /* Concatenate two strings. */ | |
| 283 GCstr *lj_buf_cat2str(lua_State *L, GCstr *s1, GCstr *s2) | |
| 284 { | |
| 285 MSize len1 = s1->len, len2 = s2->len; | |
| 286 char *buf = lj_buf_tmp(L, len1 + len2); | |
| 287 memcpy(buf, strdata(s1), len1); | |
| 288 memcpy(buf+len1, strdata(s2), len2); | |
| 289 return lj_str_new(L, buf, len1 + len2); | |
| 290 } | |
| 291 | |
| 292 /* Read ULEB128 from buffer. */ | |
| 293 uint32_t LJ_FASTCALL lj_buf_ruleb128(const char **pp) | |
| 294 { | |
| 295 const uint8_t *w = (const uint8_t *)*pp; | |
| 296 uint32_t v = *w++; | |
| 297 if (LJ_UNLIKELY(v >= 0x80)) { | |
| 298 int sh = 0; | |
| 299 v &= 0x7f; | |
| 300 do { v |= ((*w & 0x7f) << (sh += 7)); } while (*w++ >= 0x80); | |
| 301 } | |
| 302 *pp = (const char *)w; | |
| 303 return v; | |
| 304 } | |
| 305 |