blob: b1946090d48d96b935ff2343ae44b83515317356 [file] [log] [blame]
//===---ReferenceQueue.h - Implementation of soft/weak/phantom references--===//
//
// The VMKit project
//
// This file is distributed under the University of Pierre et Marie Curie
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef J3_REFERENCE_QUEUE_H
#define J3_REFERENCE_QUEUE_H
#include "mvm/Threads/Locks.h"
#include "JavaThread.h"
// Same values than JikesRVM
#define INITIAL_QUEUE_SIZE 256
#define GROW_FACTOR 2
namespace j3 {
class ReferenceThread;
class Jnjvm;
class ReferenceQueue {
private:
gc** References;
uint32 QueueLength;
uint32 CurrentIndex;
mvm::SpinLock QueueLock;
uint8_t semantics;
gc* processReference(gc*, ReferenceThread*, word_t closure);
public:
static const uint8_t WEAK = 1;
static const uint8_t SOFT = 2;
static const uint8_t PHANTOM = 3;
ReferenceQueue(uint8_t s) {
References = new gc*[INITIAL_QUEUE_SIZE];
memset(References, 0, INITIAL_QUEUE_SIZE * sizeof(gc*));
QueueLength = INITIAL_QUEUE_SIZE;
CurrentIndex = 0;
semantics = s;
}
~ReferenceQueue() {
delete[] References;
}
void addReference(gc* ref) {
llvm_gcroot(ref, 0);
QueueLock.acquire();
if (CurrentIndex >= QueueLength) {
uint32 newLength = QueueLength * GROW_FACTOR;
gc** newQueue = new gc*[newLength];
if (!newQueue) {
fprintf(stderr, "I don't know how to handle reference overflow yet!\n");
abort();
}
memset(newQueue, 0, newLength * sizeof(gc*));
for (uint32 i = 0; i < QueueLength; ++i) newQueue[i] = References[i];
delete[] References;
References = newQueue;
QueueLength = newLength;
}
References[CurrentIndex++] = ref;
QueueLock.release();
}
void acquire() {
QueueLock.acquire();
}
void release() {
QueueLock.release();
}
void scan(ReferenceThread* thread, word_t closure);
};
class ReferenceThread : public JavaThread {
public:
/// WeakReferencesQueue - The queue of weak references.
///
ReferenceQueue WeakReferencesQueue;
/// SoftReferencesQueue - The queue of soft references.
///
ReferenceQueue SoftReferencesQueue;
/// PhantomReferencesQueue - The queue of phantom references.
///
ReferenceQueue PhantomReferencesQueue;
gc** ToEnqueue;
uint32 ToEnqueueLength;
uint32 ToEnqueueIndex;
/// ToEnqueueLock - A lock to protect access to the queue.
///
mvm::LockNormal EnqueueLock;
mvm::Cond EnqueueCond;
mvm::SpinLock ToEnqueueLock;
void addToEnqueue(gc* obj);
static void enqueueStart(ReferenceThread*);
/// addWeakReference - Add a weak reference to the queue.
///
void addWeakReference(gc* ref) {
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) {
llvm_gcroot(ref, 0);
PhantomReferencesQueue.addReference(ref);
}
ReferenceThread(Jnjvm* vm);
~ReferenceThread() {
delete[] ToEnqueue;
}
};
class FinalizerThread : public JavaThread {
public:
/// FinalizationQueueLock - A lock to protect access to the queue.
///
mvm::SpinLock FinalizationQueueLock;
/// finalizationQueue - A list of allocated objets that contain a finalize
/// method.
///
gc** FinalizationQueue;
/// CurrentIndex - Current index in the queue of finalizable objects.
///
uint32 CurrentIndex;
/// QueueLength - Current length of the queue of finalizable objects.
///
uint32 QueueLength;
/// growFinalizationQueue - Grow the queue of finalizable objects.
///
void growFinalizationQueue();
/// ToBeFinalized - List of objects that are scheduled to be finalized.
///
gc** ToBeFinalized;
/// ToBeFinalizedLength - Current length of the queue of objects scheduled
/// for finalization.
///
uint32 ToBeFinalizedLength;
/// CurrentFinalizedIndex - The current index in the ToBeFinalized queue
/// that will be sceduled for finalization.
///
uint32 CurrentFinalizedIndex;
/// growToBeFinalizedQueue - Grow the queue of the to-be finalized objects.
///
void growToBeFinalizedQueue();
/// finalizationCond - Condition variable to wake up finalization threads.
///
mvm::Cond FinalizationCond;
/// finalizationLock - Lock for the condition variable.
///
mvm::LockNormal FinalizationLock;
static void finalizerStart(FinalizerThread*);
/// addFinalizationCandidate - Add an object to the queue of objects with
/// a finalization method.
///
void addFinalizationCandidate(gc*);
/// scanFinalizationQueue - Scan objets with a finalized method and schedule
/// them for finalization if they are not live.
///
void scanFinalizationQueue(word_t closure);
FinalizerThread(Jnjvm* vm);
~FinalizerThread() {
delete[] FinalizationQueue;
delete[] ToBeFinalized;
}
};
} // namespace j3
#endif //J3_REFERENCE_QUEUE_H