Skip to content

Commit

Permalink
Clean up GC by making WeakRef first class
Browse files Browse the repository at this point in the history
  • Loading branch information
Evan Phoenix committed Aug 24, 2009
1 parent 0d2d248 commit 90c657e
Show file tree
Hide file tree
Showing 11 changed files with 98 additions and 52 deletions.
24 changes: 15 additions & 9 deletions kernel/bootstrap/weakref.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,28 @@ class WeakRef

class RefError < RuntimeError; end

def initialize(object)
@wr = Rubinius::Tuple.create_weakref(object)
def self.new
Ruby.primitive :weakref_new
raise PrimitiveFailure, "WeakRef.new failed"
end

def inspect
"#<WeakRef:0x#{object_id.to_s(16)} object=#{@wr.at(0).inspect}>"
end

def weakref_alive?
!@wr.at(0).nil?
def __object__
Ruby.primitive :weakref_object
raise PrimitiveFailure, "WeakRef#object failed"
end

def object
obj = @wr.at(0)
obj = __object__()
raise RefError, "Object has been collected as garbage" unless obj
return obj
end

def inspect
"#<WeakRef:0x#{object_id.to_s(16)} object=#{object.inspect}>"
end

def weakref_alive?
!!__object__
end

end
1 change: 1 addition & 0 deletions rakelib/vm.rake
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ field_extract_headers = %w[
vm/builtin/location.hpp
vm/builtin/capi_handle.hpp
vm/builtin/global_cache_entry.hpp
vm/builtin/weakref.hpp
]

