From 34b98bc030c69a061c294f4dc983bcde41a9a7a8 Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Tue, 22 Sep 2020 14:29:24 -0700 Subject: [PATCH] Avoid passing too many params to fallback. --- upb/decode_fast.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/upb/decode_fast.c b/upb/decode_fast.c index 070ae68e13..2b565a4da7 100644 --- a/upb/decode_fast.c +++ b/upb/decode_fast.c @@ -52,22 +52,23 @@ const char *upb_psf32_2bt(UPB_PARSE_PARAMS) { } UPB_FORCEINLINE -static const char *fastdecode_longvarint_impl(UPB_PARSE_PARAMS, int64_t res1, - int valbytes) { +static const char *fastdecode_longvarint_impl(UPB_PARSE_PARAMS, int valbytes) { char *field = (char *)data; // The algorithm relies on sign extension to set all high bits when the varint // continues. This way it can use "and" to aggregate in to the result. const int8_t *p = (const int8_t*)(ptr); + int64_t res1 = *p; + uint64_t ones = res1; // save the useful high bit 1's in res1 + uint64_t byte; + int64_t res2, res3; + int sign_bit; + // However this requires the low bits after shifting to be 1's as well. On // x86_64 a shld from a single register filled with enough 1's in the high // bits can accomplish all this in one instruction. It so happens that res1 // has 57 high bits of ones, which is enough for the largest shift done. assert(res1 >> 7 == -1); - uint64_t ones = res1; // save the useful high bit 1's in res1 - uint64_t byte; - int64_t res2, res3; - int sign_bit; #define SHLD(n) byte = ((byte << (n * 7)) | (ones >> (64 - (n * 7)))) @@ -155,22 +156,21 @@ done2 : { } UPB_NOINLINE -static const char *fastdecode_longvarint32(UPB_PARSE_PARAMS, int64_t val) { - return fastdecode_longvarint_impl(d, ptr, msg, table, hasbits, data, val, 4); +static const char *fastdecode_longvarint32(UPB_PARSE_PARAMS) { + return fastdecode_longvarint_impl(d, ptr, msg, table, hasbits, data, 4); } UPB_NOINLINE -static const char *fastdecode_longvarint64(UPB_PARSE_PARAMS, int64_t val) { - return fastdecode_longvarint_impl(d, ptr, msg, table, hasbits, data, val, 8); +static const char *fastdecode_longvarint64(UPB_PARSE_PARAMS) { + return fastdecode_longvarint_impl(d, ptr, msg, table, hasbits, data, 8); } UPB_FORCEINLINE -static const char *fastdecode_longvarint(UPB_PARSE_PARAMS, int64_t val, - int valbytes) { +static const char *fastdecode_longvarint(UPB_PARSE_PARAMS, int valbytes) { if (valbytes == 4) { - return fastdecode_longvarint32(d, ptr, msg, table, hasbits, data, val); + return fastdecode_longvarint32(d, ptr, msg, table, hasbits, data); } else if (valbytes == 8) { - return fastdecode_longvarint64(d, ptr, msg, table, hasbits, data, val); + return fastdecode_longvarint64(d, ptr, msg, table, hasbits, data); } UPB_UNREACHABLE(); } @@ -178,17 +178,17 @@ static const char *fastdecode_longvarint(UPB_PARSE_PARAMS, int64_t val, UPB_FORCEINLINE static const char *fastdecode_scalarvarint(UPB_PARSE_PARAMS, int tagbytes, int valbytes) { - int64_t val; + uint64_t val = 0; void *field; if (UPB_UNLIKELY(!fastdecode_checktag(data, tagbytes))) return ptr; ptr += tagbytes; hasbits |= data; field = (char*)msg + (data >> 48); - val = *ptr; - if (UPB_UNLIKELY(val < 0)) { + if (UPB_UNLIKELY(*ptr < 0)) { return fastdecode_longvarint(d, ptr, msg, table, hasbits, (uint64_t)field, - val, valbytes); + valbytes); } + val = *ptr; memcpy(field, &val, valbytes); return fastdecode_dispatch(d, ptr + 1, msg, table, hasbits); }