[wasm] consolidate wasm and asm.js module compilation sequence

This unblocks avoiding the separate code template.
In the upcoming CL doing away with code templates, We need to track instances
through the module object, which needs to be separate from the compiled module
data, which is then shared with the first instance.

This CL ensures we have the object available in the asm.js scenario, too.

Note that this CL also unifies the error messaging when module
decoding fails.

BUG=v8:5316

Review-Url: https://codereview.chromium.org/2299873002
Cr-Commit-Position: refs/heads/master@{#39097}
This commit is contained in:
mtrofin 2016-09-01 09:47:15 -07:00 committed by Commit bot
parent f93ee70c88
commit 5f8a6ec4b1
7 changed files with 64 additions and 54 deletions

View File

@ -7040,8 +7040,9 @@ MaybeLocal<WasmCompiledModule> WasmCompiledModule::Deserialize(
if (!maybe_compiled_part.ToHandle(&compiled_part)) {
return MaybeLocal<WasmCompiledModule>();
}
return Local<WasmCompiledModule>::Cast(Utils::ToLocal(
i::wasm::CreateCompiledModuleObject(i_isolate, compiled_part)));
return Local<WasmCompiledModule>::Cast(
Utils::ToLocal(i::wasm::CreateCompiledModuleObject(
i_isolate, compiled_part, i::wasm::ModuleOrigin::kWasmOrigin)));
}
// static

View File

@ -30,29 +30,6 @@ namespace v8 {
namespace internal {
namespace {
i::MaybeHandle<i::FixedArray> CompileModule(
i::Isolate* isolate, const byte* start, const byte* end,
ErrorThrower* thrower,
internal::wasm::ModuleOrigin origin = i::wasm::kWasmOrigin) {
// Decode but avoid a redundant pass over function bodies for verification.
// Verification will happen during compilation.
i::Zone zone(isolate->allocator());
internal::wasm::ModuleResult result = internal::wasm::DecodeWasmModule(
isolate, &zone, start, end, false, origin);
i::MaybeHandle<i::FixedArray> compiled_module;
if (result.failed() && origin == internal::wasm::kAsmJsOrigin) {
thrower->Error("Asm.js converted module failed to decode");
} else if (result.failed()) {
thrower->Failed("", result);
} else {
compiled_module = result.val->CompileFunctions(isolate, thrower);
}
if (result.val) delete result.val;
return compiled_module;
}
Handle<i::Object> StdlibMathMember(i::Isolate* isolate,
Handle<JSReceiver> stdlib,
Handle<Name> name) {
@ -187,9 +164,9 @@ MaybeHandle<FixedArray> AsmJs::ConvertAsmToWasm(ParseInfo* info) {
i::Handle<i::FixedArray> foreign_globals;
auto module = builder.Run(&foreign_globals);
i::MaybeHandle<i::FixedArray> compiled =
CompileModule(info->isolate(), module->begin(), module->end(), &thrower,
internal::wasm::kAsmJsOrigin);
i::MaybeHandle<i::JSObject> compiled = wasm::CreateModuleObjectFromBytes(
info->isolate(), module->begin(), module->end(), &thrower,
internal::wasm::kAsmJsOrigin);
DCHECK(!compiled.is_null());
wasm::AsmTyper::StdlibSet uses = typer.StdlibUses();
@ -223,7 +200,9 @@ MaybeHandle<Object> AsmJs::InstantiateAsmWasm(i::Isolate* isolate,
Handle<FixedArray> wasm_data,
Handle<JSArrayBuffer> memory,
Handle<JSReceiver> foreign) {
i::Handle<i::FixedArray> compiled(i::FixedArray::cast(wasm_data->get(0)));
i::Handle<i::JSObject> module(i::JSObject::cast(wasm_data->get(0)));
i::Handle<i::FixedArray> compiled(
i::FixedArray::cast(module->GetInternalField(0)));
i::Handle<i::FixedArray> foreign_globals(
i::FixedArray::cast(wasm_data->get(1)));

View File

@ -769,7 +769,8 @@ RUNTIME_FUNCTION(Runtime_DeserializeWasmModule) {
if (!maybe_compiled_module.ToHandle(&compiled_module)) {
return isolate->heap()->undefined_value();
}
return *wasm::CreateCompiledModuleObject(isolate, compiled_module);
return *wasm::CreateCompiledModuleObject(isolate, compiled_module,
wasm::ModuleOrigin::kWasmOrigin);
}
} // namespace internal

View File

@ -195,20 +195,9 @@ static i::MaybeHandle<i::JSObject> CreateModuleObject(
if (buffer.start == nullptr) return i::MaybeHandle<i::JSObject>();
DCHECK(source->IsArrayBuffer() || source->IsTypedArray());
i::Zone zone(i_isolate->allocator());
i::wasm::ModuleResult result = i::wasm::DecodeWasmModule(
i_isolate, &zone, buffer.start, buffer.end, false, i::wasm::kWasmOrigin);
std::unique_ptr<const i::wasm::WasmModule> decoded_module(result.val);
if (result.failed()) {
thrower->Failed("", result);
return nothing;
}
i::MaybeHandle<i::FixedArray> compiled_module =
decoded_module->CompileFunctions(i_isolate, thrower);
if (compiled_module.is_null()) return nothing;
return i::wasm::CreateCompiledModuleObject(i_isolate,
compiled_module.ToHandleChecked());
return i::wasm::CreateModuleObjectFromBytes(
i_isolate, buffer.start, buffer.end, thrower,
i::wasm::ModuleOrigin::kWasmOrigin);
}
void WebAssemblyCompile(const v8::FunctionCallbackInfo<v8::Value>& args) {

View File

@ -1629,17 +1629,50 @@ int GetNumberOfFunctions(JSObject* wasm) {
return ByteArray::cast(func_names_obj)->get_int(0);
}
Handle<JSObject> CreateCompiledModuleObject(
Isolate* isolate, Handle<FixedArray> compiled_module) {
Handle<JSFunction> module_cons(
isolate->native_context()->wasm_module_constructor());
Handle<JSObject> module_obj = isolate->factory()->NewJSObject(module_cons);
Handle<JSObject> CreateCompiledModuleObject(Isolate* isolate,
Handle<FixedArray> compiled_module,
ModuleOrigin origin) {
Handle<JSObject> module_obj;
if (origin == ModuleOrigin::kWasmOrigin) {
Handle<JSFunction> module_cons(
isolate->native_context()->wasm_module_constructor());
module_obj = isolate->factory()->NewJSObject(module_cons);
} else {
DCHECK(origin == ModuleOrigin::kAsmJsOrigin);
Handle<Map> map = isolate->factory()->NewMap(
JS_OBJECT_TYPE, JSObject::kHeaderSize + kPointerSize);
module_obj = isolate->factory()->NewJSObjectFromMap(map, TENURED);
}
module_obj->SetInternalField(0, *compiled_module);
Handle<Symbol> module_sym(isolate->native_context()->wasm_module_sym());
Object::SetProperty(module_obj, module_sym, module_obj, STRICT).Check();
if (origin == ModuleOrigin::kWasmOrigin) {
Handle<Symbol> module_sym(isolate->native_context()->wasm_module_sym());
Object::SetProperty(module_obj, module_sym, module_obj, STRICT).Check();
}
return module_obj;
}
MaybeHandle<JSObject> CreateModuleObjectFromBytes(Isolate* isolate,
const byte* start,
const byte* end,
ErrorThrower* thrower,
ModuleOrigin origin) {
MaybeHandle<JSObject> nothing;
Zone zone(isolate->allocator());
ModuleResult result =
DecodeWasmModule(isolate, &zone, start, end, false, origin);
std::unique_ptr<const WasmModule> decoded_module(result.val);
if (result.failed()) {
thrower->Failed("Wasm decoding failed", result);
return nothing;
}
MaybeHandle<FixedArray> compiled_module =
decoded_module->CompileFunctions(isolate, thrower);
if (compiled_module.is_null()) return nothing;
return CreateCompiledModuleObject(isolate, compiled_module.ToHandleChecked(),
origin);
}
namespace testing {
int32_t CompileAndRunWasmModule(Isolate* isolate, const byte* module_start,

View File

@ -399,7 +399,14 @@ void PopulateFunctionTable(Handle<FixedArray> table, uint32_t table_size,
const std::vector<Handle<Code>>* code_table);
Handle<JSObject> CreateCompiledModuleObject(Isolate* isolate,
Handle<FixedArray> compiled_module);
Handle<FixedArray> compiled_module,
ModuleOrigin origin);
MaybeHandle<JSObject> CreateModuleObjectFromBytes(Isolate* isolate,
const byte* start,
const byte* end,
ErrorThrower* thrower,
ModuleOrigin origin);
// Assumed to be called with a code object associated to a wasm module instance.
// Intended to be called from runtime functions.

View File

@ -215,8 +215,8 @@ TEST(Run_WasmModule_Serialization) {
MaybeHandle<FixedArray> compiled_module =
module->CompileFunctions(isolate, &thrower);
CHECK(!compiled_module.is_null());
Handle<JSObject> module_obj =
CreateCompiledModuleObject(isolate, compiled_module.ToHandleChecked());
Handle<JSObject> module_obj = CreateCompiledModuleObject(
isolate, compiled_module.ToHandleChecked(), ModuleOrigin::kWasmOrigin);
v8::Local<v8::Object> v8_module_obj = v8::Utils::ToLocal(module_obj);
CHECK(v8_module_obj->IsWebAssemblyCompiledModule());