Almost good to go :)<br><br><div class="gmail_quote">On Mon, Nov 7, 2011 at 3:50 AM, Will Dietz <span dir="ltr"><<a href="mailto:wdietz2@illinois.edu">wdietz2@illinois.edu</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div class="im">On Fri, Nov 4, 2011 at 4:06 PM, Nicolas Geoffray<br>
<<a href="mailto:nicolas.geoffray@gmail.com">nicolas.geoffray@gmail.com</a>> wrote:<br>
> Thanks Will for the new change. I have a few comments that I'd like you to<br>
> take into account before moving forward.<br>
</div>[snip]<br>
<br>
Thank you for your comments!  Updated patch inlined below :).<br>
<br>
~Will<br>
<br>
>From 64c05c78614b4036e40dc915926f590b82f60966 Mon Sep 17 00:00:00 2001<br>
<div class="im">From: Will Dietz <<a href="mailto:w@wdtz.org">w@wdtz.org</a>><br>
Date: Fri, 14 Oct 2011 06:07:15 -0500<br>
</div>Subject: [PATCH 6/8] Implement a number of Java.sun.misc.Unsafe.* methods.<br>
<div class="im"><br>
Of particular interest is the addition of VMStaticInstance, used to<br>
enable us to return a reference to a static instance, even though a<br>
static instance isn't a heap object (and prevents the underlying<br>
static instance from being GC'd while this reference is live).<br>
<br>
This is required for us to support staticFieldBase/staticFieldOffset.<br>
---<br>
</div> lib/J3/ClassLib/Classpath.inc       |  195 ++++++++++++++++++++++++++++++++++-<br>
 lib/J3/ClassLib/VMStaticInstance.h  |   82 +++++++++++++++<br>
 lib/J3/Compiler/JavaAOTCompiler.cpp |    5 +-<br>
 lib/J3/Compiler/Makefile            |    2 +-<br>
 lib/J3/VMCore/Jnjvm.cpp             |    5 +<br>
<div class="im"> lib/J3/VMCore/Makefile              |    2 +-<br>
 lib/J3/VMCore/VirtualTables.cpp     |   11 ++-<br>
</div> 7 files changed, 296 insertions(+), 6 deletions(-)<br>
<div class="im"> create mode 100644 lib/J3/ClassLib/VMStaticInstance.h<br>
<br>
diff --git a/lib/J3/ClassLib/Classpath.inc b/lib/J3/ClassLib/Classpath.inc<br>
</div>index ccb9607..c81e26b 100644<br>
<div><div class="h5">--- a/lib/J3/ClassLib/Classpath.inc<br>
+++ b/lib/J3/ClassLib/Classpath.inc<br>
@@ -15,12 +15,23 @@<br>
 #include "JavaThread.h"<br>
 #include "JavaUpcalls.h"<br>
 #include "Jnjvm.h"<br>
+#include "Reader.h"<br>
+#include "VMStaticInstance.h"<br>
<br>
<br>
 using namespace j3;<br>
