[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