[vmkit-commits] [vmkit] r183679 - Adding Incinerator feature to J3. Added core implementation.
Koutheir Attouchi
koutheir at gmail.com
Mon Jun 10 09:20:59 PDT 2013
Author: koutheir
Date: Mon Jun 10 11:20:59 2013
New Revision: 183679
URL: http://llvm.org/viewvc/llvm-project?rev=183679&view=rev
Log:
Adding Incinerator feature to J3. Added core implementation.
Added:
vmkit/branches/incinerator/lib/j3/VMCore/Incinerator.cpp (with props)
vmkit/branches/incinerator/lib/j3/VMCore/Incinerator.h (with props)
vmkit/branches/incinerator/lib/j3/VMCore/IncineratorOSGi.cpp (with props)
Modified:
vmkit/branches/incinerator/include/vmkit/VirtualMachine.h
vmkit/branches/incinerator/include/vmkit/config.h.in
vmkit/branches/incinerator/lib/j3/Compiler/JavaJITOpcodes.cpp
vmkit/branches/incinerator/lib/j3/VMCore/Jnjvm.cpp
vmkit/branches/incinerator/lib/j3/VMCore/Jnjvm.h
vmkit/branches/incinerator/lib/j3/VMCore/JnjvmClassLoader.cpp
vmkit/branches/incinerator/lib/j3/VMCore/JnjvmClassLoader.h
vmkit/branches/incinerator/mmtk/java/src/org/j3/mmtk/Collection.java
vmkit/branches/incinerator/mmtk/java/src/org/mmtk/plan/SimpleCollector.java
vmkit/branches/incinerator/mmtk/java/src/org/mmtk/vm/Collection.java
vmkit/branches/incinerator/mmtk/mmtk-alloc/Selected.cpp
vmkit/branches/incinerator/mmtk/mmtk-j3/Collection.cpp
vmkit/branches/incinerator/mmtk/mmtk-j3/FinalizableProcessor.cpp
Modified: vmkit/branches/incinerator/include/vmkit/VirtualMachine.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/incinerator/include/vmkit/VirtualMachine.h?rev=183679&r1=183678&r2=183679&view=diff
==============================================================================
--- vmkit/branches/incinerator/include/vmkit/VirtualMachine.h (original)
+++ vmkit/branches/incinerator/include/vmkit/VirtualMachine.h Mon Jun 10 11:20:59 2013
@@ -223,6 +223,13 @@ public:
///
CooperativeCollectionRV rendezvous;
+#if RESET_STALE_REFERENCES
+ virtual bool beforeMarkingReference(const void* source, void** ref) = 0;
+ virtual bool beforeMarkingStackReference(const void* frameInfo, void** ref) = 0;
+ virtual void collectorPhaseComplete() = 0;
+ virtual void markingFinalizersDone() = 0;
+#endif
+
//===----------------------------------------------------------------------===//
// (2.5) GC-DEBUG-related methods.
//===----------------------------------------------------------------------===//
Modified: vmkit/branches/incinerator/include/vmkit/config.h.in
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/incinerator/include/vmkit/config.h.in?rev=183679&r1=183678&r2=183679&view=diff
==============================================================================
--- vmkit/branches/incinerator/include/vmkit/config.h.in (original)
+++ vmkit/branches/incinerator/include/vmkit/config.h.in Mon Jun 10 11:20:59 2013
@@ -0,0 +1,2 @@
+/* Kill stale references */
+#undef RESET_STALE_REFERENCES
Modified: vmkit/branches/incinerator/lib/j3/Compiler/JavaJITOpcodes.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/incinerator/lib/j3/Compiler/JavaJITOpcodes.cpp?rev=183679&r1=183678&r2=183679&view=diff
==============================================================================
--- vmkit/branches/incinerator/lib/j3/Compiler/JavaJITOpcodes.cpp (original)
+++ vmkit/branches/incinerator/lib/j3/Compiler/JavaJITOpcodes.cpp Mon Jun 10 11:20:59 2013
@@ -2566,11 +2566,15 @@ void JavaJIT::compileOpcodes(Reader& rea
}
case MONITOREXIT : {
+#if RESET_STALE_REFERENCES
// NOTE: monitorExit() should NOT throw an exception if object is null.
// See monitorExit() implementation.
- //bool thisReference = isThisReference(currentStackIndex - 1);
Value* obj = pop();
- // if (!thisReference) JITVerifyNull(obj);
+#else
+ bool thisReference = isThisReference(currentStackIndex - 1);
+ Value* obj = pop();
+ if (!thisReference) JITVerifyNull(obj);
+#endif
monitorExit(obj);
break;
}
Added: vmkit/branches/incinerator/lib/j3/VMCore/Incinerator.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/incinerator/lib/j3/VMCore/Incinerator.cpp?rev=183679&view=auto
==============================================================================
--- vmkit/branches/incinerator/lib/j3/VMCore/Incinerator.cpp (added)
+++ vmkit/branches/incinerator/lib/j3/VMCore/Incinerator.cpp Mon Jun 10 11:20:59 2013
@@ -0,0 +1,458 @@
+
+#include "VmkitGC.h"
+#include "Jnjvm.h"
+#include "VMStaticInstance.h"
+#include "JavaReferenceQueue.h"
+
+#include <sstream>
+#include <algorithm>
+
+#if RESET_STALE_REFERENCES
+
+#define DEBUG_VERBOSE_STALE_REF 0
+
+using namespace std;
+
+namespace j3 {
+
+Incinerator::Incinerator(Jnjvm* j3vm) :
+ scanRef(Incinerator::scanRef_Disabled),
+ scanStackRef(Incinerator::scanStackRef_Disabled),
+ vm(j3vm),
+ needsStaleRefRescan(false),
+ findReferencesToObject(NULL) {}
+
+Incinerator::~Incinerator()
+{
+}
+
+Incinerator* Incinerator::get()
+{
+ vmkit::Thread* th = vmkit::Thread::get();
+ assert(th && "Invalid current thread.");
+ if (!th) return NULL;
+
+ return &static_cast<Jnjvm*>(th->MyVM)->incinerator;
+}
+
+void Incinerator::dumpClassLoaderBundles() const
+{
+ vmkit::LockGuard lg(bundleClassLoadersLock);
+ bundleClassLoadersType::const_iterator
+ i = bundleClassLoaders.begin(), e = bundleClassLoaders.end();
+
+ for (; i != e; ++i)
+ cerr << "bundleID=" << i->first << " classLoader=" << i->second << endl;
+
+ staleBundleClassLoadersType::const_iterator
+ si = staleBundleClassLoaders.begin(), se = staleBundleClassLoaders.end();
+ staleBundleClassLoadersType::mapped_type::const_iterator li, le;
+ for (; si != se; ++si) {
+ cerr << "stale bundleID=" << si->first << " classLoaders={";
+ le = si->second.end();
+ li = si->second.begin();
+ for (; li != le; ++li) cerr << " " << *li;
+ cerr << "}" << endl;
+ }
+}
+
+void Incinerator::setBundleStaleReferenceCorrected(int64_t bundleID, bool corrected)
+{
+ JnjvmClassLoader * loader = this->getBundleClassLoader(bundleID);
+ if (!loader) {
+ vm->illegalArgumentException("Invalid bundle ID"); return;}
+
+#if DEBUG_VERBOSE_STALE_REF
+ cerr << "Stale references to bundleID=" << bundleID << " are ";
+ if (corrected)
+ cerr << "corrected." << endl;
+ else
+ cerr << "no more corrected." << endl;
+#endif
+
+ loader->setStaleReferencesCorrectionEnabled(corrected);
+}
+
+bool Incinerator::isBundleStaleReferenceCorrected(int64_t bundleID) const
+{
+ JnjvmClassLoader const* loader = this->getBundleClassLoader(bundleID);
+ if (!loader) {
+ vm->illegalArgumentException("Invalid bundle ID"); return false;}
+
+ return loader->isStaleReferencesCorrectionEnabled();
+}
+
+JnjvmClassLoader * Incinerator::getBundleClassLoader(int64_t bundleID) const
+{
+ if (bundleID == -1) return NULL;
+
+ vmkit::LockGuard lg(bundleClassLoadersLock);
+
+ bundleClassLoadersType::const_iterator
+ i = bundleClassLoaders.find(bundleID), e = bundleClassLoaders.end();
+ return (i == e) ? NULL : i->second;
+}
+
+bool Incinerator::InstalledBundles_finder::operator() (
+ const bundleClassLoadersType::value_type& pair) const
+{
+ return (loader == pair.second);
+}
+
+bool Incinerator::UninstalledBundles_finder::operator() (
+ const staleBundleClassLoadersType::value_type& pair) const
+{
+ staleBundleClassLoadersType::mapped_type::const_iterator
+ b = pair.second.begin(), e = pair.second.end();
+ staleBundleClassLoadersType::mapped_type::const_iterator
+ i = find(b, e, loader);
+ return (i != e);
+}
+
+int64_t Incinerator::getClassLoaderBundleID(JnjvmClassLoader const * loader) const
+{
+ if (loader == NULL) return -1;
+ vmkit::LockGuard lg(bundleClassLoadersLock);
+
+ bundleClassLoadersType::const_iterator
+ b = bundleClassLoaders.begin(),
+ e = bundleClassLoaders.end();
+ bundleClassLoadersType::const_iterator
+ i = find_if(b, e, InstalledBundles_finder(loader));
+
+ if (i != e) return i->first;
+
+ // Look up in stale bundles list
+ staleBundleClassLoadersType::const_iterator
+ sb = staleBundleClassLoaders.begin(),
+ se = staleBundleClassLoaders.end();
+ staleBundleClassLoadersType::const_iterator
+ si = find_if(sb, se, UninstalledBundles_finder(loader));
+
+ return (si == se) ? -1 : si->first;
+}
+
+// Link a bundle ID (OSGi world) to a class loader (Java world).
+void Incinerator::setBundleClassLoader(int64_t bundleID, JnjvmClassLoader* loader)
+{
+ if (bundleID == -1) return;
+ vmkit::LockGuard lg(bundleClassLoadersLock);
+
+ JnjvmClassLoader * previous_loader = bundleClassLoaders[bundleID];
+
+ if (!loader) {
+ // Unloaded bundle
+ bundleClassLoaders.erase(bundleID);
+
+#if DEBUG_VERBOSE_STALE_REF
+ cerr << "Bundle uninstalled: bundleID=" << bundleID
+ << " classLoader=" << previous_loader << endl;
+#endif
+ } else {
+ // Installed/Updated bundle
+ if (previous_loader == loader)
+ return; // Same class loader already associated with the bundle, do nothing
+
+ // Associate the class loader with the bundle
+ bundleClassLoaders[bundleID] = loader;
+
+ // Propagate the stale reference correction setting to the new
+ // class loader if a previous one exists.
+ if (previous_loader != NULL) {
+ loader->setStaleReferencesCorrectionEnabled(
+ previous_loader->isStaleReferencesCorrectionEnabled());
+ }
+
+#if DEBUG_VERBOSE_STALE_REF
+ if (!previous_loader) {
+ cerr << "Bundle installed: bundleID=" << bundleID
+ << " classLoader=" << loader << endl;
+ } else {
+ cerr << "Bundle updated: bundleID=" << bundleID
+ << " classLoader=" << loader
+ << " previousClassLoader=" << previous_loader << endl;
+ }
+#endif
+ }
+
+ if (!previous_loader)
+ return; // No previous class loader, nothing to clean up
+
+ // Mark the previous class loader as stale
+ staleBundleClassLoaders[bundleID].push_front(previous_loader);
+ previous_loader->markStale(true);
+
+ // Enable stale references scanning
+ setScanningInclusive();
+}
+
+IncineratorManagedClassLoader::~IncineratorManagedClassLoader()
+{
+ Incinerator& incinerator = JavaThread::get()->getJVM()->incinerator;
+ incinerator.classLoaderUnloaded(static_cast<JnjvmClassLoader const *>(this));
+}
+
+void Incinerator::classLoaderUnloaded(JnjvmClassLoader const * loader)
+{
+ int64_t bundleID = getClassLoaderBundleID(loader);
+ if (bundleID == -1) {
+#if DEBUG_VERBOSE_STALE_REF
+ cerr << "Class loader unloaded: " << loader << endl;
+#endif
+ return;
+ }
+
+ staleBundleClassLoaders[bundleID].remove(loader);
+ if (staleBundleClassLoaders[bundleID].size() == 0)
+ staleBundleClassLoaders.erase(bundleID);
+
+#if DEBUG_VERBOSE_STALE_REF
+ cerr << "Class loader unloaded: " << loader
+ << " bundleID=" << bundleID << endl;
+#endif
+}
+
+void Incinerator::dumpReferencesToObject(JavaObject* object) const
+{
+ findReferencesToObject = object;
+ vmkit::Collector::collect();
+}
+
+void Incinerator::forceStaleReferenceScanning()
+{
+ setScanningInclusive();
+ vmkit::Collector::collect();
+}
+
+bool Incinerator::isScanningEnabled()
+{
+ return scanRef != Incinerator::scanRef_Disabled;
+}
+
+void Incinerator::setScanningDisabled()
+{
+ scanRef = Incinerator::scanRef_Disabled;
+ scanStackRef = Incinerator::scanStackRef_Disabled;
+
+#if DEBUG_VERBOSE_STALE_REF
+ cerr << "Looking for stale references done." << endl;
+#endif
+}
+
+void Incinerator::setScanningInclusive()
+{
+ scanRef = Incinerator::scanRef_Inclusive;
+ scanStackRef = Incinerator::scanStackRef_Inclusive;
+
+#if DEBUG_VERBOSE_STALE_REF
+ cerr << "Looking for stale references..." << endl;
+#endif
+}
+
+void Incinerator::setScanningExclusive()
+{
+ scanRef = Incinerator::scanRef_Exclusive;
+ scanStackRef = Incinerator::scanStackRef_Exclusive;
+
+#if DEBUG_VERBOSE_STALE_REF
+ cerr << "Excluding stale references..." << endl;
+#endif
+}
+
+void Incinerator::beforeCollection()
+{
+ if (findReferencesToObject != NULL)
+ foundReferencerObjects.clear();
+
+#if DEBUG_VERBOSE_STALE_REF
+ if (needsStaleRefRescan) {
+ cerr << "Some stale references were previously ignored due to"
+ " finalizable stale objects."
+ " Scanning for stale references enabled." << endl;
+ }
+#endif
+
+ if (!needsStaleRefRescan && !isScanningEnabled()) return;
+
+ needsStaleRefRescan = false;
+ setScanningInclusive();
+}
+
+void Incinerator::markingFinalizersDone()
+{
+ if (!isScanningEnabled()) return;
+ setScanningExclusive();
+}
+
+void Incinerator::collectorPhaseComplete()
+{
+ for (StaleRefListType::const_iterator
+ i = staleRefList.begin(), e = staleRefList.end(); i != e; ++i)
+ {
+ eliminateStaleRef(i->second, i->first);
+ }
+
+ staleRefList.clear();
+}
+
+void Incinerator::afterCollection()
+{
+ findReferencesToObject = NULL;
+
+ if (!isScanningEnabled()) return;
+
+#if DEBUG_VERBOSE_STALE_REF
+ if (needsStaleRefRescan) {
+ cerr << "Some stale references were ignored due to finalizable"
+ " stale objects. Another garbage collection is needed." << endl;
+ }
+#endif
+
+ setScanningDisabled();
+}
+
+bool Incinerator::isStaleObject(const JavaObject* obj)
+{
+ llvm_gcroot(obj, 0);
+ if (!obj || isVMObject(obj)) return false;
+
+ CommonClass* ccl = JavaObject::getClass(obj);
+ assert (ccl && "Object Class is not null.");
+
+ JnjvmClassLoader* loader = ccl->classLoader;
+ return loader->isStale() && loader->isStaleReferencesCorrectionEnabled();
+}
+
+bool Incinerator::isVMObject(const JavaObject* obj)
+{
+ llvm_gcroot(obj, 0);
+
+ // Check the type of Java object.
+ // Some Java objects are not real object, but are bridges between Java
+ // and the VM C++ objects.
+ return (obj != NULL) && (
+ VMClassLoader::isVMClassLoader(obj)
+ || VMStaticInstance::isVMStaticInstance(obj));
+}
+
+bool Incinerator::scanRef_Disabled(Incinerator&, const JavaObject* source, JavaObject** ref)
+{
+ llvm_gcroot(source, 0);
+#if DEBUG_VERBOSE_STALE_REF
+ if (!ref || !(*ref)) return true;
+ if (JavaObject::getClass(*ref)->name->elements[0] == 'i')
+ cout << ref << " ==> " << **ref << endl;
+#endif
+ return true;
+}
+
+bool Incinerator::scanStackRef_Disabled(Incinerator&, const JavaMethod* method, JavaObject** ref)
+{
+#if DEBUG_VERBOSE_STALE_REF
+ if (!ref || !(*ref)) return true;
+ if (method && method->classDef->name->elements[0] == 'i')
+ cout << *method << ": " << ref << " ==> " << **ref << endl;
+#endif
+ return true;
+}
+
+bool Incinerator::scanRef_Inclusive(Incinerator& incinerator, const JavaObject* source, JavaObject** ref)
+{
+ llvm_gcroot(source, 0);
+
+ if (!ref || !isStaleObject(*ref)) return true;
+
+#if DEBUG_VERBOSE_STALE_REF
+ cerr << "Stale ref: " << ref << "==>" << **ref << endl;
+#endif
+
+ // Queue the stale reference to be eliminated.
+ incinerator.staleRefList[ref] = source;
+
+ // Skip this reference and don't trace it.
+ return false;
+}
+
+bool Incinerator::scanStackRef_Inclusive(Incinerator& incinerator, const JavaMethod* method, JavaObject** ref)
+{
+#if DEBUG_VERBOSE_STALE_REF
+ if (!ref || !(*ref)) return true;
+ if (method && method->classDef->name->elements[0] == 'i')
+ cout << *method << ": " << ref << " ==> " << **ref << endl;
+#endif
+
+ return Incinerator::scanRef_Inclusive(incinerator, NULL, ref);
+}
+
+bool Incinerator::scanRef_Exclusive(Incinerator& incinerator, const JavaObject* source, JavaObject** ref)
+{
+ llvm_gcroot(source, 0);
+
+ // Do not eliminate any stale references traced via finalizable objects.
+ if ((ref != NULL) && isStaleObject(*ref)) {
+#if DEBUG_VERBOSE_STALE_REF
+ size_t removed =
+#endif
+
+ incinerator.staleRefList.erase(ref);
+ incinerator.needsStaleRefRescan = true;
+
+#if DEBUG_VERBOSE_STALE_REF
+ if (!removed)
+ cerr << "Stale ref (ignored): " << ref << "==>" << **ref << endl;
+ else
+ cerr << "Excluded stale ref: " << ref << "==>" << **ref << endl;
+#endif
+ }
+ return true; // Trace this reference.
+}
+
+bool Incinerator::scanStackRef_Exclusive(Incinerator& incinerator, const JavaMethod* method, JavaObject** ref)
+{
+#if DEBUG_VERBOSE_STALE_REF
+ if (!ref || !(*ref)) return true;
+ if (method && method->classDef->name->elements[0] == 'i')
+ cout << *method << ": " << ref << " ==> " << **ref << endl;
+#endif
+
+ return Incinerator::scanRef_Exclusive(incinerator, NULL, ref);
+}
+
+void Incinerator::eliminateStaleRef(const JavaObject *source, JavaObject** ref)
+{
+ CommonClass* ccl = JavaObject::getClass(*ref);
+ assert (ccl && "Object Class is not null.");
+
+#if DEBUG_VERBOSE_STALE_REF
+ cerr << "Resetting stale ref=" << ref << " obj=" << **ref << " classLoader=" << ccl->classLoader;
+ if (source) cerr << " source=" << *source;
+ cerr << endl;
+#endif
+
+ if (!ccl->classLoader->isStaleReferencesCorrectionEnabled()) {
+#if DEBUG_VERBOSE_STALE_REF
+ cerr << "WARNING: Ignoring stale ref=" << ref << " obj=" << **ref << " classLoader=" << ccl->classLoader;
+ if (source) cerr << " source=" << *source;
+ cerr << endl;
+#endif
+ return;
+ }
+
+ if (JavaThread* ownerThread = (JavaThread*)vmkit::ThinLock::getOwner(*ref, vm->lockSystem)) {
+ if (vmkit::FatLock* lock = vmkit::ThinLock::getFatLock(*ref, vm->lockSystem))
+ lock->markAssociatedObjectAsDead();
+
+ // Notify all threads waiting on this object
+ ownerThread->lockingThread.notifyAll(*ref, vm->lockSystem, ownerThread);
+
+ // Release this object
+ while (vmkit::ThinLock::getOwner(*ref, vm->lockSystem) == ownerThread)
+ vmkit::ThinLock::release(*ref, vm->lockSystem, ownerThread);
+ }
+
+ *ref = NULL; // Reset the reference
+}
+
+}
+
+#endif
Propchange: vmkit/branches/incinerator/lib/j3/VMCore/Incinerator.cpp
------------------------------------------------------------------------------
svn:executable = *
Propchange: vmkit/branches/incinerator/lib/j3/VMCore/Incinerator.cpp
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: vmkit/branches/incinerator/lib/j3/VMCore/Incinerator.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/incinerator/lib/j3/VMCore/Incinerator.h?rev=183679&view=auto
==============================================================================
--- vmkit/branches/incinerator/lib/j3/VMCore/Incinerator.h (added)
+++ vmkit/branches/incinerator/lib/j3/VMCore/Incinerator.h Mon Jun 10 11:20:59 2013
@@ -0,0 +1,145 @@
+
+#ifndef INCINERATOR_H
+#define INCINERATOR_H
+
+#include "vmkit/Locks.h"
+
+#include <list>
+#include <map>
+#include <set>
+#include <vector>
+#include <stdint.h>
+
+namespace j3 {
+
+class Jnjvm;
+class JnjvmClassLoader;
+class VMClassLoader;
+class VMStaticInstance;
+class JavaObject;
+class JavaMethod;
+
+
+class Incinerator
+{
+public:
+ Incinerator(j3::Jnjvm* j3vm);
+ virtual ~Incinerator();
+
+ void setBundleStaleReferenceCorrected(int64_t bundleID, bool corrected);
+ bool isBundleStaleReferenceCorrected(int64_t bundleID) const;
+ void dumpClassLoaderBundles() const;
+ void dumpReferencesToObject(JavaObject* object) const;
+ void forceStaleReferenceScanning();
+
+ JnjvmClassLoader * getBundleClassLoader(int64_t bundleID) const;
+ int64_t getClassLoaderBundleID(JnjvmClassLoader const * loader) const;
+ void setBundleClassLoader(int64_t bundleID, JnjvmClassLoader* loader);
+
+ void beforeCollection();
+ void markingFinalizersDone();
+ void collectorPhaseComplete();
+ void afterCollection();
+ void classLoaderUnloaded(JnjvmClassLoader const * loader);
+
+ static Incinerator* get();
+
+ typedef bool (*scanRefFunc)(
+ Incinerator& incinerator, const JavaObject* source, JavaObject** ref);
+ typedef bool (*scanStackRefFunc)(
+ Incinerator& incinerator, const JavaMethod* method, JavaObject** ref);
+
+ volatile scanRefFunc scanRef;
+ volatile scanStackRefFunc scanStackRef;
+
+protected:
+ typedef std::map<int64_t, std::list<JnjvmClassLoader const *> >
+ staleBundleClassLoadersType;
+ typedef std::map<int64_t, JnjvmClassLoader *> bundleClassLoadersType;
+ typedef std::map<JavaObject**, const JavaObject*>
+ StaleRefListType; // (ref, source)
+
+ inline static bool isStaleObject(const JavaObject* obj);
+ inline static bool isVMObject(const JavaObject* obj);
+ void eliminateStaleRef(const JavaObject *source, JavaObject** ref);
+
+ bool isScanningEnabled();
+ void setScanningDisabled();
+ void setScanningInclusive();
+ void setScanningExclusive();
+
+ static bool scanRef_Disabled(
+ Incinerator& incinerator, const JavaObject* source, JavaObject** ref);
+ static bool scanRef_Inclusive(
+ Incinerator& incinerator, const JavaObject* source, JavaObject** ref);
+ static bool scanRef_Exclusive(
+ Incinerator& incinerator, const JavaObject* source, JavaObject** ref);
+ static bool scanStackRef_Disabled(
+ Incinerator& incinerator, const JavaMethod* method, JavaObject** ref);
+ static bool scanStackRef_Inclusive(
+ Incinerator& incinerator, const JavaMethod* method, JavaObject** ref);
+ static bool scanStackRef_Exclusive(
+ Incinerator& incinerator, const JavaMethod* method, JavaObject** ref);
+
+ class InstalledBundles_finder {
+ JnjvmClassLoader const * loader;
+ public:
+ InstalledBundles_finder(JnjvmClassLoader const * l) : loader(l) {}
+ bool operator() (const bundleClassLoadersType::value_type& pair) const;
+ };
+
+ class UninstalledBundles_finder {
+ JnjvmClassLoader const * loader;
+ public:
+ UninstalledBundles_finder(JnjvmClassLoader const * l) : loader(l) {}
+ bool operator() (
+ const staleBundleClassLoadersType::value_type& pair) const;
+ };
+
+ j3::Jnjvm* vm;
+
+ mutable vmkit::LockRecursive bundleClassLoadersLock;
+ bundleClassLoadersType bundleClassLoaders;
+ staleBundleClassLoadersType staleBundleClassLoaders;
+
+ StaleRefListType staleRefList;
+ bool needsStaleRefRescan;
+
+ mutable JavaObject* findReferencesToObject;
+ std::vector<const JavaObject*> foundReferencerObjects;
+};
+
+
+class IncineratorManagedClassLoader
+{
+protected:
+ enum StaleTags {
+ CorrectStaleRef = 0x1,
+ RefIsStale = 0x2
+ };
+
+ uint8_t staleRefFlags;
+
+ IncineratorManagedClassLoader() : staleRefFlags(CorrectStaleRef) {}
+ virtual ~IncineratorManagedClassLoader();
+
+public:
+ bool isStale() const {return (staleRefFlags & RefIsStale) != 0;}
+
+ void markStale(bool stale = true) {
+ if (stale) staleRefFlags |= RefIsStale;
+ else staleRefFlags &= ~RefIsStale;
+ }
+
+ bool isStaleReferencesCorrectionEnabled() const {
+ return (staleRefFlags & CorrectStaleRef) != 0;}
+
+ void setStaleReferencesCorrectionEnabled(bool enable) {
+ if (enable) staleRefFlags |= CorrectStaleRef;
+ else staleRefFlags &= ~CorrectStaleRef;
+ }
+};
+
+}
+
+#endif
Propchange: vmkit/branches/incinerator/lib/j3/VMCore/Incinerator.h
------------------------------------------------------------------------------
svn:executable = *
Propchange: vmkit/branches/incinerator/lib/j3/VMCore/Incinerator.h
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: vmkit/branches/incinerator/lib/j3/VMCore/IncineratorOSGi.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/incinerator/lib/j3/VMCore/IncineratorOSGi.cpp?rev=183679&view=auto
==============================================================================
--- vmkit/branches/incinerator/lib/j3/VMCore/IncineratorOSGi.cpp (added)
+++ vmkit/branches/incinerator/lib/j3/VMCore/IncineratorOSGi.cpp Mon Jun 10 11:20:59 2013
@@ -0,0 +1,80 @@
+
+#include "Incinerator.h"
+#include "ClasspathReflect.h"
+#include "j3/jni.h"
+
+
+using namespace j3;
+
+/*
+ This Java native method must be called by the framework in order to link bundles (given
+ by bundle identifiers) to objects (thus, class loaders). This allows the VM to perform
+ operations on bundles without actually having to know the precise structure of these.
+*/
+extern "C" void Java_j3_vm_OSGi_associateBundleClass(jlong bundleID, JavaObjectClass* classObject)
+{
+ llvm_gcroot(classObject, 0);
+
+#if RESET_STALE_REFERENCES
+
+ CommonClass* ccl = JavaObjectClass::getClass(classObject);
+ Incinerator::get()->setBundleClassLoader(bundleID, ccl->classLoader);
+
+#endif
+}
+
+extern "C" void Java_j3_vm_OSGi_notifyBundleUninstalled(jlong bundleID)
+{
+#if RESET_STALE_REFERENCES
+
+ Incinerator::get()->setBundleClassLoader(bundleID, NULL);
+
+#endif
+}
+
+extern "C" void Java_j3_vm_OSGi_setBundleStaleReferenceCorrected(jlong bundleID, jboolean corrected)
+{
+#if RESET_STALE_REFERENCES
+
+ Incinerator::get()->setBundleStaleReferenceCorrected(bundleID, corrected);
+
+#endif
+}
+
+extern "C" jboolean Java_j3_vm_OSGi_isBundleStaleReferenceCorrected(jlong bundleID)
+{
+#if RESET_STALE_REFERENCES
+
+ return Incinerator::get()->isBundleStaleReferenceCorrected(bundleID);
+
+#else
+ return false;
+#endif
+}
+
+extern "C" void Java_j3_vm_OSGi_dumpClassLoaderBundles()
+{
+#if RESET_STALE_REFERENCES
+
+ Incinerator::get()->dumpClassLoaderBundles();
+
+#endif
+}
+
+extern "C" void Java_j3_vm_OSGi_dumpReferencesToObject(jlong obj)
+{
+#if RESET_STALE_REFERENCES
+
+ Incinerator::get()->dumpReferencesToObject(reinterpret_cast<JavaObject*>(obj));
+
+#endif
+}
+
+extern "C" void Java_j3_vm_OSGi_forceStaleReferenceScanning()
+{
+#if RESET_STALE_REFERENCES
+
+ Incinerator::get()->forceStaleReferenceScanning();
+
+#endif
+}
Propchange: vmkit/branches/incinerator/lib/j3/VMCore/IncineratorOSGi.cpp
------------------------------------------------------------------------------
svn:executable = *
Propchange: vmkit/branches/incinerator/lib/j3/VMCore/IncineratorOSGi.cpp
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: vmkit/branches/incinerator/lib/j3/VMCore/Jnjvm.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/incinerator/lib/j3/VMCore/Jnjvm.cpp?rev=183679&r1=183678&r2=183679&view=diff
==============================================================================
--- vmkit/branches/incinerator/lib/j3/VMCore/Jnjvm.cpp (original)
+++ vmkit/branches/incinerator/lib/j3/VMCore/Jnjvm.cpp Mon Jun 10 11:20:59 2013
@@ -1350,6 +1350,9 @@ Jnjvm::Jnjvm(vmkit::BumpPtrAllocator& Al
vmkit::CompiledFrames** frames,
JnjvmBootstrapLoader* loader) :
VirtualMachine(Alloc, frames), lockSystem(Alloc)
+#if RESET_STALE_REFERENCES
+, incinerator(this)
+#endif
{
classpath = getenv("CLASSPATH");
@@ -1388,6 +1391,10 @@ void Jnjvm::startCollection() {
fflush(stdout);
#endif
+#if RESET_STALE_REFERENCES
+ incinerator.beforeCollection();
+#endif
+
finalizerThread->FinalizationQueueLock.acquire();
referenceThread->ToEnqueueLock.acquire();
referenceThread->SoftReferencesQueue.acquire();
@@ -1404,6 +1411,10 @@ void Jnjvm::endCollection() {
finalizerThread->FinalizationCond.broadcast();
referenceThread->EnqueueCond.broadcast();
+#if RESET_STALE_REFERENCES
+ incinerator.afterCollection();
+#endif
+
#if DEBUG > 0
printf("End Collection\n");
vmkit::Thread::get()->printBacktrace();
Modified: vmkit/branches/incinerator/lib/j3/VMCore/Jnjvm.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/incinerator/lib/j3/VMCore/Jnjvm.h?rev=183679&r1=183678&r2=183679&view=diff
==============================================================================
--- vmkit/branches/incinerator/lib/j3/VMCore/Jnjvm.h (original)
+++ vmkit/branches/incinerator/lib/j3/VMCore/Jnjvm.h Mon Jun 10 11:20:59 2013
@@ -10,10 +10,6 @@
#ifndef JNJVM_JAVA_VM_H
#define JNJVM_JAVA_VM_H
-#include <vector>
-#include <map>
-#include <list>
-
#include "types.h"
#include "vmkit/Allocator.h"
@@ -26,6 +22,7 @@
#include "JnjvmConfig.h"
#include "JNIReferences.h"
#include "LockedMap.h"
+#include "Incinerator.h"
namespace j3 {
@@ -365,6 +362,33 @@ public:
void loadBootstrap();
static void printBacktrace() __attribute__((noinline));
+
+#if RESET_STALE_REFERENCES
+public:
+ Incinerator incinerator;
+
+ virtual void markingFinalizersDone() {
+ incinerator.markingFinalizersDone();
+ }
+
+ virtual void collectorPhaseComplete() {
+ return incinerator.collectorPhaseComplete();
+ }
+
+ virtual bool beforeMarkingStackReference(const void* frameInfo, void** ref) {
+ const JavaMethod* method = (!frameInfo) ? NULL :
+ reinterpret_cast<const JavaMethod*>(
+ reinterpret_cast<const vmkit::FrameInfo*>(frameInfo)->Metadata);
+
+ return incinerator.scanStackRef(incinerator, method,
+ reinterpret_cast<JavaObject**>(ref));
+ }
+ virtual bool beforeMarkingReference(const void* source, void** ref) {
+ return incinerator.scanRef(incinerator,
+ reinterpret_cast<const JavaObject*>(source),
+ reinterpret_cast<JavaObject**>(ref));
+ }
+#endif
};
} // end namespace j3
Modified: vmkit/branches/incinerator/lib/j3/VMCore/JnjvmClassLoader.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/incinerator/lib/j3/VMCore/JnjvmClassLoader.cpp?rev=183679&r1=183678&r2=183679&view=diff
==============================================================================
--- vmkit/branches/incinerator/lib/j3/VMCore/JnjvmClassLoader.cpp (original)
+++ vmkit/branches/incinerator/lib/j3/VMCore/JnjvmClassLoader.cpp Mon Jun 10 11:20:59 2013
@@ -879,29 +879,38 @@ JnjvmClassLoader::~JnjvmClassLoader() {
if (classes) {
classes->~ClassMap();
allocator.Deallocate(classes);
+ classes = NULL;
}
if (hashUTF8) {
hashUTF8->~UTF8Map();
allocator.Deallocate(hashUTF8);
+ hashUTF8 = NULL;
}
if (javaTypes) {
javaTypes->~TypeMap();
allocator.Deallocate(javaTypes);
+ javaTypes = NULL;
}
if (javaSignatures) {
javaSignatures->~SignMap();
allocator.Deallocate(javaSignatures);
+ javaSignatures = NULL;
}
- for (std::vector<void*>::iterator i = nativeLibs.begin();
- i < nativeLibs.end(); ++i) {
+ for (std::vector<void*>::iterator
+ i = nativeLibs.begin(), e = nativeLibs.end(); i != e; ++i)
+ {
dlclose(*i);
}
+ nativeLibs.clear();
+
+ vm = NULL;
delete TheCompiler;
+ TheCompiler = NULL;
// Don't delete the allocator. The caller of this method must
// delete it after the current object is deleted.
Modified: vmkit/branches/incinerator/lib/j3/VMCore/JnjvmClassLoader.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/incinerator/lib/j3/VMCore/JnjvmClassLoader.h?rev=183679&r1=183678&r2=183679&view=diff
==============================================================================
--- vmkit/branches/incinerator/lib/j3/VMCore/JnjvmClassLoader.h (original)
+++ vmkit/branches/incinerator/lib/j3/VMCore/JnjvmClassLoader.h Mon Jun 10 11:20:59 2013
@@ -25,6 +25,7 @@
#include "JavaArray.h"
#include "JnjvmConfig.h"
#include "UTF8.h"
+#include "Incinerator.h"
namespace j3 {
@@ -56,7 +57,12 @@ typedef TJavaArray<JavaObject*> ArrayObj
/// its own tables (signatures, UTF8, types) which are mapped to a single
/// table for non-isolate environments.
///
-class JnjvmClassLoader : public vmkit::PermanentObject {
+class JnjvmClassLoader :
+ public vmkit::PermanentObject
+#if RESET_STALE_REFERENCES
+ , public IncineratorManagedClassLoader
+#endif
+{
private:
/// isolate - Which isolate defined me? Null for the bootstrap class loader.
Modified: vmkit/branches/incinerator/mmtk/java/src/org/j3/mmtk/Collection.java
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/incinerator/mmtk/java/src/org/j3/mmtk/Collection.java?rev=183679&r1=183678&r2=183679&view=diff
==============================================================================
--- vmkit/branches/incinerator/mmtk/java/src/org/j3/mmtk/Collection.java (original)
+++ vmkit/branches/incinerator/mmtk/java/src/org/j3/mmtk/Collection.java Mon Jun 10 11:20:59 2013
@@ -91,6 +91,7 @@ public final class Collection extends or
* @param c the collector to prepare
*/
public native final void prepareCollector(CollectorContext c);
+ public native final void collectorPhaseComplete(CollectorContext c);
/**
* Rendezvous with all other processors, returning the rank
Modified: vmkit/branches/incinerator/mmtk/java/src/org/mmtk/plan/SimpleCollector.java
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/incinerator/mmtk/java/src/org/mmtk/plan/SimpleCollector.java?rev=183679&r1=183678&r2=183679&view=diff
==============================================================================
--- vmkit/branches/incinerator/mmtk/java/src/org/mmtk/plan/SimpleCollector.java (original)
+++ vmkit/branches/incinerator/mmtk/java/src/org/mmtk/plan/SimpleCollector.java Mon Jun 10 11:20:59 2013
@@ -143,7 +143,7 @@ public abstract class SimpleCollector ex
}
if (phaseId == Simple.COMPLETE) {
- // Nothing to do
+ VM.collection.collectorPhaseComplete(this);
return;
}
Modified: vmkit/branches/incinerator/mmtk/java/src/org/mmtk/vm/Collection.java
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/incinerator/mmtk/java/src/org/mmtk/vm/Collection.java?rev=183679&r1=183678&r2=183679&view=diff
==============================================================================
--- vmkit/branches/incinerator/mmtk/java/src/org/mmtk/vm/Collection.java (original)
+++ vmkit/branches/incinerator/mmtk/java/src/org/mmtk/vm/Collection.java Mon Jun 10 11:20:59 2013
@@ -135,6 +135,7 @@ import org.vmmagic.pragma.*;
* @param c the collector to prepare
*/
public abstract void prepareCollector(CollectorContext c);
+ public abstract void collectorPhaseComplete(CollectorContext c);
/**
* Rendezvous with all other processors, returning the rank
Modified: vmkit/branches/incinerator/mmtk/mmtk-alloc/Selected.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/incinerator/mmtk/mmtk-alloc/Selected.cpp?rev=183679&r1=183678&r2=183679&view=diff
==============================================================================
--- vmkit/branches/incinerator/mmtk/mmtk-alloc/Selected.cpp (original)
+++ vmkit/branches/incinerator/mmtk/mmtk-alloc/Selected.cpp Mon Jun 10 11:20:59 2013
@@ -184,6 +184,9 @@ void Collector::scanObject(FrameInfo* FI
if ((*ptr) != NULL) {
assert(vmkit::Thread::get()->MyVM->isCorruptedType((gc*)(*ptr)));
}
+#if RESET_STALE_REFERENCES
+ if (!vmkit::Thread::get()->MyVM->beforeMarkingStackReference(FI, ptr)) return;
+#endif
JnJVM_org_j3_bindings_Bindings_reportDelayedRootEdge__Lorg_mmtk_plan_TraceLocal_2Lorg_vmmagic_unboxed_Address_2(closure, ptr);
}
@@ -194,6 +197,9 @@ void Collector::markAndTrace(void* sourc
assert(vmkit::Thread::get()->MyVM->isCorruptedType((gc*)(*ptr_)));
}
if ((*(void**)ptr) != NULL) assert(vmkit::Thread::get()->MyVM->isCorruptedType((gc*)(*(void**)ptr)));
+#if RESET_STALE_REFERENCES
+ if (!vmkit::Thread::get()->MyVM->beforeMarkingReference(source, ptr_)) return;
+#endif
JnJVM_org_j3_bindings_Bindings_processEdge__Lorg_mmtk_plan_TransitiveClosure_2Lorg_vmmagic_unboxed_ObjectReference_2Lorg_vmmagic_unboxed_Address_2(closure, source, ptr);
}
@@ -203,6 +209,9 @@ void Collector::markAndTraceRoot(void* s
if ((*ptr_) != NULL) {
assert(vmkit::Thread::get()->MyVM->isCorruptedType((gc*)(*ptr_)));
}
+#if RESET_STALE_REFERENCES
+ if (!vmkit::Thread::get()->MyVM->beforeMarkingReference(source, ptr_)) return;
+#endif
JnJVM_org_j3_bindings_Bindings_processRootEdge__Lorg_mmtk_plan_TraceLocal_2Lorg_vmmagic_unboxed_Address_2Z(closure, ptr, true);
}
Modified: vmkit/branches/incinerator/mmtk/mmtk-j3/Collection.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/incinerator/mmtk/mmtk-j3/Collection.cpp?rev=183679&r1=183678&r2=183679&view=diff
==============================================================================
--- vmkit/branches/incinerator/mmtk/mmtk-j3/Collection.cpp (original)
+++ vmkit/branches/incinerator/mmtk/mmtk-j3/Collection.cpp Mon Jun 10 11:20:59 2013
@@ -76,6 +76,14 @@ extern "C" void Java_org_j3_mmtk_Collect
// Nothing to do.
}
+extern "C" void Java_org_j3_mmtk_Collection_collectorPhaseComplete__Lorg_mmtk_plan_CollectorContext_2 (MMTkObject* C, MMTkObject* CC)
+{
+#if RESET_STALE_REFERENCES
+ vmkit::MutatorThread* th = vmkit::MutatorThread::get();
+ th->MyVM->collectorPhaseComplete();
+#endif
+}
+
extern "C" void Java_org_j3_mmtk_Collection_prepareMutator__Lorg_mmtk_plan_MutatorContext_2 (MMTkObject* C, MMTkObject* MC) {
}
Modified: vmkit/branches/incinerator/mmtk/mmtk-j3/FinalizableProcessor.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/incinerator/mmtk/mmtk-j3/FinalizableProcessor.cpp?rev=183679&r1=183678&r2=183679&view=diff
==============================================================================
--- vmkit/branches/incinerator/mmtk/mmtk-j3/FinalizableProcessor.cpp (original)
+++ vmkit/branches/incinerator/mmtk/mmtk-j3/FinalizableProcessor.cpp Mon Jun 10 11:20:59 2013
@@ -27,6 +27,9 @@ extern "C" void
Java_org_j3_mmtk_FinalizableProcessor_scan__Lorg_mmtk_plan_TraceLocal_2Z (MMTkObject* FP, MMTkObject* TL, uint8_t nursery) {
vmkit::Thread* th = vmkit::Thread::get();
th->MyVM->scanFinalizationQueue(reinterpret_cast<word_t>(TL));
+#if RESET_STALE_REFERENCES
+ th->MyVM->markingFinalizersDone();
+#endif
}
}
More information about the vmkit-commits
mailing list