[no-wasm] Remove wasm-specific code from codegen

This removes many wasm-specific code paths from codegen, such that
includes from src/wasm can be removed. After src/wasm is fully excluded
from no-wasm builds, we can also clean up unused enum values, but for
now they are still being referenced.

R=mslekova@chromium.org

Bug: v8:11238
Change-Id: I526ac931f023a57f70b5248befa2733ad10ce9ce
Cq-Include-Trybots: luci.v8.try:v8_linux64_no_wasm_compile_rel
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2732011
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Reviewed-by: Maya Lekova <mslekova@chromium.org>
Cr-Commit-Position: refs/heads/master@{#73189}
This commit is contained in:
Clemens Backes 2021-03-04 13:34:51 +01:00 committed by Commit Bot
parent 69d1e2c21d
commit 75d7d12720
36 changed files with 612 additions and 250 deletions

View File

@ -25,7 +25,10 @@
#include "src/runtime/runtime.h"
#include "src/snapshot/embedded/embedded-data.h"
#include "src/snapshot/snapshot.h"
#if V8_ENABLE_WEBASSEMBLY
#include "src/wasm/wasm-code-manager.h"
#endif // V8_ENABLE_WEBASSEMBLY
// Satisfy cpplint check, but don't include platform-specific header. It is
// included recursively via macro-assembler.h.
@ -1914,7 +1917,11 @@ void TurboAssembler::TruncateDoubleToI(Isolate* isolate, Zone* zone,
vstr(double_input, MemOperand(sp, 0));
if (stub_mode == StubCallMode::kCallWasmRuntimeStub) {
#if V8_ENABLE_WEBASSEMBLY
Call(wasm::WasmCode::kDoubleToI, RelocInfo::WASM_STUB_CALL);
#else
UNREACHABLE();
#endif // V8_ENABLE_WEBASSEMBLY
} else if (options().inline_offheap_trampolines) {
CallBuiltin(Builtins::kDoubleToI);
} else {

View File

@ -22,7 +22,10 @@
#include "src/runtime/runtime.h"
#include "src/snapshot/embedded/embedded-data.h"
#include "src/snapshot/snapshot.h"
#if V8_ENABLE_WEBASSEMBLY
#include "src/wasm/wasm-code-manager.h"
#endif // V8_ENABLE_WEBASSEMBLY
// Satisfy cpplint check, but don't include platform-specific header. It is
// included recursively via macro-assembler.h.
@ -2425,7 +2428,11 @@ void TurboAssembler::TruncateDoubleToI(Isolate* isolate, Zone* zone,
// DoubleToI preserves any registers it needs to clobber.
if (stub_mode == StubCallMode::kCallWasmRuntimeStub) {
#if V8_ENABLE_WEBASSEMBLY
Call(wasm::WasmCode::kDoubleToI, RelocInfo::WASM_STUB_CALL);
#else
UNREACHABLE();
#endif // V8_ENABLE_WEBASSEMBLY
} else if (options().inline_offheap_trampolines) {
CallBuiltin(Builtins::kDoubleToI);
} else {
@ -2457,7 +2464,11 @@ void TurboAssembler::Prologue() {
void TurboAssembler::EnterFrame(StackFrame::Type type) {
UseScratchRegisterScope temps(this);
if (type == StackFrame::INTERNAL || type == StackFrame::WASM_DEBUG_BREAK) {
if (type == StackFrame::INTERNAL
#if V8_ENABLE_WEBASSEMBLY
|| type == StackFrame::WASM_DEBUG_BREAK
#endif // V8_ENABLE_WEBASSEMBLY
) {
Register type_reg = temps.AcquireX();
Mov(type_reg, StackFrame::TypeToMarker(type));
Push<TurboAssembler::kSignLR>(lr, fp, type_reg, padreg);
@ -2468,6 +2479,7 @@ void TurboAssembler::EnterFrame(StackFrame::Type type) {
// sp[2] : fp
// sp[1] : type
// sp[0] : for alignment
#if V8_ENABLE_WEBASSEMBLY
} else if (type == StackFrame::WASM ||
type == StackFrame::WASM_COMPILE_LAZY ||
type == StackFrame::WASM_EXIT) {
@ -2480,6 +2492,7 @@ void TurboAssembler::EnterFrame(StackFrame::Type type) {
// sp[2] : fp
// sp[1] : type
// sp[0] : for alignment
#endif // V8_ENABLE_WEBASSEMBLY
} else if (type == StackFrame::CONSTRUCT) {
Register type_reg = temps.AcquireX();
Mov(type_reg, StackFrame::TypeToMarker(type));
@ -3430,6 +3443,7 @@ void TurboAssembler::RestoreFPAndLR() {
#endif
}
#if V8_ENABLE_WEBASSEMBLY
void TurboAssembler::StoreReturnAddressInWasmExitFrame(Label* return_location) {
UseScratchRegisterScope temps(this);
temps.Exclude(x16, x17);
@ -3440,6 +3454,7 @@ void TurboAssembler::StoreReturnAddressInWasmExitFrame(Label* return_location) {
#endif
Str(x17, MemOperand(fp, WasmExitFrameConstants::kCallingPCOffset));
}
#endif // V8_ENABLE_WEBASSEMBLY
void TurboAssembler::I64x2BitMask(Register dst, VRegister src) {
UseScratchRegisterScope scope(this);

View File

@ -1374,7 +1374,9 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
// authenticate the LR when pointer authentication is enabled.
void RestoreFPAndLR();
#if V8_ENABLE_WEBASSEMBLY
void StoreReturnAddressInWasmExitFrame(Label* return_location);
#endif // V8_ENABLE_WEBASSEMBLY
// Wasm SIMD helpers. These instructions don't have direct lowering to native
// instructions. These helpers allow us to define the optimal code sequence,

View File

@ -8,7 +8,10 @@
#include "src/common/globals.h"
#include "src/handles/handles-inl.h"
#include "src/objects/objects-inl.h"
#if V8_ENABLE_WEBASSEMBLY
#include "src/wasm/wasm-code-manager.h"
#endif // V8_ENABLE_WEBASSEMBLY
namespace v8 {
namespace internal {
@ -28,6 +31,7 @@ struct JSOps {
int code_comments_size() const { return code->code_comments_size(); }
};
#if V8_ENABLE_WEBASSEMBLY
struct WasmOps {
const wasm::WasmCode* code;
@ -48,6 +52,7 @@ struct WasmOps {
Address code_comments() const { return code->code_comments(); }
int code_comments_size() const { return code->code_comments_size(); }
};
#endif // V8_ENABLE_WEBASSEMBLY
struct CodeDescOps {
const CodeDesc* code_desc;
@ -76,6 +81,7 @@ struct CodeDescOps {
};
} // namespace
#if V8_ENABLE_WEBASSEMBLY
#define DISPATCH(ret, method) \
ret CodeReference::method() const { \
DCHECK(!is_null()); \
@ -90,6 +96,18 @@ struct CodeDescOps {
UNREACHABLE(); \
} \
}
#else
#define DISPATCH(ret, method) \
ret CodeReference::method() const { \
DCHECK(!is_null()); \
DCHECK(kind_ == JS || kind_ == CODE_DESC); \
if (kind_ == JS) { \
return JSOps{js_code_}.method(); \
} else { \
return CodeDescOps{code_desc_}.method(); \
} \
}
#endif // V8_ENABLE_WEBASSEMBLY
DISPATCH(Address, constant_pool)
DISPATCH(Address, instruction_start)

View File

@ -25,7 +25,10 @@
#include "src/objects/ordered-hash-table-inl.h"
#include "src/objects/property-cell.h"
#include "src/roots/roots.h"
#if V8_ENABLE_WEBASSEMBLY
#include "src/wasm/wasm-objects.h"
#endif // V8_ENABLE_WEBASSEMBLY
namespace v8 {
namespace internal {
@ -13549,15 +13552,19 @@ TNode<Code> CodeStubAssembler::GetSharedFunctionInfoCode(
*data_type_out = data_type;
}
int32_t case_values[] = {BYTECODE_ARRAY_TYPE,
BASELINE_DATA_TYPE,
WASM_EXPORTED_FUNCTION_DATA_TYPE,
ASM_WASM_DATA_TYPE,
UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE,
UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE,
FUNCTION_TEMPLATE_INFO_TYPE,
WASM_JS_FUNCTION_DATA_TYPE,
WASM_CAPI_FUNCTION_DATA_TYPE};
int32_t case_values[] = {
BYTECODE_ARRAY_TYPE,
BASELINE_DATA_TYPE,
UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE,
UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE,
FUNCTION_TEMPLATE_INFO_TYPE,
#if V8_ENABLE_WEBASSEMBLY
WASM_EXPORTED_FUNCTION_DATA_TYPE,
ASM_WASM_DATA_TYPE,
WASM_JS_FUNCTION_DATA_TYPE,
WASM_CAPI_FUNCTION_DATA_TYPE,
#endif // V8_ENABLE_WEBASSEMBLY
};
Label check_is_bytecode_array(this);
Label check_is_baseline_data(this);
Label check_is_exported_function_data(this);
@ -13568,15 +13575,19 @@ TNode<Code> CodeStubAssembler::GetSharedFunctionInfoCode(
Label check_is_interpreter_data(this);
Label check_is_wasm_js_function_data(this);
Label check_is_wasm_capi_function_data(this);
Label* case_labels[] = {&check_is_bytecode_array,
&check_is_baseline_data,
&check_is_exported_function_data,
&check_is_asm_wasm_data,
&check_is_uncompiled_data_without_preparse_data,
&check_is_uncompiled_data_with_preparse_data,
&check_is_function_template_info,
&check_is_wasm_js_function_data,
&check_is_wasm_capi_function_data};
Label* case_labels[] = {
&check_is_bytecode_array,
&check_is_baseline_data,
&check_is_uncompiled_data_without_preparse_data,
&check_is_uncompiled_data_with_preparse_data,
&check_is_function_template_info,
#if V8_ENABLE_WEBASSEMBLY
&check_is_exported_function_data,
&check_is_asm_wasm_data,
&check_is_wasm_js_function_data,
&check_is_wasm_capi_function_data
#endif // V8_ENABLE_WEBASSEMBLY
};
STATIC_ASSERT(arraysize(case_values) == arraysize(case_labels));
Switch(data_type, &check_is_interpreter_data, case_values, case_labels,
arraysize(case_labels));
@ -13594,17 +13605,6 @@ TNode<Code> CodeStubAssembler::GetSharedFunctionInfoCode(
sfi_code = baseline_code;
Goto(&done);
// IsWasmExportedFunctionData: Use the wrapper code
BIND(&check_is_exported_function_data);
sfi_code = CAST(LoadObjectField(
CAST(sfi_data), WasmExportedFunctionData::kWrapperCodeOffset));
Goto(&done);
// IsAsmWasmData: Instantiate using AsmWasmData
BIND(&check_is_asm_wasm_data);
sfi_code = HeapConstant(BUILTIN_CODE(isolate(), InstantiateAsmJs));
Goto(&done);
// IsUncompiledDataWithPreparseData | IsUncompiledDataWithoutPreparseData:
// Compile lazy
BIND(&check_is_uncompiled_data_with_preparse_data);
@ -13627,6 +13627,18 @@ TNode<Code> CodeStubAssembler::GetSharedFunctionInfoCode(
CAST(sfi_data), InterpreterData::kInterpreterTrampolineOffset));
Goto(&done);
#if V8_ENABLE_WEBASSEMBLY
// IsWasmExportedFunctionData: Use the wrapper code
BIND(&check_is_exported_function_data);
sfi_code = CAST(LoadObjectField(
CAST(sfi_data), WasmExportedFunctionData::kWrapperCodeOffset));
Goto(&done);
// IsAsmWasmData: Instantiate using AsmWasmData
BIND(&check_is_asm_wasm_data);
sfi_code = HeapConstant(BUILTIN_CODE(isolate(), InstantiateAsmJs));
Goto(&done);
// IsWasmJSFunctionData: Use the wrapper code.
BIND(&check_is_wasm_js_function_data);
sfi_code = CAST(
@ -13638,6 +13650,7 @@ TNode<Code> CodeStubAssembler::GetSharedFunctionInfoCode(
sfi_code = CAST(LoadObjectField(CAST(sfi_data),
WasmCapiFunctionData::kWrapperCodeOffset));
Goto(&done);
#endif // V8_ENABLE_WEBASSEMBLY
BIND(&done);
return sfi_code.value();

View File

@ -319,12 +319,15 @@ namespace {
void RecordUnoptimizedCompilationStats(Isolate* isolate,
Handle<SharedFunctionInfo> shared_info) {
int code_size;
if (shared_info->HasBytecodeArray()) {
code_size = shared_info->GetBytecodeArray(isolate).SizeIncludingMetadata();
} else {
code_size = shared_info->asm_wasm_data().Size();
}
#if V8_ENABLE_WEBASSEMBLY
int code_size =
shared_info->HasBytecodeArray()
? shared_info->GetBytecodeArray(isolate).SizeIncludingMetadata()
: shared_info->asm_wasm_data().Size();
#else
int code_size =
shared_info->GetBytecodeArray(isolate).SizeIncludingMetadata();
#endif // V8_ENABLE_WEBASSEMBLY
Counters* counters = isolate->counters();
// TODO(4280): Rename counters from "baseline" to "unoptimized" eventually.
@ -574,12 +577,16 @@ void InstallUnoptimizedCode(UnoptimizedCompilationInfo* compilation_info,
isolate, compilation_info->feedback_vector_spec());
shared_info->set_feedback_metadata(*feedback_metadata);
} else {
#if V8_ENABLE_WEBASSEMBLY
DCHECK(compilation_info->has_asm_wasm_data());
// We should only have asm/wasm data when finalizing on the main thread.
DCHECK((std::is_same<LocalIsolate, Isolate>::value));
shared_info->set_asm_wasm_data(*compilation_info->asm_wasm_data());
shared_info->set_feedback_metadata(
ReadOnlyRoots(isolate).empty_feedback_metadata());
#else
UNREACHABLE();
#endif // V8_ENABLE_WEBASSEMBLY
}
}

View File

@ -170,6 +170,7 @@ StackFrame::Type OptimizedCompilationInfo::GetOutputStackFrameType() const {
case CodeKind::BYTECODE_HANDLER:
case CodeKind::BUILTIN:
return StackFrame::STUB;
#if V8_ENABLE_WEBASSEMBLY
case CodeKind::WASM_FUNCTION:
return StackFrame::WASM;
case CodeKind::WASM_TO_CAPI_FUNCTION:
@ -180,6 +181,7 @@ StackFrame::Type OptimizedCompilationInfo::GetOutputStackFrameType() const {
return StackFrame::WASM_TO_JS;
case CodeKind::C_WASM_ENTRY:
return StackFrame::C_WASM_ENTRY;
#endif // V8_ENABLE_WEBASSEMBLY
default:
UNIMPLEMENTED();
return StackFrame::NONE;

View File

@ -15,8 +15,11 @@
#include "src/heap/memory-chunk.h"
#include "src/numbers/double.h"
#include "src/utils/boxed-float.h"
#if V8_ENABLE_WEBASSEMBLY
#include "src/wasm/wasm-code-manager.h"
#include "src/wasm/wasm-objects.h"
#endif // V8_ENABLE_WEBASSEMBLY
namespace v8 {
namespace internal {
@ -120,11 +123,12 @@ class ArmOperandConverter final : public InstructionOperandConverter {
Constant constant = ToConstant(operand);
switch (constant.type()) {
case Constant::kInt32:
#if V8_ENABLE_WEBASSEMBLY
if (RelocInfo::IsWasmReference(constant.rmode())) {
return Operand(constant.ToInt32(), constant.rmode());
} else {
return Operand(constant.ToInt32());
}
#endif // V8_ENABLE_WEBASSEMBLY
return Operand(constant.ToInt32());
case Constant::kFloat32:
return Operand::EmbeddedNumber(constant.ToFloat32());
case Constant::kFloat64:
@ -180,10 +184,13 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
offset_(offset),
value_(value),
mode_(mode),
#if V8_ENABLE_WEBASSEMBLY
stub_mode_(stub_mode),
#endif // V8_ENABLE_WEBASSEMBLY
must_save_lr_(!gen->frame_access_state()->has_frame()),
unwinding_info_writer_(unwinding_info_writer),
zone_(gen->zone()) {}
zone_(gen->zone()) {
}
void Generate() final {
if (mode_ > RecordWriteMode::kValueIsPointer) {
@ -203,9 +210,11 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
}
if (mode_ == RecordWriteMode::kValueIsEphemeronKey) {
__ CallEphemeronKeyBarrier(object_, offset_, save_fp_mode);
#if V8_ENABLE_WEBASSEMBLY
} else if (stub_mode_ == StubCallMode::kCallWasmRuntimeStub) {
__ CallRecordWriteStub(object_, offset_, remembered_set_action,
save_fp_mode, wasm::WasmCode::kRecordWrite);
#endif // V8_ENABLE_WEBASSEMBLY
} else {
__ CallRecordWriteStub(object_, offset_, remembered_set_action,
save_fp_mode);
@ -221,7 +230,9 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
Operand const offset_;
Register const value_;
RecordWriteMode const mode_;
#if V8_ENABLE_WEBASSEMBLY
StubCallMode stub_mode_;
#endif // V8_ENABLE_WEBASSEMBLY
bool must_save_lr_;
UnwindingInfoWriter* const unwinding_info_writer_;
Zone* zone_;
@ -749,6 +760,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
frame_access_state()->ClearSPDelta();
break;
}
#if V8_ENABLE_WEBASSEMBLY
case kArchCallWasmFunction: {
if (instr->InputAt(0)->IsImmediate()) {
Constant constant = i.ToConstant(instr->InputAt(0));
@ -762,6 +774,21 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
frame_access_state()->ClearSPDelta();
break;
}
case kArchTailCallWasm: {
if (instr->InputAt(0)->IsImmediate()) {
Constant constant = i.ToConstant(instr->InputAt(0));
Address wasm_code = static_cast<Address>(constant.ToInt32());
__ Jump(wasm_code, constant.rmode());
} else {
__ Jump(i.InputRegister(0));
}
DCHECK_EQ(LeaveCC, i.OutputSBit());
unwinding_info_writer_.MarkBlockWillExit();
frame_access_state()->ClearSPDelta();
frame_access_state()->SetFrameAccessToDefault();
break;
}
#endif // V8_ENABLE_WEBASSEMBLY
case kArchTailCallCodeObject: {
if (instr->InputAt(0)->IsImmediate()) {
__ Jump(i.InputCode(0), RelocInfo::CODE_TARGET);
@ -778,20 +805,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
frame_access_state()->SetFrameAccessToDefault();
break;
}
case kArchTailCallWasm: {
if (instr->InputAt(0)->IsImmediate()) {
Constant constant = i.ToConstant(instr->InputAt(0));
Address wasm_code = static_cast<Address>(constant.ToInt32());
__ Jump(wasm_code, constant.rmode());
} else {
__ Jump(i.InputRegister(0));
}
DCHECK_EQ(LeaveCC, i.OutputSBit());
unwinding_info_writer_.MarkBlockWillExit();
frame_access_state()->ClearSPDelta();
frame_access_state()->SetFrameAccessToDefault();
break;
}
case kArchTailCallAddress: {
CHECK(!instr->InputAt(0)->IsImmediate());
Register reg = i.InputRegister(0);
@ -859,10 +872,12 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
break;
case kArchCallCFunction: {
int const num_parameters = MiscField::decode(instr->opcode());
#if V8_ENABLE_WEBASSEMBLY
if (linkage()->GetIncomingDescriptor()->IsWasmCapiFunction()) {
// Put the return address in a stack slot.
__ str(pc, MemOperand(fp, WasmExitFrameConstants::kCallingPCOffset));
}
#endif // V8_ENABLE_WEBASSEMBLY
if (instr->InputAt(0)->IsImmediate()) {
ExternalReference ref = i.InputExternalReference(0);
__ CallCFunction(ref, num_parameters);
@ -870,9 +885,11 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
Register func = i.InputRegister(0);
__ CallCFunction(func, num_parameters);
}
#if V8_ENABLE_WEBASSEMBLY
if (linkage()->GetIncomingDescriptor()->IsWasmCapiFunction()) {
RecordSafepoint(instr->reference_map());
}
#endif // V8_ENABLE_WEBASSEMBLY
frame_access_state()->SetFrameAccessToDefault();
// Ideally, we should decrement SP delta to match the change of stack
// pointer in CallCFunction. However, for certain architectures (e.g.
@ -3644,6 +3661,7 @@ void CodeGenerator::AssembleArchJump(RpoNumber target) {
if (!IsNextInAssemblyOrder(target)) __ b(GetLabel(target));
}
#if V8_ENABLE_WEBASSEMBLY
void CodeGenerator::AssembleArchTrap(Instruction* instr,
FlagsCondition condition) {
class OutOfLineTrap final : public OutOfLineCode {
@ -3697,6 +3715,7 @@ void CodeGenerator::AssembleArchTrap(Instruction* instr,
Condition cc = FlagsConditionToCondition(condition);
__ b(cc, tlabel);
}
#endif // V8_ENABLE_WEBASSEMBLY
// Assembles boolean materializations after an instruction.
void CodeGenerator::AssembleArchBoolean(Instruction* instr,
@ -3768,9 +3787,13 @@ void CodeGenerator::AssembleConstructFrame() {
if (frame_access_state()->has_frame()) {
if (call_descriptor->IsCFunctionCall()) {
if (info()->GetOutputStackFrameType() == StackFrame::C_WASM_ENTRY) {
#if V8_ENABLE_WEBASSEMBLY
__ StubPrologue(StackFrame::C_WASM_ENTRY);
// Reserve stack space for saving the c_entry_fp later.
__ AllocateStackSpace(kSystemPointerSize);
#else
UNREACHABLE();
#endif // V8_ENABLE_WEBASSEMBLY
} else {
__ Push(lr, fp);
__ mov(fp, sp);
@ -3779,6 +3802,7 @@ void CodeGenerator::AssembleConstructFrame() {
__ Prologue();
} else {
__ StubPrologue(info()->GetOutputStackFrameType());
#if V8_ENABLE_WEBASSEMBLY
if (call_descriptor->IsWasmFunctionCall()) {
__ Push(kWasmInstanceRegister);
} else if (call_descriptor->IsWasmImportWrapper() ||
@ -3797,6 +3821,7 @@ void CodeGenerator::AssembleConstructFrame() {
__ AllocateStackSpace(kSystemPointerSize);
}
}
#endif // V8_ENABLE_WEBASSEMBLY
}
unwinding_info_writer_.MarkFrameConstructed(__ pc_offset());
@ -3824,6 +3849,7 @@ void CodeGenerator::AssembleConstructFrame() {
if (required_slots > 0) {
DCHECK(frame_access_state()->has_frame());
#if V8_ENABLE_WEBASSEMBLY
if (info()->IsWasm() && required_slots > 128) {
// For WebAssembly functions with big frames we have to do the stack
// overflow check before we construct the frame. Otherwise we may not
@ -3856,6 +3882,7 @@ void CodeGenerator::AssembleConstructFrame() {
__ bind(&done);
}
#endif // V8_ENABLE_WEBASSEMBLY
// Skip callee-saved and return slots, which are pushed below.
required_slots -= base::bits::CountPopulation(saves);

View File

@ -112,6 +112,7 @@ void VisitSimdShiftRRR(InstructionSelector* selector, ArchOpcode opcode,
}
}
#if V8_ENABLE_WEBASSEMBLY
void VisitRRRShuffle(InstructionSelector* selector, ArchOpcode opcode,
Node* node) {
ArmOperandGenerator g(selector);
@ -132,6 +133,7 @@ void VisitRRRShuffle(InstructionSelector* selector, ArchOpcode opcode,
g.UseRegister(node->InputAt(0)),
g.UseRegister(node->InputAt(1)));
}
#endif // V8_ENABLE_WEBASSEMBLY
void VisitRRI(InstructionSelector* selector, ArchOpcode opcode, Node* node) {
ArmOperandGenerator g(selector);
@ -2833,6 +2835,7 @@ void InstructionSelector::VisitS128Select(Node* node) {
g.UseRegister(node->InputAt(2)));
}
#if V8_ENABLE_WEBASSEMBLY
namespace {
struct ShuffleEntry {
@ -2979,6 +2982,9 @@ void InstructionSelector::VisitI8x16Shuffle(Node* node) {
g.UseImmediate(wasm::SimdShuffle::Pack4Lanes(shuffle + 8)),
g.UseImmediate(wasm::SimdShuffle::Pack4Lanes(shuffle + 12)));
}
#else
void InstructionSelector::VisitI8x16Shuffle(Node* node) { UNREACHABLE(); }
#endif // V8_ENABLE_WEBASSEMBLY
void InstructionSelector::VisitI8x16Swizzle(Node* node) {
ArmOperandGenerator g(this);

View File

@ -12,8 +12,11 @@
#include "src/compiler/osr.h"
#include "src/execution/frame-constants.h"
#include "src/heap/memory-chunk.h"
#if V8_ENABLE_WEBASSEMBLY
#include "src/wasm/wasm-code-manager.h"
#include "src/wasm/wasm-objects.h"
#endif // V8_ENABLE_WEBASSEMBLY
namespace v8 {
namespace internal {
@ -212,11 +215,12 @@ class Arm64OperandConverter final : public InstructionOperandConverter {
case Constant::kInt32:
return Operand(constant.ToInt32());
case Constant::kInt64:
#if V8_ENABLE_WEBASSEMBLY
if (RelocInfo::IsWasmReference(constant.rmode())) {
return Operand(constant.ToInt64(), constant.rmode());
} else {
return Operand(constant.ToInt64());
}
#endif // V8_ENABLE_WEBASSEMBLY
return Operand(constant.ToInt64());
case Constant::kFloat32:
return Operand(Operand::EmbeddedNumber(constant.ToFloat32()));
case Constant::kFloat64:
@ -269,10 +273,13 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
offset_(offset),
value_(value),
mode_(mode),
#if V8_ENABLE_WEBASSEMBLY
stub_mode_(stub_mode),
#endif // V8_ENABLE_WEBASSEMBLY
must_save_lr_(!gen->frame_access_state()->has_frame()),
unwinding_info_writer_(unwinding_info_writer),
zone_(gen->zone()) {}
zone_(gen->zone()) {
}
void Generate() final {
if (mode_ > RecordWriteMode::kValueIsPointer) {
@ -295,12 +302,14 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
}
if (mode_ == RecordWriteMode::kValueIsEphemeronKey) {
__ CallEphemeronKeyBarrier(object_, offset_, save_fp_mode);
#if V8_ENABLE_WEBASSEMBLY
} else if (stub_mode_ == StubCallMode::kCallWasmRuntimeStub) {
// A direct call to a wasm runtime stub defined in this module.
// Just encode the stub index. This will be patched when the code
// is added to the native module and copied into wasm code space.
__ CallRecordWriteStub(object_, offset_, remembered_set_action,
save_fp_mode, wasm::WasmCode::kRecordWrite);
#endif // V8_ENABLE_WEBASSEMBLY
} else {
__ CallRecordWriteStub(object_, offset_, remembered_set_action,
save_fp_mode);
@ -316,7 +325,9 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
Operand const offset_;
Register const value_;
RecordWriteMode const mode_;
#if V8_ENABLE_WEBASSEMBLY
StubCallMode const stub_mode_;
#endif // V8_ENABLE_WEBASSEMBLY
bool must_save_lr_;
UnwindingInfoWriter* const unwinding_info_writer_;
Zone* zone_;
@ -375,6 +386,7 @@ Condition FlagsConditionToCondition(FlagsCondition condition) {
UNREACHABLE();
}
#if V8_ENABLE_WEBASSEMBLY
class WasmOutOfLineTrap : public OutOfLineCode {
public:
WasmOutOfLineTrap(CodeGenerator* gen, Instruction* instr)
@ -436,12 +448,17 @@ class WasmProtectedInstructionTrap final : public WasmOutOfLineTrap {
void EmitOOLTrapIfNeeded(Zone* zone, CodeGenerator* codegen,
InstructionCode opcode, Instruction* instr, int pc) {
const MemoryAccessMode access_mode =
static_cast<MemoryAccessMode>(AccessModeField::decode(opcode));
const MemoryAccessMode access_mode = AccessModeField::decode(opcode);
if (access_mode == kMemoryAccessProtected) {
zone->New<WasmProtectedInstructionTrap>(codegen, pc, instr);
}
}
#else
void EmitOOLTrapIfNeeded(Zone* zone, CodeGenerator* codegen,
InstructionCode opcode, Instruction* instr, int pc) {
DCHECK_NE(kMemoryAccessProtected, AccessModeField::decode(opcode));
}
#endif // V8_ENABLE_WEBASSEMBLY
void EmitWordLoadPoisoningIfNeeded(CodeGenerator* codegen,
InstructionCode opcode, Instruction* instr,
@ -749,6 +766,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
frame_access_state()->ClearSPDelta();
break;
}
#if V8_ENABLE_WEBASSEMBLY
case kArchCallWasmFunction: {
if (instr->InputAt(0)->IsImmediate()) {
Constant constant = i.ToConstant(instr->InputAt(0));
@ -762,21 +780,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
frame_access_state()->ClearSPDelta();
break;
}
case kArchTailCallCodeObject: {
if (instr->InputAt(0)->IsImmediate()) {
__ Jump(i.InputCode(0), RelocInfo::CODE_TARGET);
} else {
Register reg = i.InputRegister(0);
DCHECK_IMPLIES(
instr->HasCallDescriptorFlag(CallDescriptor::kFixedTargetRegister),
reg == kJavaScriptCallCodeStartRegister);
__ JumpCodeObject(reg);
}
unwinding_info_writer_.MarkBlockWillExit();
frame_access_state()->ClearSPDelta();
frame_access_state()->SetFrameAccessToDefault();
break;
}
case kArchTailCallWasm: {
if (instr->InputAt(0)->IsImmediate()) {
Constant constant = i.ToConstant(instr->InputAt(0));
@ -794,6 +797,22 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
frame_access_state()->SetFrameAccessToDefault();
break;
}
#endif // V8_ENABLE_WEBASSEMBLY
case kArchTailCallCodeObject: {
if (instr->InputAt(0)->IsImmediate()) {
__ Jump(i.InputCode(0), RelocInfo::CODE_TARGET);
} else {
Register reg = i.InputRegister(0);
DCHECK_IMPLIES(
instr->HasCallDescriptorFlag(CallDescriptor::kFixedTargetRegister),
reg == kJavaScriptCallCodeStartRegister);
__ JumpCodeObject(reg);
}
unwinding_info_writer_.MarkBlockWillExit();
frame_access_state()->ClearSPDelta();
frame_access_state()->SetFrameAccessToDefault();
break;
}
case kArchTailCallAddress: {
CHECK(!instr->InputAt(0)->IsImmediate());
Register reg = i.InputRegister(0);
@ -867,10 +886,12 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kArchCallCFunction: {
int const num_parameters = MiscField::decode(instr->opcode());
Label return_location;
#if V8_ENABLE_WEBASSEMBLY
if (linkage()->GetIncomingDescriptor()->IsWasmCapiFunction()) {
// Put the return address in a stack slot.
__ StoreReturnAddressInWasmExitFrame(&return_location);
}
#endif // V8_ENABLE_WEBASSEMBLY
if (instr->InputAt(0)->IsImmediate()) {
ExternalReference ref = i.InputExternalReference(0);
@ -880,9 +901,11 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ CallCFunction(func, num_parameters, 0);
}
__ Bind(&return_location);
#if V8_ENABLE_WEBASSEMBLY
if (linkage()->GetIncomingDescriptor()->IsWasmCapiFunction()) {
RecordSafepoint(instr->reference_map());
}
#endif // V8_ENABLE_WEBASSEMBLY
frame_access_state()->SetFrameAccessToDefault();
// Ideally, we should decrement SP delta to match the change of stack
// pointer in CallCFunction. However, for certain architectures (e.g.
@ -2931,6 +2954,7 @@ void CodeGenerator::AssembleArchJump(RpoNumber target) {
if (!IsNextInAssemblyOrder(target)) __ B(GetLabel(target));
}
#if V8_ENABLE_WEBASSEMBLY
void CodeGenerator::AssembleArchTrap(Instruction* instr,
FlagsCondition condition) {
auto ool = zone()->New<WasmOutOfLineTrap>(this, instr);
@ -2938,6 +2962,7 @@ void CodeGenerator::AssembleArchTrap(Instruction* instr,
Condition cc = FlagsConditionToCondition(condition);
__ B(cc, tlabel);
}
#endif // V8_ENABLE_WEBASSEMBLY
// Assemble boolean materializations after this instruction.
void CodeGenerator::AssembleArchBoolean(Instruction* instr,
@ -3070,6 +3095,7 @@ void CodeGenerator::AssembleConstructFrame() {
ResetSpeculationPoison();
}
#if V8_ENABLE_WEBASSEMBLY
if (info()->IsWasm() && required_slots > 128) {
// For WebAssembly functions with big frames we have to do the stack
// overflow check before we construct the frame. Otherwise we may not
@ -3109,6 +3135,7 @@ void CodeGenerator::AssembleConstructFrame() {
}
__ Bind(&done);
}
#endif // V8_ENABLE_WEBASSEMBLY
// Skip callee-saved slots, which are pushed below.
required_slots -= saves.Count();
@ -3137,6 +3164,7 @@ void CodeGenerator::AssembleConstructFrame() {
DCHECK_GE(required_slots, 1);
__ Claim(required_slots - 1);
} break;
#if V8_ENABLE_WEBASSEMBLY
case CallDescriptor::kCallWasmFunction: {
UseScratchRegisterScope temps(tasm());
Register scratch = temps.AcquireX();
@ -3164,7 +3192,9 @@ void CodeGenerator::AssembleConstructFrame() {
: 1; // C-API function: PC.
__ Claim(required_slots + extra_slots);
} break;
#endif // V8_ENABLE_WEBASSEMBLY
case CallDescriptor::kCallAddress:
#if V8_ENABLE_WEBASSEMBLY
if (info()->GetOutputStackFrameType() == StackFrame::C_WASM_ENTRY) {
UseScratchRegisterScope temps(tasm());
Register scratch = temps.AcquireX();
@ -3172,6 +3202,7 @@ void CodeGenerator::AssembleConstructFrame() {
__ Push(scratch, padreg);
// The additional slot will be used for the saved c_entry_fp.
}
#endif // V8_ENABLE_WEBASSEMBLY
__ Claim(required_slots);
break;
default:

View File

@ -3762,6 +3762,7 @@ VISIT_SIMD_QFMOP(F32x4Qfma)
VISIT_SIMD_QFMOP(F32x4Qfms)
#undef VISIT_SIMD_QFMOP
#if V8_ENABLE_WEBASSEMBLY
namespace {
struct ShuffleEntry {
@ -3909,6 +3910,9 @@ void InstructionSelector::VisitI8x16Shuffle(Node* node) {
g.UseImmediate(wasm::SimdShuffle::Pack4Lanes(shuffle + 8)),
g.UseImmediate(wasm::SimdShuffle::Pack4Lanes(shuffle + 12)));
}
#else
void InstructionSelector::VisitI8x16Shuffle(Node* node) { UNREACHABLE(); }
#endif // V8_ENABLE_WEBASSEMBLY
void InstructionSelector::VisitSignExtendWord8ToInt32(Node* node) {
VisitRR(this, kArm64Sxtb32, node);

View File

@ -875,7 +875,11 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleInstruction(
break;
}
case kFlags_trap: {
#if V8_ENABLE_WEBASSEMBLY
AssembleArchTrap(instr, condition);
#else
UNREACHABLE();
#endif // V8_ENABLE_WEBASSEMBLY
break;
}
case kFlags_none: {
@ -937,12 +941,15 @@ bool CodeGenerator::GetSlotAboveSPBeforeTailCall(Instruction* instr,
}
StubCallMode CodeGenerator::DetermineStubCallMode() const {
#if V8_ENABLE_WEBASSEMBLY
CodeKind code_kind = info()->code_kind();
return (code_kind == CodeKind::WASM_FUNCTION ||
code_kind == CodeKind::WASM_TO_CAPI_FUNCTION ||
code_kind == CodeKind::WASM_TO_JS_FUNCTION)
? StubCallMode::kCallWasmRuntimeStub
: StubCallMode::kCallCodeObject;
if (code_kind == CodeKind::WASM_FUNCTION ||
code_kind == CodeKind::WASM_TO_CAPI_FUNCTION ||
code_kind == CodeKind::WASM_TO_JS_FUNCTION) {
return StubCallMode::kCallWasmRuntimeStub;
}
#endif // V8_ENABLE_WEBASSEMBLY
return StubCallMode::kCallCodeObject;
}
void CodeGenerator::AssembleGaps(Instruction* instr) {
@ -1176,6 +1183,7 @@ void CodeGenerator::BuildTranslationForFrameStateDescriptor(
height);
break;
}
#if V8_ENABLE_WEBASSEMBLY
case FrameStateType::kJSToWasmBuiltinContinuation: {
const JSToWasmFrameStateDescriptor* js_to_wasm_descriptor =
static_cast<const JSToWasmFrameStateDescriptor*>(descriptor);
@ -1184,6 +1192,7 @@ void CodeGenerator::BuildTranslationForFrameStateDescriptor(
js_to_wasm_descriptor->return_kind());
break;
}
#endif // V8_ENABLE_WEBASSEMBLY
case FrameStateType::kJavaScriptBuiltinContinuation: {
translations_.BeginJavaScriptBuiltinContinuationFrame(
bailout_id, shared_info_id, height);

View File

@ -261,7 +261,9 @@ class V8_EXPORT_PRIVATE CodeGenerator final : public GapResolver::Assembler {
void AssembleArchDeoptBranch(Instruction* instr, BranchInfo* branch);
void AssembleArchBoolean(Instruction* instr, FlagsCondition condition);
#if V8_ENABLE_WEBASSEMBLY
void AssembleArchTrap(Instruction* instr, FlagsCondition condition);
#endif // V8_ENABLE_WEBASSEMBLY
void AssembleArchBinarySearchSwitchRange(Register input, RpoNumber def_block,
std::pair<int32_t, Label*>* begin,
std::pair<int32_t, Label*>* end);

View File

@ -18,8 +18,11 @@
#include "src/execution/frames.h"
#include "src/heap/memory-chunk.h"
#include "src/objects/smi.h"
#if V8_ENABLE_WEBASSEMBLY
#include "src/wasm/wasm-code-manager.h"
#include "src/wasm/wasm-objects.h"
#endif // V8_ENABLE_WEBASSEMBLY
namespace v8 {
namespace internal {
@ -65,11 +68,13 @@ class IA32OperandConverter : public InstructionOperandConverter {
Immediate ToImmediate(InstructionOperand* operand) {
Constant constant = ToConstant(operand);
#if V8_ENABLE_WEBASSEMBLY
if (constant.type() == Constant::kInt32 &&
RelocInfo::IsWasmReference(constant.rmode())) {
return Immediate(static_cast<Address>(constant.ToInt32()),
constant.rmode());
}
#endif // V8_ENABLE_WEBASSEMBLY
switch (constant.type()) {
case Constant::kInt32:
return Immediate(constant.ToInt32());
@ -257,18 +262,26 @@ class OutOfLineTruncateDoubleToI final : public OutOfLineCode {
: OutOfLineCode(gen),
result_(result),
input_(input),
#if V8_ENABLE_WEBASSEMBLY
stub_mode_(stub_mode),
#endif // V8_ENABLE_WEBASSEMBLY
isolate_(gen->isolate()),
zone_(gen->zone()) {}
zone_(gen->zone()) {
}
void Generate() final {
__ AllocateStackSpace(kDoubleSize);
__ Movsd(MemOperand(esp, 0), input_);
#if V8_ENABLE_WEBASSEMBLY
if (stub_mode_ == StubCallMode::kCallWasmRuntimeStub) {
// A direct call to a wasm runtime stub defined in this module.
// Just encode the stub index. This will be patched when the code
// is added to the native module and copied into wasm code space.
__ wasm_call(wasm::WasmCode::kDoubleToI, RelocInfo::WASM_STUB_CALL);
#else
// For balance.
if (false) {
#endif // V8_ENABLE_WEBASSEMBLY
} else if (tasm()->options().inline_offheap_trampolines) {
__ CallBuiltin(Builtins::kDoubleToI);
} else {
@ -281,7 +294,9 @@ class OutOfLineTruncateDoubleToI final : public OutOfLineCode {
private:
Register const result_;
XMMRegister const input_;
#if V8_ENABLE_WEBASSEMBLY
StubCallMode stub_mode_;
#endif // V8_ENABLE_WEBASSEMBLY
Isolate* isolate_;
Zone* zone_;
};
@ -298,8 +313,11 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
scratch0_(scratch0),
scratch1_(scratch1),
mode_(mode),
#if V8_ENABLE_WEBASSEMBLY
stub_mode_(stub_mode),
zone_(gen->zone()) {}
#endif // V8_ENABLE_WEBASSEMBLY
zone_(gen->zone()) {
}
void Generate() final {
if (mode_ > RecordWriteMode::kValueIsPointer) {
@ -316,6 +334,7 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs;
if (mode_ == RecordWriteMode::kValueIsEphemeronKey) {
__ CallEphemeronKeyBarrier(object_, scratch1_, save_fp_mode);
#if V8_ENABLE_WEBASSEMBLY
} else if (stub_mode_ == StubCallMode::kCallWasmRuntimeStub) {
// A direct call to a wasm runtime stub defined in this module.
// Just encode the stub index. This will be patched when the code
@ -323,6 +342,7 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
__ CallRecordWriteStub(object_, scratch1_, remembered_set_action,
save_fp_mode, wasm::WasmCode::kRecordWrite);
} else {
#endif // V8_ENABLE_WEBASSEMBLY
__ CallRecordWriteStub(object_, scratch1_, remembered_set_action,
save_fp_mode);
}
@ -335,7 +355,9 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
Register const scratch0_;
Register const scratch1_;
RecordWriteMode const mode_;
#if V8_ENABLE_WEBASSEMBLY
StubCallMode const stub_mode_;
#endif // V8_ENABLE_WEBASSEMBLY
Zone* zone_;
};
@ -707,6 +729,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
frame_access_state()->ClearSPDelta();
break;
}
#if V8_ENABLE_WEBASSEMBLY
case kArchCallWasmFunction: {
if (HasImmediateInput(instr, 0)) {
Constant constant = i.ToConstant(instr->InputAt(0));
@ -732,16 +755,13 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
frame_access_state()->ClearSPDelta();
break;
}
case kArchTailCallCodeObject: {
case kArchTailCallWasm: {
if (HasImmediateInput(instr, 0)) {
Handle<Code> code = i.InputCode(0);
__ Jump(code, RelocInfo::CODE_TARGET);
Constant constant = i.ToConstant(instr->InputAt(0));
Address wasm_code = static_cast<Address>(constant.ToInt32());
__ jmp(wasm_code, constant.rmode());
} else {
Register reg = i.InputRegister(0);
DCHECK_IMPLIES(
instr->HasCallDescriptorFlag(CallDescriptor::kFixedTargetRegister),
reg == kJavaScriptCallCodeStartRegister);
__ LoadCodeObjectEntry(reg, reg);
if (instr->HasCallDescriptorFlag(CallDescriptor::kRetpoline)) {
__ RetpolineJump(reg);
} else {
@ -752,13 +772,17 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
frame_access_state()->SetFrameAccessToDefault();
break;
}
case kArchTailCallWasm: {
#endif // V8_ENABLE_WEBASSEMBLY
case kArchTailCallCodeObject: {
if (HasImmediateInput(instr, 0)) {
Constant constant = i.ToConstant(instr->InputAt(0));
Address wasm_code = static_cast<Address>(constant.ToInt32());
__ jmp(wasm_code, constant.rmode());
Handle<Code> code = i.InputCode(0);
__ Jump(code, RelocInfo::CODE_TARGET);
} else {
Register reg = i.InputRegister(0);
DCHECK_IMPLIES(
instr->HasCallDescriptorFlag(CallDescriptor::kFixedTargetRegister),
reg == kJavaScriptCallCodeStartRegister);
__ LoadCodeObjectEntry(reg, reg);
if (instr->HasCallDescriptorFlag(CallDescriptor::kRetpoline)) {
__ RetpolineJump(reg);
} else {
@ -836,6 +860,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kArchCallCFunction: {
int const num_parameters = MiscField::decode(instr->opcode());
Label return_location;
#if V8_ENABLE_WEBASSEMBLY
if (linkage()->GetIncomingDescriptor()->IsWasmCapiFunction()) {
// Put the return address in a stack slot.
Register scratch = eax;
@ -849,6 +874,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
scratch);
__ pop(scratch);
}
#endif // V8_ENABLE_WEBASSEMBLY
if (HasImmediateInput(instr, 0)) {
ExternalReference ref = i.InputExternalReference(0);
__ CallCFunction(ref, num_parameters);
@ -857,9 +883,11 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ CallCFunction(func, num_parameters);
}
__ bind(&return_location);
#if V8_ENABLE_WEBASSEMBLY
if (linkage()->GetIncomingDescriptor()->IsWasmCapiFunction()) {
RecordSafepoint(instr->reference_map());
}
#endif // V8_ENABLE_WEBASSEMBLY
frame_access_state()->SetFrameAccessToDefault();
// Ideally, we should decrement SP delta to match the change of stack
// pointer in CallCFunction. However, for certain architectures (e.g.
@ -4340,6 +4368,7 @@ void CodeGenerator::AssembleArchJump(RpoNumber target) {
if (!IsNextInAssemblyOrder(target)) __ jmp(GetLabel(target));
}
#if V8_ENABLE_WEBASSEMBLY
void CodeGenerator::AssembleArchTrap(Instruction* instr,
FlagsCondition condition) {
class OutOfLineTrap final : public OutOfLineCode {
@ -4395,6 +4424,7 @@ void CodeGenerator::AssembleArchTrap(Instruction* instr,
__ j(FlagsConditionToCondition(condition), tlabel);
__ bind(&end);
}
#endif // V8_ENABLE_WEBASSEMBLY
// Assembles boolean materializations after an instruction.
void CodeGenerator::AssembleArchBoolean(Instruction* instr,
@ -4606,15 +4636,18 @@ void CodeGenerator::AssembleConstructFrame() {
if (call_descriptor->IsCFunctionCall()) {
__ push(ebp);
__ mov(ebp, esp);
#if V8_ENABLE_WEBASSEMBLY
if (info()->GetOutputStackFrameType() == StackFrame::C_WASM_ENTRY) {
__ Push(Immediate(StackFrame::TypeToMarker(StackFrame::C_WASM_ENTRY)));
// Reserve stack space for saving the c_entry_fp later.
__ AllocateStackSpace(kSystemPointerSize);
}
#endif // V8_ENABLE_WEBASSEMBLY
} else if (call_descriptor->IsJSFunctionCall()) {
__ Prologue();
} else {
__ StubPrologue(info()->GetOutputStackFrameType());
#if V8_ENABLE_WEBASSEMBLY
if (call_descriptor->IsWasmFunctionCall()) {
__ push(kWasmInstanceRegister);
} else if (call_descriptor->IsWasmImportWrapper() ||
@ -4635,6 +4668,7 @@ void CodeGenerator::AssembleConstructFrame() {
__ AllocateStackSpace(kSystemPointerSize);
}
}
#endif // V8_ENABLE_WEBASSEMBLY
}
}
@ -4657,6 +4691,7 @@ void CodeGenerator::AssembleConstructFrame() {
const RegList saves = call_descriptor->CalleeSavedRegisters();
if (required_slots > 0) {
DCHECK(frame_access_state()->has_frame());
#if V8_ENABLE_WEBASSEMBLY
if (info()->IsWasm() && required_slots > 128) {
// For WebAssembly functions with big frames we have to do the stack
// overflow check before we construct the frame. Otherwise we may not
@ -4687,6 +4722,7 @@ void CodeGenerator::AssembleConstructFrame() {
__ AssertUnreachable(AbortReason::kUnexpectedReturnFromWasmTrap);
__ bind(&done);
}
#endif // V8_ENABLE_WEBASSEMBLY
// Skip callee-saved and return slots, which are created below.
required_slots -= base::bits::CountPopulation(saves);

View File

@ -2734,6 +2734,7 @@ void InstructionSelector::VisitInt64AbsWithOverflow(Node* node) {
UNREACHABLE();
}
#if V8_ENABLE_WEBASSEMBLY
namespace {
// Returns true if shuffle can be decomposed into two 16x4 half shuffles
@ -3023,6 +3024,9 @@ void InstructionSelector::VisitI8x16Shuffle(Node* node) {
}
Emit(opcode, 1, &dst, input_count, inputs, temp_count, temps);
}
#else
void InstructionSelector::VisitI8x16Shuffle(Node* node) { UNREACHABLE(); }
#endif // V8_ENABLE_WEBASSEMBLY
void InstructionSelector::VisitI8x16Swizzle(Node* node) {
IA32OperandGenerator g(this);

View File

@ -71,12 +71,12 @@ inline RecordWriteMode WriteBarrierKindToRecordWriteMode(
/* IsCallWithDescriptorFlags fast */ \
V(ArchTailCallCodeObject) \
V(ArchTailCallAddress) \
V(ArchTailCallWasm) \
IF_WASM(V, ArchTailCallWasm) \
/* Update IsTailCall if further TailCall opcodes are added */ \
\
V(ArchCallCodeObject) \
V(ArchCallJSFunction) \
V(ArchCallWasmFunction) \
IF_WASM(V, ArchCallWasmFunction) \
V(ArchCallBuiltinPointer) \
/* Update IsCallWithDescriptorFlags if further Call opcodes are added */ \
\

View File

@ -307,7 +307,9 @@ int InstructionScheduler::GetInstructionFlags(const Instruction* instr) const {
case kArchPrepareTailCall:
case kArchTailCallCodeObject:
case kArchTailCallAddress:
#if V8_ENABLE_WEBASSEMBLY
case kArchTailCallWasm:
#endif // V8_ENABLE_WEBASSEMBLY
case kArchAbortCSAAssert:
return kHasSideEffect;
@ -321,7 +323,9 @@ int InstructionScheduler::GetInstructionFlags(const Instruction* instr) const {
case kArchCallCFunction:
case kArchCallCodeObject:
case kArchCallJSFunction:
#if V8_ENABLE_WEBASSEMBLY
case kArchCallWasmFunction:
#endif // V8_ENABLE_WEBASSEMBLY
case kArchCallBuiltinPointer:
// Calls can cause GC and GC may relocate objects. If a pure instruction
// operates on a tagged pointer that was cast to a word then it may be

View File

@ -19,7 +19,10 @@
#include "src/compiler/schedule.h"
#include "src/compiler/state-values-utils.h"
#include "src/deoptimizer/deoptimizer.h"
#if V8_ENABLE_WEBASSEMBLY
#include "src/wasm/simd-shuffle.h"
#endif // V8_ENABLE_WEBASSEMBLY
namespace v8 {
namespace internal {
@ -2919,10 +2922,15 @@ void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) {
case CallDescriptor::kCallJSFunction:
opcode = EncodeCallDescriptorFlags(kArchCallJSFunction, flags);
break;
// TODO(clemensb): Remove these call descriptor kinds.
case CallDescriptor::kCallWasmCapiFunction:
case CallDescriptor::kCallWasmFunction:
case CallDescriptor::kCallWasmImportWrapper:
#if V8_ENABLE_WEBASSEMBLY
opcode = EncodeCallDescriptorFlags(kArchCallWasmFunction, flags);
#else
UNREACHABLE();
#endif // V8_ENABLE_WEBASSEMBLY
break;
case CallDescriptor::kCallBuiltinPointer:
opcode = EncodeCallDescriptorFlags(kArchCallBuiltinPointer, flags);
@ -2982,10 +2990,12 @@ void InstructionSelector::VisitTailCall(Node* node) {
DCHECK(!caller->IsJSFunctionCall());
opcode = kArchTailCallAddress;
break;
#if V8_ENABLE_WEBASSEMBLY
case CallDescriptor::kCallWasmFunction:
DCHECK(!caller->IsJSFunctionCall());
opcode = kArchTailCallWasm;
break;
#endif // V8_ENABLE_WEBASSEMBLY
default:
UNREACHABLE();
}
@ -3255,6 +3265,7 @@ FrameStateDescriptor* GetFrameStateDescriptorInternal(Zone* zone,
GetFrameStateDescriptorInternal(zone, state.outer_frame_state());
}
#if V8_ENABLE_WEBASSEMBLY
if (state_info.type() == FrameStateType::kJSToWasmBuiltinContinuation) {
auto function_info = static_cast<const JSToWasmFrameStateFunctionInfo*>(
state_info.function_info());
@ -3263,6 +3274,7 @@ FrameStateDescriptor* GetFrameStateDescriptorInternal(Zone* zone,
state_info.state_combine(), parameters, locals, stack,
state_info.shared_info(), outer_state, function_info->signature());
}
#endif // V8_ENABLE_WEBASSEMBLY
return zone->New<FrameStateDescriptor>(
zone, state_info.type(), state_info.bailout_id(),
@ -3281,6 +3293,7 @@ FrameStateDescriptor* InstructionSelector::GetFrameStateDescriptor(
return desc;
}
#if V8_ENABLE_WEBASSEMBLY
void InstructionSelector::CanonicalizeShuffle(Node* node, uint8_t* shuffle,
bool* is_swizzle) {
// Get raw shuffle indices.
@ -3308,6 +3321,7 @@ void InstructionSelector::SwapShuffleInputs(Node* node) {
node->ReplaceInput(0, input1);
node->ReplaceInput(1, input0);
}
#endif // V8_ENABLE_WEBASSEMBLY
// static
bool InstructionSelector::NeedsPoisoning(IsSafetyCheck safety_check) const {

View File

@ -652,6 +652,7 @@ class V8_EXPORT_PRIVATE InstructionSelector final {
// ============= Vector instruction (SIMD) helper fns. =======================
// ===========================================================================
#if V8_ENABLE_WEBASSEMBLY
// Canonicalize shuffles to make pattern matching simpler. Returns the shuffle
// indices, and a boolean indicating if the shuffle is a swizzle (one input).
void CanonicalizeShuffle(Node* node, uint8_t* shuffle, bool* is_swizzle);
@ -659,6 +660,7 @@ class V8_EXPORT_PRIVATE InstructionSelector final {
// Swaps the two first input operands of the node, to help match shuffles
// to specific architectural instructions.
void SwapShuffleInputs(Node* node);
#endif // V8_ENABLE_WEBASSEMBLY
// ===========================================================================

View File

@ -17,7 +17,10 @@
#include "src/deoptimizer/deoptimizer.h"
#include "src/execution/frames.h"
#include "src/utils/ostreams.h"
#if V8_ENABLE_WEBASSEMBLY
#include "src/wasm/value-type.h"
#endif // V8_ENABLE_WEBASSEMBLY
namespace v8 {
namespace internal {
@ -1022,7 +1025,9 @@ size_t GetConservativeFrameSizeInBytes(FrameStateType type,
return info.frame_size_in_bytes();
}
case FrameStateType::kBuiltinContinuation:
#if V8_ENABLE_WEBASSEMBLY
case FrameStateType::kJSToWasmBuiltinContinuation:
#endif // V8_ENABLE_WEBASSEMBLY
case FrameStateType::kJavaScriptBuiltinContinuation:
case FrameStateType::kJavaScriptBuiltinContinuationWithCatch: {
const RegisterConfiguration* config = RegisterConfiguration::Default();
@ -1077,7 +1082,9 @@ size_t FrameStateDescriptor::GetHeight() const {
case FrameStateType::kUnoptimizedFunction:
return locals_count(); // The accumulator is *not* included.
case FrameStateType::kBuiltinContinuation:
#if V8_ENABLE_WEBASSEMBLY
case FrameStateType::kJSToWasmBuiltinContinuation:
#endif
// Custom, non-JS calling convention (that does not have a notion of
// a receiver or context).
return parameters_count();
@ -1129,6 +1136,7 @@ size_t FrameStateDescriptor::GetJSFrameCount() const {
return count;
}
#if V8_ENABLE_WEBASSEMBLY
JSToWasmFrameStateDescriptor::JSToWasmFrameStateDescriptor(
Zone* zone, FrameStateType type, BytecodeOffset bailout_id,
OutputFrameStateCombine state_combine, size_t parameters_count,
@ -1139,6 +1147,7 @@ JSToWasmFrameStateDescriptor::JSToWasmFrameStateDescriptor(
parameters_count, locals_count, stack_count,
shared_info, outer_state),
return_kind_(wasm::WasmReturnTypeFromSignature(wasm_signature)) {}
#endif // V8_ENABLE_WEBASSEMBLY
std::ostream& operator<<(std::ostream& os, const RpoNumber& rpo) {
return os << rpo.ToSize();

View File

@ -924,7 +924,11 @@ class V8_EXPORT_PRIVATE Instruction final {
bool IsJump() const { return arch_opcode() == ArchOpcode::kArchJmp; }
bool IsRet() const { return arch_opcode() == ArchOpcode::kArchRet; }
bool IsTailCall() const {
#if V8_ENABLE_WEBASSEMBLY
return arch_opcode() <= ArchOpcode::kArchTailCallWasm;
#else
return arch_opcode() <= ArchOpcode::kArchTailCallAddress;
#endif // V8_ENABLE_WEBASSEMBLY
}
bool IsThrow() const {
return arch_opcode() == ArchOpcode::kArchThrowTerminator;
@ -1319,7 +1323,9 @@ class FrameStateDescriptor : public ZoneObject {
bool HasContext() const {
return FrameStateFunctionInfo::IsJSFunctionType(type_) ||
type_ == FrameStateType::kBuiltinContinuation ||
#if V8_ENABLE_WEBASSEMBLY
type_ == FrameStateType::kJSToWasmBuiltinContinuation ||
#endif // V8_ENABLE_WEBASSEMBLY
type_ == FrameStateType::kConstructStub;
}
@ -1359,6 +1365,7 @@ class FrameStateDescriptor : public ZoneObject {
FrameStateDescriptor* const outer_state_;
};
#if V8_ENABLE_WEBASSEMBLY
class JSToWasmFrameStateDescriptor : public FrameStateDescriptor {
public:
JSToWasmFrameStateDescriptor(Zone* zone, FrameStateType type,
@ -1375,6 +1382,7 @@ class JSToWasmFrameStateDescriptor : public FrameStateDescriptor {
private:
base::Optional<wasm::ValueKind> return_kind_;
};
#endif // V8_ENABLE_WEBASSEMBLY
// A deoptimization entry is a pair of the reason why we deoptimize and the
// frame state descriptor that we have to go back to.

View File

@ -19,8 +19,11 @@
#include "src/compiler/osr.h"
#include "src/heap/memory-chunk.h"
#include "src/objects/smi.h"
#if V8_ENABLE_WEBASSEMBLY
#include "src/wasm/wasm-code-manager.h"
#include "src/wasm/wasm-objects.h"
#endif // V8_ENABLE_WEBASSEMBLY
namespace v8 {
namespace internal {
@ -206,21 +209,29 @@ class OutOfLineTruncateDoubleToI final : public OutOfLineCode {
: OutOfLineCode(gen),
result_(result),
input_(input),
#if V8_ENABLE_WEBASSEMBLY
stub_mode_(stub_mode),
#endif // V8_ENABLE_WEBASSEMBLY
unwinding_info_writer_(unwinding_info_writer),
isolate_(gen->isolate()),
zone_(gen->zone()) {}
zone_(gen->zone()) {
}
void Generate() final {
__ AllocateStackSpace(kDoubleSize);
unwinding_info_writer_->MaybeIncreaseBaseOffsetAt(__ pc_offset(),
kDoubleSize);
__ Movsd(MemOperand(rsp, 0), input_);
#if V8_ENABLE_WEBASSEMBLY
if (stub_mode_ == StubCallMode::kCallWasmRuntimeStub) {
// A direct call to a wasm runtime stub defined in this module.
// Just encode the stub index. This will be patched when the code
// is added to the native module and copied into wasm code space.
__ near_call(wasm::WasmCode::kDoubleToI, RelocInfo::WASM_STUB_CALL);
#else
// For balance.
if (false) {
#endif // V8_ENABLE_WEBASSEMBLY
} else if (tasm()->options().inline_offheap_trampolines) {
// With embedded builtins we do not need the isolate here. This allows
// the call to be generated asynchronously.
@ -237,7 +248,9 @@ class OutOfLineTruncateDoubleToI final : public OutOfLineCode {
private:
Register const result_;
XMMRegister const input_;
#if V8_ENABLE_WEBASSEMBLY
StubCallMode stub_mode_;
#endif // V8_ENABLE_WEBASSEMBLY
UnwindingInfoWriter* const unwinding_info_writer_;
Isolate* isolate_;
Zone* zone_;
@ -255,8 +268,11 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
scratch0_(scratch0),
scratch1_(scratch1),
mode_(mode),
#if V8_ENABLE_WEBASSEMBLY
stub_mode_(stub_mode),
zone_(gen->zone()) {}
#endif // V8_ENABLE_WEBASSEMBLY
zone_(gen->zone()) {
}
void Generate() final {
if (mode_ > RecordWriteMode::kValueIsPointer) {
@ -278,12 +294,14 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
if (mode_ == RecordWriteMode::kValueIsEphemeronKey) {
__ CallEphemeronKeyBarrier(object_, scratch1_, save_fp_mode);
#if V8_ENABLE_WEBASSEMBLY
} else if (stub_mode_ == StubCallMode::kCallWasmRuntimeStub) {
// A direct call to a wasm runtime stub defined in this module.
// Just encode the stub index. This will be patched when the code
// is added to the native module and copied into wasm code space.
__ CallRecordWriteStub(object_, scratch1_, remembered_set_action,
save_fp_mode, wasm::WasmCode::kRecordWrite);
#endif // V8_ENABLE_WEBASSEMBLY
} else {
__ CallRecordWriteStub(object_, scratch1_, remembered_set_action,
save_fp_mode);
@ -297,10 +315,13 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
Register const scratch0_;
Register const scratch1_;
RecordWriteMode const mode_;
#if V8_ENABLE_WEBASSEMBLY
StubCallMode const stub_mode_;
#endif // V8_ENABLE_WEBASSEMBLY
Zone* zone_;
};
#if V8_ENABLE_WEBASSEMBLY
class WasmOutOfLineTrap : public OutOfLineCode {
public:
WasmOutOfLineTrap(CodeGenerator* gen, Instruction* instr)
@ -371,6 +392,15 @@ void EmitOOLTrapIfNeeded(Zone* zone, CodeGenerator* codegen,
}
}
#else
void EmitOOLTrapIfNeeded(Zone* zone, CodeGenerator* codegen,
InstructionCode opcode, Instruction* instr, int pc) {
DCHECK_NE(kMemoryAccessProtected, AccessModeField::decode(opcode));
}
#endif // V8_ENABLE_WEBASSEMBLY
void EmitWordLoadPoisoningIfNeeded(CodeGenerator* codegen,
InstructionCode opcode, Instruction* instr,
X64OperandConverter const& i) {
@ -872,6 +902,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
frame_access_state()->ClearSPDelta();
break;
}
#if V8_ENABLE_WEBASSEMBLY
case kArchCallWasmFunction: {
if (HasImmediateInput(instr, 0)) {
Constant constant = i.ToConstant(instr->InputAt(0));
@ -897,27 +928,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
frame_access_state()->ClearSPDelta();
break;
}
case kArchTailCallCodeObject: {
if (HasImmediateInput(instr, 0)) {
Handle<Code> code = i.InputCode(0);
__ Jump(code, RelocInfo::CODE_TARGET);
} else {
Register reg = i.InputRegister(0);
DCHECK_IMPLIES(
instr->HasCallDescriptorFlag(CallDescriptor::kFixedTargetRegister),
reg == kJavaScriptCallCodeStartRegister);
__ LoadCodeObjectEntry(reg, reg);
if (instr->HasCallDescriptorFlag(CallDescriptor::kRetpoline)) {
__ RetpolineJump(reg);
} else {
__ jmp(reg);
}
}
unwinding_info_writer_.MarkBlockWillExit();
frame_access_state()->ClearSPDelta();
frame_access_state()->SetFrameAccessToDefault();
break;
}
case kArchTailCallWasm: {
if (HasImmediateInput(instr, 0)) {
Constant constant = i.ToConstant(instr->InputAt(0));
@ -941,6 +951,28 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
frame_access_state()->SetFrameAccessToDefault();
break;
}
#endif // V8_ENABLE_WEBASSEMBLY
case kArchTailCallCodeObject: {
if (HasImmediateInput(instr, 0)) {
Handle<Code> code = i.InputCode(0);
__ Jump(code, RelocInfo::CODE_TARGET);
} else {
Register reg = i.InputRegister(0);
DCHECK_IMPLIES(
instr->HasCallDescriptorFlag(CallDescriptor::kFixedTargetRegister),
reg == kJavaScriptCallCodeStartRegister);
__ LoadCodeObjectEntry(reg, reg);
if (instr->HasCallDescriptorFlag(CallDescriptor::kRetpoline)) {
__ RetpolineJump(reg);
} else {
__ jmp(reg);
}
}
unwinding_info_writer_.MarkBlockWillExit();
frame_access_state()->ClearSPDelta();
frame_access_state()->SetFrameAccessToDefault();
break;
}
case kArchTailCallAddress: {
CHECK(!HasImmediateInput(instr, 0));
Register reg = i.InputRegister(0);
@ -1010,12 +1042,14 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kArchCallCFunction: {
int const num_parameters = MiscField::decode(instr->opcode());
Label return_location;
#if V8_ENABLE_WEBASSEMBLY
if (linkage()->GetIncomingDescriptor()->IsWasmCapiFunction()) {
// Put the return address in a stack slot.
__ leaq(kScratchRegister, Operand(&return_location, 0));
__ movq(MemOperand(rbp, WasmExitFrameConstants::kCallingPCOffset),
kScratchRegister);
}
#endif // V8_ENABLE_WEBASSEMBLY
if (HasImmediateInput(instr, 0)) {
ExternalReference ref = i.InputExternalReference(0);
__ CallCFunction(ref, num_parameters);
@ -1024,9 +1058,11 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ CallCFunction(func, num_parameters);
}
__ bind(&return_location);
#if V8_ENABLE_WEBASSEMBLY
if (linkage()->GetIncomingDescriptor()->IsWasmCapiFunction()) {
RecordSafepoint(instr->reference_map());
}
#endif // V8_ENABLE_WEBASSEMBLY
frame_access_state()->SetFrameAccessToDefault();
// Ideally, we should decrement SP delta to match the change of stack
// pointer in CallCFunction. However, for certain architectures (e.g.
@ -4345,6 +4381,7 @@ void CodeGenerator::AssembleArchJump(RpoNumber target) {
if (!IsNextInAssemblyOrder(target)) __ jmp(GetLabel(target));
}
#if V8_ENABLE_WEBASSEMBLY
void CodeGenerator::AssembleArchTrap(Instruction* instr,
FlagsCondition condition) {
auto ool = zone()->New<WasmOutOfLineTrap>(this, instr);
@ -4358,6 +4395,7 @@ void CodeGenerator::AssembleArchTrap(Instruction* instr,
__ j(FlagsConditionToCondition(condition), tlabel);
__ bind(&end);
}
#endif // V8_ENABLE_WEBASSEMBLY
// Assembles boolean materializations after this instruction.
void CodeGenerator::AssembleArchBoolean(Instruction* instr,
@ -4449,15 +4487,18 @@ void CodeGenerator::AssembleConstructFrame() {
if (call_descriptor->IsCFunctionCall()) {
__ pushq(rbp);
__ movq(rbp, rsp);
#if V8_ENABLE_WEBASSEMBLY
if (info()->GetOutputStackFrameType() == StackFrame::C_WASM_ENTRY) {
__ Push(Immediate(StackFrame::TypeToMarker(StackFrame::C_WASM_ENTRY)));
// Reserve stack space for saving the c_entry_fp later.
__ AllocateStackSpace(kSystemPointerSize);
}
#endif // V8_ENABLE_WEBASSEMBLY
} else if (call_descriptor->IsJSFunctionCall()) {
__ Prologue();
} else {
__ StubPrologue(info()->GetOutputStackFrameType());
#if V8_ENABLE_WEBASSEMBLY
if (call_descriptor->IsWasmFunctionCall()) {
__ pushq(kWasmInstanceRegister);
} else if (call_descriptor->IsWasmImportWrapper() ||
@ -4478,6 +4519,7 @@ void CodeGenerator::AssembleConstructFrame() {
__ AllocateStackSpace(kSystemPointerSize);
}
}
#endif // V8_ENABLE_WEBASSEMBLY
}
unwinding_info_writer_.MarkFrameConstructed(pc_base);
@ -4504,6 +4546,7 @@ void CodeGenerator::AssembleConstructFrame() {
if (required_slots > 0) {
DCHECK(frame_access_state()->has_frame());
#if V8_ENABLE_WEBASSEMBLY
if (info()->IsWasm() && required_slots > 128) {
// For WebAssembly functions with big frames we have to do the stack
// overflow check before we construct the frame. Otherwise we may not
@ -4532,6 +4575,7 @@ void CodeGenerator::AssembleConstructFrame() {
__ AssertUnreachable(AbortReason::kUnexpectedReturnFromWasmTrap);
__ bind(&done);
}
#endif // V8_ENABLE_WEBASSEMBLY
// Skip callee-saved and return slots, which are created below.
required_slots -= base::bits::CountPopulation(saves);

View File

@ -3257,6 +3257,7 @@ void InstructionSelector::VisitInt64AbsWithOverflow(Node* node) {
UNREACHABLE();
}
#if V8_ENABLE_WEBASSEMBLY
namespace {
// Returns true if shuffle can be decomposed into two 16x4 half shuffles
@ -3562,6 +3563,9 @@ void InstructionSelector::VisitI8x16Shuffle(Node* node) {
}
Emit(opcode, 1, &dst, input_count, inputs, temp_count, temps);
}
#else
void InstructionSelector::VisitI8x16Shuffle(Node* node) { UNREACHABLE(); }
#endif // V8_ENABLE_WEBASSEMBLY
void InstructionSelector::VisitI8x16Swizzle(Node* node) {
X64OperandGenerator g(this);

View File

@ -1625,6 +1625,7 @@ CommonOperatorBuilder::CreateFrameStateFunctionInfo(
shared_info);
}
#if V8_ENABLE_WEBASSEMBLY
const FrameStateFunctionInfo*
CommonOperatorBuilder::CreateJSToWasmFrameStateFunctionInfo(
FrameStateType type, int parameter_count, int local_count,
@ -1635,6 +1636,7 @@ CommonOperatorBuilder::CreateJSToWasmFrameStateFunctionInfo(
return zone()->New<JSToWasmFrameStateFunctionInfo>(
type, parameter_count, local_count, shared_info, signature);
}
#endif // V8_ENABLE_WEBASSEMBLY
const Operator* CommonOperatorBuilder::DeadValue(MachineRepresentation rep) {
return zone()->New<Operator1<MachineRepresentation>>( // --

View File

@ -561,10 +561,12 @@ class V8_EXPORT_PRIVATE CommonOperatorBuilder final
const FrameStateFunctionInfo* CreateFrameStateFunctionInfo(
FrameStateType type, int parameter_count, int local_count,
Handle<SharedFunctionInfo> shared_info);
#if V8_ENABLE_WEBASSEMBLY
const FrameStateFunctionInfo* CreateJSToWasmFrameStateFunctionInfo(
FrameStateType type, int parameter_count, int local_count,
Handle<SharedFunctionInfo> shared_info,
const wasm::FunctionSig* signature);
#endif // V8_ENABLE_WEBASSEMBLY
const Operator* MarkAsSafetyCheck(const Operator* op,
IsSafetyCheck safety_check);

View File

@ -61,9 +61,11 @@ std::ostream& operator<<(std::ostream& os, FrameStateType type) {
case FrameStateType::kBuiltinContinuation:
os << "BUILTIN_CONTINUATION_FRAME";
break;
#if V8_ENABLE_WEBASSEMBLY
case FrameStateType::kJSToWasmBuiltinContinuation:
os << "JS_TO_WASM_BUILTIN_CONTINUATION_FRAME";
break;
#endif // V8_ENABLE_WEBASSEMBLY
case FrameStateType::kJavaScriptBuiltinContinuation:
os << "JAVA_SCRIPT_BUILTIN_CONTINUATION_FRAME";
break;
@ -119,11 +121,17 @@ FrameState CreateBuiltinContinuationFrameStateCommon(
Node* params_node = graph->NewNode(op_param, parameter_count, parameters);
BytecodeOffset bailout_id = Builtins::GetContinuationBytecodeOffset(name);
#if V8_ENABLE_WEBASSEMBLY
const FrameStateFunctionInfo* state_info =
signature ? common->CreateJSToWasmFrameStateFunctionInfo(
frame_type, parameter_count, 0, shared, signature)
: common->CreateFrameStateFunctionInfo(
frame_type, parameter_count, 0, shared);
#else
const FrameStateFunctionInfo* state_info =
common->CreateFrameStateFunctionInfo(frame_type, parameter_count, 0,
shared);
#endif // V8_ENABLE_WEBASSEMBLY
const Operator* op = common->FrameState(
bailout_id, OutputFrameStateCombine::Ignore(), state_info);
@ -167,16 +175,19 @@ FrameState CreateStubBuiltinContinuationFrameState(
}
FrameStateType frame_state_type = FrameStateType::kBuiltinContinuation;
#if V8_ENABLE_WEBASSEMBLY
if (name == Builtins::kJSToWasmLazyDeoptContinuation) {
CHECK_NOT_NULL(signature);
frame_state_type = FrameStateType::kJSToWasmBuiltinContinuation;
}
#endif // V8_ENABLE_WEBASSEMBLY
return CreateBuiltinContinuationFrameStateCommon(
jsgraph, frame_state_type, name, jsgraph->UndefinedConstant(), context,
actual_parameters.data(), static_cast<int>(actual_parameters.size()),
outer_frame_state, Handle<SharedFunctionInfo>(), signature);
}
#if V8_ENABLE_WEBASSEMBLY
FrameState CreateJSWasmCallBuiltinContinuationFrameState(
JSGraph* jsgraph, Node* context, Node* outer_frame_state,
const wasm::FunctionSig* signature) {
@ -190,6 +201,7 @@ FrameState CreateJSWasmCallBuiltinContinuationFrameState(
lazy_deopt_parameters, arraysize(lazy_deopt_parameters),
outer_frame_state, ContinuationFrameStateMode::LAZY, signature);
}
#endif // V8_ENABLE_WEBASSEMBLY
FrameState CreateJavaScriptBuiltinContinuationFrameState(
JSGraph* jsgraph, const SharedFunctionInfoRef& shared, Builtins::Name name,

View File

@ -66,8 +66,10 @@ enum class FrameStateType {
kArgumentsAdaptor, // Represents an ArgumentsAdaptorFrame.
kConstructStub, // Represents a ConstructStubFrame.
kBuiltinContinuation, // Represents a continuation to a stub.
#if V8_ENABLE_WEBASSEMBLY // ↓ WebAssembly only
kJSToWasmBuiltinContinuation, // Represents a lazy deopt continuation for a
// JS to Wasm call.
#endif // ↑ WebAssembly only
kJavaScriptBuiltinContinuation, // Represents a continuation to a JavaScipt
// builtin.
kJavaScriptBuiltinContinuationWithCatch // Represents a continuation to a
@ -170,9 +172,11 @@ FrameState CreateStubBuiltinContinuationFrameState(
ContinuationFrameStateMode mode,
const wasm::FunctionSig* signature = nullptr);
#if V8_ENABLE_WEBASSEMBLY
FrameState CreateJSWasmCallBuiltinContinuationFrameState(
JSGraph* jsgraph, Node* context, Node* outer_frame_state,
const wasm::FunctionSig* signature);
#endif // V8_ENABLE_WEBASSEMBLY
FrameState CreateJavaScriptBuiltinContinuationFrameState(
JSGraph* graph, const SharedFunctionInfoRef& shared, Builtins::Name name,

View File

@ -861,22 +861,22 @@ class ScopeInfoRef : public HeapObjectRef {
void SerializeScopeInfoChain();
};
#define BROKER_SFI_FIELDS(V) \
V(int, internal_formal_parameter_count) \
V(bool, has_duplicate_parameters) \
V(int, function_map_index) \
V(FunctionKind, kind) \
V(LanguageMode, language_mode) \
V(bool, native) \
V(bool, HasBreakInfo) \
V(bool, HasBuiltinId) \
V(bool, construct_as_builtin) \
V(bool, HasBytecodeArray) \
V(int, StartPosition) \
V(bool, is_compiled) \
V(bool, IsUserJavaScript) \
V(const wasm::WasmModule*, wasm_module) \
V(const wasm::FunctionSig*, wasm_function_signature)
#define BROKER_SFI_FIELDS(V) \
V(int, internal_formal_parameter_count) \
V(bool, has_duplicate_parameters) \
V(int, function_map_index) \
V(FunctionKind, kind) \
V(LanguageMode, language_mode) \
V(bool, native) \
V(bool, HasBreakInfo) \
V(bool, HasBuiltinId) \
V(bool, construct_as_builtin) \
V(bool, HasBytecodeArray) \
V(int, StartPosition) \
V(bool, is_compiled) \
V(bool, IsUserJavaScript) \
IF_WASM(V, const wasm::WasmModule*, wasm_module) \
IF_WASM(V, const wasm::FunctionSig*, wasm_function_signature)
class V8_EXPORT_PRIVATE SharedFunctionInfoRef : public HeapObjectRef {
public:

View File

@ -3429,8 +3429,9 @@ Reduction JSCallReducer::ReduceArraySome(Node* node,
return ReplaceWithSubgraph(&a, subgraph);
}
namespace {
#if V8_ENABLE_WEBASSEMBLY
namespace {
bool CanInlineJSToWasmCall(const wasm::FunctionSig* wasm_signature) {
DCHECK(FLAG_turbo_inline_js_wasm_calls);
if (wasm_signature->return_count() > 1) {
@ -3449,7 +3450,6 @@ bool CanInlineJSToWasmCall(const wasm::FunctionSig* wasm_signature) {
return true;
}
} // namespace
Reduction JSCallReducer::ReduceCallWasmFunction(
@ -3500,6 +3500,7 @@ Reduction JSCallReducer::ReduceCallWasmFunction(
NodeProperties::ChangeOp(node, op);
return Changed(node);
}
#endif // V8_ENABLE_WEBASSEMBLY
#ifndef V8_ENABLE_FP_PARAMS_IN_C_LINKAGE
namespace {
@ -4625,9 +4626,11 @@ Reduction JSCallReducer::ReduceJSCall(Node* node,
return ReduceCallApiFunction(node, shared);
}
#if V8_ENABLE_WEBASSEMBLY
if ((flags() & kInlineJSToWasmCalls) && shared.wasm_function_signature()) {
return ReduceCallWasmFunction(node, shared);
}
#endif // V8_ENABLE_WEBASSEMBLY
return NoChange();
}

View File

@ -138,11 +138,15 @@ JSInliningHeuristic::Candidate JSInliningHeuristic::CollectFunctions(
}
Reduction JSInliningHeuristic::Reduce(Node* node) {
#if V8_ENABLE_WEBASSEMBLY
if (mode() == kWasmOnly) {
return (node->opcode() == IrOpcode::kJSWasmCall)
? inliner_.ReduceJSWasmCall(node)
: NoChange();
if (node->opcode() == IrOpcode::kJSWasmCall) {
return inliner_.ReduceJSWasmCall(node);
}
return NoChange();
}
#endif // V8_ENABLE_WEBASSEMBLY
DCHECK_EQ(mode(), kJSOnly);
if (!IrOpcode::IsInlineeOpcode(node->opcode())) return NoChange();

View File

@ -81,6 +81,7 @@ class JSCallAccessor {
Node* call_;
};
#if V8_ENABLE_WEBASSEMBLY
Reduction JSInliner::InlineJSWasmCall(Node* call, Node* new_target,
Node* context, Node* frame_state,
StartNode start, Node* end,
@ -92,6 +93,7 @@ Reduction JSInliner::InlineJSWasmCall(Node* call, Node* new_target,
uncaught_subcalls,
static_cast<int>(n.Parameters().signature()->parameter_count()));
}
#endif // V8_ENABLE_WEBASSEMBLY
Reduction JSInliner::InlineCall(Node* call, Node* new_target, Node* context,
Node* frame_state, StartNode start, Node* end,
@ -384,6 +386,7 @@ FeedbackCellRef JSInliner::DetermineCallContext(Node* node,
UNREACHABLE();
}
#if V8_ENABLE_WEBASSEMBLY
Reduction JSInliner::ReduceJSWasmCall(Node* node) {
// Create the subgraph for the inlinee.
Node* start_node;
@ -455,6 +458,7 @@ Reduction JSInliner::ReduceJSWasmCall(Node* node) {
return InlineJSWasmCall(node, new_target, context, frame_state, start, end,
exception_target, uncaught_subcalls);
}
#endif // V8_ENABLE_WEBASSEMBLY
Reduction JSInliner::ReduceJSCall(Node* node) {
DCHECK(IrOpcode::IsInlineeOpcode(node->opcode()));

View File

@ -41,7 +41,9 @@ class JSInliner final : public AdvancedReducer {
// using the above generic reducer interface of the inlining machinery.
Reduction ReduceJSCall(Node* node);
#if V8_ENABLE_WEBASSEMBLY
Reduction ReduceJSWasmCall(Node* node);
#endif // V8_ENABLE_WEBASSEMBLY
private:
Zone* zone() const { return local_zone_; }
@ -73,10 +75,12 @@ class JSInliner final : public AdvancedReducer {
Node* exception_target,
const NodeVector& uncaught_subcalls, int argument_count);
#if V8_ENABLE_WEBASSEMBLY
Reduction InlineJSWasmCall(Node* call, Node* new_target, Node* context,
Node* frame_state, StartNode start, Node* end,
Node* exception_target,
const NodeVector& uncaught_subcalls);
#endif // V8_ENABLE_WEBASSEMBLY
};
} // namespace compiler

View File

@ -585,10 +585,12 @@ bool Linkage::ParameterHasSecondaryLocation(int index) const {
return IsTaggedReg(loc, kJSFunctionRegister) ||
IsTaggedReg(loc, kContextRegister);
}
#if V8_ENABLE_WEBASSEMBLY
if (incoming_->IsWasmFunctionCall()) {
LinkageLocation loc = GetParameterLocation(index);
return IsTaggedReg(loc, kWasmInstanceRegister);
}
#endif // V8_ENABLE_WEBASSEMBLY
return false;
}
@ -596,7 +598,6 @@ LinkageLocation Linkage::GetParameterSecondaryLocation(int index) const {
// TODO(titzer): these constants are necessary due to offset/slot# mismatch
static const int kJSContextSlot = 2 + StandardFrameConstants::kCPSlotCount;
static const int kJSFunctionSlot = 3 + StandardFrameConstants::kCPSlotCount;
static const int kWasmInstanceSlot = 3 + StandardFrameConstants::kCPSlotCount;
DCHECK(ParameterHasSecondaryLocation(index));
LinkageLocation loc = GetParameterLocation(index);
@ -612,11 +613,14 @@ LinkageLocation Linkage::GetParameterSecondaryLocation(int index) const {
MachineType::AnyTagged());
}
}
#if V8_ENABLE_WEBASSEMBLY
static const int kWasmInstanceSlot = 3 + StandardFrameConstants::kCPSlotCount;
if (incoming_->IsWasmFunctionCall()) {
DCHECK(IsTaggedReg(loc, kWasmInstanceRegister));
return LinkageLocation::ForCalleeFrameSlot(kWasmInstanceSlot,
MachineType::AnyTagged());
}
#endif // V8_ENABLE_WEBASSEMBLY
UNREACHABLE();
return LinkageLocation::ForCalleeFrameSlot(0, MachineType::AnyTagged());
}

View File

@ -94,9 +94,12 @@
#include "src/tracing/traced-value.h"
#include "src/utils/ostreams.h"
#include "src/utils/utils.h"
#if V8_ENABLE_WEBASSEMBLY
#include "src/wasm/function-body-decoder.h"
#include "src/wasm/function-compiler.h"
#include "src/wasm/wasm-engine.h"
#endif // V8_ENABLE_WEBASSEMBLY
namespace v8 {
namespace internal {
@ -184,6 +187,7 @@ class PipelineData {
info_->zone()->New<CompilationDependencies>(broker_, info_->zone());
}
#if V8_ENABLE_WEBASSEMBLY
// For WebAssembly compile entry point.
PipelineData(ZoneStats* zone_stats, wasm::WasmEngine* wasm_engine,
OptimizedCompilationInfo* info, MachineGraph* mcgraph,
@ -220,6 +224,7 @@ class PipelineData {
jsgraph_ = graph_zone_->New<JSGraph>(isolate_, graph_, common_, javascript_,
simplified_, machine_);
}
#endif // V8_ENABLE_WEBASSEMBLY
// For CodeStubAssembler and machine graph testing entry point.
PipelineData(ZoneStats* zone_stats, OptimizedCompilationInfo* info,
@ -230,7 +235,9 @@ class PipelineData {
const AssemblerOptions& assembler_options,
const ProfileDataFromFile* profile_data)
: isolate_(isolate),
#if V8_ENABLE_WEBASSEMBLY
wasm_engine_(isolate_->wasm_engine()),
#endif // V8_ENABLE_WEBASSEMBLY
allocator_(allocator),
info_(info),
debug_name_(info_->GetDebugName()),
@ -421,8 +428,10 @@ class PipelineData {
}
CodeTracer* GetCodeTracer() const {
return wasm_engine_ == nullptr ? isolate_->GetCodeTracer()
: wasm_engine_->GetCodeTracer();
#if V8_ENABLE_WEBASSEMBLY
if (wasm_engine_) return wasm_engine_->GetCodeTracer();
#endif // V8_ENABLE_WEBASSEMBLY
return isolate_->GetCodeTracer();
}
Typer* CreateTyper() {
@ -590,7 +599,9 @@ class PipelineData {
private:
Isolate* const isolate_;
#if V8_ENABLE_WEBASSEMBLY
wasm::WasmEngine* const wasm_engine_ = nullptr;
#endif // V8_ENABLE_WEBASSEMBLY
AccountingAllocator* const allocator_;
OptimizedCompilationInfo* const info_;
std::unique_ptr<char[]> debug_name_;
@ -1007,6 +1018,7 @@ PipelineStatistics* CreatePipelineStatistics(Handle<Script> script,
return pipeline_statistics;
}
#if V8_ENABLE_WEBASSEMBLY
PipelineStatistics* CreatePipelineStatistics(
wasm::WasmEngine* wasm_engine, wasm::FunctionBody function_body,
const wasm::WasmModule* wasm_module, OptimizedCompilationInfo* info,
@ -1048,6 +1060,7 @@ PipelineStatistics* CreatePipelineStatistics(
return pipeline_statistics;
}
#endif // V8_ENABLE_WEBASSEMBLY
} // namespace
@ -2460,6 +2473,7 @@ struct VerifyGraphPhase {
#undef DECL_PIPELINE_PHASE_CONSTANTS
#undef DECL_PIPELINE_PHASE_CONSTANTS_HELPER
#if V8_ENABLE_WEBASSEMBLY
class WasmHeapStubCompilationJob final : public OptimizedCompilationJob {
public:
WasmHeapStubCompilationJob(Isolate* isolate, wasm::WasmEngine* wasm_engine,
@ -2578,6 +2592,21 @@ CompilationJob::Status WasmHeapStubCompilationJob::FinalizeJobImpl(
return FAILED;
}
#else
// TODO(clemensb): Remove these methods once src/wasm is excluded from no-wasm
// builds.
// static
std::unique_ptr<OptimizedCompilationJob>
Pipeline::NewWasmHeapStubCompilationJob(
Isolate* isolate, wasm::WasmEngine* wasm_engine,
CallDescriptor* call_descriptor, std::unique_ptr<Zone> zone, Graph* graph,
CodeKind kind, std::unique_ptr<char[]> debug_name,
const AssemblerOptions& options, SourcePositionTable* source_positions) {
UNREACHABLE();
}
#endif // V8_ENABLE_WEBASSEMBLY
void PipelineImpl::RunPrintAndVerify(const char* phase, bool untyped) {
if (info()->trace_turbo_json() || info()->trace_turbo_graph()) {
Run<PrintGraphPhase>(phase);
@ -3050,6 +3079,7 @@ std::ostream& operator<<(std::ostream& out, const BlockStartsAsJSON& s) {
return out;
}
#if V8_ENABLE_WEBASSEMBLY
// static
wasm::WasmCompilationResult Pipeline::GenerateCodeForWasmNativeStub(
wasm::WasmEngine* wasm_engine, CallDescriptor* call_descriptor,
@ -3148,115 +3178,6 @@ wasm::WasmCompilationResult Pipeline::GenerateCodeForWasmNativeStub(
return result;
}
// static
MaybeHandle<Code> Pipeline::GenerateCodeForTesting(
OptimizedCompilationInfo* info, Isolate* isolate,
std::unique_ptr<JSHeapBroker>* out_broker) {
ZoneStats zone_stats(isolate->allocator());
std::unique_ptr<PipelineStatistics> pipeline_statistics(
CreatePipelineStatistics(Handle<Script>::null(), info, isolate,
&zone_stats));
PipelineData data(&zone_stats, isolate, info, pipeline_statistics.get(),
i::FLAG_concurrent_inlining);
PipelineImpl pipeline(&data);
Linkage linkage(Linkage::ComputeIncoming(data.instruction_zone(), info));
{
CompilationHandleScope compilation_scope(isolate, info);
CanonicalHandleScope canonical(isolate, info);
info->ReopenHandlesInNewHandleScope(isolate);
pipeline.Serialize();
// Emulating the proper pipeline, we call CreateGraph on different places
// (i.e before or after creating a LocalIsolateScope) depending on
// is_concurrent_inlining.
if (!data.broker()->is_concurrent_inlining()) {
if (!pipeline.CreateGraph()) return MaybeHandle<Code>();
}
}
{
LocalIsolateScope local_isolate_scope(data.broker(), info,
isolate->main_thread_local_isolate());
if (data.broker()->is_concurrent_inlining()) {
if (!pipeline.CreateGraph()) return MaybeHandle<Code>();
}
// We selectively Unpark inside OptimizeGraph.
if (!pipeline.OptimizeGraph(&linkage)) return MaybeHandle<Code>();
pipeline.AssembleCode(&linkage);
}
const bool will_retire_broker = out_broker == nullptr;
if (!will_retire_broker) {
// If the broker is going to be kept alive, pass the persistent and the
// canonical handles containers back to the JSHeapBroker since it will
// outlive the OptimizedCompilationInfo.
data.broker()->SetPersistentAndCopyCanonicalHandlesForTesting(
info->DetachPersistentHandles(), info->DetachCanonicalHandles());
}
Handle<Code> code;
if (pipeline.FinalizeCode(will_retire_broker).ToHandle(&code) &&
pipeline.CommitDependencies(code)) {
if (!will_retire_broker) *out_broker = data.ReleaseBroker();
return code;
}
return MaybeHandle<Code>();
}
// static
MaybeHandle<Code> Pipeline::GenerateCodeForTesting(
OptimizedCompilationInfo* info, Isolate* isolate,
CallDescriptor* call_descriptor, Graph* graph,
const AssemblerOptions& options, Schedule* schedule) {
// Construct a pipeline for scheduling and code generation.
ZoneStats zone_stats(isolate->allocator());
NodeOriginTable* node_positions = info->zone()->New<NodeOriginTable>(graph);
PipelineData data(&zone_stats, info, isolate, isolate->allocator(), graph,
nullptr, schedule, nullptr, node_positions, nullptr,
options, nullptr);
std::unique_ptr<PipelineStatistics> pipeline_statistics;
if (FLAG_turbo_stats || FLAG_turbo_stats_nvp) {
pipeline_statistics.reset(new PipelineStatistics(
info, isolate->GetTurboStatistics(), &zone_stats));
pipeline_statistics->BeginPhaseKind("V8.TFTestCodegen");
}
PipelineImpl pipeline(&data);
if (info->trace_turbo_json()) {
TurboJsonFile json_of(info, std::ios_base::trunc);
json_of << "{\"function\":\"" << info->GetDebugName().get()
<< "\", \"source\":\"\",\n\"phases\":[";
}
// TODO(rossberg): Should this really be untyped?
pipeline.RunPrintAndVerify("V8.TFMachineCode", true);
// Ensure we have a schedule.
if (data.schedule() == nullptr) {
pipeline.ComputeScheduledGraph();
}
Handle<Code> code;
if (pipeline.GenerateCode(call_descriptor).ToHandle(&code) &&
pipeline.CommitDependencies(code)) {
return code;
}
return MaybeHandle<Code>();
}
// static
std::unique_ptr<OptimizedCompilationJob> Pipeline::NewCompilationJob(
Isolate* isolate, Handle<JSFunction> function, CodeKind code_kind,
bool has_script, BytecodeOffset osr_offset, JavaScriptFrame* osr_frame) {
Handle<SharedFunctionInfo> shared =
handle(function->shared(), function->GetIsolate());
return std::make_unique<PipelineCompilationJob>(
isolate, shared, function, osr_offset, osr_frame, code_kind);
}
// static
void Pipeline::GenerateCodeForWasmFunction(
OptimizedCompilationInfo* info, wasm::WasmEngine* wasm_engine,
@ -3378,6 +3299,137 @@ void Pipeline::GenerateCodeForWasmFunction(
DCHECK(result->succeeded());
info->SetWasmCompilationResult(std::move(result));
}
#else // V8_ENABLE_WEBASSEMBLY
// TODO(clemensb): Remove these methods once src/wasm is excluded from no-wasm
// builds.
// static
wasm::WasmCompilationResult Pipeline::GenerateCodeForWasmNativeStub(
wasm::WasmEngine* wasm_engine, CallDescriptor* call_descriptor,
MachineGraph* mcgraph, CodeKind kind, int wasm_kind, const char* debug_name,
const AssemblerOptions& options, SourcePositionTable* source_positions) {
UNREACHABLE();
}
// static
void Pipeline::GenerateCodeForWasmFunction(
OptimizedCompilationInfo* info, wasm::WasmEngine* wasm_engine,
MachineGraph* mcgraph, CallDescriptor* call_descriptor,
SourcePositionTable* source_positions, NodeOriginTable* node_origins,
wasm::FunctionBody function_body, const wasm::WasmModule* module,
int function_index, std::vector<compiler::WasmLoopInfo>* loop_info) {
UNREACHABLE();
}
#endif // V8_ENABLE_WEBASSEMBLY
// static
MaybeHandle<Code> Pipeline::GenerateCodeForTesting(
OptimizedCompilationInfo* info, Isolate* isolate,
std::unique_ptr<JSHeapBroker>* out_broker) {
ZoneStats zone_stats(isolate->allocator());
std::unique_ptr<PipelineStatistics> pipeline_statistics(
CreatePipelineStatistics(Handle<Script>::null(), info, isolate,
&zone_stats));
PipelineData data(&zone_stats, isolate, info, pipeline_statistics.get(),
i::FLAG_concurrent_inlining);
PipelineImpl pipeline(&data);
Linkage linkage(Linkage::ComputeIncoming(data.instruction_zone(), info));
{
CompilationHandleScope compilation_scope(isolate, info);
CanonicalHandleScope canonical(isolate, info);
info->ReopenHandlesInNewHandleScope(isolate);
pipeline.Serialize();
// Emulating the proper pipeline, we call CreateGraph on different places
// (i.e before or after creating a LocalIsolateScope) depending on
// is_concurrent_inlining.
if (!data.broker()->is_concurrent_inlining()) {
if (!pipeline.CreateGraph()) return MaybeHandle<Code>();
}
}
{
LocalIsolateScope local_isolate_scope(data.broker(), info,
isolate->main_thread_local_isolate());
if (data.broker()->is_concurrent_inlining()) {
if (!pipeline.CreateGraph()) return MaybeHandle<Code>();
}
// We selectively Unpark inside OptimizeGraph.
if (!pipeline.OptimizeGraph(&linkage)) return MaybeHandle<Code>();
pipeline.AssembleCode(&linkage);
}
const bool will_retire_broker = out_broker == nullptr;
if (!will_retire_broker) {
// If the broker is going to be kept alive, pass the persistent and the
// canonical handles containers back to the JSHeapBroker since it will
// outlive the OptimizedCompilationInfo.
data.broker()->SetPersistentAndCopyCanonicalHandlesForTesting(
info->DetachPersistentHandles(), info->DetachCanonicalHandles());
}
Handle<Code> code;
if (pipeline.FinalizeCode(will_retire_broker).ToHandle(&code) &&
pipeline.CommitDependencies(code)) {
if (!will_retire_broker) *out_broker = data.ReleaseBroker();
return code;
}
return MaybeHandle<Code>();
}
// static
MaybeHandle<Code> Pipeline::GenerateCodeForTesting(
OptimizedCompilationInfo* info, Isolate* isolate,
CallDescriptor* call_descriptor, Graph* graph,
const AssemblerOptions& options, Schedule* schedule) {
// Construct a pipeline for scheduling and code generation.
ZoneStats zone_stats(isolate->allocator());
NodeOriginTable* node_positions = info->zone()->New<NodeOriginTable>(graph);
PipelineData data(&zone_stats, info, isolate, isolate->allocator(), graph,
nullptr, schedule, nullptr, node_positions, nullptr,
options, nullptr);
std::unique_ptr<PipelineStatistics> pipeline_statistics;
if (FLAG_turbo_stats || FLAG_turbo_stats_nvp) {
pipeline_statistics.reset(new PipelineStatistics(
info, isolate->GetTurboStatistics(), &zone_stats));
pipeline_statistics->BeginPhaseKind("V8.TFTestCodegen");
}
PipelineImpl pipeline(&data);
if (info->trace_turbo_json()) {
TurboJsonFile json_of(info, std::ios_base::trunc);
json_of << "{\"function\":\"" << info->GetDebugName().get()
<< "\", \"source\":\"\",\n\"phases\":[";
}
// TODO(rossberg): Should this really be untyped?
pipeline.RunPrintAndVerify("V8.TFMachineCode", true);
// Ensure we have a schedule.
if (data.schedule() == nullptr) {
pipeline.ComputeScheduledGraph();
}
Handle<Code> code;
if (pipeline.GenerateCode(call_descriptor).ToHandle(&code) &&
pipeline.CommitDependencies(code)) {
return code;
}
return MaybeHandle<Code>();
}
// static
std::unique_ptr<OptimizedCompilationJob> Pipeline::NewCompilationJob(
Isolate* isolate, Handle<JSFunction> function, CodeKind code_kind,
bool has_script, BytecodeOffset osr_offset, JavaScriptFrame* osr_frame) {
Handle<SharedFunctionInfo> shared =
handle(function->shared(), function->GetIsolate());
return std::make_unique<PipelineCompilationJob>(
isolate, shared, function, osr_offset, osr_frame, code_kind);
}
bool Pipeline::AllocateRegistersForTesting(const RegisterConfiguration* config,
InstructionSequence* sequence,

View File

@ -255,6 +255,7 @@ Type::bitset BitsetType::Lub(const MapRefLike& map) {
case JS_WEAK_REF_TYPE:
case JS_WEAK_SET_TYPE:
case JS_PROMISE_TYPE:
#if V8_ENABLE_WEBASSEMBLY
case WASM_ARRAY_TYPE:
case WASM_EXCEPTION_OBJECT_TYPE:
case WASM_GLOBAL_OBJECT_TYPE:
@ -263,7 +264,6 @@ Type::bitset BitsetType::Lub(const MapRefLike& map) {
case WASM_MODULE_OBJECT_TYPE:
case WASM_STRUCT_TYPE:
case WASM_TABLE_OBJECT_TYPE:
#if V8_ENABLE_WEBASSEMBLY
case WASM_VALUE_OBJECT_TYPE:
#endif // V8_ENABLE_WEBASSEMBLY
case WEAK_CELL_TYPE:
@ -345,7 +345,9 @@ Type::bitset BitsetType::Lub(const MapRefLike& map) {
case UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE:
case UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE:
case COVERAGE_INFO_TYPE:
#if V8_ENABLE_WEBASSEMBLY
case WASM_TYPE_INFO_TYPE:
#endif // V8_ENABLE_WEBASSEMBLY
return kOtherInternal;
// Remaining instance types are unsupported for now. If any of them do

View File

@ -53,6 +53,7 @@
#include "src/wasm/object-access.h"
#include "src/wasm/wasm-code-manager.h"
#include "src/wasm/wasm-constants.h"
#include "src/wasm/wasm-engine.h"
#include "src/wasm/wasm-limits.h"
#include "src/wasm/wasm-linkage.h"
#include "src/wasm/wasm-module.h"