Implement LLVM version of stack walking. Fix Jni_Compiler tests.
Thread.cc has many visitors such as CatchBlockStackVisitor and
ReferenceMapVisitor that assume non-LLVM stack layout. LLVM version's
exception handling and gc have no use of those. Per Ian's suggestion,
this LLVM CL relies on ShadowFrame to implement stack walking. And
we use the same Frame class in LLVM version. Result: The Thread.cc
runtime is common across LLVM and non-LLVM compilers, except for
WalkStack utility in Thread.cc.
Key: LLVM's Frame has its (only) field point to the method* in the
ShadowFrame. With this, we finally pass all the jni_compiler tests.
(cherry picked from commit aa4923361d850f8094a546e84ec18672ebbb19fb)
Conflicts:
src/stack.cc
Change-Id: I77098ee5fa7b16cb7e21c0de667e3d7ca5be256f
diff --git a/src/stack.cc b/src/stack.cc
index bab36c4..5dda584 100644
--- a/src/stack.cc
+++ b/src/stack.cc
@@ -28,6 +28,9 @@
}
void Frame::Next() {
+#if defined(ART_USE_LLVM_COMPILER)
+ LOG(FATAL) << "LLVM compiler don't support this function";
+#else
size_t frame_size = GetMethod()->GetFrameSizeInBytes();
DCHECK_NE(frame_size, 0u);
DCHECK_LT(frame_size, 1024u);
@@ -37,16 +40,26 @@
DCHECK((*sp_)->GetClass() == Method::GetMethodClass() ||
(*sp_)->GetClass() == Method::GetConstructorClass());
}
+#endif
}
uintptr_t Frame::GetReturnPC() const {
+#if defined(ART_USE_LLVM_COMPILER)
+ LOG(FATAL) << "LLVM compiler don't support this function";
+ return 0;
+#else
byte* pc_addr = reinterpret_cast<byte*>(sp_) + GetMethod()->GetReturnPcOffsetInBytes();
return *reinterpret_cast<uintptr_t*>(pc_addr);
+#endif
}
void Frame::SetReturnPC(uintptr_t pc) {
+#if defined(ART_USE_LLVM_COMPILER)
+ LOG(FATAL) << "LLVM compiler don't support this function";
+#else
byte* pc_addr = reinterpret_cast<byte*>(sp_) + GetMethod()->GetReturnPcOffsetInBytes();
*reinterpret_cast<uintptr_t*>(pc_addr) = pc;
+#endif
}
/*
@@ -89,8 +102,13 @@
*/
int Frame::GetVRegOffset(const DexFile::CodeItem* code_item,
uint32_t core_spills, uint32_t fp_spills,
- size_t frame_size, int reg) {
- DCHECK_EQ(frame_size & (kStackAlignment - 1), 0U);
+ size_t frame_size, int reg)
+{
+#if defined(ART_USE_LLVM_COMPILER)
+ LOG(FATAL) << "LLVM compiler don't support this function";
+ return 0;
+#else
+ DCHECK_EQ( frame_size & (kStackAlignment - 1), 0U);
int num_spills = __builtin_popcount(core_spills) + __builtin_popcount(fp_spills) + 1 /* filler */;
int num_ins = code_item->ins_size_;
int num_regs = code_item->registers_size_ - num_ins;
@@ -104,16 +122,26 @@
} else {
return frame_size + ((reg - num_regs) * sizeof(uint32_t)) + sizeof(uint32_t); // Dalvik in
}
+#endif
}
uint32_t Frame::GetVReg(const DexFile::CodeItem* code_item, uint32_t core_spills,
uint32_t fp_spills, size_t frame_size, int vreg) const {
+#if defined(ART_USE_LLVM_COMPILER)
+ LOG(FATAL) << "LLVM compiler don't support this function";
+ return 0;
+#else
int offset = GetVRegOffset(code_item, core_spills, fp_spills, frame_size, vreg);
byte* vreg_addr = reinterpret_cast<byte*>(sp_) + offset;
return *reinterpret_cast<uint32_t*>(vreg_addr);
+#endif
}
uint32_t Frame::GetVReg(Method* m, int vreg) const {
+#if defined(ART_USE_LLVM_COMPILER)
+ LOG(FATAL) << "LLVM compiler don't support this function";
+ return 0;
+#else
DCHECK(m == GetMethod());
const DexFile::CodeItem* code_item = MethodHelper(m).GetCodeItem();
DCHECK(code_item != NULL); // can't be NULL or how would we compile its instructions?
@@ -121,9 +149,13 @@
uint32_t fp_spills = m->GetFpSpillMask();
size_t frame_size = m->GetFrameSizeInBytes();
return GetVReg(code_item, core_spills, fp_spills, frame_size, vreg);
+#endif
}
void Frame::SetVReg(Method* m, int vreg, uint32_t new_value) {
+#if defined(ART_USE_LLVM_COMPILER)
+ LOG(FATAL) << "LLVM compiler don't support this function";
+#else
DCHECK(m == GetMethod());
const DexFile::CodeItem* code_item = MethodHelper(m).GetCodeItem();
DCHECK(code_item != NULL); // can't be NULL or how would we compile its instructions?
@@ -133,9 +165,14 @@
int offset = GetVRegOffset(code_item, core_spills, fp_spills, frame_size, vreg);
byte* vreg_addr = reinterpret_cast<byte*>(sp_) + offset;
*reinterpret_cast<uint32_t*>(vreg_addr) = new_value;
+#endif
}
uintptr_t Frame::LoadCalleeSave(int num) const {
+#if defined(ART_USE_LLVM_COMPILER)
+ LOG(FATAL) << "LLVM compiler don't support this function";
+ return 0;
+#else
// Callee saves are held at the top of the frame
Method* method = GetMethod();
DCHECK(method != NULL);
@@ -145,11 +182,17 @@
save_addr -= kPointerSize; // account for return address
#endif
return *reinterpret_cast<uintptr_t*>(save_addr);
+#endif
}
Method* Frame::NextMethod() const {
+#if defined(ART_USE_LLVM_COMPILER)
+ LOG(FATAL) << "LLVM compiler don't support this function";
+ return NULL;
+#else
byte* next_sp = reinterpret_cast<byte*>(sp_) + GetMethod()->GetFrameSizeInBytes();
return *reinterpret_cast<Method**>(next_sp);
+#endif
}
class StackGetter {