Merge "LLVM doesn't use Frame." into ics-mr1-plus-art
diff --git a/src/compiler_llvm/jni_compiler.cc b/src/compiler_llvm/jni_compiler.cc
index 936fb66..097c4f1 100644
--- a/src/compiler_llvm/jni_compiler.cc
+++ b/src/compiler_llvm/jni_compiler.cc
@@ -133,11 +133,6 @@
   llvm::Value* shadow_frame_upcast = irb_.CreateConstGEP2_32(shadow_frame_, 0, 0);
   irb_.CreateCall(irb_.GetRuntime(runtime_support::PushShadowFrame), shadow_frame_upcast);
 
-  // Set top of managed stack to the method field in the SIRT
-  StoreToObjectOffset(thread_object_addr,
-                      Thread::TopOfManagedStackOffset().Int32Value(),
-                      method_field_addr);
-
   // Get JNIEnv
   llvm::Value* jni_env_object_addr = LoadFromObjectOffset(thread_object_addr,
                                                           Thread::JniEnvOffset().Int32Value(),
diff --git a/src/dalvik_system_VMStack.cc b/src/dalvik_system_VMStack.cc
index 7ba4d14..696d723 100644
--- a/src/dalvik_system_VMStack.cc
+++ b/src/dalvik_system_VMStack.cc
@@ -19,6 +19,7 @@
 #include "object.h"
 #include "scoped_heap_lock.h"
 #include "scoped_thread_list_lock.h"
+#include "shadow_frame.h"
 #include "thread_list.h"
 
 #include "JniConstants.h" // Last to avoid problems with LOG redefinition.
@@ -45,10 +46,17 @@
 static jobject VMStack_getCallingClassLoader(JNIEnv* env, jclass) {
   // Returns the defining class loader of the caller's caller.
   // TODO: need SmartFrame (Thread::WalkStack-like iterator).
+#if !defined(ART_USE_LLVM_COMPILER)
   Frame frame = Thread::Current()->GetTopOfStack();
   frame.Next();
   frame.Next();
   Method* callerCaller = frame.GetMethod();
+#else
+  ShadowFrame* frame = Thread::Current()->GetTopOfShadowFrame();
+  frame = frame->GetLink();
+  frame = frame->GetLink();
+  Method* callerCaller = frame->GetMethod();
+#endif
   DCHECK(callerCaller != NULL);
   const Object* cl = callerCaller->GetDeclaringClass()->GetClassLoader();
   return AddLocalReference<jobject>(env, cl);
diff --git a/src/shadow_frame.h b/src/shadow_frame.h
index 9a02a58..a12abc8 100644
--- a/src/shadow_frame.h
+++ b/src/shadow_frame.h
@@ -56,6 +56,11 @@
     references_[i] = object;
   }
 
+  Method* GetMethod() const {
+    DCHECK_NE(method_, static_cast<void*>(NULL));
+    return method_;
+  }
+
   bool Contains(Object** shadow_frame_entry) const {
     // A ShadowFrame should at least contain a reference. Even if a
     // native method has no argument, we put jobject or jclass as a
@@ -98,7 +103,7 @@
 
   uint32_t number_of_references_;
   ShadowFrame* link_;
-  Object* method_;
+  Method* method_;
   uint32_t line_num_;
   Object* references_[];
 
diff --git a/src/thread.cc b/src/thread.cc
index 5233dd1..d8de7d0 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -433,6 +433,7 @@
      << " HZ=" << sysconf(_SC_CLK_TCK) << "\n";
 }
 
+#if !defined(ART_USE_LLVM_COMPILER)
 void Thread::PushNativeToManagedRecord(NativeToManagedRecord* record) {
   Method **sp = top_of_managed_stack_.GetSP();
 #ifndef NDEBUG
@@ -448,12 +449,23 @@
   native_to_managed_record_ = record;
   top_of_managed_stack_.SetSP(NULL);
 }
+#else
+void Thread::PushNativeToManagedRecord(NativeToManagedRecord*) {
+  LOG(FATAL) << "Called non-LLVM method with LLVM";
+}
+#endif
 
+#if !defined(ART_USE_LLVM_COMPILER)
 void Thread::PopNativeToManagedRecord(const NativeToManagedRecord& record) {
   native_to_managed_record_ = record.link_;
   top_of_managed_stack_.SetSP(reinterpret_cast<Method**>(record.last_top_of_managed_stack_));
   top_of_managed_stack_pc_ = record.last_top_of_managed_stack_pc_;
 }
+#else
+void Thread::PopNativeToManagedRecord(const NativeToManagedRecord&) {
+  LOG(FATAL) << "Called non-LLVM method with LLVM";
+}
+#endif
 
 struct StackDumpVisitor : public Thread::StackVisitor {
   StackDumpVisitor(std::ostream& os, const Thread* thread)
@@ -1556,6 +1568,7 @@
   return result;
 }
 
+#if !defined(ART_USE_LLVM_COMPILER)
 Method* Thread::GetCurrentMethod(uintptr_t* pc, Method*** sp) const {
   Frame f = top_of_managed_stack_;
   Method* m = f.GetMethod();
@@ -1578,6 +1591,15 @@
   }
   return m;
 }
+#else
+Method* Thread::GetCurrentMethod(uintptr_t*, Method***) const {
+  ShadowFrame* frame = top_shadow_frame_;
+  while(frame->GetMethod()->IsNative()) {
+    frame = frame->GetLink();
+  }
+  return frame->GetMethod();
+}
+#endif
 
 bool Thread::HoldsLock(Object* object) {
   if (object == NULL) {
diff --git a/src/thread.h b/src/thread.h
index 40409b6..08187bb 100644
--- a/src/thread.h
+++ b/src/thread.h
@@ -228,6 +228,10 @@
     return top_of_managed_stack_;
   }
 
+  ShadowFrame* GetTopOfShadowFrame() const {
+    return top_shadow_frame_;
+  }
+
   // TODO: this is here for testing, remove when we have exception unit tests
   // that use the real stack
   void SetTopOfStack(void* stack, uintptr_t pc) {