Skip to content

Commit c9d4385

Browse files
Auto-generate files after cl/758304268
1 parent 1c088d8 commit c9d4385

File tree

4 files changed

+106
-166
lines changed

4 files changed

+106
-166
lines changed

php/ext/google/protobuf/php-upb.c

Lines changed: 8 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -6715,44 +6715,6 @@ const upb_MiniTableExtension* upb_ExtensionRegistry_Lookup(
67156715

67166716
// Must be last.
67176717

6718-
const upb_MiniTableField* upb_MiniTable_FindFieldByNumber(
6719-
const upb_MiniTable* m, uint32_t number) {
6720-
const size_t i = ((size_t)number) - 1; // 0 wraps to SIZE_MAX
6721-
6722-
// Ideal case: index into dense fields
6723-
if (i < m->UPB_PRIVATE(dense_below)) {
6724-
UPB_ASSERT(m->UPB_PRIVATE(fields)[i].UPB_PRIVATE(number) == number);
6725-
return &m->UPB_PRIVATE(fields)[i];
6726-
}
6727-
6728-
// Slow case: binary search
6729-
uint32_t lo = m->UPB_PRIVATE(dense_below);
6730-
int32_t hi = m->UPB_PRIVATE(field_count) - 1;
6731-
const upb_MiniTableField* base = m->UPB_PRIVATE(fields);
6732-
while (hi >= (int32_t)lo) {
6733-
uint32_t mid = (hi + lo) / 2;
6734-
uint32_t num = base[mid].UPB_ONLYBITS(number);
6735-
// These comparison operations allow, on ARM machines, to fuse all these
6736-
// branches into one comparison followed by two CSELs to set the lo/hi
6737-
// values, followed by a BNE to continue or terminate the loop. Since binary
6738-
// search branches are generally unpredictable (50/50 in each direction),
6739-
// this is a good deal. We use signed for the high, as this decrement may
6740-
// underflow if mid is 0.
6741-
int32_t hi_mid = mid - 1;
6742-
uint32_t lo_mid = mid + 1;
6743-
if (num == number) {
6744-
return &base[mid];
6745-
}
6746-
if (UPB_UNPREDICTABLE(num < number)) {
6747-
lo = lo_mid;
6748-
} else {
6749-
hi = hi_mid;
6750-
}
6751-
}
6752-
6753-
return NULL;
6754-
}
6755-
67566718
const upb_MiniTableField* upb_MiniTable_GetOneof(const upb_MiniTable* m,
67576719
const upb_MiniTableField* f) {
67586720
if (UPB_UNLIKELY(!upb_MiniTableField_IsInOneof(f))) {
@@ -7809,55 +7771,22 @@ UPB_NOINLINE const upb_MiniTableField* _upb_Decoder_FindExtensionField(
78097771
return &upb_Decoder_FieldNotFoundField;
78107772
}
78117773

7812-
static const upb_MiniTableField* _upb_Decoder_FindField(
7813-
upb_Decoder* d, const upb_MiniTable* t, uint32_t field_number,
7814-
uint32_t* last_field_index, int wire_type) {
7774+
static const upb_MiniTableField* _upb_Decoder_FindField(upb_Decoder* d,
7775+
const upb_MiniTable* t,
7776+
uint32_t field_number,
7777+
int wire_type) {
78157778
if (t == NULL) return &upb_Decoder_FieldNotFoundField;
78167779

7817-
uint32_t idx = ((uint32_t)field_number) - 1; // 0 wraps to UINT32_MAX
7818-
if (idx < t->UPB_PRIVATE(dense_below)) {
7819-
// Fastest case: index into dense fields, and don't update last_field_index.
7820-
return &t->UPB_PRIVATE(fields)[idx];
7821-
}
7822-
7823-
uint32_t field_count = t->UPB_PRIVATE(field_count);
7824-
if (t->UPB_PRIVATE(dense_below) < field_count) {
7825-
// Linear search non-dense fields. Resume scanning from last_field_index
7826-
// since fields are usually in order.
7827-
idx = *last_field_index;
7828-
uint32_t candidate;
7829-
do {
7830-
candidate = t->UPB_PRIVATE(fields)[idx].UPB_PRIVATE(number);
7831-
if (candidate == field_number) {
7832-
goto found;
7833-
}
7834-
} while (++idx < field_count);
7835-
7836-
if (UPB_LIKELY(field_number > candidate)) {
7837-
// The field number we encountered is larger than any of our known fields,
7838-
// so it's likely that subsequent ones will be too.
7839-
*last_field_index = idx - 1;
7840-
} else {
7841-
// Fields not in tag order - scan from beginning
7842-
for (idx = t->UPB_PRIVATE(dense_below); idx < *last_field_index; idx++) {
7843-
if (t->UPB_PRIVATE(fields)[idx].UPB_PRIVATE(number) == field_number) {
7844-
goto found;
7845-
}
7846-
}
7847-
}
7848-
}
7780+
const upb_MiniTableField* field =
7781+
upb_MiniTable_FindFieldByNumber(t, field_number);
7782+
if (field) return field;
78497783

78507784
if (d->extreg && t->UPB_PRIVATE(ext)) {
78517785
return _upb_Decoder_FindExtensionField(d, t, field_number,
78527786
t->UPB_PRIVATE(ext), wire_type);
78537787
}
78547788

78557789
return &upb_Decoder_FieldNotFoundField; // Unknown field.
7856-
7857-
found:
7858-
UPB_ASSERT(t->UPB_PRIVATE(fields)[idx].UPB_PRIVATE(number) == field_number);
7859-
*last_field_index = idx;
7860-
return &t->UPB_PRIVATE(fields)[idx];
78617790
}
78627791

78637792
static int _upb_Decoder_GetVarintOp(const upb_MiniTableField* field) {
@@ -8162,8 +8091,6 @@ UPB_NOINLINE
81628091
const char* _upb_Decoder_DecodeMessage(upb_Decoder* d, const char* ptr,
81638092
upb_Message* msg,
81648093
const upb_MiniTable* layout) {
8165-
uint32_t last_field_index = 0;
8166-
81678094
#if UPB_FASTTABLE
81688095
// The first time we want to skip fast dispatch, because we may have just been
81698096
// invoked by the fast parser to handle a case that it bailed on.
@@ -8202,8 +8129,7 @@ const char* _upb_Decoder_DecodeMessage(upb_Decoder* d, const char* ptr,
82028129
return ptr;
82038130
}
82048131

8205-
field = _upb_Decoder_FindField(d, layout, field_number, &last_field_index,
8206-
wire_type);
8132+
field = _upb_Decoder_FindField(d, layout, field_number, wire_type);
82078133
ptr = _upb_Decoder_DecodeWireValue(d, ptr, layout, field, wire_type, &val,
82088134
&op);
82098135

php/ext/google/protobuf/php-upb.h

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2479,6 +2479,50 @@ UPB_API_INLINE bool upb_MiniTable_IsMessageSet(const struct upb_MiniTable* m) {
24792479
return m->UPB_PRIVATE(ext) == kUpb_ExtMode_IsMessageSet;
24802480
}
24812481

2482+
UPB_API_INLINE
2483+
const struct upb_MiniTableField* upb_MiniTable_FindFieldByNumber(
2484+
const struct upb_MiniTable* m, uint32_t number) {
2485+
const size_t i = ((size_t)number) - 1; // 0 wraps to SIZE_MAX
2486+
2487+
// Ideal case: index into dense fields
2488+
if (i < m->UPB_PRIVATE(dense_below)) {
2489+
UPB_ASSERT(m->UPB_ONLYBITS(fields)[i].UPB_ONLYBITS(number) == number);
2490+
return &m->UPB_ONLYBITS(fields)[i];
2491+
}
2492+
2493+
// Early exit if the field number is out of range.
2494+
int32_t hi = m->UPB_ONLYBITS(field_count) - 1;
2495+
if (hi < 0 || number > m->UPB_ONLYBITS(fields)[hi].UPB_ONLYBITS(number)) {
2496+
return NULL;
2497+
}
2498+
2499+
// Slow case: binary search
2500+
uint32_t lo = m->UPB_PRIVATE(dense_below);
2501+
const struct upb_MiniTableField* base = m->UPB_ONLYBITS(fields);
2502+
while (hi >= (int32_t)lo) {
2503+
uint32_t mid = (hi + lo) / 2;
2504+
uint32_t num = base[mid].UPB_ONLYBITS(number);
2505+
// These comparison operations allow, on ARM machines, to fuse all these
2506+
// branches into one comparison followed by two CSELs to set the lo/hi
2507+
// values, followed by a BNE to continue or terminate the loop. Since binary
2508+
// search branches are generally unpredictable (50/50 in each direction),
2509+
// this is a good deal. We use signed for the high, as this decrement may
2510+
// underflow if mid is 0.
2511+
int32_t hi_mid = mid - 1;
2512+
uint32_t lo_mid = mid + 1;
2513+
if (num == number) {
2514+
return &base[mid];
2515+
}
2516+
if (UPB_UNPREDICTABLE(num < number)) {
2517+
lo = lo_mid;
2518+
} else {
2519+
hi = hi_mid;
2520+
}
2521+
}
2522+
2523+
return NULL;
2524+
}
2525+
24822526
UPB_INLINE bool UPB_PRIVATE(_upb_MiniTable_IsEmpty)(
24832527
const struct upb_MiniTable* m) {
24842528
extern const struct upb_MiniTable UPB_PRIVATE(_kUpb_MiniTable_Empty);
@@ -2590,7 +2634,7 @@ typedef struct upb_MiniTable upb_MiniTable;
25902634
extern "C" {
25912635
#endif
25922636

2593-
UPB_API const upb_MiniTableField* upb_MiniTable_FindFieldByNumber(
2637+
UPB_API_INLINE const upb_MiniTableField* upb_MiniTable_FindFieldByNumber(
25942638
const upb_MiniTable* m, uint32_t number);
25952639

25962640
UPB_API_INLINE const upb_MiniTableField* upb_MiniTable_GetFieldByIndex(

ruby/ext/google/protobuf_c/ruby-upb.c

Lines changed: 8 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -6715,44 +6715,6 @@ const upb_MiniTableExtension* upb_ExtensionRegistry_Lookup(
67156715

67166716
// Must be last.
67176717

6718-
const upb_MiniTableField* upb_MiniTable_FindFieldByNumber(
6719-
const upb_MiniTable* m, uint32_t number) {
6720-
const size_t i = ((size_t)number) - 1; // 0 wraps to SIZE_MAX
6721-
6722-
// Ideal case: index into dense fields
6723-
if (i < m->UPB_PRIVATE(dense_below)) {
6724-
UPB_ASSERT(m->UPB_PRIVATE(fields)[i].UPB_PRIVATE(number) == number);
6725-
return &m->UPB_PRIVATE(fields)[i];
6726-
}
6727-
6728-
// Slow case: binary search
6729-
uint32_t lo = m->UPB_PRIVATE(dense_below);
6730-
int32_t hi = m->UPB_PRIVATE(field_count) - 1;
6731-
const upb_MiniTableField* base = m->UPB_PRIVATE(fields);
6732-
while (hi >= (int32_t)lo) {
6733-
uint32_t mid = (hi + lo) / 2;
6734-
uint32_t num = base[mid].UPB_ONLYBITS(number);
6735-
// These comparison operations allow, on ARM machines, to fuse all these
6736-
// branches into one comparison followed by two CSELs to set the lo/hi
6737-
// values, followed by a BNE to continue or terminate the loop. Since binary
6738-
// search branches are generally unpredictable (50/50 in each direction),
6739-
// this is a good deal. We use signed for the high, as this decrement may
6740-
// underflow if mid is 0.
6741-
int32_t hi_mid = mid - 1;
6742-
uint32_t lo_mid = mid + 1;
6743-
if (num == number) {
6744-
return &base[mid];
6745-
}
6746-
if (UPB_UNPREDICTABLE(num < number)) {
6747-
lo = lo_mid;
6748-
} else {
6749-
hi = hi_mid;
6750-
}
6751-
}
6752-
6753-
return NULL;
6754-
}
6755-
67566718
const upb_MiniTableField* upb_MiniTable_GetOneof(const upb_MiniTable* m,
67576719
const upb_MiniTableField* f) {
67586720
if (UPB_UNLIKELY(!upb_MiniTableField_IsInOneof(f))) {
@@ -7809,55 +7771,22 @@ UPB_NOINLINE const upb_MiniTableField* _upb_Decoder_FindExtensionField(
78097771
return &upb_Decoder_FieldNotFoundField;
78107772
}
78117773

7812-
static const upb_MiniTableField* _upb_Decoder_FindField(
7813-
upb_Decoder* d, const upb_MiniTable* t, uint32_t field_number,
7814-
uint32_t* last_field_index, int wire_type) {
7774+
static const upb_MiniTableField* _upb_Decoder_FindField(upb_Decoder* d,
7775+
const upb_MiniTable* t,
7776+
uint32_t field_number,
7777+
int wire_type) {
78157778
if (t == NULL) return &upb_Decoder_FieldNotFoundField;
78167779

7817-
uint32_t idx = ((uint32_t)field_number) - 1; // 0 wraps to UINT32_MAX
7818-
if (idx < t->UPB_PRIVATE(dense_below)) {
7819-
// Fastest case: index into dense fields, and don't update last_field_index.
7820-
return &t->UPB_PRIVATE(fields)[idx];
7821-
}
7822-
7823-
uint32_t field_count = t->UPB_PRIVATE(field_count);
7824-
if (t->UPB_PRIVATE(dense_below) < field_count) {
7825-
// Linear search non-dense fields. Resume scanning from last_field_index
7826-
// since fields are usually in order.
7827-
idx = *last_field_index;
7828-
uint32_t candidate;
7829-
do {
7830-
candidate = t->UPB_PRIVATE(fields)[idx].UPB_PRIVATE(number);
7831-
if (candidate == field_number) {
7832-
goto found;
7833-
}
7834-
} while (++idx < field_count);
7835-
7836-
if (UPB_LIKELY(field_number > candidate)) {
7837-
// The field number we encountered is larger than any of our known fields,
7838-
// so it's likely that subsequent ones will be too.
7839-
*last_field_index = idx - 1;
7840-
} else {
7841-
// Fields not in tag order - scan from beginning
7842-
for (idx = t->UPB_PRIVATE(dense_below); idx < *last_field_index; idx++) {
7843-
if (t->UPB_PRIVATE(fields)[idx].UPB_PRIVATE(number) == field_number) {
7844-
goto found;
7845-
}
7846-
}
7847-
}
7848-
}
7780+
const upb_MiniTableField* field =
7781+
upb_MiniTable_FindFieldByNumber(t, field_number);
7782+
if (field) return field;
78497783

78507784
if (d->extreg && t->UPB_PRIVATE(ext)) {
78517785
return _upb_Decoder_FindExtensionField(d, t, field_number,
78527786
t->UPB_PRIVATE(ext), wire_type);
78537787
}
78547788

78557789
return &upb_Decoder_FieldNotFoundField; // Unknown field.
7856-
7857-
found:
7858-
UPB_ASSERT(t->UPB_PRIVATE(fields)[idx].UPB_PRIVATE(number) == field_number);
7859-
*last_field_index = idx;
7860-
return &t->UPB_PRIVATE(fields)[idx];
78617790
}
78627791

78637792
static int _upb_Decoder_GetVarintOp(const upb_MiniTableField* field) {
@@ -8162,8 +8091,6 @@ UPB_NOINLINE
81628091
const char* _upb_Decoder_DecodeMessage(upb_Decoder* d, const char* ptr,
81638092
upb_Message* msg,
81648093
const upb_MiniTable* layout) {
8165-
uint32_t last_field_index = 0;
8166-
81678094
#if UPB_FASTTABLE
81688095
// The first time we want to skip fast dispatch, because we may have just been
81698096
// invoked by the fast parser to handle a case that it bailed on.
@@ -8202,8 +8129,7 @@ const char* _upb_Decoder_DecodeMessage(upb_Decoder* d, const char* ptr,
82028129
return ptr;
82038130
}
82048131

8205-
field = _upb_Decoder_FindField(d, layout, field_number, &last_field_index,
8206-
wire_type);
8132+
field = _upb_Decoder_FindField(d, layout, field_number, wire_type);
82078133
ptr = _upb_Decoder_DecodeWireValue(d, ptr, layout, field, wire_type, &val,
82088134
&op);
82098135

ruby/ext/google/protobuf_c/ruby-upb.h

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2481,6 +2481,50 @@ UPB_API_INLINE bool upb_MiniTable_IsMessageSet(const struct upb_MiniTable* m) {
24812481
return m->UPB_PRIVATE(ext) == kUpb_ExtMode_IsMessageSet;
24822482
}
24832483

2484+
UPB_API_INLINE
2485+
const struct upb_MiniTableField* upb_MiniTable_FindFieldByNumber(
2486+
const struct upb_MiniTable* m, uint32_t number) {
2487+
const size_t i = ((size_t)number) - 1; // 0 wraps to SIZE_MAX
2488+
2489+
// Ideal case: index into dense fields
2490+
if (i < m->UPB_PRIVATE(dense_below)) {
2491+
UPB_ASSERT(m->UPB_ONLYBITS(fields)[i].UPB_ONLYBITS(number) == number);
2492+
return &m->UPB_ONLYBITS(fields)[i];
2493+
}
2494+
2495+
// Early exit if the field number is out of range.
2496+
int32_t hi = m->UPB_ONLYBITS(field_count) - 1;
2497+
if (hi < 0 || number > m->UPB_ONLYBITS(fields)[hi].UPB_ONLYBITS(number)) {
2498+
return NULL;
2499+
}
2500+
2501+
// Slow case: binary search
2502+
uint32_t lo = m->UPB_PRIVATE(dense_below);
2503+
const struct upb_MiniTableField* base = m->UPB_ONLYBITS(fields);
2504+
while (hi >= (int32_t)lo) {
2505+
uint32_t mid = (hi + lo) / 2;
2506+
uint32_t num = base[mid].UPB_ONLYBITS(number);
2507+
// These comparison operations allow, on ARM machines, to fuse all these
2508+
// branches into one comparison followed by two CSELs to set the lo/hi
2509+
// values, followed by a BNE to continue or terminate the loop. Since binary
2510+
// search branches are generally unpredictable (50/50 in each direction),
2511+
// this is a good deal. We use signed for the high, as this decrement may
2512+
// underflow if mid is 0.
2513+
int32_t hi_mid = mid - 1;
2514+
uint32_t lo_mid = mid + 1;
2515+
if (num == number) {
2516+
return &base[mid];
2517+
}
2518+
if (UPB_UNPREDICTABLE(num < number)) {
2519+
lo = lo_mid;
2520+
} else {
2521+
hi = hi_mid;
2522+
}
2523+
}
2524+
2525+
return NULL;
2526+
}
2527+
24842528
UPB_INLINE bool UPB_PRIVATE(_upb_MiniTable_IsEmpty)(
24852529
const struct upb_MiniTable* m) {
24862530
extern const struct upb_MiniTable UPB_PRIVATE(_kUpb_MiniTable_Empty);
@@ -2592,7 +2636,7 @@ typedef struct upb_MiniTable upb_MiniTable;
25922636
extern "C" {
25932637
#endif
25942638

2595-
UPB_API const upb_MiniTableField* upb_MiniTable_FindFieldByNumber(
2639+
UPB_API_INLINE const upb_MiniTableField* upb_MiniTable_FindFieldByNumber(
25962640
const upb_MiniTable* m, uint32_t number);
25972641

25982642
UPB_API_INLINE const upb_MiniTableField* upb_MiniTable_GetFieldByIndex(

0 commit comments

Comments
 (0)