blob: ca2e0b60b6f286fda2b54d50868c6c7b51540880 [file] [log] [blame]
#ifndef INCINERATOR_H
#define INCINERATOR_H
#include "OSGiGateway.h"
#include "vmkit/Locks.h"
#include "j3/jni.h"
#include <map>
#include <list>
#include <vector>
#include <set>
#include <deque>
#include <stdint.h>
#define DEBUG_VERBOSE_STALE_REF 1
#define DEBUG_EXCLUDE_FINALIZABLE_STALE_OBJECTS 0
#define DEBUG_OBJECT_REF_DUMPING 0
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(OSGiGateway::bundle_id_t bundleID, bool corrected);
bool isBundleStaleReferenceCorrected(OSGiGateway::bundle_id_t bundleID) const;
void dumpClassLoaderBundles() const;
void forceStaleReferenceScanning();
#if DEBUG_OBJECT_REF_DUMPING
void dumpReferencesToObject(const JavaObject* object);
#endif
OSGiGateway::bundle_id_t getClassLoaderBundleID(JnjvmClassLoader const * loader) const;
void setBundleClassLoader(OSGiGateway::bundle_id_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<OSGiGateway::bundle_id_t, std::list<JnjvmClassLoader const *> >
staleBundleClassLoadersType;
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 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 lock;
staleBundleClassLoadersType staleBundleClassLoaders;
StaleRefListType staleRefList;
bool needsStaleRefRescan;
#if DEBUG_OBJECT_REF_DUMPING
mutable const JavaObject* findReferencesToObject;
std::set<const JavaObject*> foundReferencerObjects;
std::deque<const JavaObject*> pendingRefObject;
std::set<const JavaObject*> seenObjects;
#endif
};
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;
}
};
}
extern "C" void Java_j3_vm_OSGi_setBundleStaleReferenceCorrected(jlong bundleID, jboolean corrected);
extern "C" jboolean Java_j3_vm_OSGi_isBundleStaleReferenceCorrected(jlong bundleID);
extern "C" void Java_j3_vm_OSGi_forceStaleReferenceScanning();
#if DEBUG_OBJECT_REF_DUMPING
extern "C" void Java_j3_vm_OSGi_dumpReferencesToObject(jlong obj);
#endif
#endif