summaryrefslogtreecommitdiffstats
path: root/compiler/optimizing/code_generator_arm.cc
diff options
context:
space:
mode:
authorDavid Srbecky <dsrbecky@google.com>2015-04-07 20:32:43 +0100
committerDavid Srbecky <dsrbecky@google.com>2015-04-09 16:47:50 +0100
commitc6b4dd8980350aaf250f0185f73e9c42ec17cd57 (patch)
treeef8d73e37abc04aecb430072a8bc463c73398fee /compiler/optimizing/code_generator_arm.cc
parentdd97393aca1a3ff2abec4dc4f78d7724300971bc (diff)
downloadart-c6b4dd8980350aaf250f0185f73e9c42ec17cd57.tar.gz
art-c6b4dd8980350aaf250f0185f73e9c42ec17cd57.tar.bz2
art-c6b4dd8980350aaf250f0185f73e9c42ec17cd57.zip
Implement CFI for Optimizing.
CFI is necessary for stack unwinding in gdb, lldb, and libunwind. Change-Id: I1a3480e3a4a99f48bf7e6e63c4e83a80cfee40a2
Diffstat (limited to 'compiler/optimizing/code_generator_arm.cc')
-rw-r--r--compiler/optimizing/code_generator_arm.cc31
1 files changed, 28 insertions, 3 deletions
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc
index cfc798a34e..a799a519c0 100644
--- a/compiler/optimizing/code_generator_arm.cc
+++ b/compiler/optimizing/code_generator_arm.cc
@@ -513,6 +513,14 @@ void CodeGeneratorARM::ComputeSpillMask() {
}
}
+static dwarf::Reg DWARFReg(Register reg) {
+ return dwarf::Reg::ArmCore(static_cast<int>(reg));
+}
+
+static dwarf::Reg DWARFReg(SRegister reg) {
+ return dwarf::Reg::ArmFp(static_cast<int>(reg));
+}
+
void CodeGeneratorARM::GenerateFrameEntry() {
bool skip_overflow_check =
IsLeafMethod() && !FrameNeedsStackCheck(GetFrameSize(), InstructionSet::kArm);
@@ -531,12 +539,19 @@ void CodeGeneratorARM::GenerateFrameEntry() {
// PC is in the list of callee-save to mimic Quick, but we need to push
// LR at entry instead.
- __ PushList((core_spill_mask_ & (~(1 << PC))) | 1 << LR);
+ uint32_t push_mask = (core_spill_mask_ & (~(1 << PC))) | 1 << LR;
+ __ PushList(push_mask);
+ __ cfi().AdjustCFAOffset(kArmWordSize * POPCOUNT(push_mask));
+ __ cfi().RelOffsetForMany(DWARFReg(Register(0)), 0, push_mask, kArmWordSize);
if (fpu_spill_mask_ != 0) {
SRegister start_register = SRegister(LeastSignificantBit(fpu_spill_mask_));
__ vpushs(start_register, POPCOUNT(fpu_spill_mask_));
+ __ cfi().AdjustCFAOffset(kArmWordSize * POPCOUNT(fpu_spill_mask_));
+ __ cfi().RelOffsetForMany(DWARFReg(SRegister(0)), 0, fpu_spill_mask_, kArmWordSize);
}
- __ AddConstant(SP, -(GetFrameSize() - FrameEntrySpillSize()));
+ int adjust = GetFrameSize() - FrameEntrySpillSize();
+ __ AddConstant(SP, -adjust);
+ __ cfi().AdjustCFAOffset(adjust);
__ StoreToOffset(kStoreWord, R0, SP, 0);
}
@@ -545,10 +560,14 @@ void CodeGeneratorARM::GenerateFrameExit() {
__ bx(LR);
return;
}
- __ AddConstant(SP, GetFrameSize() - FrameEntrySpillSize());
+ int adjust = GetFrameSize() - FrameEntrySpillSize();
+ __ AddConstant(SP, adjust);
+ __ cfi().AdjustCFAOffset(-adjust);
if (fpu_spill_mask_ != 0) {
SRegister start_register = SRegister(LeastSignificantBit(fpu_spill_mask_));
__ vpops(start_register, POPCOUNT(fpu_spill_mask_));
+ __ cfi().AdjustCFAOffset(-kArmPointerSize * POPCOUNT(fpu_spill_mask_));
+ __ cfi().RestoreMany(DWARFReg(SRegister(0)), fpu_spill_mask_);
}
__ PopList(core_spill_mask_);
}
@@ -1190,7 +1209,10 @@ void LocationsBuilderARM::VisitReturnVoid(HReturnVoid* ret) {
void InstructionCodeGeneratorARM::VisitReturnVoid(HReturnVoid* ret) {
UNUSED(ret);
+ __ cfi().RememberState();
codegen_->GenerateFrameExit();
+ __ cfi().RestoreState();
+ __ cfi().DefCFAOffset(codegen_->GetFrameSize());
}
void LocationsBuilderARM::VisitReturn(HReturn* ret) {
@@ -1201,7 +1223,10 @@ void LocationsBuilderARM::VisitReturn(HReturn* ret) {
void InstructionCodeGeneratorARM::VisitReturn(HReturn* ret) {
UNUSED(ret);
+ __ cfi().RememberState();
codegen_->GenerateFrameExit();
+ __ cfi().RestoreState();
+ __ cfi().DefCFAOffset(codegen_->GetFrameSize());
}
void LocationsBuilderARM::VisitInvokeStaticOrDirect(HInvokeStaticOrDirect* invoke) {