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

Unified Diff: src/d8.cc

Issue 2657403002: Revert of [d8] Use ValueSerializer for postMessage (instead of ad-hoc serializer) (Closed)
Patch Set: Created 3 years, 11 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/d8.h ('k') | src/messages.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/d8.cc
diff --git a/src/d8.cc b/src/d8.cc
index 13f0bc1ff05de8271ab8f1ccd9ed6df644108429..171c59b6f0464fb9dc314cb8a2d9246aa6574f70 100644
--- a/src/d8.cc
+++ b/src/d8.cc
@@ -31,7 +31,6 @@
#include "src/base/sys-info.h"
#include "src/basic-block-profiler.h"
#include "src/interpreter/interpreter.h"
-#include "src/list-inl.h"
#include "src/msan.h"
#include "src/objects-inl.h"
#include "src/snapshot/natives.h"
@@ -219,6 +218,16 @@
}
+bool FindInObjectList(Local<Object> object, const Shell::ObjectList& list) {
+ for (int i = 0; i < list.length(); ++i) {
+ if (list[i]->StrictEquals(object)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+
Worker* GetWorkerFromInternalField(Isolate* isolate, Local<Object> object) {
if (object->InternalFieldCount() != 1) {
Throw(isolate, "this is not a Worker");
@@ -401,10 +410,7 @@
base::LazyMutex Shell::workers_mutex_;
bool Shell::allow_new_workers_ = true;
i::List<Worker*> Shell::workers_;
-std::unordered_set<SharedArrayBuffer::Contents,
- Shell::SharedArrayBufferContentsHash,
- Shell::SharedArrayBufferContentsIsEqual>
- Shell::externalized_shared_contents_;
+i::List<SharedArrayBuffer::Contents> Shell::externalized_shared_contents_;
Global<Context> Shell::evaluation_context_;
ArrayBuffer::Allocator* Shell::array_buffer_allocator;
@@ -1144,6 +1150,7 @@
void Shell::WorkerPostMessage(const v8::FunctionCallbackInfo<v8::Value>& args) {
Isolate* isolate = args.GetIsolate();
HandleScope handle_scope(isolate);
+ Local<Context> context = isolate->GetCurrentContext();
if (args.Length() < 1) {
Throw(isolate, "Invalid argument");
@@ -1156,12 +1163,36 @@
}
Local<Value> message = args[0];
- Local<Value> transfer =
- args.Length() >= 2 ? args[1] : Local<Value>::Cast(Undefined(isolate));
- std::unique_ptr<SerializationData> data =
- Shell::SerializeValue(isolate, message, transfer);
- if (data) {
- worker->PostMessage(std::move(data));
+ ObjectList to_transfer;
+ if (args.Length() >= 2) {
+ if (!args[1]->IsArray()) {
+ Throw(isolate, "Transfer list must be an Array");
+ return;
+ }
+
+ Local<Array> transfer = Local<Array>::Cast(args[1]);
+ uint32_t length = transfer->Length();
+ for (uint32_t i = 0; i < length; ++i) {
+ Local<Value> element;
+ if (transfer->Get(context, i).ToLocal(&element)) {
+ if (!element->IsArrayBuffer() && !element->IsSharedArrayBuffer()) {
+ Throw(isolate,
+ "Transfer array elements must be an ArrayBuffer or "
+ "SharedArrayBuffer.");
+ break;
+ }
+
+ to_transfer.Add(Local<Object>::Cast(element));
+ }
+ }
+ }
+
+ ObjectList seen_objects;
+ SerializationData* data = new SerializationData;
+ if (SerializeValue(isolate, message, to_transfer, &seen_objects, data)) {
+ worker->PostMessage(data);
+ } else {
+ delete data;
}
}
@@ -1174,12 +1205,14 @@
return;
}
- std::unique_ptr<SerializationData> data = worker->GetMessage();
+ SerializationData* data = worker->GetMessage();
if (data) {
- Local<Value> value;
- if (Shell::DeserializeValue(isolate, std::move(data)).ToLocal(&value)) {
- args.GetReturnValue().Set(value);
- }
+ int offset = 0;
+ Local<Value> data_value;
+ if (Shell::DeserializeValue(isolate, *data, &offset).ToLocal(&data_value)) {
+ args.GetReturnValue().Set(data_value);
+ }
+ delete data;
}
}
@@ -2115,12 +2148,14 @@
thread_->Join();
}
+
SerializationData::~SerializationData() {
// Any ArrayBuffer::Contents are owned by this SerializationData object if
- // ownership hasn't been transferred out.
+ // ownership hasn't been transferred out via ReadArrayBufferContents.
// SharedArrayBuffer::Contents may be used by multiple threads, so must be
// cleaned up by the main thread in Shell::CleanupWorkers().
- for (const auto& contents : array_buffer_contents_) {
+ for (int i = 0; i < array_buffer_contents_.length(); ++i) {
+ ArrayBuffer::Contents& contents = array_buffer_contents_[i];
if (contents.Data()) {
Shell::array_buffer_allocator->Free(contents.Data(),
contents.ByteLength());
@@ -2128,35 +2163,96 @@
}
}
-void SerializationData::ClearTransferredArrayBuffers() {
- array_buffer_contents_.clear();
-}
-
-void SerializationDataQueue::Enqueue(std::unique_ptr<SerializationData> data) {
+
+void SerializationData::WriteTag(SerializationTag tag) { data_.Add(tag); }
+
+
+void SerializationData::WriteMemory(const void* p, int length) {
+ if (length > 0) {
+ i::Vector<uint8_t> block = data_.AddBlock(0, length);
+ memcpy(&block[0], p, length);
+ }
+}
+
+
+void SerializationData::WriteArrayBufferContents(
+ const ArrayBuffer::Contents& contents) {
+ array_buffer_contents_.Add(contents);
+ WriteTag(kSerializationTagTransferredArrayBuffer);
+ int index = array_buffer_contents_.length() - 1;
+ Write(index);
+}
+
+
+void SerializationData::WriteSharedArrayBufferContents(
+ const SharedArrayBuffer::Contents& contents) {
+ shared_array_buffer_contents_.Add(contents);
+ WriteTag(kSerializationTagTransferredSharedArrayBuffer);
+ int index = shared_array_buffer_contents_.length() - 1;
+ Write(index);
+}
+
+
+SerializationTag SerializationData::ReadTag(int* offset) const {
+ return static_cast<SerializationTag>(Read<uint8_t>(offset));
+}
+
+
+void SerializationData::ReadMemory(void* p, int length, int* offset) const {
+ if (length > 0) {
+ memcpy(p, &data_[*offset], length);
+ (*offset) += length;
+ }
+}
+
+
+void SerializationData::ReadArrayBufferContents(ArrayBuffer::Contents* contents,
+ int* offset) const {
+ int index = Read<int>(offset);
+ DCHECK(index < array_buffer_contents_.length());
+ *contents = array_buffer_contents_[index];
+ // Ownership of this ArrayBuffer::Contents is passed to the caller. Neuter
+ // our copy so it won't be double-free'd when this SerializationData is
+ // destroyed.
+ array_buffer_contents_[index] = ArrayBuffer::Contents();
+}
+
+
+void SerializationData::ReadSharedArrayBufferContents(
+ SharedArrayBuffer::Contents* contents, int* offset) const {
+ int index = Read<int>(offset);
+ DCHECK(index < shared_array_buffer_contents_.length());
+ *contents = shared_array_buffer_contents_[index];
+}
+
+
+void SerializationDataQueue::Enqueue(SerializationData* data) {
base::LockGuard<base::Mutex> lock_guard(&mutex_);
- data_.push_back(std::move(data));
-}
-
-bool SerializationDataQueue::Dequeue(
- std::unique_ptr<SerializationData>* out_data) {
- out_data->reset();
+ data_.Add(data);
+}
+
+
+bool SerializationDataQueue::Dequeue(SerializationData** data) {
base::LockGuard<base::Mutex> lock_guard(&mutex_);
- if (data_.empty()) return false;
- *out_data = std::move(data_[0]);
- data_.erase(data_.begin());
+ *data = NULL;
+ if (data_.is_empty()) return false;
+ *data = data_.Remove(0);
return true;
}
bool SerializationDataQueue::IsEmpty() {
base::LockGuard<base::Mutex> lock_guard(&mutex_);
- return data_.empty();
+ return data_.is_empty();
}
void SerializationDataQueue::Clear() {
base::LockGuard<base::Mutex> lock_guard(&mutex_);
- data_.clear();
+ for (int i = 0; i < data_.length(); ++i) {
+ delete data_[i];
+ }
+ data_.Clear();
}
@@ -2185,20 +2281,22 @@
thread_->Start();
}
-void Worker::PostMessage(std::unique_ptr<SerializationData> data) {
- in_queue_.Enqueue(std::move(data));
+
+void Worker::PostMessage(SerializationData* data) {
+ in_queue_.Enqueue(data);
in_semaphore_.Signal();
}
-std::unique_ptr<SerializationData> Worker::GetMessage() {
- std::unique_ptr<SerializationData> result;
- while (!out_queue_.Dequeue(&result)) {
+
+SerializationData* Worker::GetMessage() {
+ SerializationData* data = NULL;
+ while (!out_queue_.Dequeue(&data)) {
// If the worker is no longer running, and there are no messages in the
// queue, don't expect any more messages from it.
if (!base::NoBarrier_Load(&running_)) break;
out_semaphore_.Wait();
}
- return result;
+ return data;
}
@@ -2262,21 +2360,19 @@
// Now wait for messages
while (true) {
in_semaphore_.Wait();
- std::unique_ptr<SerializationData> data;
+ SerializationData* data;
if (!in_queue_.Dequeue(&data)) continue;
- if (!data) {
+ if (data == NULL) {
break;
}
- v8::TryCatch try_catch(isolate);
- Local<Value> value;
- if (Shell::DeserializeValue(isolate, std::move(data))
- .ToLocal(&value)) {
- Local<Value> argv[] = {value};
+ int offset = 0;
+ Local<Value> data_value;
+ if (Shell::DeserializeValue(isolate, *data, &offset)
+ .ToLocal(&data_value)) {
+ Local<Value> argv[] = {data_value};
(void)onmessage_fun->Call(context, global, 1, argv);
}
- if (try_catch.HasCaught()) {
- Shell::ReportException(isolate, &try_catch);
- }
+ delete data;
}
}
}
@@ -2303,15 +2399,21 @@
}
Local<Value> message = args[0];
- Local<Value> transfer = Undefined(isolate);
- std::unique_ptr<SerializationData> data =
- Shell::SerializeValue(isolate, message, transfer);
- if (data) {
+
+ // TODO(binji): Allow transferring from worker to main thread?
+ Shell::ObjectList to_transfer;
+
+ Shell::ObjectList seen_objects;
+ SerializationData* data = new SerializationData;
+ if (Shell::SerializeValue(isolate, message, to_transfer, &seen_objects,
+ data)) {
DCHECK(args.Data()->IsExternal());
Local<External> this_value = Local<External>::Cast(args.Data());
Worker* worker = static_cast<Worker*>(this_value->Value());
- worker->out_queue_.Enqueue(std::move(data));
+ worker->out_queue_.Enqueue(data);
worker->out_semaphore_.Signal();
+ } else {
+ delete data;
}
}
@@ -2504,202 +2606,234 @@
}
}
-class Serializer : public ValueSerializer::Delegate {
- public:
- explicit Serializer(Isolate* isolate)
- : isolate_(isolate), serializer_(isolate, this) {}
-
- Maybe<bool> WriteValue(Local<Context> context, Local<Value> value,
- Local<Value> transfer) {
- bool ok;
- DCHECK(!data_);
- data_.reset(new SerializationData);
- if (!PrepareTransfer(context, transfer).To(&ok)) {
- return Nothing<bool>();
- }
- serializer_.WriteHeader();
-
- if (!serializer_.WriteValue(context, value).To(&ok)) {
- data_.reset();
- return Nothing<bool>();
- }
-
- if (!FinalizeTransfer().To(&ok)) {
- return Nothing<bool>();
- }
-
- std::pair<uint8_t*, size_t> pair = serializer_.Release();
- data_->data_.reset(pair.first);
- data_->size_ = pair.second;
- return Just(true);
- }
-
- std::unique_ptr<SerializationData> Release() { return std::move(data_); }
-
- protected:
- // Implements ValueSerializer::Delegate.
- void ThrowDataCloneError(Local<String> message) override {
- isolate_->ThrowException(Exception::Error(message));
- }
-
- Maybe<uint32_t> GetSharedArrayBufferId(
- Isolate* isolate, Local<SharedArrayBuffer> shared_array_buffer) override {
- DCHECK(data_ != nullptr);
- for (size_t index = 0; index < shared_array_buffers_.size(); ++index) {
- if (shared_array_buffers_[index] == shared_array_buffer) {
- return Just<uint32_t>(static_cast<uint32_t>(index));
+
+bool Shell::SerializeValue(Isolate* isolate, Local<Value> value,
+ const ObjectList& to_transfer,
+ ObjectList* seen_objects,
+ SerializationData* out_data) {
+ DCHECK(out_data);
+ Local<Context> context = isolate->GetCurrentContext();
+
+ if (value->IsUndefined()) {
+ out_data->WriteTag(kSerializationTagUndefined);
+ } else if (value->IsNull()) {
+ out_data->WriteTag(kSerializationTagNull);
+ } else if (value->IsTrue()) {
+ out_data->WriteTag(kSerializationTagTrue);
+ } else if (value->IsFalse()) {
+ out_data->WriteTag(kSerializationTagFalse);
+ } else if (value->IsNumber()) {
+ Local<Number> num = Local<Number>::Cast(value);
+ double value = num->Value();
+ out_data->WriteTag(kSerializationTagNumber);
+ out_data->Write(value);
+ } else if (value->IsString()) {
+ v8::String::Utf8Value str(value);
+ out_data->WriteTag(kSerializationTagString);
+ out_data->Write(str.length());
+ out_data->WriteMemory(*str, str.length());
+ } else if (value->IsArray()) {
+ Local<Array> array = Local<Array>::Cast(value);
+ if (FindInObjectList(array, *seen_objects)) {
+ Throw(isolate, "Duplicated arrays not supported");
+ return false;
+ }
+ seen_objects->Add(array);
+ out_data->WriteTag(kSerializationTagArray);
+ uint32_t length = array->Length();
+ out_data->Write(length);
+ for (uint32_t i = 0; i < length; ++i) {
+ Local<Value> element_value;
+ if (array->Get(context, i).ToLocal(&element_value)) {
+ if (!SerializeValue(isolate, element_value, to_transfer, seen_objects,
+ out_data))
+ return false;
+ } else {
+ Throw(isolate, "Failed to serialize array element.");
+ return false;
}
}
-
- size_t index = shared_array_buffers_.size();
- shared_array_buffers_.emplace_back(isolate_, shared_array_buffer);
- return Just<uint32_t>(static_cast<uint32_t>(index));
- }
-
- void* ReallocateBufferMemory(void* old_buffer, size_t size,
- size_t* actual_size) override {
- void* result = realloc(old_buffer, size);
- *actual_size = result ? size : 0;
- return result;
- }
-
- void FreeBufferMemory(void* buffer) override { free(buffer); }
-
- private:
- Maybe<bool> PrepareTransfer(Local<Context> context, Local<Value> transfer) {
- if (transfer->IsArray()) {
- Local<Array> transfer_array = Local<Array>::Cast(transfer);
- uint32_t length = transfer_array->Length();
+ } else if (value->IsArrayBuffer()) {
+ Local<ArrayBuffer> array_buffer = Local<ArrayBuffer>::Cast(value);
+ if (FindInObjectList(array_buffer, *seen_objects)) {
+ Throw(isolate, "Duplicated array buffers not supported");
+ return false;
+ }
+ seen_objects->Add(array_buffer);
+ if (FindInObjectList(array_buffer, to_transfer)) {
+ // Transfer ArrayBuffer
+ if (!array_buffer->IsNeuterable()) {
+ Throw(isolate, "Attempting to transfer an un-neuterable ArrayBuffer");
+ return false;
+ }
+
+ ArrayBuffer::Contents contents = array_buffer->IsExternal()
+ ? array_buffer->GetContents()
+ : array_buffer->Externalize();
+ array_buffer->Neuter();
+ out_data->WriteArrayBufferContents(contents);
+ } else {
+ ArrayBuffer::Contents contents = array_buffer->GetContents();
+ // Clone ArrayBuffer
+ if (contents.ByteLength() > i::kMaxInt) {
+ Throw(isolate, "ArrayBuffer is too big to clone");
+ return false;
+ }
+
+ int32_t byte_length = static_cast<int32_t>(contents.ByteLength());
+ out_data->WriteTag(kSerializationTagArrayBuffer);
+ out_data->Write(byte_length);
+ out_data->WriteMemory(contents.Data(), byte_length);
+ }
+ } else if (value->IsSharedArrayBuffer()) {
+ Local<SharedArrayBuffer> sab = Local<SharedArrayBuffer>::Cast(value);
+ if (FindInObjectList(sab, *seen_objects)) {
+ Throw(isolate, "Duplicated shared array buffers not supported");
+ return false;
+ }
+ seen_objects->Add(sab);
+ if (!FindInObjectList(sab, to_transfer)) {
+ Throw(isolate, "SharedArrayBuffer must be transferred");
+ return false;
+ }
+
+ SharedArrayBuffer::Contents contents;
+ if (sab->IsExternal()) {
+ contents = sab->GetContents();
+ } else {
+ contents = sab->Externalize();
+ base::LockGuard<base::Mutex> lock_guard(workers_mutex_.Pointer());
+ externalized_shared_contents_.Add(contents);
+ }
+ out_data->WriteSharedArrayBufferContents(contents);
+ } else if (value->IsObject()) {
+ Local<Object> object = Local<Object>::Cast(value);
+ if (FindInObjectList(object, *seen_objects)) {
+ Throw(isolate, "Duplicated objects not supported");
+ return false;
+ }
+ seen_objects->Add(object);
+ Local<Array> property_names;
+ if (!object->GetOwnPropertyNames(context).ToLocal(&property_names)) {
+ Throw(isolate, "Unable to get property names");
+ return false;
+ }
+
+ uint32_t length = property_names->Length();
+ out_data->WriteTag(kSerializationTagObject);
+ out_data->Write(length);
+ for (uint32_t i = 0; i < length; ++i) {
+ Local<Value> name;
+ Local<Value> property_value;
+ if (property_names->Get(context, i).ToLocal(&name) &&
+ object->Get(context, name).ToLocal(&property_value)) {
+ if (!SerializeValue(isolate, name, to_transfer, seen_objects, out_data))
+ return false;
+ if (!SerializeValue(isolate, property_value, to_transfer, seen_objects,
+ out_data))
+ return false;
+ } else {
+ Throw(isolate, "Failed to serialize property.");
+ return false;
+ }
+ }
+ } else {
+ Throw(isolate, "Don't know how to serialize object");
+ return false;
+ }
+
+ return true;
+}
+
+
+MaybeLocal<Value> Shell::DeserializeValue(Isolate* isolate,
+ const SerializationData& data,
+ int* offset) {
+ DCHECK(offset);
+ EscapableHandleScope scope(isolate);
+ Local<Value> result;
+ SerializationTag tag = data.ReadTag(offset);
+
+ switch (tag) {
+ case kSerializationTagUndefined:
+ result = Undefined(isolate);
+ break;
+ case kSerializationTagNull:
+ result = Null(isolate);
+ break;
+ case kSerializationTagTrue:
+ result = True(isolate);
+ break;
+ case kSerializationTagFalse:
+ result = False(isolate);
+ break;
+ case kSerializationTagNumber:
+ result = Number::New(isolate, data.Read<double>(offset));
+ break;
+ case kSerializationTagString: {
+ int length = data.Read<int>(offset);
+ CHECK(length >= 0);
+ std::vector<char> buffer(length + 1); // + 1 so it is never empty.
+ data.ReadMemory(&buffer[0], length, offset);
+ MaybeLocal<String> str =
+ String::NewFromUtf8(isolate, &buffer[0], NewStringType::kNormal,
+ length).ToLocalChecked();
+ if (!str.IsEmpty()) result = str.ToLocalChecked();
+ break;
+ }
+ case kSerializationTagArray: {
+ uint32_t length = data.Read<uint32_t>(offset);
+ Local<Array> array = Array::New(isolate, length);
for (uint32_t i = 0; i < length; ++i) {
- Local<Value> element;
- if (transfer_array->Get(context, i).ToLocal(&element)) {
- if (!element->IsArrayBuffer()) {
- Throw(isolate_, "Transfer array elements must be an ArrayBuffer");
- break;
- }
-
- Local<ArrayBuffer> array_buffer = Local<ArrayBuffer>::Cast(element);
- serializer_.TransferArrayBuffer(
- static_cast<uint32_t>(array_buffers_.size()), array_buffer);
- array_buffers_.emplace_back(isolate_, array_buffer);
- } else {
- return Nothing<bool>();
- }
+ Local<Value> element_value;
+ CHECK(DeserializeValue(isolate, data, offset).ToLocal(&element_value));
+ array->Set(isolate->GetCurrentContext(), i, element_value).FromJust();
}
- return Just(true);
- } else if (transfer->IsUndefined()) {
- return Just(true);
- } else {
- Throw(isolate_, "Transfer list must be an Array or undefined");
- return Nothing<bool>();
- }
- }
-
- Maybe<bool> FinalizeTransfer() {
- for (const auto& global_array_buffer : array_buffers_) {
- Local<ArrayBuffer> array_buffer =
- Local<ArrayBuffer>::New(isolate_, global_array_buffer);
- if (!array_buffer->IsNeuterable()) {
- Throw(isolate_, "ArrayBuffer could not be transferred");
- return Nothing<bool>();
+ result = array;
+ break;
+ }
+ case kSerializationTagObject: {
+ int length = data.Read<int>(offset);
+ Local<Object> object = Object::New(isolate);
+ for (int i = 0; i < length; ++i) {
+ Local<Value> property_name;
+ CHECK(DeserializeValue(isolate, data, offset).ToLocal(&property_name));
+ Local<Value> property_value;
+ CHECK(DeserializeValue(isolate, data, offset).ToLocal(&property_value));
+ object->Set(isolate->GetCurrentContext(), property_name, property_value)
+ .FromJust();
}
-
- if (!array_buffer->IsExternal()) {
- array_buffer->Externalize();
- }
+ result = object;
+ break;
+ }
+ case kSerializationTagArrayBuffer: {
+ int32_t byte_length = data.Read<int32_t>(offset);
+ Local<ArrayBuffer> array_buffer = ArrayBuffer::New(isolate, byte_length);
ArrayBuffer::Contents contents = array_buffer->GetContents();
- array_buffer->Neuter();
- data_->array_buffer_contents_.push_back(contents);
- }
-
- for (const auto& global_shared_array_buffer : shared_array_buffers_) {
- Local<SharedArrayBuffer> shared_array_buffer =
- Local<SharedArrayBuffer>::New(isolate_, global_shared_array_buffer);
- if (!shared_array_buffer->IsExternal()) {
- shared_array_buffer->Externalize();
- }
- data_->shared_array_buffer_contents_.push_back(
- shared_array_buffer->GetContents());
- }
-
- return Just(true);
- }
-
- Isolate* isolate_;
- ValueSerializer serializer_;
- std::unique_ptr<SerializationData> data_;
- std::vector<Global<ArrayBuffer>> array_buffers_;
- std::vector<Global<SharedArrayBuffer>> shared_array_buffers_;
-
- DISALLOW_COPY_AND_ASSIGN(Serializer);
-};
-
-class Deserializer : public ValueDeserializer::Delegate {
- public:
- Deserializer(Isolate* isolate, std::unique_ptr<SerializationData> data)
- : isolate_(isolate),
- deserializer_(isolate, data->data(), data->size(), this),
- data_(std::move(data)) {
- deserializer_.SetSupportsLegacyWireFormat(true);
- }
-
- MaybeLocal<Value> ReadValue(Local<Context> context) {
- bool read_header;
- if (!deserializer_.ReadHeader(context).To(&read_header)) {
- return MaybeLocal<Value>();
- }
-
- uint32_t index = 0;
- for (const auto& contents : data_->array_buffer_contents()) {
- Local<ArrayBuffer> array_buffer =
- ArrayBuffer::New(isolate_, contents.Data(), contents.ByteLength());
- deserializer_.TransferArrayBuffer(index++, array_buffer);
- }
-
- index = 0;
- for (const auto& contents : data_->shared_array_buffer_contents()) {
- Local<SharedArrayBuffer> shared_array_buffer = SharedArrayBuffer::New(
- isolate_, contents.Data(), contents.ByteLength());
- deserializer_.TransferSharedArrayBuffer(index++, shared_array_buffer);
- }
-
- MaybeLocal<Value> result = deserializer_.ReadValue(context);
- if (!result.IsEmpty()) {
- data_->ClearTransferredArrayBuffers();
- }
- return result;
- }
-
- private:
- Isolate* isolate_;
- ValueDeserializer deserializer_;
- std::unique_ptr<SerializationData> data_;
-
- DISALLOW_COPY_AND_ASSIGN(Deserializer);
-};
-
-std::unique_ptr<SerializationData> Shell::SerializeValue(
- Isolate* isolate, Local<Value> value, Local<Value> transfer) {
- bool ok;
- Local<Context> context = isolate->GetCurrentContext();
- Serializer serializer(isolate);
- if (serializer.WriteValue(context, value, transfer).To(&ok)) {
- std::unique_ptr<SerializationData> data = serializer.Release();
- base::LockGuard<base::Mutex> lock_guard(workers_mutex_.Pointer());
- for (const auto& contents : data->shared_array_buffer_contents()) {
- externalized_shared_contents_.insert(contents);
- }
- return data;
- }
- return nullptr;
-}
-
-MaybeLocal<Value> Shell::DeserializeValue(
- Isolate* isolate, std::unique_ptr<SerializationData> data) {
- Local<Value> value;
- Local<Context> context = isolate->GetCurrentContext();
- Deserializer deserializer(isolate, std::move(data));
- return deserializer.ReadValue(context);
+ DCHECK(static_cast<size_t>(byte_length) == contents.ByteLength());
+ data.ReadMemory(contents.Data(), byte_length, offset);
+ result = array_buffer;
+ break;
+ }
+ case kSerializationTagTransferredArrayBuffer: {
+ ArrayBuffer::Contents contents;
+ data.ReadArrayBufferContents(&contents, offset);
+ result = ArrayBuffer::New(isolate, contents.Data(), contents.ByteLength(),
+ ArrayBufferCreationMode::kInternalized);
+ break;
+ }
+ case kSerializationTagTransferredSharedArrayBuffer: {
+ SharedArrayBuffer::Contents contents;
+ data.ReadSharedArrayBufferContents(&contents, offset);
+ result = SharedArrayBuffer::New(isolate, contents.Data(),
+ contents.ByteLength());
+ break;
+ }
+ default:
+ UNREACHABLE();
+ }
+
+ return scope.Escape(result);
}
@@ -2725,10 +2859,12 @@
base::LockGuard<base::Mutex> lock_guard(workers_mutex_.Pointer());
allow_new_workers_ = true;
- for (const auto& contents : externalized_shared_contents_) {
+ for (int i = 0; i < externalized_shared_contents_.length(); ++i) {
+ const SharedArrayBuffer::Contents& contents =
+ externalized_shared_contents_[i];
Shell::array_buffer_allocator->Free(contents.Data(), contents.ByteLength());
}
- externalized_shared_contents_.clear();
+ externalized_shared_contents_.Clear();
}
« no previous file with comments | « src/d8.h ('k') | src/messages.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698