xref: /aosp_15_r20/art/runtime/nterp_helpers.cc (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2019 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker #include "arch/instruction_set.h"
18*795d594fSAndroid Build Coastguard Worker #include "art_method-inl.h"
19*795d594fSAndroid Build Coastguard Worker #include "dex/code_item_accessors.h"
20*795d594fSAndroid Build Coastguard Worker #include "entrypoints/quick/callee_save_frame.h"
21*795d594fSAndroid Build Coastguard Worker #include "interpreter/mterp/nterp.h"
22*795d594fSAndroid Build Coastguard Worker #include "nterp_helpers.h"
23*795d594fSAndroid Build Coastguard Worker #include "oat/oat_quick_method_header.h"
24*795d594fSAndroid Build Coastguard Worker #include "quick/quick_method_frame_info.h"
25*795d594fSAndroid Build Coastguard Worker 
26*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
27*795d594fSAndroid Build Coastguard Worker 
28*795d594fSAndroid Build Coastguard Worker /**
29*795d594fSAndroid Build Coastguard Worker  * An nterp frame follows the optimizing compiler's ABI conventions, with
30*795d594fSAndroid Build Coastguard Worker  * int/long/reference parameters being passed in core registers / stack and
31*795d594fSAndroid Build Coastguard Worker  * float/double parameters being passed in floating point registers / stack.
32*795d594fSAndroid Build Coastguard Worker  *
33*795d594fSAndroid Build Coastguard Worker  * There are no ManagedStack transitions between compiler and nterp frames.
34*795d594fSAndroid Build Coastguard Worker  *
35*795d594fSAndroid Build Coastguard Worker  * On entry, nterp will copy its parameters to a dex register array allocated on
36*795d594fSAndroid Build Coastguard Worker  * the stack. There is a fast path when calling from nterp to nterp to not
37*795d594fSAndroid Build Coastguard Worker  * follow the ABI but just copy the parameters from the caller's dex registers
38*795d594fSAndroid Build Coastguard Worker  * to the callee's dex registers.
39*795d594fSAndroid Build Coastguard Worker  *
40*795d594fSAndroid Build Coastguard Worker  * The stack layout of an nterp frame is:
41*795d594fSAndroid Build Coastguard Worker  *    ----------------
42*795d594fSAndroid Build Coastguard Worker  *    |              |      All callee save registers of the platform
43*795d594fSAndroid Build Coastguard Worker  *    | callee-save  |      (core and floating point).
44*795d594fSAndroid Build Coastguard Worker  *    | registers    |      On x86 and x64 this includes the return address,
45*795d594fSAndroid Build Coastguard Worker  *    |              |      already spilled on entry.
46*795d594fSAndroid Build Coastguard Worker  *    ----------------
47*795d594fSAndroid Build Coastguard Worker  *    |   x86 args   |      x86 only: registers used for argument passing.
48*795d594fSAndroid Build Coastguard Worker  *    ----------------
49*795d594fSAndroid Build Coastguard Worker  *    |  alignment   |      Stack aligment of kStackAlignment.
50*795d594fSAndroid Build Coastguard Worker  *    ----------------
51*795d594fSAndroid Build Coastguard Worker  *    |              |      Contains `registers_size` entries (of size 4) from
52*795d594fSAndroid Build Coastguard Worker  *    |    dex       |      the code item information of the method.
53*795d594fSAndroid Build Coastguard Worker  *    |  registers   |
54*795d594fSAndroid Build Coastguard Worker  *    |              |
55*795d594fSAndroid Build Coastguard Worker  *    ----------------
56*795d594fSAndroid Build Coastguard Worker  *    |              |      A copy of the dex registers above, but only
57*795d594fSAndroid Build Coastguard Worker  *    |  reference   |      containing references, used for GC.
58*795d594fSAndroid Build Coastguard Worker  *    |  registers   |
59*795d594fSAndroid Build Coastguard Worker  *    |              |
60*795d594fSAndroid Build Coastguard Worker  *    ----------------
61*795d594fSAndroid Build Coastguard Worker  *    |  caller fp   |      Frame pointer of caller. Stored below the reference
62*795d594fSAndroid Build Coastguard Worker  *    ----------------      registers array for easy access from nterp when returning.
63*795d594fSAndroid Build Coastguard Worker  *    |  dex_pc_ptr  |      Pointer to the dex instruction being executed.
64*795d594fSAndroid Build Coastguard Worker  *    ----------------      Stored whenever nterp goes into the runtime.
65*795d594fSAndroid Build Coastguard Worker  *    |  alignment   |      Pointer aligment for dex_pc_ptr and caller_fp.
66*795d594fSAndroid Build Coastguard Worker  *    ----------------
67*795d594fSAndroid Build Coastguard Worker  *    |              |      In case nterp calls compiled code, we reserve space
68*795d594fSAndroid Build Coastguard Worker  *    |     out      |      for out registers. This space will be used for
69*795d594fSAndroid Build Coastguard Worker  *    |   registers  |      arguments passed on stack.
70*795d594fSAndroid Build Coastguard Worker  *    |              |
71*795d594fSAndroid Build Coastguard Worker  *    ----------------
72*795d594fSAndroid Build Coastguard Worker  *    |  ArtMethod*  |      The method being currently executed.
73*795d594fSAndroid Build Coastguard Worker  *    ----------------
74*795d594fSAndroid Build Coastguard Worker  *
75*795d594fSAndroid Build Coastguard Worker  *    Exception handling:
76*795d594fSAndroid Build Coastguard Worker  *    Nterp follows the same convention than the compiler,
77*795d594fSAndroid Build Coastguard Worker  *    with the addition of:
78*795d594fSAndroid Build Coastguard Worker  *    - All catch handlers have the same landing pad.
79*795d594fSAndroid Build Coastguard Worker  *    - Before doing the longjmp for exception delivery, the register containing the
80*795d594fSAndroid Build Coastguard Worker  *      dex PC pointer must be updated.
81*795d594fSAndroid Build Coastguard Worker  *
82*795d594fSAndroid Build Coastguard Worker  *    Stack walking:
83*795d594fSAndroid Build Coastguard Worker  *    An nterp frame is walked like a compiled code frame. We add an
84*795d594fSAndroid Build Coastguard Worker  *    OatQuickMethodHeader prefix to the nterp entry point, which contains:
85*795d594fSAndroid Build Coastguard Worker  *    - vmap_table_offset=0 (nterp doesn't need one).
86*795d594fSAndroid Build Coastguard Worker  *    - code_size=NterpEnd-NterpStart
87*795d594fSAndroid Build Coastguard Worker  */
88*795d594fSAndroid Build Coastguard Worker 
89*795d594fSAndroid Build Coastguard Worker static constexpr size_t kPointerSize = static_cast<size_t>(kRuntimePointerSize);
90*795d594fSAndroid Build Coastguard Worker 
NterpGetFrameEntrySize(InstructionSet isa)91*795d594fSAndroid Build Coastguard Worker static constexpr size_t NterpGetFrameEntrySize(InstructionSet isa) {
92*795d594fSAndroid Build Coastguard Worker   uint32_t core_spills = 0;
93*795d594fSAndroid Build Coastguard Worker   uint32_t fp_spills = 0;
94*795d594fSAndroid Build Coastguard Worker   // Note: the return address is considered part of the callee saves.
95*795d594fSAndroid Build Coastguard Worker   switch (isa) {
96*795d594fSAndroid Build Coastguard Worker     case InstructionSet::kX86:
97*795d594fSAndroid Build Coastguard Worker       core_spills = x86::X86CalleeSaveFrame::GetCoreSpills(CalleeSaveType::kSaveAllCalleeSaves);
98*795d594fSAndroid Build Coastguard Worker       fp_spills = x86::X86CalleeSaveFrame::GetFpSpills(CalleeSaveType::kSaveAllCalleeSaves);
99*795d594fSAndroid Build Coastguard Worker       // x86 also saves registers used for argument passing.
100*795d594fSAndroid Build Coastguard Worker       core_spills |= x86::kX86CalleeSaveEverythingSpills;
101*795d594fSAndroid Build Coastguard Worker       break;
102*795d594fSAndroid Build Coastguard Worker     case InstructionSet::kX86_64:
103*795d594fSAndroid Build Coastguard Worker       core_spills =
104*795d594fSAndroid Build Coastguard Worker           x86_64::X86_64CalleeSaveFrame::GetCoreSpills(CalleeSaveType::kSaveAllCalleeSaves);
105*795d594fSAndroid Build Coastguard Worker       fp_spills = x86_64::X86_64CalleeSaveFrame::GetFpSpills(CalleeSaveType::kSaveAllCalleeSaves);
106*795d594fSAndroid Build Coastguard Worker       break;
107*795d594fSAndroid Build Coastguard Worker     case InstructionSet::kArm:
108*795d594fSAndroid Build Coastguard Worker     case InstructionSet::kThumb2:
109*795d594fSAndroid Build Coastguard Worker       core_spills = arm::ArmCalleeSaveFrame::GetCoreSpills(CalleeSaveType::kSaveAllCalleeSaves);
110*795d594fSAndroid Build Coastguard Worker       fp_spills = arm::ArmCalleeSaveFrame::GetFpSpills(CalleeSaveType::kSaveAllCalleeSaves);
111*795d594fSAndroid Build Coastguard Worker       break;
112*795d594fSAndroid Build Coastguard Worker     case InstructionSet::kArm64:
113*795d594fSAndroid Build Coastguard Worker       core_spills = arm64::Arm64CalleeSaveFrame::GetCoreSpills(CalleeSaveType::kSaveAllCalleeSaves);
114*795d594fSAndroid Build Coastguard Worker       fp_spills = arm64::Arm64CalleeSaveFrame::GetFpSpills(CalleeSaveType::kSaveAllCalleeSaves);
115*795d594fSAndroid Build Coastguard Worker       break;
116*795d594fSAndroid Build Coastguard Worker     case InstructionSet::kRiscv64:
117*795d594fSAndroid Build Coastguard Worker       core_spills =
118*795d594fSAndroid Build Coastguard Worker           riscv64::Riscv64CalleeSaveFrame::GetCoreSpills(CalleeSaveType::kSaveAllCalleeSaves);
119*795d594fSAndroid Build Coastguard Worker       fp_spills = riscv64::Riscv64CalleeSaveFrame::GetFpSpills(CalleeSaveType::kSaveAllCalleeSaves);
120*795d594fSAndroid Build Coastguard Worker       break;
121*795d594fSAndroid Build Coastguard Worker     default:
122*795d594fSAndroid Build Coastguard Worker       InstructionSetAbort(isa);
123*795d594fSAndroid Build Coastguard Worker   }
124*795d594fSAndroid Build Coastguard Worker   // Note: the return address is considered part of the callee saves.
125*795d594fSAndroid Build Coastguard Worker   return (POPCOUNT(core_spills) + POPCOUNT(fp_spills)) *
126*795d594fSAndroid Build Coastguard Worker       static_cast<size_t>(InstructionSetPointerSize(isa));
127*795d594fSAndroid Build Coastguard Worker }
128*795d594fSAndroid Build Coastguard Worker 
GetNumberOfOutRegs(const CodeItemDataAccessor & accessor,InstructionSet isa)129*795d594fSAndroid Build Coastguard Worker static uint16_t GetNumberOfOutRegs(const CodeItemDataAccessor& accessor, InstructionSet isa) {
130*795d594fSAndroid Build Coastguard Worker   uint16_t out_regs = accessor.OutsSize();
131*795d594fSAndroid Build Coastguard Worker   switch (isa) {
132*795d594fSAndroid Build Coastguard Worker     case InstructionSet::kX86: {
133*795d594fSAndroid Build Coastguard Worker       // On x86, we use three slots for temporaries.
134*795d594fSAndroid Build Coastguard Worker       out_regs = std::max(out_regs, static_cast<uint16_t>(3u));
135*795d594fSAndroid Build Coastguard Worker       break;
136*795d594fSAndroid Build Coastguard Worker     }
137*795d594fSAndroid Build Coastguard Worker     default:
138*795d594fSAndroid Build Coastguard Worker       break;
139*795d594fSAndroid Build Coastguard Worker   }
140*795d594fSAndroid Build Coastguard Worker   return out_regs;
141*795d594fSAndroid Build Coastguard Worker }
142*795d594fSAndroid Build Coastguard Worker 
GetNumberOfOutRegs(ArtMethod * method,InstructionSet isa)143*795d594fSAndroid Build Coastguard Worker static uint16_t GetNumberOfOutRegs(ArtMethod* method, InstructionSet isa)
144*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_) {
145*795d594fSAndroid Build Coastguard Worker   CodeItemDataAccessor accessor(method->DexInstructionData());
146*795d594fSAndroid Build Coastguard Worker   return GetNumberOfOutRegs(accessor, isa);
147*795d594fSAndroid Build Coastguard Worker }
148*795d594fSAndroid Build Coastguard Worker 
149*795d594fSAndroid Build Coastguard Worker // Note: There may be two pieces of alignment but there is no need to align
150*795d594fSAndroid Build Coastguard Worker // out args to `kPointerSize` separately before aligning to kStackAlignment.
151*795d594fSAndroid Build Coastguard Worker // This allows using the size without padding for the maximum frame size check
152*795d594fSAndroid Build Coastguard Worker // in `CanMethodUseNterp()`.
NterpGetFrameSizeWithoutPadding(ArtMethod * method,InstructionSet isa)153*795d594fSAndroid Build Coastguard Worker static size_t NterpGetFrameSizeWithoutPadding(ArtMethod* method, InstructionSet isa)
154*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_) {
155*795d594fSAndroid Build Coastguard Worker   CodeItemDataAccessor accessor(method->DexInstructionData());
156*795d594fSAndroid Build Coastguard Worker   const uint16_t num_regs = accessor.RegistersSize();
157*795d594fSAndroid Build Coastguard Worker   const uint16_t out_regs = GetNumberOfOutRegs(accessor, isa);
158*795d594fSAndroid Build Coastguard Worker   size_t pointer_size = static_cast<size_t>(InstructionSetPointerSize(isa));
159*795d594fSAndroid Build Coastguard Worker 
160*795d594fSAndroid Build Coastguard Worker   DCHECK(IsAlignedParam(kStackAlignment, pointer_size));
161*795d594fSAndroid Build Coastguard Worker   DCHECK(IsAlignedParam(NterpGetFrameEntrySize(isa), pointer_size));
162*795d594fSAndroid Build Coastguard Worker   DCHECK(IsAlignedParam(kVRegSize * 2, pointer_size));
163*795d594fSAndroid Build Coastguard Worker   size_t frame_size =
164*795d594fSAndroid Build Coastguard Worker       NterpGetFrameEntrySize(isa) +
165*795d594fSAndroid Build Coastguard Worker       (num_regs * kVRegSize) * 2 +  // dex registers and reference registers
166*795d594fSAndroid Build Coastguard Worker       pointer_size +  // previous frame
167*795d594fSAndroid Build Coastguard Worker       pointer_size +  // saved dex pc
168*795d594fSAndroid Build Coastguard Worker       (out_regs * kVRegSize) +  // out arguments
169*795d594fSAndroid Build Coastguard Worker       pointer_size;  // method
170*795d594fSAndroid Build Coastguard Worker   return frame_size;
171*795d594fSAndroid Build Coastguard Worker }
172*795d594fSAndroid Build Coastguard Worker 
173*795d594fSAndroid Build Coastguard Worker // The frame size nterp will use for the given method.
NterpGetFrameSize(ArtMethod * method,InstructionSet isa)174*795d594fSAndroid Build Coastguard Worker static inline size_t NterpGetFrameSize(ArtMethod* method, InstructionSet isa)
175*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_) {
176*795d594fSAndroid Build Coastguard Worker   return RoundUp(NterpGetFrameSizeWithoutPadding(method, isa), kStackAlignment);
177*795d594fSAndroid Build Coastguard Worker }
178*795d594fSAndroid Build Coastguard Worker 
NterpFrameInfo(ArtMethod ** frame)179*795d594fSAndroid Build Coastguard Worker QuickMethodFrameInfo NterpFrameInfo(ArtMethod** frame) {
180*795d594fSAndroid Build Coastguard Worker   uint32_t core_spills =
181*795d594fSAndroid Build Coastguard Worker       RuntimeCalleeSaveFrame::GetCoreSpills(CalleeSaveType::kSaveAllCalleeSaves);
182*795d594fSAndroid Build Coastguard Worker   uint32_t fp_spills =
183*795d594fSAndroid Build Coastguard Worker       RuntimeCalleeSaveFrame::GetFpSpills(CalleeSaveType::kSaveAllCalleeSaves);
184*795d594fSAndroid Build Coastguard Worker   return QuickMethodFrameInfo(NterpGetFrameSize(*frame, kRuntimeQuickCodeISA),
185*795d594fSAndroid Build Coastguard Worker                               core_spills,
186*795d594fSAndroid Build Coastguard Worker                               fp_spills);
187*795d594fSAndroid Build Coastguard Worker }
188*795d594fSAndroid Build Coastguard Worker 
NterpGetRegistersArray(ArtMethod ** frame)189*795d594fSAndroid Build Coastguard Worker uintptr_t NterpGetRegistersArray(ArtMethod** frame) {
190*795d594fSAndroid Build Coastguard Worker   CodeItemDataAccessor accessor((*frame)->DexInstructionData());
191*795d594fSAndroid Build Coastguard Worker   const uint16_t num_regs = accessor.RegistersSize();
192*795d594fSAndroid Build Coastguard Worker   // The registers array is just above the reference array.
193*795d594fSAndroid Build Coastguard Worker   return NterpGetReferenceArray(frame) + (num_regs * kVRegSize);
194*795d594fSAndroid Build Coastguard Worker }
195*795d594fSAndroid Build Coastguard Worker 
NterpGetReferenceArray(ArtMethod ** frame)196*795d594fSAndroid Build Coastguard Worker uintptr_t NterpGetReferenceArray(ArtMethod** frame) {
197*795d594fSAndroid Build Coastguard Worker   const uint16_t out_regs = GetNumberOfOutRegs(*frame, kRuntimeQuickCodeISA);
198*795d594fSAndroid Build Coastguard Worker   // The references array is just above the saved frame pointer.
199*795d594fSAndroid Build Coastguard Worker   return reinterpret_cast<uintptr_t>(frame) +
200*795d594fSAndroid Build Coastguard Worker       kPointerSize +  // method
201*795d594fSAndroid Build Coastguard Worker       RoundUp(out_regs * kVRegSize, kPointerSize) +  // out arguments and pointer alignment
202*795d594fSAndroid Build Coastguard Worker       kPointerSize +  // saved dex pc
203*795d594fSAndroid Build Coastguard Worker       kPointerSize;  // previous frame.
204*795d594fSAndroid Build Coastguard Worker }
205*795d594fSAndroid Build Coastguard Worker 
NterpGetDexPC(ArtMethod ** frame)206*795d594fSAndroid Build Coastguard Worker uint32_t NterpGetDexPC(ArtMethod** frame) {
207*795d594fSAndroid Build Coastguard Worker   const uint16_t out_regs = GetNumberOfOutRegs(*frame, kRuntimeQuickCodeISA);
208*795d594fSAndroid Build Coastguard Worker   uintptr_t dex_pc_ptr = reinterpret_cast<uintptr_t>(frame) +
209*795d594fSAndroid Build Coastguard Worker       kPointerSize +  // method
210*795d594fSAndroid Build Coastguard Worker       RoundUp(out_regs * kVRegSize, kPointerSize);  // out arguments and pointer alignment
211*795d594fSAndroid Build Coastguard Worker   CodeItemInstructionAccessor instructions((*frame)->DexInstructions());
212*795d594fSAndroid Build Coastguard Worker   return *reinterpret_cast<const uint16_t**>(dex_pc_ptr) - instructions.Insns();
213*795d594fSAndroid Build Coastguard Worker }
214*795d594fSAndroid Build Coastguard Worker 
NterpGetVReg(ArtMethod ** frame,uint16_t vreg)215*795d594fSAndroid Build Coastguard Worker uint32_t NterpGetVReg(ArtMethod** frame, uint16_t vreg) {
216*795d594fSAndroid Build Coastguard Worker   return reinterpret_cast<uint32_t*>(NterpGetRegistersArray(frame))[vreg];
217*795d594fSAndroid Build Coastguard Worker }
218*795d594fSAndroid Build Coastguard Worker 
NterpGetVRegReference(ArtMethod ** frame,uint16_t vreg)219*795d594fSAndroid Build Coastguard Worker uint32_t NterpGetVRegReference(ArtMethod** frame, uint16_t vreg) {
220*795d594fSAndroid Build Coastguard Worker   return reinterpret_cast<uint32_t*>(NterpGetReferenceArray(frame))[vreg];
221*795d594fSAndroid Build Coastguard Worker }
222*795d594fSAndroid Build Coastguard Worker 
NterpGetCatchHandler()223*795d594fSAndroid Build Coastguard Worker uintptr_t NterpGetCatchHandler() {
224*795d594fSAndroid Build Coastguard Worker   // Nterp uses the same landing pad for all exceptions. The dex_pc_ptr set before
225*795d594fSAndroid Build Coastguard Worker   // longjmp will actually be used to jmp to the catch handler.
226*795d594fSAndroid Build Coastguard Worker   return reinterpret_cast<uintptr_t>(artNterpAsmInstructionEnd);
227*795d594fSAndroid Build Coastguard Worker }
228*795d594fSAndroid Build Coastguard Worker 
CanMethodUseNterp(ArtMethod * method,InstructionSet isa)229*795d594fSAndroid Build Coastguard Worker bool CanMethodUseNterp(ArtMethod* method, InstructionSet isa) {
230*795d594fSAndroid Build Coastguard Worker   uint32_t access_flags = method->GetAccessFlags();
231*795d594fSAndroid Build Coastguard Worker   if (ArtMethod::IsNative(access_flags) ||
232*795d594fSAndroid Build Coastguard Worker       !ArtMethod::IsInvokable(access_flags) ||
233*795d594fSAndroid Build Coastguard Worker       ArtMethod::MustCountLocks(access_flags) ||
234*795d594fSAndroid Build Coastguard Worker       // Proxy methods do not go through the JIT like other methods, so we don't
235*795d594fSAndroid Build Coastguard Worker       // run them with nterp.
236*795d594fSAndroid Build Coastguard Worker       method->IsProxyMethod()) {
237*795d594fSAndroid Build Coastguard Worker     return false;
238*795d594fSAndroid Build Coastguard Worker   }
239*795d594fSAndroid Build Coastguard Worker   if (isa == InstructionSet::kRiscv64 && method->GetDexFile()->IsCompactDexFile()) {
240*795d594fSAndroid Build Coastguard Worker     return false;  // Riscv64 nterp does not support compact dex yet.
241*795d594fSAndroid Build Coastguard Worker   }
242*795d594fSAndroid Build Coastguard Worker   // There is no need to add the alignment padding size for comparison with aligned limit.
243*795d594fSAndroid Build Coastguard Worker   size_t frame_size_without_padding = NterpGetFrameSizeWithoutPadding(method, isa);
244*795d594fSAndroid Build Coastguard Worker   DCHECK_EQ(NterpGetFrameSize(method, isa), RoundUp(frame_size_without_padding, kStackAlignment));
245*795d594fSAndroid Build Coastguard Worker   static_assert(IsAligned<kStackAlignment>(interpreter::kNterpMaxFrame));
246*795d594fSAndroid Build Coastguard Worker   return frame_size_without_padding <= interpreter::kNterpMaxFrame;
247*795d594fSAndroid Build Coastguard Worker }
248*795d594fSAndroid Build Coastguard Worker 
249*795d594fSAndroid Build Coastguard Worker }  // namespace art
250