Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Unified Diff: src/value-serializer.cc

Issue 2275033003: Blink-compatible serialization of ArrayBuffer transfer. (Closed)
Patch Set: Accepts Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/value-serializer.h ('k') | test/unittests/value-serializer-unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/value-serializer.cc
diff --git a/src/value-serializer.cc b/src/value-serializer.cc
index 756732043a404595d9412b9079d64678416906e8..bbfb2c77e038e5fe2051ec406e0ae66a15b9f045 100644
--- a/src/value-serializer.cc
+++ b/src/value-serializer.cc
@@ -92,12 +92,15 @@ enum class SerializationTag : uint8_t {
kEndJSSet = ',',
// Array buffer. byteLength:uint32_t, then raw data.
kArrayBuffer = 'B',
+ // Array buffer (transferred). transferID:uint32_t
+ kArrayBufferTransfer = 't',
};
ValueSerializer::ValueSerializer(Isolate* isolate)
: isolate_(isolate),
zone_(isolate->allocator()),
- id_map_(isolate->heap(), &zone_) {}
+ id_map_(isolate->heap(), &zone_),
+ array_buffer_transfer_map_(isolate->heap(), &zone_) {}
ValueSerializer::~ValueSerializer() {}
@@ -172,6 +175,12 @@ uint8_t* ValueSerializer::ReserveRawBytes(size_t bytes) {
return &buffer_[old_size];
}
+void ValueSerializer::TransferArrayBuffer(uint32_t transfer_id,
+ Handle<JSArrayBuffer> array_buffer) {
+ DCHECK(!array_buffer_transfer_map_.Find(array_buffer));
+ array_buffer_transfer_map_.Set(array_buffer, transfer_id);
+}
+
Maybe<bool> ValueSerializer::WriteObject(Handle<Object> object) {
if (object->IsSmi()) {
WriteSmi(Smi::cast(*object));
@@ -500,6 +509,14 @@ Maybe<bool> ValueSerializer::WriteJSSet(Handle<JSSet> set) {
}
Maybe<bool> ValueSerializer::WriteJSArrayBuffer(JSArrayBuffer* array_buffer) {
+ uint32_t* transfer_entry = array_buffer_transfer_map_.Find(array_buffer);
+ if (transfer_entry) {
+ DCHECK(array_buffer->was_neutered());
+ WriteTag(SerializationTag::kArrayBufferTransfer);
+ WriteVarint(*transfer_entry);
+ return Just(true);
+ }
+
if (array_buffer->was_neutered()) return Nothing<bool>();
double byte_length = array_buffer->byte_length()->Number();
if (byte_length > std::numeric_limits<uint32_t>::max()) {
@@ -550,6 +567,11 @@ ValueDeserializer::ValueDeserializer(Isolate* isolate,
ValueDeserializer::~ValueDeserializer() {
GlobalHandles::Destroy(Handle<Object>::cast(id_map_).location());
+
+ Handle<Object> transfer_map_handle;
+ if (array_buffer_transfer_map_.ToHandle(&transfer_map_handle)) {
+ GlobalHandles::Destroy(transfer_map_handle.location());
+ }
}
Maybe<bool> ValueDeserializer::ReadHeader() {
@@ -645,6 +667,26 @@ Maybe<Vector<const uint8_t>> ValueDeserializer::ReadRawBytes(int size) {
return Just(Vector<const uint8_t>(start, size));
}
+void ValueDeserializer::TransferArrayBuffer(
+ uint32_t transfer_id, Handle<JSArrayBuffer> array_buffer) {
+ if (array_buffer_transfer_map_.is_null()) {
+ array_buffer_transfer_map_ =
+ Handle<SeededNumberDictionary>::cast(isolate_->global_handles()->Create(
+ *SeededNumberDictionary::New(isolate_, 0)));
+ }
+ Handle<SeededNumberDictionary> dictionary =
+ array_buffer_transfer_map_.ToHandleChecked();
+ const bool used_as_prototype = false;
+ Handle<SeededNumberDictionary> new_dictionary =
+ SeededNumberDictionary::AtNumberPut(dictionary, transfer_id, array_buffer,
+ used_as_prototype);
+ if (!new_dictionary.is_identical_to(dictionary)) {
+ GlobalHandles::Destroy(Handle<Object>::cast(dictionary).location());
+ array_buffer_transfer_map_ = Handle<SeededNumberDictionary>::cast(
+ isolate_->global_handles()->Create(*new_dictionary));
+ }
+}
+
MaybeHandle<Object> ValueDeserializer::ReadObject() {
SerializationTag tag;
if (!ReadTag().To(&tag)) return MaybeHandle<Object>();
@@ -706,6 +748,8 @@ MaybeHandle<Object> ValueDeserializer::ReadObject() {
return ReadJSSet();
case SerializationTag::kArrayBuffer:
return ReadJSArrayBuffer();
+ case SerializationTag::kArrayBufferTransfer:
+ return ReadTransferredJSArrayBuffer();
default:
return MaybeHandle<Object>();
}
@@ -992,6 +1036,24 @@ MaybeHandle<JSArrayBuffer> ValueDeserializer::ReadJSArrayBuffer() {
return array_buffer;
}
+MaybeHandle<JSArrayBuffer> ValueDeserializer::ReadTransferredJSArrayBuffer() {
+ uint32_t id = next_id_++;
+ uint32_t transfer_id;
+ Handle<SeededNumberDictionary> transfer_map;
+ if (!ReadVarint<uint32_t>().To(&transfer_id) ||
+ !array_buffer_transfer_map_.ToHandle(&transfer_map)) {
+ return MaybeHandle<JSArrayBuffer>();
+ }
+ int index = transfer_map->FindEntry(isolate_, transfer_id);
+ if (index == SeededNumberDictionary::kNotFound) {
+ return MaybeHandle<JSArrayBuffer>();
+ }
+ Handle<JSArrayBuffer> array_buffer(
+ JSArrayBuffer::cast(transfer_map->ValueAt(index)), isolate_);
+ AddObjectWithID(id, array_buffer);
+ return array_buffer;
+}
+
Maybe<uint32_t> ValueDeserializer::ReadJSObjectProperties(
Handle<JSObject> object, SerializationTag end_tag) {
for (uint32_t num_properties = 0;; num_properties++) {
« no previous file with comments | « src/value-serializer.h ('k') | test/unittests/value-serializer-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698