01f5af5157
This change avoids needing to keep around an unused compiled module. Instead, the result of compiling the wasm bytes is given to the first instance. The module object and that instance object point to the same compiled module. Instances are, then, cloned from the compiled module the module object points to. When an instance is collected, we make sure that the module object still has a clone available, and, if the last instance is GC-ed, we also reset the compiled module so that it does not reference its heap, so that it (==heap) may be collected. This is achieved by linking the clones in a double-linked list and registering a finalizer for each. When we create an instance, we tie it in the front of the list, making the module object point to it (O(1)). When the finalizer is called, we relink the list over the dying object (O(1)). The costliest operation is finalizing the last instance, since we need to visit all wasm functions and reset heap references. BUG=v8:5316 Review-Url: https://codereview.chromium.org/2305903002 Cr-Commit-Position: refs/heads/master@{#39153}
51 lines
1.6 KiB
JavaScript
51 lines
1.6 KiB
JavaScript
// Copyright 2016 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.
|
|
|
|
// TODO (mtrofin): re-enable ignition (v8:5345)
|
|
// Flags: --no-ignition --no-ignition-staging
|
|
// Flags: --expose-wasm --expose-gc --allow-natives-syntax
|
|
|
|
load("test/mjsunit/wasm/wasm-constants.js");
|
|
load("test/mjsunit/wasm/wasm-module-builder.js");
|
|
|
|
|
|
(function CompiledModuleInstancesAreGCed() {
|
|
var builder = new WasmModuleBuilder();
|
|
|
|
builder.addMemory(1,1, true);
|
|
builder.addImport("getValue", kSig_i);
|
|
builder.addFunction("f", kSig_i)
|
|
.addBody([
|
|
kExprCallImport, kArity0, 0
|
|
]).exportFunc();
|
|
|
|
var module = new WebAssembly.Module(builder.toBuffer());
|
|
%ValidateWasmModuleState(module);
|
|
%ValidateWasmInstancesChain(module, 0);
|
|
var i1 = new WebAssembly.Instance(module, {getValue: () => 1});
|
|
%ValidateWasmInstancesChain(module, 1);
|
|
var i2 = new WebAssembly.Instance(module, {getValue: () => 2});
|
|
%ValidateWasmInstancesChain(module, 2);
|
|
var i3 = new WebAssembly.Instance(module, {getValue: () => 3});
|
|
%ValidateWasmInstancesChain(module, 3);
|
|
|
|
assertEquals(1, i1.exports.f());
|
|
i1 = null;
|
|
gc();
|
|
%ValidateWasmInstancesChain(module, 2);
|
|
assertEquals(3, i3.exports.f());
|
|
i3 = null;
|
|
gc();
|
|
%ValidateWasmInstancesChain(module, 1);
|
|
assertEquals(2, i2.exports.f());
|
|
i2 = null;
|
|
gc();
|
|
%ValidateWasmModuleState(module);
|
|
var i4 = new WebAssembly.Instance(module, {getValue: () => 4});
|
|
assertEquals(4, i4.exports.f());
|
|
module = null;
|
|
gc();
|
|
%ValidateWasmOrphanedInstance(i4);
|
|
})();
|