Commit 359a00bf authored by machenbach's avatar machenbach Committed by Commit bot

Revert of [wasm] reuse the first compiled module (patchset #12 id:220001 of...

Revert of [wasm] reuse the first compiled module (patchset #12 id:220001 of https://codereview.chromium.org/2305903002/ )

Reason for revert:
mac gc stress failures:
https://build.chromium.org/p/client.v8/builders/V8%20Mac%20GC%20Stress/builds/8341

Original issue's description:
> [wasm] reuse the first compiled module.
>
> 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
>
> Committed: https://crrev.com/01f5af515728aebe6c5246f4f7dd6c573e8748af
> Cr-Commit-Position: refs/heads/master@{#39153}

TBR=bradnelson@chromium.org,verwaest@chromium.org,vogelheim@chromium.org,yangguo@chromium.org,mtrofin@chromium.org
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=v8:5316

Review-Url: https://codereview.chromium.org/2306403002
Cr-Commit-Position: refs/heads/master@{#39154}
parent 01f5af51
......@@ -773,31 +773,5 @@ RUNTIME_FUNCTION(Runtime_DeserializeWasmModule) {
wasm::ModuleOrigin::kWasmOrigin);
}
RUNTIME_FUNCTION(Runtime_ValidateWasmInstancesChain) {
HandleScope shs(isolate);
DCHECK(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSObject, module_obj, 0);
CONVERT_ARG_HANDLE_CHECKED(Smi, instance_count, 1);
wasm::testing::ValidateInstancesChain(isolate, module_obj,
instance_count->value());
return isolate->heap()->ToBoolean(true);
}
RUNTIME_FUNCTION(Runtime_ValidateWasmModuleState) {
HandleScope shs(isolate);
DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSObject, module_obj, 0);
wasm::testing::ValidateModuleState(isolate, module_obj);
return isolate->heap()->ToBoolean(true);
}
RUNTIME_FUNCTION(Runtime_ValidateWasmOrphanedInstance) {
HandleScope shs(isolate);
DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSObject, instance_obj, 0);
wasm::testing::ValidateOrphanedInstance(isolate, instance_obj);
return isolate->heap()->ToBoolean(true);
}
} // namespace internal
} // namespace v8
......@@ -18,12 +18,16 @@
namespace v8 {
namespace internal {
namespace {
const int kWasmMemArrayBuffer = 2;
}
RUNTIME_FUNCTION(Runtime_WasmGrowMemory) {
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
uint32_t delta_pages = 0;
CHECK(args[0]->ToUint32(&delta_pages));
Handle<JSObject> module_instance;
Handle<JSObject> module_object;
{
// Get the module JSObject
......@@ -37,17 +41,17 @@ RUNTIME_FUNCTION(Runtime_WasmGrowMemory) {
Object* owning_instance = wasm::GetOwningWasmInstance(undefined, code);
CHECK_NOT_NULL(owning_instance);
CHECK_NE(owning_instance, undefined);
module_instance = handle(JSObject::cast(owning_instance), isolate);
module_object = handle(JSObject::cast(owning_instance), isolate);
}
Address old_mem_start, new_mem_start;
uint32_t old_size, new_size;
// Get mem buffer associated with module object
MaybeHandle<JSArrayBuffer> maybe_mem_buffer =
wasm::GetInstanceMemory(isolate, module_instance);
Handle<JSArrayBuffer> old_buffer;
if (!maybe_mem_buffer.ToHandle(&old_buffer)) {
Handle<Object> obj(module_object->GetInternalField(kWasmMemArrayBuffer),
isolate);
if (obj->IsUndefined(isolate)) {
// If module object does not have linear memory associated with it,
// Allocate new array buffer of given size.
old_mem_start = nullptr;
......@@ -69,6 +73,7 @@ RUNTIME_FUNCTION(Runtime_WasmGrowMemory) {
}
#endif
} else {
Handle<JSArrayBuffer> old_buffer = Handle<JSArrayBuffer>::cast(obj);
old_mem_start = static_cast<Address>(old_buffer->backing_store());
old_size = old_buffer->byte_length()->Number();
// If the old memory was zero-sized, we should have been in the
......@@ -96,10 +101,9 @@ RUNTIME_FUNCTION(Runtime_WasmGrowMemory) {
buffer->set_is_neuterable(false);
// Set new buffer to be wasm memory
module_object->SetInternalField(kWasmMemArrayBuffer, *buffer);
wasm::SetInstanceMemory(module_instance, *buffer);
CHECK(wasm::UpdateWasmModuleMemory(module_instance, old_mem_start,
CHECK(wasm::UpdateWasmModuleMemory(module_object, old_mem_start,
new_mem_start, old_size, new_size));
return *isolate->factory()->NewNumberFromInt(old_size /
......
......@@ -887,10 +887,7 @@ namespace internal {
F(SerializeWasmModule, 1, 1) \
F(DeserializeWasmModule, 1, 1) \
F(IsAsmWasmCode, 1, 1) \
F(IsNotAsmWasmCode, 1, 1) \
F(ValidateWasmInstancesChain, 2, 1) \
F(ValidateWasmModuleState, 1, 1) \
F(ValidateWasmOrphanedInstance, 1, 1)
F(IsNotAsmWasmCode, 1, 1)
#define FOR_EACH_INTRINSIC_TYPEDARRAY(F) \
F(ArrayBufferGetByteLength, 1, 1) \
......
......@@ -98,10 +98,6 @@ void CodeSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code,
UNREACHABLE();
}
if (SkipOver(obj)) {
return SerializeObject(*isolate()->factory()->undefined_value(),
how_to_code, where_to_point, skip);
}
// Past this point we should not see any (context-specific) maps anymore.
CHECK(!obj->IsMap());
// There should be no references to the global object embedded.
......
......@@ -36,7 +36,6 @@ class CodeSerializer : public Serializer {
UNREACHABLE();
}
virtual bool SkipOver(Object* obj) { return false; }
void SerializeGeneric(HeapObject* heap_object, HowToCode how_to_code,
WhereToPoint where_to_point);
......@@ -74,8 +73,6 @@ class WasmCompiledModuleSerializer : public CodeSerializer {
}
}
bool SkipOver(Object* obj) override { return obj->IsWeakCell(); };
private:
WasmCompiledModuleSerializer(Isolate* isolate, uint32_t source_hash)
: CodeSerializer(isolate, source_hash) {}
......
This diff is collapsed.
......@@ -415,10 +415,6 @@ MaybeHandle<JSObject> CreateModuleObjectFromBytes(Isolate* isolate,
// was collected, or the instance object owning the Code object
Object* GetOwningWasmInstance(Object* undefined, Code* code);
MaybeHandle<JSArrayBuffer> GetInstanceMemory(Isolate* isolate,
Handle<JSObject> instance);
void SetInstanceMemory(Handle<JSObject> instance, JSArrayBuffer* buffer);
namespace testing {
// Decode, verify, and run the function labeled "main" in the
......@@ -429,12 +425,6 @@ int32_t CompileAndRunWasmModule(Isolate* isolate, const byte* module_start,
int32_t CallFunction(Isolate* isolate, Handle<JSObject> instance,
ErrorThrower* thrower, const char* name, int argc,
Handle<Object> argv[], bool asm_js = false);
void ValidateInstancesChain(Isolate* isolate, Handle<JSObject> module_obj,
int instance_count);
void ValidateModuleState(Isolate* isolate, Handle<JSObject> module_obj);
void ValidateOrphanedInstance(Isolate* isolate, Handle<JSObject> instance);
} // namespace testing
} // namespace wasm
} // namespace internal
......
// 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);
})();
......@@ -155,50 +155,24 @@ promise.then(module => CheckInstance(new WebAssembly.Instance(module)));
})();
(function GlobalsArePrivateToTheInstance() {
var builder = new WasmModuleBuilder();
builder.addGlobal(kAstI32);
builder.addFunction("read", kSig_i_v)
.addBody([
kExprGetGlobal, 0])
.exportFunc();
builder.addFunction("write", kSig_v_i)
.addBody([
kExprGetLocal, 0,
kExprSetGlobal, 0])
.exportFunc();
var module = new WebAssembly.Module(builder.toBuffer());
var i1 = new WebAssembly.Instance(module);
var i2 = new WebAssembly.Instance(module);
i1.exports.write(1);
i2.exports.write(2);
assertEquals(1, i1.exports.read());
assertEquals(2, i2.exports.read());
})();
(function InstanceMemoryIsIsolated() {
var builder = new WasmModuleBuilder();
builder.addMemory(1,1, true);
builder.addFunction("f", kSig_i)
builder.addGlobal(kAstI32);
builder.addFunction("read", kSig_i_v)
.addBody([
kExprI32Const, 0,
kExprI32LoadMem, 0, 0
]).exportFunc();
kExprGetGlobal, 0])
.exportFunc();
var mem_1 = new ArrayBuffer(65536);
var mem_2 = new ArrayBuffer(65536);
var view_1 = new Int32Array(mem_1);
var view_2 = new Int32Array(mem_2);
view_1[0] = 1;
view_2[0] = 1000;
builder.addFunction("write", kSig_v_i)
.addBody([
kExprGetLocal, 0,
kExprSetGlobal, 0])
.exportFunc();
var module = new WebAssembly.Module(builder.toBuffer());
var i1 = new WebAssembly.Instance(module, null, mem_1);
var i2 = new WebAssembly.Instance(module, null, mem_2);
assertEquals(1, i1.exports.f());
assertEquals(1000, i2.exports.f());
var i1 = new WebAssembly.Instance(module);
var i2 = new WebAssembly.Instance(module);
i1.exports.write(1);
i2.exports.write(2);
assertEquals(1, i1.exports.read());
assertEquals(2, i2.exports.read());
})();
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