Commit 0c63aa9e authored by Shu-yu Guo's avatar Shu-yu Guo Committed by Commit Bot

[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/+/2716075Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Commit-Queue: Shu-yu Guo <syg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#73204}
parent f458cade
...@@ -108,6 +108,7 @@ declare_args() { ...@@ -108,6 +108,7 @@ declare_args() {
# Enable pointer compression (sets -dV8_COMPRESS_POINTERS). # Enable pointer compression (sets -dV8_COMPRESS_POINTERS).
v8_enable_pointer_compression = "" v8_enable_pointer_compression = ""
v8_enable_pointer_compression_shared_cage = ""
v8_enable_31bit_smis_on_64bit_arch = false v8_enable_31bit_smis_on_64bit_arch = false
# Sets -dOBJECT_PRINT. # Sets -dOBJECT_PRINT.
...@@ -324,6 +325,9 @@ if (v8_enable_pointer_compression == "") { ...@@ -324,6 +325,9 @@ if (v8_enable_pointer_compression == "") {
v8_enable_pointer_compression = v8_enable_pointer_compression =
v8_current_cpu == "arm64" || v8_current_cpu == "x64" 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 == "") { if (v8_enable_fast_torque == "") {
v8_enable_fast_torque = v8_enable_fast_mksnapshot v8_enable_fast_torque = v8_enable_fast_mksnapshot
} }
...@@ -388,6 +392,10 @@ assert(!v8_use_multi_snapshots || !v8_control_flow_integrity, ...@@ -388,6 +392,10 @@ assert(!v8_use_multi_snapshots || !v8_control_flow_integrity,
assert(!v8_enable_heap_sandbox || v8_enable_pointer_compression, assert(!v8_enable_heap_sandbox || v8_enable_pointer_compression,
"V8 Heap Sandbox requires 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, assert(!v8_enable_unconditional_write_barriers || !v8_disable_write_barriers,
"Write barriers can't be both enabled and disabled") "Write barriers can't be both enabled and disabled")
...@@ -527,6 +535,7 @@ config("external_startup_data") { ...@@ -527,6 +535,7 @@ config("external_startup_data") {
external_v8_defines = [ external_v8_defines = [
"V8_ENABLE_CHECKS", "V8_ENABLE_CHECKS",
"V8_COMPRESS_POINTERS", "V8_COMPRESS_POINTERS",
"V8_COMPRESS_POINTERS_IN_SHARED_CAGE",
"V8_31BIT_SMIS_ON_64BIT_ARCH", "V8_31BIT_SMIS_ON_64BIT_ARCH",
"V8_COMPRESS_ZONES", "V8_COMPRESS_ZONES",
"V8_HEAP_SANDBOX", "V8_HEAP_SANDBOX",
...@@ -544,6 +553,9 @@ if (v8_enable_v8_checks) { ...@@ -544,6 +553,9 @@ if (v8_enable_v8_checks) {
if (v8_enable_pointer_compression) { if (v8_enable_pointer_compression) {
enabled_external_v8_defines += [ "V8_COMPRESS_POINTERS" ] 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) { if (v8_enable_pointer_compression || v8_enable_31bit_smis_on_64bit_arch) {
enabled_external_v8_defines += [ "V8_31BIT_SMIS_ON_64BIT_ARCH" ] enabled_external_v8_defines += [ "V8_31BIT_SMIS_ON_64BIT_ARCH" ]
} }
......
...@@ -17,7 +17,7 @@ namespace detail { ...@@ -17,7 +17,7 @@ namespace detail {
// Avoid using kScratchRegister(==r10) since the macro-assembler doesn't use // Avoid using kScratchRegister(==r10) since the macro-assembler doesn't use
// this scope and will conflict. // 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); static constexpr int kNumScratchRegisters = arraysize(kScratchRegisters);
} // namespace detail } // namespace detail
......
...@@ -632,6 +632,11 @@ void Generate_JSEntryVariant(MacroAssembler* masm, StackFrame::Type type, ...@@ -632,6 +632,11 @@ void Generate_JSEntryVariant(MacroAssembler* masm, StackFrame::Type type,
// Initialize the root register. // Initialize the root register.
// C calling convention. The first argument is passed in x0. // C calling convention. The first argument is passed in x0.
__ Mov(kRootRegister, 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 // 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, ...@@ -910,10 +915,13 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
__ Mov(x23, x19); __ Mov(x23, x19);
__ Mov(x24, x19); __ Mov(x24, x19);
__ Mov(x25, x19); __ Mov(x25, x19);
#ifndef V8_COMPRESS_POINTERS_IN_SHARED_CAGE
__ Mov(x28, x19); __ Mov(x28, x19);
#endif
// Don't initialize the reserved registers. // Don't initialize the reserved registers.
// x26 : root register (kRootRegister). // x26 : root register (kRootRegister).
// x27 : context pointer (cp). // x27 : context pointer (cp).
// x28 : pointer cage base register (kPointerCageBaseRegister).
// x29 : frame pointer (fp). // x29 : frame pointer (fp).
Handle<Code> builtin = is_construct Handle<Code> builtin = is_construct
......
...@@ -377,6 +377,12 @@ void Generate_JSEntryVariant(MacroAssembler* masm, StackFrame::Type type, ...@@ -377,6 +377,12 @@ void Generate_JSEntryVariant(MacroAssembler* masm, StackFrame::Type type,
// Initialize the root register. // Initialize the root register.
// C calling convention. The first argument is passed in arg_reg_1. // C calling convention. The first argument is passed in arg_reg_1.
__ movq(kRootRegister, 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. // Save copies of the top frame descriptor on the stack.
...@@ -1633,7 +1639,7 @@ void Builtins::Generate_BaselineOutOfLinePrologue(MacroAssembler* masm) { ...@@ -1633,7 +1639,7 @@ void Builtins::Generate_BaselineOutOfLinePrologue(MacroAssembler* masm) {
__ incl( __ incl(
FieldOperand(feedback_vector, FeedbackVector::kInvocationCountOffset)); FieldOperand(feedback_vector, FeedbackVector::kInvocationCountOffset));
Register return_address = r12; Register return_address = r15;
__ RecordComment("[ Frame Setup"); __ RecordComment("[ Frame Setup");
// Save the return address, so that we can push it to the end of the newly // 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, ...@@ -2810,8 +2816,8 @@ void Builtins::Generate_CEntry(MacroAssembler* masm, int result_size,
DCHECK(save_doubles == kDontSaveFPRegs); DCHECK(save_doubles == kDontSaveFPRegs);
DCHECK(!builtin_exit_frame); DCHECK(!builtin_exit_frame);
__ EnterApiExitFrame(arg_stack_space); __ EnterApiExitFrame(arg_stack_space);
// Move argc into r14 (argv is already in r15). // Move argc into r12 (argv is already in r15).
__ movq(r14, rax); __ movq(r12, rax);
} else { } else {
__ EnterExitFrame( __ EnterExitFrame(
arg_stack_space, save_doubles == kSaveFPRegs, arg_stack_space, save_doubles == kSaveFPRegs,
...@@ -2821,7 +2827,7 @@ void Builtins::Generate_CEntry(MacroAssembler* masm, int result_size, ...@@ -2821,7 +2827,7 @@ void Builtins::Generate_CEntry(MacroAssembler* masm, int result_size,
// rbx: pointer to builtin function (C callee-saved). // rbx: pointer to builtin function (C callee-saved).
// rbp: frame pointer of exit frame (restored after C call). // rbp: frame pointer of exit frame (restored after C call).
// rsp: stack pointer (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). // r15: argv pointer (C callee-saved).
// Check stack alignment. // Check stack alignment.
...@@ -2834,7 +2840,7 @@ void Builtins::Generate_CEntry(MacroAssembler* masm, int result_size, ...@@ -2834,7 +2840,7 @@ void Builtins::Generate_CEntry(MacroAssembler* masm, int result_size,
if (result_size <= kMaxRegisterResultSize) { if (result_size <= kMaxRegisterResultSize) {
// Pass a pointer to the Arguments object as the first argument. // Pass a pointer to the Arguments object as the first argument.
// Return result in single register (rax), or a register pair (rax, rdx). // Return result in single register (rax), or a register pair (rax, rdx).
__ movq(kCCallArg0, r14); // argc. __ movq(kCCallArg0, r12); // argc.
__ movq(kCCallArg1, r15); // argv. __ movq(kCCallArg1, r15); // argv.
__ Move(kCCallArg2, ExternalReference::isolate_address(masm->isolate())); __ Move(kCCallArg2, ExternalReference::isolate_address(masm->isolate()));
} else { } else {
...@@ -2842,7 +2848,7 @@ void Builtins::Generate_CEntry(MacroAssembler* masm, int result_size, ...@@ -2842,7 +2848,7 @@ void Builtins::Generate_CEntry(MacroAssembler* masm, int result_size,
// Pass a pointer to the result location as the first argument. // Pass a pointer to the result location as the first argument.
__ leaq(kCCallArg0, StackSpaceOperand(kArgExtraStackSpace)); __ leaq(kCCallArg0, StackSpaceOperand(kArgExtraStackSpace));
// Pass a pointer to the Arguments object as the second argument. // Pass a pointer to the Arguments object as the second argument.
__ movq(kCCallArg1, r14); // argc. __ movq(kCCallArg1, r12); // argc.
__ movq(kCCallArg2, r15); // argv. __ movq(kCCallArg2, r15); // argv.
__ Move(kCCallArg3, ExternalReference::isolate_address(masm->isolate())); __ Move(kCCallArg3, ExternalReference::isolate_address(masm->isolate()));
} }
...@@ -2866,12 +2872,12 @@ void Builtins::Generate_CEntry(MacroAssembler* masm, int result_size, ...@@ -2866,12 +2872,12 @@ void Builtins::Generate_CEntry(MacroAssembler* masm, int result_size,
// should have returned the exception sentinel. // should have returned the exception sentinel.
if (FLAG_debug_code) { if (FLAG_debug_code) {
Label okay; Label okay;
__ LoadRoot(r14, RootIndex::kTheHoleValue); __ LoadRoot(kScratchRegister, RootIndex::kTheHoleValue);
ExternalReference pending_exception_address = ExternalReference::Create( ExternalReference pending_exception_address = ExternalReference::Create(
IsolateAddressId::kPendingExceptionAddress, masm->isolate()); IsolateAddressId::kPendingExceptionAddress, masm->isolate());
Operand pending_exception_operand = Operand pending_exception_operand =
masm->ExternalReferenceAsOperand(pending_exception_address); masm->ExternalReferenceAsOperand(pending_exception_address);
__ cmp_tagged(r14, pending_exception_operand); __ cmp_tagged(kScratchRegister, pending_exception_operand);
__ j(equal, &okay, Label::kNear); __ j(equal, &okay, Label::kNear);
__ int3(); __ int3();
__ bind(&okay); __ bind(&okay);
...@@ -3212,7 +3218,7 @@ void Builtins::Generate_GenericJSToWasmWrapper(MacroAssembler* masm) { ...@@ -3212,7 +3218,7 @@ void Builtins::Generate_GenericJSToWasmWrapper(MacroAssembler* masm) {
kLastSpillOffset - kSystemPointerSize; kLastSpillOffset - kSystemPointerSize;
// For Integer section. // For Integer section.
// Set the current_int_param_slot to point to the start of the 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)); __ leaq(current_int_param_slot, MemOperand(rsp, -kSystemPointerSize));
Register params_size = param_count; Register params_size = param_count;
param_count = no_reg; param_count = no_reg;
...@@ -3326,7 +3332,7 @@ void Builtins::Generate_GenericJSToWasmWrapper(MacroAssembler* masm) { ...@@ -3326,7 +3332,7 @@ void Builtins::Generate_GenericJSToWasmWrapper(MacroAssembler* masm) {
// ----------- S t a t e ------------- // ----------- S t a t e -------------
// -- r8 : start_int_section // -- r8 : start_int_section
// -- rdi : start_float_section // -- rdi : start_float_section
// -- r14 : current_int_param_slot // -- r10 : current_int_param_slot
// -- r15 : current_float_param_slot // -- r15 : current_float_param_slot
// -- r11 : valuetypes_array_ptr // -- r11 : valuetypes_array_ptr
// -- r12 : valuetype // -- r12 : valuetype
...@@ -3758,7 +3764,7 @@ int Offset(ExternalReference ref0, ExternalReference ref1) { ...@@ -3758,7 +3764,7 @@ int Offset(ExternalReference ref0, ExternalReference ref1) {
} }
// Calls an API function. Allocates HandleScope, extracts returned value // 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 // caller-save registers. Restores context. On return removes
// stack_space * kSystemPointerSize (GCed). // stack_space * kSystemPointerSize (GCed).
void CallApiFunctionAndReturn(MacroAssembler* masm, Register function_address, void CallApiFunctionAndReturn(MacroAssembler* masm, Register function_address,
...@@ -3785,7 +3791,7 @@ 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); DCHECK(rdx == function_address || r8 == function_address);
// Allocate HandleScope in callee-save registers. // Allocate HandleScope in callee-save registers.
Register prev_next_address_reg = r14; Register prev_next_address_reg = r12;
Register prev_limit_reg = rbx; Register prev_limit_reg = rbx;
Register base_reg = r15; Register base_reg = r15;
__ Move(base_reg, next_address); __ Move(base_reg, next_address);
......
...@@ -1036,6 +1036,9 @@ void TurboAssembler::Uxtw(const Register& rd, const Register& rn) { ...@@ -1036,6 +1036,9 @@ void TurboAssembler::Uxtw(const Register& rd, const Register& rn) {
void TurboAssembler::InitializeRootRegister() { void TurboAssembler::InitializeRootRegister() {
ExternalReference isolate_root = ExternalReference::isolate_root(isolate()); ExternalReference isolate_root = ExternalReference::isolate_root(isolate());
Mov(kRootRegister, Operand(isolate_root)); 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) { void MacroAssembler::SmiTag(Register dst, Register src) {
......
...@@ -2816,14 +2816,14 @@ void TurboAssembler::DecompressTaggedPointer(const Register& destination, ...@@ -2816,14 +2816,14 @@ void TurboAssembler::DecompressTaggedPointer(const Register& destination,
const MemOperand& field_operand) { const MemOperand& field_operand) {
RecordComment("[ DecompressTaggedPointer"); RecordComment("[ DecompressTaggedPointer");
Ldr(destination.W(), field_operand); Ldr(destination.W(), field_operand);
Add(destination, kRootRegister, destination); Add(destination, kPointerCageBaseRegister, destination);
RecordComment("]"); RecordComment("]");
} }
void TurboAssembler::DecompressTaggedPointer(const Register& destination, void TurboAssembler::DecompressTaggedPointer(const Register& destination,
const Register& source) { const Register& source) {
RecordComment("[ DecompressTaggedPointer"); RecordComment("[ DecompressTaggedPointer");
Add(destination, kRootRegister, Operand(source, UXTW)); Add(destination, kPointerCageBaseRegister, Operand(source, UXTW));
RecordComment("]"); RecordComment("]");
} }
...@@ -2831,7 +2831,7 @@ void TurboAssembler::DecompressAnyTagged(const Register& destination, ...@@ -2831,7 +2831,7 @@ void TurboAssembler::DecompressAnyTagged(const Register& destination,
const MemOperand& field_operand) { const MemOperand& field_operand) {
RecordComment("[ DecompressAnyTagged"); RecordComment("[ DecompressAnyTagged");
Ldr(destination.W(), field_operand); Ldr(destination.W(), field_operand);
Add(destination, kRootRegister, destination); Add(destination, kPointerCageBaseRegister, destination);
RecordComment("]"); RecordComment("]");
} }
......
...@@ -30,11 +30,21 @@ namespace internal { ...@@ -30,11 +30,21 @@ namespace internal {
// x18 is the platform register and is reserved for the use of platform ABIs. // 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. // 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(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(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(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) \ #define FLOAT_REGISTERS(V) \
V(s0) V(s1) V(s2) V(s3) V(s4) V(s5) V(s6) V(s7) \ 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); ...@@ -458,6 +468,12 @@ ALIAS_REGISTER(Register, wip1, w17);
// Root register. // Root register.
ALIAS_REGISTER(Register, kRootRegister, x26); ALIAS_REGISTER(Register, kRootRegister, x26);
ALIAS_REGISTER(Register, rr, 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. // Context pointer register.
ALIAS_REGISTER(Register, cp, x27); ALIAS_REGISTER(Register, cp, x27);
ALIAS_REGISTER(Register, fp, x29); ALIAS_REGISTER(Register, fp, x29);
......
...@@ -25,6 +25,9 @@ void CallInterfaceDescriptorData::InitializePlatformSpecific( ...@@ -25,6 +25,9 @@ void CallInterfaceDescriptorData::InitializePlatformSpecific(
// within the calling convention are disallowed. // within the calling convention are disallowed.
#ifdef DEBUG #ifdef DEBUG
CHECK_NE(registers[i], kRootRegister); CHECK_NE(registers[i], kRootRegister);
#ifdef V8_COMPRESS_POINTERS_IN_SHARED_CAGE
CHECK_NE(registers[i], kPointerCageBaseRegister);
#endif
// Check for duplicated registers. // Check for duplicated registers.
for (int j = i + 1; j < register_parameter_count; j++) { for (int j = i + 1; j < register_parameter_count; j++) {
CHECK_NE(registers[i], registers[j]); CHECK_NE(registers[i], registers[j]);
......
...@@ -288,7 +288,7 @@ void TurboAssembler::DecompressTaggedPointer(Register destination, ...@@ -288,7 +288,7 @@ void TurboAssembler::DecompressTaggedPointer(Register destination,
Operand field_operand) { Operand field_operand) {
RecordComment("[ DecompressTaggedPointer"); RecordComment("[ DecompressTaggedPointer");
movl(destination, field_operand); movl(destination, field_operand);
addq(destination, kRootRegister); addq(destination, kPointerCageBaseRegister);
RecordComment("]"); RecordComment("]");
} }
...@@ -296,7 +296,7 @@ void TurboAssembler::DecompressTaggedPointer(Register destination, ...@@ -296,7 +296,7 @@ void TurboAssembler::DecompressTaggedPointer(Register destination,
Register source) { Register source) {
RecordComment("[ DecompressTaggedPointer"); RecordComment("[ DecompressTaggedPointer");
movl(destination, source); movl(destination, source);
addq(destination, kRootRegister); addq(destination, kPointerCageBaseRegister);
RecordComment("]"); RecordComment("]");
} }
...@@ -304,7 +304,7 @@ void TurboAssembler::DecompressAnyTagged(Register destination, ...@@ -304,7 +304,7 @@ void TurboAssembler::DecompressAnyTagged(Register destination,
Operand field_operand) { Operand field_operand) {
RecordComment("[ DecompressAnyTagged"); RecordComment("[ DecompressAnyTagged");
movl(destination, field_operand); movl(destination, field_operand);
addq(destination, kRootRegister); addq(destination, kPointerCageBaseRegister);
RecordComment("]"); RecordComment("]");
} }
...@@ -3379,7 +3379,7 @@ void TurboAssembler::AllocateStackSpace(int bytes) { ...@@ -3379,7 +3379,7 @@ void TurboAssembler::AllocateStackSpace(int bytes) {
} }
#endif #endif
void MacroAssembler::EnterExitFramePrologue(bool save_rax, void MacroAssembler::EnterExitFramePrologue(Register saved_rax_reg,
StackFrame::Type frame_type) { StackFrame::Type frame_type) {
DCHECK(frame_type == StackFrame::EXIT || DCHECK(frame_type == StackFrame::EXIT ||
frame_type == StackFrame::BUILTIN_EXIT); frame_type == StackFrame::BUILTIN_EXIT);
...@@ -3399,8 +3399,8 @@ void MacroAssembler::EnterExitFramePrologue(bool save_rax, ...@@ -3399,8 +3399,8 @@ void MacroAssembler::EnterExitFramePrologue(bool save_rax,
Push(Immediate(0)); // Saved entry sp, patched before call. Push(Immediate(0)); // Saved entry sp, patched before call.
// Save the frame pointer and the context in top. // Save the frame pointer and the context in top.
if (save_rax) { if (saved_rax_reg != no_reg) {
movq(r14, rax); // Backup rax in callee-save register. movq(saved_rax_reg, rax); // Backup rax in callee-save register.
} }
Store( Store(
...@@ -3449,18 +3449,19 @@ void MacroAssembler::EnterExitFrameEpilogue(int arg_stack_space, ...@@ -3449,18 +3449,19 @@ void MacroAssembler::EnterExitFrameEpilogue(int arg_stack_space,
void MacroAssembler::EnterExitFrame(int arg_stack_space, bool save_doubles, void MacroAssembler::EnterExitFrame(int arg_stack_space, bool save_doubles,
StackFrame::Type frame_type) { 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, // Set up argv in callee-saved register r15. It is reused in LeaveExitFrame,
// so it must be retained across the C-call. // so it must be retained across the C-call.
int offset = StandardFrameConstants::kCallerSPOffset - kSystemPointerSize; 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); EnterExitFrameEpilogue(arg_stack_space, save_doubles);
} }
void MacroAssembler::EnterApiExitFrame(int arg_stack_space) { void MacroAssembler::EnterApiExitFrame(int arg_stack_space) {
EnterExitFramePrologue(false, StackFrame::EXIT); EnterExitFramePrologue(no_reg, StackFrame::EXIT);
EnterExitFrameEpilogue(arg_stack_space, false); EnterExitFrameEpilogue(arg_stack_space, false);
} }
......
...@@ -704,6 +704,9 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { ...@@ -704,6 +704,9 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
void InitializeRootRegister() { void InitializeRootRegister() {
ExternalReference isolate_root = ExternalReference::isolate_root(isolate()); ExternalReference isolate_root = ExternalReference::isolate_root(isolate());
Move(kRootRegister, isolate_root); Move(kRootRegister, isolate_root);
#ifdef V8_COMPRESS_POINTERS_IN_SHARED_CAGE
Move(kPointerCageBaseRegister, isolate_root);
#endif
} }
void SaveRegisters(RegList registers); void SaveRegisters(RegList registers);
...@@ -1146,7 +1149,8 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler { ...@@ -1146,7 +1149,8 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {
Register actual_parameter_count, Label* done, Register actual_parameter_count, Label* done,
InvokeFlag flag); 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 // Allocates arg_stack_space * kSystemPointerSize memory (not GCed) on the
// stack accessible via StackSpaceOperand. // stack accessible via StackSpaceOperand.
......
...@@ -29,20 +29,29 @@ namespace internal { ...@@ -29,20 +29,29 @@ namespace internal {
V(r14) \ V(r14) \
V(r15) V(r15)
#define ALLOCATABLE_GENERAL_REGISTERS(V) \ #define ALWAYS_ALLOCATABLE_GENERAL_REGISTERS(V) \
V(rax) \ V(rax) \
V(rbx) \ V(rbx) \
V(rdx) \ V(rdx) \
V(rcx) \ V(rcx) \
V(rsi) \ V(rsi) \
V(rdi) \ V(rdi) \
V(r8) \ V(r8) \
V(r9) \ V(r9) \
V(r11) \ V(r11) \
V(r12) \ V(r12) \
V(r14) \
V(r15) 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 { enum RegisterCode {
#define REGISTER_CODE(R) kRegCode_##R, #define REGISTER_CODE(R) kRegCode_##R,
GENERAL_REGISTERS(REGISTER_CODE) GENERAL_REGISTERS(REGISTER_CODE)
...@@ -201,7 +210,7 @@ constexpr Register kAllocateSizeRegister = rdx; ...@@ -201,7 +210,7 @@ constexpr Register kAllocateSizeRegister = rdx;
constexpr Register kSpeculationPoisonRegister = r12; constexpr Register kSpeculationPoisonRegister = r12;
constexpr Register kInterpreterAccumulatorRegister = rax; constexpr Register kInterpreterAccumulatorRegister = rax;
constexpr Register kInterpreterBytecodeOffsetRegister = r9; constexpr Register kInterpreterBytecodeOffsetRegister = r9;
constexpr Register kInterpreterBytecodeArrayRegister = r14; constexpr Register kInterpreterBytecodeArrayRegister = r12;
constexpr Register kInterpreterDispatchTableRegister = r15; constexpr Register kInterpreterDispatchTableRegister = r15;
constexpr Register kJavaScriptCallArgCountRegister = rax; constexpr Register kJavaScriptCallArgCountRegister = rax;
...@@ -221,6 +230,11 @@ constexpr Register kWasmInstanceRegister = rsi; ...@@ -221,6 +230,11 @@ constexpr Register kWasmInstanceRegister = rsi;
constexpr Register kScratchRegister = r10; constexpr Register kScratchRegister = r10;
constexpr XMMRegister kScratchDoubleReg = xmm15; constexpr XMMRegister kScratchDoubleReg = xmm15;
constexpr Register kRootRegister = r13; // callee save 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; constexpr Register kOffHeapTrampolineRegister = kScratchRegister;
......
...@@ -962,6 +962,10 @@ void Deoptimizer::DoComputeOutputFrames() { ...@@ -962,6 +962,10 @@ void Deoptimizer::DoComputeOutputFrames() {
FrameDescription* topmost = output_[count - 1]; FrameDescription* topmost = output_[count - 1];
topmost->GetRegisterValues()->SetRegister(kRootRegister.code(), topmost->GetRegisterValues()->SetRegister(kRootRegister.code(),
isolate()->isolate_root()); isolate()->isolate_root());
#ifdef V8_COMPRESS_POINTERS_IN_SHARED_CAGE
topmost->GetRegisterValues()->SetRegister(kPointerCageBaseRegister.code(),
isolate()->isolate_root());
#endif
// Print some helpful diagnostic information. // Print some helpful diagnostic information.
if (verbose_tracing_enabled()) { if (verbose_tracing_enabled()) {
......
...@@ -58,11 +58,15 @@ constexpr RegList kLiftoffAssemblerFpCacheRegs = LowDwVfpRegister::ListOf( ...@@ -58,11 +58,15 @@ constexpr RegList kLiftoffAssemblerFpCacheRegs = LowDwVfpRegister::ListOf(
#elif V8_TARGET_ARCH_ARM64 #elif V8_TARGET_ARCH_ARM64
// x16: ip0, x17: ip1, x18: platform register, x26: root, x27: cp, x29: fp, // x16: ip0, x17: ip1, x18: platform register, x26: root, x27: cp, x8: base,
// x30: lr, x31: xzr. // x29: fp, x30: lr, x31: xzr.
constexpr RegList kLiftoffAssemblerGpCacheRegs = constexpr RegList kLiftoffAssemblerGpCacheRegs =
CPURegister::ListOf(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, 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); x13, x14, x15, x19, x20, x21, x22, x23, x24, x25, x28);
#endif
// d15: fp_zero, d30-d31: macro-assembler scratch V Registers. // d15: fp_zero, d30-d31: macro-assembler scratch V Registers.
constexpr RegList kLiftoffAssemblerFpCacheRegs = CPURegister::ListOf( constexpr RegList kLiftoffAssemblerFpCacheRegs = CPURegister::ListOf(
......
...@@ -60,10 +60,18 @@ using F0 = int(); ...@@ -60,10 +60,18 @@ using F0 = int();
static void EntryCode(MacroAssembler* masm) { static void EntryCode(MacroAssembler* masm) {
// Smi constant register is callee save. // Smi constant register is callee save.
__ pushq(kRootRegister); __ pushq(kRootRegister);
#ifdef V8_COMPRESS_POINTERS_IN_SHARED_CAGE
__ pushq(kPointerCageBaseRegister);
#endif
__ InitializeRootRegister(); __ 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) { TEST(Smi) {
// Check that C++ Smi operations work as expected. // Check that C++ Smi operations work as expected.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment