Skip to content

Commit 26bb70c

Browse files
Extract EPS macro and use it in fast decoder
This allows eliding null checks on the hot path PiperOrigin-RevId: 919794585
1 parent 37b2497 commit 26bb70c

11 files changed

Lines changed: 33 additions & 42 deletions

File tree

upb/wire/decode.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -89,12 +89,6 @@ enum {
8989
#define OP_FIXPCK_LG2(n) (n + 5) /* n in [2, 3] => op in [7, 8] */
9090
#define OP_VARPCK_LG2(n) (n + 9) /* n in [0, 2, 3] => op in [9, 11, 12] */
9191

92-
static void _upb_Decoder_AssumeEpsHasErrorHandler(upb_Decoder* d) {
93-
UPB_ASSUME(upb_EpsCopyInputStream_HasErrorHandler(&d->input));
94-
}
95-
96-
#define EPS(d) (_upb_Decoder_AssumeEpsHasErrorHandler(d), &(d)->input)
97-
9892
static bool _upb_Decoder_Reserve(upb_Decoder* d, upb_Array* arr, size_t elem) {
9993
bool need_realloc =
10094
arr->UPB_PRIVATE(capacity) - arr->UPB_PRIVATE(size) < elem;

upb/wire/decode_fast/cardinality.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11

22
#include "upb/wire/decode_fast/cardinality.h"
33

4-
#include "upb/wire/eps_copy_input_stream.h"
54
#include "upb/wire/internal/decoder.h"
5+
#include "upb/wire/internal/eps_copy_input_stream.h"
66

77
UPB_PRESERVE_MOST
88
const char* upb_DecodeFast_IsDoneFallback(upb_Decoder* d, const char* ptr) {
99
int overrun;
1010
upb_IsDoneStatus status = UPB_PRIVATE(upb_EpsCopyInputStream_IsDoneStatus)(
1111
&d->input, ptr, &overrun);
1212
UPB_ASSERT(status == kUpb_IsDoneStatus_NeedFallback);
13-
return UPB_PRIVATE(upb_EpsCopyInputStream_IsDoneFallback)(&d->input, ptr,
13+
return UPB_PRIVATE(upb_EpsCopyInputStream_IsDoneFallback)(EPS(d), ptr,
1414
overrun);
1515
}

upb/wire/decode_fast/cardinality.h

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -470,12 +470,7 @@ bool upb_DecodeFast_Delimited(upb_Decoder* d, const char** ptr,
470470
ctx)) {
471471
if (UPB_UNLIKELY(p == NULL)) goto fail;
472472
} else {
473-
ptrdiff_t delta = upb_EpsCopyInputStream_PushLimit(&d->input, p, size);
474-
if (UPB_UNLIKELY(delta < 0)) {
475-
// Corrupt wire format: invalid limit.
476-
*ptr = NULL;
477-
return UPB_DECODEFAST_ERROR(d, kUpb_DecodeStatus_Malformed, ret);
478-
}
473+
ptrdiff_t delta = upb_EpsCopyInputStream_PushLimit(EPS(d), p, size);
479474
p = func(&d->input, p, size, ctx);
480475
if (UPB_UNLIKELY(p == NULL)) goto fail;
481476
upb_EpsCopyInputStream_PopLimit(&d->input, p, delta);

upb/wire/decode_fast/dispatch.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ upb_DecodeFast_MessageIsDoneFallback(UPB_PARSE_PARAMS) {
3434
}
3535
case kUpb_IsDoneStatus_NeedFallback:
3636
// We've reached end-of-buffer. Refresh the buffer.
37-
ptr = UPB_PRIVATE(upb_EpsCopyInputStream_IsDoneFallback)(&d->input, ptr,
37+
ptr = UPB_PRIVATE(upb_EpsCopyInputStream_IsDoneFallback)(EPS(d), ptr,
3838
overrun);
3939

4040
// We successfully refreshed the buffer (otherwise the function above

upb/wire/decode_fast/field_mismatch.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ UPB_PRESERVE_NONE upb_FastDecoder_Return _upb_FastDecoder_DecodeCheckMiniTable(
9898
uint32_t field_num = data;
9999
#ifndef NDEBUG
100100
uint32_t check;
101-
const char* read = upb_WireReader_ReadTag(ptr, &check, &d->input);
101+
const char* read = upb_WireReader_ReadTag(ptr, &check, EPS(d));
102102
UPB_PRIVATE(upb_EpsCopyInputStream_BoundsChecked)(&d->input);
103103
UPB_ASSERT(upb_WireReader_GetFieldNumber(check) == field_num);
104104
UPB_ASSERT(ptr + upb_DecodeFastData2_GetTagLen(data2) == read);
@@ -127,7 +127,7 @@ _upb_FastDecoder_DecodeCheckExtRegMiniTable(struct upb_Decoder* d,
127127
#ifndef NDEBUG
128128
UPB_PRIVATE(upb_EpsCopyInputStream_BoundsChecked)(&d->input);
129129
uint32_t check;
130-
const char* read = upb_WireReader_ReadTag(ptr, &check, &d->input);
130+
const char* read = upb_WireReader_ReadTag(ptr, &check, EPS(d));
131131

132132
UPB_ASSERT(upb_WireReader_GetFieldNumber(check) == field_num);
133133
UPB_ASSERT(ptr + upb_DecodeFastData2_GetTagLen(data2) == read);

upb/wire/decode_fast/field_string.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,12 @@ bool upb_DecodeFast_SingleStringAlias(upb_Decoder* d, const char** ptr,
3232

3333
if (!upb_DecodeFast_DecodeSize(d, ptr, &size, next)) return false;
3434

35-
const char* p = *ptr;
36-
if (!upb_EpsCopyInputStream_ReadStringAlwaysAlias(&d->input, p, size, sv)) {
37-
return UPB_DECODEFAST_EXIT(kUpb_DecodeFastNext_FallbackToMiniTable, next);
38-
}
35+
*ptr = upb_EpsCopyInputStream_ReadStringAlwaysAlias(EPS(d), *ptr, size, sv);
3936

4037
if (validate_utf8 && !utf8_range_IsValid(sv->data, sv->size)) {
4138
return UPB_DECODEFAST_ERROR(d, kUpb_DecodeStatus_BadUtf8, next);
4239
}
4340

44-
*ptr = p + size;
4541
return true;
4642
}
4743

upb/wire/decode_fast/field_unknown.c

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -125,10 +125,7 @@ UPB_FORCEINLINE bool _upb_FastDecoder_DoDecodeUnknown(
125125
while (true) {
126126
switch (wire_type) {
127127
case kUpb_WireType_Varint:
128-
*ptr = upb_WireReader_SkipVarint(*ptr, &d->input);
129-
if (UPB_UNLIKELY(!*ptr)) {
130-
return UPB_DECODEFAST_ERROR(d, kUpb_DecodeStatus_Malformed, ret);
131-
}
128+
*ptr = upb_WireReader_SkipVarint(*ptr, EPS(d));
132129
break;
133130
case kUpb_WireType_32Bit:
134131
UPB_PRIVATE(upb_EpsCopyInputStream_ConsumeBytes)(&d->input, 4);
@@ -140,9 +137,8 @@ UPB_FORCEINLINE bool _upb_FastDecoder_DoDecodeUnknown(
140137
break;
141138
case kUpb_WireType_Delimited: {
142139
int size;
143-
const char* p = upb_WireReader_ReadSize(*ptr, &size, &d->input);
144-
if (UPB_UNLIKELY(
145-
!p || !upb_EpsCopyInputStream_CheckSize(&d->input, p, size))) {
140+
const char* p = upb_WireReader_ReadSize(*ptr, &size, EPS(d));
141+
if (UPB_UNLIKELY(!upb_EpsCopyInputStream_CheckSize(EPS(d), p, size))) {
146142
return UPB_DECODEFAST_ERROR(d, kUpb_DecodeStatus_Malformed, ret);
147143
}
148144
*ptr = p + size;
@@ -205,9 +201,7 @@ UPB_FORCEINLINE bool _upb_FastDecoder_DoDecodeUnknown(
205201
}
206202

207203
upb_StringView sv;
208-
if (UPB_UNLIKELY(!upb_EpsCopyCapture_End(&capture, &d->input, *ptr, &sv))) {
209-
return UPB_DECODEFAST_ERROR(d, kUpb_DecodeStatus_Malformed, ret);
210-
}
204+
upb_EpsCopyCapture_End(&capture, EPS(d), *ptr, &sv);
211205

212206
bool handled_fast =
213207
// Check AddUnknown mode is AliasAllowMerge.

upb/wire/decode_fast/field_varint.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,7 @@ static bool upb_DecodeFast_SingleVarint(upb_Decoder* d, const char** ptr,
5252
const char* p = *ptr;
5353
uint64_t val;
5454

55-
p = upb_WireReader_ReadVarint(p, &val, &d->input);
56-
if (!p) {
57-
return UPB_DECODEFAST_ERROR(d, kUpb_DecodeStatus_Malformed, next);
58-
}
55+
p = upb_WireReader_ReadVarint(p, &val, EPS(d));
5956

6057
switch (type) {
6158
case kUpb_DecodeFast_Bool:

upb/wire/eps_copy_input_stream.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,10 @@
1616
// Must be last.
1717
#include "upb/port/def.inc"
1818

19-
const char* UPB_PRIVATE(upb_EpsCopyInputStream_ReturnError)(
20-
upb_EpsCopyInputStream* e) {
19+
UPB_NORETURN UPB_NOINLINE void UPB_PRIVATE(
20+
upb_EpsCopyInputStream_ThrowMalformed)(upb_EpsCopyInputStream* e) {
2121
e->error = true;
22-
if (e->err) upb_ErrorHandler_ThrowError(e->err, kUpb_ErrorCode_Malformed);
23-
return NULL;
22+
upb_ErrorHandler_ThrowError(e->err, kUpb_ErrorCode_Malformed);
2423
}
2524

2625
const char* UPB_PRIVATE(upb_EpsCopyInputStream_IsDoneFallback)(

upb/wire/internal/decoder.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,12 @@ typedef struct upb_Decoder {
6969
#endif
7070
} upb_Decoder;
7171

72+
UPB_INLINE void _upb_Decoder_AssumeEpsHasErrorHandler(upb_Decoder* d) {
73+
UPB_ASSUME(upb_EpsCopyInputStream_HasErrorHandler(&d->input));
74+
}
75+
76+
#define EPS(d) (_upb_Decoder_AssumeEpsHasErrorHandler(d), &(d)->input)
77+
7278
UPB_INLINE const char* upb_Decoder_Init(upb_Decoder* d, const char* buf,
7379
size_t size,
7480
const upb_ExtensionRegistry* extreg,

0 commit comments

Comments
 (0)