[vmkit-commits] [vmkit] r180349 - Moved VirtualTable getter/setter to JavaObject so now Type is accessed threw the VirtualMachine.

Peter Senna Tschudin peter.senna at gmail.com
Thu Apr 25 10:02:15 PDT 2013


Author: peter.senna
Date: Thu Apr 25 12:00:19 2013
New Revision: 180349

URL: http://llvm.org/viewvc/llvm-project?rev=180349&view=rev
Log:
Moved VirtualTable getter/setter to JavaObject so now Type is accessed threw the VirtualMachine.
Made ReferenceQueue generic with template class, have to put implementation in a separated file in vmkit folder.
(cherry picked from commit 06f4e14e863db720daf75f18bc47a752af7b8ab1)

Modified:
    vmkit/trunk/include/vmkit/GC.h
    vmkit/trunk/include/vmkit/VirtualMachine.h
    vmkit/trunk/lib/j3/VMCore/JavaObject.h
    vmkit/trunk/lib/j3/VMCore/JavaThread.cpp
    vmkit/trunk/lib/j3/VMCore/JavaThread.h
    vmkit/trunk/lib/j3/VMCore/Jnjvm.cpp
    vmkit/trunk/lib/j3/VMCore/Jnjvm.h
    vmkit/trunk/lib/j3/VMCore/ReferenceQueue.cpp
    vmkit/trunk/lib/j3/VMCore/ReferenceQueue.h
    vmkit/trunk/lib/vmkit/MMTk/VmkitGC.cpp
    vmkit/trunk/lib/vmkit/MMTk/VmkitGC.h
    vmkit/trunk/mmtk/mmtk-alloc/Selected.cpp
    vmkit/trunk/mmtk/mmtk-j3/ObjectModel.cpp

Modified: vmkit/trunk/include/vmkit/GC.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/vmkit/GC.h?rev=180349&r1=180348&r2=180349&view=diff
==============================================================================
--- vmkit/trunk/include/vmkit/GC.h (original)
+++ vmkit/trunk/include/vmkit/GC.h Thu Apr 25 12:00:19 2013
@@ -28,25 +28,25 @@ public:
 
 class gcRoot {
 	private:
+  /// getVirtualTable - Returns the virtual table of this object.
+  ///
+//  VirtualTable* getVirtualTable() const {
+//    return ((VirtualTable**)(this))[0];
+//  }
+  
+  /// setVirtualTable - Sets the virtual table of this object.
+  ///
+//  void setVirtualTable(VirtualTable* VT) {
+//    ((VirtualTable**)(this))[0] = VT;
+//  }
 public:
   virtual           ~gcRoot() {}
   virtual void      tracer(word_t closure) {}
 
   word_t& header(){return toHeader()->_header; }
-  
+
   inline gcHeader* toHeader() { return (gcHeader*)((uintptr_t)this - gcHeader::hiddenHeaderSize()); }
 
-  /// getVirtualTable - Returns the virtual table of this object.
-  ///
-  VirtualTable* getVirtualTable() const {
-    return ((VirtualTable**)(this))[0];
-  }
-  
-  /// setVirtualTable - Sets the virtual table of this object.
-  ///
-  void setVirtualTable(VirtualTable* VT) {
-    ((VirtualTable**)(this))[0] = VT;
-  }
 };
 
 namespace vmkit {

Modified: vmkit/trunk/include/vmkit/VirtualMachine.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/vmkit/VirtualMachine.h?rev=180349&r1=180348&r2=180349&view=diff
==============================================================================
--- vmkit/trunk/include/vmkit/VirtualMachine.h (original)
+++ vmkit/trunk/include/vmkit/VirtualMachine.h Thu Apr 25 12:00:19 2013
@@ -188,6 +188,10 @@ public:
   ///
   virtual void addFinalizationCandidate(gc* object) {}
 
+  /// finalizeObject - Called by the finalizer thread for objects finalization.
+  ///
+  virtual void finalizeObject(gc* res) {}
+
   /// tracer - Trace this virtual machine's GC-objects.
   ///
   virtual void tracer(word_t closure) {}
@@ -199,7 +203,11 @@ public:
   /// setType - Method called when allocating an object. The VirtualMachine has to
   /// set the identity of the object (identity is determined by user).
   ///
-  virtual void setType(gcHeader* header, void* type) = 0;
+  virtual void setType(gc* header, void* type) = 0;
+
+  /// getType - Gets the type of given object.
+  ///
+  virtual void* getType(gc* header) = 0;
 
   /// getObjectSize - Get the size of this object. Used by copying collectors.
   ///
@@ -219,6 +227,15 @@ public:
 #endif
 
 //===----------------------------------------------------------------------===//
+// (2.5) GC-DEBUG-related methods.
+//===----------------------------------------------------------------------===//
+
+  /// isCorruptedType - Return true if object is corrupted.
+  ///
+  virtual bool isCorruptedType(gc* header) { return false; }
+
+
+//===----------------------------------------------------------------------===//
 // (3) Backtrace-related methods.
 //===----------------------------------------------------------------------===//
 
@@ -246,7 +263,34 @@ public:
 
   virtual void nullPointerException() = 0;
   virtual void stackOverflowError() = 0;
+
+//===----------------------------------------------------------------------===//
+// (6) ReferenceQueue-related methods (if used).
+//     You have to create a class which inherits from specialized ReferenceThread class.
+//  			e.g: class MyReferenceThread : public ReferenceThread<YourThread> (see ReferenceQueue.h)
+//
+//     Then once thread has been started you can enqueue references and the reference thread
+//     delegates enqueuing process to the virtual machine threw the following methods.
+//===----------------------------------------------------------------------===//
+
+  /// invokeEnqueueReference - This method is called whenever an object is enqueued in
+  /// Soft, Weak or Phantom reference queues.
+  ///
+  virtual void invokeEnqueueReference(gc* ref) {}
+
+  /// clearObjectReferent - Clears object's referent
+  ///
+  virtual void clearObjectReferent(gc* ref) {}
+
+  /// getObjectReferentPtr - returns object referent's pointer
+  ///
+  virtual gc** getObjectReferentPtr(gc* _obj) { abort(); return NULL; }
+
+  /// setObjectReferent - set the referent of an object
+  ///
+  virtual void setObjectReferent(gc* _obj, gc* val) {}
 };
 
