summaryrefslogtreecommitdiff
path: root/runtime/nterp_helpers.cc
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/nterp_helpers.cc')
-rw-r--r--runtime/nterp_helpers.cc53
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