diff --git a/vm/builtin/data.cpp b/vm/builtin/data.cpp index 567ca0d265..94aea31dc8 100644 --- a/vm/builtin/data.cpp +++ b/vm/builtin/data.cpp @@ -29,9 +29,9 @@ namespace rubinius { return data; } - void Data::finalize(STATE) { - FreeFunctor f = this->free(); - if(f) f(data()); + void Data::finalize(STATE, Data* data) { + FreeFunctor f = data->free(); + if(f) f(data->data()); } void Data::Info::mark(Object* t, ObjectMark& mark) { diff --git a/vm/builtin/data.hpp b/vm/builtin/data.hpp index 145a5e6039..3d48986c18 100644 --- a/vm/builtin/data.hpp +++ b/vm/builtin/data.hpp @@ -35,7 +35,7 @@ namespace rubinius { /** New Data instance. */ static Data* create(STATE, void* data, MarkFunctor mark, FreeFunctor free); - void finalize(STATE); + static void finalize(STATE, Data* data); RDataExposed* exposed() { return &exposed_; diff --git a/vm/builtin/dir.cpp b/vm/builtin/dir.cpp index 32a3ae55bb..9166b6c98a 100644 --- a/vm/builtin/dir.cpp +++ b/vm/builtin/dir.cpp @@ -24,7 +24,7 @@ namespace rubinius { Dir* d = state->new_object(G(dir)); d->os_ = 0; - state->om->needs_finalization(d); + state->om->needs_finalization(d, (FinalizerFunction)&Dir::finalize); return d; } @@ -39,10 +39,10 @@ namespace rubinius { return dir; } - void Dir::finalize(STATE) { - if(os_) { - closedir(os_); - os_ = 0; + void Dir::finalize(STATE, Dir* dir) { + if(dir->os_) { + closedir(dir->os_); + dir->os_ = 0; } } diff --git a/vm/builtin/dir.hpp b/vm/builtin/dir.hpp index 20061b4a01..fbecc42c08 100644 --- a/vm/builtin/dir.hpp +++ b/vm/builtin/dir.hpp @@ -29,7 +29,7 @@ namespace rubinius { static Dir* create(STATE); - void finalize(STATE); + static void finalize(STATE, Dir* dir); // Ruby.primitive :dir_allocate static Dir* allocate(STATE, Object* self); diff --git a/vm/builtin/fiber.cpp b/vm/builtin/fiber.cpp index 4f7ebd6176..9a456a0c4a 100644 --- a/vm/builtin/fiber.cpp +++ b/vm/builtin/fiber.cpp @@ -37,7 +37,7 @@ namespace rubinius { fib->stack_ = state->stack_start(); fib->context_ = new ucontext_t; - state->om->needs_finalization(fib); + state->om->needs_finalization(fib, (FinalizerFunction)&Fiber::finalize); state->current_fiber.set(fib); } @@ -98,7 +98,7 @@ namespace rubinius { fib->stack_ = malloc(stack_size); fib->context_ = new ucontext_t; - state->om->needs_finalization(fib); + state->om->needs_finalization(fib, (FinalizerFunction)&Fiber::finalize); ucontext_t* ctx = fib->ucontext(); @@ -189,10 +189,10 @@ namespace rubinius { #endif } - void Fiber::finalize(STATE) { + void Fiber::finalize(STATE, Fiber* fib) { #ifdef FIBER_ENABLED - delete context_; - if(stack_ && !root_) free(stack_); + delete fib->context_; + if(fib->stack_ && !fib->root_) free(fib->stack_); #endif } diff --git a/vm/builtin/fiber.hpp b/vm/builtin/fiber.hpp index c19b08fa85..94c8c171d8 100644 --- a/vm/builtin/fiber.hpp +++ b/vm/builtin/fiber.hpp @@ -92,7 +92,7 @@ namespace rubinius { // Ruby.primitive :fiber_s_yield static Object* s_yield(STATE, Arguments& args, CallFrame* calling_environment); - void finalize(STATE); + static void finalize(STATE, Fiber* fib); public: /* TypeInfo */ diff --git a/vm/builtin/io.cpp b/vm/builtin/io.cpp index 52344c7580..0e163d45c6 100644 --- a/vm/builtin/io.cpp +++ b/vm/builtin/io.cpp @@ -43,7 +43,7 @@ namespace rubinius { // Don't bother to add finalization for stdio if(fd >= 3) { - state->om->needs_finalization(io); + state->om->needs_finalization(io, (FinalizerFunction)&IO::finalize); } return io; @@ -60,7 +60,7 @@ namespace rubinius { // Ensure the instance's class is set (i.e. for subclasses of IO) io->klass(state, as(self)); - state->om->needs_finalization(io); + state->om->needs_finalization(io, (FinalizerFunction)&IO::finalize); return io; } @@ -385,15 +385,15 @@ namespace rubinius { mode(state, Fixnum::from((m & ~O_ACCMODE) | O_WRONLY)); } - void IO::finalize(STATE) { - if(descriptor_->nil_p()) return; + void IO::finalize(STATE, IO* io) { + if(io->descriptor()->nil_p()) return; - native_int fd = descriptor_->to_native(); + native_int fd = io->descriptor()->to_native(); // don't close stdin, stdout, stderr (0, 1, 2) if(fd >= 3) { ::close(fd); - descriptor(state, Fixnum::from(-1)); + io->descriptor(state, Fixnum::from(-1)); } } diff --git a/vm/builtin/io.hpp b/vm/builtin/io.hpp index 368240d243..c00a7cc571 100644 --- a/vm/builtin/io.hpp +++ b/vm/builtin/io.hpp @@ -43,7 +43,7 @@ namespace rubinius { void unsafe_set_descriptor(native_int fd); void force_read_only(STATE); void force_write_only(STATE); - void finalize(STATE); + static void finalize(STATE, IO* io); /* Class primitives */ diff --git a/vm/builtin/memorypointer.cpp b/vm/builtin/memorypointer.cpp index 4f96335c79..b3a0325a4e 100644 --- a/vm/builtin/memorypointer.cpp +++ b/vm/builtin/memorypointer.cpp @@ -58,16 +58,17 @@ namespace rubinius { autorelease = val->true_p() ? true : false; if(autorelease && !set_finalizer) { - state->om->needs_finalization(this); + state->om->needs_finalization(this, + (FinalizerFunction)&MemoryPointer::finalize); set_finalizer = true; } return val; } - void MemoryPointer::finalize(STATE) { - if(autorelease && pointer) { - ::free(pointer); + void MemoryPointer::finalize(STATE, MemoryPointer* ptr) { + if(ptr->autorelease && ptr->pointer) { + ::free(ptr->pointer); } } diff --git a/vm/builtin/memorypointer.hpp b/vm/builtin/memorypointer.hpp index 077b3b9754..8c8da039d6 100644 --- a/vm/builtin/memorypointer.hpp +++ b/vm/builtin/memorypointer.hpp @@ -17,7 +17,7 @@ namespace rubinius { static MemoryPointer* create(STATE, void* ptr); - void finalize(STATE); + static void finalize(STATE, MemoryPointer* ptr); // Ruby.primitive :memorypointer_address Integer* get_address(STATE); diff --git a/vm/gc/finalize.hpp b/vm/gc/finalize.hpp index 33b1bcdead..9185eed2ba 100644 --- a/vm/gc/finalize.hpp +++ b/vm/gc/finalize.hpp @@ -1,5 +1,7 @@ namespace rubinius { + typedef void (*FinalizerFunction)(STATE, Object*); + struct FinalizeObject { public: enum FinalizationStatus { @@ -11,11 +13,13 @@ namespace rubinius { public: FinalizeObject() : queue_count(0) + , finalizer(0) {} Object* object; FinalizationStatus status; int queue_count; + FinalizerFunction finalizer; void queued() { status = eQueued; diff --git a/vm/objectmemory.cpp b/vm/objectmemory.cpp index 9abcf2b43d..6d3a064c21 100644 --- a/vm/objectmemory.cpp +++ b/vm/objectmemory.cpp @@ -452,10 +452,11 @@ namespace rubinius { code_manager_.add_resource(cr); } - void ObjectMemory::needs_finalization(Object* obj) { + void ObjectMemory::needs_finalization(Object* obj, FinalizerFunction func) { FinalizeObject fi; fi.object = obj; fi.status = FinalizeObject::eLive; + fi.finalizer = func; // Makes a copy of fi. finalize_.push_back(fi); @@ -466,16 +467,8 @@ namespace rubinius { i != to_finalize_.end(); ) { FinalizeObject* fi = *i; - if(IO* io = try_as(fi->object)) { - io->finalize(state); - } else if(Fiber* fib = try_as(fi->object)) { - fib->finalize(state); - } else if(MemoryPointer* ptr = try_as(fi->object)) { - ptr->finalize(state); - } else if(Data* data = try_as(fi->object)) { - data->finalize(state); - } else if(Dir* dir = try_as(fi->object)) { - dir->finalize(state); + if(fi->finalizer) { + (*fi->finalizer)(state, fi->object); } else { std::cerr << "Unsupported object to be finalized: " << fi->object->to_s(state)->c_str() << "\n"; diff --git a/vm/objectmemory.hpp b/vm/objectmemory.hpp index e46f84b2b9..1cb9d843bb 100644 --- a/vm/objectmemory.hpp +++ b/vm/objectmemory.hpp @@ -193,7 +193,7 @@ namespace rubinius { int mature_bytes_allocated(); - void needs_finalization(Object* obj); + void needs_finalization(Object* obj, FinalizerFunction func = 0); void run_finalizers(STATE); void find_referers(Object* obj, ObjectArray& result);