[vmkit-commits] [vmkit] r143479 - in /vmkit/trunk/lib/J3/ClassLib/OpenJDK: ClasspathReflect.cpp ClasspathReflect.h OpenJDK.inc

Will Dietz wdietz2 at illinois.edu
Tue Nov 1 13:06:06 PDT 2011


Author: wdietz2
Date: Tue Nov  1 15:06:06 2011
New Revision: 143479

URL: http://llvm.org/viewvc/llvm-project?rev=143479&view=rev
Log:
Add OpenJDK support for stack traces

Modified:
    vmkit/trunk/lib/J3/ClassLib/OpenJDK/ClasspathReflect.cpp
    vmkit/trunk/lib/J3/ClassLib/OpenJDK/ClasspathReflect.h
    vmkit/trunk/lib/J3/ClassLib/OpenJDK/OpenJDK.inc

Modified: vmkit/trunk/lib/J3/ClassLib/OpenJDK/ClasspathReflect.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/J3/ClassLib/OpenJDK/ClasspathReflect.cpp?rev=143479&r1=143478&r2=143479&view=diff
==============================================================================
--- vmkit/trunk/lib/J3/ClassLib/OpenJDK/ClasspathReflect.cpp (original)
+++ vmkit/trunk/lib/J3/ClassLib/OpenJDK/ClasspathReflect.cpp Tue Nov  1 15:06:06 2011
@@ -11,6 +11,9 @@
 #include "JavaClass.h"
 #include "JavaObject.h"
 #include "JavaThread.h"
+#include "Jnjvm.h"
+#include "JavaUpcalls.h"
+#include "JavaArray.h"
 
 namespace j3 {
 
@@ -20,11 +23,61 @@
   return &(cls->asClass()->virtualMethods[self->slot]);
 }
 
-
 JavaMethod* JavaObjectMethod::getInternalMethod(JavaObjectMethod* self) {
   llvm_gcroot(self, 0);
   UserCommonClass* cls = JavaObjectClass::getClass(self->clazz);
   return &(cls->asClass()->virtualMethods[self->slot]);
 }
 
+
+int JavaObjectThrowable::getStackTraceBase(JavaObjectThrowable * self) {
+  JavaObject * stack = NULL;
+  llvm_gcroot(self, 0);
+  llvm_gcroot(stack, 0);
+
+  if (!self->backtrace) return 0;
+
+  Jnjvm* vm = JavaThread::get()->getJVM();
+
+  stack = self->backtrace;
+  sint32 index = 2;;
+  while (index != JavaArray::getSize(stack)) {
+    mvm::FrameInfo* FI = vm->IPToFrameInfo(ArrayPtr::getElement((ArrayPtr*)stack, index));
+    if (FI->Metadata == NULL) ++index;
+    else {
+      JavaMethod* meth = (JavaMethod*)FI->Metadata;
+      assert(meth && "Wrong stack trace");
+      if (meth->classDef->isAssignableFrom(vm->upcalls->newThrowable)) {
+        ++index;
+      } else return index;
+    }
+  }
+
+  assert(0 && "Invalid stack trace!");
+  return 0;
+}
+
+int JavaObjectThrowable::getStackTraceDepth(JavaObjectThrowable * self) {
+  JavaObject * stack = NULL;
+  llvm_gcroot(self, 0);
+  llvm_gcroot(stack, 0);
+
+  if (!self->backtrace) return 0;
+
+  Jnjvm* vm = JavaThread::get()->getJVM();
+
+  stack = self->backtrace;
+  sint32 index = getStackTraceBase(self);
+
+  sint32 size = 0;
+  sint32 cur = index;
+  while (cur < JavaArray::getSize(stack)) {
+    mvm::FrameInfo* FI = vm->IPToFrameInfo(ArrayPtr::getElement((ArrayPtr*)stack, cur));
+    ++cur;
+    if (FI->Metadata != NULL) ++size;
+  }
+
+  return size;
+}
+
 }

