| Index: src/value-serializer.cc
|
| diff --git a/src/value-serializer.cc b/src/value-serializer.cc
|
| index 8dfb27c4445819ad0b22654942f8c22305f690c0..0b16ce79a5d2f12d11e40711a9119abd3f30a590 100644
|
| --- a/src/value-serializer.cc
|
| +++ b/src/value-serializer.cc
|
| @@ -147,7 +147,15 @@ ValueSerializer::ValueSerializer(Isolate* isolate,
|
| id_map_(isolate->heap(), &zone_),
|
| array_buffer_transfer_map_(isolate->heap(), &zone_) {}
|
|
|
| -ValueSerializer::~ValueSerializer() {}
|
| +ValueSerializer::~ValueSerializer() {
|
| + if (buffer_) {
|
| + if (delegate_) {
|
| + delegate_->FreeBufferMemory(buffer_);
|
| + } else {
|
| + free(buffer_);
|
| + }
|
| + }
|
| +}
|
|
|
| void ValueSerializer::WriteHeader() {
|
| WriteTag(SerializationTag::kVersion);
|
| @@ -155,7 +163,8 @@ void ValueSerializer::WriteHeader() {
|
| }
|
|
|
| void ValueSerializer::WriteTag(SerializationTag tag) {
|
| - buffer_.push_back(static_cast<uint8_t>(tag));
|
| + uint8_t raw_tag = static_cast<uint8_t>(tag);
|
| + WriteRawBytes(&raw_tag, sizeof(raw_tag));
|
| }
|
|
|
| template <typename T>
|
| @@ -174,7 +183,7 @@ void ValueSerializer::WriteVarint(T value) {
|
| value >>= 7;
|
| } while (value);
|
| *(next_byte - 1) &= 0x7f;
|
| - buffer_.insert(buffer_.end(), stack_buffer, next_byte);
|
| + WriteRawBytes(stack_buffer, next_byte - stack_buffer);
|
| }
|
|
|
| template <typename T>
|
| @@ -192,34 +201,50 @@ void ValueSerializer::WriteZigZag(T value) {
|
|
|
| void ValueSerializer::WriteDouble(double value) {
|
| // Warning: this uses host endianness.
|
| - buffer_.insert(buffer_.end(), reinterpret_cast<const uint8_t*>(&value),
|
| - reinterpret_cast<const uint8_t*>(&value + 1));
|
| + WriteRawBytes(&value, sizeof(value));
|
| }
|
|
|
| void ValueSerializer::WriteOneByteString(Vector<const uint8_t> chars) {
|
| WriteVarint<uint32_t>(chars.length());
|
| - buffer_.insert(buffer_.end(), chars.begin(), chars.end());
|
| + WriteRawBytes(chars.begin(), chars.length() * sizeof(uint8_t));
|
| }
|
|
|
| void ValueSerializer::WriteTwoByteString(Vector<const uc16> chars) {
|
| // Warning: this uses host endianness.
|
| WriteVarint<uint32_t>(chars.length() * sizeof(uc16));
|
| - buffer_.insert(buffer_.end(), reinterpret_cast<const uint8_t*>(chars.begin()),
|
| - reinterpret_cast<const uint8_t*>(chars.end()));
|
| + WriteRawBytes(chars.begin(), chars.length() * sizeof(uc16));
|
| }
|
|
|
| void ValueSerializer::WriteRawBytes(const void* source, size_t length) {
|
| - const uint8_t* begin = reinterpret_cast<const uint8_t*>(source);
|
| - buffer_.insert(buffer_.end(), begin, begin + length);
|
| + memcpy(ReserveRawBytes(length), source, length);
|
| }
|
|
|
| uint8_t* ValueSerializer::ReserveRawBytes(size_t bytes) {
|
| - if (!bytes) return nullptr;
|
| - auto old_size = buffer_.size();
|
| - buffer_.resize(buffer_.size() + bytes);
|
| + size_t old_size = buffer_size_;
|
| + size_t new_size = old_size + bytes;
|
| + if (new_size > buffer_capacity_) ExpandBuffer(new_size);
|
| + buffer_size_ = new_size;
|
| return &buffer_[old_size];
|
| }
|
|
|
| +void ValueSerializer::ExpandBuffer(size_t required_capacity) {
|
| + DCHECK_GT(required_capacity, buffer_capacity_);
|
| + size_t requested_capacity =
|
| + std::max(required_capacity, buffer_capacity_ * 2) + 64;
|
| + size_t provided_capacity = 0;
|
| + void* new_buffer = nullptr;
|
| + if (delegate_) {
|
| + new_buffer = delegate_->ReallocateBufferMemory(buffer_, requested_capacity,
|
| + &provided_capacity);
|
| + } else {
|
| + new_buffer = realloc(buffer_, requested_capacity);
|
| + provided_capacity = requested_capacity;
|
| + }
|
| + DCHECK_GE(provided_capacity, requested_capacity);
|
| + buffer_ = reinterpret_cast<uint8_t*>(new_buffer);
|
| + buffer_capacity_ = provided_capacity;
|
| +}
|
| +
|
| void ValueSerializer::WriteUint32(uint32_t value) {
|
| WriteVarint<uint32_t>(value);
|
| }
|
| @@ -228,6 +253,18 @@ void ValueSerializer::WriteUint64(uint64_t value) {
|
| WriteVarint<uint64_t>(value);
|
| }
|
|
|
| +std::vector<uint8_t> ValueSerializer::ReleaseBuffer() {
|
| + return std::vector<uint8_t>(buffer_, buffer_ + buffer_size_);
|
| +}
|
| +
|
| +std::pair<uint8_t*, size_t> ValueSerializer::Release() {
|
| + auto result = std::make_pair(buffer_, buffer_size_);
|
| + buffer_ = nullptr;
|
| + buffer_size_ = 0;
|
| + buffer_capacity_ = 0;
|
| + return result;
|
| +}
|
| +
|
| void ValueSerializer::TransferArrayBuffer(uint32_t transfer_id,
|
| Handle<JSArrayBuffer> array_buffer) {
|
| DCHECK(!array_buffer_transfer_map_.Find(array_buffer));
|
| @@ -338,7 +375,7 @@ void ValueSerializer::WriteString(Handle<String> string) {
|
| Vector<const uc16> chars = flat.ToUC16Vector();
|
| uint32_t byte_length = chars.length() * sizeof(uc16);
|
| // The existing reading code expects 16-byte strings to be aligned.
|
| - if ((buffer_.size() + 1 + BytesNeededForVarint(byte_length)) & 1)
|
| + if ((buffer_size_ + 1 + BytesNeededForVarint(byte_length)) & 1)
|
| WriteTag(SerializationTag::kPadding);
|
| WriteTag(SerializationTag::kTwoByteString);
|
| WriteTwoByteString(chars);
|
|
|