1
0
Fork 0
mirror of https://github.com/rubyjs/therubyracer synced 2023-03-27 23:21:42 -04:00

handle checkpoint.

This commit is contained in:
Charles Lowell 2011-04-07 11:49:47 -05:00
parent fdb62441b1
commit 0ffce72fe1
5 changed files with 140 additions and 42 deletions

View file

@ -1,3 +1,4 @@
#include "v8_handle.h"
#include "v8_cxt.h"
#include "v8_value.h"
#include "v8_str.h"
@ -19,27 +20,28 @@
#include <stdio.h>
extern "C" {
void Init_v8();
void Init_v8();
}
extern "C" {
void Init_v8() {
rr_init_cxt();
rr_init_value();
rr_init_str();
rr_init_script();
rr_init_template();
rr_init_obj();
rr_init_func();
rr_init_v8_array();
rr_init_v8_date();
rr_init_msg();
rr_init_v8_try_catch();
rr_init_v8_callbacks();
rr_init_v8_external();
rr_init_v8_exception();
rr_init_v8_locker();
rr_init_v8_debug();
rr_init_v8_v8();
}
void Init_v8() {
rr_init_handle();
rr_init_cxt();
rr_init_value();
rr_init_str();
rr_init_script();
rr_init_template();
rr_init_obj();
rr_init_func();
rr_init_v8_array();
rr_init_v8_date();
rr_init_msg();
rr_init_v8_try_catch();
rr_init_v8_callbacks();
rr_init_v8_external();
rr_init_v8_exception();
rr_init_v8_locker();
rr_init_v8_debug();
rr_init_v8_v8();
}
}

View file

@ -27,10 +27,8 @@ namespace {
return (VALUE)V8_Ref_Get<External>(self)->Value();
}
void GCWeakReferenceCallback(Persistent<Value> object, void* parameter) {
// printf("V8 GC!!!!\n");
Local<External> external(External::Cast(*object));
rb_hash_delete(references, rb_obj_id((VALUE)external->Value()));
// V8::AdjustAmountOfExternalAllocatedMemory(-100000000);
}
}
@ -51,7 +49,6 @@ Handle<Value> rr_v8_external_create(VALUE value) {
rb_hash_aset(references, rb_obj_id(value), value);
Local<Value> external(External::New((void *)value));
Persistent<Value> record = Persistent<Value>::New(external);
// V8::AdjustAmountOfExternalAllocatedMemory(100000000);
record.MakeWeak(NULL, GCWeakReferenceCallback);
return external;
}

60
ext/v8/v8_handle.cpp Normal file
View file

@ -0,0 +1,60 @@
#include "rr.h"
#include "v8_ref.h"
using namespace v8;
namespace {
VALUE New(VALUE self, VALUE handle) {
return rr_v8_ref_create(self, rr_v8_handle(handle));
}
VALUE IsEmpty(VALUE self) {
return rr_v82rb(rr_v8_handle(self).IsEmpty());
}
VALUE Clear(VALUE self) {
rr_v8_handle(self).Clear();
return Qnil;
}
VALUE Dispose(VALUE self) {
rr_v8_handle(self).Dispose();
return Qnil;
}
void NoopWeakReferenceCallback(Persistent<Value> object, void* parameter) {}
VALUE MakeWeak(VALUE self) {
rr_v8_handle(self).MakeWeak(0, NoopWeakReferenceCallback);
return Qnil;
}
VALUE ClearWeak(VALUE self) {
rr_v8_handle(self).ClearWeak();
return Qnil;
}
VALUE IsNearDeath(VALUE self) {
return rr_v82rb(rr_v8_handle(self).IsNearDeath());
}
VALUE IsWeak(VALUE self) {
return rr_v82rb(rr_v8_handle(self).IsWeak());
}
}
void rr_init_handle() {
VALUE HandleClass = rr_define_class("Handle");
rr_define_singleton_method(HandleClass, "New", New, 1);
rr_define_method(HandleClass, "IsEmpty", IsEmpty, 0);
rr_define_method(HandleClass, "Clear", Clear, 0);
rr_define_method(HandleClass, "Dispose", Dispose, 0);
rr_define_method(HandleClass, "MakeWeak", MakeWeak, 0);
rr_define_method(HandleClass, "ClearWeak", ClearWeak, 0);
rr_define_method(HandleClass, "IsNearDeath", IsNearDeath, 0);
rr_define_method(HandleClass, "IsWeak", IsWeak, 0);
}

8
ext/v8/v8_handle.h Normal file
View file

@ -0,0 +1,8 @@
#ifndef _RR_V8_HANDLE_
#define _RR_V8_HANDLE_
void rr_init_handle();
VALUE rr_v8_handle_new(v8::Local<void>& handle);
VALUE rr_v8_handle_new(v8::Persistent<void>& handle);
#endif

View file

@ -4,37 +4,56 @@ require 'weakref'
describe "Memory Usage" do
context "for low level C interface" do
it "does not leak a context" do
weak :context, V8::C::Context::New()
context "the low level C interface" do
context "at the very minimum" do
it "does not leak a context" do
weak :context, V8::C::Context::New()
end
it "does not leak a simple object either" do
cxt = V8::C::Context::New()
cxt.Enter()
begin
weak :object, V8::C::Object::New()
ensure
cxt.Exit()
end
end
end
it "does not leak a simple object either" do
cxt = V8::C::Context::New()
cxt.Enter()
begin
weak :object, V8::C::Object::New()
ensure
cxt.Exit()
context "a ruby proxy for a JavaScript object" do
it "holds a strong reference to the JavaScript object" do
pending
cxt = V8::C::Context::New()
handle = c::Handle::New(cxt)
handle.MakeWeak()
gc do
handle.IsEmpty().should be_false
handle.IsNearDeath().should be_false
handle.IsWeak().should be_true
end
cxt = nil
gc do
# handle.IsEmpty().should be_true
handle.IsNearDeath().should be_true
end
end
end
end
before(:all) {GC.stress = true}
after(:all) {GC.stress = false}
before(:all) {@stress = GC.stress; GC.stress = true}
after(:all) {GC.stress = @stress}
before do
@refs = {}
end
after do
GC.start
while !V8::C::V8::IdleNotification();end
GC.start
while !V8::C::V8::IdleNotification();end
for name, ref in @refs
if ref.weakref_alive?
fail "refererc #{name} was not garbage collected"
gc do
for name, ref in @refs
if ref.weakref_alive?
fail "reference #{name} was not garbage collected"
end
end
end
end
@ -45,4 +64,16 @@ describe "Memory Usage" do
@refs[name] = WeakRef.new(ref)
end
def gc
GC.start
while !V8::C::V8::IdleNotification();end
GC.start
while !V8::C::V8::IdleNotification();end
yield
end
def c
V8::C
end
end if GC.respond_to?(:stress=)