<br>
 extern "C" {<br>
<br>
+// Convert a 'base' JavaObject to its pointer representation.<br>
+// Handles our special VMStaticInstance wrapper.<br>
+static inline uint8 *baseToPtr(JavaObject *base) {<br>
+  if (VMStaticInstance::isVMStaticInstance(base))<br>
+    return (uint8*)((VMStaticInstance*)base)->getStaticInstance();<br>
+  else<br>
+    return (uint8*)base;<br>
+}<br>
+<br>
 // Define hasClassInitializer because of a buggy implementation in Classpath.<br>
 JNIEXPORT bool JNICALL Java_java_io_VMObjectStreamClass_hasClassInitializer(<br>
 #ifdef NATIVE_JNI<br>
@@ -359,6 +370,186 @@ JavaObject* unsafe, JavaObject* obj, jlong<br>
offset, JavaObject* value) {<br>
   mvm::Collector::objectReferenceWriteBarrier((gc*)obj, (gc**)ptr, (gc*)value);<br>
 }<br>
<br>
+JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_allocateMemory(<br>
+JavaObject* unsafe, jlong size) {<br>
+  // TODO: Invalid size/OOM/etc handling!<br>
+  jlong res = 0;<br>
+  BEGIN_NATIVE_EXCEPTION(0)<br>
+  res = (jlong)malloc(size);<br>
+  END_NATIVE_EXCEPTION<br>
+  return res;<br>
+}<br>
+<br>
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_freeMemory(<br>
+JavaObject* unsafe, jlong ptr) {<br>
+  // TODO: Exception handling...<br>
+  BEGIN_NATIVE_EXCEPTION(0)<br>
+  free((void*)ptr);<br>
+  END_NATIVE_EXCEPTION<br>
+}<br>
+<br>
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putLong__JJ(<br>
+JavaObject* unsafe, jlong ptr, jlong value) {<br>
+  BEGIN_NATIVE_EXCEPTION(0)<br>
+  *(jlong*)ptr = value;<br>
+  END_NATIVE_EXCEPTION<br>
+}<br>
+<br>
+JNIEXPORT jbyte JNICALL Java_sun_misc_Unsafe_getByte__J(<br>
+JavaObject* unsafe, jlong ptr) {<br>
+  jbyte res = 0;<br>
+  BEGIN_NATIVE_EXCEPTION(0)<br>
+  res =  *(jbyte*)ptr;<br>
+  END_NATIVE_EXCEPTION<br>
+<br>
+  return res;<br>
+}<br>
+<br>
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_ensureClassInitialized(<br>
+JavaObject* unsafe, JavaObject* clazz) {<br>
+  llvm_gcroot(unsafe, 0);<br>
+  llvm_gcroot(clazz, 0);<br>
+  BEGIN_NATIVE_EXCEPTION(0)<br>
+<br>
+  Jnjvm* vm = JavaThread::get()->getJVM();<br>
+<br>
+  CommonClass * cl = JavaObject::getClass(clazz);<br>
+  assert(cl && cl->isClass());<br>
</div></div>+  cl->asClass()->resolveClass();<br>
<div><div class="h5">+  cl->asClass()->initialiseClass(vm);<br>
+<br>
+  END_NATIVE_EXCEPTION;<br>
+}<br>
+<br>
+JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_staticFieldOffset(<br>
+JavaObject* unsafe, JavaObjectField* _field) {<br>
+  llvm_gcroot(unsafe, 0);<br>
+  llvm_gcroot(_field, 0);<br>
+<br>
+  jlong res = 0;<br>
+  BEGIN_NATIVE_EXCEPTION(0)<br>
+<br>
+  JavaField * field = JavaObjectField::getInternalField(_field);<br>
+  assert(field);<br>
+<br>
+  res = field->ptrOffset;<br>
+<br>
+  END_NATIVE_EXCEPTION;<br>
+<br>
+  return res;<br>
+}<br>
+<br>
+JNIEXPORT JavaObject* JNICALL Java_sun_misc_Unsafe_staticFieldBase(<br>
+JavaObject* unsafe, JavaObjectField* _field) {<br>
</div></div><div class="im">+  JavaObject* res = 0;<br>
+  llvm_gcroot(unsafe, 0);<br>
</div>+  llvm_gcroot(_field, 0);<br>
+  llvm_gcroot(res, 0);<br>
<div class="im">+  BEGIN_NATIVE_EXCEPTION(0)<br>
+<br>
+  JavaField * field = JavaObjectField::getInternalField(_field);<br>
+  assert(field);<br>
+  field->classDef->initialiseClass(JavaThread::get()->getJVM());<br>
+<br>
</div>+  res = VMStaticInstance::allocate(<br>
+    (JavaObjectClass*)field->classDef->getDelegatee());<br>
<div class="im">+<br>
+  END_NATIVE_EXCEPTION;<br>
+<br>
+  return res;<br>
+}<br>
+<br>
+JNIEXPORT JavaObject* JNICALL Java_sun_misc_Unsafe_getObjectVolatile(<br>
+JavaObject* unsafe, JavaObject* base, jlong offset) {<br>
+  JavaObject * res = 0;<br>
+  llvm_gcroot(unsafe, 0);<br>
+  llvm_gcroot(base, 0);<br>
+  llvm_gcroot(res, 0);<br>
+<br>
+  BEGIN_NATIVE_EXCEPTION(0)<br>
+  JavaObject** ptr = (JavaObject**) (baseToPtr(base) + offset);<br>
+  res = *ptr;<br>
+  END_NATIVE_EXCEPTION;<br>
+<br>
+  return res;<br>
+}<br>
+<br>
+JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_arrayBaseOffset(<br>
+JavaObject* unsafe, JavaObject* clazz) {<br>
</div>+  UNIMPLEMENTED();<br>
<div class="im">+  return 0;<br>
+}<br>
+<br>
+JNIEXPORT jlong JNICALL Java_sun_misc_Unsafe_arrayIndexScale(<br>
+#ifdef NATIVE_JNI<br>
+JNIEnv *env,<br>
+#endif<br>
+JavaObject* unsafe, JavaObject* clazz) {<br>
</div>+  UNIMPLEMENTED();<br>
<div><div class="h5">+  return 0;<br>
+}<br>
+<br>
+JNIEXPORT JavaObject* JNICALL<br>
Java_sun_misc_Unsafe_defineClass__Ljava_lang_String_2_3BIILjava_lang_ClassLoader_2Ljava_security_ProtectionDomain_2(<br>
+JavaObject* unsafe, JavaString *name, ArrayObject * bytesArr, jint<br>
off, jint len, JavaObject * loader, JavaObject * pd) {<br>
+  JavaObject* res = 0;<br>
+  llvm_gcroot(res, 0);<br>
+  llvm_gcroot(unsafe, 0);<br>
+  llvm_gcroot(name, 0);<br>
+  llvm_gcroot(bytesArr, 0);<br>
+  llvm_gcroot(loader, 0);<br>
+  llvm_gcroot(pd, 0);<br>
+  BEGIN_NATIVE_EXCEPTION(0)<br>
+<br>
+  Jnjvm* vm = JavaThread::get()->getJVM();<br>
+  JnjvmClassLoader* JCL = NULL;<br>
+  JCL = JnjvmClassLoader::getJnjvmLoaderFromJavaObject(loader, vm);<br>
+<br>
+  jint last = off + len;<br>
+  if (last < bytesArr->size) {<br>
+    assert(0 && "What exception to throw here?");<br>
+  }<br>
+  ClassBytes * bytes = new (JCL->allocator, len) ClassBytes(len);<br>
+  memcpy(bytes->elements, JavaArray::getElements(bytesArr)+off, len);<br>
+  const UTF8* utfName = JavaString::javaToInternal(name, JCL->hashUTF8);<br>
+  UserClass *cl = JCL->constructClass(utfName, bytes);<br>
+<br>
+  if (cl) res = (JavaObject*)cl->getClassDelegatee(vm);<br>
+<br>
+  END_NATIVE_EXCEPTION;<br>
+<br>
+  return res;<br>
+}<br>
+<br>
+JNIEXPORT JavaObject* JNICALL<br>
Java_sun_misc_Unsafe_allocateInstance__Ljava_lang_Class_2(<br>
+JavaObject* unsafe, JavaObjectClass * clazz) {<br>
+  JavaObject* res = 0;<br>
+  llvm_gcroot(unsafe, 0);<br>
+  llvm_gcroot(clazz, 0);<br>
+  llvm_gcroot(res, 0);<br>
+<br>
+  BEGIN_NATIVE_EXCEPTION(0)<br>
+<br>
+  JavaThread* th = JavaThread::get();<br>
+  Jnjvm* vm = th->getJVM();<br>
+<br>
+  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, clazz, true);<br>
+  if (cl->isClass())<br>
+    res = cl->asClass()->doNew(vm);<br>
+<br>
+  END_NATIVE_EXCEPTION;<br>
+<br>
+  return res;<br>
+}<br>
+<br>
+<br>
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_throwException(<br>
+JavaObject* unsafe, JavaObject * obj) {<br>
+  llvm_gcroot(unsafe, 0);<br>
+  llvm_gcroot(obj, 0);<br>
+<br>
</div></div>+  JavaThread::get()->throwException(obj);<br>
<div><div class="h5">+}<br>
+<br>
 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_registerNatives(JavaObject*) {<br>
   // Nothing<br>
 }<br>
