diff options
author | Jisi Liu <jisi.liu@gmail.com> | 2015-02-28 14:51:22 -0800 |
---|---|---|
committer | Jisi Liu <jisi.liu@gmail.com> | 2015-02-28 17:06:49 -0800 |
commit | 885b612f74f133678bf82808c589331e4c59dad9 (patch) | |
tree | e5f3f65b41af477c52810053b8694896c8bcd1f7 /src/google/protobuf/io | |
parent | 1939efed2db35020b7830a4927f10feac47b6757 (diff) | |
download | protobuf-885b612f74f133678bf82808c589331e4c59dad9.tar.gz protobuf-885b612f74f133678bf82808c589331e4c59dad9.tar.bz2 protobuf-885b612f74f133678bf82808c589331e4c59dad9.zip |
Down integrate from Google internal branch for C++ and Java.
- Maps for C++ lite
- C++ Arena optimizations.
- Java Lite runtime code size optimization.
Change-Id: I7537a4357c1cb385d23f9e8aa7ffdfeefe079f13
Diffstat (limited to 'src/google/protobuf/io')
-rw-r--r-- | src/google/protobuf/io/coded_stream.cc | 77 | ||||
-rw-r--r-- | src/google/protobuf/io/coded_stream.h | 56 | ||||
-rw-r--r-- | src/google/protobuf/io/coded_stream_unittest.cc | 4 | ||||
-rw-r--r-- | src/google/protobuf/io/gzip_stream.cc | 1 | ||||
-rw-r--r-- | src/google/protobuf/io/zero_copy_stream_impl_lite.h | 2 |
5 files changed, 53 insertions, 87 deletions
diff --git a/src/google/protobuf/io/coded_stream.cc b/src/google/protobuf/io/coded_stream.cc index df88205c..93e1a22e 100644 --- a/src/google/protobuf/io/coded_stream.cc +++ b/src/google/protobuf/io/coded_stream.cc @@ -153,7 +153,7 @@ void CodedInputStream::PopLimit(Limit limit) { std::pair<CodedInputStream::Limit, int> CodedInputStream::IncrementRecursionDepthAndPushLimit(int byte_limit) { - return make_pair(PushLimit(byte_limit), --recursion_budget_); + return std::make_pair(PushLimit(byte_limit), --recursion_budget_); } bool CodedInputStream::DecrementRecursionDepthAndPopLimit(Limit limit) { @@ -613,8 +613,15 @@ CodedOutputStream::CodedOutputStream(ZeroCopyOutputStream* output) } CodedOutputStream::~CodedOutputStream() { + Trim(); +} + +void CodedOutputStream::Trim() { if (buffer_size_ > 0) { output_->BackUp(buffer_size_); + total_bytes_ -= buffer_size_; + buffer_size_ = 0; + buffer_ = NULL; } } @@ -662,12 +669,7 @@ void CodedOutputStream::WriteAliasedRaw(const void* data, int size) { ) { WriteRaw(data, size); } else { - if (buffer_size_ > 0) { - output_->BackUp(buffer_size_); - total_bytes_ -= buffer_size_; - buffer_ = NULL; - buffer_size_ = 0; - } + Trim(); total_bytes_ += size; had_error_ |= !output_->WriteAliasedRaw(data, size); @@ -704,61 +706,12 @@ void CodedOutputStream::WriteLittleEndian64(uint64 value) { } } -inline uint8* CodedOutputStream::WriteVarint32FallbackToArrayInline( - uint32 value, uint8* target) { - target[0] = static_cast<uint8>(value | 0x80); - if (value >= (1 << 7)) { - target[1] = static_cast<uint8>((value >> 7) | 0x80); - if (value >= (1 << 14)) { - target[2] = static_cast<uint8>((value >> 14) | 0x80); - if (value >= (1 << 21)) { - target[3] = static_cast<uint8>((value >> 21) | 0x80); - if (value >= (1 << 28)) { - target[4] = static_cast<uint8>(value >> 28); - return target + 5; - } else { - target[3] &= 0x7F; - return target + 4; - } - } else { - target[2] &= 0x7F; - return target + 3; - } - } else { - target[1] &= 0x7F; - return target + 2; - } - } else { - target[0] &= 0x7F; - return target + 1; - } -} - -void CodedOutputStream::WriteVarint32(uint32 value) { - if (buffer_size_ >= kMaxVarint32Bytes) { - // Fast path: We have enough bytes left in the buffer to guarantee that - // this write won't cross the end, so we can skip the checks. - uint8* target = buffer_; - uint8* end = WriteVarint32FallbackToArrayInline(value, target); - int size = end - target; - Advance(size); - } else { - // Slow path: This write might cross the end of the buffer, so we - // compose the bytes first then use WriteRaw(). - uint8 bytes[kMaxVarint32Bytes]; - int size = 0; - while (value > 0x7F) { - bytes[size++] = (static_cast<uint8>(value) & 0x7F) | 0x80; - value >>= 7; - } - bytes[size++] = static_cast<uint8>(value) & 0x7F; - WriteRaw(bytes, size); - } -} - -uint8* CodedOutputStream::WriteVarint32FallbackToArray( - uint32 value, uint8* target) { - return WriteVarint32FallbackToArrayInline(value, target); +void CodedOutputStream::WriteVarint32SlowPath(uint32 value) { + uint8 bytes[kMaxVarint32Bytes]; + uint8* target = &bytes[0]; + uint8* end = WriteVarint32ToArray(value, target); + int size = end - target; + WriteRaw(bytes, size); } inline uint8* CodedOutputStream::WriteVarint64ToArrayInline( diff --git a/src/google/protobuf/io/coded_stream.h b/src/google/protobuf/io/coded_stream.h index 978cc19d..dea4b650 100644 --- a/src/google/protobuf/io/coded_stream.h +++ b/src/google/protobuf/io/coded_stream.h @@ -647,6 +647,13 @@ class LIBPROTOBUF_EXPORT CodedOutputStream { // ZeroCopyOutputStream immediately after the last byte written. ~CodedOutputStream(); + // Trims any unused space in the underlying buffer so that its size matches + // the number of bytes written by this stream. The underlying buffer will + // automatically be trimmed when this stream is destroyed; this call is only + // necessary if the underlying buffer is accessed *before* the stream is + // destroyed. + void Trim(); + // Skips a number of bytes, leaving the bytes unmodified in the underlying // buffer. Returns false if an underlying write error occurs. This is // mainly useful with GetDirectBufferPointer(). @@ -789,7 +796,9 @@ class LIBPROTOBUF_EXPORT CodedOutputStream { // ZeroCopyOutputStream supports it. void WriteAliasedRaw(const void* buffer, int size); - static uint8* WriteVarint32FallbackToArray(uint32 value, uint8* target); + // If this write might cross the end of the buffer, we compose the bytes first + // then use WriteRaw(). + void WriteVarint32SlowPath(uint32 value); // Always-inlined versions of WriteVarint* functions so that code can be // reused, while still controlling size. For instance, WriteVarint32ToArray() @@ -798,8 +807,6 @@ class LIBPROTOBUF_EXPORT CodedOutputStream { // WriteVarint32FallbackToArray. Meanwhile, WriteVarint32() is already // out-of-line, so it should just invoke this directly to avoid any extra // function call overhead. - static uint8* WriteVarint32FallbackToArrayInline( - uint32 value, uint8* target) GOOGLE_ATTRIBUTE_ALWAYS_INLINE; static uint8* WriteVarint64ToArrayInline( uint64 value, uint8* target) GOOGLE_ATTRIBUTE_ALWAYS_INLINE; @@ -919,7 +926,7 @@ inline std::pair<uint32, bool> CodedInputStream::ReadTagWithCutoff( const uint32 kMax1ByteVarint = 0x7f; uint32 tag = last_tag_ = buffer_[0]; Advance(1); - return make_pair(tag, cutoff >= kMax1ByteVarint || tag <= cutoff); + return std::make_pair(tag, cutoff >= kMax1ByteVarint || tag <= cutoff); } // Other hot case: cutoff >= 0x80, buffer_ has at least two bytes available, // and tag is two bytes. The latter is tested by bitwise-and-not of the @@ -937,12 +944,12 @@ inline std::pair<uint32, bool> CodedInputStream::ReadTagWithCutoff( // so we don't have to check for tag == 0. We may need to check whether // it exceeds cutoff. bool at_or_below_cutoff = cutoff >= kMax2ByteVarint || tag <= cutoff; - return make_pair(tag, at_or_below_cutoff); + return std::make_pair(tag, at_or_below_cutoff); } } // Slow path last_tag_ = ReadTagFallback(); - return make_pair(last_tag_, static_cast<uint32>(last_tag_ - 1) < cutoff); + return std::make_pair(last_tag_, static_cast<uint32>(last_tag_ - 1) < cutoff); } inline bool CodedInputStream::LastTagWas(uint32 expected) { @@ -1027,13 +1034,14 @@ inline uint8* CodedOutputStream::GetDirectBufferForNBytesAndAdvance(int size) { } inline uint8* CodedOutputStream::WriteVarint32ToArray(uint32 value, - uint8* target) { - if (value < 0x80) { - *target = value; - return target + 1; - } else { - return WriteVarint32FallbackToArray(value, target); + uint8* target) { + while (value >= 0x80) { + *target = static_cast<uint8>(value | 0x80); + value >>= 7; + ++target; } + *target = static_cast<uint8>(value); + return target + 1; } inline void CodedOutputStream::WriteVarint32SignExtended(int32 value) { @@ -1086,22 +1094,26 @@ inline uint8* CodedOutputStream::WriteLittleEndian64ToArray(uint64 value, return target + sizeof(value); } +inline void CodedOutputStream::WriteVarint32(uint32 value) { + if (buffer_size_ >= 5) { + // Fast path: We have enough bytes left in the buffer to guarantee that + // this write won't cross the end, so we can skip the checks. + uint8* target = buffer_; + uint8* end = WriteVarint32ToArray(value, target); + int size = end - target; + Advance(size); + } else { + WriteVarint32SlowPath(value); + } +} + inline void CodedOutputStream::WriteTag(uint32 value) { WriteVarint32(value); } inline uint8* CodedOutputStream::WriteTagToArray( uint32 value, uint8* target) { - if (value < (1 << 7)) { - target[0] = value; - return target + 1; - } else if (value < (1 << 14)) { - target[0] = static_cast<uint8>(value | 0x80); - target[1] = static_cast<uint8>(value >> 7); - return target + 2; - } else { - return WriteVarint32FallbackToArray(value, target); - } + return WriteVarint32ToArray(value, target); } inline int CodedOutputStream::VarintSize32(uint32 value) { diff --git a/src/google/protobuf/io/coded_stream_unittest.cc b/src/google/protobuf/io/coded_stream_unittest.cc index bbe5e399..02d5bad3 100644 --- a/src/google/protobuf/io/coded_stream_unittest.cc +++ b/src/google/protobuf/io/coded_stream_unittest.cc @@ -502,11 +502,11 @@ struct Fixed64Case { }; inline std::ostream& operator<<(std::ostream& os, const Fixed32Case& c) { - return os << "0x" << hex << c.value << dec; + return os << "0x" << std::hex << c.value << std::dec; } inline std::ostream& operator<<(std::ostream& os, const Fixed64Case& c) { - return os << "0x" << hex << c.value << dec; + return os << "0x" << std::hex << c.value << std::dec; } Fixed32Case kFixed32Cases[] = { diff --git a/src/google/protobuf/io/gzip_stream.cc b/src/google/protobuf/io/gzip_stream.cc index e6037863..c9f4ca7f 100644 --- a/src/google/protobuf/io/gzip_stream.cc +++ b/src/google/protobuf/io/gzip_stream.cc @@ -49,6 +49,7 @@ static const int kDefaultBufferSize = 65536; GzipInputStream::GzipInputStream( ZeroCopyInputStream* sub_stream, Format format, int buffer_size) : format_(format), sub_stream_(sub_stream), zerror_(Z_OK), byte_count_(0) { + zcontext_.state = Z_NULL; zcontext_.zalloc = Z_NULL; zcontext_.zfree = Z_NULL; zcontext_.opaque = Z_NULL; diff --git a/src/google/protobuf/io/zero_copy_stream_impl_lite.h b/src/google/protobuf/io/zero_copy_stream_impl_lite.h index 3e25edfa..4360b18f 100644 --- a/src/google/protobuf/io/zero_copy_stream_impl_lite.h +++ b/src/google/protobuf/io/zero_copy_stream_impl_lite.h @@ -368,7 +368,7 @@ inline char* mutable_string_data(string* s) { inline std::pair<char*, bool> as_string_data(string* s) { char *p = mutable_string_data(s); #ifdef LANG_CXX11 - return make_pair(p, true); + return std::make_pair(p, true); #else return make_pair(p, p != NULL); #endif |