mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 00:13:50 +00:00
[vm, compiler] Support ShadowCallStack on Fuchsia RISC-V.
Remove fixed uses of X18. TEST=ci (Linux), speculative (Fuchsia) Change-Id: I20e31fc2ab7d44cbf02e591be92261067158509d Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/244943 Reviewed-by: Alexander Markov <alexmarkov@google.com> Commit-Queue: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
parent
e1773c7ebc
commit
09b7f36b2f
|
@ -3031,9 +3031,9 @@ void Assembler::StoreBarrier(Register object,
|
|||
if (object != kWriteBarrierValueReg) {
|
||||
PushRegister(kWriteBarrierValueReg);
|
||||
} else {
|
||||
COMPILE_ASSERT(S2 != kWriteBarrierValueReg);
|
||||
COMPILE_ASSERT(S3 != kWriteBarrierValueReg);
|
||||
objectForCall = (value == S2) ? S3 : S2;
|
||||
COMPILE_ASSERT(S4 != kWriteBarrierValueReg);
|
||||
objectForCall = (value == S3) ? S4 : S3;
|
||||
PushRegisterPair(kWriteBarrierValueReg, objectForCall);
|
||||
mv(objectForCall, object);
|
||||
}
|
||||
|
|
|
@ -272,12 +272,12 @@ void StubCodeCompiler::GenerateExitSafepointIgnoreUnwindInProgressStub(
|
|||
// Stack: set up for native call (SP), aligned, CSP < SP
|
||||
//
|
||||
// On exit:
|
||||
// S2: clobbered, although normally callee-saved
|
||||
// S3: clobbered, although normally callee-saved
|
||||
// Stack: preserved, CSP == SP
|
||||
void StubCodeCompiler::GenerateCallNativeThroughSafepointStub(
|
||||
Assembler* assembler) {
|
||||
COMPILE_ASSERT(IsAbiPreservedRegister(S2));
|
||||
__ mv(S2, RA);
|
||||
COMPILE_ASSERT(IsAbiPreservedRegister(S3));
|
||||
__ mv(S3, RA);
|
||||
__ LoadImmediate(T1, target::Thread::exit_through_ffi());
|
||||
__ TransitionGeneratedToNative(T0, FPREG, T1 /*volatile*/,
|
||||
/*enter_safepoint=*/true);
|
||||
|
@ -294,7 +294,7 @@ void StubCodeCompiler::GenerateCallNativeThroughSafepointStub(
|
|||
__ jalr(T0);
|
||||
|
||||
__ TransitionNativeToGenerated(T1, /*leave_safepoint=*/true);
|
||||
__ jr(S2);
|
||||
__ jr(S3);
|
||||
}
|
||||
|
||||
#if !defined(DART_PRECOMPILER)
|
||||
|
@ -1321,7 +1321,9 @@ void StubCodeCompiler::GenerateInvokeDartCodeStub(Assembler* assembler) {
|
|||
__ lx(TMP2, Address(A3, target::Thread::invoke_dart_code_stub_offset()));
|
||||
__ PushRegister(TMP2);
|
||||
|
||||
#if defined(USING_SHADOW_CALL_STACK)
|
||||
#if defined(DART_TARGET_OS_FUCHSIA)
|
||||
__ sx(S2, Address(A3, target::Thread::saved_shadow_call_stack_offset()));
|
||||
#elif defined(USING_SHADOW_CALL_STACK)
|
||||
#error Unimplemented
|
||||
#endif
|
||||
|
||||
|
@ -3032,7 +3034,9 @@ void StubCodeCompiler::GenerateJumpToFrameStub(Assembler* assembler) {
|
|||
__ mv(SP, A1); // Stack pointer.
|
||||
__ mv(FP, A2); // Frame_pointer.
|
||||
__ mv(THR, A3);
|
||||
#if defined(USING_SHADOW_CALL_STACK)
|
||||
#if defined(DART_TARGET_OS_FUCHSIA)
|
||||
__ lx(S2, Address(THR, target::Thread::saved_shadow_call_stack_offset()));
|
||||
#elif defined(USING_SHADOW_CALL_STACK)
|
||||
#error Unimplemented
|
||||
#endif
|
||||
Label exit_through_non_ffi;
|
||||
|
|
|
@ -61,7 +61,7 @@ enum Register {
|
|||
A5 = 15, // PP, untagged
|
||||
A6 = 16,
|
||||
A7 = 17,
|
||||
S2 = 18,
|
||||
S2 = 18, // ShadowCallStack
|
||||
S3 = 19,
|
||||
S4 = 20, // ARGS_DESC_REG
|
||||
S5 = 21, // IC_DATA_REG
|
||||
|
@ -192,10 +192,10 @@ struct InstantiationABI {
|
|||
// Registers in addition to those listed in TypeTestABI used inside the
|
||||
// implementation of type testing stubs that are _not_ preserved.
|
||||
struct TTSInternalRegs {
|
||||
static constexpr Register kInstanceTypeArgumentsReg = S2;
|
||||
static constexpr Register kScratchReg = S3;
|
||||
static constexpr Register kSubTypeArgumentReg = S4;
|
||||
static constexpr Register kSuperTypeArgumentReg = S5;
|
||||
static constexpr Register kInstanceTypeArgumentsReg = S3;
|
||||
static constexpr Register kScratchReg = S4;
|
||||
static constexpr Register kSubTypeArgumentReg = S5;
|
||||
static constexpr Register kSuperTypeArgumentReg = S6;
|
||||
|
||||
// Must be pushed/popped whenever generic type arguments are being checked as
|
||||
// they overlap with registers in TypeTestABI.
|
||||
|
@ -210,10 +210,10 @@ struct TTSInternalRegs {
|
|||
// Registers in addition to those listed in TypeTestABI used inside the
|
||||
// implementation of subtype test cache stubs that are _not_ preserved.
|
||||
struct STCInternalRegs {
|
||||
static constexpr Register kInstanceCidOrSignatureReg = S2;
|
||||
static constexpr Register kInstanceInstantiatorTypeArgumentsReg = S3;
|
||||
static constexpr Register kInstanceParentFunctionTypeArgumentsReg = S4;
|
||||
static constexpr Register kInstanceDelayedFunctionTypeArgumentsReg = S5;
|
||||
static constexpr Register kInstanceCidOrSignatureReg = S3;
|
||||
static constexpr Register kInstanceInstantiatorTypeArgumentsReg = S4;
|
||||
static constexpr Register kInstanceParentFunctionTypeArgumentsReg = S5;
|
||||
static constexpr Register kInstanceDelayedFunctionTypeArgumentsReg = S6;
|
||||
|
||||
static const intptr_t kInternalRegisters =
|
||||
(1 << kInstanceCidOrSignatureReg) |
|
||||
|
@ -443,15 +443,30 @@ constexpr RegList kAbiPreservedCpuRegs = R(S1) | R(S2) | R(S3) | R(S4) | R(S5) |
|
|||
R(S6) | R(S7) | R(S8) | R(S9) |
|
||||
R(S10) | R(S11);
|
||||
constexpr int kAbiPreservedCpuRegCount = 11;
|
||||
|
||||
#if defined(DART_TARGET_OS_FUCHSIA)
|
||||
// We rely on X18 not being touched by Dart generated assembly or stubs at all.
|
||||
// We rely on that any calls into C++ also preserve X18.
|
||||
constexpr intptr_t kReservedCpuRegisters =
|
||||
R(ZR) | R(TP) | R(GP) | R(SP) | R(FP) | R(TMP) | R(TMP2) | R(PP) | R(THR) |
|
||||
R(RA) | R(WRITE_BARRIER_MASK) | R(NULL_REG) | R(DISPATCH_TABLE_REG) |
|
||||
R(FAR_TMP) | R(18);
|
||||
constexpr intptr_t kNumberOfReservedCpuRegisters = 15;
|
||||
#else
|
||||
constexpr intptr_t kReservedCpuRegisters =
|
||||
R(ZR) | R(TP) | R(GP) | R(SP) | R(FP) | R(TMP) | R(TMP2) | R(PP) | R(THR) |
|
||||
R(RA) | R(WRITE_BARRIER_MASK) | R(NULL_REG) | R(DISPATCH_TABLE_REG) |
|
||||
R(FAR_TMP);
|
||||
constexpr intptr_t kNumberOfReservedCpuRegisters = 14;
|
||||
#endif
|
||||
// CPU registers available to Dart allocator.
|
||||
constexpr RegList kDartAvailableCpuRegs =
|
||||
kAllCpuRegistersList & ~kReservedCpuRegisters;
|
||||
#if defined(DART_TARGET_OS_FUCHSIA)
|
||||
constexpr int kNumberOfDartAvailableCpuRegs = 17;
|
||||
#else
|
||||
constexpr int kNumberOfDartAvailableCpuRegs = 18;
|
||||
#endif
|
||||
// Registers X8-15 (S0-1,A0-5) have more compressed instructions available.
|
||||
constexpr int kRegisterAllocationBias = 8;
|
||||
// Registers available to Dart that are not preserved by runtime calls.
|
||||
|
@ -511,7 +526,8 @@ class CallingConventions {
|
|||
static constexpr Register kSecondReturnReg = A1;
|
||||
static constexpr FpuRegister kReturnFpuReg = FA0;
|
||||
|
||||
static constexpr Register kFfiAnyNonAbiRegister = S2; // S0=FP, S1=THR
|
||||
// S0=FP, S1=THR, S2=ShadowCallStack
|
||||
static constexpr Register kFfiAnyNonAbiRegister = S3;
|
||||
static constexpr Register kFirstNonArgumentRegister = T0;
|
||||
static constexpr Register kSecondNonArgumentRegister = T1;
|
||||
static constexpr Register kStackPointerRegister = SPREG;
|
||||
|
|
|
@ -418,16 +418,16 @@ bool PcRelativeTrampolineJumpPattern::IsValid() const {
|
|||
|
||||
intptr_t TypeTestingStubCallPattern::GetSubtypeTestCachePoolIndex() {
|
||||
// Calls to the type testing stubs look like:
|
||||
// lx s3, ...
|
||||
// lx s4, ...
|
||||
// lx Rn, idx(pp)
|
||||
// jalr s3
|
||||
// jalr s4
|
||||
// where Rn = TypeTestABI::kSubtypeTestCacheReg.
|
||||
|
||||
// Ensure the caller of the type testing stub (whose return address is [pc_])
|
||||
// branched via `blr R9` or a pc-relative call.
|
||||
if (*reinterpret_cast<uint16_t*>(pc_ - 2) == 0x9982) { // jalr s3
|
||||
if (*reinterpret_cast<uint16_t*>(pc_ - 2) == 0x9a02) { // jalr s4
|
||||
// indirect call
|
||||
// xxxx c.jalr s3
|
||||
// xxxx c.jalr s4
|
||||
Register reg;
|
||||
intptr_t pool_index = -1;
|
||||
InstructionPattern::DecodeLoadWordFromPool(pc_ - 2, ®, &pool_index);
|
||||
|
|
Loading…
Reference in a new issue