Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

203 lines (163 sloc) 4.981 kB
#ifndef RBX_VM_GC_HPP
#define RBX_VM_GC_HPP
#include <list>
#include "oop.hpp"
#include "builtin/object.hpp"
namespace rubinius {
class ObjectMemory;
struct CallFrame;
class VariableScope;
class GlobalCache;
class StackVariables;
class ManagedThread;
class LLVMState;
namespace capi {
class Handles;
}
typedef std::vector<Object*> ObjectArray;
/**
* Holds all the root pointers from which garbage collections will commence.
* This includes the globally accessible Ruby objects such as class and
* module instances, global variables, etc, but also various handles that
* are used for FFI and CAPI.
*/
class GCData {
Roots& roots_;
capi::Handles* handles_;
std::list<capi::Handle*>* cached_handles_;
GlobalCache* global_cache_;
std::list<ManagedThread*>* threads_;
std::list<capi::GlobalHandle*>* global_handle_locations_;
GCTokenImpl* gc_token_;
#ifdef ENABLE_LLVM
LLVMState* llvm_state_;
#endif
public:
GCData(VM*, GCToken gct);
GCData(VM*);
GCData(Roots& r,
capi::Handles* handles = NULL, std::list<capi::Handle*>* cached_handles = NULL,
GlobalCache *cache = NULL, std::list<ManagedThread*>* ths = NULL,
std::list<capi::GlobalHandle*>* global_handle_locations = NULL)
: roots_(r)
, handles_(handles)
, cached_handles_(cached_handles)
, global_cache_(cache)
, threads_(ths)
, global_handle_locations_(global_handle_locations)
#ifdef ENABLE_LLVM
, llvm_state_(0)
#endif
{}
Roots& roots() {
return roots_;
}
std::list<ManagedThread*>* threads() {
return threads_;
}
capi::Handles* handles() {
return handles_;
}
std::list<capi::Handle*>* cached_handles() {
return cached_handles_;
}
GlobalCache* global_cache() {
return global_cache_;
}
std::list<capi::GlobalHandle*>* global_handle_locations() {
return global_handle_locations_;
}
GCTokenImpl* gc_token() {
return gc_token_;
}
#ifdef ENABLE_LLVM
LLVMState* llvm_state() {
return llvm_state_;
}
#endif
};
class AddressDisplacement {
intptr_t offset_;
intptr_t lower_bound_;
intptr_t upper_bound_;
public:
AddressDisplacement(intptr_t o, intptr_t l, intptr_t u)
: offset_(o)
, lower_bound_(l)
, upper_bound_(u)
{}
template <typename T>
T displace(T ptr) {
intptr_t addr = (intptr_t)ptr;
if(addr < lower_bound_) return ptr;
if(addr >= upper_bound_) return ptr;
return (T)((char*)ptr + offset_);
}
};
/**
* Abstract base class for the various garbage collector implementations.
* Defines the interface the VM will use to perform garbage collections,
* as well as providing implementations of common methods such as
* mark_object and scan_object.
*/
class GarbageCollector {
protected:
/// Reference to the ObjectMemory we are collecting
ObjectMemory* object_memory_;
private:
/// Array of weak references
ObjectArray* weak_refs_;
public:
/**
* Constructor; takes a pointer to ObjectMemory.
*/
GarbageCollector(ObjectMemory *om);
virtual ~GarbageCollector() {
if(weak_refs_) delete weak_refs_;
}
/**
* Subclasses implement appropriate behaviour for handling a live object
* encountered during garbage collection.
*/
virtual Object* saw_object(Object*) = 0;
// Scans the specified Object for references to other Objects.
void scan_object(Object* obj);
void delete_object(Object* obj);
void walk_call_frame(CallFrame* top_call_frame, AddressDisplacement* offset=0);
void saw_variable_scope(CallFrame* call_frame, StackVariables* scope);
/**
* Marks the specified Object +obj+ as live.
*/
Object* mark_object(Object* obj) {
if(!obj || !obj->reference_p()) return obj;
Object* tmp = saw_object(obj);
if(tmp) return tmp;
return obj;
}
void clean_weakrefs(bool check_forwards=false);
// Scans the thread for object references
void scan(ManagedThread* thr, bool young_only);
void scan(VariableRootBuffers& buffers, bool young_only, AddressDisplacement* offset=0);
void scan(RootBuffers& rb, bool young_only);
VM* state();
/**
* Adds a weak reference to the specified object.
*
* A weak reference provides a way to hold a reference to an object without
* that reference being sufficient to keep the object alive. If no other
* reference to the weak-referenced object exists, it can be collected by
* the garbage collector, with the weak-reference subsequently returning
* null.
*/
void add_weak_ref(Object* obj) {
if(!weak_refs_) {
weak_refs_ = new ObjectArray;
}
weak_refs_->push_back(obj);
}
void reset_stats() {
}
friend class ObjectMark;
};
}
#endif
Jump to Line
Something went wrong with that request. Please try again.