@@ -369,7 +560,7 @@ JNIEXPORT jtype JNICALL Java_sun_misc_Unsafe_get<br>
## Type ## __Ljava_lang_Object_<br>
 JavaObject* unsafe, JavaObject* base, jlong offset) { \<br>
   jtype res = 0; \<br>
   BEGIN_NATIVE_EXCEPTION(0) \<br>
-  jtype* ptr = (jtype*) (((uint8 *) base) + offset); \<br>
+  jtype* ptr = (jtype*) (baseToPtr(base) + offset); \<br>
   res = *ptr; \<br>
   END_NATIVE_EXCEPTION \<br>
  \<br>
@@ -379,7 +570,7 @@ JavaObject* unsafe, JavaObject* base, jlong offset) { \<br>
 JNIEXPORT void JNICALL Java_sun_misc_Unsafe_put ## Type ##<br>
__Ljava_lang_Object_2J ## shorttype( \<br>
 JavaObject* unsafe, JavaObject* base, jlong offset, jtype val) { \<br>
   BEGIN_NATIVE_EXCEPTION(0) \<br>
-  jtype* ptr = (jtype*) (((uint8 *) base) + offset); \<br>
+  jtype* ptr = (jtype*) (baseToPtr(base) + offset); \<br>
   *ptr = val; \<br>
   END_NATIVE_EXCEPTION \<br>
 }<br>
