summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
author TDYa127 <tdy@google.com> 2012-03-19 10:12:32 -0700
committer Shih-wei Liao <sliao@google.com> 2012-03-26 21:07:56 -0700
commit9b2ba2ee9fafe46a08473657a2387fd20ab49a35 (patch)
treefd2fd68fac377d3c342f511f5cc20fdaed94b75c /src
parent31a9933bfe68ef1241c74c6586b3bc259a0244ea (diff)
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
Diffstat (limited to 'src')
-rw-r--r--src/stack.cc47
-rw-r--r--src/thread.cc56
2 files changed, 101 insertions, 2 deletions
diff --git a/src/stack.cc b/src/stack.cc
index bab36c4fd7..5dda584d31 100644
--- a/src/stack.cc
+++ b/src/stack.cc
@@ -28,6 +28,9 @@ bool Frame::HasMethod() const {
}
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 @@ void Frame::Next() {
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 @@ void Frame::SetReturnPC(uintptr_t pc) {
*/
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 @@ int Frame::GetVRegOffset(const DexFile::CodeItem* code_item,
} 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 Frame::GetVReg(Method* m, int vreg) const {
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 @@ void Frame::SetVReg(Method* m, int vreg, uint32_t new_value) {
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 @@ uintptr_t Frame::LoadCalleeSave(int num) const {
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 {
diff --git a/src/thread.cc b/src/thread.cc
index 6b340d2784..ae460e48d9 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -1330,6 +1330,8 @@ StackIndirectReferenceTable* Thread::PopSirt() {
return sirt;
}
+#if !defined(ART_USE_LLVM_COMPILER) // LLVM use ShadowFrame
+
void Thread::WalkStack(StackVisitor* visitor, bool include_upcalls) const {
Frame frame = GetTopOfStack();
uintptr_t pc = ManglePc(top_of_managed_stack_pc_);
@@ -1375,6 +1377,60 @@ void Thread::WalkStack(StackVisitor* visitor, bool include_upcalls) const {
}
}
+#else // defined(ART_USE_LLVM_COMPILER) // LLVM uses ShadowFrame
+
+void Thread::WalkStack(StackVisitor* visitor, bool /*include_upcalls*/) const {
+ for (ShadowFrame* cur = top_shadow_frame_; cur; cur = cur->GetLink()) {
+ Frame frame;
+ frame.SetSP(reinterpret_cast<Method**>(reinterpret_cast<byte*>(cur) +
+ ShadowFrame::MethodOffset()));
+ bool should_continue = visitor->VisitFrame(frame, 0);
+ if (!should_continue) {
+ return;
+ }
+ }
+}
+
+/*
+ * | |
+ * | |
+ * | |
+ * | . |
+ * | . |
+ * | . |
+ * | . |
+ * | Method* |
+ * | . |
+ * | . | <-- top_shadow_frame_ (ShadowFrame*)
+ * / +------------------------+
+ * ->| . |
+ * . | . |
+ * . | . |
+ * /+------------------------+
+ * / | . |
+ * / | . |
+ * --- | | . |
+ * | | | . |
+ * | | Method* | <-- frame.GetSP() (Method**)
+ * ShadowFrame \ | . |
+ * | ->| . | <-- cur (ShadowFrame*)
+ * --- /+------------------------+
+ * / | . |
+ * / | . |
+ * --- | | . |
+ * | cur->GetLink() | | . |
+ * | | Method* |
+ * ShadowFrame \ | . |
+ * | ->| . |
+ * --- +------------------------+
+ * | . |
+ * | . |
+ * | . |
+ * +========================+
+ */
+
+#endif
+
jobject Thread::CreateInternalStackTrace(JNIEnv* env) const {
// Compute depth of stack
CountStackDepthVisitor count_visitor;