Commit f20323dc authored by bradnelson's avatar bradnelson Committed by Commit bot

Hooking up asm-wasm conversion.

Directs 'use asm' traffic through asm-wasm conversion when --validate-asm is passed.

Adds a builtin that handles the fallback to JS.

BUG= https://bugs.chromium.org/p/v8/issues/detail?id=4203
TEST=asm-wasm
R=mstarzinger@chromium.org,titzer@chromium.org
LOG=N

Review-Url: https://codereview.chromium.org/2057403003
Cr-Commit-Position: refs/heads/master@{#37470}
parent d781b956
......@@ -628,7 +628,9 @@ action("run_mksnapshot") {
action("v8_dump_build_config") {
script = "tools/testrunner/utils/dump_build_config.py"
outputs = [ "$root_out_dir/v8_build_config.json" ]
outputs = [
"$root_out_dir/v8_build_config.json",
]
args = [
rebase_path("$root_out_dir/v8_build_config.json", root_build_dir),
"dcheck_always_on=$dcheck_always_on",
......@@ -642,10 +644,9 @@ action("v8_dump_build_config") {
"v8_enable_i18n_support=$v8_enable_i18n_support",
"v8_target_cpu=\"$v8_target_cpu\"",
"v8_use_snapshot=$v8_use_snapshot",
]
]
}
###############################################################################
# Source Sets (aka static libraries)
#
......@@ -779,6 +780,14 @@ v8_source_set("v8_base") {
"src/api.h",
"src/arguments.cc",
"src/arguments.h",
"src/asmjs/asm-js.cc",
"src/asmjs/asm-js.h",
"src/asmjs/asm-types.cc",
"src/asmjs/asm-types.h",
"src/asmjs/asm-wasm-builder.cc",
"src/asmjs/asm-wasm-builder.h",
"src/asmjs/typing-asm.cc",
"src/asmjs/typing-asm.h",
"src/assembler.cc",
"src/assembler.h",
"src/assert-scope.cc",
......@@ -1493,8 +1502,6 @@ v8_source_set("v8_base") {
"src/type-info.h",
"src/types.cc",
"src/types.h",
"src/typing-asm.cc",
"src/typing-asm.h",
"src/unicode-cache-inl.h",
"src/unicode-cache.h",
"src/unicode-decoder.cc",
......@@ -1516,10 +1523,6 @@ v8_source_set("v8_base") {
"src/version.h",
"src/vm-state-inl.h",
"src/vm-state.h",
"src/wasm/asm-types.cc",
"src/wasm/asm-types.h",
"src/wasm/asm-wasm-builder.cc",
"src/wasm/asm-wasm-builder.h",
"src/wasm/ast-decoder.cc",
"src/wasm/ast-decoder.h",
"src/wasm/decoder.h",
......@@ -2129,7 +2132,9 @@ if (is_component_build) {
"src/v8dll-main.cc",
]
deps = [ ":v8_dump_build_config" ]
deps = [
":v8_dump_build_config",
]
public_deps = [
":v8_base",
......@@ -2142,7 +2147,9 @@ if (is_component_build) {
}
} else {
group("v8") {
deps = [ ":v8_dump_build_config" ]
deps = [
":v8_dump_build_config",
]
public_deps = [
":v8_base",
......
......@@ -1418,6 +1418,48 @@ void Builtins::Generate_CompileOptimizedConcurrent(MacroAssembler* masm) {
GenerateTailCallToReturnedCode(masm, Runtime::kCompileOptimized_Concurrent);
}
void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r0 : argument count (preserved for callee)
// -- r1 : new target (preserved for callee)
// -- r3 : target function (preserved for callee)
// -----------------------------------
Label failed;
{
FrameScope scope(masm, StackFrame::INTERNAL);
// Push the number of arguments to the callee.
__ SmiTag(r0);
__ push(r0);
// Push a copy of the target function and the new target.
__ push(r1);
__ push(r3);
// The function.
__ push(r1);
// Copy arguments from caller (stdlib, foreign, heap).
for (int i = 2; i >= 0; --i) {
__ ldr(r4, MemOperand(fp, StandardFrameConstants::kCallerSPOffset +
i * kPointerSize));
__ push(r4);
}
// Call runtime, on success unwind frame, and parent frame.
__ CallRuntime(Runtime::kInstantiateAsmJs, 4);
// A smi 0 is returned on failure, an object on success.
__ JumpIfSmi(r0, &failed);
scope.GenerateLeaveFrame();
__ Drop(4);
__ Ret();
__ bind(&failed);
// Restore target function and new target.
__ pop(r3);
__ pop(r1);
__ pop(r0);
__ SmiUntag(r0);
}
// On failure, tail call back to regular js.
GenerateTailCallToReturnedCode(masm, Runtime::kCompileLazy);
}
static void GenerateMakeCodeYoungAgainCommon(MacroAssembler* masm) {
// For now, we are relying on the fact that make_code_young doesn't do any
......
......@@ -1415,6 +1415,42 @@ void Builtins::Generate_CompileOptimizedConcurrent(MacroAssembler* masm) {
GenerateTailCallToReturnedCode(masm, Runtime::kCompileOptimized_Concurrent);
}
void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- x0 : argument count (preserved for callee)
// -- x1 : new target (preserved for callee)
// -- x3 : target function (preserved for callee)
// -----------------------------------
Label failed;
{
FrameScope scope(masm, StackFrame::INTERNAL);
// Push a copy of the target function and the new target.
__ SmiTag(x0);
// Push another copy as a parameter to the runtime call.
__ Push(x0, x1, x3, x1);
// Copy arguments from caller (stdlib, foreign, heap).
for (int i = 2; i >= 0; --i) {
__ ldr(x4, MemOperand(fp, StandardFrameConstants::kCallerSPOffset +
i * kPointerSize));
__ push(x4);
}
// Call runtime, on success unwind frame, and parent frame.
__ CallRuntime(Runtime::kInstantiateAsmJs, 4);
// A smi 0 is returned on failure, an object on success.
__ JumpIfSmi(x0, &failed);
scope.GenerateLeaveFrame();
__ Drop(4);
__ Ret();
__ bind(&failed);
// Restore target function and new target.
__ Pop(x3, x1, x0);
__ SmiUntag(x0);
}
// On failure, tail call back to regular js.
GenerateTailCallToReturnedCode(masm, Runtime::kCompileLazy);
}
static void GenerateMakeCodeYoungAgainCommon(MacroAssembler* masm) {
// For now, we are relying on the fact that make_code_young doesn't do any
......
set noparent
ahaas@chromium.org
bradnelson@chromium.org
jpp@chromium.org
mtrofin@chromium.org
rossberg@chromium.org
titzer@chromium.org
// Copyright 2015 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.
#include "src/asmjs/asm-js.h"
#include "src/api-natives.h"
#include "src/api.h"
#include "src/asmjs/asm-wasm-builder.h"
#include "src/asmjs/typing-asm.h"
#include "src/assert-scope.h"
#include "src/ast/ast.h"
#include "src/ast/scopes.h"
#include "src/execution.h"
#include "src/factory.h"
#include "src/handles.h"
#include "src/isolate.h"
#include "src/objects.h"
#include "src/parsing/parser.h"
#include "src/wasm/encoder.h"
#include "src/wasm/module-decoder.h"
#include "src/wasm/wasm-js.h"
#include "src/wasm/wasm-module.h"
#include "src/wasm/wasm-result.h"
typedef uint8_t byte;
using v8::internal::wasm::ErrorThrower;
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);
}
if (result.val) delete result.val;
return compiled_module;
}
} // namespace
MaybeHandle<FixedArray> AsmJs::ConvertAsmToWasm(ParseInfo* info) {
ErrorThrower thrower(info->isolate(), "Asm.js -> WebAssembly conversion");
AsmTyper typer(info->isolate(), info->zone(), *(info->script()),
info->literal());
typer.set_fixed_signature(true);
if (i::FLAG_enable_simd_asmjs) {
typer.set_allow_simd(true);
}
if (!typer.Validate()) {
DCHECK(!info->isolate()->has_pending_exception());
PrintF("Validation of asm.js module failed: %s", typer.error_message());
return MaybeHandle<FixedArray>();
}
v8::internal::wasm::AsmWasmBuilder builder(info->isolate(), info->zone(),
info->literal(), &typer);
i::Handle<i::FixedArray> foreign_globals;
auto module = builder.Run(&foreign_globals);
size_t byte_length = module->end() - module->begin();
Handle<JSArrayBuffer> buffer = info->isolate()->factory()->NewJSArrayBuffer();
JSArrayBuffer::SetupAllocatingData(buffer, info->isolate(), byte_length,
false, SharedFlag::kNotShared);
uint8_t* module_bytes = reinterpret_cast<uint8_t*>(buffer->backing_store());
memcpy(module_bytes, module->begin(), byte_length);
Handle<FixedArray> result = info->isolate()->factory()->NewFixedArray(2);
result->set(0, *buffer);
result->set(1, *foreign_globals);
return result;
}
MaybeHandle<Object> AsmJs::InstantiateAsmWasm(i::Isolate* isolate,
Handle<FixedArray> wasm_data,
Handle<JSArrayBuffer> memory,
Handle<JSObject> foreign) {
i::Handle<i::JSArrayBuffer> module_bytes(
i::JSArrayBuffer::cast(wasm_data->get(0)));
i::Handle<i::FixedArray> foreign_globals(
i::FixedArray::cast(wasm_data->get(1)));
ErrorThrower thrower(isolate, "Asm.js -> WebAssembly instantiation");
const byte* module_start =
reinterpret_cast<const byte*>(module_bytes->backing_store());
size_t module_length =
static_cast<size_t>(module_bytes->byte_length()->Number());
const byte* module_end = module_start + module_length;
i::MaybeHandle<i::FixedArray> compiled =
CompileModule(isolate, module_start, module_end, &thrower,
internal::wasm::kAsmJsOrigin);
if (compiled.is_null()) {
return MaybeHandle<Object>();
}
i::MaybeHandle<i::JSObject> maybe_module_object =
i::wasm::WasmModule::Instantiate(isolate, compiled.ToHandleChecked(),
foreign, memory);
if (maybe_module_object.is_null()) {
return MaybeHandle<Object>();
}
i::Handle<i::Name> name(isolate->factory()->InternalizeOneByteString(
STATIC_CHAR_VECTOR("__foreign_init__")));
i::Handle<i::Object> module_object = maybe_module_object.ToHandleChecked();
i::MaybeHandle<i::Object> maybe_init =
i::Object::GetProperty(module_object, name);
DCHECK(!maybe_init.is_null());
i::Handle<i::Object> init = maybe_init.ToHandleChecked();
i::Handle<i::Object> undefined(isolate->heap()->undefined_value(), isolate);
i::Handle<i::Object>* foreign_args_array =
new i::Handle<i::Object>[foreign_globals->length()];
for (int j = 0; j < foreign_globals->length(); j++) {
if (!foreign.is_null()) {
i::MaybeHandle<i::Name> name = i::Object::ToName(
isolate, i::Handle<i::Object>(foreign_globals->get(j), isolate));
if (!name.is_null()) {
i::MaybeHandle<i::Object> val =
i::Object::GetProperty(foreign, name.ToHandleChecked());
if (!val.is_null()) {
foreign_args_array[j] = val.ToHandleChecked();
continue;
}
}
}
foreign_args_array[j] = undefined;
}
i::MaybeHandle<i::Object> retval = i::Execution::Call(
isolate, init, undefined, foreign_globals->length(), foreign_args_array);
delete[] foreign_args_array;
if (retval.is_null()) {
thrower.Error(
"WASM.instantiateModuleFromAsm(): foreign init function failed");
return MaybeHandle<Object>();
}
return maybe_module_object;
}
} // namespace internal
} // namespace v8
// 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.
#ifndef V8_ASMJS_ASM_JS_H_
#define V8_ASMJS_ASM_JS_H_
#ifndef V8_SHARED
#include "src/allocation.h"
#include "src/base/hashmap.h"
#else
#include "include/v8.h"
#include "src/base/compiler-specific.h"
#endif // !V8_SHARED
#include "src/parsing/parser.h"
namespace v8 {
namespace internal {
// Interface to compile and instantiate for asmjs.
class AsmJs {
public:
static MaybeHandle<FixedArray> ConvertAsmToWasm(i::ParseInfo* info);
static MaybeHandle<Object> InstantiateAsmWasm(i::Isolate* isolate,
Handle<FixedArray> wasm_data,
Handle<JSArrayBuffer> memory,
Handle<JSObject> foreign);
};
} // namespace internal
} // namespace v8
#endif
......@@ -4,7 +4,7 @@
#include "src/v8.h"
#include "src/wasm/asm-types.h"
#include "src/asmjs/asm-types.h"
namespace v8 {
namespace internal {
......
......@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SRC_WASM_ASM_TYPES_H_
#define SRC_WASM_ASM_TYPES_H_
#ifndef SRC_ASMJS_ASM_TYPES_H_
#define SRC_ASMJS_ASM_TYPES_H_
#include <string>
......
......@@ -10,7 +10,7 @@
#endif
#include <math.h>
#include "src/wasm/asm-wasm-builder.h"
#include "src/asmjs/asm-wasm-builder.h"
#include "src/wasm/switch-logic.h"
#include "src/wasm/wasm-macro-gen.h"
#include "src/wasm/wasm-opcodes.h"
......
......@@ -2,12 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_WASM_ASM_WASM_BUILDER_H_
#define V8_WASM_ASM_WASM_BUILDER_H_
#ifndef V8_ASMJS_ASM_WASM_BUILDER_H_
#define V8_ASMJS_ASM_WASM_BUILDER_H_
#include "src/allocation.h"
#include "src/asmjs/typing-asm.h"
#include "src/objects.h"
#include "src/typing-asm.h"
#include "src/wasm/encoder.h"
#include "src/zone.h"
......
......@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_TYPING_ASM_H_
#define V8_TYPING_ASM_H_
#ifndef V8_ASMJS_TYPING_ASM_H_
#define V8_ASMJS_TYPING_ASM_H_
#include "src/allocation.h"
#include "src/ast/ast-type-bounds.h"
......@@ -24,6 +24,7 @@ class AsmTyper : public AstVisitor {
FunctionLiteral* root);
bool Validate();
void set_allow_simd(bool simd) { allow_simd_ = simd; }
void set_fixed_signature(bool fixed) { fixed_signature_ = fixed; }
const char* error_message() { return error_message_; }
const AstTypeBounds* bounds() { return &bounds_; }
......@@ -71,6 +72,7 @@ class AsmTyper : public AstVisitor {
FunctionLiteral* root_;
bool valid_;
bool allow_simd_;
bool fixed_signature_;
struct VariableInfo : public ZoneObject {
Type* type;
......
......@@ -3450,9 +3450,7 @@ bool Genesis::InstallSpecialObjects(Handle<Context> native_context) {
JSObject::AddProperty(global, debug_string, global_proxy, DONT_ENUM);
}
if (FLAG_expose_wasm) {
WasmJs::Install(isolate, global);
}
WasmJs::Install(isolate, global);
return true;
}
......
......@@ -225,6 +225,7 @@ class CodeStubAssembler;
V(JSEntryTrampoline, BUILTIN, kNoExtraICState) \
V(JSConstructEntryTrampoline, BUILTIN, kNoExtraICState) \
V(ResumeGeneratorTrampoline, BUILTIN, kNoExtraICState) \
V(InstantiateAsmJs, BUILTIN, kNoExtraICState) \
V(CompileLazy, BUILTIN, kNoExtraICState) \
V(CompileBaseline, BUILTIN, kNoExtraICState) \
V(CompileOptimized, BUILTIN, kNoExtraICState) \
......@@ -480,6 +481,7 @@ class Builtins {
static void Generate_AllocateInNewSpace(MacroAssembler* masm);
static void Generate_AllocateInOldSpace(MacroAssembler* masm);
static void Generate_ConstructedNonConstructable(MacroAssembler* masm);
static void Generate_InstantiateAsmJs(MacroAssembler* masm);
static void Generate_CompileLazy(MacroAssembler* masm);
static void Generate_CompileBaseline(MacroAssembler* masm);
static void Generate_InOptimizationQueue(MacroAssembler* masm);
......
......@@ -6,6 +6,8 @@
#include <algorithm>
#include "src/asmjs/asm-js.h"
#include "src/asmjs/typing-asm.h"
#include "src/ast/ast-numbering.h"
#include "src/ast/prettyprinter.h"
#include "src/ast/scopeinfo.h"
......@@ -30,7 +32,6 @@
#include "src/parsing/scanner-character-streams.h"
#include "src/runtime-profiler.h"
#include "src/snapshot/code-serializer.h"
#include "src/typing-asm.h"
#include "src/vm-state-inl.h"
namespace v8 {
......@@ -477,14 +478,12 @@ bool GenerateUnoptimizedCode(CompilationInfo* info) {
bool success;
EnsureFeedbackMetadata(info);
if (FLAG_validate_asm && info->scope()->asm_module()) {
AsmTyper typer(info->isolate(), info->zone(), *(info->script()),
info->literal());
if (FLAG_enable_simd_asmjs) {
typer.set_allow_simd(true);
}
if (!typer.Validate()) {
DCHECK(!info->isolate()->has_pending_exception());
PrintF("Validation of asm.js module failed: %s", typer.error_message());
MaybeHandle<FixedArray> wasm_data;
wasm_data = AsmJs::ConvertAsmToWasm(info->parse_info());
if (!wasm_data.is_null()) {
info->shared_info()->set_asm_wasm_data(*wasm_data.ToHandleChecked());
info->SetCode(info->isolate()->builtins()->InstantiateAsmJs());
return true;
}
}
if (FLAG_ignition && UseIgnition(info)) {
......
......@@ -1019,6 +1019,46 @@ void Builtins::Generate_CompileOptimizedConcurrent(MacroAssembler* masm) {
GenerateTailCallToReturnedCode(masm, Runtime::kCompileOptimized_Concurrent);
}
void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- eax : argument count (preserved for callee)
// -- edx : new target (preserved for callee)
// -- edi : target function (preserved for callee)
// -----------------------------------
Label failed;
{
FrameScope scope(masm, StackFrame::INTERNAL);
// Push the number of arguments to the callee.
__ SmiTag(eax);
__ push(eax);
// Push a copy of the target function and the new target.
__ push(edi);
__ push(edx);
// The function.
__ push(edi);
// Copy arguments from caller (stdlib, foreign, heap).
for (int i = 2; i >= 0; --i) {
__ push(Operand(
ebp, StandardFrameConstants::kCallerSPOffset + i * kPointerSize));
}
// Call runtime, on success unwind frame, and parent frame.
__ CallRuntime(Runtime::kInstantiateAsmJs, 4);
// A smi 0 is returned on failure, an object on success.
__ JumpIfSmi(eax, &failed, Label::kNear);
scope.GenerateLeaveFrame();
__ ret(4 * kPointerSize);
__ bind(&failed);
// Restore target function and new target.
__ pop(edx);
__ pop(edi);
__ pop(eax);
__ SmiUntag(eax);
}
// On failure, tail call back to regular js.
GenerateTailCallToReturnedCode(masm, Runtime::kCompileLazy);
}
static void GenerateMakeCodeYoungAgainCommon(MacroAssembler* masm) {
// For now, we are relying on the fact that make_code_young doesn't do any
......
......@@ -1413,6 +1413,42 @@ void Builtins::Generate_CompileOptimizedConcurrent(MacroAssembler* masm) {
GenerateTailCallToReturnedCode(masm, Runtime::kCompileOptimized_Concurrent);
}
void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- a0 : argument count (preserved for callee)
// -- a1 : new target (preserved for callee)
// -- a3 : target function (preserved for callee)
// -----------------------------------
Label failed;
{
FrameScope scope(masm, StackFrame::INTERNAL);
// Push a copy of the target function and the new target.
// Push function as parameter to the runtime call.
__ SmiTag(a0);
__ Push(a0, a1, a3, a1);
// Copy arguments from caller (stdlib, foreign, heap).
for (int i = 2; i >= 0; --i) {
__ lw(a3, MemOperand(fp, StandardFrameConstants::kCallerSPOffset +
i * kPointerSize));
__ push(a3);
}
// Call runtime, on success unwind frame, and parent frame.
__ CallRuntime(Runtime::kInstantiateAsmJs, 4);
// A smi 0 is returned on failure, an object on success.
__ JumpIfSmi(a0, &failed);
scope.GenerateLeaveFrame();
__ Drop(4);
__ Ret();
__ bind(&failed);
// Restore target function and new target.
__ Pop(a0, a1, a3);
__ SmiUntag(a0);
}
// On failure, tail call back to regular js.
GenerateTailCallToReturnedCode(masm, Runtime::kCompileLazy);
}
static void GenerateMakeCodeYoungAgainCommon(MacroAssembler* masm) {
// For now, we are relying on the fact that make_code_young doesn't do any
......
......@@ -1397,6 +1397,42 @@ void Builtins::Generate_CompileOptimizedConcurrent(MacroAssembler* masm) {
GenerateTailCallToReturnedCode(masm, Runtime::kCompileOptimized_Concurrent);
}
void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- a0 : argument count (preserved for callee)
// -- a1 : new target (preserved for callee)
// -- a3 : target function (preserved for callee)
// -----------------------------------
Label failed;
{
FrameScope scope(masm, StackFrame::INTERNAL);
// Push a copy of the target function and the new target.
// Push function as parameter to the runtime call.
__ SmiTag(a0);
__ Push(a0, a1, a3, a1);
// Copy arguments from caller (stdlib, foreign, heap).
for (int i = 2; i >= 0; --i) {
__ lw(a3, MemOperand(fp, StandardFrameConstants::kCallerSPOffset +
i * kPointerSize));
__ push(a3);
}
// Call runtime, on success unwind frame, and parent frame.
__ CallRuntime(Runtime::kInstantiateAsmJs, 4);
// A smi 0 is returned on failure, an object on success.
__ JumpIfSmi(a0, &failed);
scope.GenerateLeaveFrame();
__ Drop(4);
__ Ret();
__ bind(&failed);
// Restore target function and new target.
__ Pop(a0, a1, a3);
__ SmiUntag(a0);
}
// On failure, tail call back to regular js.
GenerateTailCallToReturnedCode(masm, Runtime::kCompileLazy);
}
static void GenerateMakeCodeYoungAgainCommon(MacroAssembler* masm) {
// For now, we are relying on the fact that make_code_young doesn't do any
......
......@@ -564,7 +564,7 @@ void SharedFunctionInfo::SharedFunctionInfoVerify() {
VerifyObjectField(kScopeInfoOffset);
VerifyObjectField(kInstanceClassNameOffset);
CHECK(function_data()->IsUndefined(GetIsolate()) || IsApiFunction() ||
HasBytecodeArray());
HasBytecodeArray() || HasAsmWasmData());
VerifyObjectField(kFunctionDataOffset);
VerifyObjectField(kScriptOffset);
VerifyObjectField(kDebugInfoOffset);
......
......@@ -6084,6 +6084,25 @@ void SharedFunctionInfo::ClearBytecodeArray() {
set_function_data(GetHeap()->undefined_value());
}
bool SharedFunctionInfo::HasAsmWasmData() {
return function_data()->IsFixedArray();
}
FixedArray* SharedFunctionInfo::asm_wasm_data() {
DCHECK(HasAsmWasmData());
return FixedArray::cast(function_data());
}
void SharedFunctionInfo::set_asm_wasm_data(FixedArray* data) {
DCHECK(function_data()->IsUndefined(GetIsolate()) || HasAsmWasmData());
set_function_data(data);
}
void SharedFunctionInfo::ClearAsmWasmData() {
DCHECK(function_data()->IsUndefined(GetIsolate()) || HasAsmWasmData());
set_function_data(GetHeap()->undefined_value());
}
bool SharedFunctionInfo::HasBuiltinFunctionId() {
return function_identifier()->IsSmi();
}
......
......@@ -6916,6 +6916,7 @@ class SharedFunctionInfo: public HeapObject {
// Currently it has one of:
// - a FunctionTemplateInfo to make benefit the API [IsApiFunction()].
// - a BytecodeArray for the interpreter [HasBytecodeArray()].
// - a FixedArray with Asm->Wasm conversion [HasAsmWasmData()].
DECL_ACCESSORS(function_data, Object)
inline bool IsApiFunction();
......@@ -6925,6 +6926,10 @@ class SharedFunctionInfo: public HeapObject {
inline BytecodeArray* bytecode_array();
inline void set_bytecode_array(BytecodeArray* bytecode);
inline void ClearBytecodeArray();
inline bool HasAsmWasmData();
inline FixedArray* asm_wasm_data();
inline void set_asm_wasm_data(FixedArray* data);
inline void ClearAsmWasmData();
// [function identifier]: This field holds an additional identifier for the
// function.
......
......@@ -1415,6 +1415,42 @@ void Builtins::Generate_CompileOptimizedConcurrent(MacroAssembler* masm) {
GenerateTailCallToReturnedCode(masm, Runtime::kCompileOptimized_Concurrent);
}
void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r3 : argument count (preserved for callee)
// -- r4 : new target (preserved for callee)
// -- r6 : target function (preserved for callee)
// -----------------------------------
Label failed;
{
FrameScope scope(masm, StackFrame::INTERNAL);
// Push a copy of the target function and the new target.
// Push function as parameter to the runtime call.
__ SmiTag(r3);
__ Push(r3, r4, r6, r4);
// Copy arguments from caller (stdlib, foreign, heap).
for (int i = 2; i >= 0; --i) {
__ LoadP(r4, MemOperand(fp, StandardFrameConstants::kCallerSPOffset +
i * kPointerSize));
__ push(r4);
}
// Call runtime, on success unwind frame, and parent frame.
__ CallRuntime(Runtime::kInstantiateAsmJs, 4);
// A smi 0 is returned on failure, an object on success.
__ JumpIfSmi(r3, &failed);
scope.GenerateLeaveFrame();
__ Drop(4);
__ Ret();
__ bind(&failed);
// Restore target function and new target.
__ Pop(r3, r4, r6);
__ SmiUntag(r3);
}
// On failure, tail call back to regular js.
GenerateTailCallToReturnedCode(masm, Runtime::kCompileLazy);
}
static void GenerateMakeCodeYoungAgainCommon(MacroAssembler* masm) {
// For now, we are relying on the fact that make_code_young doesn't do any
......
......@@ -5,6 +5,7 @@
#include "src/runtime/runtime-utils.h"
#include "src/arguments.h"
#include "src/asmjs/asm-js.h"
#include "src/compiler.h"
#include "src/deoptimizer.h"
#include "src/frames-inl.h"
......@@ -79,6 +80,31 @@ RUNTIME_FUNCTION(Runtime_CompileOptimized_NotConcurrent) {
return function->code();
}
RUNTIME_FUNCTION(Runtime_InstantiateAsmJs) {
HandleScope scope(isolate);
DCHECK_EQ(args.length(), 4);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
Handle<JSObject> foreign;
if (args[2]->IsJSObject()) {
foreign = args.at<i::JSObject>(2);
}
Handle<JSArrayBuffer> memory;
if (args[3]->IsJSArrayBuffer()) {
memory = args.at<i::JSArrayBuffer>(3);
}
if (args[1]->IsJSObject()) {
MaybeHandle<Object> result;
result = AsmJs::InstantiateAsmWasm(
isolate, handle(function->shared()->asm_wasm_data()), memory, foreign);
if (!result.is_null()) {
return *result.ToHandleChecked();
}
}
// Remove wasm data and return a smi 0 to indicate failure.
function->shared()->ClearAsmWasmData();
return Smi::FromInt(0);
}
RUNTIME_FUNCTION(Runtime_NotifyStubFailure) {
HandleScope scope(isolate);
......@@ -89,7 +115,6 @@ RUNTIME_FUNCTION(Runtime_NotifyStubFailure) {
return isolate->heap()->undefined_value();
}
class ActivationsFinder : public ThreadVisitor {
public:
Code* code_;
......
......@@ -127,7 +127,8 @@ namespace internal {
F(NotifyDeoptimized, 1, 1) \
F(CompileForOnStackReplacement, 1, 1) \
F(TryInstallOptimizedCode, 1, 1) \
F(ResolvePossiblyDirectEval, 6, 1)
F(ResolvePossiblyDirectEval, 6, 1) \
F(InstantiateAsmJs, 4, 1)
#define FOR_EACH_INTRINSIC_DATE(F) \
F(IsDate, 1, 1) \
......
......@@ -1396,6 +1396,43 @@ void Builtins::Generate_CompileOptimizedConcurrent(MacroAssembler* masm) {
GenerateTailCallToReturnedCode(masm, Runtime::kCompileOptimized_Concurrent);
}
void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r2 : argument count (preserved for callee)
// -- r3 : new target (preserved for callee)
// -- r5 : target function (preserved for callee)
// -----------------------------------
Label failed;
{
FrameScope scope(masm, StackFrame::INTERNAL);
// Push a copy of the target function and the new target.
__ SmiTag(r2);
// Push another copy as a parameter to the runtime call.
__ Push(r2, r3, r5, r3);
// Copy arguments from caller (stdlib, foreign, heap).
for (int i = 2; i >= 0; --i) {
__ LoadP(r4, MemOperand(fp, StandardFrameConstants::kCallerSPOffset +
i * kPointerSize));
__ push(r4);
}
// Call runtime, on success unwind frame, and parent frame.
__ CallRuntime(Runtime::kInstantiateAsmJs, 4);
// A smi 0 is returned on failure, an object on success.
__ JumpIfSmi(r2, &failed);
scope.GenerateLeaveFrame();
__ Drop(4);
__ Ret();
__ bind(&failed);
// Restore target function and new target.
__ Pop(r2, r3, r5);
__ SmiUntag(r2);
}
// On failure, tail call back to regular js.
GenerateTailCallToReturnedCode(masm, Runtime::kCompileLazy);
}
static void GenerateMakeCodeYoungAgainCommon(MacroAssembler* masm) {
// For now, we are relying on the fact that make_code_young doesn't do any
// garbage collection which allows us to save/restore the registers without
......
......@@ -418,6 +418,14 @@
'api-natives.h',
'arguments.cc',
'arguments.h',
'asmjs/asm-js.cc',
'asmjs/asm-js.h',
'asmjs/asm-types.cc',
'asmjs/asm-types.h',
'asmjs/asm-wasm-builder.cc',
'asmjs/asm-wasm-builder.h',
'asmjs/typing-asm.cc',
'asmjs/typing-asm.h',
'assembler.cc',
'assembler.h',
'assert-scope.h',
......@@ -1137,8 +1145,6 @@
'type-info.h',
'types.cc',
'types.h',
'typing-asm.cc',
'typing-asm.h',
'unicode-inl.h',
'unicode.cc',
'unicode.h',
......@@ -1161,10 +1167,6 @@
'version.h',
'vm-state-inl.h',
'vm-state.h',
'wasm/asm-types.cc',
'wasm/asm-types.h',
'wasm/asm-wasm-builder.cc',
'wasm/asm-wasm-builder.h',
'wasm/ast-decoder.cc',
'wasm/ast-decoder.h',
'wasm/decoder.h',
......
......@@ -4,6 +4,8 @@
#include "src/api-natives.h"
#include "src/api.h"
#include "src/asmjs/asm-wasm-builder.h"
#include "src/asmjs/typing-asm.h"
#include "src/assert-scope.h"
#include "src/ast/ast.h"
#include "src/ast/scopes.h"
......@@ -13,9 +15,7 @@
#include "src/isolate.h"
#include "src/objects.h"
#include "src/parsing/parser.h"
#include "src/typing-asm.h"
#include "src/wasm/asm-wasm-builder.h"
#include "src/wasm/encoder.h"
#include "src/wasm/module-decoder.h"
#include "src/wasm/wasm-js.h"
......
......@@ -92,7 +92,6 @@ static void GenerateTailCallToReturnedCode(MacroAssembler* masm,
__ jmp(rbx);
}
void Builtins::Generate_InOptimizationQueue(MacroAssembler* masm) {
// Checking whether the queued function is ready for install is optional,
// since we come across interrupts and stack checks elsewhere. However,
......@@ -1073,6 +1072,46 @@ void Builtins::Generate_CompileOptimizedConcurrent(MacroAssembler* masm) {
GenerateTailCallToReturnedCode(masm, Runtime::kCompileOptimized_Concurrent);
}
void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- rax : argument count (preserved for callee)
// -- rdx : new target (preserved for callee)
// -- rdi : target function (preserved for callee)
// -----------------------------------
Label failed;
{
FrameScope scope(masm, StackFrame::INTERNAL);
// Push the number of arguments to the callee.
__ Integer32ToSmi(rax, rax);
__ Push(rax);
// Push a copy of the target function and the new target.
__ Push(rdi);
__ Push(rdx);
// The function.
__ Push(rdi);
// Copy arguments from caller (stdlib, foreign, heap).
for (int i = 2; i >= 0; --i) {
__ Push(Operand(
rbp, StandardFrameConstants::kCallerSPOffset + i * kPointerSize));
}
// Call runtime, on success unwind frame, and parent frame.
__ CallRuntime(Runtime::kInstantiateAsmJs, 4);
// A smi 0 is returned on failure, an object on success.
__ JumpIfSmi(rax, &failed, Label::kNear);
scope.GenerateLeaveFrame();
__ ret(4 * kPointerSize);
__ bind(&failed);
// Restore target function and new target.
__ Pop(rdx);
__ Pop(rdi);
__ Pop(rax);
__ SmiToInteger32(rax, rax);
}
// On failure, tail call back to regular js.
GenerateTailCallToReturnedCode(masm, Runtime::kCompileLazy);
}
static void GenerateMakeCodeYoungAgainCommon(MacroAssembler* masm) {
// For now, we are relying on the fact that make_code_young doesn't do any
......
......@@ -1018,6 +1018,46 @@ void Builtins::Generate_CompileOptimizedConcurrent(MacroAssembler* masm) {
GenerateTailCallToReturnedCode(masm, Runtime::kCompileOptimized_Concurrent);
}
void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- eax : argument count (preserved for callee)
// -- edx : new target (preserved for callee)
// -- edi : target function (preserved for callee)
// -----------------------------------
Label failed;
{
FrameScope scope(masm, StackFrame::INTERNAL);
// Push the number of arguments to the callee.
__ SmiTag(eax);
__ push(eax);
// Push a copy of the target function and the new target.
__ push(edi);
__ push(edx);
// The function.
__ push(edi);
// Copy arguments from caller (stdlib, foreign, heap).
for (int i = 2; i >= 0; --i) {
__ push(Operand(
ebp, StandardFrameConstants::kCallerSPOffset + i * kPointerSize));
}
// Call runtime, on success unwind frame, and parent frame.
__ CallRuntime(Runtime::kInstantiateAsmJs, 4);
// A smi 0 is returned on failure, an object on success.
__ JumpIfSmi(eax, &failed, Label::kNear);
scope.GenerateLeaveFrame();
__ ret(4 * kPointerSize);
__ bind(&failed);
// Restore target function and new target.
__ pop(edx);
__ pop(edi);
__ pop(eax);
__ SmiUntag(eax);
}
// On failure, tail call back to regular js.
GenerateTailCallToReturnedCode(masm, Runtime::kCompileLazy);
}
static void GenerateMakeCodeYoungAgainCommon(MacroAssembler* masm) {
// For now, we are relying on the fact that make_code_young doesn't do any
......
......@@ -4,16 +4,16 @@
#include "src/v8.h"
#include "src/ast/ast.h"
#include "src/asmjs/typing-asm.h"
#include "src/ast/ast-expression-visitor.h"
#include "src/ast/ast.h"
#include "src/ast/scopes.h"
#include "src/parsing/parser.h"
#include "src/parsing/rewriter.h"
#include "src/type-cache.h"
#include "src/typing-asm.h"
#include "test/cctest/cctest.h"
#include "test/cctest/expression-type-collector.h"
#include "test/cctest/expression-type-collector-macros.h"
#include "test/cctest/expression-type-collector.h"
// Macros for function types.
#define FUNC_FOREIGN_TYPE Bounds(Type::Function(Type::Any(), zone))
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/wasm/asm-types.h"
#include "src/asmjs/asm-types.h"
#include <unordered_map>
#include <unordered_set>
......
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