diff --git a/lib/J3/ClassLib/VMStaticInstance.h<br>
b/lib/J3/ClassLib/VMStaticInstance.h<br>
new file mode 100644<br>
</div></div>index 0000000..f2ca906<br>
--- /dev/null<br>
+++ b/lib/J3/ClassLib/VMStaticInstance.h<br>
@@ -0,0 +1,82 @@<br>
<div class="im">+//===-------- VMStaticInstance.h - Java wrapper for a static<br>
instance------===//<br>
+//<br>
+//                            The VMKit project<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#ifndef JNJVM_VMSTATICINSTANCE_H<br>
+#define JNJVM_VMSTATICINSTANCE_H<br>
+<br>
</div>+#include "ClasspathReflect.h"<br>
+#include "JavaObject.h"<br>
+#include "MvmGC.h"<br>
+<br>
+namespace j3 {<br>
+<br>
+/// VMStaticInstance - Used as a placeholder for a staticInstance, tracing to<br>
+/// the corresponding Class to ensure it doesn't get improperly GC'd.<br>
+/// This placeholder is used solely in getStaticFieldBase and the various<br>
+/// put/get methods in sun.misc.Unsafe, any other use is invalid.<br>
<div class="im">+/// Largely inspired by VMClassLoader.<br>
+///<br>
+class VMStaticInstance : public JavaObject {<br>
+private:<br>
+<br>
</div>+  /// OwningClass - The Class this is represents a static instance of.<br>
+  JavaObjectClass * OwningClass;<br></blockquote><div><br></div><div>You should use the Class* instead of the JavaObjectClass. This makes it less brittle for the GC.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">

+<br>
+public:<br>
+<br>
+  static VMStaticInstance* allocate(JavaObjectClass * Class) {<br>
<div class="im">+    VMStaticInstance* res = 0;<br>
+    llvm_gcroot(res, 0);<br>
</div>+    llvm_gcroot(Class, 0);<br>
<div class="im">+    res = (VMStaticInstance*)gc::operator new(sizeof(VMStaticInstance), &VT);<br>
</div>+    res->OwningClass = Class;<br>
<div class="im">+<br>
+    return res;<br>
+  }<br>
+<br>
</div><div class="im">+  /// VT - The VirtualTable for this GC-class.<br>
+  ///<br>
+  static VirtualTable VT;<br>
+<br>
+  /// Is the object a VMStaticInstance object?<br>
+  ///<br>
+  static bool isVMStaticInstance(JavaObject* obj) {<br>
+    llvm_gcroot(obj, 0);<br>
+    return obj->getVirtualTable() == &VT;<br>
+  }<br>
+<br>
+  /// ~VMStaticInstance - Nothing. Placeholder method<br>
+  /// to give the VirtualTable.<br>
+  ///<br>
+  static void staticDestructor(VMStaticInstance* obj) {<br>
+    llvm_gcroot(obj, 0);<br>
+    // Nothing to do here<br>
+  }<br>
+<br>
</div>+  /// staticTracer - Trace through to our Class<br>
<div class="im">+  ///<br>
+  static void staticTracer(VMStaticInstance* obj, word_t closure) {<br>
+    llvm_gcroot(obj, 0);<br>
</div>+    if (obj->OwningClass != NULL) obj->OwningClass->tracer(closure);<br></blockquote><div><br></div><div>That's a bug if it's null. Maybe assert that it's not. Also, by replacing OwningClass to a Class*, you should do obj->OwningClass->JCL->tracer(closure);</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div class="im">+  }<br>
+<br>
+  /// getStaticInstance - Get the static instance contained in this object<br>
+  ///<br>
+  void * getStaticInstance() {<br></div></blockquote><div><br></div><div>Just change it to OwningClass->getStaticInstance();</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div class="im">
</div>+    assert(OwningClass);<br>
+    UserCommonClass * Cl = JavaObjectClass::getClass(OwningClass);<br>
+    assert(Cl && Cl->isClass());<br>
+    return Cl->asClass()->getStaticInstance();<br>
<div class="im">+  }<br>
+<br>
+};<br>
+<br>
+}<br>
+<br>
+#endif // JNJVM_VMSTATICINSTANCE_H<br>
</div>diff --git a/lib/J3/Compiler/JavaAOTCompiler.cpp<br>
b/lib/J3/Compiler/JavaAOTCompiler.cpp<br>
index d16d57c..1a4d2e4 100644<br>
--- a/lib/J3/Compiler/JavaAOTCompiler.cpp<br>
+++ b/lib/J3/Compiler/JavaAOTCompiler.cpp<br>
@@ -32,6 +32,7 @@<br>
 #include "JavaUpcalls.h"<br>
 #include "Jnjvm.h"<br>
 #include "Reader.h"<br>
+#include "VMStaticInstance.h"<br>
 #include "Zip.h"<br>
<br>
 #include <cstdio><br>
@@ -2545,7 +2546,9 @@ CommonClass*<br>
JavaAOTCompiler::getUniqueBaseClass(CommonClass* cl) {<br>
<br>
   for (; I != E; ++I) {<br>
     JavaObject* obj = (JavaObject*)(*I);<br>
-    if (!VMClassLoader::isVMClassLoader(obj) &&<br>
JavaObject::instanceOf(obj, cl)) {<br>
+    if (!VMClassLoader::isVMClassLoader(obj) &&<br>
+        !VMStaticInstance::isVMStaticInstance(obj) &&<br>
+        JavaObject::instanceOf(obj, cl)) {<br>
       if (currentClass != NULL) {<br>
         if (JavaObject::getClass(obj) != currentClass) {<br>
           return 0;<br>
diff --git a/lib/J3/Compiler/Makefile b/lib/J3/Compiler/Makefile<br>
index 58bb2e1..99c46db 100644<br>
--- a/lib/J3/Compiler/Makefile<br>
+++ b/lib/J3/Compiler/Makefile<br>
@@ -14,4 +14,4 @@ MODULE_WITH_GC = J3Compiler<br>
<br>
 include $(LEVEL)/Makefile.common<br>
<br>
-CXX.Flags += -I$(PROJ_OBJ_DIR)/../LLVMRuntime<br>
-I$(PROJ_SRC_DIR)/../ClassLib/$(CLASSPATH_DIR)<br>
-I$(PROJ_SRC_DIR)/../VMCore<br>
+CXX.Flags += -I$(PROJ_OBJ_DIR)/../LLVMRuntime<br>
-I$(PROJ_SRC_DIR)/../ClassLib/$(CLASSPATH_DIR)<br>
-I$(PROJ_SRC_DIR)/../ClassLib/ -I$(PROJ_SRC_DIR)/../VMCore<br>
diff --git a/lib/J3/VMCore/Jnjvm.cpp b/lib/J3/VMCore/Jnjvm.cpp<br>
index 4961694..5165b88 100644<br>
--- a/lib/J3/VMCore/Jnjvm.cpp<br>
+++ b/lib/J3/VMCore/Jnjvm.cpp<br>
@@ -35,6 +35,7 @@<br>
 #include "LockedMap.h"<br>
 #include "Reader.h"<br>
<div class="im"> #include "ReferenceQueue.h"<br>
+#include "VMStaticInstance.h"<br>
 #include "Zip.h"<br>
<br>
 using namespace j3;<br>
</div>@@ -1394,6 +1395,8 @@ size_t Jnjvm::getObjectSize(gc* object) {<br>
   JavaObject* src = (JavaObject*)object;<br>
   if (VMClassLoader::isVMClassLoader(src)) {<br>
     size = sizeof(VMClassLoader);<br>
+  } else if (VMStaticInstance::isVMStaticInstance(src)) {<br>
+    size = sizeof(VMStaticInstance);<br>
   } else {<br>
     CommonClass* cl = JavaObject::getClass(src);<br>
     if (cl->isArray()) {<br>
@@ -1416,6 +1419,8 @@ const char* Jnjvm::getObjectTypeName(gc* object) {<br>
   JavaObject* src = (JavaObject*)object;<br>
   if (VMClassLoader::isVMClassLoader(src)) {<br>
     return "VMClassLoader";<br>
+  } else if (VMStaticInstance::isVMStaticInstance(src)) {<br>
+    return "VMStaticInstance";<br>
   } else {<br>
     CommonClass* cl = JavaObject::getClass(src);<br>
     // This code is only used for debugging on a fatal error. It is fine to<br>
<div class="HOEnZb"><div class="h5">diff --git a/lib/J3/VMCore/Makefile b/lib/J3/VMCore/Makefile<br>
index fc07061..987919a 100644<br>
--- a/lib/J3/VMCore/Makefile<br>
+++ b/lib/J3/VMCore/Makefile<br>
@@ -14,4 +14,4 @@ MODULE_WITH_GC = J3<br>
<br>
 include $(LEVEL)/Makefile.common<br>
<br>
-CXX.Flags += -I$(PROJ_OBJ_DIR)/../ClassLib<br>
-I$(PROJ_OBJ_DIR)/../LLVMRuntime<br>
-I$(PROJ_SRC_DIR)/../ClassLib/$(CLASSPATH_DIR)<br>
-I$(PROJ_SRC_DIR)/../../../include/j3<br>
+CXX.Flags += -I$(PROJ_OBJ_DIR)/../ClassLib<br>
-I$(PROJ_OBJ_DIR)/../LLVMRuntime<br>
-I$(PROJ_SRC_DIR)/../ClassLib/$(CLASSPATH_DIR)<br>
-I$(PROJ_SRC_DIR)/../../../include/j3 -I$(PROJ_SRC_DIR)/../ClassLib<br>
diff --git a/lib/J3/VMCore/VirtualTables.cpp b/lib/J3/VMCore/VirtualTables.cpp<br>
index 68774b7..6b3b999 100644<br>
--- a/lib/J3/VMCore/VirtualTables.cpp<br>
+++ b/lib/J3/VMCore/VirtualTables.cpp<br>
@@ -32,6 +32,7 @@<br>
 #include "JnjvmClassLoader.h"<br>
 #include "LockedMap.h"<br>
 #include "ReferenceQueue.h"<br>
+#include "VMStaticInstance.h"<br>
 #include "Zip.h"<br>
<br>
 using namespace j3;<br>
@@ -44,7 +45,7 @@ using namespace j3;<br>
 // Having many GC classes gives more work to the GC for the scanning phase<br>
 // and for the relocation phase (for copying collectors).<br>
 //<br>
-// In J3, there is only one internal gc object, the class loader.<br>
+// In J3, there is only one primary internal gc object, the class loader.<br>
 // We decided that this was the best solution because<br>
 // otherwise it would involve hacks on the java.lang.Classloader class.<br>
 // Therefore, we create a new GC class with a finalize method that will<br>
@@ -52,12 +53,20 @@ using namespace j3;<br>
 // not reachable anymore. This also relies on the java.lang.Classloader class<br>
 // referencing an object of type VMClassLoader (this is the case in GNU<br>
 // Classpath with the vmdata field).<br>
+// In addition, to handle support for sun.misc.Unsafe, we have a similar<br>
+// second clsas VMStaticInstance that wraps static instances for use<br>
+// in staticFieldBase and traces the owning ClassLoader to make sure<br>
+// the underlying instance and class don't get GC'd improperly.<br>
 //===----------------------------------------------------------------------===//<br>
<br>
 VirtualTable VMClassLoader::VT((word_t)VMClassLoader::staticDestructor,<br>
                                (word_t)VMClassLoader::staticDestructor,<br>
                                (word_t)VMClassLoader::staticTracer);<br>
<br>
+VirtualTable VMStaticInstance::VT((word_t)VMStaticInstance::staticDestructor,<br>
+                                  (word_t)VMStaticInstance::staticDestructor,<br>
+                                  (word_t)VMStaticInstance::staticTracer);<br>
+<br>
 //===----------------------------------------------------------------------===//<br>
 // Trace methods for Java objects. There are four types of objects:<br>
 // (1) java.lang.Object and primitive arrays: no need to trace anything.<br>
--<br>
1.7.5.1<br>
</div></div></blockquote></div><br>