Commit 38b14408 authored by Adam Cozzette's avatar Adam Cozzette Committed by GitHub

Merge pull request #2663 from ckennelly/varint-size

Inline branch-less VarintSize32/VarintSize64 implementations.
parents 15360e59 36f68e02
...@@ -816,25 +816,6 @@ bool CodedOutputStream::Refresh() { ...@@ -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<size_t>((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<size_t>((log2value * 9 + 73) / 64);
}
uint8* CodedOutputStream::WriteStringWithSizeToArray(const string& str, uint8* CodedOutputStream::WriteStringWithSizeToArray(const string& str,
uint8* target) { uint8* target) {
GOOGLE_DCHECK_LE(str.size(), kuint32max); GOOGLE_DCHECK_LE(str.size(), kuint32max);
......
...@@ -903,8 +903,6 @@ class LIBPROTOBUF_EXPORT CodedOutputStream { ...@@ -903,8 +903,6 @@ class LIBPROTOBUF_EXPORT CodedOutputStream {
void WriteVarint32SlowPath(uint32 value); void WriteVarint32SlowPath(uint32 value);
void WriteVarint64SlowPath(uint64 value); void WriteVarint64SlowPath(uint64 value);
static size_t VarintSize32Fallback(uint32 value);
// See above. Other projects may use "friend" to allow them to call this. // See above. Other projects may use "friend" to allow them to call this.
// Requires: no protocol buffer serialization in progress. // Requires: no protocol buffer serialization in progress.
friend void ::google::protobuf::internal::MapTestForceDeterministic(); friend void ::google::protobuf::internal::MapTestForceDeterministic();
...@@ -1290,11 +1288,23 @@ inline uint8* CodedOutputStream::WriteTagToArray( ...@@ -1290,11 +1288,23 @@ inline uint8* CodedOutputStream::WriteTagToArray(
} }
inline size_t CodedOutputStream::VarintSize32(uint32 value) { inline size_t CodedOutputStream::VarintSize32(uint32 value) {
if (value < (1 << 7)) { // This computes value == 0 ? 1 : floor(log2(value)) / 7 + 1
return 1; // Use an explicit multiplication to implement the divide of
} else { // a number in the 1..31 range.
return VarintSize32Fallback(value); // Explicit OR 0x1 to avoid calling Bits::Log2FloorNonZero(0), which is
} // undefined.
uint32 log2value = Bits::Log2FloorNonZero(value | 0x1);
return static_cast<size_t>((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<size_t>((log2value * 9 + 73) / 64);
} }
inline size_t CodedOutputStream::VarintSize32SignExtended(int32 value) { inline size_t CodedOutputStream::VarintSize32SignExtended(int32 value) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment