Add x86 implementation for nterp.
Bug: 112676029
Test: test.py, run-libcore-tests, run-libjdwp-tests
Change-Id: I06bd2c9dde6834f371f042fadda2ced23e02b7ed
diff --git a/runtime/nterp_helpers.cc b/runtime/nterp_helpers.cc
index 9670e6e..a476412 100644
--- a/runtime/nterp_helpers.cc
+++ b/runtime/nterp_helpers.cc
@@ -43,6 +43,8 @@
* | registers | On x86 and x64 this includes the return address,
* | | already spilled on entry.
* ----------------
+ * | x86 args | x86 only: registers used for argument passing.
+ * ----------------
* | alignment | Stack aligment of kStackAlignment.
* ----------------
* | | Contains `registers_size` entries (of size 4) from
@@ -93,6 +95,8 @@
case InstructionSet::kX86:
core_spills = x86::X86CalleeSaveFrame::GetCoreSpills(CalleeSaveType::kSaveAllCalleeSaves);
fp_spills = x86::X86CalleeSaveFrame::GetFpSpills(CalleeSaveType::kSaveAllCalleeSaves);
+ // x86 also saves registers used for argument passing.
+ core_spills |= x86::kX86CalleeSaveEverythingSpills;
break;
case InstructionSet::kX86_64:
core_spills =
@@ -116,10 +120,26 @@
static_cast<size_t>(InstructionSetPointerSize(isa));
}
+static uint16_t GetNumberOfOutRegs(ArtMethod* method, InstructionSet isa)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
+ CodeItemDataAccessor accessor(method->DexInstructionData());
+ uint16_t out_regs = accessor.OutsSize();
+ switch (isa) {
+ case InstructionSet::kX86: {
+ // On x86, we use three slots for temporaries.
+ out_regs = std::max(out_regs, static_cast<uint16_t>(3u));
+ break;
+ }
+ default:
+ break;
+ }
+ return out_regs;
+}
+
size_t NterpGetFrameSize(ArtMethod* method, InstructionSet isa) {
CodeItemDataAccessor accessor(method->DexInstructionData());
const uint16_t num_regs = accessor.RegistersSize();
- const uint16_t out_regs = accessor.OutsSize();
+ const uint16_t out_regs = GetNumberOfOutRegs(method, 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
@@ -153,8 +173,7 @@
}
uintptr_t NterpGetReferenceArray(ArtMethod** frame) {
- CodeItemDataAccessor accessor((*frame)->DexInstructionData());
- const uint16_t out_regs = accessor.OutsSize();
+ const uint16_t out_regs = GetNumberOfOutRegs(*frame, kRuntimeISA);
// The references array is just above the saved frame pointer.
return reinterpret_cast<uintptr_t>(frame) +
kPointerSize + // method
@@ -164,8 +183,7 @@
}
uint32_t NterpGetDexPC(ArtMethod** frame) {
- CodeItemDataAccessor accessor((*frame)->DexInstructionData());
- const uint16_t out_regs = accessor.OutsSize();
+ const uint16_t out_regs = GetNumberOfOutRegs(*frame, kRuntimeISA);
uintptr_t dex_pc_ptr = reinterpret_cast<uintptr_t>(frame) +
kPointerSize + // method
RoundUp(out_regs * kVRegSize, kPointerSize); // out arguments and pointer alignment