[vmkit-commits] [vmkit] r76369 - in /vmkit/trunk: include/jnjvm/ include/mvm/Threads/ lib/JnJVM/Classpath/ lib/JnJVM/Compiler/ lib/JnJVM/LLVMRuntime/ lib/JnJVM/VMCore/ lib/Mvm/CommonThread/

Nicolas Geoffray nicolas.geoffray at lip6.fr
Sun Jul 19 09:38:59 PDT 2009


Author: geoffray
Date: Sun Jul 19 11:38:58 2009
New Revision: 76369

URL: http://llvm.org/viewvc/llvm-project?rev=76369&view=rev
Log:
Handle references on object* in JNI, instead of references on
object. This makes sure that the stack of threads running native
methods can be precisely scanned.


Modified:
    vmkit/trunk/include/jnjvm/JnjvmModule.h
    vmkit/trunk/include/mvm/Threads/Thread.h
    vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMRuntime.inc
    vmkit/trunk/lib/JnJVM/Compiler/JITInfo.cpp
    vmkit/trunk/lib/JnJVM/Compiler/JavaAOTCompiler.cpp
    vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp
    vmkit/trunk/lib/JnJVM/Compiler/JavaJITCompiler.cpp
    vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll
    vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp
    vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h
    vmkit/trunk/lib/JnJVM/VMCore/JavaMetaJIT.cpp
    vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp
    vmkit/trunk/lib/JnJVM/VMCore/JavaThread.cpp
    vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h
    vmkit/trunk/lib/JnJVM/VMCore/Jni.cpp
    vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp
    vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h
    vmkit/trunk/lib/JnJVM/VMCore/VirtualTables.cpp
    vmkit/trunk/lib/Mvm/CommonThread/Sigsegv.cpp

Modified: vmkit/trunk/include/jnjvm/JnjvmModule.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/jnjvm/JnjvmModule.h?rev=76369&r1=76368&r2=76369&view=diff

==============================================================================
--- vmkit/trunk/include/jnjvm/JnjvmModule.h (original)
+++ vmkit/trunk/include/jnjvm/JnjvmModule.h Sun Jul 19 11:38:58 2009
@@ -421,6 +421,7 @@
   virtual JavaObject* getFinalObject(llvm::Value* C) = 0;
   virtual llvm::Constant* getNativeClass(CommonClass* cl) = 0;
   virtual llvm::Constant* getJavaClass(CommonClass* cl) = 0;
+  virtual llvm::Constant* getJavaClassPtr(CommonClass* cl) = 0;
   virtual llvm::Constant* getStaticInstance(Class* cl) = 0;
   virtual llvm::Constant* getVirtualTable(JavaVirtualTable*) = 0;
   virtual llvm::Constant* getMethodInClass(JavaMethod* meth) = 0;
@@ -492,6 +493,7 @@
   virtual JavaObject* getFinalObject(llvm::Value* C);
   virtual llvm::Constant* getNativeClass(CommonClass* cl);
   virtual llvm::Constant* getJavaClass(CommonClass* cl);
+  virtual llvm::Constant* getJavaClassPtr(CommonClass* cl);
   virtual llvm::Constant* getStaticInstance(Class* cl);
   virtual llvm::Constant* getVirtualTable(JavaVirtualTable*);
   virtual llvm::Constant* getMethodInClass(JavaMethod* meth);
@@ -546,6 +548,7 @@
   virtual JavaObject* getFinalObject(llvm::Value* C);
   virtual llvm::Constant* getNativeClass(CommonClass* cl);
   virtual llvm::Constant* getJavaClass(CommonClass* cl);
+  virtual llvm::Constant* getJavaClassPtr(CommonClass* cl);
   virtual llvm::Constant* getStaticInstance(Class* cl);
   virtual llvm::Constant* getVirtualTable(JavaVirtualTable*);
   virtual llvm::Constant* getMethodInClass(JavaMethod* meth);

Modified: vmkit/trunk/include/mvm/Threads/Thread.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/mvm/Threads/Thread.h?rev=76369&r1=76368&r2=76369&view=diff

==============================================================================
--- vmkit/trunk/include/mvm/Threads/Thread.h (original)
+++ vmkit/trunk/include/mvm/Threads/Thread.h Sun Jul 19 11:38:58 2009
@@ -218,6 +218,10 @@
     return cpt;
   }
 
+  /// printBacktraceAfterSignal - Print the backtrace during a signal
+  /// handler.
+  ///
+  virtual void printBacktraceAfterSignal() {}
 };
 
 

Modified: vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMRuntime.inc
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMRuntime.inc?rev=76369&r1=76368&r2=76369&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMRuntime.inc (original)
+++ vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMRuntime.inc Sun Jul 19 11:38:58 2009
@@ -76,7 +76,8 @@
 #endif
 
 typedef int (*onLoad_t)(const void**, void*);
-extern "C" void  jnjvmJNIProceedPendingException();
+extern "C" void  jnjvmJNIProceedPendingException(uint32** old);
+extern "C" void* jnjvmGetSJLJBuffer(uint32* num, uint32** old);
 
 // Calls the JNI_OnLoad function of a dynamic library.
 void callOnLoad(void* res, JnjvmClassLoader* loader, Jnjvm* vm) {
@@ -84,16 +85,15 @@
   onLoad_t onLoad = (onLoad_t)loader->loadInLib("JNI_OnLoad", res);
   
   if (onLoad) {
-    JavaThread* th = JavaThread::get();
-    mvm::Allocator& allocator = th->getJVM()->gcAllocator;
-    void** buf = (void**)allocator.allocateTemporaryMemory(sizeof(jmp_buf));
-    th->sjlj_buffers.push_back((jmp_buf*)buf);
-
-    th->startNative(1);
+    uint32 num = 0;
+    uint32* old = 0;
+    void* buf = jnjvmGetSJLJBuffer(&num, &old);
+    
     if (setjmp((jumpbuf_t)buf) == 0) {
       onLoad(&vm->javavmEnv, res);
     }
-    jnjvmJNIProceedPendingException();
+
+    jnjvmJNIProceedPendingException(&old);
   }
 }
 

Modified: vmkit/trunk/lib/JnJVM/Compiler/JITInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/JITInfo.cpp?rev=76369&r1=76368&r2=76369&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/JITInfo.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/JITInfo.cpp Sun Jul 19 11:38:58 2009
@@ -283,14 +283,21 @@
     std::vector<const llvm::Type*> llvmArgs;
     uint32 size = signature->nbArguments;
     Typedef* const* arguments = signature->getArgumentsType();
-    
+   
+    const llvm::Type* Ty = PointerType::getUnqual(JnjvmModule::JavaObjectType);
+
     llvmArgs.push_back(mvm::MvmModule::ptrType); // JNIEnv
-    llvmArgs.push_back(JnjvmModule::JavaObjectType); // Class
+    llvmArgs.push_back(Ty); // Class
 
     for (uint32 i = 0; i < size; ++i) {
       Typedef* type = arguments[i];
       LLVMAssessorInfo& LAI = JavaLLVMCompiler::getTypedefInfo(type);
-      llvmArgs.push_back(LAI.llvmType);
+      const llvm::Type* Ty = LAI.llvmType;
+      if (Ty == JnjvmModule::JavaObjectType) {
+        llvmArgs.push_back(LAI.llvmTypePtr);
+      } else {
+        llvmArgs.push_back(LAI.llvmType);
+      }
     }
 
 #if defined(ISOLATE_SHARING)
@@ -299,7 +306,9 @@
 
     LLVMAssessorInfo& LAI = 
       JavaLLVMCompiler::getTypedefInfo(signature->getReturnType());
-    nativeType = FunctionType::get(LAI.llvmType, llvmArgs, false);
+    const llvm::Type* RetType = LAI.llvmType == JnjvmModule::JavaObjectType ?
+      LAI.llvmTypePtr : LAI.llvmType;
+    nativeType = FunctionType::get(RetType, llvmArgs, false);
     mvm::MvmModule::unprotectIR();
   }
   return nativeType;

Modified: vmkit/trunk/lib/JnJVM/Compiler/JavaAOTCompiler.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/JavaAOTCompiler.cpp?rev=76369&r1=76368&r2=76369&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/JavaAOTCompiler.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/JavaAOTCompiler.cpp Sun Jul 19 11:38:58 2009
@@ -206,7 +206,28 @@
     return res;
   } else {
     return I->second;
-    }
+  }
+}
+
+Constant* JavaAOTCompiler::getJavaClassPtr(CommonClass* cl) {
+#ifdef ISOLATE
+  abort();
+  return 0;
+#else
+  // Make sure it's emitted.
+  getJavaClass(cl);
+
+  Constant* Cl = getNativeClass(cl);
+
+  Constant* GEP[2] = { JnjvmModule::constantZero, JnjvmModule::constantZero };
+  
+  Constant* TCMArray = ConstantExpr::getGetElementPtr(Cl, GEP, 2);
+    
+  Constant* GEP2[2] = { JnjvmModule::constantZero, JnjvmModule::constantZero };
+
+  Constant* Ptr = ConstantExpr::getGetElementPtr(TCMArray, GEP2, 2);
+  return Ptr;
+#endif
 }
 
 JavaObject* JavaAOTCompiler::getFinalObject(llvm::Value* obj) {

Modified: vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp?rev=76369&r1=76368&r2=76369&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp Sun Jul 19 11:38:58 2009
@@ -278,17 +278,30 @@
   currentBlock = createBasicBlock("start");
   BasicBlock* executeBlock = createBasicBlock("execute");
   endBlock = createBasicBlock("end block");
+      
+  // Allocate currentLocalIndexNumber pointer
+  Value* temp = new AllocaInst(*llvmContext, Type::Int32Ty, "",
+                               currentBlock);
+  new StoreInst(module->constantZero, temp, false, currentBlock);
+  
+  // Allocate oldCurrentLocalIndexNumber pointer
+  Value* oldCLIN = new AllocaInst(*llvmContext, 
+                                  PointerType::getUnqual(Type::Int32Ty), "",
+                                  currentBlock);
+
+  Value* Args2[2] = { temp, oldCLIN };
+
+  Value* buf = CallInst::Create(module->GetSJLJBufferFunction,
+                                Args2, Args2 + 2, "", currentBlock);
+  Value* test = CallInst::Create(module->setjmpLLVM, buf, "",
+                                 currentBlock);
 
-  Value* buf = llvm::CallInst::Create(module->GetSJLJBufferFunction,
-                                      "", currentBlock);
-  Value* test = llvm::CallInst::Create(module->setjmpLLVM, buf, "",
-                                       currentBlock);
   test = new ICmpInst(*currentBlock, ICmpInst::ICMP_EQ, test,
                       module->constantZero, "");
-  llvm::BranchInst::Create(executeBlock, endBlock, test, currentBlock);
+  BranchInst::Create(executeBlock, endBlock, test, currentBlock);
   
   if (returnType != Type::VoidTy) {
-    endNode = llvm::PHINode::Create(returnType, "", endBlock);
+    endNode = PHINode::Create(returnType, "", endBlock);
     endNode->addIncoming(llvmContext->getNullValue(returnType),
                          currentBlock);
   }
@@ -317,21 +330,45 @@
   if (stat) {
 #ifdef ISOLATE_SHARING
     Value* val = getClassCtp();
-    Value* res = CallInst::Create(module->GetClassDelegateeFunction,
-                                  val, "", currentBlock);
-    nativeArgs.push_back(res);
+    Value* cl = CallInst::Create(module->GetClassDelegateePtrFunction,
+                                 val, "", currentBlock);
 #else
-    Value* cl = TheCompiler->getJavaClass(compilingClass);
-    nativeArgs.push_back(cl);
+    Value* cl = TheCompiler->getJavaClassPtr(compilingClass);
 #endif
+    nativeArgs.push_back(cl);
     index = 2;
   } else {
     index = 1;
   }
   for (Function::arg_iterator i = func->arg_begin(); 
        index < nargs; ++i, ++index) {
-     
-    nativeArgs.push_back(i);
+    
+    if (i->getType() == module->JavaObjectType) {
+      BasicBlock* BB = createBasicBlock("");
+      BasicBlock* NotZero = createBasicBlock("");
+      const Type* Ty = PointerType::getUnqual(module->JavaObjectType);
+      PHINode* node = PHINode::Create(Ty, "", BB);
+
+      test = new ICmpInst(*currentBlock, ICmpInst::ICMP_EQ, i,
+                          module->JavaObjectNullConstant, "");
+
+      node->addIncoming(llvmContext->getNullValue(Ty), currentBlock);
+      BranchInst::Create(BB, NotZero, test, currentBlock);
+
+      currentBlock = NotZero;
+
+      Value* temp = new AllocaInst(*llvmContext, module->JavaObjectType, "",
+                                   currentBlock);
+      new StoreInst(i, temp, false, currentBlock);
+      node->addIncoming(temp, currentBlock);
+      BranchInst::Create(BB, currentBlock);
+
+      currentBlock = BB;
+
+      nativeArgs.push_back(node);
+    } else {
+      nativeArgs.push_back(i);
+    }
   }
   
   Value* nativeFunc = TheCompiler->getNativeFunction(compilingMethod,
@@ -376,15 +413,32 @@
   Value* result = llvm::CallInst::Create(nativeFunc, nativeArgs.begin(),
                                          nativeArgs.end(), "", currentBlock);
 
-  if (returnType != Type::VoidTy)
+  if (returnType == module->JavaObjectType) {
+    const Type* Ty = PointerType::getUnqual(module->JavaObjectType);
+    Constant* C = llvmContext->getNullValue(Ty);
+    Value* cmp = new ICmpInst(*currentBlock, ICmpInst::ICMP_EQ, result, C, "");
+    BasicBlock* loadBlock = createBasicBlock("");
+
+    endNode->addIncoming(module->JavaObjectNullConstant, currentBlock);
+    BranchInst::Create(endBlock, loadBlock, cmp, currentBlock);
+
+    currentBlock = loadBlock;
+    result = new LoadInst(result, "", currentBlock);
+    
+    endNode->addIncoming(result, currentBlock);
+
+  } else if (returnType != Type::VoidTy) {
     endNode->addIncoming(result, currentBlock);
+  }
+  
   BranchInst::Create(endBlock, currentBlock);
 
+
   currentBlock = endBlock; 
   if (isSynchro(compilingMethod->access))
     endSynchronize();
   
-  CallInst::Create(module->JniProceedPendingExceptionFunction, "",
+  CallInst::Create(module->JniProceedPendingExceptionFunction, oldCLIN, "",
                    currentBlock);
   
   if (returnType != Type::VoidTy)

Modified: vmkit/trunk/lib/JnJVM/Compiler/JavaJITCompiler.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/JavaJITCompiler.cpp?rev=76369&r1=76368&r2=76369&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/JavaJITCompiler.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/JavaJITCompiler.cpp Sun Jul 19 11:38:58 2009
@@ -73,6 +73,16 @@
   return ConstantExpr::getIntToPtr(CI, JnjvmModule::JavaObjectType);
 }
 
+Constant* JavaJITCompiler::getJavaClassPtr(CommonClass* cl) {
+  Jnjvm* vm = JavaThread::get()->getJVM();
+  JavaObject* const* obj = cl->getClassDelegateePtr(vm);
+  assert(obj && "Delegatee not created");
+  LLVMContext& Context = getLLVMModule()->getContext();
+  Constant* CI = Context.getConstantInt(Type::Int64Ty, uint64(obj));
+  const Type* Ty = PointerType::getUnqual(JnjvmModule::JavaObjectType);
+  return ConstantExpr::getIntToPtr(CI, Ty);
+}
+
 JavaObject* JavaJITCompiler::getFinalObject(llvm::Value* obj) {
   if (ConstantExpr* CE = dyn_cast<ConstantExpr>(obj)) {
     if (ConstantInt* C = dyn_cast<ConstantInt>(CE->getOperand(0))) {

Modified: vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll?rev=76369&r1=76368&r2=76369&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll (original)
+++ vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll Sun Jul 19 11:38:58 2009
@@ -26,7 +26,7 @@
 
 ;;; The Enveloppe type, which contains the first cache and all the info
 ;;; to lookup in the constant pool.
-%Enveloppe = type { %CacheNode*, %UTF8*, %UTF8*, i8, %JavaClass*, %CacheNode }
+%Enveloppe = type { %CacheNode*, %UTF8*, %UTF8*, i32, %JavaClass*, %CacheNode }
 
 ;;; The task class mirror.
 ;;; Field 1: The class state
@@ -221,8 +221,8 @@
 declare void @jnjvmThrowException(%JavaObject*)
 declare void @jnjvmThrowExceptionFromJIT()
 
-declare void @jnjvmJNIProceedPendingException()
-declare i8*  @jnjvmGetSJLJBuffer()
+declare void @jnjvmJNIProceedPendingException(i32**)
+declare i8*  @jnjvmGetSJLJBuffer(i32*, i32**)
 
 declare %JavaObject* @gcmalloc(i32, %VT*)
 

Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp?rev=76369&r1=76368&r2=76369&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp Sun Jul 19 11:38:58 2009
@@ -989,6 +989,10 @@
   return delegatee[JavaThread::get()->getJVM()->IsolateID];
 }
 
+JavaObject** CommonClass::getDelegateePtr() {
+  return &(delegatee[JavaThread::get()->getJVM()->IsolateID]);
+}
+
 JavaObject* CommonClass::setDelegatee(JavaObject* val) {
   JavaObject** obj = &(delegatee[JavaThread::get()->getJVM()->IsolateID]);
 

Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h?rev=76369&r1=76368&r2=76369&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h Sun Jul 19 11:38:58 2009
@@ -289,6 +289,11 @@
   ///
   JavaObject* getClassDelegatee(Jnjvm* vm, JavaObject* pd = 0);
   
+  /// getClassDelegateePtr - Return a pointer on the java/lang/Class
+  /// representation of this class. Used for JNI.
+  ///
+  JavaObject* const* getClassDelegateePtr(Jnjvm* vm, JavaObject* pd = 0);
+  
   /// CommonClass - Create a class with th given name.
   ///
   CommonClass(JnjvmClassLoader* loader, const UTF8* name);
@@ -325,10 +330,18 @@
   JavaObject* getDelegatee() const {
     return delegatee[0];
   }
+  
+  /// getDelegatee - Get a pointer on the java/lang/Class object
+  /// representing this class.
+  ///
+  JavaObject* const* getDelegateePtr() const {
+    return delegatee;
+  }
 
 #else
 #if defined(ISOLATE)
   JavaObject* getDelegatee();
+  JavaObject** getDelegateePtr();
 #endif
 #endif
   
@@ -1060,37 +1073,37 @@
 //===----------------------------------------------------------------------===//
   
   /// This class of methods takes a variable argument list.
-  uint32 invokeIntSpecialAP(Jnjvm* vm, UserClass*, JavaObject* obj, va_list ap)
+  uint32 invokeIntSpecialAP(Jnjvm* vm, UserClass*, JavaObject* obj, va_list ap, bool jni = false)
     __attribute__ ((noinline));
-  float invokeFloatSpecialAP(Jnjvm* vm, UserClass*, JavaObject* obj, va_list ap)
+  float invokeFloatSpecialAP(Jnjvm* vm, UserClass*, JavaObject* obj, va_list ap, bool jni = false)
     __attribute__ ((noinline));
   double invokeDoubleSpecialAP(Jnjvm* vm, UserClass*, JavaObject* obj,
-                               va_list ap) __attribute__ ((noinline));
-  sint64 invokeLongSpecialAP(Jnjvm* vm, UserClass*, JavaObject* obj, va_list ap)
+                               va_list ap, bool jni = false) __attribute__ ((noinline));
+  sint64 invokeLongSpecialAP(Jnjvm* vm, UserClass*, JavaObject* obj, va_list ap, bool jni = false)
     __attribute__ ((noinline));
   JavaObject* invokeJavaObjectSpecialAP(Jnjvm* vm, UserClass*, JavaObject* obj,
-                                        va_list ap) __attribute__ ((noinline));
+                                        va_list ap, bool jni = false) __attribute__ ((noinline));
   
-  uint32 invokeIntVirtualAP(Jnjvm* vm, UserClass*, JavaObject* obj, va_list ap)
+  uint32 invokeIntVirtualAP(Jnjvm* vm, UserClass*, JavaObject* obj, va_list ap, bool jni = false)
     __attribute__ ((noinline));
-  float invokeFloatVirtualAP(Jnjvm* vm, UserClass*, JavaObject* obj, va_list ap)
+  float invokeFloatVirtualAP(Jnjvm* vm, UserClass*, JavaObject* obj, va_list ap, bool jni = false)
     __attribute__ ((noinline));
   double invokeDoubleVirtualAP(Jnjvm* vm, UserClass*, JavaObject* obj,
-                               va_list ap) __attribute__ ((noinline));
-  sint64 invokeLongVirtualAP(Jnjvm* vm, UserClass*, JavaObject* obj, va_list ap)
+                               va_list ap, bool jni = false) __attribute__ ((noinline));
+  sint64 invokeLongVirtualAP(Jnjvm* vm, UserClass*, JavaObject* obj, va_list ap, bool jni = false)
     __attribute__ ((noinline));
   JavaObject* invokeJavaObjectVirtualAP(Jnjvm* vm, UserClass*, JavaObject* obj,
-                                        va_list ap) __attribute__ ((noinline));
+                                        va_list ap, bool jni = false) __attribute__ ((noinline));
   
-  uint32 invokeIntStaticAP(Jnjvm* vm, UserClass*, va_list ap)
+  uint32 invokeIntStaticAP(Jnjvm* vm, UserClass*, va_list ap, bool jni = false)
     __attribute__ ((noinline));
-  float invokeFloatStaticAP(Jnjvm* vm, UserClass*, va_list ap)
+  float invokeFloatStaticAP(Jnjvm* vm, UserClass*, va_list ap, bool jni = false)
     __attribute__ ((noinline));
-  double invokeDoubleStaticAP(Jnjvm* vm, UserClass*, va_list ap)
+  double invokeDoubleStaticAP(Jnjvm* vm, UserClass*, va_list ap, bool jni = false)
     __attribute__ ((noinline));
-  sint64 invokeLongStaticAP(Jnjvm* vm, UserClass*, va_list ap)
+  sint64 invokeLongStaticAP(Jnjvm* vm, UserClass*, va_list ap, bool jni = false)
     __attribute__ ((noinline));
-  JavaObject* invokeJavaObjectStaticAP(Jnjvm* vm, UserClass*, va_list ap)
+  JavaObject* invokeJavaObjectStaticAP(Jnjvm* vm, UserClass*, va_list ap, bool jni = false)
     __attribute__ ((noinline));
 
   /// This class of methods takes a buffer which contain the arguments of the

Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaMetaJIT.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaMetaJIT.cpp?rev=76369&r1=76368&r2=76369&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaMetaJIT.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaMetaJIT.cpp Sun Jul 19 11:38:58 2009
@@ -21,7 +21,7 @@
 
 using namespace jnjvm;
 
-#define readArgs(buf, signature, ap) \
+#define readArgs(buf, signature, ap, jni) \
   Typedef* const* arguments = signature->getArgumentsType(); \
   for (uint32 i = 0; i < signature->nbArguments; ++i) { \
     const Typedef* type = arguments[i];\
@@ -48,7 +48,16 @@
         abort();\
       }\
     } else{\
-      ((JavaObject**)buf)[0] = va_arg(ap, JavaObject*);\
+      if (jni) { \
+        JavaObject** obj = va_arg(ap, JavaObject**);\
+        if (obj) {\
+          ((JavaObject**)buf)[0] = *obj;\
+        } else {\
+          ((JavaObject**)buf)[0] = 0;\
+        }\
+      } else { \
+        ((JavaObject**)buf)[0] = va_arg(ap, JavaObject*);\
+      } \
     }\
     buf += 8; \
   }\
