Reland "[ptr-cage] Reserve base registers on x64 (r14) and arm64 (x28)"
This is a reland of 0c63aa9eee
Fixes the correctness fuzzing BUILD.gn breakage.
Original change's description:
> [ptr-cage] Reserve base registers on x64 (r14) and arm64 (x28)
>
> Also add a V8_COMPRESS_POINTERS_IN_SHARED_CAGE define when pointer
> compression is enabled.
>
> This CL is to get performance numbers for reserving an extra register.
> There is no actual pointer cage yet, and the base register will always
> have the same value as the root register. The pointer decompression code
> is switched to using the base register instead of the root register.
>
> Bug: v8:11460
> Change-Id: I40bae556c2098608fb6fc193a52694e3f54754bd
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2716075
> Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
> Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
> Reviewed-by: Leszek Swirski <leszeks@chromium.org>
> Commit-Queue: Shu-yu Guo <syg@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#73204}
TBR=rmcilroy@chromium.org,jkummerow@chromium.org,leszeks@chromium.org
Bug: v8:11460
Change-Id: Iecf6b783392a384b40ab33e0f4ce13538a8f81ee
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2737681
Reviewed-by: Shu-yu Guo <syg@chromium.org>
Commit-Queue: Shu-yu Guo <syg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#73207}
This commit is contained in:
parent
5300b26dcf
commit
eed7206347
13
BUILD.gn
13
BUILD.gn
@ -108,6 +108,7 @@ declare_args() {
|
||||
|
||||
# Enable pointer compression (sets -dV8_COMPRESS_POINTERS).
|
||||
v8_enable_pointer_compression = ""
|
||||
v8_enable_pointer_compression_shared_cage = ""
|
||||
v8_enable_31bit_smis_on_64bit_arch = false
|
||||
|
||||
# Sets -dOBJECT_PRINT.
|
||||
@ -324,6 +325,9 @@ if (v8_enable_pointer_compression == "") {
|
||||
v8_enable_pointer_compression =
|
||||
v8_current_cpu == "arm64" || v8_current_cpu == "x64"
|
||||
}
|
||||
if (v8_enable_pointer_compression_shared_cage == "") {
|
||||
v8_enable_pointer_compression_shared_cage = v8_enable_pointer_compression
|
||||
}
|
||||
if (v8_enable_fast_torque == "") {
|
||||
v8_enable_fast_torque = v8_enable_fast_mksnapshot
|
||||
}
|
||||
@ -362,6 +366,7 @@ if (v8_multi_arch_build &&
|
||||
rebase_path(get_label_info(":d8", "root_out_dir"), root_build_dir) ==
|
||||
"clang_x64_pointer_compression") {
|
||||
v8_enable_pointer_compression = !v8_enable_pointer_compression
|
||||
v8_enable_pointer_compression_shared_cage = v8_enable_pointer_compression
|
||||
}
|
||||
if (v8_enable_shared_ro_heap == "") {
|
||||
v8_enable_shared_ro_heap = !v8_enable_pointer_compression
|
||||
@ -388,6 +393,10 @@ assert(!v8_use_multi_snapshots || !v8_control_flow_integrity,
|
||||
assert(!v8_enable_heap_sandbox || v8_enable_pointer_compression,
|
||||
"V8 Heap Sandbox requires pointer compression")
|
||||
|
||||
assert(
|
||||
!v8_enable_pointer_compression_shared_cage || v8_enable_pointer_compression,
|
||||
"Can't share a pointer compression cage if pointers aren't compressed")
|
||||
|
||||
assert(!v8_enable_unconditional_write_barriers || !v8_disable_write_barriers,
|
||||
"Write barriers can't be both enabled and disabled")
|
||||
|
||||
@ -527,6 +536,7 @@ config("external_startup_data") {
|
||||
external_v8_defines = [
|
||||
"V8_ENABLE_CHECKS",
|
||||
"V8_COMPRESS_POINTERS",
|
||||
"V8_COMPRESS_POINTERS_IN_SHARED_CAGE",
|
||||
"V8_31BIT_SMIS_ON_64BIT_ARCH",
|
||||
"V8_COMPRESS_ZONES",
|
||||
"V8_HEAP_SANDBOX",
|
||||
@ -544,6 +554,9 @@ if (v8_enable_v8_checks) {
|
||||
if (v8_enable_pointer_compression) {
|
||||
enabled_external_v8_defines += [ "V8_COMPRESS_POINTERS" ]
|
||||
}
|
||||
if (v8_enable_pointer_compression_shared_cage) {
|
||||
enabled_external_v8_defines += [ "V8_COMPRESS_POINTERS_IN_SHARED_CAGE" ]
|
||||
}
|
||||
if (v8_enable_pointer_compression || v8_enable_31bit_smis_on_64bit_arch) {
|
||||
enabled_external_v8_defines += [ "V8_31BIT_SMIS_ON_64BIT_ARCH" ]
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ namespace detail {
|
||||
|
||||
// Avoid using kScratchRegister(==r10) since the macro-assembler doesn't use
|
||||
// this scope and will conflict.
|
||||
static constexpr Register kScratchRegisters[] = {r8, r9, r11, r12, r14, r15};
|
||||
static constexpr Register kScratchRegisters[] = {r8, r9, r11, r12, r15};
|
||||
static constexpr int kNumScratchRegisters = arraysize(kScratchRegisters);
|
||||
|
||||
} // namespace detail
|
||||
|
@ -632,6 +632,11 @@ void Generate_JSEntryVariant(MacroAssembler* masm, StackFrame::Type type,
|
||||
// Initialize the root register.
|
||||
// C calling convention. The first argument is passed in x0.
|
||||
__ Mov(kRootRegister, x0);
|
||||
|
||||
#ifdef V8_COMPRESS_POINTERS_IN_SHARED_CAGE
|
||||
// Initialize the pointer cage base register.
|
||||
__ Mov(kPointerCageBaseRegister, x0);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Set up fp. It points to the {fp, lr} pair pushed as the last step in
|
||||
@ -910,10 +915,13 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
|
||||
__ Mov(x23, x19);
|
||||
__ Mov(x24, x19);
|
||||
__ Mov(x25, x19);
|
||||
#ifndef V8_COMPRESS_POINTERS_IN_SHARED_CAGE
|
||||
__ Mov(x28, x19);
|
||||
#endif
|
||||
// Don't initialize the reserved registers.
|
||||
// x26 : root register (kRootRegister).
|
||||
// x27 : context pointer (cp).
|
||||
// x28 : pointer cage base register (kPointerCageBaseRegister).
|
||||
// x29 : frame pointer (fp).
|
||||
|
||||
Handle<Code> builtin = is_construct
|
||||
|
@ -377,6 +377,12 @@ void Generate_JSEntryVariant(MacroAssembler* masm, StackFrame::Type type,
|
||||
// Initialize the root register.
|
||||
// C calling convention. The first argument is passed in arg_reg_1.
|
||||
__ movq(kRootRegister, arg_reg_1);
|
||||
|
||||
#ifdef V8_COMPRESS_POINTERS_IN_SHARED_CAGE
|
||||
// Initialize the pointer cage base register.
|
||||
// TODO(syg): Actually make a cage.
|
||||
__ movq(kPointerCageBaseRegister, arg_reg_1);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Save copies of the top frame descriptor on the stack.
|
||||
@ -1633,7 +1639,7 @@ void Builtins::Generate_BaselineOutOfLinePrologue(MacroAssembler* masm) {
|
||||
__ incl(
|
||||
FieldOperand(feedback_vector, FeedbackVector::kInvocationCountOffset));
|
||||
|
||||
Register return_address = r12;
|
||||
Register return_address = r15;
|
||||
|
||||
__ RecordComment("[ Frame Setup");
|
||||
// Save the return address, so that we can push it to the end of the newly
|
||||
@ -2810,8 +2816,8 @@ void Builtins::Generate_CEntry(MacroAssembler* masm, int result_size,
|
||||
DCHECK(save_doubles == kDontSaveFPRegs);
|
||||
DCHECK(!builtin_exit_frame);
|
||||
__ EnterApiExitFrame(arg_stack_space);
|
||||
// Move argc into r14 (argv is already in r15).
|
||||
__ movq(r14, rax);
|
||||
// Move argc into r12 (argv is already in r15).
|
||||
__ movq(r12, rax);
|
||||
} else {
|
||||
__ EnterExitFrame(
|
||||
arg_stack_space, save_doubles == kSaveFPRegs,
|
||||
@ -2821,7 +2827,7 @@ void Builtins::Generate_CEntry(MacroAssembler* masm, int result_size,
|
||||
// rbx: pointer to builtin function (C callee-saved).
|
||||
// rbp: frame pointer of exit frame (restored after C call).
|
||||
// rsp: stack pointer (restored after C call).
|
||||
// r14: number of arguments including receiver (C callee-saved).
|
||||
// r12: number of arguments including receiver (C callee-saved).
|
||||
// r15: argv pointer (C callee-saved).
|
||||
|
||||
// Check stack alignment.
|
||||
@ -2834,7 +2840,7 @@ void Builtins::Generate_CEntry(MacroAssembler* masm, int result_size,
|
||||
if (result_size <= kMaxRegisterResultSize) {
|
||||
// Pass a pointer to the Arguments object as the first argument.
|
||||
// Return result in single register (rax), or a register pair (rax, rdx).
|
||||
__ movq(kCCallArg0, r14); // argc.
|
||||
__ movq(kCCallArg0, r12); // argc.
|
||||
__ movq(kCCallArg1, r15); // argv.
|
||||
__ Move(kCCallArg2, ExternalReference::isolate_address(masm->isolate()));
|
||||
} else {
|
||||
@ -2842,7 +2848,7 @@ void Builtins::Generate_CEntry(MacroAssembler* masm, int result_size,
|
||||
// Pass a pointer to the result location as the first argument.
|
||||
__ leaq(kCCallArg0, StackSpaceOperand(kArgExtraStackSpace));
|
||||
// Pass a pointer to the Arguments object as the second argument.
|
||||
__ movq(kCCallArg1, r14); // argc.
|
||||
__ movq(kCCallArg1, r12); // argc.
|
||||
__ movq(kCCallArg2, r15); // argv.
|
||||
__ Move(kCCallArg3, ExternalReference::isolate_address(masm->isolate()));
|
||||
}
|
||||
@ -2866,12 +2872,12 @@ void Builtins::Generate_CEntry(MacroAssembler* masm, int result_size,
|
||||
// should have returned the exception sentinel.
|
||||
if (FLAG_debug_code) {
|
||||
Label okay;
|
||||
__ LoadRoot(r14, RootIndex::kTheHoleValue);
|
||||
__ LoadRoot(kScratchRegister, RootIndex::kTheHoleValue);
|
||||
ExternalReference pending_exception_address = ExternalReference::Create(
|
||||
IsolateAddressId::kPendingExceptionAddress, masm->isolate());
|
||||
Operand pending_exception_operand =
|
||||
masm->ExternalReferenceAsOperand(pending_exception_address);
|
||||
__ cmp_tagged(r14, pending_exception_operand);
|
||||
__ cmp_tagged(kScratchRegister, pending_exception_operand);
|
||||
__ j(equal, &okay, Label::kNear);
|
||||
__ int3();
|
||||
__ bind(&okay);
|
||||
@ -3212,7 +3218,7 @@ void Builtins::Generate_GenericJSToWasmWrapper(MacroAssembler* masm) {
|
||||
kLastSpillOffset - kSystemPointerSize;
|
||||
// For Integer section.
|
||||
// Set the current_int_param_slot to point to the start of the section.
|
||||
Register current_int_param_slot = r14;
|
||||
Register current_int_param_slot = r10;
|
||||
__ leaq(current_int_param_slot, MemOperand(rsp, -kSystemPointerSize));
|
||||
Register params_size = param_count;
|
||||
param_count = no_reg;
|
||||
@ -3326,7 +3332,7 @@ void Builtins::Generate_GenericJSToWasmWrapper(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- r8 : start_int_section
|
||||
// -- rdi : start_float_section
|
||||
// -- r14 : current_int_param_slot
|
||||
// -- r10 : current_int_param_slot
|
||||
// -- r15 : current_float_param_slot
|
||||
// -- r11 : valuetypes_array_ptr
|
||||
// -- r12 : valuetype
|
||||
@ -3758,7 +3764,7 @@ int Offset(ExternalReference ref0, ExternalReference ref1) {
|
||||
}
|
||||
|
||||
// Calls an API function. Allocates HandleScope, extracts returned value
|
||||
// from handle and propagates exceptions. Clobbers r14, r15, rbx and
|
||||
// from handle and propagates exceptions. Clobbers r12, r15, rbx and
|
||||
// caller-save registers. Restores context. On return removes
|
||||
// stack_space * kSystemPointerSize (GCed).
|
||||
void CallApiFunctionAndReturn(MacroAssembler* masm, Register function_address,
|
||||
@ -3785,7 +3791,7 @@ void CallApiFunctionAndReturn(MacroAssembler* masm, Register function_address,
|
||||
|
||||
DCHECK(rdx == function_address || r8 == function_address);
|
||||
// Allocate HandleScope in callee-save registers.
|
||||
Register prev_next_address_reg = r14;
|
||||
Register prev_next_address_reg = r12;
|
||||
Register prev_limit_reg = rbx;
|
||||
Register base_reg = r15;
|
||||
__ Move(base_reg, next_address);
|
||||
|
@ -1036,6 +1036,9 @@ void TurboAssembler::Uxtw(const Register& rd, const Register& rn) {
|
||||
void TurboAssembler::InitializeRootRegister() {
|
||||
ExternalReference isolate_root = ExternalReference::isolate_root(isolate());
|
||||
Mov(kRootRegister, Operand(isolate_root));
|
||||
#ifdef V8_COMPRESS_POINTERS_IN_SHARED_CAGE
|
||||
Mov(kPointerCageBaseRegister, Operand(isolate_root));
|
||||
#endif
|
||||
}
|
||||
|
||||
void MacroAssembler::SmiTag(Register dst, Register src) {
|
||||
|
@ -2816,14 +2816,14 @@ void TurboAssembler::DecompressTaggedPointer(const Register& destination,
|
||||
const MemOperand& field_operand) {
|
||||
RecordComment("[ DecompressTaggedPointer");
|
||||
Ldr(destination.W(), field_operand);
|
||||
Add(destination, kRootRegister, destination);
|
||||
Add(destination, kPointerCageBaseRegister, destination);
|
||||
RecordComment("]");
|
||||
}
|
||||
|
||||
void TurboAssembler::DecompressTaggedPointer(const Register& destination,
|
||||
const Register& source) {
|
||||
RecordComment("[ DecompressTaggedPointer");
|
||||
Add(destination, kRootRegister, Operand(source, UXTW));
|
||||
Add(destination, kPointerCageBaseRegister, Operand(source, UXTW));
|
||||
RecordComment("]");
|
||||
}
|
||||
|
||||
@ -2831,7 +2831,7 @@ void TurboAssembler::DecompressAnyTagged(const Register& destination,
|
||||
const MemOperand& field_operand) {
|
||||
RecordComment("[ DecompressAnyTagged");
|
||||
Ldr(destination.W(), field_operand);
|
||||
Add(destination, kRootRegister, destination);
|
||||
Add(destination, kPointerCageBaseRegister, destination);
|
||||
RecordComment("]");
|
||||
}
|
||||
|
||||
|
@ -30,11 +30,21 @@ namespace internal {
|
||||
|
||||
// x18 is the platform register and is reserved for the use of platform ABIs.
|
||||
// It is known to be reserved by the OS at least on Windows and iOS.
|
||||
#define ALLOCATABLE_GENERAL_REGISTERS(R) \
|
||||
#define ALWAYS_ALLOCATABLE_GENERAL_REGISTERS(R) \
|
||||
R(x0) R(x1) R(x2) R(x3) R(x4) R(x5) R(x6) R(x7) \
|
||||
R(x8) R(x9) R(x10) R(x11) R(x12) R(x13) R(x14) R(x15) \
|
||||
R(x19) R(x20) R(x21) R(x22) R(x23) R(x24) R(x25) \
|
||||
R(x27) R(x28)
|
||||
R(x27)
|
||||
|
||||
#ifdef V8_COMPRESS_POINTERS_IN_SHARED_CAGE
|
||||
#define MAYBE_ALLOCATABLE_GENERAL_REGISTERS(R)
|
||||
#else
|
||||
#define MAYBE_ALLOCATABLE_GENERAL_REGISTERS(R) R(x28)
|
||||
#endif
|
||||
|
||||
#define ALLOCATABLE_GENERAL_REGISTERS(V) \
|
||||
ALWAYS_ALLOCATABLE_GENERAL_REGISTERS(V) \
|
||||
MAYBE_ALLOCATABLE_GENERAL_REGISTERS(V)
|
||||
|
||||
#define FLOAT_REGISTERS(V) \
|
||||
V(s0) V(s1) V(s2) V(s3) V(s4) V(s5) V(s6) V(s7) \
|
||||
@ -458,6 +468,12 @@ ALIAS_REGISTER(Register, wip1, w17);
|
||||
// Root register.
|
||||
ALIAS_REGISTER(Register, kRootRegister, x26);
|
||||
ALIAS_REGISTER(Register, rr, x26);
|
||||
// Pointer cage base register.
|
||||
#ifdef V8_COMPRESS_POINTERS_IN_SHARED_CAGE
|
||||
ALIAS_REGISTER(Register, kPointerCageBaseRegister, x28);
|
||||
#else
|
||||
ALIAS_REGISTER(Register, kPointerCageBaseRegister, kRootRegister);
|
||||
#endif
|
||||
// Context pointer register.
|
||||
ALIAS_REGISTER(Register, cp, x27);
|
||||
ALIAS_REGISTER(Register, fp, x29);
|
||||
|
@ -25,6 +25,9 @@ void CallInterfaceDescriptorData::InitializePlatformSpecific(
|
||||
// within the calling convention are disallowed.
|
||||
#ifdef DEBUG
|
||||
CHECK_NE(registers[i], kRootRegister);
|
||||
#ifdef V8_COMPRESS_POINTERS_IN_SHARED_CAGE
|
||||
CHECK_NE(registers[i], kPointerCageBaseRegister);
|
||||
#endif
|
||||
// Check for duplicated registers.
|
||||
for (int j = i + 1; j < register_parameter_count; j++) {
|
||||
CHECK_NE(registers[i], registers[j]);
|
||||
|
@ -288,7 +288,7 @@ void TurboAssembler::DecompressTaggedPointer(Register destination,
|
||||
Operand field_operand) {
|
||||
RecordComment("[ DecompressTaggedPointer");
|
||||
movl(destination, field_operand);
|
||||
addq(destination, kRootRegister);
|
||||
addq(destination, kPointerCageBaseRegister);
|
||||
RecordComment("]");
|
||||
}
|
||||
|
||||
@ -296,7 +296,7 @@ void TurboAssembler::DecompressTaggedPointer(Register destination,
|
||||
Register source) {
|
||||
RecordComment("[ DecompressTaggedPointer");
|
||||
movl(destination, source);
|
||||
addq(destination, kRootRegister);
|
||||
addq(destination, kPointerCageBaseRegister);
|
||||
RecordComment("]");
|
||||
}
|
||||
|
||||
@ -304,7 +304,7 @@ void TurboAssembler::DecompressAnyTagged(Register destination,
|
||||
Operand field_operand) {
|
||||
RecordComment("[ DecompressAnyTagged");
|
||||
movl(destination, field_operand);
|
||||
addq(destination, kRootRegister);
|
||||
addq(destination, kPointerCageBaseRegister);
|
||||
RecordComment("]");
|
||||
}
|
||||
|
||||
@ -3383,7 +3383,7 @@ void TurboAssembler::AllocateStackSpace(int bytes) {
|
||||
}
|
||||
#endif
|
||||
|
||||
void MacroAssembler::EnterExitFramePrologue(bool save_rax,
|
||||
void MacroAssembler::EnterExitFramePrologue(Register saved_rax_reg,
|
||||
StackFrame::Type frame_type) {
|
||||
DCHECK(frame_type == StackFrame::EXIT ||
|
||||
frame_type == StackFrame::BUILTIN_EXIT);
|
||||
@ -3403,8 +3403,8 @@ void MacroAssembler::EnterExitFramePrologue(bool save_rax,
|
||||
Push(Immediate(0)); // Saved entry sp, patched before call.
|
||||
|
||||
// Save the frame pointer and the context in top.
|
||||
if (save_rax) {
|
||||
movq(r14, rax); // Backup rax in callee-save register.
|
||||
if (saved_rax_reg != no_reg) {
|
||||
movq(saved_rax_reg, rax); // Backup rax in callee-save register.
|
||||
}
|
||||
|
||||
Store(
|
||||
@ -3453,18 +3453,19 @@ void MacroAssembler::EnterExitFrameEpilogue(int arg_stack_space,
|
||||
|
||||
void MacroAssembler::EnterExitFrame(int arg_stack_space, bool save_doubles,
|
||||
StackFrame::Type frame_type) {
|
||||
EnterExitFramePrologue(true, frame_type);
|
||||
Register saved_rax_reg = r12;
|
||||
EnterExitFramePrologue(saved_rax_reg, frame_type);
|
||||
|
||||
// Set up argv in callee-saved register r15. It is reused in LeaveExitFrame,
|
||||
// so it must be retained across the C-call.
|
||||
int offset = StandardFrameConstants::kCallerSPOffset - kSystemPointerSize;
|
||||
leaq(r15, Operand(rbp, r14, times_system_pointer_size, offset));
|
||||
leaq(r15, Operand(rbp, saved_rax_reg, times_system_pointer_size, offset));
|
||||
|
||||
EnterExitFrameEpilogue(arg_stack_space, save_doubles);
|
||||
}
|
||||
|
||||
void MacroAssembler::EnterApiExitFrame(int arg_stack_space) {
|
||||
EnterExitFramePrologue(false, StackFrame::EXIT);
|
||||
EnterExitFramePrologue(no_reg, StackFrame::EXIT);
|
||||
EnterExitFrameEpilogue(arg_stack_space, false);
|
||||
}
|
||||
|
||||
|
@ -704,6 +704,9 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
|
||||
void InitializeRootRegister() {
|
||||
ExternalReference isolate_root = ExternalReference::isolate_root(isolate());
|
||||
Move(kRootRegister, isolate_root);
|
||||
#ifdef V8_COMPRESS_POINTERS_IN_SHARED_CAGE
|
||||
Move(kPointerCageBaseRegister, isolate_root);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SaveRegisters(RegList registers);
|
||||
@ -1146,7 +1149,8 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {
|
||||
Register actual_parameter_count, Label* done,
|
||||
InvokeFlag flag);
|
||||
|
||||
void EnterExitFramePrologue(bool save_rax, StackFrame::Type frame_type);
|
||||
void EnterExitFramePrologue(Register saved_rax_reg,
|
||||
StackFrame::Type frame_type);
|
||||
|
||||
// Allocates arg_stack_space * kSystemPointerSize memory (not GCed) on the
|
||||
// stack accessible via StackSpaceOperand.
|
||||
|
@ -29,20 +29,29 @@ namespace internal {
|
||||
V(r14) \
|
||||
V(r15)
|
||||
|
||||
#define ALLOCATABLE_GENERAL_REGISTERS(V) \
|
||||
V(rax) \
|
||||
V(rbx) \
|
||||
V(rdx) \
|
||||
V(rcx) \
|
||||
V(rsi) \
|
||||
V(rdi) \
|
||||
V(r8) \
|
||||
V(r9) \
|
||||
V(r11) \
|
||||
V(r12) \
|
||||
V(r14) \
|
||||
#define ALWAYS_ALLOCATABLE_GENERAL_REGISTERS(V) \
|
||||
V(rax) \
|
||||
V(rbx) \
|
||||
V(rdx) \
|
||||
V(rcx) \
|
||||
V(rsi) \
|
||||
V(rdi) \
|
||||
V(r8) \
|
||||
V(r9) \
|
||||
V(r11) \
|
||||
V(r12) \
|
||||
V(r15)
|
||||
|
||||
#ifdef V8_COMPRESS_POINTERS_IN_SHARED_CAGE
|
||||
#define MAYBE_ALLOCATABLE_GENERAL_REGISTERS(V)
|
||||
#else
|
||||
#define MAYBE_ALLOCATABLE_GENERAL_REGISTERS(V) V(r14)
|
||||
#endif
|
||||
|
||||
#define ALLOCATABLE_GENERAL_REGISTERS(V) \
|
||||
ALWAYS_ALLOCATABLE_GENERAL_REGISTERS(V) \
|
||||
MAYBE_ALLOCATABLE_GENERAL_REGISTERS(V)
|
||||
|
||||
enum RegisterCode {
|
||||
#define REGISTER_CODE(R) kRegCode_##R,
|
||||
GENERAL_REGISTERS(REGISTER_CODE)
|
||||
@ -201,7 +210,7 @@ constexpr Register kAllocateSizeRegister = rdx;
|
||||
constexpr Register kSpeculationPoisonRegister = r12;
|
||||
constexpr Register kInterpreterAccumulatorRegister = rax;
|
||||
constexpr Register kInterpreterBytecodeOffsetRegister = r9;
|
||||
constexpr Register kInterpreterBytecodeArrayRegister = r14;
|
||||
constexpr Register kInterpreterBytecodeArrayRegister = r12;
|
||||
constexpr Register kInterpreterDispatchTableRegister = r15;
|
||||
|
||||
constexpr Register kJavaScriptCallArgCountRegister = rax;
|
||||
@ -221,6 +230,11 @@ constexpr Register kWasmInstanceRegister = rsi;
|
||||
constexpr Register kScratchRegister = r10;
|
||||
constexpr XMMRegister kScratchDoubleReg = xmm15;
|
||||
constexpr Register kRootRegister = r13; // callee save
|
||||
#ifdef V8_COMPRESS_POINTERS_IN_SHARED_CAGE
|
||||
constexpr Register kPointerCageBaseRegister = r14; // callee save
|
||||
#else
|
||||
constexpr Register kPointerCageBaseRegister = kRootRegister;
|
||||
#endif
|
||||
|
||||
constexpr Register kOffHeapTrampolineRegister = kScratchRegister;
|
||||
|
||||
|
@ -962,6 +962,10 @@ void Deoptimizer::DoComputeOutputFrames() {
|
||||
FrameDescription* topmost = output_[count - 1];
|
||||
topmost->GetRegisterValues()->SetRegister(kRootRegister.code(),
|
||||
isolate()->isolate_root());
|
||||
#ifdef V8_COMPRESS_POINTERS_IN_SHARED_CAGE
|
||||
topmost->GetRegisterValues()->SetRegister(kPointerCageBaseRegister.code(),
|
||||
isolate()->isolate_root());
|
||||
#endif
|
||||
|
||||
// Print some helpful diagnostic information.
|
||||
if (verbose_tracing_enabled()) {
|
||||
|
@ -58,11 +58,15 @@ constexpr RegList kLiftoffAssemblerFpCacheRegs = LowDwVfpRegister::ListOf(
|
||||
|
||||
#elif V8_TARGET_ARCH_ARM64
|
||||
|
||||
// x16: ip0, x17: ip1, x18: platform register, x26: root, x27: cp, x29: fp,
|
||||
// x30: lr, x31: xzr.
|
||||
// x16: ip0, x17: ip1, x18: platform register, x26: root, x27: cp, x8: base,
|
||||
// x29: fp, x30: lr, x31: xzr.
|
||||
constexpr RegList kLiftoffAssemblerGpCacheRegs =
|
||||
CPURegister::ListOf(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12,
|
||||
#ifdef V8_COMPRESS_POINTERS_IN_SHARED_CAGE
|
||||
x13, x14, x15, x19, x20, x21, x22, x23, x24, x25);
|
||||
#else
|
||||
x13, x14, x15, x19, x20, x21, x22, x23, x24, x25, x28);
|
||||
#endif
|
||||
|
||||
// d15: fp_zero, d30-d31: macro-assembler scratch V Registers.
|
||||
constexpr RegList kLiftoffAssemblerFpCacheRegs = CPURegister::ListOf(
|
||||
|
@ -60,10 +60,18 @@ using F0 = int();
|
||||
static void EntryCode(MacroAssembler* masm) {
|
||||
// Smi constant register is callee save.
|
||||
__ pushq(kRootRegister);
|
||||
#ifdef V8_COMPRESS_POINTERS_IN_SHARED_CAGE
|
||||
__ pushq(kPointerCageBaseRegister);
|
||||
#endif
|
||||
__ InitializeRootRegister();
|
||||
}
|
||||
|
||||
static void ExitCode(MacroAssembler* masm) { __ popq(kRootRegister); }
|
||||
static void ExitCode(MacroAssembler* masm) {
|
||||
#ifdef V8_COMPRESS_POINTERS_IN_SHARED_CAGE
|
||||
__ popq(kPointerCageBaseRegister);
|
||||
#endif
|
||||
__ popq(kRootRegister);
|
||||
}
|
||||
|
||||
TEST(Smi) {
|
||||
// Check that C++ Smi operations work as expected.
|
||||
|
@ -121,7 +121,7 @@ TEST(DisasmPoisonPolymorphicLoad) {
|
||||
"csdb", // spec. barrier
|
||||
"ldur w<<BSt:[0-9]+>>, \\[<<Obj>>, #[0-9]+\\]", // load backing store
|
||||
// branchful decompress
|
||||
"add x<<BSt>>, x26, x<<BSt>>", // Add root to ref
|
||||
"add x<<BSt>>, x2[68], x<<BSt>>", // Add root to ref
|
||||
"and x<<BSt>>, x<<BSt>>, " + kPReg, // apply the poison
|
||||
"ldur w<<Prop:[0-9]+>>, \\[x<<BSt>>, #[0-9]+\\]", // load the property
|
||||
"and x<<Prop>>, x<<Prop>>, " + kPReg, // apply the poison
|
||||
@ -194,7 +194,7 @@ TEST(DisasmPoisonMonomorphicLoadFloat64) {
|
||||
"csel " + kPReg + ", xzr, " + kPReg + ", ne", // update the poison
|
||||
"csdb", // spec. barrier
|
||||
"ldur w<<F1:[0-9]+>>, \\[<<Obj>>, #11\\]", // load heap number
|
||||
"add x<<F1>>, x26, x<<F1>>", // Decompress ref
|
||||
"add x<<F1>>, x2[68], x<<F1>>", // Decompress ref
|
||||
"and x<<F1>>, x<<F1>>, " + kPReg, // apply the poison
|
||||
"add <<Addr:x[0-9]+>>, x<<F1>>, #0x[0-9a-f]+", // addr. calculation
|
||||
"and <<Addr>>, <<Addr>>, " + kPReg, // apply the poison
|
||||
|
Loading…
Reference in New Issue
Block a user