diff --git a/php/ext/google/protobuf/php-upb.c b/php/ext/google/protobuf/php-upb.c index d592b5d6a2..7a7a804638 100644 --- a/php/ext/google/protobuf/php-upb.c +++ b/php/ext/google/protobuf/php-upb.c @@ -12873,34 +12873,23 @@ static void _upb_Decoder_AddUnknownVarints(upb_Decoder* d, upb_Message* msg, } } -UPB_NOINLINE -static bool _upb_Decoder_CheckEnumSlow(upb_Decoder* d, const char* ptr, - upb_Message* msg, - const upb_MiniTableEnum* e, - const upb_MiniTableField* field, - uint32_t v) { - if (_upb_MiniTable_CheckEnumValueSlow(e, v)) return true; - - // Unrecognized enum goes into unknown fields. - // For packed fields the tag could be arbitrarily far in the past, so we - // just re-encode the tag and value here. - uint32_t tag = ((uint32_t)field->number << 3) | kUpb_WireType_Varint; - upb_Message* unknown_msg = - field->mode & kUpb_LabelFlags_IsExtension ? d->unknown_msg : msg; - _upb_Decoder_AddUnknownVarints(d, unknown_msg, tag, v); - return false; -} - UPB_FORCEINLINE static bool _upb_Decoder_CheckEnum(upb_Decoder* d, const char* ptr, upb_Message* msg, const upb_MiniTableEnum* e, const upb_MiniTableField* field, wireval* val) { - uint32_t v = val->uint32_val; + const uint32_t v = val->uint32_val; - _kUpb_FastEnumCheck_Status status = _upb_MiniTable_CheckEnumValueFast(e, v); - if (UPB_LIKELY(status == _kUpb_FastEnumCheck_ValueIsInEnum)) return true; - return _upb_Decoder_CheckEnumSlow(d, ptr, msg, e, field, v); + if (UPB_LIKELY(upb_MiniTableEnum_CheckValue(e, v))) return true; + + // Unrecognized enum goes into unknown fields. + // For packed fields the tag could be arbitrarily far in the past, + // so we just re-encode the tag and value here. + const uint32_t tag = ((uint32_t)field->number << 3) | kUpb_WireType_Varint; + upb_Message* unknown_msg = + field->mode & kUpb_LabelFlags_IsExtension ? d->unknown_msg : msg; + _upb_Decoder_AddUnknownVarints(d, unknown_msg, tag, v); + return false; } UPB_NOINLINE diff --git a/php/ext/google/protobuf/php-upb.h b/php/ext/google/protobuf/php-upb.h index a35625b89c..4d762828b2 100644 --- a/php/ext/google/protobuf/php-upb.h +++ b/php/ext/google/protobuf/php-upb.h @@ -918,6 +918,8 @@ UPB_API void* upb_Array_MutableDataPtr(upb_Array* arr); #ifndef UPB_MINI_TABLE_ENUM_H_ #define UPB_MINI_TABLE_ENUM_H_ +#include + #ifndef UPB_MINI_TABLE_INTERNAL_ENUM_H_ #define UPB_MINI_TABLE_INTERNAL_ENUM_H_ @@ -932,30 +934,26 @@ struct upb_MiniTableEnum { uint32_t data[]; // Bitmask + enumerated values follow. }; -typedef enum { - _kUpb_FastEnumCheck_ValueIsInEnum = 0, - _kUpb_FastEnumCheck_ValueIsNotInEnum = 1, - _kUpb_FastEnumCheck_CannotCheckFast = 2, -} _kUpb_FastEnumCheck_Status; - #ifdef __cplusplus extern "C" { #endif -UPB_INLINE _kUpb_FastEnumCheck_Status _upb_MiniTable_CheckEnumValueFast( +UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableEnum_CheckValue)( const struct upb_MiniTableEnum* e, uint32_t val) { - if (UPB_UNLIKELY(val >= 64)) return _kUpb_FastEnumCheck_CannotCheckFast; - uint64_t mask = e->data[0] | ((uint64_t)e->data[1] << 32); - return (mask & (1ULL << val)) ? _kUpb_FastEnumCheck_ValueIsInEnum - : _kUpb_FastEnumCheck_ValueIsNotInEnum; -} + if (UPB_LIKELY(val < 64)) { + const uint64_t mask = e->data[0] | ((uint64_t)e->data[1] << 32); + const uint64_t bit = 1ULL << val; + return (mask & bit) != 0; + } + if (UPB_LIKELY(val < e->mask_limit)) { + const uint32_t mask = e->data[val / 32]; + const uint32_t bit = 1ULL << (val % 32); + return (mask & bit) != 0; + } -UPB_INLINE bool _upb_MiniTable_CheckEnumValueSlow( - const struct upb_MiniTableEnum* e, uint32_t val) { - if (val < e->mask_limit) return e->data[val / 32] & (1ULL << (val % 32)); // OPT: binary search long lists? const uint32_t* start = &e->data[e->mask_limit / 32]; - const uint32_t* limit = &e->data[(e->mask_limit / 32) + e->value_count]; + const uint32_t* limit = &e->data[e->mask_limit / 32 + e->value_count]; for (const uint32_t* p = start; p < limit; p++) { if (*p == val) return true; } @@ -978,13 +976,9 @@ extern "C" { #endif // Validates enum value against range defined by enum mini table. -UPB_INLINE bool upb_MiniTableEnum_CheckValue(const struct upb_MiniTableEnum* e, +UPB_INLINE bool upb_MiniTableEnum_CheckValue(const upb_MiniTableEnum* e, uint32_t val) { - _kUpb_FastEnumCheck_Status status = _upb_MiniTable_CheckEnumValueFast(e, val); - if (UPB_UNLIKELY(status == _kUpb_FastEnumCheck_CannotCheckFast)) { - return _upb_MiniTable_CheckEnumValueSlow(e, val); - } - return status == _kUpb_FastEnumCheck_ValueIsInEnum ? true : false; + return UPB_PRIVATE(_upb_MiniTableEnum_CheckValue)(e, val); } #ifdef __cplusplus @@ -1120,8 +1114,6 @@ typedef enum { kUpb_ExtMode_IsMapEntry = 4, } upb_ExtMode; -union upb_MiniTableSub; - // upb_MiniTable represents the memory layout of a given upb_MessageDef. // The members are public so generated code can initialize them, // but users MUST NOT directly read or write any of its members. @@ -1170,15 +1162,18 @@ UPB_INLINE uint64_t upb_MiniTable_requiredmask(const struct upb_MiniTable* l) { #endif /* UPB_MINI_TABLE_INTERNAL_MESSAGE_H_ */ + #ifndef UPB_MINI_TABLE_INTERNAL_SUB_H_ #define UPB_MINI_TABLE_INTERNAL_SUB_H_ +// Must be last. union upb_MiniTableSub { const struct upb_MiniTable* submsg; const struct upb_MiniTableEnum* subenum; }; + #endif /* UPB_MINI_TABLE_INTERNAL_SUB_H_ */ // Must be last. @@ -3308,7 +3303,6 @@ upb_MiniTable* upb_MiniTable_BuildWithBuf(const char* data, size_t len, #ifndef UPB_MINI_TABLE_INTERNAL_FILE_H_ #define UPB_MINI_TABLE_INTERNAL_FILE_H_ - // Must be last. struct upb_MiniTableFile { diff --git a/ruby/ext/google/protobuf_c/ruby-upb.c b/ruby/ext/google/protobuf_c/ruby-upb.c index b4c0d08d15..bb52bcf6be 100644 --- a/ruby/ext/google/protobuf_c/ruby-upb.c +++ b/ruby/ext/google/protobuf_c/ruby-upb.c @@ -12388,34 +12388,23 @@ static void _upb_Decoder_AddUnknownVarints(upb_Decoder* d, upb_Message* msg, } } -UPB_NOINLINE -static bool _upb_Decoder_CheckEnumSlow(upb_Decoder* d, const char* ptr, - upb_Message* msg, - const upb_MiniTableEnum* e, - const upb_MiniTableField* field, - uint32_t v) { - if (_upb_MiniTable_CheckEnumValueSlow(e, v)) return true; - - // Unrecognized enum goes into unknown fields. - // For packed fields the tag could be arbitrarily far in the past, so we - // just re-encode the tag and value here. - uint32_t tag = ((uint32_t)field->number << 3) | kUpb_WireType_Varint; - upb_Message* unknown_msg = - field->mode & kUpb_LabelFlags_IsExtension ? d->unknown_msg : msg; - _upb_Decoder_AddUnknownVarints(d, unknown_msg, tag, v); - return false; -} - UPB_FORCEINLINE static bool _upb_Decoder_CheckEnum(upb_Decoder* d, const char* ptr, upb_Message* msg, const upb_MiniTableEnum* e, const upb_MiniTableField* field, wireval* val) { - uint32_t v = val->uint32_val; + const uint32_t v = val->uint32_val; - _kUpb_FastEnumCheck_Status status = _upb_MiniTable_CheckEnumValueFast(e, v); - if (UPB_LIKELY(status == _kUpb_FastEnumCheck_ValueIsInEnum)) return true; - return _upb_Decoder_CheckEnumSlow(d, ptr, msg, e, field, v); + if (UPB_LIKELY(upb_MiniTableEnum_CheckValue(e, v))) return true; + + // Unrecognized enum goes into unknown fields. + // For packed fields the tag could be arbitrarily far in the past, + // so we just re-encode the tag and value here. + const uint32_t tag = ((uint32_t)field->number << 3) | kUpb_WireType_Varint; + upb_Message* unknown_msg = + field->mode & kUpb_LabelFlags_IsExtension ? d->unknown_msg : msg; + _upb_Decoder_AddUnknownVarints(d, unknown_msg, tag, v); + return false; } UPB_NOINLINE diff --git a/ruby/ext/google/protobuf_c/ruby-upb.h b/ruby/ext/google/protobuf_c/ruby-upb.h index 192c105eb7..5714b9f6a1 100755 --- a/ruby/ext/google/protobuf_c/ruby-upb.h +++ b/ruby/ext/google/protobuf_c/ruby-upb.h @@ -920,6 +920,8 @@ UPB_API void* upb_Array_MutableDataPtr(upb_Array* arr); #ifndef UPB_MINI_TABLE_ENUM_H_ #define UPB_MINI_TABLE_ENUM_H_ +#include + #ifndef UPB_MINI_TABLE_INTERNAL_ENUM_H_ #define UPB_MINI_TABLE_INTERNAL_ENUM_H_ @@ -934,30 +936,26 @@ struct upb_MiniTableEnum { uint32_t data[]; // Bitmask + enumerated values follow. }; -typedef enum { - _kUpb_FastEnumCheck_ValueIsInEnum = 0, - _kUpb_FastEnumCheck_ValueIsNotInEnum = 1, - _kUpb_FastEnumCheck_CannotCheckFast = 2, -} _kUpb_FastEnumCheck_Status; - #ifdef __cplusplus extern "C" { #endif -UPB_INLINE _kUpb_FastEnumCheck_Status _upb_MiniTable_CheckEnumValueFast( +UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableEnum_CheckValue)( const struct upb_MiniTableEnum* e, uint32_t val) { - if (UPB_UNLIKELY(val >= 64)) return _kUpb_FastEnumCheck_CannotCheckFast; - uint64_t mask = e->data[0] | ((uint64_t)e->data[1] << 32); - return (mask & (1ULL << val)) ? _kUpb_FastEnumCheck_ValueIsInEnum - : _kUpb_FastEnumCheck_ValueIsNotInEnum; -} + if (UPB_LIKELY(val < 64)) { + const uint64_t mask = e->data[0] | ((uint64_t)e->data[1] << 32); + const uint64_t bit = 1ULL << val; + return (mask & bit) != 0; + } + if (UPB_LIKELY(val < e->mask_limit)) { + const uint32_t mask = e->data[val / 32]; + const uint32_t bit = 1ULL << (val % 32); + return (mask & bit) != 0; + } -UPB_INLINE bool _upb_MiniTable_CheckEnumValueSlow( - const struct upb_MiniTableEnum* e, uint32_t val) { - if (val < e->mask_limit) return e->data[val / 32] & (1ULL << (val % 32)); // OPT: binary search long lists? const uint32_t* start = &e->data[e->mask_limit / 32]; - const uint32_t* limit = &e->data[(e->mask_limit / 32) + e->value_count]; + const uint32_t* limit = &e->data[e->mask_limit / 32 + e->value_count]; for (const uint32_t* p = start; p < limit; p++) { if (*p == val) return true; } @@ -980,13 +978,9 @@ extern "C" { #endif // Validates enum value against range defined by enum mini table. -UPB_INLINE bool upb_MiniTableEnum_CheckValue(const struct upb_MiniTableEnum* e, +UPB_INLINE bool upb_MiniTableEnum_CheckValue(const upb_MiniTableEnum* e, uint32_t val) { - _kUpb_FastEnumCheck_Status status = _upb_MiniTable_CheckEnumValueFast(e, val); - if (UPB_UNLIKELY(status == _kUpb_FastEnumCheck_CannotCheckFast)) { - return _upb_MiniTable_CheckEnumValueSlow(e, val); - } - return status == _kUpb_FastEnumCheck_ValueIsInEnum ? true : false; + return UPB_PRIVATE(_upb_MiniTableEnum_CheckValue)(e, val); } #ifdef __cplusplus @@ -1122,8 +1116,6 @@ typedef enum { kUpb_ExtMode_IsMapEntry = 4, } upb_ExtMode; -union upb_MiniTableSub; - // upb_MiniTable represents the memory layout of a given upb_MessageDef. // The members are public so generated code can initialize them, // but users MUST NOT directly read or write any of its members. @@ -1172,15 +1164,18 @@ UPB_INLINE uint64_t upb_MiniTable_requiredmask(const struct upb_MiniTable* l) { #endif /* UPB_MINI_TABLE_INTERNAL_MESSAGE_H_ */ + #ifndef UPB_MINI_TABLE_INTERNAL_SUB_H_ #define UPB_MINI_TABLE_INTERNAL_SUB_H_ +// Must be last. union upb_MiniTableSub { const struct upb_MiniTable* submsg; const struct upb_MiniTableEnum* subenum; }; + #endif /* UPB_MINI_TABLE_INTERNAL_SUB_H_ */ // Must be last. @@ -3310,7 +3305,6 @@ upb_MiniTable* upb_MiniTable_BuildWithBuf(const char* data, size_t len, #ifndef UPB_MINI_TABLE_INTERNAL_FILE_H_ #define UPB_MINI_TABLE_INTERNAL_FILE_H_ - // Must be last. struct upb_MiniTableFile {