@@ -59,12 +68,12 @@
 #if 1//defined(__PPC__) && !defined(__MACH__)
 #define INVOKE(TYPE, TYPE_NAME, FUNC_TYPE_VIRTUAL_AP, FUNC_TYPE_STATIC_AP, FUNC_TYPE_VIRTUAL_BUF, FUNC_TYPE_STATIC_BUF) \
 \
-TYPE JavaMethod::invoke##TYPE_NAME##VirtualAP(Jnjvm* vm, UserClass* cl, JavaObject* obj, va_list ap) { \
+TYPE JavaMethod::invoke##TYPE_NAME##VirtualAP(Jnjvm* vm, UserClass* cl, JavaObject* obj, va_list ap, bool jni) { \
   verifyNull(obj); \
   Signdef* sign = getSignature(); \
   uintptr_t buf = (uintptr_t)alloca(sign->nbArguments * sizeof(uint64)); \
   void* _buf = (void*)buf; \
-  readArgs(buf, sign, ap); \
+  readArgs(buf, sign, ap, jni); \
   void* func = (((void***)obj)[0])[offset];\
   JavaThread* th = JavaThread::get(); \
   th->startJava(); \
@@ -78,12 +87,12 @@
   return res; \
 }\
 \
-TYPE JavaMethod::invoke##TYPE_NAME##SpecialAP(Jnjvm* vm, UserClass* cl, JavaObject* obj, va_list ap) {\
+TYPE JavaMethod::invoke##TYPE_NAME##SpecialAP(Jnjvm* vm, UserClass* cl, JavaObject* obj, va_list ap, bool jni) {\
   verifyNull(obj);\
   Signdef* sign = getSignature(); \
   uintptr_t buf = (uintptr_t)alloca(sign->nbArguments * sizeof(uint64)); \
   void* _buf = (void*)buf; \
-  readArgs(buf, sign, ap); \
+  readArgs(buf, sign, ap, jni); \
   void* func = this->compiledPtr();\
   JavaThread* th = JavaThread::get(); \
   th->startJava(); \
@@ -97,7 +106,7 @@
   return res; \
 }\
 \
-TYPE JavaMethod::invoke##TYPE_NAME##StaticAP(Jnjvm* vm, UserClass* cl, va_list ap) {\
+TYPE JavaMethod::invoke##TYPE_NAME##StaticAP(Jnjvm* vm, UserClass* cl, va_list ap, bool jni) {\
   if (!cl->isReady()) { \
     cl->resolveClass(); \
     cl->initialiseClass(vm); \
@@ -106,7 +115,7 @@
   Signdef* sign = getSignature(); \
   uintptr_t buf = (uintptr_t)alloca(sign->nbArguments * sizeof(uint64)); \
   void* _buf = (void*)buf; \
-  readArgs(buf, sign, ap); \
+  readArgs(buf, sign, ap, jni); \
   void* func = this->compiledPtr();\
   JavaThread* th = JavaThread::get(); \
   th->startJava(); \
@@ -335,12 +344,12 @@
 #if 1//defined(__PPC__) && !defined(__MACH__)
 #define INVOKE(TYPE, TYPE_NAME, FUNC_TYPE_VIRTUAL_AP, FUNC_TYPE_STATIC_AP, FUNC_TYPE_VIRTUAL_BUF, FUNC_TYPE_STATIC_BUF) \
 \
-TYPE JavaMethod::invoke##TYPE_NAME##VirtualAP(Jnjvm* vm, UserClass* cl, JavaObject* obj, va_list ap) { \
+TYPE JavaMethod::invoke##TYPE_NAME##VirtualAP(Jnjvm* vm, UserClass* cl, JavaObject* obj, va_list ap, bool jni) { \
   verifyNull(obj); \
   Signdef* sign = getSignature(); \
   uintptr_t buf = (uintptr_t)alloca(sign->nbArguments * sizeof(uint64)); \
   void* _buf = (void*)buf; \
-  readArgs(buf, sign, ap); \
+  readArgs(buf, sign, ap, jni); \
   void* func = (((void***)obj)[0])[offset];\
   JavaThread* th = JavaThread::get(); \
   th->startJava(); \
@@ -353,12 +362,12 @@
   return res; \
 }\
 \
-TYPE JavaMethod::invoke##TYPE_NAME##SpecialAP(Jnjvm* vm, UserClass* cl, JavaObject* obj, va_list ap) {\
+TYPE JavaMethod::invoke##TYPE_NAME##SpecialAP(Jnjvm* vm, UserClass* cl, JavaObject* obj, va_list ap, bool jni) {\
   verifyNull(obj);\
   Signdef* sign = getSignature(); \
   uintptr_t buf = (uintptr_t)alloca(sign->nbArguments * sizeof(uint64)); \
   void* _buf = (void*)buf; \
-  readArgs(buf, sign, ap); \
+  readArgs(buf, sign, ap, jni); \
   void* func = this->compiledPtr();\
   JavaThread* th = JavaThread::get(); \
   th->startJava(); \
@@ -371,7 +380,7 @@
   return res; \
 }\
 \
-TYPE JavaMethod::invoke##TYPE_NAME##StaticAP(Jnjvm* vm, UserClass* cl, va_list ap) {\
+TYPE JavaMethod::invoke##TYPE_NAME##StaticAP(Jnjvm* vm, UserClass* cl, va_list ap, bool jni) {\
   if (!cl->isReady()) { \
     cl->resolveClass(); \
     cl->initialiseClass(vm); \
@@ -380,7 +389,7 @@
   Signdef* sign = getSignature(); \
   uintptr_t buf = (uintptr_t)alloca(sign->nbArguments * sizeof(uint64)); \
   void* _buf = (void*)buf; \
-  readArgs(buf, sign, ap); \
+  readArgs(buf, sign, ap, jni); \
   void* func = this->compiledPtr();\
   JavaThread* th = JavaThread::get(); \
   th->startJava(); \

Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp?rev=76369&r1=76368&r2=76369&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp Sun Jul 19 11:38:58 2009
@@ -369,19 +369,20 @@
 }
 
 // Does not call Java code.
