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