summaryrefslogtreecommitdiffstats
path: root/compiler/utils/x86/assembler_x86.cc
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/utils/x86/assembler_x86.cc')
-rw-r--r--compiler/utils/x86/assembler_x86.cc24
1 files changed, 21 insertions, 3 deletions
diff --git a/compiler/utils/x86/assembler_x86.cc b/compiler/utils/x86/assembler_x86.cc
index 4cca529258..51cc7acbd0 100644
--- a/compiler/utils/x86/assembler_x86.cc
+++ b/compiler/utils/x86/assembler_x86.cc
@@ -1639,18 +1639,25 @@ void X86Assembler::EmitGenericShift(int reg_or_opcode,
EmitOperand(reg_or_opcode, Operand(operand));
}
+static dwarf::Reg DWARFReg(Register reg) {
+ return dwarf::Reg::X86Core(static_cast<int>(reg));
+}
+
constexpr size_t kFramePointerSize = 4;
void X86Assembler::BuildFrame(size_t frame_size, ManagedRegister method_reg,
const std::vector<ManagedRegister>& spill_regs,
const ManagedRegisterEntrySpills& entry_spills) {
DCHECK_EQ(buffer_.Size(), 0U); // Nothing emitted yet.
+ cfi_.SetCurrentCFAOffset(4); // Return address on stack.
CHECK_ALIGNED(frame_size, kStackAlignment);
int gpr_count = 0;
for (int i = spill_regs.size() - 1; i >= 0; --i) {
Register spill = spill_regs.at(i).AsX86().AsCpuRegister();
pushl(spill);
gpr_count++;
+ cfi_.AdjustCFAOffset(kFramePointerSize);
+ cfi_.RelOffset(DWARFReg(spill), 0);
}
// return address then method on stack.
@@ -1658,7 +1665,10 @@ void X86Assembler::BuildFrame(size_t frame_size, ManagedRegister method_reg,
sizeof(StackReference<mirror::ArtMethod>) /*method*/ -
kFramePointerSize /*return address*/;
addl(ESP, Immediate(-adjust));
+ cfi_.AdjustCFAOffset(adjust);
pushl(method_reg.AsX86().AsCpuRegister());
+ cfi_.AdjustCFAOffset(kFramePointerSize);
+ DCHECK_EQ(static_cast<size_t>(cfi_.GetCurrentCFAOffset()), frame_size);
for (size_t i = 0; i < entry_spills.size(); ++i) {
ManagedRegisterSpill spill = entry_spills.at(i);
@@ -1680,25 +1690,33 @@ void X86Assembler::BuildFrame(size_t frame_size, ManagedRegister method_reg,
void X86Assembler::RemoveFrame(size_t frame_size,
const std::vector<ManagedRegister>& spill_regs) {
CHECK_ALIGNED(frame_size, kStackAlignment);
+ cfi_.RememberState();
int adjust = frame_size - (spill_regs.size() * kFramePointerSize) -
sizeof(StackReference<mirror::ArtMethod>);
addl(ESP, Immediate(adjust));
+ cfi_.AdjustCFAOffset(-adjust);
for (size_t i = 0; i < spill_regs.size(); ++i) {
- x86::X86ManagedRegister spill = spill_regs.at(i).AsX86();
- DCHECK(spill.IsCpuRegister());
- popl(spill.AsCpuRegister());
+ Register spill = spill_regs.at(i).AsX86().AsCpuRegister();
+ popl(spill);
+ cfi_.AdjustCFAOffset(-static_cast<int>(kFramePointerSize));
+ cfi_.Restore(DWARFReg(spill));
}
ret();
+ // The CFI should be restored for any code that follows the exit block.
+ cfi_.RestoreState();
+ cfi_.DefCFAOffset(frame_size);
}
void X86Assembler::IncreaseFrameSize(size_t adjust) {
CHECK_ALIGNED(adjust, kStackAlignment);
addl(ESP, Immediate(-adjust));
+ cfi_.AdjustCFAOffset(adjust);
}
void X86Assembler::DecreaseFrameSize(size_t adjust) {
CHECK_ALIGNED(adjust, kStackAlignment);
addl(ESP, Immediate(adjust));
+ cfi_.AdjustCFAOffset(-adjust);
}
void X86Assembler::Store(FrameOffset offs, ManagedRegister msrc, size_t size) {