mirror of
https://github.com/rubyjs/therubyracer
synced 2023-03-27 23:21:42 -04:00
allocate a handle's payload wrapper beforehand, that way it is not allocated during GC.
This commit is contained in:
parent
56359f4bf3
commit
6a43f6b13a
2 changed files with 13 additions and 13 deletions
|
@ -18,15 +18,24 @@ v8_handle::v8_handle(Handle<void> object) {
|
||||||
v8_handle::~v8_handle() {}
|
v8_handle::~v8_handle() {}
|
||||||
|
|
||||||
v8_handle::Payload::Payload(Handle<void> object) {
|
v8_handle::Payload::Payload(Handle<void> object) {
|
||||||
|
rb_gc_register_address(&wrapper);
|
||||||
handle = Persistent<void>::New(object);
|
handle = Persistent<void>::New(object);
|
||||||
|
wrapper = Data_Wrap_Struct(rb_cObject, 0, destroy, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
v8_handle::Payload::~Payload() {
|
||||||
|
rb_gc_unregister_address(&wrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
v8_handle::Payload::~Payload() {}
|
|
||||||
void v8_handle::Payload::release() {
|
void v8_handle::Payload::release() {
|
||||||
handle.Dispose();
|
handle.Dispose();
|
||||||
handle.Clear();
|
handle.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void v8_handle::Payload::destroy(v8_handle::Payload* payload) {
|
||||||
|
delete payload;
|
||||||
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
/**
|
/**
|
||||||
* Holds dead references, that are no longer being held in Ruby, so that they can be garbage collected
|
* Holds dead references, that are no longer being held in Ruby, so that they can be garbage collected
|
||||||
|
@ -44,14 +53,6 @@ namespace {
|
||||||
rb_gc_mark(handle->weakref_callback_parameters);
|
rb_gc_mark(handle->weakref_callback_parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Deallocates this handle. This function is invoked on Zombie handles after they have
|
|
||||||
* been released from V8 and finally
|
|
||||||
*/
|
|
||||||
void v8_handle_free(v8_handle::Payload* payload) {
|
|
||||||
delete payload;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whenver a V8::C::Handle becomes garbage collected, we do not free it immediately.
|
* Whenver a V8::C::Handle becomes garbage collected, we do not free it immediately.
|
||||||
* instead, we put them into a "zombie" queue, where its corresponding V8 storage cell
|
* instead, we put them into a "zombie" queue, where its corresponding V8 storage cell
|
||||||
|
@ -60,8 +61,7 @@ namespace {
|
||||||
*/
|
*/
|
||||||
void v8_handle_enqueue(v8_handle* handle) {
|
void v8_handle_enqueue(v8_handle* handle) {
|
||||||
handle->dead = true;
|
handle->dead = true;
|
||||||
VALUE payload = Data_Wrap_Struct(rb_cObject, 0, v8_handle_free, handle->payload);
|
rb_ary_unshift(handle_queue, handle->payload->wrapper);
|
||||||
rb_ary_unshift(handle_queue, payload);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -113,8 +113,6 @@ namespace {
|
||||||
}
|
}
|
||||||
value.Dispose();
|
value.Dispose();
|
||||||
handle->payload->release();
|
handle->payload->release();
|
||||||
// handle->handle.Dispose();
|
|
||||||
// handle->handle.Clear();
|
|
||||||
handle->dead = true;
|
handle->dead = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,9 @@ struct v8_handle {
|
||||||
Payload(v8::Handle<void> object);
|
Payload(v8::Handle<void> object);
|
||||||
virtual ~Payload();
|
virtual ~Payload();
|
||||||
void release();
|
void release();
|
||||||
|
static void destroy(v8_handle::Payload* payload);
|
||||||
v8::Persistent<void> handle;
|
v8::Persistent<void> handle;
|
||||||
|
VALUE wrapper;
|
||||||
};
|
};
|
||||||
|
|
||||||
v8_handle(v8::Handle<void> object);
|
v8_handle(v8::Handle<void> object);
|
||||||
|
|
Loading…
Reference in a new issue