Modified: vmkit/trunk/lib/J3/ClassLib/OpenJDK/ClasspathReflect.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/J3/ClassLib/OpenJDK/ClasspathReflect.h?rev=143479&r1=143478&r2=143479&view=diff
==============================================================================
--- vmkit/trunk/lib/J3/ClassLib/OpenJDK/ClasspathReflect.h (original)
+++ vmkit/trunk/lib/J3/ClassLib/OpenJDK/ClasspathReflect.h Tue Nov  1 15:06:06 2011
@@ -17,6 +17,7 @@
 #include "JavaThread.h"
 #include "JavaString.h"
 
+extern "C" j3::JavaObject* internalFillInStackTrace(j3::JavaObject*);
 namespace j3 {
 
 class JavaObjectClass : public JavaObject {
@@ -262,18 +263,18 @@
     llvm_gcroot(self, 0);
     llvm_gcroot(stackTrace, 0);
 
-    // TODO: Implement this right
-    assert(0 && "fillInStackTrace not implemented yet!");
-
-    // stackTrace = internalFillInStackTrace(self);
-    // mvm::Collector::objectReferenceWriteBarrier(
-    //     (gc*)self, (gc**)&(self->vmState), (gc*)stackTrace);
+    stackTrace = internalFillInStackTrace(self);
+    mvm::Collector::objectReferenceWriteBarrier(
+        (gc*)self, (gc**)&(self->backtrace), (gc*)stackTrace);
 
-    // mvm::Collector::objectReferenceWriteBarrier(
-    //     (gc*)self, (gc**)&(self->cause), (gc*)self);
+    mvm::Collector::objectReferenceWriteBarrier(
+        (gc*)self, (gc**)&(self->cause), (gc*)self);
 
-    // self->stackTrace = NULL;
+    self->stackTrace = NULL;
   }
+
+  static int getStackTraceDepth(JavaObjectThrowable * self);
+  static int getStackTraceBase(JavaObjectThrowable * self);
 };
 
 class JavaObjectReference : public JavaObject {

Modified: vmkit/trunk/lib/J3/ClassLib/OpenJDK/OpenJDK.inc
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/J3/ClassLib/OpenJDK/OpenJDK.inc?rev=143479&r1=143478&r2=143479&view=diff
==============================================================================
--- vmkit/trunk/lib/J3/ClassLib/OpenJDK/OpenJDK.inc (original)
+++ vmkit/trunk/lib/J3/ClassLib/OpenJDK/OpenJDK.inc Tue Nov  1 15:06:06 2011
@@ -22,6 +22,76 @@
 #define NYI() \
   do{ assert(0 && "Not yet implemented!"); abort(); } while(0)
 
+JavaObject* internalFillInStackTrace(JavaObject* throwable) {
+
+  ArrayPtr* result = 0;
+  llvm_gcroot(throwable, 0);
+  llvm_gcroot(result, 0);
+
+  JavaThread* th = JavaThread::get();
+  Jnjvm* vm = th->getJVM();
+  assert(th);
+  assert(vm);
+
+  uint32 length = th->getFrameContextLength();
+
+#ifdef ARCH_64
+    ClassArray* cl = vm->upcalls->ArrayOfInt;
+    result = (ArrayPtr*) cl->doNew(length, vm);
+#else
+    ClassArray* cl = vm->upcalls->ArrayOfLong;
+    result = (ArrayPtr*) cl->doNew(length, vm);
+#endif
+
+  // Don't call th->getFrameContext because it is not GC-safe.
+  mvm::StackWalker Walker(th);
+  uint32_t i = 0;
+
+  while (intptr_t ip = *Walker) {
+    ArrayPtr::setElement(result, ip, i);
+    ++i;
+    ++Walker;
+  }
+
+  return result;
+}
+
+JavaObject* consStackElement(mvm::FrameInfo* FI, intptr_t ip) {
+
+  JavaString* methodName = 0;
+  JavaString* className = 0;
+  JavaString* sourceName = 0;
+  JavaObject* res = 0;
+  llvm_gcroot(methodName, 0);
+  llvm_gcroot(className, 0);
+  llvm_gcroot(sourceName, 0);
+  llvm_gcroot(res, 0);
+
+  Jnjvm* vm = JavaThread::get()->getJVM();
+  JavaMethod* meth = (JavaMethod*)FI->Metadata;
+  methodName = vm->internalUTF8ToStr(meth->name);
+  Class* cl = meth->classDef;
+  className = JavaString::internalToJava(cl->name, vm);
+
+  Attribut* sourceAtt = cl->lookupAttribut(Attribut::sourceFileAttribut);
+
+  if (sourceAtt) {
+    Reader reader(sourceAtt, cl->bytes);
+    uint16 index = reader.readU2();
+    sourceName = vm->internalUTF8ToStr(cl->getConstantPool()->UTF8At(index));
+  }
+
+  uint16 lineNumber = meth->lookupLineNumber(FI);
+
+  UserClass* newS = vm->upcalls->newStackTraceElement;
+  res = newS->doNew(vm);
+  vm->upcalls->initStackTraceElement->invokeIntSpecial(vm, newS, res,
+                                                       &className,
+                                                       &methodName,
+                                                       &sourceName,
+                                                       lineNumber);
+  return res;
+}
 
 JNIEXPORT jint JNICALL
 JVM_GetInterfaceVersion(void) {
@@ -266,7 +336,17 @@
  */
 JNIEXPORT void JNICALL
 JVM_FillInStackTrace(JNIEnv *env, jobject throwable) {
-  NYI();
+  JavaObjectThrowable * T = 0;
+  llvm_gcroot(T, 0);
+
+  BEGIN_JNI_EXCEPTION
+
+  T = *(JavaObjectThrowable**)throwable;
+  JavaObjectThrowable::fillInStackTrace(T);
+
+  RETURN_VOID_FROM_JNI;
+
+  END_JNI_EXCEPTION
 }
 
 JNIEXPORT void JNICALL
@@ -276,12 +356,60 @@
 
 JNIEXPORT jint JNICALL
 JVM_GetStackTraceDepth(JNIEnv *env, jobject throwable) {
-  NYI();
+  JavaObjectThrowable * T = 0;
+  llvm_gcroot(T, 0);
+
+  jint res = -1;
+
+  BEGIN_JNI_EXCEPTION
+
+  T = *(JavaObjectThrowable**)throwable;
+  res = JavaObjectThrowable::getStackTraceDepth(T);
+
+  RETURN_FROM_JNI(res);
+
+  END_JNI_EXCEPTION
+
+  return 0;
 }
 
 JNIEXPORT jobject JNICALL
 JVM_GetStackTraceElement(JNIEnv *env, jobject throwable, jint index) {
-  NYI();
+  JavaObjectThrowable * T = 0;
+  JavaObject * result = 0;
+  JavaObject * stack = 0;
+  llvm_gcroot(T, 0);
+  llvm_gcroot(result, 0);
+  llvm_gcroot(stack, 0);
+
+  BEGIN_JNI_EXCEPTION
+
+  T = *(JavaObjectThrowable**)throwable;
+  Jnjvm* vm = JavaThread::get()->getJVM();
+  stack = vm->upcalls->backtrace->getInstanceObjectField(T);
+  verifyNull(stack);
+
+  sint32 base = JavaObjectThrowable::getStackTraceBase(T);
+
+  sint32 cur = 0;
+  for (sint32 i = base; i < JavaArray::getSize(stack); ++i) {
+    intptr_t ip = ArrayPtr::getElement((ArrayPtr*)stack, i);
+    mvm::FrameInfo* FI = vm->IPToFrameInfo(ip);
+    if (FI->Metadata != NULL) {
+      if (cur == index) {
+        result = consStackElement(FI, ip);
+        break;
+      }
+      cur++;
+    }
+  }
+
+  assert(result && "No stack element found");
+  RETURN_FROM_JNI((jobject)th->pushJNIRef(result));
+
+  END_JNI_EXCEPTION
+
+  return 0;
 }
 
 /*





More information about the vmkit-commits mailing list