diff options
Diffstat (limited to 'runtime/nterp_helpers.cc')
| -rw-r--r-- | runtime/nterp_helpers.cc | 53 |
1 files changed, 39 insertions, 14 deletions
diff --git a/runtime/nterp_helpers.cc b/runtime/nterp_helpers.cc index 12afa3a014..36135fd712 100644 --- a/runtime/nterp_helpers.cc +++ b/runtime/nterp_helpers.cc @@ -112,6 +112,11 @@ static constexpr size_t NterpGetFrameEntrySize(InstructionSet isa) { core_spills = arm64::Arm64CalleeSaveFrame::GetCoreSpills(CalleeSaveType::kSaveAllCalleeSaves); fp_spills = arm64::Arm64CalleeSaveFrame::GetFpSpills(CalleeSaveType::kSaveAllCalleeSaves); break; + case InstructionSet::kRiscv64: + core_spills = + riscv64::Riscv64CalleeSaveFrame::GetCoreSpills(CalleeSaveType::kSaveAllCalleeSaves); + fp_spills = riscv64::Riscv64CalleeSaveFrame::GetFpSpills(CalleeSaveType::kSaveAllCalleeSaves); + break; default: InstructionSetAbort(isa); } @@ -120,9 +125,7 @@ static constexpr size_t NterpGetFrameEntrySize(InstructionSet isa) { static_cast<size_t>(InstructionSetPointerSize(isa)); } -static uint16_t GetNumberOfOutRegs(ArtMethod* method, InstructionSet isa) - REQUIRES_SHARED(Locks::mutator_lock_) { - CodeItemDataAccessor accessor(method->DexInstructionData()); +static uint16_t GetNumberOfOutRegs(const CodeItemDataAccessor& accessor, InstructionSet isa) { uint16_t out_regs = accessor.OutsSize(); switch (isa) { case InstructionSet::kX86: { @@ -136,14 +139,23 @@ static uint16_t GetNumberOfOutRegs(ArtMethod* method, InstructionSet isa) return out_regs; } -size_t NterpGetFrameSize(ArtMethod* method, InstructionSet isa) { +static uint16_t GetNumberOfOutRegs(ArtMethod* method, InstructionSet isa) + REQUIRES_SHARED(Locks::mutator_lock_) { + CodeItemDataAccessor accessor(method->DexInstructionData()); + return GetNumberOfOutRegs(accessor, isa); +} + +// Note: There may be two pieces of alignment but there is no need to align +// out args to `kPointerSize` separately before aligning to kStackAlignment. +// This allows using the size without padding for the maximum frame size check +// in `CanMethodUseNterp()`. +static size_t NterpGetFrameSizeWithoutPadding(ArtMethod* method, InstructionSet isa) + REQUIRES_SHARED(Locks::mutator_lock_) { CodeItemDataAccessor accessor(method->DexInstructionData()); const uint16_t num_regs = accessor.RegistersSize(); - const uint16_t out_regs = GetNumberOfOutRegs(method, isa); + const uint16_t out_regs = GetNumberOfOutRegs(accessor, isa); size_t pointer_size = static_cast<size_t>(InstructionSetPointerSize(isa)); - // Note: There may be two pieces of alignment but there is no need to align - // out args to `kPointerSize` separately before aligning to kStackAlignment. DCHECK(IsAlignedParam(kStackAlignment, pointer_size)); DCHECK(IsAlignedParam(NterpGetFrameEntrySize(isa), pointer_size)); DCHECK(IsAlignedParam(kVRegSize * 2, pointer_size)); @@ -154,7 +166,13 @@ size_t NterpGetFrameSize(ArtMethod* method, InstructionSet isa) { pointer_size + // saved dex pc (out_regs * kVRegSize) + // out arguments pointer_size; // method - return RoundUp(frame_size, kStackAlignment); + return frame_size; +} + +// The frame size nterp will use for the given method. +static inline size_t NterpGetFrameSize(ArtMethod* method, InstructionSet isa) + REQUIRES_SHARED(Locks::mutator_lock_) { + return RoundUp(NterpGetFrameSizeWithoutPadding(method, isa), kStackAlignment); } QuickMethodFrameInfo NterpFrameInfo(ArtMethod** frame) { @@ -162,7 +180,7 @@ QuickMethodFrameInfo NterpFrameInfo(ArtMethod** frame) { RuntimeCalleeSaveFrame::GetCoreSpills(CalleeSaveType::kSaveAllCalleeSaves); uint32_t fp_spills = RuntimeCalleeSaveFrame::GetFpSpills(CalleeSaveType::kSaveAllCalleeSaves); - return QuickMethodFrameInfo(NterpGetFrameSize(*frame), core_spills, fp_spills); + return QuickMethodFrameInfo(NterpGetFrameSize(*frame, kRuntimeISA), core_spills, fp_spills); } uintptr_t NterpGetRegistersArray(ArtMethod** frame) { @@ -206,13 +224,20 @@ uintptr_t NterpGetCatchHandler() { } bool CanMethodUseNterp(ArtMethod* method, InstructionSet isa) { - return !method->IsNative() && - method->IsInvokable() && - !method->MustCountLocks() && + uint32_t access_flags = method->GetAccessFlags(); + if (ArtMethod::IsNative(access_flags) || + !ArtMethod::IsInvokable(access_flags) || + ArtMethod::MustCountLocks(access_flags) || // Proxy methods do not go through the JIT like other methods, so we don't // run them with nterp. - !method->IsProxyMethod() && - NterpGetFrameSize(method, isa) <= interpreter::kNterpMaxFrame; + method->IsProxyMethod()) { + return false; + } + // There is no need to add the alignment padding size for comparison with aligned limit. + size_t frame_size_without_padding = NterpGetFrameSizeWithoutPadding(method, isa); + DCHECK_EQ(NterpGetFrameSize(method, isa), RoundUp(frame_size_without_padding, kStackAlignment)); + static_assert(IsAligned<kStackAlignment>(interpreter::kNterpMaxFrame)); + return frame_size_without_padding <= interpreter::kNterpMaxFrame; } } // namespace art |