-extern "C" void jnjvmJNIProceedPendingException() {
+extern "C" void jnjvmJNIProceedPendingException(uint32** oldLRN) {
   JavaThread* th = JavaThread::get();
   jmp_buf* buf = th->sjlj_buffers.back();
   
   // Remove the buffer.
   th->sjlj_buffers.pop_back();
-
-  // We're going back to Java, remove the native address.
-  th->addresses.pop_back();
-
   mvm::Allocator& allocator = th->getJVM()->gcAllocator;
   allocator.freeTemporaryMemory(buf);
 
+  // We're going back to Java
+  th->endJNI();
+
+  th->currentAddedReferences = *oldLRN;
+
 #ifdef DWARF_EXCEPTIONS
   // If there's an exception, throw it now.
   if (JavaThread::get()->pendingException) {
@@ -391,15 +392,18 @@
 }
 
 // Never throws.
-extern "C" void* jnjvmGetSJLJBuffer() {
+extern "C" void* jnjvmGetSJLJBuffer(uint32* localReferencesNumber,
+                                    uint32** oldLocalReferencesNumber) {
   JavaThread* th = JavaThread::get();
   mvm::Allocator& allocator = th->getJVM()->gcAllocator;
   void** buf = (void**)allocator.allocateTemporaryMemory(sizeof(jmp_buf));
   th->sjlj_buffers.push_back((jmp_buf*)buf);
+  *oldLocalReferencesNumber = th->currentAddedReferences;
+  th->currentAddedReferences = localReferencesNumber;
 
-  // Start native because the next instruction after setjmp is a call to a
-  // native function.
-  th->startNative(2);
+  // Start JNI because the next instruction after setjmp is a call to a
+  // JNI function.
+  th->startJNI(2);
 
   // Finally, return the buffer that the Java code will use to do the setjmp.
   return (void*)buf;

Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaThread.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaThread.cpp?rev=76369&r1=76368&r2=76369&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaThread.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaThread.cpp Sun Jul 19 11:38:58 2009
@@ -31,6 +31,9 @@
   state = StateRunning;
   pendingException = 0;
   jniEnv = isolate->jniEnv;
+  localJNIRefs = new JNILocalReferences();
+  currentAddedReferences = 0;
+
 #ifdef SERVICE
   eipIndex = 0;
   replacedEIPs = new void*[100];
@@ -79,7 +82,19 @@
     cur = (void**)cur[0];
 
   // When entering, the number of addresses should be odd.
-  // Enable this when finalization gets proper support.
+  assert((addresses.size() % 2) && "Wrong stack");
+  
+  addresses.push_back(cur);
+}
+
+void JavaThread::startJNI(int level) {
+  // Caller of this function.
+  void** cur = (void**)FRAME_PTR();
+  
+  while (level--)
+    cur = (void**)cur[0];
+
+  // When entering, the number of addresses should be odd.
   assert((addresses.size() % 2) && "Wrong stack");
   
   addresses.push_back(cur);
@@ -275,3 +290,39 @@
   }
 
 }
+
+void JavaThread::printBacktraceAfterSignal() {
+  printBacktrace();
+}
+
+JavaObject** JNILocalReferences::addJNIReference(JavaThread* th,
+                                                 JavaObject* obj) {
+  if (length == MAXIMUM_REFERENCES) {
+    JNILocalReferences* next = new JNILocalReferences();
+    th->localJNIRefs = next;
+    next->prev = this;
+    return next->addJNIReference(th, obj);
+  } else {
+    localReferences[length] = obj;
+    return &localReferences[length++];
+  }
+}
+
+void JNILocalReferences::removeJNIReferences(JavaThread* th, uint32_t num) {
+    
+  if (th->localJNIRefs != this) {
+    delete th->localJNIRefs;
+    th->localJNIRefs = this;
+  }
+
+  if (num > length) {
+    fprintf(stderr, "num = %d et length = %d\n", num, length);
+    if (!prev) {
+      JavaThread::get()->printBacktrace();
+    }
+    assert(prev && "No prev and deleting too much local references");
+    prev->removeJNIReferences(th, num - length);
+  } else {
+    length -= num;
+  }
+}

Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h?rev=76369&r1=76368&r2=76369&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h Sun Jul 19 11:38:58 2009
@@ -19,6 +19,7 @@
 #include "mvm/Threads/Thread.h"
 
 #include "JavaObject.h"
+#include "JNIReferences.h"
 
 namespace jnjvm {
 
@@ -118,6 +119,23 @@
   ///
   std::vector<void*> addresses;
 
+  /// currentAddedReferences - Current number of added local references.
+  ///
+  uint32_t* currentAddedReferences;
+
+  /// localJNIRefs - List of local JNI references.
+  ///
+  JNILocalReferences* localJNIRefs;
+
+
+  JavaObject** pushJNIRef(JavaObject* obj) {
+    if (!obj) return 0;
+    
+    ++(*currentAddedReferences);
+    return localJNIRefs->addJNIReference(this, obj);
+
+  }
+
   /// tracer - Traces GC-objects pointed by this thread object.
   ///
   virtual void tracer();
@@ -201,6 +219,10 @@
   /// startNative - Record that we are entering native code.
   ///
   void startNative(int level) __attribute__ ((noinline));
+  
+  /// startNative - Record that we are entering native code.
+  ///
+  void startJNI(int level) __attribute__ ((noinline));
 
   /// startJava - Record that we are entering Java code.
   ///
@@ -213,6 +235,13 @@
     addresses.pop_back();
   }
 
+  void endJNI() {
+    assert(!(addresses.size() % 2) && "Wrong stack");    
+  
+    localJNIRefs->removeJNIReferences(this, *currentAddedReferences);
+    addresses.pop_back();
+  }
+
   /// endJava - Record that we are leaving Java code.
   ///
   void endJava() {
@@ -244,6 +273,12 @@
   ///
   void printBacktrace() __attribute__ ((noinline));
   
+  /// printBacktraceAfterSignal - Prints the backtrace of this thread while
+  /// in a signal handler.
+  ///
+  virtual void printBacktraceAfterSignal() __attribute__ ((noinline));
+  
+  
   /// printJavaBacktrace - Prints the backtrace of this thread. Only prints
   /// the Java methods on the stack.
   ///

Modified: vmkit/trunk/lib/JnJVM/VMCore/Jni.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/Jni.cpp?rev=76369&r1=76368&r2=76369&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/Jni.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/Jni.cpp Sun Jul 19 11:38:58 2009
@@ -27,9 +27,9 @@
 }
 
 static UserClass* getClassFromStaticMethod(Jnjvm* vm, JavaMethod* meth,
-                                           jclass clazz) {
+                                           JavaObject* clazz) {
 #ifdef ISOLATE_SHARING
-  return (UserClass*)NativeUtil::resolvedImplClass(vm, vm, clazz, true);
+  return (UserClass*)UserCommonClass::resolvedImplClass(vm, clazz, false);
 #else
   return meth->classDef;
 #endif
@@ -73,8 +73,9 @@
 
   UserCommonClass* cl = loader->loadClassFromAsciiz(asciiz, true, true);
   if (cl && cl->asClass()) cl->asClass()->initialiseClass(vm);
-  return (jclass)(cl->getClassDelegatee(vm));
-  
+  jclass res = (jclass)cl->getClassDelegateePtr(vm);
+  return res;
+
   END_JNI_EXCEPTION
   return 0;
 }
@@ -83,10 +84,12 @@
 jmethodID FromReflectedMethod(JNIEnv *env, jobject method) {
   
   BEGIN_JNI_EXCEPTION
-  
+ 
+  // Local object references. 
+  JavaObject* meth = *(JavaObject**)method;
+
   Jnjvm* vm = myVM(env);
   Classpath* upcalls = vm->upcalls;
-  JavaObject* meth = (JavaObject*)method;
   UserCommonClass* cl = meth->getClass();
   if (cl == upcalls->newConstructor)  {
     return (jmethodID)((JavaObjectMethod*)meth)->getInternalMethod();
@@ -106,15 +109,19 @@
 }
   
  
-jboolean IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup) {
+jboolean IsAssignableFrom(JNIEnv *env, jclass _sub, jclass _sup) {
   
   BEGIN_JNI_EXCEPTION
+ 
+  // Local object references.
+  JavaObject* sub = *(JavaObject**)_sub;
+  JavaObject* sup = *(JavaObject**)_sup;
   
   Jnjvm* vm = JavaThread::get()->getJVM();
   UserCommonClass* cl2 = 
-    UserCommonClass::resolvedImplClass(vm, (JavaObject*)sup, false);
+    UserCommonClass::resolvedImplClass(vm, sup, false);
   UserCommonClass* cl1 = 
-    UserCommonClass::resolvedImplClass(vm, (JavaObject*)sub, false);
+    UserCommonClass::resolvedImplClass(vm, sub, false);
 
   return cl1->isAssignableFrom(cl2);
   
@@ -131,15 +138,19 @@
 }
 
 
-jint ThrowNew(JNIEnv* env, jclass Cl, const char *msg) {
+jint ThrowNew(JNIEnv* env, jclass _Cl, const char *msg) {
   
   BEGIN_JNI_EXCEPTION
+ 
+  // Local object references.
+  JavaObject* Cl = *(JavaObject**)_Cl;
+  
+  Jnjvm* vm = JavaThread::get()->getJVM();
   
-  Jnjvm* vm = myVM(env);
   verifyNull(Cl);
-  UserCommonClass* cl = 
-    UserCommonClass::resolvedImplClass(vm, (JavaObject*)Cl, true);
-  if (!cl->asClass()) return 0;
+  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, Cl, true);
+  if (!cl->isClass()) return 0;
+
   UserClass* realCl = cl->asClass();
   JavaObject* res = realCl->doNew(vm);
   JavaMethod* init = realCl->lookupMethod(vm->bootstrapLoader->initName,
@@ -197,7 +208,11 @@
 
 
 jboolean IsSameObject(JNIEnv *env, jobject ref1, jobject ref2) {
-  return ref1 == ref2;
+
+  JavaObject* Ref1 = *(JavaObject**)ref1;
+  JavaObject* Ref2 = *(JavaObject**)ref2;
+
+  return Ref1 == Ref2;
 }
 
 
@@ -215,35 +230,53 @@
 }
 
 
-jobject AllocObject(JNIEnv *env, jclass clazz) {
+jobject AllocObject(JNIEnv *env, jclass _clazz) {
   
   BEGIN_JNI_EXCEPTION
-  
-  Jnjvm* vm = JavaThread::get()->getJVM();
-  UserCommonClass* cl = 
-    UserCommonClass::resolvedImplClass(vm, (JavaObject*)clazz, true);
-  if (cl->isArray()) return 0;
+ 
+  // Local object references.  
+  JavaObject* clazz = *(JavaObject**)_clazz;
+  JavaObject* res = 0;
 
-  return (jobject)((UserClass*)cl)->doNew(JavaThread::get()->getJVM());
+  JavaThread* th = JavaThread::get();
+  Jnjvm* vm = th->getJVM();
+
+  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, clazz, true);
+  if (!cl->isClass()) return 0;
+
+  // Store local reference
+  res = cl->asClass()->doNew(vm);
+  
+  return (jobject)th->pushJNIRef(res);
 
   END_JNI_EXCEPTION
   return 0;
 }
 
 
-jobject NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...) {
+jobject NewObject(JNIEnv *env, jclass _clazz, jmethodID methodID, ...) {
   BEGIN_JNI_EXCEPTION
-    
+  
+ 
+  // Local object references
+  JavaObject* clazz = *(JavaObject**)_clazz;
+  JavaObject* res = 0;
+  
+  JavaMethod* meth = (JavaMethod*)methodID;
+  JavaThread* th = JavaThread::get();
+  Jnjvm* vm = th->getJVM();
+  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, clazz, true);
+  if (!cl->isClass()) return 0;
+  
+  // Store local reference
+  res = cl->asClass()->doNew(vm);
+
   va_list ap;
   va_start(ap, methodID);
-  JavaMethod* meth = (JavaMethod*)methodID;
-  Jnjvm* vm = JavaThread::get()->getJVM();
-  UserClass* cl = (UserClass*)
-    UserCommonClass::resolvedImplClass(vm, (JavaObject*)clazz, true);
-  JavaObject* res = cl->doNew(vm);
-  meth->invokeIntSpecialAP(vm, cl, res, ap);
+  meth->invokeIntSpecialAP(vm, cl->asClass(), res, ap, true);
   va_end(ap);
-  return (jobject)res;
+  
+  return (jobject)th->pushJNIRef(res);
   
   END_JNI_EXCEPTION
   return 0;
@@ -257,32 +290,91 @@
   return 0;
 }
 
+#define BufToBuf(_args, _buf, signature) \
+  Typedef* const* arguments = signature->getArgumentsType(); \
+  uintptr_t __buf = (uintptr_t)_buf; \
+  uintptr_t __args = (uintptr_t)_args;\
+  for (uint32 i = 0; i < signature->nbArguments; ++i) { \
+    const Typedef* type = arguments[i];\
+    if (type->isPrimitive()) {\
+      const PrimitiveTypedef* prim = (PrimitiveTypedef*)type;\
+      if (prim->isLong()) {\
+        ((sint64*)__buf)[0] = ((sint64*)__args)[0];\
+      } else if (prim->isInt()){ \
+        ((sint32*)__buf)[0] = ((sint32*)__args)[0];\
+      } else if (prim->isChar()) { \
+        ((uint32*)__buf)[0] = ((uint32*)__args)[0];\
+      } else if (prim->isShort()) { \
+        ((uint32*)__buf)[0] = ((uint32*)__args)[0];\
+      } else if (prim->isByte()) { \
+        ((uint32*)__buf)[0] = ((uint32*)__args)[0];\
+      } else if (prim->isBool()) { \
+        ((uint32*)__buf)[0] = ((uint32*)__args)[0];\
+      } else if (prim->isFloat()) {\
+        ((float*)__buf)[0] = ((float*)__args)[0];\
+      } else if (prim->isDouble()) {\
+        ((double*)__buf)[0] = ((double*)__args)[0];\
+      } else {\
+        fprintf(stderr, "Can't happen");\
+        abort();\
+      }\
+    } else{\
+      JavaObject** obj = ((JavaObject***)__args)[0];\
+      if (obj) {\
+        ((JavaObject**)__buf)[0] = *obj;\
+      } else {\
+        ((JavaObject**)__buf)[0] = 0;\
+      }\
+    }\
+    __buf += 8; \
+    __args += 8; \
+  }\
 
-jobject NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID,
+
+jobject NewObjectA(JNIEnv* env, jclass _clazz, jmethodID methodID,
                    const jvalue *args) {
+  
   BEGIN_JNI_EXCEPTION
   
-  Jnjvm* vm = JavaThread::get()->getJVM();
+  // Local object references
+  JavaObject* clazz = *(JavaObject**)_clazz;
+  JavaObject* res = 0;
+
+  JavaThread* th = JavaThread::get();
+  Jnjvm* vm = th->getJVM();
   JavaMethod* meth = (JavaMethod*)methodID;
-  UserClass* cl = (UserClass*)
-    UserCommonClass::resolvedImplClass(vm, (JavaObject*)clazz, true);
-  JavaObject* res = cl->doNew(vm);
-  meth->invokeIntSpecialBuf(vm, cl, res, (void*)args);
-  return (jobject)res; 
+
+  Signdef* sign = meth->getSignature();
+  uintptr_t buf = (uintptr_t)alloca(sign->nbArguments * sizeof(uint64));
+  BufToBuf(args, buf, sign);
+
+  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, clazz, true);
+  
+  // Store local reference
+  res = cl->asClass()->doNew(vm);
+
+  meth->invokeIntSpecialBuf(vm, cl->asClass(), res, (void*)buf);
+
+  return (jobject)th->pushJNIRef(res); 
   
   END_JNI_EXCEPTION
   return 0;
 }
 
 
-jclass GetObjectClass(JNIEnv *env, jobject obj) {
+jclass GetObjectClass(JNIEnv *env, jobject _obj) {
   
   BEGIN_JNI_EXCEPTION
 
-  verifyNull((JavaObject*)obj);
-  Jnjvm* vm = JavaThread::get()->getJVM();
-  return (jclass)((JavaObject*)obj)->getClass()->getClassDelegatee(vm);
+  // Local object references
+  JavaObject* obj = *(JavaObject**)_obj;
 
+  JavaThread* th = JavaThread::get();
+  Jnjvm* vm = th->getJVM();
+  
+  // Store local reference
+  return (jclass)obj->getClass()->getClassDelegateePtr(vm);
+  
   END_JNI_EXCEPTION
   return 0;
 }
@@ -303,7 +395,7 @@
 
 
 jobject ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID,
-                          jboolean isStatic) {
+                               jboolean isStatic) {
   fprintf(stderr, "Implement me\n");
   abort();
   return 0;
@@ -318,21 +410,18 @@
 }
 
 
-jmethodID GetMethodID(JNIEnv* env, jclass clazz, const char *aname,
-		      const char *atype) {
+jmethodID GetMethodID(JNIEnv* env, jclass _clazz, const char *aname,
+		                  const char *atype) {
   
   BEGIN_JNI_EXCEPTION
-  
+ 
+  // Local object references.
+  JavaObject* clazz = *(JavaObject**)_clazz;
+
   Jnjvm* vm = JavaThread::get()->getJVM();
-  UserCommonClass* cl = 
-    UserCommonClass::resolvedImplClass(vm, (JavaObject*)clazz, true);
+  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, clazz, true);
 
-  UserClass* realCl = 0;
-  if (cl->isClass()) {
-    realCl = cl->asClass();
-  } else {
-    realCl = cl->super;
-  }
+  UserClass* realCl = cl->isClass() ? cl->asClass() : cl->super;
 
   const UTF8* name = cl->classLoader->hashUTF8->lookupAsciiz(aname);
   if (name) {
@@ -348,19 +437,27 @@
 }
 
 
-jobject CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...) {
+jobject CallObjectMethod(JNIEnv *env, jobject _obj, jmethodID methodID, ...) {
 
   BEGIN_JNI_EXCEPTION
 
+  verifyNull(_obj);
+
   va_list ap;
   va_start(ap, methodID);
-  JavaObject* self = (JavaObject*)obj;
+  
+  // Local object references.
+  JavaObject* obj = *(JavaObject**)_obj;
+  
   JavaMethod* meth = (JavaMethod*)methodID;
-  Jnjvm* vm = JavaThread::get()->getJVM();
-  UserClass* cl = getClassFromVirtualMethod(vm, meth, self->getClass());
-  JavaObject* res = meth->invokeJavaObjectVirtualAP(vm, cl, self, ap);
+  JavaThread* th = JavaThread::get();
+  Jnjvm* vm = th->getJVM();
+  UserClass* cl = getClassFromVirtualMethod(vm, meth, obj->getClass());
+  
+  JavaObject* res = meth->invokeJavaObjectVirtualAP(vm, cl, obj, ap, true);
   va_end(ap);
-  return (jobject)res;
+
+  return (jobject)th->pushJNIRef(res);
 
   END_JNI_EXCEPTION
   return 0;
@@ -372,11 +469,20 @@
   
   BEGIN_JNI_EXCEPTION
   
-  JavaObject* obj = (JavaObject*)_obj;
+  verifyNull(_obj);
+ 
+  // Local object references.
+  JavaObject* obj = *(JavaObject**)_obj;
+  JavaObject* res = 0;
+  
   JavaMethod* meth = (JavaMethod*)methodID;
+  JavaThread* th = JavaThread::get();
   Jnjvm* vm = JavaThread::get()->getJVM();
   UserClass* cl = getClassFromVirtualMethod(vm, meth, obj->getClass());
-  return (jobject)meth->invokeJavaObjectVirtualAP(vm, cl, obj, args);
+  
+  // Store local reference.
+  res = meth->invokeJavaObjectVirtualAP(vm, cl, obj, args, true);
+  return (jobject)th->pushJNIRef(res);
 
   END_JNI_EXCEPTION
   
@@ -395,15 +501,22 @@
 jboolean CallBooleanMethod(JNIEnv *env, jobject _obj, jmethodID methodID, ...) {
 
   BEGIN_JNI_EXCEPTION
-
+  
+  verifyNull(_obj);
+  
   va_list ap;
   va_start(ap, methodID);
-  JavaObject* self = (JavaObject*)_obj;
+  
+  // Local object references.  
+  JavaObject* self = *(JavaObject**)_obj;
+
   JavaMethod* meth = (JavaMethod*)methodID;
   Jnjvm* vm = JavaThread::get()->getJVM();
   UserClass* cl = getClassFromVirtualMethod(vm, meth, self->getClass());
-  uint32 res = meth->invokeIntVirtualAP(vm, cl, self, ap);
+  
+  uint32 res = meth->invokeIntVirtualAP(vm, cl, self, ap, true);
   va_end(ap);
+
   return res;
 
   END_JNI_EXCEPTION
@@ -416,11 +529,15 @@
   
   BEGIN_JNI_EXCEPTION
   
-  JavaObject* obj = (JavaObject*)_obj;
+  verifyNull(_obj);
+  
+  // Local object references.
+  JavaObject* obj = *(JavaObject**)_obj;
+  
   JavaMethod* meth = (JavaMethod*)methodID;
   Jnjvm* vm = JavaThread::get()->getJVM();
   UserClass* cl = getClassFromVirtualMethod(vm, meth, obj->getClass());
-  return (jboolean)meth->invokeIntVirtualAP(vm, cl, obj, args);
+  return (jboolean)meth->invokeIntVirtualAP(vm, cl, obj, args, true);
 
   END_JNI_EXCEPTION
   
@@ -446,12 +563,16 @@
                       va_list args) {
   
   BEGIN_JNI_EXCEPTION
+ 
+  verifyNull(_obj);
   
-  JavaObject* obj = (JavaObject*)_obj;
+  // Local object references.
+  JavaObject* obj = *(JavaObject**)_obj;
+
   JavaMethod* meth = (JavaMethod*)methodID;
   Jnjvm* vm = JavaThread::get()->getJVM();
   UserClass* cl = getClassFromVirtualMethod(vm, meth, obj->getClass());
-  return (jbyte)meth->invokeIntVirtualAP(vm, cl, obj, args);
+  return (jbyte)meth->invokeIntVirtualAP(vm, cl, obj, args, true);
 
   END_JNI_EXCEPTION
   
@@ -479,11 +600,16 @@
   
   BEGIN_JNI_EXCEPTION
   
-  JavaObject* obj = (JavaObject*)_obj;
+  verifyNull(_obj);
+  
+  // Local object references.
+  JavaObject* obj = *(JavaObject**)_obj;
+
+  
   JavaMethod* meth = (JavaMethod*)methodID;
   Jnjvm* vm = JavaThread::get()->getJVM();
   UserClass* cl = getClassFromVirtualMethod(vm, meth, obj->getClass());
-  return (jchar)meth->invokeIntVirtualAP(vm, cl, obj, args);
+  return (jchar)meth->invokeIntVirtualAP(vm, cl, obj, args, true);
 
   END_JNI_EXCEPTION
   
@@ -511,11 +637,15 @@
   
   BEGIN_JNI_EXCEPTION
   
-  JavaObject* obj = (JavaObject*)_obj;
+  verifyNull(_obj);
+  
+  // Local object references.
+  JavaObject* obj = *(JavaObject**)_obj;
+  
   JavaMethod* meth = (JavaMethod*)methodID;
   Jnjvm* vm = JavaThread::get()->getJVM();
   UserClass* cl = getClassFromVirtualMethod(vm, meth, obj->getClass());
-  return (jshort)meth->invokeIntVirtualAP(vm, cl, obj, args);
+  return (jshort)meth->invokeIntVirtualAP(vm, cl, obj, args, true);
 
   END_JNI_EXCEPTION
   
@@ -535,15 +665,22 @@
 jint CallIntMethod(JNIEnv *env, jobject _obj, jmethodID methodID, ...) {
 
   BEGIN_JNI_EXCEPTION
-
+  
+  verifyNull(_obj);
+  
   va_list ap;
   va_start(ap, methodID);
-  JavaObject* obj = (JavaObject*)_obj;
+  
+  // Local object references.
+  JavaObject* obj = *(JavaObject**)_obj;
+
   JavaMethod* meth = (JavaMethod*)methodID;
   Jnjvm* vm = JavaThread::get()->getJVM();
   UserClass* cl = getClassFromVirtualMethod(vm, meth, obj->getClass());
-  uint32 res = meth->invokeIntVirtualAP(vm, cl, obj, ap);
+  
+  uint32 res = meth->invokeIntVirtualAP(vm, cl, obj, ap, true);
   va_end(ap);
+  
   return res;
 
   END_JNI_EXCEPTION
@@ -556,11 +693,16 @@
   
   BEGIN_JNI_EXCEPTION
   
-  JavaObject* obj = (JavaObject*)_obj;
+  verifyNull(_obj);
+  
+  // Local object references.
+  JavaObject* obj = *(JavaObject**)_obj;
+  
   JavaMethod* meth = (JavaMethod*)methodID;
   Jnjvm* vm = JavaThread::get()->getJVM();
   UserClass* cl = getClassFromVirtualMethod(vm, meth, obj->getClass());
-  return (jint)meth->invokeIntVirtualAP(vm, cl, obj, args);
+  
+  return (jint)meth->invokeIntVirtualAP(vm, cl, obj, args, true);
 
   END_JNI_EXCEPTION
   
@@ -568,7 +710,7 @@
 }
 
 
-jint CallIntMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
+jint CallIntMethodA(JNIEnv *env, jobject _obj, jmethodID methodID,
                     const jvalue *args) {
   fprintf(stderr, "Implement me\n");
   abort();
@@ -577,7 +719,7 @@
 
 
 
-jlong CallLongMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...) {
+jlong CallLongMethod(JNIEnv *env, jobject _obj, jmethodID methodID, ...) {
   fprintf(stderr, "Implement me\n");
   abort();
   return 0;
@@ -589,11 +731,15 @@
   
   BEGIN_JNI_EXCEPTION
   
-  JavaObject* obj = (JavaObject*)_obj;
+  verifyNull(_obj);
+  
+  // Local object references.
+  JavaObject* obj = *(JavaObject**)_obj;
+  
   JavaMethod* meth = (JavaMethod*)methodID;
   Jnjvm* vm = JavaThread::get()->getJVM();
   UserClass* cl = getClassFromVirtualMethod(vm, meth, obj->getClass());
-  return (jlong)meth->invokeLongVirtualAP(vm, cl, obj, args);
+  return (jlong)meth->invokeLongVirtualAP(vm, cl, obj, args, true);
 
   END_JNI_EXCEPTION
   
@@ -613,14 +759,19 @@
 jfloat CallFloatMethod(JNIEnv *env, jobject _obj, jmethodID methodID, ...) {
   
   BEGIN_JNI_EXCEPTION
-
+  
+  verifyNull(_obj);
+  
   va_list ap;
   va_start(ap, methodID);
-  JavaObject* obj = (JavaObject*)_obj;
+  
+  // Local object references.
+  JavaObject* obj = *(JavaObject**)_obj;
+
   JavaMethod* meth = (JavaMethod*)methodID;
   Jnjvm* vm = JavaThread::get()->getJVM();
   UserClass* cl = getClassFromVirtualMethod(vm, meth, obj->getClass());
-  jfloat res = meth->invokeFloatVirtualAP(vm, cl, obj, ap);
+  jfloat res = meth->invokeFloatVirtualAP(vm, cl, obj, ap, true);
   va_end(ap);
   return res;
 
@@ -633,12 +784,16 @@
                         va_list args) {
   
   BEGIN_JNI_EXCEPTION
+ 
+  verifyNull(_obj);
+  
+  // Local object references.
+  JavaObject* obj = *(JavaObject**)_obj;
   
-  JavaObject* obj = (JavaObject*)_obj;
   JavaMethod* meth = (JavaMethod*)methodID;
   Jnjvm* vm = JavaThread::get()->getJVM();
   UserClass* cl = getClassFromVirtualMethod(vm, meth, obj->getClass());
-  return (jfloat)meth->invokeFloatVirtualAP(vm, cl, obj, args);
+  return (jfloat)meth->invokeFloatVirtualAP(vm, cl, obj, args, true);
 
   END_JNI_EXCEPTION
   
@@ -658,14 +813,19 @@
 jdouble CallDoubleMethod(JNIEnv *env, jobject _obj, jmethodID methodID, ...) {
   
   BEGIN_JNI_EXCEPTION
-
+  
+  verifyNull(_obj);
+  
   va_list ap;
   va_start(ap, methodID);
-  JavaObject* obj = (JavaObject*)_obj;
+  
+  // Local object references.
+  JavaObject* obj = *(JavaObject**)_obj;
+
   JavaMethod* meth = (JavaMethod*)methodID;
   Jnjvm* vm = JavaThread::get()->getJVM();
   UserClass* cl = getClassFromVirtualMethod(vm, meth, obj->getClass());
-  jdouble res = meth->invokeDoubleVirtualAP(vm, cl, obj, ap);
+  jdouble res = meth->invokeDoubleVirtualAP(vm, cl, obj, ap, true);
   va_end(ap);
   return res;
 
@@ -679,11 +839,14 @@
   
   BEGIN_JNI_EXCEPTION
   
-  JavaObject* obj = (JavaObject*)_obj;
+  verifyNull(_obj);
+  
+  // Local object references.
+  JavaObject* obj = *(JavaObject**)_obj;
   JavaMethod* meth = (JavaMethod*)methodID;
   Jnjvm* vm = JavaThread::get()->getJVM();
   UserClass* cl = getClassFromVirtualMethod(vm, meth, obj->getClass());
-  return (jdouble)meth->invokeDoubleVirtualAP(vm, cl, obj, args);
+  return (jdouble)meth->invokeDoubleVirtualAP(vm, cl, obj, args, true);
 
   END_JNI_EXCEPTION
   return 0.0;
@@ -704,13 +867,18 @@
   
   BEGIN_JNI_EXCEPTION
 
+  verifyNull(_obj);
+
   va_list ap;
   va_start(ap, methodID);
-  JavaObject* obj = (JavaObject*)_obj;
+
+  // Local object references.
+  JavaObject* obj = *(JavaObject**)_obj;
+
   JavaMethod* meth = (JavaMethod*)methodID;
   Jnjvm* vm = JavaThread::get()->getJVM();
   UserClass* cl = getClassFromVirtualMethod(vm, meth, obj->getClass());
-  meth->invokeIntVirtualAP(vm, cl, obj, ap);
+  meth->invokeIntVirtualAP(vm, cl, obj, ap, true);
   va_end(ap);
 
   END_JNI_EXCEPTION
@@ -722,11 +890,15 @@
   
   BEGIN_JNI_EXCEPTION
   
-  JavaObject* obj = (JavaObject*)_obj;
+  verifyNull(_obj);
+  
+  // Local object references.
+  JavaObject* obj = *(JavaObject**)_obj;
+
   JavaMethod* meth = (JavaMethod*)methodID;
   Jnjvm* vm = JavaThread::get()->getJVM();
   UserClass* cl = getClassFromVirtualMethod(vm, meth, obj->getClass());
-  meth->invokeIntVirtualAP(vm, cl, obj, args);
+  meth->invokeIntVirtualAP(vm, cl, obj, args, true);
 
   END_JNI_EXCEPTION
 }
@@ -968,14 +1140,19 @@
                               jmethodID methodID, ...) {
   
   BEGIN_JNI_EXCEPTION
-
+  
+  verifyNull(_obj);
+  
   va_list ap;
   va_start(ap, methodID);
-  JavaObject* obj = (JavaObject*)_obj;
+  
+  // Local object references.
+  JavaObject* obj = *(JavaObject**)_obj;
+
   JavaMethod* meth = (JavaMethod*)methodID;
   Jnjvm* vm = JavaThread::get()->getJVM();
   UserClass* cl = getClassFromVirtualMethod(vm, meth, obj->getClass());
-  meth->invokeIntSpecialAP(vm, cl, obj, ap);
+  meth->invokeIntSpecialAP(vm, cl, obj, ap, true);
   va_end(ap);
 
   END_JNI_EXCEPTION
@@ -996,14 +1173,16 @@
 }
 
 
-jfieldID GetFieldID(JNIEnv *env, jclass clazz, const char *aname,
+jfieldID GetFieldID(JNIEnv *env, jclass _clazz, const char *aname,
 		    const char *sig)  {
 
   BEGIN_JNI_EXCEPTION
 
+  // Local object references.
+  JavaObject* clazz = *(JavaObject**)_clazz;
+
   Jnjvm* vm = JavaThread::get()->getJVM();
-  UserCommonClass* cl = 
-    UserCommonClass::resolvedImplClass(vm, (JavaObject*)clazz, true);
+  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, clazz, true);
 
   if (cl->isClass()) {
     const UTF8* name = cl->classLoader->hashUTF8->lookupAsciiz(aname);
@@ -1023,240 +1202,285 @@
 }
 
 
-jobject GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID) {
+jobject GetObjectField(JNIEnv *env, jobject _obj, jfieldID fieldID) {
 
   BEGIN_JNI_EXCEPTION
+  
+  // Local object references.
+  JavaObject* obj = *(JavaObject**)_obj;
+  JavaObject* res = 0;
 
   JavaField* field = (JavaField*)fieldID;
-  JavaObject* o = (JavaObject*)obj;
-  return (jobject)field->getObjectField(o);
+
+  // Store local reference.
+  res = field->getObjectField(obj);
+
+  JavaThread* th = JavaThread::get();
+  return (jobject)th->pushJNIRef(res);
 
   END_JNI_EXCEPTION
   return 0;
 }
 
 
-jboolean GetBooleanField(JNIEnv *env, jobject obj, jfieldID fieldID) {
+jboolean GetBooleanField(JNIEnv *env, jobject _obj, jfieldID fieldID) {
 
   BEGIN_JNI_EXCEPTION
+  
+  // Local object references.
+  JavaObject* obj = *(JavaObject**)_obj;
 
   JavaField* field = (JavaField*)fieldID;
-  JavaObject* o = (JavaObject*)obj;
-  return (uint8)field->getInt8Field(o);
+  return (uint8)field->getInt8Field(obj);
 
   END_JNI_EXCEPTION
   return 0;
 }
 
 
-jbyte GetByteField(JNIEnv *env, jobject obj, jfieldID fieldID) {
+jbyte GetByteField(JNIEnv *env, jobject _obj, jfieldID fieldID) {
 
   BEGIN_JNI_EXCEPTION
+  
+  // Local object references.
+  JavaObject* obj = *(JavaObject**)_obj;
 
   JavaField* field = (JavaField*)fieldID;
-  JavaObject* o = (JavaObject*)obj;
-  return (sint8)field->getInt8Field(o);
+  return (sint8)field->getInt8Field(obj);
 
   END_JNI_EXCEPTION
   return 0;
 }
 
 
-jchar GetCharField(JNIEnv *env, jobject obj, jfieldID fieldID) {
+jchar GetCharField(JNIEnv *env, jobject _obj, jfieldID fieldID) {
 
   BEGIN_JNI_EXCEPTION
 
+  // Local object references.
+  JavaObject* obj = *(JavaObject**)_obj;
+  
   JavaField* field = (JavaField*)fieldID;
-  JavaObject* o = (JavaObject*)obj;
-  return (uint16)field->getInt16Field(o);
+  return (uint16)field->getInt16Field(obj);
 
   END_JNI_EXCEPTION
   return 0;
 }
 
 
-jshort GetShortField(JNIEnv *env, jobject obj, jfieldID fieldID) {
+jshort GetShortField(JNIEnv *env, jobject _obj, jfieldID fieldID) {
 
   BEGIN_JNI_EXCEPTION
+  
+  // Local object references.
+  JavaObject* obj = *(JavaObject**)_obj;
 
   JavaField* field = (JavaField*)fieldID;
-  JavaObject* o = (JavaObject*)obj;
-  return (sint16)field->getInt16Field(o);
+  return (sint16)field->getInt16Field(obj);
 
   END_JNI_EXCEPTION
   return 0;
 }
 
 
-jint GetIntField(JNIEnv *env, jobject obj, jfieldID fieldID) {
+jint GetIntField(JNIEnv *env, jobject _obj, jfieldID fieldID) {
 
   BEGIN_JNI_EXCEPTION
+  
+  // Local object references.
+  JavaObject* obj = *(JavaObject**)_obj;
 
   JavaField* field = (JavaField*)fieldID;
-  JavaObject* o = (JavaObject*)obj;
-  return (sint32)field->getInt32Field(o);
+  return (sint32)field->getInt32Field(obj);
 
   END_JNI_EXCEPTION
   return 0;
 }
 
 
-jlong GetLongField(JNIEnv *env, jobject obj, jfieldID fieldID) {
+jlong GetLongField(JNIEnv *env, jobject _obj, jfieldID fieldID) {
 
   BEGIN_JNI_EXCEPTION
 
+  // Local object references.
+  JavaObject* obj = *(JavaObject**)_obj;
+  
   JavaField* field = (JavaField*)fieldID;
-  JavaObject* o = (JavaObject*)obj;
-  return (sint64)field->getLongField(o);
+  return (sint64)field->getLongField(obj);
 
   END_JNI_EXCEPTION
   return 0;
 }
 
 
-jfloat GetFloatField(JNIEnv *env, jobject obj, jfieldID fieldID) {
+jfloat GetFloatField(JNIEnv *env, jobject _obj, jfieldID fieldID) {
 
   BEGIN_JNI_EXCEPTION
+  
+  // Local object references.
+  JavaObject* obj = *(JavaObject**)_obj;
 
   JavaField* field = (JavaField*)fieldID;
-  JavaObject* o = (JavaObject*)obj;
-  return field->getFloatField(o);
+  return field->getFloatField(obj);
 
   END_JNI_EXCEPTION
   return 0;
 }
 
 
-jdouble GetDoubleField(JNIEnv *env, jobject obj, jfieldID fieldID) {
+jdouble GetDoubleField(JNIEnv *env, jobject _obj, jfieldID fieldID) {
 
   BEGIN_JNI_EXCEPTION
 
+  // Local object references.
+  JavaObject* obj = *(JavaObject**)_obj;
+  
   JavaField* field = (JavaField*)fieldID;
-  JavaObject* o = (JavaObject*)obj;
-  return (jdouble)field->getDoubleField(o);
+  return (jdouble)field->getDoubleField(obj);
 
   END_JNI_EXCEPTION
   return 0;
 }
 
 
-void SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID, jobject value) {
+void SetObjectField(JNIEnv *env, jobject _obj, jfieldID fieldID, jobject _value) {
 
   BEGIN_JNI_EXCEPTION
+  
+  // Local object references.
+  JavaObject* obj = *(JavaObject**)_obj;
+  JavaObject* value = *(JavaObject**)_value;
 
   JavaField* field = (JavaField*)fieldID;
-  JavaObject* o = (JavaObject*)obj;
-  field->setObjectField(o, (JavaObject*)value);
+  field->setObjectField(obj, value);
 
   END_JNI_EXCEPTION
 }
 
 
-void SetBooleanField(JNIEnv *env, jobject obj, jfieldID fieldID,
+void SetBooleanField(JNIEnv *env, jobject _obj, jfieldID fieldID,
                      jboolean value) {
 
   BEGIN_JNI_EXCEPTION
+  
+  // Local object references.
+  JavaObject* obj = *(JavaObject**)_obj;
 
   JavaField* field = (JavaField*)fieldID;
-  JavaObject* o = (JavaObject*)obj;
-  field->setInt8Field(o, (uint8)value);
+  field->setInt8Field(obj, (uint8)value);
 
   END_JNI_EXCEPTION
 }
 
 
-void SetByteField(JNIEnv *env, jobject obj, jfieldID fieldID, jbyte value) {
+void SetByteField(JNIEnv *env, jobject _obj, jfieldID fieldID, jbyte value) {
 
   BEGIN_JNI_EXCEPTION
   
+  // Local object references.
+  JavaObject* obj = *(JavaObject**)_obj;
+  
   JavaField* field = (JavaField*)fieldID;
-  JavaObject* o = (JavaObject*)obj;
-  field->setInt8Field(o, (uint8)value);
+  field->setInt8Field(obj, (uint8)value);
 
   END_JNI_EXCEPTION
 }
 
 
-void SetCharField(JNIEnv *env, jobject obj, jfieldID fieldID, jchar value) {
+void SetCharField(JNIEnv *env, jobject _obj, jfieldID fieldID, jchar value) {
 
   BEGIN_JNI_EXCEPTION
 
+  // Local object references.
+  JavaObject* obj = *(JavaObject**)_obj;
+
   JavaField* field = (JavaField*)fieldID;
-  JavaObject* o = (JavaObject*)obj;
-  field->setInt16Field(o, (uint16)value);
+  field->setInt16Field(obj, (uint16)value);
   
   END_JNI_EXCEPTION
 }
 
 
-void SetShortField(JNIEnv *env, jobject obj, jfieldID fieldID, jshort value) {
+void SetShortField(JNIEnv *env, jobject _obj, jfieldID fieldID, jshort value) {
 
   BEGIN_JNI_EXCEPTION
 
+  // Local object references.
+  JavaObject* obj = *(JavaObject**)_obj;
+  
   JavaField* field = (JavaField*)fieldID;
-  JavaObject* o = (JavaObject*)obj;
-  field->setInt16Field(o, (sint16)value);
+  field->setInt16Field(obj, (sint16)value);
 
   END_JNI_EXCEPTION
 }
 
 
-void SetIntField(JNIEnv *env, jobject obj, jfieldID fieldID, jint value) {
+void SetIntField(JNIEnv *env, jobject _obj, jfieldID fieldID, jint value) {
 
   BEGIN_JNI_EXCEPTION
 
+  // Local object references.
+  JavaObject* obj = *(JavaObject**)_obj;
+  
   JavaField* field = (JavaField*)fieldID;
-  JavaObject* o = (JavaObject*)obj;
-  field->setInt32Field(o, (sint32)value);
+  field->setInt32Field(obj, (sint32)value);
 
   END_JNI_EXCEPTION
 }
 
 
-void SetLongField(JNIEnv *env, jobject obj, jfieldID fieldID, jlong value) {
+void SetLongField(JNIEnv *env, jobject _obj, jfieldID fieldID, jlong value) {
 
   BEGIN_JNI_EXCEPTION
 
+  // Local object references.
+  JavaObject* obj = *(JavaObject**)_obj;
+  
   JavaField* field = (JavaField*)fieldID;
-  JavaObject* o = (JavaObject*)obj;
-  field->setLongField(o, (sint64)value);
+  field->setLongField(obj, (sint64)value);
 
   END_JNI_EXCEPTION
 }
 
 
-void SetFloatField(JNIEnv *env, jobject obj, jfieldID fieldID, jfloat value) {
+void SetFloatField(JNIEnv *env, jobject _obj, jfieldID fieldID, jfloat value) {
 
   BEGIN_JNI_EXCEPTION
 
+  // Local object references.
+  JavaObject* obj = *(JavaObject**)_obj;
+  
   JavaField* field = (JavaField*)fieldID;
-  JavaObject* o = (JavaObject*)obj;
-  field->setFloatField(o, (float)value);
+  field->setFloatField(obj, (float)value);
 
   END_JNI_EXCEPTION
 }
 
 
-void SetDoubleField(JNIEnv *env, jobject obj, jfieldID fieldID, jdouble value) {
+void SetDoubleField(JNIEnv *env, jobject _obj, jfieldID fieldID, jdouble value) {
 
   BEGIN_JNI_EXCEPTION
 
+  // Local object references.
+  JavaObject* obj = *(JavaObject**)_obj;
+  
   JavaField* field = (JavaField*)fieldID;
-  JavaObject* o = (JavaObject*)obj;
-  field->setDoubleField(o, (float)value);
+  field->setDoubleField(obj, (float)value);
 
   END_JNI_EXCEPTION
 }
 
 
-jmethodID GetStaticMethodID(JNIEnv *env, jclass clazz, const char *aname,
+jmethodID GetStaticMethodID(JNIEnv *env, jclass _clazz, const char *aname,
 			    const char *atype) {
 
   BEGIN_JNI_EXCEPTION
   
+  // Local object references.
+  JavaObject* clazz = *(JavaObject**)_clazz;
+  
   Jnjvm* vm = JavaThread::get()->getJVM();
-  UserCommonClass* cl = 
-    UserCommonClass::resolvedImplClass(vm, (JavaObject*)clazz, true);
+  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, clazz, true);
 
   if (cl->isClass()) {
     const UTF8* name = cl->classLoader->hashUTF8->lookupAsciiz(aname);
@@ -1275,33 +1499,52 @@
 }
 
 
-jobject CallStaticObjectMethod(JNIEnv *env, jclass clazz, jmethodID methodID,
+jobject CallStaticObjectMethod(JNIEnv *env, jclass _clazz, jmethodID methodID,
                                ...) {
   
   BEGIN_JNI_EXCEPTION
   
   va_list ap;
   va_start(ap, methodID);
+ 
+  // Local object references.
+  JavaObject* clazz = *(JavaObject**)_clazz;
+  JavaObject* res = 0;
+
+
   JavaMethod* meth = (JavaMethod*)methodID;
-  Jnjvm* vm = JavaThread::get()->getJVM();
+  JavaThread* th = JavaThread::get();
+  Jnjvm* vm = th->getJVM();
   UserClass* cl = getClassFromStaticMethod(vm, meth, clazz);
-  jobject res = (jobject) meth->invokeJavaObjectStaticAP(vm, cl, ap);
+  
+  // Store local reference.
+  res = meth->invokeJavaObjectStaticAP(vm, cl, ap, true);
   va_end(ap);
-  return res;
+  
+  return (jobject)th->pushJNIRef(res);
 
   END_JNI_EXCEPTION
   return 0;
 }
 
 
-jobject CallStaticObjectMethodV(JNIEnv *env, jclass clazz, jmethodID methodID,
-                                va_list args) {
+jobject CallStaticObjectMethodV(JNIEnv *env, jclass _clazz, jmethodID methodID,
+                                     va_list args) {
   BEGIN_JNI_EXCEPTION
   
+  // Local object references.
+  JavaObject* clazz = *(JavaObject**)_clazz;
+  JavaObject* res = 0;
+  
   JavaMethod* meth = (JavaMethod*)methodID;
-  Jnjvm* vm = JavaThread::get()->getJVM();
+  JavaThread* th = JavaThread::get();
+  Jnjvm* vm = th->getJVM();
   UserClass* cl = getClassFromStaticMethod(vm, meth, clazz);
-  return (jobject)meth->invokeJavaObjectStaticAP(vm, cl, args);
+  
+  // Store local reference.
+  res = meth->invokeJavaObjectStaticAP(vm, cl, args, true);
+
+  return (jobject)th->pushJNIRef(res);
 
   END_JNI_EXCEPTION
   return 0;
@@ -1316,17 +1559,21 @@
 }
 
 
-jboolean CallStaticBooleanMethod(JNIEnv *env, jclass clazz, jmethodID methodID,
+jboolean CallStaticBooleanMethod(JNIEnv *env, jclass _clazz, jmethodID methodID,
                                  ...) {
   
   BEGIN_JNI_EXCEPTION
   
   va_list ap;
   va_start(ap, methodID);
+  
+  // Local object references.
+  JavaObject* clazz = *(JavaObject**)_clazz;
+  
   JavaMethod* meth = (JavaMethod*)methodID;
   Jnjvm* vm = JavaThread::get()->getJVM();
   UserClass* cl = getClassFromStaticMethod(vm, meth, clazz);
-  uint32 res = meth->invokeIntStaticAP(vm, cl, ap);
+  uint32 res = meth->invokeIntStaticAP(vm, cl, ap, true);
   va_end(ap);
   return res;
 
@@ -1335,15 +1582,18 @@
 }
 
 
-jboolean CallStaticBooleanMethodV(JNIEnv *env, jclass clazz, jmethodID methodID,
+jboolean CallStaticBooleanMethodV(JNIEnv *env, jclass _clazz, jmethodID methodID,
                                   va_list args) {
   
   BEGIN_JNI_EXCEPTION
   
+  // Local object references.
+  JavaObject* clazz = *(JavaObject**)_clazz;
+  
   JavaMethod* meth = (JavaMethod*)methodID;
   Jnjvm* vm = JavaThread::get()->getJVM();
   UserClass* cl = getClassFromStaticMethod(vm, meth, clazz);
-  return (jboolean)meth->invokeIntStaticAP(vm, cl, args);
+  return (jboolean)meth->invokeIntStaticAP(vm, cl, args, true);
 
   END_JNI_EXCEPTION
   return 0;
@@ -1358,16 +1608,19 @@
 }
 
 
-jbyte CallStaticByteMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...) {
+jbyte CallStaticByteMethod(JNIEnv *env, jclass _clazz, jmethodID methodID, ...) {
   
   BEGIN_JNI_EXCEPTION
   
+  // Local object references.
+  JavaObject* clazz = *(JavaObject**)_clazz;
+  
   va_list ap;
   va_start(ap, methodID);
   JavaMethod* meth = (JavaMethod*)methodID;
   Jnjvm* vm = JavaThread::get()->getJVM();
   UserClass* cl = getClassFromStaticMethod(vm, meth, clazz);
-  jbyte res = (jbyte) meth->invokeIntStaticAP(vm, cl, ap);
+  jbyte res = (jbyte) meth->invokeIntStaticAP(vm, cl, ap, true);
   va_end(ap);
   return res;
 
@@ -1376,15 +1629,18 @@
 }
 
 
-jbyte CallStaticByteMethodV(JNIEnv *env, jclass clazz, jmethodID methodID,
+jbyte CallStaticByteMethodV(JNIEnv *env, jclass _clazz, jmethodID methodID,
                             va_list args) {
   
   BEGIN_JNI_EXCEPTION
   
+  // Local object references.
+  JavaObject* clazz = *(JavaObject**)_clazz;
+  
   JavaMethod* meth = (JavaMethod*)methodID;
   Jnjvm* vm = JavaThread::get()->getJVM();
   UserClass* cl = getClassFromStaticMethod(vm, meth, clazz);
-  return (jbyte)meth->invokeIntStaticAP(vm, cl, args);
+  return (jbyte)meth->invokeIntStaticAP(vm, cl, args, true);
 
   END_JNI_EXCEPTION
   return 0;
@@ -1399,16 +1655,20 @@
 }
 
 
-jchar CallStaticCharMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...) {
+jchar CallStaticCharMethod(JNIEnv *env, jclass _clazz, jmethodID methodID, ...) {
   
   BEGIN_JNI_EXCEPTION
   
   va_list ap;
   va_start(ap, methodID);
+  
+  // Local object references.
+  JavaObject* clazz = *(JavaObject**)_clazz;
+  
   JavaMethod* meth = (JavaMethod*)methodID;
   Jnjvm* vm = JavaThread::get()->getJVM();
   UserClass* cl = getClassFromStaticMethod(vm, meth, clazz);
-  jchar res = (jchar) meth->invokeIntStaticAP(vm, cl, ap);
+  jchar res = (jchar) meth->invokeIntStaticAP(vm, cl, ap, true);
   va_end(ap);
   return res;
 
@@ -1417,21 +1677,24 @@
 }
 
 
-jchar CallStaticCharMethodV(JNIEnv *env, jclass clazz, jmethodID methodID,
+jchar CallStaticCharMethodV(JNIEnv *env, jclass _clazz, jmethodID methodID,
                             va_list args) {
   BEGIN_JNI_EXCEPTION
   
+  // Local object references.
+  JavaObject* clazz = *(JavaObject**)_clazz;
+  
   JavaMethod* meth = (JavaMethod*)methodID;
   Jnjvm* vm = JavaThread::get()->getJVM();
   UserClass* cl = getClassFromStaticMethod(vm, meth, clazz);
-  return (jchar)meth->invokeIntStaticAP(vm, cl, args);
+  return (jchar)meth->invokeIntStaticAP(vm, cl, args, true);
 
   END_JNI_EXCEPTION
   return 0;
 }
 
 
-jchar CallStaticCharMethodA(JNIEnv *env, jclass clazz, jmethodID methodID,
+jchar CallStaticCharMethodA(JNIEnv *env, jclass _clazz, jmethodID methodID,
                             const jvalue *args) {
   fprintf(stderr, "Implement me\n");
   abort();
@@ -1439,17 +1702,21 @@
 }
 
 
-jshort CallStaticShortMethod(JNIEnv *env, jclass clazz, jmethodID methodID,
+jshort CallStaticShortMethod(JNIEnv *env, jclass _clazz, jmethodID methodID,
                              ...) {
   
   BEGIN_JNI_EXCEPTION
   
   va_list ap;
   va_start(ap, methodID);
+  
+  // Local object references.
+  JavaObject* clazz = *(JavaObject**)_clazz;
+  
   JavaMethod* meth = (JavaMethod*)methodID;
   Jnjvm* vm = JavaThread::get()->getJVM();
   UserClass* cl = getClassFromStaticMethod(vm, meth, clazz);
-  jshort res = (jshort) meth->invokeIntStaticAP(vm, cl, ap);
+  jshort res = (jshort) meth->invokeIntStaticAP(vm, cl, ap, true);
   va_end(ap);
   return res;
 
@@ -1458,15 +1725,18 @@
 }
 
 
-jshort CallStaticShortMethodV(JNIEnv *env, jclass clazz, jmethodID methodID,
+jshort CallStaticShortMethodV(JNIEnv *env, jclass _clazz, jmethodID methodID,
                               va_list args) {
   
   BEGIN_JNI_EXCEPTION
   
+  // Local object references.
+  JavaObject* clazz = *(JavaObject**)_clazz;
+  
   JavaMethod* meth = (JavaMethod*)methodID;
   Jnjvm* vm = JavaThread::get()->getJVM();
   UserClass* cl = getClassFromStaticMethod(vm, meth, clazz);
-  return (jshort)meth->invokeIntStaticAP(vm, cl, args);
+  return (jshort)meth->invokeIntStaticAP(vm, cl, args, true);
 
   END_JNI_EXCEPTION
   return 0;
@@ -1481,16 +1751,20 @@
 }
 
 
-jint CallStaticIntMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...) {
+jint CallStaticIntMethod(JNIEnv *env, jclass _clazz, jmethodID methodID, ...) {
   
   BEGIN_JNI_EXCEPTION
   
   va_list ap;
   va_start(ap, methodID);
+  
+  // Local object references.
+  JavaObject* clazz = *(JavaObject**)_clazz;
+  
   JavaMethod* meth = (JavaMethod*)methodID;
   Jnjvm* vm = JavaThread::get()->getJVM();
   UserClass* cl = getClassFromStaticMethod(vm, meth, clazz);
-  jint res = (jint) meth->invokeIntStaticAP(vm, cl, ap);
+  jint res = (jint) meth->invokeIntStaticAP(vm, cl, ap, true);
   va_end(ap);
   return res;
 
@@ -1499,14 +1773,17 @@
 }
 
 
-jint CallStaticIntMethodV(JNIEnv *env, jclass clazz, jmethodID methodID,
+jint CallStaticIntMethodV(JNIEnv *env, jclass _clazz, jmethodID methodID,
                           va_list args) {
   BEGIN_JNI_EXCEPTION
   
+  // Local object references.
+  JavaObject* clazz = *(JavaObject**)_clazz;
+  
   JavaMethod* meth = (JavaMethod*)methodID;
   Jnjvm* vm = JavaThread::get()->getJVM();
   UserClass* cl = getClassFromStaticMethod(vm, meth, clazz);
-  return (jint)meth->invokeIntStaticAP(vm, cl, args);
+  return (jint)meth->invokeIntStaticAP(vm, cl, args, true);
 
   END_JNI_EXCEPTION
   
@@ -1522,16 +1799,20 @@
 }
 
 
-jlong CallStaticLongMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...) {
+jlong CallStaticLongMethod(JNIEnv *env, jclass _clazz, jmethodID methodID, ...) {
   
   BEGIN_JNI_EXCEPTION
   
   va_list ap;
   va_start(ap, methodID);
+  
+  // Local object references.
+  JavaObject* clazz = *(JavaObject**)_clazz;
+  
   JavaMethod* meth = (JavaMethod*)methodID;
   Jnjvm* vm = JavaThread::get()->getJVM();
   UserClass* cl = getClassFromStaticMethod(vm, meth, clazz);
-  jlong res = (jlong) meth->invokeLongStaticAP(vm, cl, ap);
+  jlong res = (jlong) meth->invokeLongStaticAP(vm, cl, ap, true);
   va_end(ap);
   return res;
 
@@ -1540,15 +1821,18 @@
 }
 
 
-jlong CallStaticLongMethodV(JNIEnv *env, jclass clazz, jmethodID methodID,
+jlong CallStaticLongMethodV(JNIEnv *env, jclass _clazz, jmethodID methodID,
 			    va_list args) {
 
   BEGIN_JNI_EXCEPTION
   
+  // Local object references.
+  JavaObject* clazz = *(JavaObject**)_clazz;
+  
   JavaMethod* meth = (JavaMethod*)methodID;
   Jnjvm* vm = JavaThread::get()->getJVM();
   UserClass* cl = getClassFromStaticMethod(vm, meth, clazz);
-  return (jlong)meth->invokeLongStaticAP(vm, cl, args);
+  return (jlong)meth->invokeLongStaticAP(vm, cl, args, true);
 
   END_JNI_EXCEPTION
   
@@ -1565,17 +1849,21 @@
 
 
 
-jfloat CallStaticFloatMethod(JNIEnv *env, jclass clazz, jmethodID methodID,
+jfloat CallStaticFloatMethod(JNIEnv *env, jclass _clazz, jmethodID methodID,
                              ...) {
   
   BEGIN_JNI_EXCEPTION
   
   va_list ap;
   va_start(ap, methodID);
+  
+  // Local object references.
+  JavaObject* clazz = *(JavaObject**)_clazz;
+  
   JavaMethod* meth = (JavaMethod*)methodID;
   Jnjvm* vm = JavaThread::get()->getJVM();
   UserClass* cl = getClassFromStaticMethod(vm, meth, clazz);
-  jfloat res = (jfloat) meth->invokeFloatStaticAP(vm, cl, ap);
+  jfloat res = (jfloat) meth->invokeFloatStaticAP(vm, cl, ap, true);
   va_end(ap);
   return res;
 
@@ -1584,15 +1872,18 @@
 }
 
 
-jfloat CallStaticFloatMethodV(JNIEnv *env, jclass clazz, jmethodID methodID,
+jfloat CallStaticFloatMethodV(JNIEnv *env, jclass _clazz, jmethodID methodID,
                               va_list args) {
   
   BEGIN_JNI_EXCEPTION
   
+  // Local object references.
+  JavaObject* clazz = *(JavaObject**)_clazz;
+  
   JavaMethod* meth = (JavaMethod*)methodID;
   Jnjvm* vm = JavaThread::get()->getJVM();
   UserClass* cl = getClassFromStaticMethod(vm, meth, clazz);
-  return (jfloat)meth->invokeFloatStaticAP(vm, cl, args);
+  return (jfloat)meth->invokeFloatStaticAP(vm, cl, args, true);
 
   END_JNI_EXCEPTION
   
@@ -1608,17 +1899,21 @@
 }
 
 
-jdouble CallStaticDoubleMethod(JNIEnv *env, jclass clazz, jmethodID methodID,
+jdouble CallStaticDoubleMethod(JNIEnv *env, jclass _clazz, jmethodID methodID,
                                ...) {
   
   BEGIN_JNI_EXCEPTION
   
   va_list ap;
   va_start(ap, methodID);
+  
+  // Local object references.
+  JavaObject* clazz = *(JavaObject**)_clazz;
+  
   JavaMethod* meth = (JavaMethod*)methodID;
   Jnjvm* vm = JavaThread::get()->getJVM();
   UserClass* cl = getClassFromStaticMethod(vm, meth, clazz);
-  jdouble res = (jdouble) meth->invokeDoubleStaticAP(vm, cl, ap);
+  jdouble res = (jdouble) meth->invokeDoubleStaticAP(vm, cl, ap, true);
   va_end(ap);
   return res;
 
@@ -1627,14 +1922,17 @@
 }
 
 
-jdouble CallStaticDoubleMethodV(JNIEnv *env, jclass clazz, jmethodID methodID,
+jdouble CallStaticDoubleMethodV(JNIEnv *env, jclass _clazz, jmethodID methodID,
                                 va_list args) {
   BEGIN_JNI_EXCEPTION
   
+  // Local object references.
+  JavaObject* clazz = *(JavaObject**)_clazz;
+  
   JavaMethod* meth = (JavaMethod*)methodID;
   Jnjvm* vm = JavaThread::get()->getJVM();
   UserClass* cl = getClassFromStaticMethod(vm, meth, clazz);
-  return (jdouble)meth->invokeDoubleStaticAP(vm, cl, args);
+  return (jdouble)meth->invokeDoubleStaticAP(vm, cl, args, true);
 
   END_JNI_EXCEPTION
   
@@ -1650,31 +1948,38 @@
 }
 
 
-void CallStaticVoidMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...) {
+void CallStaticVoidMethod(JNIEnv *env, jclass _clazz, jmethodID methodID, ...) {
   
   BEGIN_JNI_EXCEPTION
-
+  
   va_list ap;
   va_start(ap, methodID);
+  
+  // Local object references.
+  JavaObject* clazz = *(JavaObject**)_clazz;
+
   JavaMethod* meth = (JavaMethod*)methodID;
   Jnjvm* vm = JavaThread::get()->getJVM();
   UserClass* cl = getClassFromStaticMethod(vm, meth, clazz);
-  meth->invokeIntStaticAP(vm, cl, ap);
+  meth->invokeIntStaticAP(vm, cl, ap, true);
   va_end(ap);
 
   END_JNI_EXCEPTION
 }
 
 
-void CallStaticVoidMethodV(JNIEnv *env, jclass clazz, jmethodID methodID,
+void CallStaticVoidMethodV(JNIEnv *env, jclass _clazz, jmethodID methodID,
                            va_list args) {
   
   BEGIN_JNI_EXCEPTION
   
+  // Local object references.
+  JavaObject* clazz = *(JavaObject**)_clazz;
+  
   JavaMethod* meth = (JavaMethod*)methodID;
   Jnjvm* vm = JavaThread::get()->getJVM();
   UserClass* cl = getClassFromStaticMethod(vm, meth, clazz);
-  meth->invokeIntStaticAP(vm, cl, args);
+  meth->invokeIntStaticAP(vm, cl, args, true);
 
   END_JNI_EXCEPTION
 }
@@ -1687,14 +1992,16 @@
 }
 
 
-jfieldID GetStaticFieldID(JNIEnv *env, jclass clazz, const char *aname,
+jfieldID GetStaticFieldID(JNIEnv *env, jclass _clazz, const char *aname,
                           const char *sig) {
   
   BEGIN_JNI_EXCEPTION
   
+  // Local object references.
+  JavaObject* clazz = *(JavaObject**)_clazz;
+  
   Jnjvm* vm = JavaThread::get()->getJVM();
-  UserCommonClass* cl = 
-    UserCommonClass::resolvedImplClass(vm, (JavaObject*)clazz, true);
+  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, clazz, true);
   
   if (cl->isClass()) {
     const UTF8* name = cl->classLoader->hashUTF8->lookupAsciiz(aname);
@@ -1713,31 +2020,36 @@
 }
 
 
-jobject GetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID) {
+jobject GetStaticObjectField(JNIEnv *env, jclass _clazz, jfieldID fieldID) {
 
   BEGIN_JNI_EXCEPTION
+  
+  // Local object references.
+  JavaObject* clazz = *(JavaObject**)_clazz;
 
-  Jnjvm* vm = JavaThread::get()->getJVM();
+  JavaThread* th = JavaThread::get();
+  Jnjvm* vm = th->getJVM();
   JavaField* field = (JavaField*)fieldID;
-  UserClass* cl = (UserClass*)
-    UserCommonClass::resolvedImplClass(vm, (JavaObject*)clazz, true);
-  void* Stat = cl->getStaticInstance();
-  return (jobject)field->getObjectField(Stat);
+  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, clazz, true);
+  void* Stat = cl->asClass()->getStaticInstance();
+  return (jobject)th->pushJNIRef(field->getObjectField(Stat));
 
   END_JNI_EXCEPTION
   return 0;
 }
 
 
-jboolean GetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID) {
+jboolean GetStaticBooleanField(JNIEnv *env, jclass _clazz, jfieldID fieldID) {
   
   BEGIN_JNI_EXCEPTION
+  
+  // Local object references.
+  JavaObject* clazz = *(JavaObject**)_clazz;
 
   Jnjvm* vm = JavaThread::get()->getJVM();
   JavaField* field = (JavaField*)fieldID;
-  UserClass* cl = (UserClass*)
-    UserCommonClass::resolvedImplClass(vm, (JavaObject*)clazz, true);
-  void* Stat = cl->getStaticInstance();
+  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, clazz, true);
+  void* Stat = cl->asClass()->getStaticInstance();
   return (jboolean)field->getInt8Field(Stat);
 
   END_JNI_EXCEPTION
@@ -1745,15 +2057,17 @@
 }
 
 
-jbyte GetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID) {
+jbyte GetStaticByteField(JNIEnv *env, jclass _clazz, jfieldID fieldID) {
 
   BEGIN_JNI_EXCEPTION
+  
+  // Local object references.
+  JavaObject* clazz = *(JavaObject**)_clazz;
 
   Jnjvm* vm = JavaThread::get()->getJVM();
   JavaField* field = (JavaField*)fieldID;
-  UserClass* cl = (UserClass*)
-    UserCommonClass::resolvedImplClass(vm, (JavaObject*)clazz, true);
-  void* Stat = cl->getStaticInstance();
+  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, clazz, true);
+  void* Stat = cl->asClass()->getStaticInstance();
   return (jbyte)field->getInt8Field(Stat);
 
   END_JNI_EXCEPTION
@@ -1761,15 +2075,17 @@
 }
 
 
-jchar GetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID) {
+jchar GetStaticCharField(JNIEnv *env, jclass _clazz, jfieldID fieldID) {
 
   BEGIN_JNI_EXCEPTION
 
+  // Local object references.
+  JavaObject* clazz = *(JavaObject**)_clazz;
+  
   Jnjvm* vm = JavaThread::get()->getJVM();
   JavaField* field = (JavaField*)fieldID;
-  UserClass* cl = (UserClass*)
-    UserCommonClass::resolvedImplClass(vm, (JavaObject*)clazz, true);
-  void* Stat = cl->getStaticInstance();
+  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, clazz, true);
+  void* Stat = cl->asClass()->getStaticInstance();
   return (jchar)field->getInt16Field(Stat);
 
   END_JNI_EXCEPTION
@@ -1777,15 +2093,17 @@
 }
 
 
-jshort GetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID) {
+jshort GetStaticShortField(JNIEnv *env, jclass _clazz, jfieldID fieldID) {
 
   BEGIN_JNI_EXCEPTION
 
+  // Local object references.
+  JavaObject* clazz = *(JavaObject**)_clazz;
+  
   Jnjvm* vm = JavaThread::get()->getJVM();
   JavaField* field = (JavaField*)fieldID;
-  UserClass* cl = (UserClass*)
-    UserCommonClass::resolvedImplClass(vm, (JavaObject*)clazz, true);
-  void* Stat = cl->getStaticInstance();
+  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, clazz, true);
+  void* Stat = cl->asClass()->getStaticInstance();
   return (jshort)field->getInt16Field(Stat);
 
   END_JNI_EXCEPTION
@@ -1793,15 +2111,17 @@
 }
 
 
-jint GetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID) {
+jint GetStaticIntField(JNIEnv *env, jclass _clazz, jfieldID fieldID) {
 
   BEGIN_JNI_EXCEPTION
 
+  // Local object references.
+  JavaObject* clazz = *(JavaObject**)_clazz;
+  
   Jnjvm* vm = JavaThread::get()->getJVM();
   JavaField* field = (JavaField*)fieldID;
-  UserClass* cl = (UserClass*)
-    UserCommonClass::resolvedImplClass(vm, (JavaObject*)clazz, true);
-  void* Stat = cl->getStaticInstance();
+  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, clazz, true);
+  void* Stat = cl->asClass()->getStaticInstance();
   return (jint)field->getInt32Field(Stat);
 
   END_JNI_EXCEPTION
@@ -1809,15 +2129,17 @@
 }
 
 
-jlong GetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID) {
+jlong GetStaticLongField(JNIEnv *env, jclass _clazz, jfieldID fieldID) {
 
   BEGIN_JNI_EXCEPTION
+  
+  // Local object references.
+  JavaObject* clazz = *(JavaObject**)_clazz;
 
   Jnjvm* vm = JavaThread::get()->getJVM();
   JavaField* field = (JavaField*)fieldID;
-  UserClass* cl = (UserClass*)
-    UserCommonClass::resolvedImplClass(vm, (JavaObject*)clazz, true);
-  void* Stat = cl->getStaticInstance();
+  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, clazz, true);
+  void* Stat = cl->asClass()->getStaticInstance();
   return (jlong)field->getLongField(Stat);
 
   END_JNI_EXCEPTION
@@ -1825,15 +2147,17 @@
 }
 
 
-jfloat GetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID) {
+jfloat GetStaticFloatField(JNIEnv *env, jclass _clazz, jfieldID fieldID) {
 
   BEGIN_JNI_EXCEPTION
+  
+  // Local object references.
+  JavaObject* clazz = *(JavaObject**)_clazz;
 
   Jnjvm* vm = JavaThread::get()->getJVM();
   JavaField* field = (JavaField*)fieldID;
-  UserClass* cl = (UserClass*)
-    UserCommonClass::resolvedImplClass(vm, (JavaObject*)clazz, true);
-  void* Stat = cl->getStaticInstance();
+  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, clazz, true);
+  void* Stat = cl->asClass()->getStaticInstance();
   return (jfloat)field->getFloatField(Stat);
 
   END_JNI_EXCEPTION
@@ -1841,15 +2165,17 @@
 }
 
 
-jdouble GetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID) {
+jdouble GetStaticDoubleField(JNIEnv *env, jclass _clazz, jfieldID fieldID) {
 
   BEGIN_JNI_EXCEPTION
 
+  // Local object references.
+  JavaObject* clazz = *(JavaObject**)_clazz;
+  
   Jnjvm* vm = JavaThread::get()->getJVM();
   JavaField* field = (JavaField*)fieldID;
-  UserClass* cl = (UserClass*)
-    UserCommonClass::resolvedImplClass(vm, (JavaObject*)clazz, true);
-  void* Stat = cl->getStaticInstance();
+  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, clazz, true);
+  void* Stat = cl->asClass()->getStaticInstance();
   return (jdouble)field->getDoubleField(Stat);
 
   END_JNI_EXCEPTION
@@ -1857,144 +2183,163 @@
 }
 
 
-void SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID,
-                          jobject value) {
+void SetStaticObjectField(JNIEnv *env, jclass _clazz, jfieldID fieldID,
+                          jobject _value) {
 
   BEGIN_JNI_EXCEPTION
+  
+  // Local object references.
+  JavaObject* clazz = *(JavaObject**)_clazz;
+  JavaObject* value = *(JavaObject**)_value;
 
   Jnjvm* vm = JavaThread::get()->getJVM();
   JavaField* field = (JavaField*)fieldID;
-  UserClass* cl = (UserClass*)
-    UserCommonClass::resolvedImplClass(vm, (JavaObject*)clazz, true);
-  void* Stat = cl->getStaticInstance();
-  field->setObjectField(Stat, (JavaObject*)value);
+  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, clazz, true);
+  void* Stat = cl->asClass()->getStaticInstance();
+  field->setObjectField(Stat, value);
   
   END_JNI_EXCEPTION
 }
 
 
-void SetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID,
+void SetStaticBooleanField(JNIEnv *env, jclass _clazz, jfieldID fieldID,
                            jboolean value) {
   
   BEGIN_JNI_EXCEPTION
   
+  // Local object references.
+  JavaObject* clazz = *(JavaObject**)_clazz;
+  
   Jnjvm* vm = JavaThread::get()->getJVM();
   JavaField* field = (JavaField*)fieldID;
-  UserClass* cl = (UserClass*)
-    UserCommonClass::resolvedImplClass(vm, (JavaObject*)clazz, true);
-  void* Stat = cl->getStaticInstance();
+  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, clazz, true);
+  void* Stat = cl->asClass()->getStaticInstance();
   field->setInt8Field(Stat, (uint8)value);
 
   END_JNI_EXCEPTION
 }
 
 
-void SetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID,
+void SetStaticByteField(JNIEnv *env, jclass _clazz, jfieldID fieldID,
                         jbyte value) {
 
   BEGIN_JNI_EXCEPTION
 
+  // Local object references.
+  JavaObject* clazz = *(JavaObject**)_clazz;
+  
   Jnjvm* vm = JavaThread::get()->getJVM();
   JavaField* field = (JavaField*)fieldID;
-  UserClass* cl = (UserClass*)
-    UserCommonClass::resolvedImplClass(vm, (JavaObject*)clazz, true);
-  void* Stat = cl->getStaticInstance();
+  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, clazz, true);
+  void* Stat = cl->asClass()->getStaticInstance();
   field->setInt8Field(Stat, (sint8)value);
 
   END_JNI_EXCEPTION
 }
 
 
-void SetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID,
+void SetStaticCharField(JNIEnv *env, jclass _clazz, jfieldID fieldID,
                         jchar value) {
 
   BEGIN_JNI_EXCEPTION
+  
+  // Local object references.
+  JavaObject* clazz = *(JavaObject**)_clazz;
 
   Jnjvm* vm = JavaThread::get()->getJVM();
   JavaField* field = (JavaField*)fieldID;
-  UserClass* cl = (UserClass*)
-    UserCommonClass::resolvedImplClass(vm, (JavaObject*)clazz, true);
-  void* Stat = cl->getStaticInstance();
+  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, clazz, true);
+  void* Stat = cl->asClass()->getStaticInstance();
   field->setInt16Field(Stat, (uint16)value);
 
   END_JNI_EXCEPTION
 }
 
 
-void SetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID,
+void SetStaticShortField(JNIEnv *env, jclass _clazz, jfieldID fieldID,
                          jshort value) {
 
   BEGIN_JNI_EXCEPTION
+  
+  // Local object references.
+  JavaObject* clazz = *(JavaObject**)_clazz;
 
   Jnjvm* vm = JavaThread::get()->getJVM();
   JavaField* field = (JavaField*)fieldID;
-  UserClass* cl = (UserClass*)
-    UserCommonClass::resolvedImplClass(vm, (JavaObject*)clazz, true);
-  void* Stat = cl->getStaticInstance();
+  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, clazz, true);
+  void* Stat = cl->asClass()->getStaticInstance();
   field->setInt16Field(Stat, (sint16)value);
 
   END_JNI_EXCEPTION
 }
 
 
-void SetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID,
+void SetStaticIntField(JNIEnv *env, jclass _clazz, jfieldID fieldID,
                        jint value) {
 
   BEGIN_JNI_EXCEPTION
+  
+  // Local object references.
+  JavaObject* clazz = *(JavaObject**)_clazz;
 
   Jnjvm* vm = JavaThread::get()->getJVM();
   JavaField* field = (JavaField*)fieldID;
-  UserClass* cl = (UserClass*)
-    UserCommonClass::resolvedImplClass(vm, (JavaObject*)clazz, true);
-  void* Stat = cl->getStaticInstance();
+  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, clazz, true);
+  void* Stat = cl->asClass()->getStaticInstance();
   field->setInt32Field(Stat, (sint32)value);
 
   END_JNI_EXCEPTION
 }
 
 
-void SetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID,
+void SetStaticLongField(JNIEnv *env, jclass _clazz, jfieldID fieldID,
                         jlong value) {
 
   BEGIN_JNI_EXCEPTION
+  
+  // Local object references.
+  JavaObject* clazz = *(JavaObject**)_clazz;
 
   Jnjvm* vm = JavaThread::get()->getJVM();
   JavaField* field = (JavaField*)fieldID;
-  UserClass* cl = (UserClass*)
-    UserCommonClass::resolvedImplClass(vm, (JavaObject*)clazz, true);
-  void* Stat = cl->getStaticInstance();
+  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, clazz, true);
+  void* Stat = cl->asClass()->getStaticInstance();
   field->setLongField(Stat, (sint64)value);
 
   END_JNI_EXCEPTION
 }
 
 
-void SetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID,
+void SetStaticFloatField(JNIEnv *env, jclass _clazz, jfieldID fieldID,
                          jfloat value) {
 
   BEGIN_JNI_EXCEPTION
+  
+  // Local object references.
+  JavaObject* clazz = *(JavaObject**)_clazz;
 
   Jnjvm* vm = JavaThread::get()->getJVM();
   JavaField* field = (JavaField*)fieldID;
-  UserClass* cl = (UserClass*)
-    UserCommonClass::resolvedImplClass(vm, (JavaObject*)clazz, true);
-  void* Stat = cl->getStaticInstance();
+  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, clazz, true);
+  void* Stat = cl->asClass()->getStaticInstance();
   field->setFloatField(Stat, (float)value);
 
   END_JNI_EXCEPTION
 }
 
 
-void SetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID,
+void SetStaticDoubleField(JNIEnv *env, jclass _clazz, jfieldID fieldID,
                           jdouble value) {
 
   BEGIN_JNI_EXCEPTION
+  
+  // Local object references.
+  JavaObject* clazz = *(JavaObject**)_clazz;
 
   Jnjvm* vm = JavaThread::get()->getJVM();
   JavaField* field = (JavaField*)fieldID;
-  UserClass* cl = (UserClass*)
-    UserCommonClass::resolvedImplClass(vm, (JavaObject*)clazz, true);
-  void* Stat = cl->getStaticInstance();
+  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, clazz, true);
+  void* Stat = cl->asClass()->getStaticInstance();
   field->setDoubleField(Stat, (double)value);
 
   END_JNI_EXCEPTION
@@ -2032,8 +2377,9 @@
 
   BEGIN_JNI_EXCEPTION
 
-  Jnjvm* vm = myVM(env);
-  return (jstring)(vm->asciizToStr(bytes));
+  JavaThread* th = JavaThread::get();
+  Jnjvm* vm = th->getJVM();
+  return (jstring)th->pushJNIRef(vm->asciizToStr(bytes));
 
   END_JNI_EXCEPTION
   return 0;
@@ -2047,65 +2393,92 @@
 }
 
 
-const char *GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy) {
+const char *GetStringUTFChars(JNIEnv *env, jstring _string, jboolean *isCopy) {
 
   BEGIN_JNI_EXCEPTION
+  
+  // Local object references.
+  JavaString* string = *(JavaString**)_string;
 
   if (isCopy != 0) (*isCopy) = true;
-  return ((JavaString*)string)->strToAsciiz();
+  return string->strToAsciiz();
 
   END_JNI_EXCEPTION
   return 0;
 }
 
 
-void ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf) {
+void ReleaseStringUTFChars(JNIEnv *env, jstring _string, const char *utf) {
   delete[] utf;
 }
 
 
-jsize GetArrayLength(JNIEnv *env, jarray array) {
+jsize GetArrayLength(JNIEnv *env, jarray _array) {
 
   BEGIN_JNI_EXCEPTION
+  
+  // Local object references.
+  JavaArray* array = *(JavaArray**)_array;
 
-  return ((JavaArray*)array)->size;
+  return array->size;
 
   END_JNI_EXCEPTION
   return 0;
 }
 
 
-jobjectArray NewObjectArray(JNIEnv *env, jsize length, jclass elementClass,
-                            jobject initialElement) {
+jobjectArray NewObjectArray(JNIEnv *env, jsize length, jclass _elementClass,
+                            jobject _initialElement) {
   BEGIN_JNI_EXCEPTION
-  Jnjvm* vm = myVM(env);
+  
+  // Local object references.
+  JavaObject* elementClass = *(JavaObject**)_elementClass;
+  JavaObject* initialElement = _initialElement ? 
+    *(JavaObject**)_initialElement : 0;
+  ArrayObject* res = 0;
+
+  JavaThread* th = JavaThread::get();
+  Jnjvm* vm = th->getJVM();
+
   if (length < 0) vm->negativeArraySizeException(length);
   
-  UserCommonClass* base = 
-    UserCommonClass::resolvedImplClass(vm, (JavaObject*)elementClass, true);
+  UserCommonClass* base =
+    UserCommonClass::resolvedImplClass(vm, elementClass, true);
   JnjvmClassLoader* loader = base->classLoader;
   const UTF8* name = base->getName();
   const UTF8* arrayName = loader->constructArrayName(1, name);
   UserClassArray* array = loader->constructArray(arrayName, base);
-  ArrayObject* res = (ArrayObject*)array->doNew(length, vm);
+  res = (ArrayObject*)array->doNew(length, vm);
+  
   if (initialElement) {
     for (sint32 i = 0; i < length; ++i) {
-      res->elements[i] = (JavaObject*)initialElement;
+      res->elements[i] = initialElement;
     }
   }
-  return (jobjectArray)res;
+  return (jobjectArray)th->pushJNIRef(res);
+
   END_JNI_EXCEPTION
   return 0;
 }
 
 
-jobject GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index) {
+jobject GetObjectArrayElement(JNIEnv *env, jobjectArray _array, jsize index) {
+  
   BEGIN_JNI_EXCEPTION
   
-  ArrayObject* JA = (ArrayObject*)array;
-  if (index >= JA->size)
-    JavaThread::get()->getJVM()->indexOutOfBounds(JA, index);
-  return (jobject)JA->elements[index];
+  // Local object references.
+  ArrayObject* array = *(ArrayObject**)_array;
+  JavaObject* res = 0;
+  
+  JavaThread* th = JavaThread::get();
+  Jnjvm* vm = th->getJVM();
+  
+  if (index >= array->size) vm->indexOutOfBounds(array, index);
+  
+  // Store local refererence.
+  res = array->elements[index];
+  
+  return (jobject)th->pushJNIRef(res);
   
   END_JNI_EXCEPTION
 
@@ -2113,15 +2486,20 @@
 }
 
 
-void SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index,
-                           jobject val) {
+void SetObjectArrayElement(JNIEnv *env, jobjectArray _array, jsize index,
+                           jobject _val) {
   
   BEGIN_JNI_EXCEPTION
   
-  ArrayObject* JA = (ArrayObject*)array;
-  if (index >= JA->size)
-    JavaThread::get()->getJVM()->indexOutOfBounds(JA, index);
-  JA->elements[index] = (JavaObject*)val;
+  // Local object references.
+  ArrayObject* array = *(ArrayObject**)_array;
+  JavaObject* val = *(JavaObject**)_val;
+
+  if (index >= array->size)
+    JavaThread::get()->getJVM()->indexOutOfBounds(array, index);
+  
+  // Store global reference.
+  array->elements[index] = val;
 
   END_JNI_EXCEPTION
 }
@@ -2131,8 +2509,11 @@
   
   BEGIN_JNI_EXCEPTION
   
-  Jnjvm* vm = myVM(env);
-  return (jbooleanArray)vm->upcalls->ArrayOfByte->doNew(len, vm);
+  JavaThread* th = JavaThread::get();
+  Jnjvm* vm = th->getJVM();
+  JavaObject* res = vm->upcalls->ArrayOfBool->doNew(len, vm);
+  return (jbooleanArray)th->pushJNIRef(res);
+
 
   END_JNI_EXCEPTION
   return 0;
@@ -2143,8 +2524,10 @@
   
   BEGIN_JNI_EXCEPTION
 
-  Jnjvm* vm = myVM(env);
-  return (jbyteArray)vm->upcalls->ArrayOfByte->doNew(len, vm);
+  JavaThread* th = JavaThread::get();
+  Jnjvm* vm = th->getJVM();
+  JavaObject* res = vm->upcalls->ArrayOfByte->doNew(len, vm);
+  return (jbyteArray)th->pushJNIRef(res);
 
   END_JNI_EXCEPTION
   return 0;
@@ -2155,8 +2538,10 @@
   
   BEGIN_JNI_EXCEPTION
   
-  Jnjvm* vm = myVM(env);
-  return (jcharArray)vm->upcalls->ArrayOfChar->doNew(len, vm);
+  JavaThread* th = JavaThread::get();
+  Jnjvm* vm = th->getJVM();
+  JavaObject* res = vm->upcalls->ArrayOfChar->doNew(len, vm);
+  return (jcharArray)th->pushJNIRef(res);
 
   END_JNI_EXCEPTION
   return 0;
@@ -2167,8 +2552,10 @@
   
   BEGIN_JNI_EXCEPTION
   
-  Jnjvm* vm = myVM(env);
-  return (jshortArray)vm->upcalls->ArrayOfShort->doNew(len, vm);
+  JavaThread* th = JavaThread::get();
+  Jnjvm* vm = th->getJVM();
+  JavaObject* res = vm->upcalls->ArrayOfShort->doNew(len, vm);
+  return (jshortArray)th->pushJNIRef(res);
 
   END_JNI_EXCEPTION
   return 0;
@@ -2179,8 +2566,10 @@
   
   BEGIN_JNI_EXCEPTION
   
-  Jnjvm* vm = myVM(env);
-  return (jintArray)vm->upcalls->ArrayOfInt->doNew(len, vm);
+  JavaThread* th = JavaThread::get();
+  Jnjvm* vm = th->getJVM();
+  JavaObject* res = vm->upcalls->ArrayOfInt->doNew(len, vm);
+  return (jintArray)th->pushJNIRef(res);
 
   END_JNI_EXCEPTION
   return 0;
@@ -2191,8 +2580,10 @@
   
   BEGIN_JNI_EXCEPTION
   
-  Jnjvm* vm = myVM(env);
-  return (jlongArray)vm->upcalls->ArrayOfLong->doNew(len, vm);
+  JavaThread* th = JavaThread::get();
+  Jnjvm* vm = th->getJVM();
+  JavaObject* res = vm->upcalls->ArrayOfLong->doNew(len, vm);
+  return (jlongArray)th->pushJNIRef(res);
 
   END_JNI_EXCEPTION
   return 0;
@@ -2203,8 +2594,10 @@
   
   BEGIN_JNI_EXCEPTION
   
-  Jnjvm* vm = myVM(env);
-  return (jfloatArray)vm->upcalls->ArrayOfFloat->doNew(len, vm);
+  JavaThread* th = JavaThread::get();
+  Jnjvm* vm = th->getJVM();
+  JavaObject* res = vm->upcalls->ArrayOfFloat->doNew(len, vm);
+  return (jfloatArray)th->pushJNIRef(res);
 
   END_JNI_EXCEPTION
   return 0;
@@ -2215,262 +2608,409 @@
   
   BEGIN_JNI_EXCEPTION
   
-  Jnjvm* vm = myVM(env);
-  return (jdoubleArray)vm->upcalls->ArrayOfDouble->doNew(len, vm);
+  JavaThread* th = JavaThread::get();
+  Jnjvm* vm = th->getJVM();
+  JavaObject* res = vm->upcalls->ArrayOfDouble->doNew(len, vm);
+  return (jdoubleArray)th->pushJNIRef(res);
 
   END_JNI_EXCEPTION
   return 0;
 }
 
 
-jboolean *GetBooleanArrayElements(JNIEnv *env, jbooleanArray array,
-				  jboolean *isCopy) {
+jboolean* GetBooleanArrayElements(JNIEnv *env, jbooleanArray _array,
+				                          jboolean *isCopy) {
   
   BEGIN_JNI_EXCEPTION
-  
-  if (isCopy) (*isCopy) = false;
-  return (jboolean*)((ArrayUInt8*)array)->elements;
+ 
+  // Local object references.
+  ArrayUInt8* array = *(ArrayUInt8**)_array;
+
+  if (isCopy) (*isCopy) = true;
+
+  sint32 len = array->size * sizeof(uint8);
+  void* buffer = malloc(len);
+  memcpy(buffer, array->elements, len);
+
+  return (jboolean*)buffer;
 
   END_JNI_EXCEPTION
   return 0;
 }
 
 
-jbyte *GetByteArrayElements(JNIEnv *env, jbyteArray array, jboolean *isCopy) {
+jbyte *GetByteArrayElements(JNIEnv *env, jbyteArray _array, jboolean *isCopy) {
 
   BEGIN_JNI_EXCEPTION
 
-  if (isCopy) (*isCopy) = false;
-  return ((ArraySInt8*)array)->elements;
+  // Local object references.
+  ArraySInt8* array = *(ArraySInt8**)_array;
+
+  if (isCopy) (*isCopy) = true;
+
+  sint32 len = array->size * sizeof(uint8);
+  void* buffer = malloc(len);
+  memcpy(buffer, array->elements, len);
+
+  return (jbyte*)buffer;
 
   END_JNI_EXCEPTION
   return 0;
 }
 
 
-jchar *GetCharArrayElements(JNIEnv *env, jcharArray array, jboolean *isCopy) {
+jchar *GetCharArrayElements(JNIEnv *env, jcharArray _array, jboolean *isCopy) {
 
   BEGIN_JNI_EXCEPTION
+  
+  // Local object references.
+  ArrayUInt16* array = *(ArrayUInt16**)_array;
+
+  if (isCopy) (*isCopy) = true;
+
+  sint32 len = array->size * sizeof(uint16);
+  void* buffer = malloc(len);
+  memcpy(buffer, array->elements, len);
 
-  if (isCopy) (*isCopy) = false;
-  return ((ArrayUInt16*)array)->elements;
+  return (jchar*)buffer;
 
   END_JNI_EXCEPTION
   return 0;
 }
 
 
-jshort *GetShortArrayElements(JNIEnv *env, jshortArray array,
+jshort *GetShortArrayElements(JNIEnv *env, jshortArray _array,
                               jboolean *isCopy) {
   
   BEGIN_JNI_EXCEPTION
   
-  if (isCopy) (*isCopy) = false;
-  return ((ArraySInt16*)array)->elements;
+  // Local object references.
+  ArraySInt16* array = *(ArraySInt16**)_array;
+  
+  if (isCopy) (*isCopy) = true;
+
+  sint32 len = array->size * sizeof(sint16);
+  void* buffer = malloc(len);
+  memcpy(buffer, array->elements, len);
+
+  return (jshort*)buffer;
 
   END_JNI_EXCEPTION
   return 0;
 }
 
 
-jint *GetIntArrayElements(JNIEnv *env, jintArray array, jboolean *isCopy) {
+jint *GetIntArrayElements(JNIEnv *env, jintArray _array, jboolean *isCopy) {
 
   BEGIN_JNI_EXCEPTION
+  
+  // Local object references.
+  ArraySInt32* array = *(ArraySInt32**)_array;
+
+  if (isCopy) (*isCopy) = true;
+
+  sint32 len = array->size * sizeof(sint32);
+  void* buffer = malloc(len);
+  memcpy(buffer, array->elements, len);
 
-  if (isCopy) (*isCopy) = false;
-  return ((ArraySInt32*)array)->elements;
+  return (jint*)buffer;
 
   END_JNI_EXCEPTION
   return 0;
 }
 
 
-jlong *GetLongArrayElements(JNIEnv *env, jlongArray array, jboolean *isCopy) {
+jlong *GetLongArrayElements(JNIEnv *env, jlongArray _array, jboolean *isCopy) {
 
   BEGIN_JNI_EXCEPTION
+  
+  // Local object references.
+  ArrayLong* array = *(ArrayLong**)_array;
+
+  if (isCopy) (*isCopy) = true;
+
+  sint32 len = array->size * sizeof(sint64);
+  void* buffer = malloc(len);
+  memcpy(buffer, array->elements, len);
 
-  if (isCopy) (*isCopy) = false;
-  return (jlong*)(void*)(((ArrayLong*)array)->elements);
+  return (jlong*)buffer;
 
   END_JNI_EXCEPTION
   return 0;
 }
 
 
-jfloat *GetFloatArrayElements(JNIEnv *env, jfloatArray array,
+jfloat *GetFloatArrayElements(JNIEnv *env, jfloatArray _array,
                               jboolean *isCopy) {
 
   BEGIN_JNI_EXCEPTION
+  
+  // Local object references.
+  ArrayFloat* array = *(ArrayFloat**)_array;
+
+  if (isCopy) (*isCopy) = true;
 
-  if (isCopy) (*isCopy) = false;
-  return ((ArrayFloat*)array)->elements;
+  sint32 len = array->size * sizeof(float);
+  void* buffer = malloc(len);
+  memcpy(buffer, array->elements, len);
+
+  return (jfloat*)buffer;
 
   END_JNI_EXCEPTION
   return 0;
 }
 
 
-jdouble *GetDoubleArrayElements(JNIEnv *env, jdoubleArray array,
+jdouble *GetDoubleArrayElements(JNIEnv *env, jdoubleArray _array,
 				jboolean *isCopy) {
   
   BEGIN_JNI_EXCEPTION
   
-  if (isCopy) (*isCopy) = false;
-  return ((ArrayDouble*)array)->elements;
+  // Local object references.
+  ArrayDouble* array = *(ArrayDouble**)_array;
+  
+  if (isCopy) (*isCopy) = true;
+
+  sint32 len = array->size * sizeof(double);
+  void* buffer = malloc(len);
+  memcpy(buffer, array->elements, len);
+
+  return (jdouble*)buffer;
 
   END_JNI_EXCEPTION
   return 0;
 }
 
 
-void ReleaseBooleanArrayElements(JNIEnv *env, jbooleanArray array,
+void ReleaseBooleanArrayElements(JNIEnv *env, jbooleanArray _array,
 				 jboolean *elems, jint mode) {
+  if (mode == JNI_ABORT) {
+    free(elems);
+  } else {
+    JavaArray* array = *(JavaArray**)_array;
+
+    sint32 len = array->size;
+    memcpy(array->elements, elems, len);
+
+    if (mode == 0) free(elems);
+  }
 }
 
 
-void ReleaseByteArrayElements(JNIEnv *env, jbyteArray array, jbyte *elems,
+void ReleaseByteArrayElements(JNIEnv *env, jbyteArray _array, jbyte *elems,
 			      jint mode) {
+  if (mode == JNI_ABORT) {
+    free(elems);
+  } else {
+    JavaArray* array = *(JavaArray**)_array;
+
+    sint32 len = array->size;
+    memcpy(array->elements, elems, len);
+
+    if (mode == 0) free(elems);
+  }
 }
 
 
-void ReleaseCharArrayElements(JNIEnv *env, jcharArray array, jchar *elems,
+void ReleaseCharArrayElements(JNIEnv *env, jcharArray _array, jchar *elems,
 			      jint mode) {
+  if (mode == JNI_ABORT) {
+    free(elems);
+  } else {
+    JavaArray* array = *(JavaArray**)_array;
+
+    sint32 len = array->size << 1;
+    memcpy(array->elements, elems, len);
+
+    if (mode == 0) free(elems);
+  }
 }
 
 
-void ReleaseShortArrayElements(JNIEnv *env, jshortArray array, jshort *elems,
+void ReleaseShortArrayElements(JNIEnv *env, jshortArray _array, jshort *elems,
 			       jint mode) {
+  if (mode == JNI_ABORT) {
+    free(elems);
+  } else {
+    JavaArray* array = *(JavaArray**)_array;
+
+    sint32 len = array->size << 1;
+    memcpy(array->elements, elems, len);
+
+    if (mode == 0) free(elems);
+  }
 }
 
 
-void ReleaseIntArrayElements(JNIEnv *env, jintArray array, jint *elems,
+void ReleaseIntArrayElements(JNIEnv *env, jintArray _array, jint *elems,
 			     jint mode) {
+  if (mode == JNI_ABORT) {
+    free(elems);
+  } else {
+    JavaArray* array = *(JavaArray**)_array;
+
+    sint32 len = array->size << 2;
+    memcpy(array->elements, elems, len);
+
+    if (mode == 0) free(elems);
+  }
 }
 
 
-void ReleaseLongArrayElements(JNIEnv *env, jlongArray array, jlong *elems,
+void ReleaseLongArrayElements(JNIEnv *env, jlongArray _array, jlong *elems,
 			      jint mode) {
+  if (mode == JNI_ABORT) {
+    free(elems);
+  } else {
+    JavaArray* array = *(JavaArray**)_array;
+
+    sint32 len = array->size << 3;
+    memcpy(array->elements, elems, len);
+
+    if (mode == 0) free(elems);
+  }
 }
 
 
-void ReleaseFloatArrayElements(JNIEnv *env, jfloatArray array, jfloat *elems,
+void ReleaseFloatArrayElements(JNIEnv *env, jfloatArray _array, jfloat *elems,
 			       jint mode) {
+  if (mode == JNI_ABORT) {
+    free(elems);
+  } else {
+    JavaArray* array = *(JavaArray**)_array;
+
+    sint32 len = array->size << 2;
+    memcpy(array->elements, elems, len);
+
+    if (mode == 0) free(elems);
+  }
 }
 
 
-void ReleaseDoubleArrayElements(JNIEnv *env, jdoubleArray array,
+void ReleaseDoubleArrayElements(JNIEnv *env, jdoubleArray _array,
 				jdouble *elems, jint mode) {
+  if (mode == JNI_ABORT) {
+    free(elems);
+  } else {
+    JavaArray* array = *(JavaArray**)_array;
+
+    sint32 len = array->size << 3;
+    memcpy(array->elements, elems, len);
+
+    if (mode == 0) free(elems);
+  }
 }
 
 
 void GetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start,
 			   jsize len, jboolean *buf) {
-  ArrayUInt8* Array = (ArrayUInt8*)array;
+  ArrayUInt8* Array = *(ArrayUInt8**)array;
   memcpy(buf, &(Array->elements[start]), len * sizeof(uint8));
 }
 
 
 void GetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len,
 			jbyte *buf) {
-  ArraySInt8* Array = (ArraySInt8*)array;
+  ArraySInt8* Array = *(ArraySInt8**)array;
   memcpy(buf, &(Array->elements[start]), len * sizeof(sint8));
 }
 
 
 void GetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len,
 			jchar *buf) {
-  ArrayUInt16* Array = (ArrayUInt16*)array;
+  ArrayUInt16* Array = *(ArrayUInt16**)array;
   memcpy(buf, &(Array->elements[start]), len * sizeof(uint16));
 }
 
 
 void GetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
 			 jsize len, jshort *buf) {
-  ArraySInt16* Array = (ArraySInt16*)array;
+  ArraySInt16* Array = *(ArraySInt16**)array;
   memcpy(buf, &(Array->elements[start]), len * sizeof(sint16));
 }
 
 
 void GetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len,
 		       jint *buf) {
-  ArraySInt32* Array = (ArraySInt32*)array;
+  ArraySInt32* Array = *(ArraySInt32**)array;
   memcpy(buf, &(Array->elements[start]), len * sizeof(sint32));
 }
 
 
 void GetLongArrayRegion(JNIEnv *env, jlongArray array, jsize start, jsize len,
 		        jlong *buf) {
-  ArrayLong* Array = (ArrayLong*)array;
+  ArrayLong* Array = *(ArrayLong**)array;
   memcpy(buf, &(Array->elements[start]), len * sizeof(sint64));
 }
 
 
 void GetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
 			 jsize len, jfloat *buf) {
-  ArrayFloat* Array = (ArrayFloat*)array;
+  ArrayFloat* Array = *(ArrayFloat**)array;
   memcpy(buf, &(Array->elements[start]), len * sizeof(float));
 }
 
 
 void GetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
 			  jsize len, jdouble *buf) {
-  ArrayDouble* Array = (ArrayDouble*)array;
+  ArrayDouble* Array = *(ArrayDouble**)array;
   memcpy(buf, &(Array->elements[start]), len * sizeof(double));
 }
 
 
 void SetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start,
 			   jsize len, const jboolean *buf) {
-  ArrayUInt8* Array = (ArrayUInt8*)array;
+  ArrayUInt8* Array = *(ArrayUInt8**)array;
   memcpy(&(Array->elements[start]), buf, len * sizeof(uint8));
 }
 
 
 void SetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len,
 			                  const jbyte *buf) {
-  ArraySInt8* Array = (ArraySInt8*)array;
+  abort();
+  ArraySInt8* Array = *(ArraySInt8**)array;
   memcpy(&(Array->elements[start]), buf, len * sizeof(sint8));
 }
 
 
 void SetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len,
 			                  const jchar *buf) {
-  ArrayUInt16* Array = (ArrayUInt16*)array;
+  ArrayUInt16* Array = *(ArrayUInt16**)array;
   memcpy(&(Array->elements[start]), buf, len * sizeof(uint16));
 }
 
 
 void SetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
 			                   jsize len, const jshort *buf) {
-  ArraySInt16* Array = (ArraySInt16*)array;
+  ArraySInt16* Array = *(ArraySInt16**)array;
   memcpy(&(Array->elements[start]), buf, len * sizeof(sint16));
 }
 
 
 void SetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len,
 		                   const jint *buf) {
-  ArraySInt32* Array = (ArraySInt32*)array;
+  ArraySInt32* Array = *(ArraySInt32**)array;
   memcpy(&(Array->elements[start]), buf, len * sizeof(sint32));
 }
 
 
 void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len,
 			                  const jlong *buf) {
-  ArrayLong* Array = (ArrayLong*)array;
+  ArrayLong* Array = *(ArrayLong**)array;
   memcpy(&(Array->elements[start]), buf, len * sizeof(sint64));
 }
 
 
 void SetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
 			                   jsize len, const jfloat *buf) {
-  ArrayFloat* Array = (ArrayFloat*)array;
+  ArrayFloat* Array = *(ArrayFloat**)array;
   memcpy(&(Array->elements[start]), buf, len * sizeof(float));
 }
 
 
 void SetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
 			                    jsize len, const jdouble *buf) {
-  ArrayDouble* Array = (ArrayDouble*)array;
+  ArrayDouble* Array = *(ArrayDouble**)array;
   memcpy(&(Array->elements[start]), buf, len * sizeof(double));
 }
 
@@ -2489,12 +3029,14 @@
   return 0;
 }
 
-jint MonitorEnter(JNIEnv *env, jobject obj) {
+jint MonitorEnter(JNIEnv *env, jobject _obj) {
   
   BEGIN_JNI_EXCEPTION
   
-  if (obj) {
-    ((JavaObject*)obj)->acquire();
+  JavaObject* Obj = *(JavaObject**)_obj;
+  
+  if (Obj) {
+    Obj->acquire();
     return 0;
   } else {
     return -1;
@@ -2506,11 +3048,11 @@
 }
 
 
-jint MonitorExit(JNIEnv *env, jobject obj) {
+jint MonitorExit(JNIEnv *env, jobject _obj) {
 
   BEGIN_JNI_EXCEPTION
 
-  JavaObject* Obj = (JavaObject*)obj;
+  JavaObject* Obj = *(JavaObject**)_obj;
  
   if (Obj) {
 
@@ -2553,19 +3095,40 @@
 }
 
 
-void *GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy) {
+void *GetPrimitiveArrayCritical(JNIEnv *env, jarray _array, jboolean *isCopy) {
   BEGIN_JNI_EXCEPTION
   
-  if (isCopy) (*isCopy) = false;
-  return ((JavaArray*)array)->elements;
+  JavaArray* array = *(JavaArray**)_array;
+
+  if (isCopy) (*isCopy) = true;
+
+  UserClassArray* cl = array->getClass()->asArrayClass();
+  uint32 logSize = cl->baseClass()->asPrimitiveClass()->logSize;
+  sint32 len = array->size << logSize;
+  void* buffer = malloc(len);
+  memcpy(buffer, array->elements, len);
+
+  return (jchar*)buffer;
 
   END_JNI_EXCEPTION
   return 0;
 }
 
 
-void ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray,
+void ReleasePrimitiveArrayCritical(JNIEnv *env, jarray _array, void *carray,
 				   jint mode) {
+  if (mode == JNI_ABORT) {
+    free(carray);
+  } else {
+    JavaArray* array = *(JavaArray**)_array;
+
+    UserClassArray* cl = array->getClass()->asArrayClass();
+    uint32 logSize = cl->baseClass()->asPrimitiveClass()->logSize;
+    sint32 len = array->size << logSize;
+    memcpy(array->elements, carray, len);
+
+    if (mode == 0) free(carray);
+  }
 }
 
 
@@ -2596,25 +3159,30 @@
 
 
 jobject NewGlobalRef(JNIEnv* env, jobject obj) {
-  Jnjvm* vm = myVM(env);
-  vm->globalRefsLock.lock();
-  vm->globalRefs.push_back((JavaObject*)obj);
-  vm->globalRefsLock.unlock();
-  return obj;
+  
+  // Local object references.
+  if (obj) {
+    JavaObject* Obj = *(JavaObject**)obj;
+
+    Jnjvm* vm = JavaThread::get()->getJVM();
+
+
+    vm->globalRefsLock.lock();
+    JavaObject** res = vm->globalRefs.addJNIReference(Obj);
+    vm->globalRefsLock.unlock();
+
+    return (jobject)res;
+  } else {
+    return 0;
+  }
 }
 
 
 void DeleteGlobalRef(JNIEnv* env, jobject globalRef) {
+  
   Jnjvm* vm = myVM(env);
   vm->globalRefsLock.lock();
-  for (std::vector<JavaObject*, gc_allocator<JavaObject*> >::iterator i =
-                                                      vm->globalRefs.begin(),
-            e = vm->globalRefs.end(); i!= e; ++i) {
-    if ((*i) == (JavaObject*)globalRef) {
-      vm->globalRefs.erase(i);
-      break;
-    }
-  }
+  vm->globalRefs.removeJNIReference((JavaObject**)globalRef);
   vm->globalRefsLock.unlock();
 }
 
@@ -2649,7 +3217,7 @@
                                                         (uint32)capacity,
                                                         (uint32)capacity, 0);
 
-  return (jobject)res;
+  return (jobject)th->pushJNIRef(res);
   
   END_JNI_EXCEPTION
   
@@ -2660,9 +3228,11 @@
 void *GetDirectBufferAddress(JNIEnv *env, jobject _buf) {
 
   BEGIN_JNI_EXCEPTION
+ 
+  // Local object references.
+  JavaObject* buf = *(JavaObject**)_buf;
 
   Jnjvm* vm = myVM(env);
-  JavaObject* buf = (JavaObject*)_buf;
   JavaObject* address = vm->upcalls->bufferAddress->getObjectField(buf);
   if (address != 0) {
 #if (__WORDSIZE == 32)

Modified: vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp?rev=76369&r1=76368&r2=76369&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp Sun Jul 19 11:38:58 2009
@@ -673,6 +673,12 @@
   return getDelegatee();
 }
 
+JavaObject* const* UserCommonClass::getClassDelegateePtr(Jnjvm* vm, JavaObject* pd) {
+  // Make sure it's created.
+  getClassDelegatee(vm, pd);
+  return getDelegateePtr();
+}
+
 #define PATH_MANIFEST "META-INF/MANIFEST.MF"
 #define MAIN_CLASS "Main-Class: "
 #define MAIN_LOWER_CLASS "Main-class: "

Modified: vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h?rev=76369&r1=76368&r2=76369&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h Sun Jul 19 11:38:58 2009
@@ -21,6 +21,7 @@
 #include "mvm/Threads/Locks.h"
 
 #include "JnjvmConfig.h"
+#include "JNIReferences.h"
 #include "LockedMap.h"
 
 namespace jnjvm {
@@ -221,7 +222,7 @@
 
   /// globalRefs - Global references that JNI wants to protect.
   ///
-  std::vector<JavaObject*, gc_allocator<JavaObject*> > globalRefs;
+  JNIGlobalReferences globalRefs;
 
   /// globalRefsLock - Lock for adding a new global reference.
   ///

Modified: vmkit/trunk/lib/JnJVM/VMCore/VirtualTables.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/VirtualTables.cpp?rev=76369&r1=76368&r2=76369&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/VirtualTables.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/VirtualTables.cpp Sun Jul 19 11:38:58 2009
@@ -265,9 +265,13 @@
   
   if (appClassLoader) appClassLoader->getJavaClassLoader()->markAndTrace();
   
-  for (std::vector<JavaObject*, gc_allocator<JavaObject*> >::iterator 
-       i = globalRefs.begin(), e = globalRefs.end(); i!= e; ++i) {
-    (*i)->markAndTrace(); 
+  JNIGlobalReferences* start = &globalRefs;
+  while (start) {
+    for (uint32 i = 0; i < start->length; ++i) {
+      JavaObject* obj = start->globalReferences[i];
+      obj->markAndTrace(); 
+    }
+    start = start->next;
   }
   
   for (StringMap::iterator i = hashStr.map.begin(), e = hashStr.map.end();
@@ -291,4 +295,13 @@
 #ifdef SERVICE
   ServiceException->markAndTrace();
 #endif
+  
+  JNILocalReferences* end = localJNIRefs;
+  while (end) {
+    for (uint32 i = 0; i < end->length; ++i) {
+      JavaObject* obj = end->localReferences[i];
+      obj->markAndTrace(); 
+    }
+    end = end->prev;
+  }
 }

Modified: vmkit/trunk/lib/Mvm/CommonThread/Sigsegv.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/Mvm/CommonThread/Sigsegv.cpp?rev=76369&r1=76368&r2=76369&view=diff

==============================================================================
--- vmkit/trunk/lib/Mvm/CommonThread/Sigsegv.cpp (original)
+++ vmkit/trunk/lib/Mvm/CommonThread/Sigsegv.cpp Sun Jul 19 11:38:58 2009
@@ -57,6 +57,7 @@
     fprintf(stderr, "I received a SIGSEGV: either the VM code or an external\n"
                     "native method is bogus. Aborting...\n");
   }
+  th->printBacktraceAfterSignal();
   abort();
   
 #if defined(__i386__)





More information about the vmkit-commits mailing list