From 36f68e02d53c68d1bd4e4bd76c82a50e7b64f2a4 Mon Sep 17 00:00:00 2001 From: Chris Kennelly Date: Thu, 2 Feb 2017 16:33:02 -0800 Subject: Inline branch-less VarintSize32/VarintSize64 implementations. --- src/google/protobuf/io/coded_stream.cc | 19 ------------------- src/google/protobuf/io/coded_stream.h | 24 +++++++++++++++++------- 2 files changed, 17 insertions(+), 26 deletions(-) (limited to 'src/google/protobuf/io') diff --git a/src/google/protobuf/io/coded_stream.cc b/src/google/protobuf/io/coded_stream.cc index 93748ee3..3c2e0fbd 100644 --- a/src/google/protobuf/io/coded_stream.cc +++ b/src/google/protobuf/io/coded_stream.cc @@ -816,25 +816,6 @@ bool CodedOutputStream::Refresh() { } } -size_t CodedOutputStream::VarintSize32Fallback(uint32 value) { - // This computes floor(log2(value)) / 7 + 1 - // Use an explicit multiplication to implement the divide of - // a number in the 1..31 range. - GOOGLE_DCHECK_NE(0, value); // This is enforced by our caller. - - uint32 log2value = Bits::Log2FloorNonZero(value); - return static_cast((log2value * 9 + 73) / 64); -} - -size_t CodedOutputStream::VarintSize64(uint64 value) { - // This computes value == 0 ? 1 : floor(log2(value)) / 7 + 1 - // Use an explicit multiplication to implement the divide of - // a number in the 1..63 range. - // Explicit OR 0x1 to avoid calling clz(0), which is undefined. - uint32 log2value = Bits::Log2FloorNonZero64(value | 0x1); - return static_cast((log2value * 9 + 73) / 64); -} - uint8* CodedOutputStream::WriteStringWithSizeToArray(const string& str, uint8* target) { GOOGLE_DCHECK_LE(str.size(), kuint32max); diff --git a/src/google/protobuf/io/coded_stream.h b/src/google/protobuf/io/coded_stream.h index 557312d3..19d1b299 100644 --- a/src/google/protobuf/io/coded_stream.h +++ b/src/google/protobuf/io/coded_stream.h @@ -903,8 +903,6 @@ class LIBPROTOBUF_EXPORT CodedOutputStream { void WriteVarint32SlowPath(uint32 value); void WriteVarint64SlowPath(uint64 value); - static size_t VarintSize32Fallback(uint32 value); - // See above. Other projects may use "friend" to allow them to call this. // Requires: no protocol buffer serialization in progress. friend void ::google::protobuf::internal::MapTestForceDeterministic(); @@ -1292,11 +1290,23 @@ inline uint8* CodedOutputStream::WriteTagToArray( } inline size_t CodedOutputStream::VarintSize32(uint32 value) { - if (value < (1 << 7)) { - return 1; - } else { - return VarintSize32Fallback(value); - } + // This computes value == 0 ? 1 : floor(log2(value)) / 7 + 1 + // Use an explicit multiplication to implement the divide of + // a number in the 1..31 range. + // Explicit OR 0x1 to avoid calling Bits::Log2FloorNonZero(0), which is + // undefined. + uint32 log2value = Bits::Log2FloorNonZero(value | 0x1); + return static_cast((log2value * 9 + 73) / 64); +} + +inline size_t CodedOutputStream::VarintSize64(uint64 value) { + // This computes value == 0 ? 1 : floor(log2(value)) / 7 + 1 + // Use an explicit multiplication to implement the divide of + // a number in the 1..63 range. + // Explicit OR 0x1 to avoid calling Bits::Log2FloorNonZero(0), which is + // undefined. + uint32 log2value = Bits::Log2FloorNonZero64(value | 0x1); + return static_cast((log2value * 9 + 73) / 64); } inline size_t CodedOutputStream::VarintSize32SignExtended(int32 value) { -- cgit v1.2.3