[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:
parent
69d1e2c21d
commit
75d7d12720
@ -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 {
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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 */ \
|
||||
\
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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>>( // --
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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:
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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()));
|
||||
|
@ -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
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user