+
 } // end namespace vmkit
 #endif // VMKIT_VIRTUALMACHINE_H

Modified: vmkit/trunk/lib/j3/VMCore/JavaObject.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/j3/VMCore/JavaObject.h?rev=180349&r1=180348&r2=180349&view=diff
==============================================================================
--- vmkit/trunk/lib/j3/VMCore/JavaObject.h (original)
+++ vmkit/trunk/lib/j3/VMCore/JavaObject.h Thu Apr 25 12:00:19 2013
@@ -237,6 +237,18 @@ private:
   
 public:
 
+  /// getVirtualTable - Returns the java virtual table of this object.
+  ///
+  JavaVirtualTable* getVirtualTable() const {
+    return ((JavaVirtualTable**)(this))[0];
+  }
+
+  /// setVirtualTable - Sets the java virtual table of this object.
+  ///
+  void setVirtualTable(JavaVirtualTable* VT) {
+    ((JavaVirtualTable**)(this))[0] = VT;
+  }
+
   /// getClass - Returns the class of this object.
   ///
   static UserCommonClass* getClass(const JavaObject* self) {

Modified: vmkit/trunk/lib/j3/VMCore/JavaThread.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/j3/VMCore/JavaThread.cpp?rev=180349&r1=180348&r2=180349&view=diff
==============================================================================
--- vmkit/trunk/lib/j3/VMCore/JavaThread.cpp (original)
+++ vmkit/trunk/lib/j3/VMCore/JavaThread.cpp Thu Apr 25 12:00:19 2013
@@ -23,10 +23,10 @@
 using namespace j3;
 using namespace std;
 
-JavaThread::JavaThread(Jnjvm* isolate) : MutatorThread() { 
+JavaThread::JavaThread(vmkit::VirtualMachine* isolate) : MutatorThread() {
   MyVM = isolate;
   pendingException = NULL;
-  jniEnv = isolate->jniEnv;
+  jniEnv = ((Jnjvm*)isolate)->jniEnv;
   localJNIRefs = new JNILocalReferences();
   currentAddedReferences = NULL;
   javaThread = NULL;

Modified: vmkit/trunk/lib/j3/VMCore/JavaThread.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/j3/VMCore/JavaThread.h?rev=180349&r1=180348&r2=180349&view=diff
==============================================================================
--- vmkit/trunk/lib/j3/VMCore/JavaThread.h (original)
+++ vmkit/trunk/lib/j3/VMCore/JavaThread.h Thu Apr 25 12:00:19 2013
@@ -119,7 +119,7 @@ public:
   
   /// JavaThread - Creates a Java thread.
   ///
-  JavaThread(Jnjvm* isolate);
+  JavaThread(vmkit::VirtualMachine* isolate);
 
   void initialise(JavaObject* thread, JavaObject* vmth);
   

Modified: vmkit/trunk/lib/j3/VMCore/Jnjvm.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/j3/VMCore/Jnjvm.cpp?rev=180349&r1=180348&r2=180349&view=diff
==============================================================================
--- vmkit/trunk/lib/j3/VMCore/Jnjvm.cpp (original)
+++ vmkit/trunk/lib/j3/VMCore/Jnjvm.cpp Thu Apr 25 12:00:19 2013
@@ -1075,9 +1075,9 @@ void Jnjvm::loadBootstrap() {
   finalizerThread->start(
       (void (*)(vmkit::Thread*))FinalizerThread::finalizerStart);
     
-  referenceThread = new ReferenceThread(this);
+  referenceThread = new JavaReferenceThread(this);
   referenceThread->start(
-      (void (*)(vmkit::Thread*))ReferenceThread::enqueueStart);
+      (void (*)(vmkit::Thread*))JavaReferenceThread::enqueueStart);
   
   // Initialise the bootstrap class loader if it's not
   // done already.
@@ -1378,23 +1378,86 @@ void Jnjvm::scanFinalizationQueue(word_t
 }
 
 void Jnjvm::addFinalizationCandidate(gc* object) {
-  llvm_gcroot(object, 0);
-  if (object->getVirtualTable()->hasDestructor())
-  	finalizerThread->addFinalizationCandidate(object);
+	JavaObject* src = 0;
+	llvm_gcroot(object, 0);
+	llvm_gcroot(src, 0);
+  src = (JavaObject*)object;
+  if (src->getVirtualTable()->hasDestructor())
+  	finalizerThread->addFinalizationCandidate(src);
+}
+
+/*
+ * PUT THIS INTO A SEPARATED FILE
+ */
+
+typedef void (*destructor_t)(void*);
+
+void invokeFinalizer(gc* _obj) {
+  Jnjvm* vm = JavaThread::get()->getJVM();
+  JavaObject* obj = (JavaObject*)_obj;
+  llvm_gcroot(obj, 0);
+  JavaMethod* meth = vm->upcalls->FinalizeObject;
+  UserClass* cl = JavaObject::getClass(obj)->asClass();
+  meth->invokeIntVirtualBuf(vm, cl, obj, 0);
+}
+
+void invokeFinalize(gc* res) {
+  llvm_gcroot(res, 0);
+  TRY {
+    invokeFinalizer(res);
+  } IGNORE;
+  vmkit::Thread::get()->clearException();
+}
+
+/*
+ *
+ */
+
+void Jnjvm::finalizeObject(gc* object) {
+	JavaObject* res = 0;
+	llvm_gcroot(object, 0);
+	llvm_gcroot(res, 0);
+	res = (JavaObject*) object;
+  JavaVirtualTable* VT = res->getVirtualTable();
+  if (VT->operatorDelete) {
+    destructor_t dest = (destructor_t)VT->destructor;
+    dest(res);
+  } else {
+    invokeFinalize(res);
+  }
+}
+
+void Jnjvm::setType(gc* header, void* type) {
+	JavaObject* src = 0;
+	llvm_gcroot(src, 0);
+	llvm_gcroot(header, 0);
+	src = (JavaObject*) header;
+	src->setVirtualTable((JavaVirtualTable*)type);
 }
 
-void Jnjvm::setType(gcHeader* header, void* type) {
-	header->toReference()->setVirtualTable((VirtualTable*)type);
+void* Jnjvm::getType(gc* header) {
+	JavaObject* src = 0;
+	llvm_gcroot(src, 0);
+	llvm_gcroot(header, 0);
+	src = (JavaObject*) header;
+	return src->getVirtualTable();
 }
 
 // This method is called during GC so no llvm_gcroot needed.
-void Jnjvm::traceObject(gc* obj, word_t closure) {
+void Jnjvm::traceObject(gc* _obj, word_t closure) {
+	JavaObject* obj = 0;
+	obj = (JavaObject*)_obj;
   assert(obj && "No object to trace");
   assert(obj->getVirtualTable() && "No virtual table");
   assert(obj->getVirtualTable()->tracer && "No tracer in VT");
   obj->tracer(closure);
 }
 
+// This method is called during GC so no llvm_gcroot needed.
+bool Jnjvm::isCorruptedType(gc* obj) {
+	return ((JavaObject*)obj)->getVirtualTable();
+}
+
 size_t Jnjvm::getObjectSize(gc* object) {
   // TODO: because this is called during GC, there is no need to do
   // llvm_gcroot. For clarity, it may be useful to have a special type

Modified: vmkit/trunk/lib/j3/VMCore/Jnjvm.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/j3/VMCore/Jnjvm.h?rev=180349&r1=180348&r2=180349&view=diff
==============================================================================
--- vmkit/trunk/lib/j3/VMCore/Jnjvm.h (original)
+++ vmkit/trunk/lib/j3/VMCore/Jnjvm.h Thu Apr 25 12:00:19 2013
@@ -41,7 +41,7 @@ class JavaThread;
 class JavaVirtualTable;
 class JnjvmBootstrapLoader;
 class JnjvmClassLoader;
-class ReferenceThread;
+class JavaReferenceThread;
 class UserClass;
 class UserClassArray;
 class UserClassPrimitive;
@@ -121,7 +121,7 @@ private:
  
   /// enqueueThread - The thread that enqueue Java references.
   ///
-  ReferenceThread* referenceThread;
+  JavaReferenceThread* referenceThread;
 
   virtual void startCollection();
   virtual void endCollection();
@@ -130,12 +130,18 @@ private:
   virtual void scanPhantomReferencesQueue(word_t closure);
   virtual void scanFinalizationQueue(word_t closure);
   virtual void addFinalizationCandidate(gc* obj);
+  virtual void finalizeObject(gc* res);
   virtual void traceObject(gc* obj, word_t closure);
-  virtual void setType(gcHeader* header, void* type);
+  virtual void setType(gc* header, void* type);
+  virtual void* getType(gc* obj);
   virtual size_t getObjectSize(gc* obj);
   virtual const char* getObjectTypeName(gc* obj);
+  virtual bool isCorruptedType(gc* header);
   virtual void printMethod(vmkit::FrameInfo* FI, word_t ip, word_t addr);
-
+  virtual void invokeEnqueueReference(gc* res);
+  virtual void clearObjectReferent(gc* ref);
+  virtual gc** getObjectReferentPtr(gc* _obj);
+  virtual void setObjectReferent(gc* _obj, gc* val);
 
   /// CreateError - Creates a Java object of the specified exception class
   /// and calling its <init> function.
@@ -317,11 +323,11 @@ public:
   
   /// setReferenceThread - Set the enqueue thread of this VM.
   ///
-  void setReferenceThread(ReferenceThread* th) { referenceThread = th; }
+  void setReferenceThread(JavaReferenceThread* th) { referenceThread = th; }
   
   /// getReferenceThread - Get the enqueue thread of this VM.
   ///
-  ReferenceThread* getReferenceThread() const { return referenceThread; }
+  JavaReferenceThread* getReferenceThread() const { return referenceThread; }
 
   /// ~Jnjvm - Destroy the JVM.
   ///

Modified: vmkit/trunk/lib/j3/VMCore/ReferenceQueue.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/j3/VMCore/ReferenceQueue.cpp?rev=180349&r1=180348&r2=180349&view=diff
==============================================================================
--- vmkit/trunk/lib/j3/VMCore/ReferenceQueue.cpp (original)
+++ vmkit/trunk/lib/j3/VMCore/ReferenceQueue.cpp Thu Apr 25 12:00:19 2013
@@ -15,17 +15,6 @@
 
 using namespace j3;
 
-ReferenceThread::ReferenceThread(Jnjvm* vm) : JavaThread(vm),
-    WeakReferencesQueue(ReferenceQueue::WEAK),
-    SoftReferencesQueue(ReferenceQueue::SOFT), 
-    PhantomReferencesQueue(ReferenceQueue::PHANTOM) {
-
-  ToEnqueue = new gc*[INITIAL_QUEUE_SIZE];
-  ToEnqueueLength = INITIAL_QUEUE_SIZE;
-  ToEnqueueIndex = 0;
-}
-
-
 bool enqueueReference(gc* _obj) {
   Jnjvm* vm = JavaThread::get()->getJVM();
   JavaObject* obj = (JavaObject*)_obj;
@@ -35,7 +24,7 @@ bool enqueueReference(gc* _obj) {
   return (bool)meth->invokeIntSpecialBuf(vm, cl, obj, 0);
 }
 
-void invokeEnqueue(gc* res) {
+void Jnjvm::invokeEnqueueReference(gc* res) {
   llvm_gcroot(res, 0);
   TRY {
     enqueueReference(res);
@@ -43,119 +32,25 @@ void invokeEnqueue(gc* res) {
   vmkit::Thread::get()->clearException();
 }
 
-void ReferenceThread::enqueueStart(ReferenceThread* th) {
-  gc* res = NULL;
-  llvm_gcroot(res, 0);
-
-  while (true) {
-    th->EnqueueLock.lock();
-    while (th->ToEnqueueIndex == 0) {
-      th->EnqueueCond.wait(&th->EnqueueLock);
-    }
-    th->EnqueueLock.unlock();
-
-    while (true) {
-      th->ToEnqueueLock.acquire();
-      if (th->ToEnqueueIndex != 0) {
-        res = th->ToEnqueue[th->ToEnqueueIndex - 1];
-        --th->ToEnqueueIndex;
-      }
-      th->ToEnqueueLock.release();
-      if (!res) break;
-
-      invokeEnqueue(res);
-      res = NULL;
-    }
-  }
-}
-
-
-void ReferenceThread::addToEnqueue(gc* obj) {
-  llvm_gcroot(obj, 0);
-  if (ToEnqueueIndex >= ToEnqueueLength) {
-    uint32 newLength = ToEnqueueLength * GROW_FACTOR;
-    gc** newQueue = new gc*[newLength];
-    if (!newQueue) {
-      fprintf(stderr, "I don't know how to handle reference overflow yet!\n");
-      abort();
-    }   
-    for (uint32 i = 0; i < ToEnqueueLength; ++i) {
-      newQueue[i] = ToEnqueue[i];
-    }   
-    delete[] ToEnqueue;
-    ToEnqueue = newQueue;
-    ToEnqueueLength = newLength;
-  }
-  ToEnqueue[ToEnqueueIndex++] = obj;
-}
-
-gc** getReferentPtr(gc* _obj) {
+gc** Jnjvm::getObjectReferentPtr(gc* _obj) {
   JavaObjectReference* obj = (JavaObjectReference*)_obj;
   llvm_gcroot(obj, 0);
   return (gc**)JavaObjectReference::getReferentPtr(obj);
 }
 
-void setReferent(gc* _obj, gc* val) {
+void Jnjvm::setObjectReferent(gc* _obj, gc* val) {
   JavaObjectReference* obj = (JavaObjectReference*)_obj;
   llvm_gcroot(obj, 0);
   llvm_gcroot(val, 0);
   JavaObjectReference::setReferent(obj, (JavaObject*)val);
 }
  
-void clearReferent(gc* _obj) {
+void Jnjvm::clearObjectReferent(gc* _obj) {
   JavaObjectReference* obj = (JavaObjectReference*)_obj;
   llvm_gcroot(obj, 0);
   JavaObjectReference::setReferent(obj, NULL);
 }
 
-gc* ReferenceQueue::processReference(gc* reference, ReferenceThread* th, word_t closure) {
-  if (!vmkit::Collector::isLive(reference, closure)) {
-    clearReferent(reference);
-    return NULL;
-  }
-
-  gc* referent = *(getReferentPtr(reference));
-
-  if (!referent) {
-    return NULL;
-  }
-
-  if (semantics == SOFT) {
-    // TODO: are we are out of memory? Consider that we always are for now.
-    if (false) {
-      vmkit::Collector::retainReferent(referent, closure);
-    }
-  } else if (semantics == PHANTOM) {
-    // Nothing to do.
-  }
-
-  gc* newReference =
-      vmkit::Collector::getForwardedReference(reference, closure);
-  if (vmkit::Collector::isLive(referent, closure)) {
-    gc* newReferent = vmkit::Collector::getForwardedReferent(referent, closure);
-    setReferent(newReference, newReferent);
-    return newReference;
-  } else {
-    clearReferent(newReference);
-    th->addToEnqueue(newReference);
-    return NULL;
-  }
-}
-
-
-void ReferenceQueue::scan(ReferenceThread* th, word_t closure) {
-  uint32 NewIndex = 0;
-
-  for (uint32 i = 0; i < CurrentIndex; ++i) {
-    gc* obj = References[i];
-    gc* res = processReference(obj, th, closure);
-    if (res) References[NewIndex++] = res;
-  }
-
-  CurrentIndex = NewIndex;
-}
-
-
 FinalizerThread::FinalizerThread(Jnjvm* vm) : JavaThread(vm) {
   FinalizationQueue = new gc*[INITIAL_QUEUE_SIZE];
   QueueLength = INITIAL_QUEUE_SIZE;
@@ -231,24 +126,6 @@ void FinalizerThread::scanFinalizationQu
   CurrentIndex = NewIndex;
 }
 
-typedef void (*destructor_t)(void*);
-
-void invokeFinalizer(gc* _obj) {
-  Jnjvm* vm = JavaThread::get()->getJVM();
-  JavaObject* obj = (JavaObject*)_obj;
-  llvm_gcroot(obj, 0);
-  JavaMethod* meth = vm->upcalls->FinalizeObject;
-  UserClass* cl = JavaObject::getClass(obj)->asClass();
-  meth->invokeIntVirtualBuf(vm, cl, obj, 0);
-}
-
-void invokeFinalize(gc* res) {
-  llvm_gcroot(res, 0);
-  TRY {
-    invokeFinalizer(res);
-  } IGNORE;
-  vmkit::Thread::get()->clearException();
-}
 
 void FinalizerThread::finalizerStart(FinalizerThread* th) {
   gc* res = NULL;
@@ -270,13 +147,8 @@ void FinalizerThread::finalizerStart(Fin
       th->FinalizationQueueLock.release();
       if (!res) break;
 
-      VirtualTable* VT = res->getVirtualTable();
-      if (VT->operatorDelete) {
-        destructor_t dest = (destructor_t)VT->destructor;
-        dest(res);
-      } else {
-        invokeFinalize(res);
-      }
+     th->MyVM->finalizeObject(res);
+
       res = NULL;
     }
   }

Modified: vmkit/trunk/lib/j3/VMCore/ReferenceQueue.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/j3/VMCore/ReferenceQueue.h?rev=180349&r1=180348&r2=180349&view=diff
==============================================================================
--- vmkit/trunk/lib/j3/VMCore/ReferenceQueue.h (original)
+++ vmkit/trunk/lib/j3/VMCore/ReferenceQueue.h Thu Apr 25 12:00:19 2013
@@ -20,9 +20,10 @@
 
 namespace j3 {
 
-class ReferenceThread;
+template <class T> class ReferenceThread;
 class Jnjvm;
 
+
 class ReferenceQueue {
 private:
   gc** References;
@@ -31,7 +32,41 @@ private:
   vmkit::SpinLock QueueLock;
   uint8_t semantics;
 
-  gc* processReference(gc*, ReferenceThread*, word_t closure);
+  template <class T>
+  gc* processReference(gc* reference, ReferenceThread<T>* th, word_t closure) {
+    if (!vmkit::Collector::isLive(reference, closure)) {
+      vmkit::Thread::get()->MyVM->clearObjectReferent(reference);
+      return NULL;
+    }
+
+    gc* referent = *(vmkit::Thread::get()->MyVM->getObjectReferentPtr(reference));
+
+    if (!referent) {
+      return NULL;
+    }
+
+    if (semantics == SOFT) {
+      // TODO: are we are out of memory? Consider that we always are for now.
+      if (false) {
+        vmkit::Collector::retainReferent(referent, closure);
+      }
+    } else if (semantics == PHANTOM) {
+      // Nothing to do.
+    }
+
+    gc* newReference =
+        vmkit::Collector::getForwardedReference(reference, closure);
+    if (vmkit::Collector::isLive(referent, closure)) {
+      gc* newReferent = vmkit::Collector::getForwardedReferent(referent, closure);
+      vmkit::Thread::get()->MyVM->setObjectReferent(newReference, newReferent);
+      return newReference;
+    } else {
+    	vmkit::Thread::get()->MyVM->clearObjectReferent(newReference);
+      th->addToEnqueue(newReference);
+      return NULL;
+    }
+  }
+
 public:
 
   static const uint8_t WEAK = 1;
@@ -79,10 +114,22 @@ public:
     QueueLock.release();
   }
 
-  void scan(ReferenceThread* thread, word_t closure);
+  template <class T>
+  void scan(ReferenceThread<T>* thread, word_t closure) {
+    uint32 NewIndex = 0;
+
+    for (uint32 i = 0; i < CurrentIndex; ++i) {
+      gc* obj = References[i];
+      gc* res = processReference(obj, thread, closure);
+      if (res) References[NewIndex++] = res;
+    }
+
+    CurrentIndex = NewIndex;
+  }
+
 };
 
-class ReferenceThread : public JavaThread {
+template <class T_THREAD> class ReferenceThread : public T_THREAD {
 public:
   /// WeakReferencesQueue - The queue of weak references.
   ///
@@ -99,16 +146,57 @@ public:
   gc** ToEnqueue;
   uint32 ToEnqueueLength;
   uint32 ToEnqueueIndex;
-  
+
   /// ToEnqueueLock - A lock to protect access to the queue.
   ///
   vmkit::LockNormal EnqueueLock;
   vmkit::Cond EnqueueCond;
   vmkit::SpinLock ToEnqueueLock;
 
-  void addToEnqueue(gc* obj);
+  static void enqueueStart(ReferenceThread* th){
+    gc* res = NULL;
+    llvm_gcroot(res, 0);
+
+    while (true) {
+      th->EnqueueLock.lock();
+      while (th->ToEnqueueIndex == 0) {
+        th->EnqueueCond.wait(&th->EnqueueLock);
+      }
+      th->EnqueueLock.unlock();
+
+      while (true) {
+        th->ToEnqueueLock.acquire();
+        if (th->ToEnqueueIndex != 0) {
+          res = th->ToEnqueue[th->ToEnqueueIndex - 1];
+          --th->ToEnqueueIndex;
+        }
+        th->ToEnqueueLock.release();
+        if (!res) break;
 
-  static void enqueueStart(ReferenceThread*);
+        vmkit::Thread::get()->MyVM->invokeEnqueueReference(res);
+        res = NULL;
+      }
+    }
+  }
+
+  void addToEnqueue(gc* obj) {
+    llvm_gcroot(obj, 0);
+    if (ToEnqueueIndex >= ToEnqueueLength) {
+      uint32 newLength = ToEnqueueLength * GROW_FACTOR;
+      gc** newQueue = new gc*[newLength];
+      if (!newQueue) {
+        fprintf(stderr, "I don't know how to handle reference overflow yet!\n");
+        abort();
+      }
+      for (uint32 i = 0; i < ToEnqueueLength; ++i) {
+        newQueue[i] = ToEnqueue[i];
+      }
+      delete[] ToEnqueue;
+      ToEnqueue = newQueue;
+      ToEnqueueLength = newLength;
+    }
+    ToEnqueue[ToEnqueueIndex++] = obj;
+  }
 
   /// addWeakReference - Add a weak reference to the queue.
   ///
@@ -116,14 +204,14 @@ public:
     llvm_gcroot(ref, 0);
     WeakReferencesQueue.addReference(ref);
   }
-  
+
   /// addSoftReference - Add a weak reference to the queue.
   ///
   void addSoftReference(gc* ref) {
     llvm_gcroot(ref, 0);
     SoftReferencesQueue.addReference(ref);
   }
-  
+
   /// addPhantomReference - Add a weak reference to the queue.
   ///
   void addPhantomReference(gc* ref) {
@@ -131,16 +219,27 @@ public:
     PhantomReferencesQueue.addReference(ref);
   }
 
-  ReferenceThread(Jnjvm* vm);
+  ReferenceThread(vmkit::VirtualMachine* vm) : T_THREAD(vm), WeakReferencesQueue(ReferenceQueue::WEAK),
+      									SoftReferencesQueue(ReferenceQueue::SOFT),
+      									PhantomReferencesQueue(ReferenceQueue::PHANTOM) {
+    ToEnqueue = new gc*[INITIAL_QUEUE_SIZE];
+    ToEnqueueLength = INITIAL_QUEUE_SIZE;
+    ToEnqueueIndex = 0;
+  }
 
   ~ReferenceThread() {
     delete[] ToEnqueue;
   }
 };
 
+class JavaReferenceThread : public ReferenceThread<JavaThread> {
+public:
+	JavaReferenceThread(Jnjvm* vm) : ReferenceThread<JavaThread>(vm) {}
+};
+
 class FinalizerThread : public JavaThread {
 public:
-    /// FinalizationQueueLock - A lock to protect access to the queue.
+  /// FinalizationQueueLock - A lock to protect access to the queue.
   ///
   vmkit::SpinLock FinalizationQueueLock;
 

Modified: vmkit/trunk/lib/vmkit/MMTk/VmkitGC.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/vmkit/MMTk/VmkitGC.cpp?rev=180349&r1=180348&r2=180349&view=diff
==============================================================================
--- vmkit/trunk/lib/vmkit/MMTk/VmkitGC.cpp (original)
+++ vmkit/trunk/lib/vmkit/MMTk/VmkitGC.cpp Thu Apr 25 12:00:19 2013
@@ -36,7 +36,7 @@ extern "C" void* prealloc(uint32_t sz) {
 }
 
 extern "C" void postalloc(gc* obj, void* type, uint32_t size) {
-	vmkit::Thread::get()->MyVM->setType(obj->toHeader(), type);
+	vmkit::Thread::get()->MyVM->setType(obj, type);
 }
 
 extern "C" void* gcmalloc(uint32_t sz, void* type) {
@@ -53,21 +53,22 @@ extern "C" void* gcmallocUnresolved(uint
 	return res;
 }
 
-extern "C" void addFinalizationCandidate(gc* obj) {
-  vmkit::Thread::get()->MyVM->addFinalizationCandidate(obj);
-}
-
+// Do not insert MagicArray ref to InternalSet of references.
 extern "C" void* AllocateMagicArray(int32_t sz, void* length) {
-	sz += gcHeader::hiddenHeaderSize();
 	gcHeader* head = 0;
   gc* res = 0;
-  head = (gcHeader*)malloc(sz);
-  memset((void*)head, 0, sz);
-  res = head->toReference();
-  res->setVirtualTable((VirtualTable*)length);
+	sz += gcHeader::hiddenHeaderSize();
+	head = (gcHeader*)malloc(sz);
+	memset((void*)head, 0, sz);
+	res = head->toReference();
+	vmkit::Thread::get()->MyVM->setType(res, length);
   return res;
 }
 
+extern "C" void addFinalizationCandidate(gc* obj) {
+  vmkit::Thread::get()->MyVM->addFinalizationCandidate(obj);
+}
+
 void* Collector::begOf(gc* obj) {
   lock.acquire();
   std::set<gc*>::iterator I = __InternalSet__.find(obj);

Modified: vmkit/trunk/lib/vmkit/MMTk/VmkitGC.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/vmkit/MMTk/VmkitGC.h?rev=180349&r1=180348&r2=180349&view=diff
==============================================================================
--- vmkit/trunk/lib/vmkit/MMTk/VmkitGC.h (original)
+++ vmkit/trunk/lib/vmkit/MMTk/VmkitGC.h Thu Apr 25 12:00:19 2013
@@ -65,8 +65,8 @@ public:
     return 0;
   }
 
-  void* operator new(size_t sz, VirtualTable *VT) {
-    return gcmallocUnresolved(sz, VT);
+  void* operator new(size_t sz, void *type) {
+    return gcmallocUnresolved(sz, type);
   }
 };
 

Modified: vmkit/trunk/mmtk/mmtk-alloc/Selected.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/mmtk/mmtk-alloc/Selected.cpp?rev=180349&r1=180348&r2=180349&view=diff
==============================================================================
--- vmkit/trunk/mmtk/mmtk-alloc/Selected.cpp (original)
+++ vmkit/trunk/mmtk/mmtk-alloc/Selected.cpp Thu Apr 25 12:00:19 2013
@@ -63,6 +63,7 @@ extern "C" void* JnJVM_org_j3_bindings_B
 extern "C" void* prealloc(uint32_t size) {
 	gc* res = 0;
   gcHeader* head = 0;
+  llvm_gcroot(res, 0);
   size = llvm::RoundUpToAlignment(size, sizeof(void*));
   head = (gcHeader*) JnJVM_org_j3_bindings_Bindings_prealloc__I(size);
   res = head->toReference();
@@ -70,7 +71,7 @@ extern "C" void* prealloc(uint32_t size)
 }
 
 extern "C" void postalloc(gc* obj, void* type, uint32_t size) {
-	vmkit::Thread::get()->MyVM->setType(obj->toHeader(), type);
+	vmkit::Thread::get()->MyVM->setType(obj, type);
 	JnJVM_org_j3_bindings_Bindings_postalloc__Lorg_vmmagic_unboxed_ObjectReference_2Lorg_vmmagic_unboxed_ObjectReference_2I(obj, type, size);
 }
 
@@ -132,37 +133,25 @@ bool Collector::isLive(gc* ptr, word_t c
 
 void Collector::scanObject(void** ptr, word_t closure) {
   if ((*ptr) != NULL) {
-    assert(((gc*)(*ptr))->getVirtualTable());
+    assert(vmkit::Thread::get()->MyVM->isCorruptedType((gc*)(*ptr)));
   }
-#if RESET_STALE_REFERENCES
-  // Allow the VM to reset references if needed
-  vmkit::Thread::get()->MyVM->resetReferenceIfStale(NULL, ptr);
-#endif
   JnJVM_org_j3_bindings_Bindings_reportDelayedRootEdge__Lorg_mmtk_plan_TraceLocal_2Lorg_vmmagic_unboxed_Address_2(closure, ptr);
 }
  
 void Collector::markAndTrace(void* source, void* ptr, word_t closure) {
   void** ptr_ = (void**)ptr;
   if ((*ptr_) != NULL) {
-    assert(((gc*)(*ptr_))->getVirtualTable());
+    assert(vmkit::Thread::get()->MyVM->isCorruptedType((gc*)(*ptr_)));
   }
-  if ((*(void**)ptr) != NULL) assert(((gc*)(*(void**)ptr))->getVirtualTable());
-#if RESET_STALE_REFERENCES
-  // Allow the VM to reset references if needed
-  vmkit::Thread::get()->MyVM->resetReferenceIfStale(source, ptr_);
-#endif
+  if ((*(void**)ptr) != NULL) assert(vmkit::Thread::get()->MyVM->isCorruptedType((gc*)(*(void**)ptr)));
   JnJVM_org_j3_bindings_Bindings_processEdge__Lorg_mmtk_plan_TransitiveClosure_2Lorg_vmmagic_unboxed_ObjectReference_2Lorg_vmmagic_unboxed_Address_2(closure, source, ptr);
 }
   
-void Collector::markAndTraceRoot(void* source, void* ptr, word_t closure) {
+void Collector::markAndTraceRoot(void* ptr, word_t closure) {
   void** ptr_ = (void**)ptr;
   if ((*ptr_) != NULL) {
-    assert(((gc*)(*ptr_))->getVirtualTable());
+    assert(vmkit::Thread::get()->MyVM->isCorruptedType((gc*)(*ptr_)));
   }
-#if RESET_STALE_REFERENCES
-  // Allow the VM to reset references if needed
-  vmkit::Thread::get()->MyVM->resetReferenceIfStale(source, ptr_);
-#endif
   JnJVM_org_j3_bindings_Bindings_processRootEdge__Lorg_mmtk_plan_TraceLocal_2Lorg_vmmagic_unboxed_Address_2Z(closure, ptr, true);
 }
 
@@ -235,9 +224,9 @@ void Collector::initialise(int argc, cha
   JnJVM_org_j3_bindings_Bindings_boot__Lorg_vmmagic_unboxed_Extent_2Lorg_vmmagic_unboxed_Extent_2_3Ljava_lang_String_2(20 * 1024 * 1024, 100 * 1024 * 1024, arguments);
 }
 
-extern "C" void* MMTkMutatorAllocate(uint32_t size, VirtualTable* VT) {
+extern "C" void* MMTkMutatorAllocate(uint32_t size, void* type) {
   gc* val = (gc*)MutatorThread::get()->Allocator.Allocate(size);
-  val->setVirtualTable(VT);
+  vmkit::Thread::get()->MyVM->setType(val, type);
   return val;
 }
 

Modified: vmkit/trunk/mmtk/mmtk-j3/ObjectModel.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/mmtk/mmtk-j3/ObjectModel.cpp?rev=180349&r1=180348&r2=180349&view=diff
==============================================================================
--- vmkit/trunk/mmtk/mmtk-j3/ObjectModel.cpp (original)
+++ vmkit/trunk/mmtk/mmtk-j3/ObjectModel.cpp Thu Apr 25 12:00:19 2013
@@ -86,7 +86,7 @@ extern "C" void Java_org_j3_bindings_Bin
 
 
 extern "C" word_t JnJVM_org_j3_bindings_Bindings_copy__Lorg_vmmagic_unboxed_ObjectReference_2Lorg_vmmagic_unboxed_ObjectReference_2II(
-    gc* obj, VirtualTable* VT, int size, int allocator);
+    gc* obj, void* type, int size, int allocator);
 
 extern "C" word_t Java_org_j3_mmtk_ObjectModel_copy__Lorg_vmmagic_unboxed_ObjectReference_2I (
     MMTkObject* OM, gc* src, int allocator) ALWAYS_INLINE;
@@ -96,7 +96,7 @@ extern "C" word_t Java_org_j3_mmtk_Objec
   size_t size = vmkit::Thread::get()->MyVM->getObjectSize(src);
   size = llvm::RoundUpToAlignment(size, sizeof(void*));
   gc* res = (gc*)JnJVM_org_j3_bindings_Bindings_copy__Lorg_vmmagic_unboxed_ObjectReference_2Lorg_vmmagic_unboxed_ObjectReference_2II(
-      src, src->getVirtualTable(), size, allocator);
+      src, vmkit::Thread::get()->MyVM->getType(src), size, allocator);
   assert((res->header() & ~vmkit::GCBitMask) == (src->header() & ~vmkit::GCBitMask));
   return (word_t)res;
 }





More information about the vmkit-commits mailing list