Commit c9b4f805 authored by Ben Smith's avatar Ben Smith Committed by Commit Bot

[wasm] postMessage of WebAssembly.Module in d8

Supporting postMessage from WebAssembly.Module requires implementing
some logic in the ValueSerializer and ValueDeserializer delegates. This
change implements some simple logic for d8.

This change also fixes a DCHECK that occurs when sending a shared
WebAssembly.Memory object to two Workers.

Bug: chromium:857049
Cq-Include-Trybots: luci.chromium.try:linux_chromium_rel_ng
Change-Id: Idddb23a48175c7175967af3fbc03d8572452a069
Reviewed-on: https://chromium-review.googlesource.com/1117871Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Commit-Queue: Ben Smith <binji@chromium.org>
Cr-Commit-Position: refs/heads/master@{#54093}
parent 63372e46
...@@ -7664,8 +7664,7 @@ v8::ArrayBuffer::Contents v8::ArrayBuffer::Externalize() { ...@@ -7664,8 +7664,7 @@ v8::ArrayBuffer::Contents v8::ArrayBuffer::Externalize() {
// longer track it. // longer track it.
// //
// TODO(eholk): Find a way to track this across externalization // TODO(eholk): Find a way to track this across externalization
isolate->wasm_engine()->memory_tracker()->ReleaseAllocation( self->StopTrackingWasmMemory(isolate);
self->backing_store());
} }
isolate->heap()->UnregisterArrayBuffer(*self); isolate->heap()->UnregisterArrayBuffer(*self);
...@@ -7899,8 +7898,7 @@ v8::SharedArrayBuffer::Contents v8::SharedArrayBuffer::Externalize() { ...@@ -7899,8 +7898,7 @@ v8::SharedArrayBuffer::Contents v8::SharedArrayBuffer::Externalize() {
// longer track it. // longer track it.
// //
// TODO(eholk): Find a way to track this across externalization // TODO(eholk): Find a way to track this across externalization
isolate->wasm_engine()->memory_tracker()->ReleaseAllocation( self->StopTrackingWasmMemory(isolate);
self->backing_store());
} }
isolate->heap()->UnregisterArrayBuffer(*self); isolate->heap()->UnregisterArrayBuffer(*self);
......
...@@ -3075,6 +3075,21 @@ class Serializer : public ValueSerializer::Delegate { ...@@ -3075,6 +3075,21 @@ class Serializer : public ValueSerializer::Delegate {
return Just<uint32_t>(static_cast<uint32_t>(index)); return Just<uint32_t>(static_cast<uint32_t>(index));
} }
Maybe<uint32_t> GetWasmModuleTransferId(
Isolate* isolate, Local<WasmCompiledModule> module) override {
DCHECK_NOT_NULL(data_);
for (size_t index = 0; index < wasm_modules_.size(); ++index) {
if (wasm_modules_[index] == module) {
return Just<uint32_t>(static_cast<uint32_t>(index));
}
}
size_t index = wasm_modules_.size();
wasm_modules_.emplace_back(isolate_, module);
data_->transferrable_modules_.push_back(module->GetTransferrableModule());
return Just<uint32_t>(static_cast<uint32_t>(index));
}
void* ReallocateBufferMemory(void* old_buffer, size_t size, void* ReallocateBufferMemory(void* old_buffer, size_t size,
size_t* actual_size) override { size_t* actual_size) override {
// Not accurate, because we don't take into account reallocated buffers, // Not accurate, because we don't take into account reallocated buffers,
...@@ -3152,6 +3167,7 @@ class Serializer : public ValueSerializer::Delegate { ...@@ -3152,6 +3167,7 @@ class Serializer : public ValueSerializer::Delegate {
std::unique_ptr<SerializationData> data_; std::unique_ptr<SerializationData> data_;
std::vector<Global<ArrayBuffer>> array_buffers_; std::vector<Global<ArrayBuffer>> array_buffers_;
std::vector<Global<SharedArrayBuffer>> shared_array_buffers_; std::vector<Global<SharedArrayBuffer>> shared_array_buffers_;
std::vector<Global<WasmCompiledModule>> wasm_modules_;
std::vector<ExternalizedContents> externalized_contents_; std::vector<ExternalizedContents> externalized_contents_;
size_t current_memory_usage_; size_t current_memory_usage_;
...@@ -3195,6 +3211,16 @@ class Deserializer : public ValueDeserializer::Delegate { ...@@ -3195,6 +3211,16 @@ class Deserializer : public ValueDeserializer::Delegate {
return MaybeLocal<SharedArrayBuffer>(); return MaybeLocal<SharedArrayBuffer>();
} }
MaybeLocal<WasmCompiledModule> GetWasmModuleFromId(
Isolate* isolate, uint32_t transfer_id) override {
DCHECK_NOT_NULL(data_);
if (transfer_id < data_->transferrable_modules().size()) {
return WasmCompiledModule::FromTransferrableModule(
isolate_, data_->transferrable_modules().at(transfer_id));
}
return MaybeLocal<WasmCompiledModule>();
}
private: private:
Isolate* isolate_; Isolate* isolate_;
ValueDeserializer deserializer_; ValueDeserializer deserializer_;
......
...@@ -177,7 +177,10 @@ class SerializationData { ...@@ -177,7 +177,10 @@ class SerializationData {
shared_array_buffer_contents() { shared_array_buffer_contents() {
return shared_array_buffer_contents_; return shared_array_buffer_contents_;
} }
const std::vector<WasmCompiledModule::TransferrableModule>&
transferrable_modules() {
return transferrable_modules_;
}
private: private:
struct DataDeleter { struct DataDeleter {
...@@ -188,6 +191,7 @@ class SerializationData { ...@@ -188,6 +191,7 @@ class SerializationData {
size_t size_; size_t size_;
std::vector<ArrayBuffer::Contents> array_buffer_contents_; std::vector<ArrayBuffer::Contents> array_buffer_contents_;
std::vector<SharedArrayBuffer::Contents> shared_array_buffer_contents_; std::vector<SharedArrayBuffer::Contents> shared_array_buffer_contents_;
std::vector<WasmCompiledModule::TransferrableModule> transferrable_modules_;
private: private:
friend class Serializer; friend class Serializer;
......
...@@ -18481,6 +18481,12 @@ void JSArrayBuffer::Neuter() { ...@@ -18481,6 +18481,12 @@ void JSArrayBuffer::Neuter() {
} }
} }
void JSArrayBuffer::StopTrackingWasmMemory(Isolate* isolate) {
DCHECK(is_wasm_memory());
isolate->wasm_engine()->memory_tracker()->ReleaseAllocation(backing_store());
set_is_wasm_memory(false);
}
void JSArrayBuffer::FreeBackingStoreFromMainThread() { void JSArrayBuffer::FreeBackingStoreFromMainThread() {
if (allocation_base() == nullptr) { if (allocation_base() == nullptr) {
return; return;
......
...@@ -196,6 +196,10 @@ class JSArrayBuffer : public JSObject { ...@@ -196,6 +196,10 @@ class JSArrayBuffer : public JSObject {
// Sets whether the buffer is tracked by the WasmMemoryTracker. // Sets whether the buffer is tracked by the WasmMemoryTracker.
void set_is_wasm_memory(bool is_wasm_memory); void set_is_wasm_memory(bool is_wasm_memory);
// Removes the backing store from the WasmMemoryTracker and sets
// |is_wasm_memory| to false.
void StopTrackingWasmMemory(Isolate* isolate);
void FreeBackingStoreFromMainThread(); void FreeBackingStoreFromMainThread();
static void FreeBackingStore(Isolate* isolate, Allocation allocation); static void FreeBackingStore(Isolate* isolate, Allocation allocation);
......
...@@ -67,3 +67,19 @@ let workerHelpers = ...@@ -67,3 +67,19 @@ let workerHelpers =
assertEquals("OK", worker.getMessage()); assertEquals("OK", worker.getMessage());
worker.terminate(); worker.terminate();
})(); })();
(function TestTwoWorkers() {
let workerScript = workerHelpers +
`onmessage = function(memory) {
assertIsWasmMemory(memory, 65536);
postMessage("OK");
};`;
let workers = [new Worker(workerScript), new Worker(workerScript)];
let memory = new WebAssembly.Memory({initial: 1, maximum: 2, shared: true});
for (let worker of workers) {
worker.postMessage(memory);
assertEquals("OK", worker.getMessage());
worker.terminate();
}
})();
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --no-wasm-disable-structured-cloning
load("test/mjsunit/wasm/wasm-constants.js");
load("test/mjsunit/wasm/wasm-module-builder.js");
function TestCloneModule() {
let builder = new WasmModuleBuilder();
builder.addFunction("add", kSig_i_ii)
.addBody([kExprGetLocal, 0, kExprGetLocal, 1, kExprI32Add])
.exportFunc();
let module = builder.toModule();
let workerScript = `
onmessage = function(module) {
try {
let instance = new WebAssembly.Instance(module);
let result = instance.exports.add(40, 2);
postMessage(result);
} catch(e) {
postMessage('ERROR: ' + e);
}
}
`;
let worker = new Worker(workerScript);
worker.postMessage(module);
assertEquals(42, worker.getMessage());
worker.terminate();
}
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