Commit 7b775118 authored by bradnelson's avatar bradnelson Committed by Commit bot

Turn on wasm flags all the time, add a reference from wasm functions to the module.

Add an internal field to each wasm function to keep a reference to the module. (So the GC can do the right thing when you only hold references to wasm functions but not the module).

Use Realloc carefully, to avoid copying from out of bounds.

Make snprintf use platform independent.

Don't disconnect external arraybuffers provided for the heap.

R=ahaas@chromium.org
BUG=

Review URL: https://codereview.chromium.org/1531243003

Cr-Commit-Position: refs/heads/master@{#32951}
parent a1e6bee6
...@@ -269,8 +269,9 @@ class CompilationInfo { ...@@ -269,8 +269,9 @@ class CompilationInfo {
bool is_first_compile() const { return GetFlag(kFirstCompile); } bool is_first_compile() const { return GetFlag(kFirstCompile); }
bool IsCodePreAgingActive() const { bool IsCodePreAgingActive() const {
// TODO(bradnelson): Figure out why this breaks wasm.
return FLAG_optimize_for_size && FLAG_age_code && !will_serialize() && return FLAG_optimize_for_size && FLAG_age_code && !will_serialize() &&
!is_debug(); !is_debug() && !FLAG_expose_wasm;
} }
void EnsureFeedbackVector(); void EnsureFeedbackVector();
......
...@@ -2,6 +2,11 @@ ...@@ -2,6 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "src/compiler/wasm-compiler.h"
#include "src/isolate-inl.h"
#include "src/base/platform/platform.h"
#include "src/compiler/access-builder.h" #include "src/compiler/access-builder.h"
#include "src/compiler/change-lowering.h" #include "src/compiler/change-lowering.h"
...@@ -21,7 +26,6 @@ ...@@ -21,7 +26,6 @@
#include "src/compiler/simplified-operator.h" #include "src/compiler/simplified-operator.h"
#include "src/compiler/source-position.h" #include "src/compiler/source-position.h"
#include "src/compiler/typer.h" #include "src/compiler/typer.h"
#include "src/compiler/wasm-compiler.h"
#include "src/code-factory.h" #include "src/code-factory.h"
#include "src/code-stubs.h" #include "src/code-stubs.h"
...@@ -340,7 +344,8 @@ Node* WasmGraphBuilder::Merge(unsigned count, Node** controls) { ...@@ -340,7 +344,8 @@ Node* WasmGraphBuilder::Merge(unsigned count, Node** controls) {
Node* WasmGraphBuilder::Phi(wasm::LocalType type, unsigned count, Node** vals, Node* WasmGraphBuilder::Phi(wasm::LocalType type, unsigned count, Node** vals,
Node* control) { Node* control) {
DCHECK(IrOpcode::IsMergeOpcode(control->opcode())); DCHECK(IrOpcode::IsMergeOpcode(control->opcode()));
Node** buf = Realloc(vals, count + 1); Node** buf = Realloc(vals, count);
buf = Realloc(buf, count + 1);
buf[count] = control; buf[count] = control;
return graph()->NewNode(jsgraph()->common()->Phi(type, count), count + 1, return graph()->NewNode(jsgraph()->common()->Phi(type, count), count + 1,
buf); buf);
...@@ -350,7 +355,8 @@ Node* WasmGraphBuilder::Phi(wasm::LocalType type, unsigned count, Node** vals, ...@@ -350,7 +355,8 @@ Node* WasmGraphBuilder::Phi(wasm::LocalType type, unsigned count, Node** vals,
Node* WasmGraphBuilder::EffectPhi(unsigned count, Node** effects, Node* WasmGraphBuilder::EffectPhi(unsigned count, Node** effects,
Node* control) { Node* control) {
DCHECK(IrOpcode::IsMergeOpcode(control->opcode())); DCHECK(IrOpcode::IsMergeOpcode(control->opcode()));
Node** buf = Realloc(effects, count + 1); Node** buf = Realloc(effects, count);
buf = Realloc(buf, count + 1);
buf[count] = control; buf[count] = control;
return graph()->NewNode(jsgraph()->common()->EffectPhi(count), count + 1, return graph()->NewNode(jsgraph()->common()->EffectPhi(count), count + 1,
buf); buf);
...@@ -959,7 +965,8 @@ Node* WasmGraphBuilder::Return(unsigned count, Node** vals) { ...@@ -959,7 +965,8 @@ Node* WasmGraphBuilder::Return(unsigned count, Node** vals) {
count = 1; count = 1;
} }
Node** buf = Realloc(vals, count + 2); Node** buf = Realloc(vals, count);
buf = Realloc(buf, count + 2);
buf[count] = *effect_; buf[count] = *effect_;
buf[count + 1] = *control_; buf[count + 1] = *control_;
Node* ret = graph()->NewNode(jsgraph()->common()->Return(), count + 2, vals); Node* ret = graph()->NewNode(jsgraph()->common()->Return(), count + 2, vals);
...@@ -1624,7 +1631,8 @@ void WasmGraphBuilder::BoundsCheckMem(MachineType memtype, Node* index, ...@@ -1624,7 +1631,8 @@ void WasmGraphBuilder::BoundsCheckMem(MachineType memtype, Node* index,
ptrdiff_t size = module_->mem_end - module_->mem_start; ptrdiff_t size = module_->mem_end - module_->mem_start;
byte memsize = wasm::WasmOpcodes::MemSize(memtype); byte memsize = wasm::WasmOpcodes::MemSize(memtype);
Node* cond; Node* cond;
if (offset >= size || (offset + memsize) > size) { if (static_cast<ptrdiff_t>(offset) >= size ||
static_cast<ptrdiff_t>(offset + memsize) > size) {
// The access will always throw. // The access will always throw.
cond = jsgraph()->Int32Constant(0); cond = jsgraph()->Int32Constant(0);
} else { } else {
...@@ -1713,11 +1721,9 @@ Node* WasmGraphBuilder::String(const char* string) { ...@@ -1713,11 +1721,9 @@ Node* WasmGraphBuilder::String(const char* string) {
Graph* WasmGraphBuilder::graph() { return jsgraph()->graph(); } Graph* WasmGraphBuilder::graph() { return jsgraph()->graph(); }
Handle<JSFunction> CompileJSToWasmWrapper(Isolate* isolate, Handle<JSFunction> CompileJSToWasmWrapper(
wasm::ModuleEnv* module, Isolate* isolate, wasm::ModuleEnv* module, Handle<String> name,
Handle<String> name, Handle<Code> wasm_code, Handle<JSObject> module_object, uint32_t index) {
Handle<Code> wasm_code,
uint32_t index) {
wasm::WasmFunction* func = &module->module->functions->at(index); wasm::WasmFunction* func = &module->module->functions->at(index);
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
...@@ -1728,7 +1734,9 @@ Handle<JSFunction> CompileJSToWasmWrapper(Isolate* isolate, ...@@ -1728,7 +1734,9 @@ Handle<JSFunction> CompileJSToWasmWrapper(Isolate* isolate,
int params = static_cast<int>(func->sig->parameter_count()); int params = static_cast<int>(func->sig->parameter_count());
shared->set_length(params); shared->set_length(params);
shared->set_internal_formal_parameter_count(1 + params); shared->set_internal_formal_parameter_count(1 + params);
Handle<JSFunction> function = isolate->factory()->NewFunction(name); Handle<JSFunction> function = isolate->factory()->NewFunction(
isolate->wasm_function_map(), name, MaybeHandle<Code>());
function->SetInternalField(0, *module_object);
function->set_shared(*shared); function->set_shared(*shared);
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
...@@ -1788,17 +1796,15 @@ Handle<JSFunction> CompileJSToWasmWrapper(Isolate* isolate, ...@@ -1788,17 +1796,15 @@ Handle<JSFunction> CompileJSToWasmWrapper(Isolate* isolate,
#ifdef ENABLE_DISASSEMBLER #ifdef ENABLE_DISASSEMBLER
// Disassemble the wrapper code for debugging. // Disassemble the wrapper code for debugging.
if (!code.is_null() && FLAG_print_opt_code) { if (!code.is_null() && FLAG_print_opt_code) {
static const int kBufferSize = 128; Vector<char> buffer;
char buffer[kBufferSize];
const char* name = ""; const char* name = "";
if (func->name_offset > 0) { if (func->name_offset > 0) {
const byte* ptr = module->module->module_start + func->name_offset; const byte* ptr = module->module->module_start + func->name_offset;
name = reinterpret_cast<const char*>(ptr); name = reinterpret_cast<const char*>(ptr);
} }
snprintf(buffer, kBufferSize, "JS->WASM function wrapper #%d:%s", index, SNPrintF(buffer, "JS->WASM function wrapper #%d:%s", index, name);
name);
OFStream os(stdout); OFStream os(stdout);
code->Disassemble(buffer, os); code->Disassemble(buffer.start(), os);
} }
#endif #endif
// Set the JSFunction's machine code. // Set the JSFunction's machine code.
...@@ -1864,17 +1870,15 @@ Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, wasm::ModuleEnv* module, ...@@ -1864,17 +1870,15 @@ Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, wasm::ModuleEnv* module,
#ifdef ENABLE_DISASSEMBLER #ifdef ENABLE_DISASSEMBLER
// Disassemble the wrapper code for debugging. // Disassemble the wrapper code for debugging.
if (!code.is_null() && FLAG_print_opt_code) { if (!code.is_null() && FLAG_print_opt_code) {
static const int kBufferSize = 128; Vector<char> buffer;
char buffer[kBufferSize];
const char* name = ""; const char* name = "";
if (func->name_offset > 0) { if (func->name_offset > 0) {
const byte* ptr = module->module->module_start + func->name_offset; const byte* ptr = module->module->module_start + func->name_offset;
name = reinterpret_cast<const char*>(ptr); name = reinterpret_cast<const char*>(ptr);
} }
snprintf(buffer, kBufferSize, "WASM->JS function wrapper #%d:%s", index, SNPrintF(buffer, "WASM->JS function wrapper #%d:%s", index, name);
name);
OFStream os(stdout); OFStream os(stdout);
code->Disassemble(buffer, os); code->Disassemble(buffer.start(), os);
} }
#endif #endif
} }
...@@ -1927,11 +1931,10 @@ Handle<Code> CompileWasmFunction(wasm::ErrorThrower& thrower, Isolate* isolate, ...@@ -1927,11 +1931,10 @@ Handle<Code> CompileWasmFunction(wasm::ErrorThrower& thrower, Isolate* isolate,
os << "Compilation failed: " << result << std::endl; os << "Compilation failed: " << result << std::endl;
} }
// Add the function as another context for the exception // Add the function as another context for the exception
const int kBufSize = 256; Vector<char> buffer;
char buffer[kBufSize]; SNPrintF(buffer, "Compiling WASM function #%d:%s failed:", index,
snprintf(buffer, kBufSize, "Compiling WASM function #%d:%s failed:", index,
module_env->module->GetName(function.name_offset)); module_env->module->GetName(function.name_offset));
thrower.Failed(buffer, result); thrower.Failed(buffer.start(), result);
return Handle<Code>::null(); return Handle<Code>::null();
} }
...@@ -1946,16 +1949,15 @@ Handle<Code> CompileWasmFunction(wasm::ErrorThrower& thrower, Isolate* isolate, ...@@ -1946,16 +1949,15 @@ Handle<Code> CompileWasmFunction(wasm::ErrorThrower& thrower, Isolate* isolate,
#ifdef ENABLE_DISASSEMBLER #ifdef ENABLE_DISASSEMBLER
// Disassemble the code for debugging. // Disassemble the code for debugging.
if (!code.is_null() && FLAG_print_opt_code) { if (!code.is_null() && FLAG_print_opt_code) {
static const int kBufferSize = 128; Vector<char> buffer;
char buffer[kBufferSize];
const char* name = ""; const char* name = "";
if (function.name_offset > 0) { if (function.name_offset > 0) {
const byte* ptr = module_env->module->module_start + function.name_offset; const byte* ptr = module_env->module->module_start + function.name_offset;
name = reinterpret_cast<const char*>(ptr); name = reinterpret_cast<const char*>(ptr);
} }
snprintf(buffer, kBufferSize, "WASM function #%d:%s", index, name); SNPrintF(buffer, "WASM function #%d:%s", index, name);
OFStream os(stdout); OFStream os(stdout);
code->Disassemble(buffer, os); code->Disassemble(buffer.start(), os);
} }
#endif #endif
return code; return code;
......
...@@ -44,11 +44,9 @@ Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, wasm::ModuleEnv* module, ...@@ -44,11 +44,9 @@ Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, wasm::ModuleEnv* module,
// Wraps a given wasm code object, producing a JSFunction that can be called // Wraps a given wasm code object, producing a JSFunction that can be called
// from JavaScript. // from JavaScript.
Handle<JSFunction> CompileJSToWasmWrapper(Isolate* isolate, Handle<JSFunction> CompileJSToWasmWrapper(
wasm::ModuleEnv* module, Isolate* isolate, wasm::ModuleEnv* module, Handle<String> name,
Handle<String> name, Handle<Code> wasm_code, Handle<JSObject> module_object, uint32_t index);
Handle<Code> wasm_code,
uint32_t index);
// Abstracts details of building TurboFan graph nodes for WASM to separate // Abstracts details of building TurboFan graph nodes for WASM to separate
// the WASM decoder from the internal details of TurboFan. // the WASM decoder from the internal details of TurboFan.
......
...@@ -258,6 +258,7 @@ enum BindingFlags { ...@@ -258,6 +258,7 @@ enum BindingFlags {
sloppy_function_without_prototype_map) \ sloppy_function_without_prototype_map) \
V(SLOPPY_FUNCTION_WITH_READONLY_PROTOTYPE_MAP_INDEX, Map, \ V(SLOPPY_FUNCTION_WITH_READONLY_PROTOTYPE_MAP_INDEX, Map, \
sloppy_function_with_readonly_prototype_map) \ sloppy_function_with_readonly_prototype_map) \
V(WASM_FUNCTION_MAP_INDEX, Map, wasm_function_map) \
V(SLOPPY_GENERATOR_FUNCTION_MAP_INDEX, Map, sloppy_generator_function_map) \ V(SLOPPY_GENERATOR_FUNCTION_MAP_INDEX, Map, sloppy_generator_function_map) \
V(SLOW_ALIASED_ARGUMENTS_MAP_INDEX, Map, slow_aliased_arguments_map) \ V(SLOW_ALIASED_ARGUMENTS_MAP_INDEX, Map, slow_aliased_arguments_map) \
V(STRICT_ARGUMENTS_MAP_INDEX, Map, strict_arguments_map) \ V(STRICT_ARGUMENTS_MAP_INDEX, Map, strict_arguments_map) \
......
...@@ -1214,6 +1214,8 @@ Handle<JSFunction> Factory::NewFunction(Handle<Map> map, ...@@ -1214,6 +1214,8 @@ Handle<JSFunction> Factory::NewFunction(Handle<Map> map,
map.is_identical_to( map.is_identical_to(
isolate()->sloppy_function_with_readonly_prototype_map()) || isolate()->sloppy_function_with_readonly_prototype_map()) ||
map.is_identical_to(isolate()->strict_function_map()) || map.is_identical_to(isolate()->strict_function_map()) ||
(FLAG_expose_wasm &&
map.is_identical_to(isolate()->wasm_function_map())) ||
map.is_identical_to(isolate()->proxy_function_map())); map.is_identical_to(isolate()->proxy_function_map()));
return NewFunction(map, info, context); return NewFunction(map, info, context);
} }
......
...@@ -471,15 +471,13 @@ DEFINE_BOOL(trace_turbo_escape, false, "enable tracing in escape analysis") ...@@ -471,15 +471,13 @@ DEFINE_BOOL(trace_turbo_escape, false, "enable tracing in escape analysis")
DEFINE_BOOL(turbo_instruction_scheduling, false, DEFINE_BOOL(turbo_instruction_scheduling, false,
"enable instruction scheduling in TurboFan") "enable instruction scheduling in TurboFan")
#if defined(V8_WASM)
// Flags for native WebAssembly. // Flags for native WebAssembly.
DEFINE_BOOL(expose_wasm, true, "expose WASM interface to JavaScript") DEFINE_BOOL(expose_wasm, false, "expose WASM interface to JavaScript")
DEFINE_BOOL(trace_wasm_decoder, false, "trace decoding of wasm code") DEFINE_BOOL(trace_wasm_decoder, false, "trace decoding of wasm code")
DEFINE_BOOL(trace_wasm_decode_time, false, "trace decoding time of wasm code") DEFINE_BOOL(trace_wasm_decode_time, false, "trace decoding time of wasm code")
DEFINE_BOOL(trace_wasm_compiler, false, "trace compiling of wasm code") DEFINE_BOOL(trace_wasm_compiler, false, "trace compiling of wasm code")
DEFINE_BOOL(wasm_break_on_decoder_error, false, DEFINE_BOOL(wasm_break_on_decoder_error, false,
"debug break when wasm decoder encounters an error") "debug break when wasm decoder encounters an error")
#endif
DEFINE_INT(typed_array_max_size_in_heap, 64, DEFINE_INT(typed_array_max_size_in_heap, 64,
"threshold for in-heap typed array") "threshold for in-heap typed array")
......
...@@ -42,8 +42,7 @@ RawBuffer GetRawBufferArgument( ...@@ -42,8 +42,7 @@ RawBuffer GetRawBufferArgument(
return {nullptr, nullptr}; return {nullptr, nullptr};
} }
Local<ArrayBuffer> buffer = Local<ArrayBuffer>::Cast(args[0]); Local<ArrayBuffer> buffer = Local<ArrayBuffer>::Cast(args[0]);
ArrayBuffer::Contents contents = ArrayBuffer::Contents contents = buffer->GetContents();
buffer->IsExternal() ? buffer->GetContents() : buffer->Externalize();
// TODO(titzer): allow offsets into buffers, views, etc. // TODO(titzer): allow offsets into buffers, views, etc.
...@@ -82,7 +81,6 @@ void VerifyFunction(const v8::FunctionCallbackInfo<v8::Value>& args) { ...@@ -82,7 +81,6 @@ void VerifyFunction(const v8::FunctionCallbackInfo<v8::Value>& args) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate());
ErrorThrower thrower(isolate, "WASM.verifyFunction()"); ErrorThrower thrower(isolate, "WASM.verifyFunction()");
// TODO(titzer): no need to externalize to get the bytes for verification.
RawBuffer buffer = GetRawBufferArgument(thrower, args); RawBuffer buffer = GetRawBufferArgument(thrower, args);
if (thrower.error()) return; if (thrower.error()) return;
...@@ -245,9 +243,6 @@ void InstantiateModule(const v8::FunctionCallbackInfo<v8::Value>& args) { ...@@ -245,9 +243,6 @@ void InstantiateModule(const v8::FunctionCallbackInfo<v8::Value>& args) {
Local<Object> obj = Local<Object>::Cast(args[2]); Local<Object> obj = Local<Object>::Cast(args[2]);
i::Handle<i::Object> mem_obj = v8::Utils::OpenHandle(*obj); i::Handle<i::Object> mem_obj = v8::Utils::OpenHandle(*obj);
memory = i::Handle<i::JSArrayBuffer>(i::JSArrayBuffer::cast(*mem_obj)); memory = i::Handle<i::JSArrayBuffer>(i::JSArrayBuffer::cast(*mem_obj));
i::Isolate* isolate = memory->GetIsolate();
memory->set_is_external(true);
isolate->heap()->UnregisterArrayBuffer(*memory);
} }
// Decode but avoid a redundant pass over function bodies for verification. // Decode but avoid a redundant pass over function bodies for verification.
...@@ -308,6 +303,12 @@ static void InstallFunc(Isolate* isolate, Handle<JSObject> object, ...@@ -308,6 +303,12 @@ static void InstallFunc(Isolate* isolate, Handle<JSObject> object,
void WasmJs::Install(Isolate* isolate, Handle<JSGlobalObject> global) { void WasmJs::Install(Isolate* isolate, Handle<JSGlobalObject> global) {
// Setup wasm function map.
Handle<Map> wasm_function_map = isolate->factory()->NewMap(
JS_FUNCTION_TYPE, JSFunction::kSize + kPointerSize);
wasm_function_map->set_is_callable();
global->native_context()->set_wasm_function_map(*wasm_function_map);
// Bind the WASM object. // Bind the WASM object.
Factory* factory = isolate->factory(); Factory* factory = isolate->factory();
Handle<String> name = v8_str(isolate, "WASM"); Handle<String> name = v8_str(isolate, "WASM");
......
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