EXTERNALS = %W[ vm/external_libs/libmpa/libptr_array.a
Expand Down
6 changes: 0 additions & 6 deletions vm/builtin/tuple.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,12 +165,6 @@ namespace rubinius {
return tuple;
}

Tuple* Tuple::create_weakref(STATE, Object* obj) {
Tuple* tup = Tuple::from(state, 1, obj);
tup->set_refs_are_weak();
return tup;
}

size_t Tuple::Info::object_size(const ObjectHeader* obj) {
const Tuple *tup = reinterpret_cast<const Tuple*>(obj);
assert(tup);
Expand Down
3 changes: 0 additions & 3 deletions vm/builtin/tuple.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,6 @@ namespace rubinius {
// Ruby.primitive :tuple_delete_inplace
Fixnum* delete_inplace(STATE, Fixnum *start, Fixnum *length, Object *obj);

// Ruby.primitive :tuple_create_weakref
static Tuple* create_weakref(STATE, Object* obj);

public: // Inline Functions
Object* at(STATE, size_t index) {
if(num_fields() <= index) {
Expand Down
16 changes: 16 additions & 0 deletions vm/builtin/weakref.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#include "builtin/weakref.hpp"
#include "builtin/class.hpp"

namespace rubinius {
void WeakRef::init(STATE) {
GO(cls_weakref).set(state->new_class("WeakRef", G(object)));
G(cls_weakref)->set_object_type(state, WeakRefType);
}

WeakRef* WeakRef::create(STATE, Object* obj) {
WeakRef* ref = state->new_object<WeakRef>(G(cls_weakref));
ref->set_object(obj);

return ref;
}
}
38 changes: 38 additions & 0 deletions vm/builtin/weakref.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#ifndef RBX_BUILTIN_WEAKREF_HPP
#define RBX_BUILTIN_WEAKREF_HPP

#include "builtin/object.hpp"
#include "builtin/exception.hpp"
#include "type_info.hpp"

namespace rubinius {
class WeakRef : public Object {
public:
const static object_type type = WeakRefType;

private:
Object* object_;

public:

// Ruby.primitive+ :weakref_object
Object* object() {
return object_;
}

void set_object(Object* obj) {
object_ = obj;
}

static void init(STATE);

// Ruby.primitive+ :weakref_new
static WeakRef* create(STATE, Object* obj);

bool alive_p() {
return object_->reference_p();
}
};
}

#endif
45 changes: 23 additions & 22 deletions vm/gc/gc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "builtin/tuple.hpp"
#include "builtin/module.hpp"
#include "builtin/symbol.hpp"
#include "builtin/weakref.hpp"
#include "builtin/compiledmethod.hpp"
#include "call_frame.hpp"
#include "builtin/variable_scope.hpp"
Expand Down Expand Up @@ -58,12 +59,14 @@ namespace rubinius {

// If this object's refs are weak, then add it to the weak_refs
// vector and don't look at it otherwise.
if(obj->refs_are_weak_p()) {
if(!weak_refs_) {
weak_refs_ = new ObjectArray(0);
}
if(WeakRef* ref = try_as<WeakRef>(obj)) {
if(ref->alive_p()) {
if(!weak_refs_) {
weak_refs_ = new ObjectArray(0);
}

weak_refs_->push_back(obj);
weak_refs_->push_back(obj);
}
return;
}

Expand Down Expand Up @@ -315,25 +318,23 @@ namespace rubinius {
for(ObjectArray::iterator i = weak_refs_->begin();
i != weak_refs_->end();
i++) {
// ATM, only a Tuple can be marked weak.
Tuple* tup = as<Tuple>(*i);
for(size_t ti = 0; ti < tup->num_fields(); ti++) {
Object* obj = tup->at(object_memory_->state, ti);

if(!obj->reference_p()) continue;

if(check_forwards) {
if(obj->young_object_p()) {
if(!obj->forwarded_p()) {
tup->field[ti] = Qnil;
} else {
tup->field[ti] = obj->forward();
tup->write_barrier(object_memory_->state, obj->forward());
}
WeakRef* ref = try_as<WeakRef>(*i);
if(!ref) continue; // WTF.

Object* obj = ref->object();
if(!obj->reference_p()) continue;

if(check_forwards) {
if(obj->young_object_p()) {
if(!obj->forwarded_p()) {
ref->set_object(Qnil);
} else {
ref->set_object(obj->forward());
ref->write_barrier(object_memory_, obj->forward());
}
} else if(!obj->marked_p()) {
tup->field[ti] = Qnil;
}
} else if(!obj->marked_p()) {
ref->set_object(Qnil);
}
}

Expand Down
4 changes: 3 additions & 1 deletion vm/globals.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ namespace rubinius {
TypedRoot<Class*> exc_vm_internal;
TypedRoot<Class*> global_cache_entry;
TypedRoot<Class*> array_iterator;
TypedRoot<Class*> cls_weakref;

/* Add new globals above this line. */

Expand Down Expand Up @@ -220,7 +221,8 @@ namespace rubinius {
jump_error(&roots),
exc_vm_internal(&roots),
global_cache_entry(&roots),
array_iterator(&roots)
array_iterator(&roots),
cls_weakref(&roots)

/* Add initialize of globals above this line. */
{ }
Expand Down
2 changes: 2 additions & 0 deletions vm/ontology.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#include "builtin/variable_scope.hpp"
#include "builtin/location.hpp"
#include "builtin/global_cache_entry.hpp"
#include "builtin/weakref.hpp"

#include "configuration.hpp"
#include "config.h"
Expand Down Expand Up @@ -249,6 +250,7 @@ namespace rubinius {
NativeMethod::init(this);

GlobalCacheEntry::init(this);
WeakRef::init(this);
}

// @todo document all the sections of bootstrap_ontology
Expand Down
1 change: 0 additions & 1 deletion vm/oop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ namespace rubinius {
ivars_ = other->ivars_;

Forwarded = 0;
RefsAreWeak = other->RefsAreWeak;
RequiresCleanup = other->RequiresCleanup;
}

Expand Down
10 changes: 0 additions & 10 deletions vm/oop.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,6 @@ const int cUndef = 0x22L;
unsigned int Marked : 2;
unsigned int RequiresCleanup : 1;

unsigned int RefsAreWeak : 1;

unsigned int InImmix : 1;
unsigned int Pinned : 1;
};
Expand Down Expand Up @@ -338,14 +336,6 @@ const int cUndef = 0x22L;
return RequiresCleanup == 1;
}

void set_refs_are_weak() {
RefsAreWeak = 1;
}

bool refs_are_weak_p() {
return RefsAreWeak == 1;
}

bool nil_p() const {
return this == reinterpret_cast<ObjectHeader*>(Qnil);
}
Expand Down

0 comments on commit 90c657e

Please sign in to comment.