decode_fast.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2009-2021, Google LLC
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of Google LLC nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT,
20  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 // Fast decoder: ~3x the speed of decode.c, but requires x86-64/ARM64.
29 // Also the table size grows by 2x.
30 //
31 // Could potentially be ported to other 64-bit archs that pass at least six
32 // arguments in registers and have 8 unused high bits in pointers.
33 //
34 // The overall design is to create specialized functions for every possible
35 // field type (eg. oneof boolean field with a 1 byte tag) and then dispatch
36 // to the specialized function as quickly as possible.
37 
38 #include "upb/decode_fast.h"
39 
40 #include "upb/decode_internal.h"
41 
42 /* Must be last. */
43 #include "upb/port_def.inc"
44 
45 #if UPB_FASTTABLE
46 
47 // The standard set of arguments passed to each parsing function.
48 // Thanks to x86-64 calling conventions, these will stay in registers.
49 #define UPB_PARSE_PARAMS \
50  upb_Decoder *d, const char *ptr, upb_Message *msg, intptr_t table, \
51  uint64_t hasbits, uint64_t data
52 
53 #define UPB_PARSE_ARGS d, ptr, msg, table, hasbits, data
54 
55 #define RETURN_GENERIC(m) \
56  /* Uncomment either of these for debugging purposes. */ \
57  /* fprintf(stderr, m); */ \
58  /*__builtin_trap(); */ \
59  return fastdecode_generic(d, ptr, msg, table, hasbits, 0);
60 
61 typedef enum {
62  CARD_s = 0, /* Singular (optional, non-repeated) */
63  CARD_o = 1, /* Oneof */
64  CARD_r = 2, /* Repeated */
65  CARD_p = 3 /* Packed Repeated */
66 } upb_card;
67 
69 static const char* fastdecode_isdonefallback(UPB_PARSE_PARAMS) {
70  int overrun = data;
71  int status;
72  ptr = decode_isdonefallback_inl(d, ptr, overrun, &status);
73  if (ptr == NULL) {
74  return fastdecode_err(d, status);
75  }
77  UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS);
78 }
79 
81 static const char* fastdecode_dispatch(UPB_PARSE_PARAMS) {
82  if (UPB_UNLIKELY(ptr >= d->limit_ptr)) {
83  int overrun = ptr - d->end;
84  if (UPB_LIKELY(overrun == d->limit)) {
85  // Parse is finished.
86  *(uint32_t*)msg |= hasbits; // Sync hasbits.
88  return UPB_UNLIKELY(l->required_count)
90  : ptr;
91  } else {
92  data = overrun;
93  UPB_MUSTTAIL return fastdecode_isdonefallback(UPB_PARSE_ARGS);
94  }
95  }
96 
97  // Read two bytes of tag data (for a one-byte tag, the high byte is junk).
99  UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS);
100 }
101 
103 static bool fastdecode_checktag(uint16_t data, int tagbytes) {
104  if (tagbytes == 1) {
105  return (data & 0xff) == 0;
106  } else {
107  return data == 0;
108  }
109 }
110 
112 static const char* fastdecode_longsize(const char* ptr, int* size) {
113  int i;
114  UPB_ASSERT(*size & 0x80);
115  *size &= 0xff;
116  for (i = 0; i < 3; i++) {
117  ptr++;
118  size_t byte = (uint8_t)ptr[-1];
119  *size += (byte - 1) << (7 + 7 * i);
120  if (UPB_LIKELY((byte & 0x80) == 0)) return ptr;
121  }
122  ptr++;
123  size_t byte = (uint8_t)ptr[-1];
124  // len is limited by 2gb not 4gb, hence 8 and not 16 as normally expected
125  // for a 32 bit varint.
126  if (UPB_UNLIKELY(byte >= 8)) return NULL;
127  *size += (byte - 1) << 28;
128  return ptr;
129 }
130 
132 static bool fastdecode_boundscheck(const char* ptr, size_t len,
133  const char* end) {
134  uintptr_t uptr = (uintptr_t)ptr;
135  uintptr_t uend = (uintptr_t)end + 16;
136  uintptr_t res = uptr + len;
137  return res < uptr || res > uend;
138 }
139 
141 static bool fastdecode_boundscheck2(const char* ptr, size_t len,
142  const char* end) {
143  // This is one extra branch compared to the more normal:
144  // return (size_t)(end - ptr) < size;
145  // However it is one less computation if we are just about to use "ptr + len":
146  // https://godbolt.org/z/35YGPz
147  // In microbenchmarks this shows an overall 4% improvement.
148  uintptr_t uptr = (uintptr_t)ptr;
149  uintptr_t uend = (uintptr_t)end;
150  uintptr_t res = uptr + len;
151  return res < uptr || res > uend;
152 }
153 
154 typedef const char* fastdecode_delimfunc(upb_Decoder* d, const char* ptr,
155  void* ctx);
156 
158 static const char* fastdecode_delimited(upb_Decoder* d, const char* ptr,
159  fastdecode_delimfunc* func, void* ctx) {
160  ptr++;
161  int len = (int8_t)ptr[-1];
162  if (fastdecode_boundscheck2(ptr, len, d->limit_ptr)) {
163  // Slow case: Sub-message is >=128 bytes and/or exceeds the current buffer.
164  // If it exceeds the buffer limit, limit/limit_ptr will change during
165  // sub-message parsing, so we need to preserve delta, not limit.
166  if (UPB_UNLIKELY(len & 0x80)) {
167  // Size varint >1 byte (length >= 128).
168  ptr = fastdecode_longsize(ptr, &len);
169  if (!ptr) {
170  // Corrupt wire format: size exceeded INT_MAX.
171  return NULL;
172  }
173  }
174  if (ptr - d->end + (int)len > d->limit) {
175  // Corrupt wire format: invalid limit.
176  return NULL;
177  }
178  int delta = decode_pushlimit(d, ptr, len);
179  ptr = func(d, ptr, ctx);
180  decode_poplimit(d, ptr, delta);
181  } else {
182  // Fast case: Sub-message is <128 bytes and fits in the current buffer.
183  // This means we can preserve limit/limit_ptr verbatim.
184  const char* saved_limit_ptr = d->limit_ptr;
185  int saved_limit = d->limit;
186  d->limit_ptr = ptr + len;
187  d->limit = d->limit_ptr - d->end;
188  UPB_ASSERT(d->limit_ptr == d->end + UPB_MIN(0, d->limit));
189  ptr = func(d, ptr, ctx);
190  d->limit_ptr = saved_limit_ptr;
191  d->limit = saved_limit;
192  UPB_ASSERT(d->limit_ptr == d->end + UPB_MIN(0, d->limit));
193  }
194  return ptr;
195 }
196 
197 /* singular, oneof, repeated field handling ***********************************/
198 
199 typedef struct {
200  upb_Array* arr;
201  void* end;
202 } fastdecode_arr;
203 
204 typedef enum {
205  FD_NEXT_ATLIMIT,
206  FD_NEXT_SAMEFIELD,
207  FD_NEXT_OTHERFIELD
208 } fastdecode_next;
209 
210 typedef struct {
211  void* dst;
212  fastdecode_next next;
213  uint32_t tag;
214 } fastdecode_nextret;
215 
217 static void* fastdecode_resizearr(upb_Decoder* d, void* dst,
218  fastdecode_arr* farr, int valbytes) {
219  if (UPB_UNLIKELY(dst == farr->end)) {
220  size_t old_size = farr->arr->size;
221  size_t old_bytes = old_size * valbytes;
222  size_t new_size = old_size * 2;
223  size_t new_bytes = new_size * valbytes;
224  char* old_ptr = _upb_array_ptr(farr->arr);
225  char* new_ptr = upb_Arena_Realloc(&d->arena, old_ptr, old_bytes, new_bytes);
226  uint8_t elem_size_lg2 = __builtin_ctz(valbytes);
227  farr->arr->size = new_size;
228  farr->arr->data = _upb_array_tagptr(new_ptr, elem_size_lg2);
229  dst = (void*)(new_ptr + (old_size * valbytes));
230  farr->end = (void*)(new_ptr + (new_size * valbytes));
231  }
232  return dst;
233 }
234 
236 static bool fastdecode_tagmatch(uint32_t tag, uint64_t data, int tagbytes) {
237  if (tagbytes == 1) {
238  return (uint8_t)tag == (uint8_t)data;
239  } else {
240  return (uint16_t)tag == (uint16_t)data;
241  }
242 }
243 
245 static void fastdecode_commitarr(void* dst, fastdecode_arr* farr,
246  int valbytes) {
247  farr->arr->len =
248  (size_t)((char*)dst - (char*)_upb_array_ptr(farr->arr)) / valbytes;
249 }
250 
252 static fastdecode_nextret fastdecode_nextrepeated(upb_Decoder* d, void* dst,
253  const char** ptr,
254  fastdecode_arr* farr,
255  uint64_t data, int tagbytes,
256  int valbytes) {
257  fastdecode_nextret ret;
258  dst = (char*)dst + valbytes;
259 
260  if (UPB_LIKELY(!decode_isdone(d, ptr))) {
261  ret.tag = fastdecode_loadtag(*ptr);
262  if (fastdecode_tagmatch(ret.tag, data, tagbytes)) {
263  ret.next = FD_NEXT_SAMEFIELD;
264  } else {
265  fastdecode_commitarr(dst, farr, valbytes);
266  ret.next = FD_NEXT_OTHERFIELD;
267  }
268  } else {
269  fastdecode_commitarr(dst, farr, valbytes);
270  ret.next = FD_NEXT_ATLIMIT;
271  }
272 
273  ret.dst = dst;
274  return ret;
275 }
276 
278 static void* fastdecode_fieldmem(upb_Message* msg, uint64_t data) {
279  size_t ofs = data >> 48;
280  return (char*)msg + ofs;
281 }
282 
284 static void* fastdecode_getfield(upb_Decoder* d, const char* ptr,
286  uint64_t* hasbits, fastdecode_arr* farr,
287  int valbytes, upb_card card) {
288  switch (card) {
289  case CARD_s: {
290  uint8_t hasbit_index = *data >> 24;
291  // Set hasbit and return pointer to scalar field.
292  *hasbits |= 1ull << hasbit_index;
293  return fastdecode_fieldmem(msg, *data);
294  }
295  case CARD_o: {
296  uint16_t case_ofs = *data >> 32;
297  uint32_t* oneof_case = UPB_PTR_AT(msg, case_ofs, uint32_t);
298  uint8_t field_number = *data >> 24;
299  *oneof_case = field_number;
300  return fastdecode_fieldmem(msg, *data);
301  }
302  case CARD_r: {
303  // Get pointer to upb_Array and allocate/expand if necessary.
304  uint8_t elem_size_lg2 = __builtin_ctz(valbytes);
305  upb_Array** arr_p = fastdecode_fieldmem(msg, *data);
306  char* begin;
307  *(uint32_t*)msg |= *hasbits;
308  *hasbits = 0;
309  if (UPB_LIKELY(!*arr_p)) {
310  farr->arr = _upb_Array_New(&d->arena, 8, elem_size_lg2);
311  *arr_p = farr->arr;
312  } else {
313  farr->arr = *arr_p;
314  }
315  begin = _upb_array_ptr(farr->arr);
316  farr->end = begin + (farr->arr->size * valbytes);
318  return begin + (farr->arr->len * valbytes);
319  }
320  default:
321  UPB_UNREACHABLE();
322  }
323 }
324 
326 static bool fastdecode_flippacked(uint64_t* data, int tagbytes) {
327  *data ^= (0x2 ^ 0x0); // Patch data to match packed wiretype.
328  return fastdecode_checktag(*data, tagbytes);
329 }
330 
331 #define FASTDECODE_CHECKPACKED(tagbytes, card, func) \
332  if (UPB_UNLIKELY(!fastdecode_checktag(data, tagbytes))) { \
333  if (card == CARD_r && fastdecode_flippacked(&data, tagbytes)) { \
334  UPB_MUSTTAIL return func(UPB_PARSE_ARGS); \
335  } \
336  RETURN_GENERIC("packed check tag mismatch\n"); \
337  }
338 
339 /* varint fields **************************************************************/
340 
342 static uint64_t fastdecode_munge(uint64_t val, int valbytes, bool zigzag) {
343  if (valbytes == 1) {
344  return val != 0;
345  } else if (zigzag) {
346  if (valbytes == 4) {
347  uint32_t n = val;
348  return (n >> 1) ^ -(int32_t)(n & 1);
349  } else if (valbytes == 8) {
350  return (val >> 1) ^ -(int64_t)(val & 1);
351  }
352  UPB_UNREACHABLE();
353  }
354  return val;
355 }
356 
358 static const char* fastdecode_varint64(const char* ptr, uint64_t* val) {
359  ptr++;
360  *val = (uint8_t)ptr[-1];
361  if (UPB_UNLIKELY(*val & 0x80)) {
362  int i;
363  for (i = 0; i < 8; i++) {
364  ptr++;
365  uint64_t byte = (uint8_t)ptr[-1];
366  *val += (byte - 1) << (7 + 7 * i);
367  if (UPB_LIKELY((byte & 0x80) == 0)) goto done;
368  }
369  ptr++;
370  uint64_t byte = (uint8_t)ptr[-1];
371  if (byte > 1) {
372  return NULL;
373  }
374  *val += (byte - 1) << 63;
375  }
376 done:
377  UPB_ASSUME(ptr != NULL);
378  return ptr;
379 }
380 
381 #define FASTDECODE_UNPACKEDVARINT(d, ptr, msg, table, hasbits, data, tagbytes, \
382  valbytes, card, zigzag, packed) \
383  uint64_t val; \
384  void* dst; \
385  fastdecode_arr farr; \
386  \
387  FASTDECODE_CHECKPACKED(tagbytes, card, packed); \
388  \
389  dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr, valbytes, \
390  card); \
391  if (card == CARD_r) { \
392  if (UPB_UNLIKELY(!dst)) { \
393  RETURN_GENERIC("need array resize\n"); \
394  } \
395  } \
396  \
397  again: \
398  if (card == CARD_r) { \
399  dst = fastdecode_resizearr(d, dst, &farr, valbytes); \
400  } \
401  \
402  ptr += tagbytes; \
403  ptr = fastdecode_varint64(ptr, &val); \
404  if (ptr == NULL) return fastdecode_err(d, kUpb_DecodeStatus_Malformed); \
405  val = fastdecode_munge(val, valbytes, zigzag); \
406  memcpy(dst, &val, valbytes); \
407  \
408  if (card == CARD_r) { \
409  fastdecode_nextret ret = fastdecode_nextrepeated( \
410  d, dst, &ptr, &farr, data, tagbytes, valbytes); \
411  switch (ret.next) { \
412  case FD_NEXT_SAMEFIELD: \
413  dst = ret.dst; \
414  goto again; \
415  case FD_NEXT_OTHERFIELD: \
416  data = ret.tag; \
417  UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \
418  case FD_NEXT_ATLIMIT: \
419  return ptr; \
420  } \
421  } \
422  \
423  UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS);
424 
425 typedef struct {
426  uint8_t valbytes;
427  bool zigzag;
428  void* dst;
429  fastdecode_arr farr;
430 } fastdecode_varintdata;
431 
433 static const char* fastdecode_topackedvarint(upb_Decoder* d, const char* ptr,
434  void* ctx) {
435  fastdecode_varintdata* data = ctx;
436  void* dst = data->dst;
437  uint64_t val;
438 
439  while (!decode_isdone(d, &ptr)) {
440  dst = fastdecode_resizearr(d, dst, &data->farr, data->valbytes);
441  ptr = fastdecode_varint64(ptr, &val);
442  if (ptr == NULL) return NULL;
443  val = fastdecode_munge(val, data->valbytes, data->zigzag);
444  memcpy(dst, &val, data->valbytes);
445  dst = (char*)dst + data->valbytes;
446  }
447 
448  fastdecode_commitarr(dst, &data->farr, data->valbytes);
449  return ptr;
450 }
451 
452 #define FASTDECODE_PACKEDVARINT(d, ptr, msg, table, hasbits, data, tagbytes, \
453  valbytes, zigzag, unpacked) \
454  fastdecode_varintdata ctx = {valbytes, zigzag}; \
455  \
456  FASTDECODE_CHECKPACKED(tagbytes, CARD_r, unpacked); \
457  \
458  ctx.dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &ctx.farr, \
459  valbytes, CARD_r); \
460  if (UPB_UNLIKELY(!ctx.dst)) { \
461  RETURN_GENERIC("need array resize\n"); \
462  } \
463  \
464  ptr += tagbytes; \
465  ptr = fastdecode_delimited(d, ptr, &fastdecode_topackedvarint, &ctx); \
466  \
467  if (UPB_UNLIKELY(ptr == NULL)) { \
468  return fastdecode_err(d, kUpb_DecodeStatus_Malformed); \
469  } \
470  \
471  UPB_MUSTTAIL return fastdecode_dispatch(d, ptr, msg, table, hasbits, 0);
472 
473 #define FASTDECODE_VARINT(d, ptr, msg, table, hasbits, data, tagbytes, \
474  valbytes, card, zigzag, unpacked, packed) \
475  if (card == CARD_p) { \
476  FASTDECODE_PACKEDVARINT(d, ptr, msg, table, hasbits, data, tagbytes, \
477  valbytes, zigzag, unpacked); \
478  } else { \
479  FASTDECODE_UNPACKEDVARINT(d, ptr, msg, table, hasbits, data, tagbytes, \
480  valbytes, card, zigzag, packed); \
481  }
482 
483 #define z_ZZ true
484 #define b_ZZ false
485 #define v_ZZ false
486 
487 /* Generate all combinations:
488  * {s,o,r,p} x {b1,v4,z4,v8,z8} x {1bt,2bt} */
489 
490 #define F(card, type, valbytes, tagbytes) \
491  UPB_NOINLINE \
492  const char* upb_p##card##type##valbytes##_##tagbytes##bt(UPB_PARSE_PARAMS) { \
493  FASTDECODE_VARINT(d, ptr, msg, table, hasbits, data, tagbytes, valbytes, \
494  CARD_##card, type##_ZZ, \
495  upb_pr##type##valbytes##_##tagbytes##bt, \
496  upb_pp##type##valbytes##_##tagbytes##bt); \
497  }
498 
499 #define TYPES(card, tagbytes) \
500  F(card, b, 1, tagbytes) \
501  F(card, v, 4, tagbytes) \
502  F(card, v, 8, tagbytes) \
503  F(card, z, 4, tagbytes) \
504  F(card, z, 8, tagbytes)
505 
506 #define TAGBYTES(card) \
507  TYPES(card, 1) \
508  TYPES(card, 2)
509 
510 TAGBYTES(s)
511 TAGBYTES(o)
512 TAGBYTES(r)
513 TAGBYTES(p)
514 
515 #undef z_ZZ
516 #undef b_ZZ
517 #undef v_ZZ
518 #undef o_ONEOF
519 #undef s_ONEOF
520 #undef r_ONEOF
521 #undef F
522 #undef TYPES
523 #undef TAGBYTES
524 #undef FASTDECODE_UNPACKEDVARINT
525 #undef FASTDECODE_PACKEDVARINT
526 #undef FASTDECODE_VARINT
527 
528 /* fixed fields ***************************************************************/
529 
530 #define FASTDECODE_UNPACKEDFIXED(d, ptr, msg, table, hasbits, data, tagbytes, \
531  valbytes, card, packed) \
532  void* dst; \
533  fastdecode_arr farr; \
534  \
535  FASTDECODE_CHECKPACKED(tagbytes, card, packed) \
536  \
537  dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr, valbytes, \
538  card); \
539  if (card == CARD_r) { \
540  if (UPB_UNLIKELY(!dst)) { \
541  RETURN_GENERIC("couldn't allocate array in arena\n"); \
542  } \
543  } \
544  \
545  again: \
546  if (card == CARD_r) { \
547  dst = fastdecode_resizearr(d, dst, &farr, valbytes); \
548  } \
549  \
550  ptr += tagbytes; \
551  memcpy(dst, ptr, valbytes); \
552  ptr += valbytes; \
553  \
554  if (card == CARD_r) { \
555  fastdecode_nextret ret = fastdecode_nextrepeated( \
556  d, dst, &ptr, &farr, data, tagbytes, valbytes); \
557  switch (ret.next) { \
558  case FD_NEXT_SAMEFIELD: \
559  dst = ret.dst; \
560  goto again; \
561  case FD_NEXT_OTHERFIELD: \
562  data = ret.tag; \
563  UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \
564  case FD_NEXT_ATLIMIT: \
565  return ptr; \
566  } \
567  } \
568  \
569  UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS);
570 
571 #define FASTDECODE_PACKEDFIXED(d, ptr, msg, table, hasbits, data, tagbytes, \
572  valbytes, unpacked) \
573  FASTDECODE_CHECKPACKED(tagbytes, CARD_r, unpacked) \
574  \
575  ptr += tagbytes; \
576  int size = (uint8_t)ptr[0]; \
577  ptr++; \
578  if (size & 0x80) { \
579  ptr = fastdecode_longsize(ptr, &size); \
580  } \
581  \
582  if (UPB_UNLIKELY(fastdecode_boundscheck(ptr, size, d->limit_ptr) || \
583  (size % valbytes) != 0)) { \
584  return fastdecode_err(d, kUpb_DecodeStatus_Malformed); \
585  } \
586  \
587  upb_Array** arr_p = fastdecode_fieldmem(msg, data); \
588  upb_Array* arr = *arr_p; \
589  uint8_t elem_size_lg2 = __builtin_ctz(valbytes); \
590  int elems = size / valbytes; \
591  \
592  if (UPB_LIKELY(!arr)) { \
593  *arr_p = arr = _upb_Array_New(&d->arena, elems, elem_size_lg2); \
594  if (!arr) { \
595  return fastdecode_err(d, kUpb_DecodeStatus_Malformed); \
596  } \
597  } else { \
598  _upb_Array_Resize(arr, elems, &d->arena); \
599  } \
600  \
601  char* dst = _upb_array_ptr(arr); \
602  memcpy(dst, ptr, size); \
603  arr->len = elems; \
604  \
605  ptr += size; \
606  UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS);
607 
608 #define FASTDECODE_FIXED(d, ptr, msg, table, hasbits, data, tagbytes, \
609  valbytes, card, unpacked, packed) \
610  if (card == CARD_p) { \
611  FASTDECODE_PACKEDFIXED(d, ptr, msg, table, hasbits, data, tagbytes, \
612  valbytes, unpacked); \
613  } else { \
614  FASTDECODE_UNPACKEDFIXED(d, ptr, msg, table, hasbits, data, tagbytes, \
615  valbytes, card, packed); \
616  }
617 
618 /* Generate all combinations:
619  * {s,o,r,p} x {f4,f8} x {1bt,2bt} */
620 
621 #define F(card, valbytes, tagbytes) \
622  UPB_NOINLINE \
623  const char* upb_p##card##f##valbytes##_##tagbytes##bt(UPB_PARSE_PARAMS) { \
624  FASTDECODE_FIXED(d, ptr, msg, table, hasbits, data, tagbytes, valbytes, \
625  CARD_##card, upb_ppf##valbytes##_##tagbytes##bt, \
626  upb_prf##valbytes##_##tagbytes##bt); \
627  }
628 
629 #define TYPES(card, tagbytes) \
630  F(card, 4, tagbytes) \
631  F(card, 8, tagbytes)
632 
633 #define TAGBYTES(card) \
634  TYPES(card, 1) \
635  TYPES(card, 2)
636 
637 TAGBYTES(s)
638 TAGBYTES(o)
639 TAGBYTES(r)
640 TAGBYTES(p)
641 
642 #undef F
643 #undef TYPES
644 #undef TAGBYTES
645 #undef FASTDECODE_UNPACKEDFIXED
646 #undef FASTDECODE_PACKEDFIXED
647 
648 /* string fields **************************************************************/
649 
650 typedef const char* fastdecode_copystr_func(struct upb_Decoder* d,
651  const char* ptr, upb_Message* msg,
652  const upb_MiniTable* table,
653  uint64_t hasbits,
655 
657 static const char* fastdecode_verifyutf8(upb_Decoder* d, const char* ptr,
659  uint64_t hasbits, uint64_t data) {
661  if (!decode_verifyutf8_inl(dst->data, dst->size)) {
663  }
664  UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS);
665 }
666 
667 #define FASTDECODE_LONGSTRING(d, ptr, msg, table, hasbits, dst, validate_utf8) \
668  int size = (uint8_t)ptr[0]; /* Could plumb through hasbits. */ \
669  ptr++; \
670  if (size & 0x80) { \
671  ptr = fastdecode_longsize(ptr, &size); \
672  } \
673  \
674  if (UPB_UNLIKELY(fastdecode_boundscheck(ptr, size, d->limit_ptr))) { \
675  dst->size = 0; \
676  return fastdecode_err(d, kUpb_DecodeStatus_Malformed); \
677  } \
678  \
679  if (d->options & kUpb_DecodeOption_AliasString) { \
680  dst->data = ptr; \
681  dst->size = size; \
682  } else { \
683  char* data = upb_Arena_Malloc(&d->arena, size); \
684  if (!data) { \
685  return fastdecode_err(d, kUpb_DecodeStatus_OutOfMemory); \
686  } \
687  memcpy(data, ptr, size); \
688  dst->data = data; \
689  dst->size = size; \
690  } \
691  \
692  ptr += size; \
693  if (validate_utf8) { \
694  data = (uint64_t)dst; \
695  UPB_MUSTTAIL return fastdecode_verifyutf8(UPB_PARSE_ARGS); \
696  } else { \
697  UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS); \
698  }
699 
701 static const char* fastdecode_longstring_utf8(struct upb_Decoder* d,
702  const char* ptr, upb_Message* msg,
703  intptr_t table, uint64_t hasbits,
704  uint64_t data) {
706  FASTDECODE_LONGSTRING(d, ptr, msg, table, hasbits, dst, true);
707 }
708 
710 static const char* fastdecode_longstring_noutf8(
711  struct upb_Decoder* d, const char* ptr, upb_Message* msg, intptr_t table,
712  uint64_t hasbits, uint64_t data) {
714  FASTDECODE_LONGSTRING(d, ptr, msg, table, hasbits, dst, false);
715 }
716 
718 static void fastdecode_docopy(upb_Decoder* d, const char* ptr, uint32_t size,
719  int copy, char* data, upb_StringView* dst) {
720  d->arena.head.ptr += copy;
721  dst->data = data;
723  memcpy(data, ptr, copy);
725 }
726 
727 #define FASTDECODE_COPYSTRING(d, ptr, msg, table, hasbits, data, tagbytes, \
728  card, validate_utf8) \
729  upb_StringView* dst; \
730  fastdecode_arr farr; \
731  int64_t size; \
732  size_t arena_has; \
733  size_t common_has; \
734  char* buf; \
735  \
736  UPB_ASSERT((d->options & kUpb_DecodeOption_AliasString) == 0); \
737  UPB_ASSERT(fastdecode_checktag(data, tagbytes)); \
738  \
739  dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr, \
740  sizeof(upb_StringView), card); \
741  \
742  again: \
743  if (card == CARD_r) { \
744  dst = fastdecode_resizearr(d, dst, &farr, sizeof(upb_StringView)); \
745  } \
746  \
747  size = (uint8_t)ptr[tagbytes]; \
748  ptr += tagbytes + 1; \
749  dst->size = size; \
750  \
751  buf = d->arena.head.ptr; \
752  arena_has = _upb_ArenaHas(&d->arena); \
753  common_has = UPB_MIN(arena_has, (d->end - ptr) + 16); \
754  \
755  if (UPB_LIKELY(size <= 15 - tagbytes)) { \
756  if (arena_has < 16) goto longstr; \
757  d->arena.head.ptr += 16; \
758  memcpy(buf, ptr - tagbytes - 1, 16); \
759  dst->data = buf + tagbytes + 1; \
760  } else if (UPB_LIKELY(size <= 32)) { \
761  if (UPB_UNLIKELY(common_has < 32)) goto longstr; \
762  fastdecode_docopy(d, ptr, size, 32, buf, dst); \
763  } else if (UPB_LIKELY(size <= 64)) { \
764  if (UPB_UNLIKELY(common_has < 64)) goto longstr; \
765  fastdecode_docopy(d, ptr, size, 64, buf, dst); \
766  } else if (UPB_LIKELY(size < 128)) { \
767  if (UPB_UNLIKELY(common_has < 128)) goto longstr; \
768  fastdecode_docopy(d, ptr, size, 128, buf, dst); \
769  } else { \
770  goto longstr; \
771  } \
772  \
773  ptr += size; \
774  \
775  if (card == CARD_r) { \
776  if (validate_utf8 && !decode_verifyutf8_inl(dst->data, dst->size)) { \
777  return fastdecode_err(d, kUpb_DecodeStatus_BadUtf8); \
778  } \
779  fastdecode_nextret ret = fastdecode_nextrepeated( \
780  d, dst, &ptr, &farr, data, tagbytes, sizeof(upb_StringView)); \
781  switch (ret.next) { \
782  case FD_NEXT_SAMEFIELD: \
783  dst = ret.dst; \
784  goto again; \
785  case FD_NEXT_OTHERFIELD: \
786  data = ret.tag; \
787  UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \
788  case FD_NEXT_ATLIMIT: \
789  return ptr; \
790  } \
791  } \
792  \
793  if (card != CARD_r && validate_utf8) { \
794  data = (uint64_t)dst; \
795  UPB_MUSTTAIL return fastdecode_verifyutf8(UPB_PARSE_ARGS); \
796  } \
797  \
798  UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS); \
799  \
800  longstr: \
801  if (card == CARD_r) { \
802  fastdecode_commitarr(dst + 1, &farr, sizeof(upb_StringView)); \
803  } \
804  ptr--; \
805  if (validate_utf8) { \
806  UPB_MUSTTAIL return fastdecode_longstring_utf8(d, ptr, msg, table, \
807  hasbits, (uint64_t)dst); \
808  } else { \
809  UPB_MUSTTAIL return fastdecode_longstring_noutf8(d, ptr, msg, table, \
810  hasbits, (uint64_t)dst); \
811  }
812 
813 #define FASTDECODE_STRING(d, ptr, msg, table, hasbits, data, tagbytes, card, \
814  copyfunc, validate_utf8) \
815  upb_StringView* dst; \
816  fastdecode_arr farr; \
817  int64_t size; \
818  \
819  if (UPB_UNLIKELY(!fastdecode_checktag(data, tagbytes))) { \
820  RETURN_GENERIC("string field tag mismatch\n"); \
821  } \
822  \
823  if (UPB_UNLIKELY((d->options & kUpb_DecodeOption_AliasString) == 0)) { \
824  UPB_MUSTTAIL return copyfunc(UPB_PARSE_ARGS); \
825  } \
826  \
827  dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr, \
828  sizeof(upb_StringView), card); \
829  \
830  again: \
831  if (card == CARD_r) { \
832  dst = fastdecode_resizearr(d, dst, &farr, sizeof(upb_StringView)); \
833  } \
834  \
835  size = (int8_t)ptr[tagbytes]; \
836  ptr += tagbytes + 1; \
837  dst->data = ptr; \
838  dst->size = size; \
839  \
840  if (UPB_UNLIKELY(fastdecode_boundscheck(ptr, size, d->end))) { \
841  ptr--; \
842  if (validate_utf8) { \
843  return fastdecode_longstring_utf8(d, ptr, msg, table, hasbits, \
844  (uint64_t)dst); \
845  } else { \
846  return fastdecode_longstring_noutf8(d, ptr, msg, table, hasbits, \
847  (uint64_t)dst); \
848  } \
849  } \
850  \
851  ptr += size; \
852  \
853  if (card == CARD_r) { \
854  if (validate_utf8 && !decode_verifyutf8_inl(dst->data, dst->size)) { \
855  return fastdecode_err(d, kUpb_DecodeStatus_BadUtf8); \
856  } \
857  fastdecode_nextret ret = fastdecode_nextrepeated( \
858  d, dst, &ptr, &farr, data, tagbytes, sizeof(upb_StringView)); \
859  switch (ret.next) { \
860  case FD_NEXT_SAMEFIELD: \
861  dst = ret.dst; \
862  if (UPB_UNLIKELY((d->options & kUpb_DecodeOption_AliasString) == 0)) { \
863  /* Buffer flipped and we can't alias any more. Bounce to */ \
864  /* copyfunc(), but via dispatch since we need to reload table */ \
865  /* data also. */ \
866  fastdecode_commitarr(dst, &farr, sizeof(upb_StringView)); \
867  data = ret.tag; \
868  UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \
869  } \
870  goto again; \
871  case FD_NEXT_OTHERFIELD: \
872  data = ret.tag; \
873  UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \
874  case FD_NEXT_ATLIMIT: \
875  return ptr; \
876  } \
877  } \
878  \
879  if (card != CARD_r && validate_utf8) { \
880  data = (uint64_t)dst; \
881  UPB_MUSTTAIL return fastdecode_verifyutf8(UPB_PARSE_ARGS); \
882  } \
883  \
884  UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS);
885 
886 /* Generate all combinations:
887  * {p,c} x {s,o,r} x {s, b} x {1bt,2bt} */
888 
889 #define s_VALIDATE true
890 #define b_VALIDATE false
891 
892 #define F(card, tagbytes, type) \
893  UPB_NOINLINE \
894  const char* upb_c##card##type##_##tagbytes##bt(UPB_PARSE_PARAMS) { \
895  FASTDECODE_COPYSTRING(d, ptr, msg, table, hasbits, data, tagbytes, \
896  CARD_##card, type##_VALIDATE); \
897  } \
898  const char* upb_p##card##type##_##tagbytes##bt(UPB_PARSE_PARAMS) { \
899  FASTDECODE_STRING(d, ptr, msg, table, hasbits, data, tagbytes, \
900  CARD_##card, upb_c##card##type##_##tagbytes##bt, \
901  type##_VALIDATE); \
902  }
903 
904 #define UTF8(card, tagbytes) \
905  F(card, tagbytes, s) \
906  F(card, tagbytes, b)
907 
908 #define TAGBYTES(card) \
909  UTF8(card, 1) \
910  UTF8(card, 2)
911 
912 TAGBYTES(s)
913 TAGBYTES(o)
914 TAGBYTES(r)
915 
916 #undef s_VALIDATE
917 #undef b_VALIDATE
918 #undef F
919 #undef TAGBYTES
920 #undef FASTDECODE_LONGSTRING
921 #undef FASTDECODE_COPYSTRING
922 #undef FASTDECODE_STRING
923 
924 /* message fields *************************************************************/
925 
927 upb_Message* decode_newmsg_ceil(upb_Decoder* d, const upb_MiniTable* l,
928  int msg_ceil_bytes) {
929  size_t size = l->size + sizeof(upb_Message_Internal);
930  char* msg_data;
931  if (UPB_LIKELY(msg_ceil_bytes > 0 &&
932  _upb_ArenaHas(&d->arena) >= msg_ceil_bytes)) {
933  UPB_ASSERT(size <= (size_t)msg_ceil_bytes);
934  msg_data = d->arena.head.ptr;
935  d->arena.head.ptr += size;
936  UPB_UNPOISON_MEMORY_REGION(msg_data, msg_ceil_bytes);
937  memset(msg_data, 0, msg_ceil_bytes);
938  UPB_POISON_MEMORY_REGION(msg_data + size, msg_ceil_bytes - size);
939  } else {
940  msg_data = (char*)upb_Arena_Malloc(&d->arena, size);
941  memset(msg_data, 0, size);
942  }
943  return msg_data + sizeof(upb_Message_Internal);
944 }
945 
946 typedef struct {
947  intptr_t table;
948  upb_Message* msg;
949 } fastdecode_submsgdata;
950 
952 static const char* fastdecode_tosubmsg(upb_Decoder* d, const char* ptr,
953  void* ctx) {
954  fastdecode_submsgdata* submsg = ctx;
955  ptr = fastdecode_dispatch(d, ptr, submsg->msg, submsg->table, 0, 0);
956  UPB_ASSUME(ptr != NULL);
957  return ptr;
958 }
959 
960 #define FASTDECODE_SUBMSG(d, ptr, msg, table, hasbits, data, tagbytes, \
961  msg_ceil_bytes, card) \
962  \
963  if (UPB_UNLIKELY(!fastdecode_checktag(data, tagbytes))) { \
964  RETURN_GENERIC("submessage field tag mismatch\n"); \
965  } \
966  \
967  if (--d->depth == 0) { \
968  return fastdecode_err(d, kUpb_DecodeStatus_MaxDepthExceeded); \
969  } \
970  \
971  upb_Message** dst; \
972  uint32_t submsg_idx = (data >> 16) & 0xff; \
973  const upb_MiniTable* tablep = decode_totablep(table); \
974  const upb_MiniTable* subtablep = tablep->subs[submsg_idx].submsg; \
975  fastdecode_submsgdata submsg = {decode_totable(subtablep)}; \
976  fastdecode_arr farr; \
977  \
978  if (subtablep->table_mask == (uint8_t)-1) { \
979  RETURN_GENERIC("submessage doesn't have fast tables."); \
980  } \
981  \
982  dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr, \
983  sizeof(upb_Message*), card); \
984  \
985  if (card == CARD_s) { \
986  *(uint32_t*)msg |= hasbits; \
987  hasbits = 0; \
988  } \
989  \
990  again: \
991  if (card == CARD_r) { \
992  dst = fastdecode_resizearr(d, dst, &farr, sizeof(upb_Message*)); \
993  } \
994  \
995  submsg.msg = *dst; \
996  \
997  if (card == CARD_r || UPB_LIKELY(!submsg.msg)) { \
998  *dst = submsg.msg = decode_newmsg_ceil(d, subtablep, msg_ceil_bytes); \
999  } \
1000  \
1001  ptr += tagbytes; \
1002  ptr = fastdecode_delimited(d, ptr, fastdecode_tosubmsg, &submsg); \
1003  \
1004  if (UPB_UNLIKELY(ptr == NULL || d->end_group != DECODE_NOGROUP)) { \
1005  return fastdecode_err(d, kUpb_DecodeStatus_Malformed); \
1006  } \
1007  \
1008  if (card == CARD_r) { \
1009  fastdecode_nextret ret = fastdecode_nextrepeated( \
1010  d, dst, &ptr, &farr, data, tagbytes, sizeof(upb_Message*)); \
1011  switch (ret.next) { \
1012  case FD_NEXT_SAMEFIELD: \
1013  dst = ret.dst; \
1014  goto again; \
1015  case FD_NEXT_OTHERFIELD: \
1016  d->depth++; \
1017  data = ret.tag; \
1018  UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \
1019  case FD_NEXT_ATLIMIT: \
1020  d->depth++; \
1021  return ptr; \
1022  } \
1023  } \
1024  \
1025  d->depth++; \
1026  UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS);
1027 
1028 #define F(card, tagbytes, size_ceil, ceil_arg) \
1029  const char* upb_p##card##m_##tagbytes##bt_max##size_ceil##b( \
1030  UPB_PARSE_PARAMS) { \
1031  FASTDECODE_SUBMSG(d, ptr, msg, table, hasbits, data, tagbytes, ceil_arg, \
1032  CARD_##card); \
1033  }
1034 
1035 #define SIZES(card, tagbytes) \
1036  F(card, tagbytes, 64, 64) \
1037  F(card, tagbytes, 128, 128) \
1038  F(card, tagbytes, 192, 192) \
1039  F(card, tagbytes, 256, 256) \
1040  F(card, tagbytes, max, -1)
1041 
1042 #define TAGBYTES(card) \
1043  SIZES(card, 1) \
1044  SIZES(card, 2)
1045 
1046 TAGBYTES(s)
1047 TAGBYTES(o)
1048 TAGBYTES(r)
1049 
1050 #undef TAGBYTES
1051 #undef SIZES
1052 #undef F
1053 #undef FASTDECODE_SUBMSG
1054 
1055 #endif /* UPB_FASTTABLE */
ptr
char * ptr
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:45
dst
static const char dst[]
Definition: test-fs-copyfile.c:37
upb_Arena_Realloc
UPB_INLINE void * upb_Arena_Realloc(upb_Arena *a, void *ptr, size_t oldsize, size_t size)
Definition: upb/upb/upb.h:246
ctx
Definition: benchmark-async.c:30
decode_internal.h
memset
return memset(p, 0, total)
_upb_array_tagptr
UPB_INLINE uintptr_t _upb_array_tagptr(void *ptr, int elem_size_lg2)
Definition: php-upb.h:1345
_upb_ArenaHas
UPB_INLINE size_t _upb_ArenaHas(upb_Arena *a)
Definition: upb/upb/upb.h:194
upb_Decoder
Definition: decode_internal.h:48
begin
char * begin
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1007
UPB_UNLIKELY
#define UPB_UNLIKELY(x)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:62
uint16_t
unsigned short uint16_t
Definition: stdint-msvc2008.h:79
decode_poplimit
UPB_INLINE void decode_poplimit(upb_decstate *d, const char *ptr, int saved_delta)
Definition: php-upb.h:1908
kUpb_DecodeStatus_BadUtf8
@ kUpb_DecodeStatus_BadUtf8
Definition: decode.h:75
copy
static int copy(grpc_slice_buffer *input, grpc_slice_buffer *output)
Definition: message_compress.cc:145
UPB_UNREACHABLE
#define UPB_UNREACHABLE()
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:145
binary_size.new_size
def new_size
Definition: binary_size.py:124
status
absl::Status status
Definition: rls.cc:251
upb_MiniTable
Definition: msg_internal.h:185
ctx
static struct test_ctx ctx
Definition: test-ipc-send-recv.c:65
xds_manager.p
p
Definition: xds_manager.py:60
decode_totablep
const UPB_INLINE upb_msglayout * decode_totablep(intptr_t table)
Definition: php-upb.h:1824
UPB_PTR_AT
#define UPB_PTR_AT(msg, ofs, type)
Definition: php-upb.c:71
uint8_t
unsigned char uint8_t
Definition: stdint-msvc2008.h:78
o
UnboundConversion o
Definition: third_party/abseil-cpp/absl/strings/internal/str_format/parser_test.cc:97
UPB_MIN
#define UPB_MIN(x, y)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:126
uint32_t
unsigned int uint32_t
Definition: stdint-msvc2008.h:80
upb_Message_Internal
Definition: msg_internal.h:275
_upb_array_ptr
UPB_INLINE void * _upb_array_ptr(upb_array *arr)
Definition: php-upb.h:1350
memcpy
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
end
char * end
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1008
int64_t
signed __int64 int64_t
Definition: stdint-msvc2008.h:89
tag
static void * tag(intptr_t t)
Definition: bad_client.cc:318
UPB_ASSUME
#define UPB_ASSUME(expr)
Definition: php-upb.c:141
decode_checkrequired
const UPB_NOINLINE char * decode_checkrequired(upb_Decoder *d, const char *ptr, const upb_Message *msg, const upb_MiniTable *l)
Definition: decode.c:715
decode_verifyutf8_inl
UPB_INLINE bool decode_verifyutf8_inl(const char *buf, int len)
Definition: php-upb.h:1798
upb_Array
Definition: msg_internal.h:424
upb_Arena_Malloc
UPB_INLINE void * upb_Arena_Malloc(upb_Arena *a, size_t size)
Definition: upb/upb/upb.h:222
UPB_INLINE
#define UPB_INLINE
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:53
uint64_t
unsigned __int64 uint64_t
Definition: stdint-msvc2008.h:90
done
struct tab * done
Definition: bloaty/third_party/zlib/examples/enough.c:176
fastdecode_loadtag
UPB_INLINE uint32_t fastdecode_loadtag(const char *ptr)
Definition: php-upb.h:1888
fastdecode_err
const char * fastdecode_err(upb_decstate *d)
Definition: php-upb.c:412
intptr_t
_W64 signed int intptr_t
Definition: stdint-msvc2008.h:118
UPB_ASSERT
#define UPB_ASSERT(expr)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:135
data
char data[kBufferLength]
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1006
uintptr_t
_W64 unsigned int uintptr_t
Definition: stdint-msvc2008.h:119
d
static const fe d
Definition: curve25519_tables.h:19
upb_Message
void upb_Message
Definition: msg.h:49
n
int n
Definition: abseil-cpp/absl/container/btree_test.cc:1080
decode_fast.h
msg
std::string msg
Definition: client_interceptors_end2end_test.cc:372
TAGBYTES
#define TAGBYTES(card)
Definition: php-upb.h:2076
decode_isdonefallback_inl
const UPB_INLINE char * decode_isdonefallback_inl(upb_decstate *d, const char *ptr, int overrun)
Definition: php-upb.h:1829
func
const EVP_CIPHER *(* func)(void)
Definition: cipher_extra.c:73
upb_StringView
Definition: upb/upb/upb.h:72
UPB_LIKELY
#define UPB_LIKELY(x)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:61
ret
UniquePtr< SSL_SESSION > ret
Definition: ssl_x509.cc:1029
next
AllocList * next[kMaxLevel]
Definition: abseil-cpp/absl/base/internal/low_level_alloc.cc:100
fix_build_deps.r
r
Definition: fix_build_deps.py:491
_upb_Array_New
UPB_INLINE upb_Array * _upb_Array_New(upb_Arena *a, size_t init_size, int elem_size_lg2)
Definition: msg_internal.h:451
decode_isdone
UPB_INLINE bool decode_isdone(upb_decstate *d, const char **ptr)
Definition: php-upb.h:1859
UPB_PARSE_PARAMS
#define UPB_PARSE_PARAMS
Definition: php-upb.h:2012
table
uint8_t table[256]
Definition: hpack_parser.cc:456
int8_t
signed char int8_t
Definition: stdint-msvc2008.h:75
len
int len
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:46
decode_pushlimit
UPB_INLINE int decode_pushlimit(upb_decstate *d, const char *ptr, int size)
Definition: php-upb.h:1898
run_grpclb_interop_tests.l
dictionary l
Definition: run_grpclb_interop_tests.py:410
size
voidpf void uLong size
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
int32_t
signed int int32_t
Definition: stdint-msvc2008.h:77
UPB_FORCEINLINE
#define UPB_FORCEINLINE
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:77
UPB_NOINLINE
#define UPB_NOINLINE
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:78
binary_size.old_size
old_size
Definition: binary_size.py:125
UPB_UNPOISON_MEMORY_REGION
#define UPB_UNPOISON_MEMORY_REGION(addr, size)
Definition: php-upb.c:253
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
UPB_POISON_MEMORY_REGION
#define UPB_POISON_MEMORY_REGION(addr, size)
Definition: php-upb.c:251
UPB_MUSTTAIL
#define UPB_MUSTTAIL
Definition: php-upb.c:181


grpc
Author(s):
autogenerated on Thu Mar 13 2025 02:59:02