[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/1117871 Reviewed-by: Michael Starzinger <mstarzinger@chromium.org> Commit-Queue: Ben Smith <binji@chromium.org> Cr-Commit-Position: refs/heads/master@{#54093}
This commit is contained in:
parent
63372e4679
commit
c9b4f805a3
@ -7664,8 +7664,7 @@ v8::ArrayBuffer::Contents v8::ArrayBuffer::Externalize() {
|
||||
// longer track it.
|
||||
//
|
||||
// TODO(eholk): Find a way to track this across externalization
|
||||
isolate->wasm_engine()->memory_tracker()->ReleaseAllocation(
|
||||
self->backing_store());
|
||||
self->StopTrackingWasmMemory(isolate);
|
||||
}
|
||||
isolate->heap()->UnregisterArrayBuffer(*self);
|
||||
|
||||
@ -7899,8 +7898,7 @@ v8::SharedArrayBuffer::Contents v8::SharedArrayBuffer::Externalize() {
|
||||
// longer track it.
|
||||
//
|
||||
// TODO(eholk): Find a way to track this across externalization
|
||||
isolate->wasm_engine()->memory_tracker()->ReleaseAllocation(
|
||||
self->backing_store());
|
||||
self->StopTrackingWasmMemory(isolate);
|
||||
}
|
||||
isolate->heap()->UnregisterArrayBuffer(*self);
|
||||
|
||||
|
26
src/d8.cc
26
src/d8.cc
@ -3075,6 +3075,21 @@ class Serializer : public ValueSerializer::Delegate {
|
||||
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,
|
||||
size_t* actual_size) override {
|
||||
// Not accurate, because we don't take into account reallocated buffers,
|
||||
@ -3152,6 +3167,7 @@ class Serializer : public ValueSerializer::Delegate {
|
||||
std::unique_ptr<SerializationData> data_;
|
||||
std::vector<Global<ArrayBuffer>> array_buffers_;
|
||||
std::vector<Global<SharedArrayBuffer>> shared_array_buffers_;
|
||||
std::vector<Global<WasmCompiledModule>> wasm_modules_;
|
||||
std::vector<ExternalizedContents> externalized_contents_;
|
||||
size_t current_memory_usage_;
|
||||
|
||||
@ -3195,6 +3211,16 @@ class Deserializer : public ValueDeserializer::Delegate {
|
||||
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:
|
||||
Isolate* isolate_;
|
||||
ValueDeserializer deserializer_;
|
||||
|
6
src/d8.h
6
src/d8.h
@ -177,7 +177,10 @@ class SerializationData {
|
||||
shared_array_buffer_contents() {
|
||||
return shared_array_buffer_contents_;
|
||||
}
|
||||
|
||||
const std::vector<WasmCompiledModule::TransferrableModule>&
|
||||
transferrable_modules() {
|
||||
return transferrable_modules_;
|
||||
}
|
||||
|
||||
private:
|
||||
struct DataDeleter {
|
||||
@ -188,6 +191,7 @@ class SerializationData {
|
||||
size_t size_;
|
||||
std::vector<ArrayBuffer::Contents> array_buffer_contents_;
|
||||
std::vector<SharedArrayBuffer::Contents> shared_array_buffer_contents_;
|
||||
std::vector<WasmCompiledModule::TransferrableModule> transferrable_modules_;
|
||||
|
||||
private:
|
||||
friend class Serializer;
|
||||
|
@ -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() {
|
||||
if (allocation_base() == nullptr) {
|
||||
return;
|
||||
|
@ -196,6 +196,10 @@ class JSArrayBuffer : public JSObject {
|
||||
// Sets whether the buffer is tracked by the WasmMemoryTracker.
|
||||
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();
|
||||
static void FreeBackingStore(Isolate* isolate, Allocation allocation);
|
||||
|
||||
|
@ -67,3 +67,19 @@ let workerHelpers =
|
||||
assertEquals("OK", worker.getMessage());
|
||||
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();
|
||||
}
|
||||
})();
|
||||
|
34
test/mjsunit/wasm/worker-module.js
Normal file
34
test/mjsunit/wasm/worker-module.js
Normal file
@ -0,0 +1,34 @@
|
||||
// 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();
|
||||
}
|
Loading…
Reference in New Issue
Block a user