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

extract memory specs into separate folder. Memory is notorious to test, and is unreliable depending on the platform.

This commit is contained in:
Charles Lowell 2011-05-03 11:13:55 -05:00
parent 3a1b0cfddf
commit d2017c673d
9 changed files with 171 additions and 158 deletions

View file

@ -1,9 +1,8 @@
module V8::ExtSpec
def self.included(object)
object.class_eval do
before(:all) {c::V8::SetFlagsFromString("--expose-gc")}
before do
@cxt = c::Context::New()
@cxt.Enter()
@ -14,7 +13,7 @@ module V8::ExtSpec
end
end
end
def v8_eval(script, sourcename = "<eval>")
c::Script::New(c::String::New(script), c::String::New(sourcename)).Run()
end
@ -22,22 +21,5 @@ module V8::ExtSpec
def c
V8::C
end
def ruby_gc
if GC.respond_to?(:stress)
current = GC.stress
GC.stress = true
end
yield
ensure
if GC.respond_to?(:stess)
GC.stress = current
end
end
def v8_gc
while !c::V8::IdleNotification();end
v8_eval('gc()', 'gc.js')
end
end

View file

@ -1,42 +0,0 @@
require 'spec_helper'
describe "Memory:" do
include V8::ExtSpec
context "A JavaScript Object reflected into Ruby" do
before do
@weakref_callback = WeakrefCallback.new
end
it "has a strong reference from the ruby side, which is not released until the Ruby reference goes away" do
handle = c::Handle::New(object = c::Object::New())
handle.MakeWeak(nil, @weakref_callback)
ruby_gc do
v8_gc
@weakref_callback.should_not have_been_invoked
handle.should_not be_dead
end
ruby_gc do
object = nil
v8_gc
@weakref_callback.should have_been_invoked
handle.should be_dead
end
end
private
class WeakrefCallback
def call(value, parameters)
@invoked = true
end
def has_been_invoked?
@invoked
end
end
end
#These don't work in 1.8.7. Can't determine why not. I'll probably have to come back to this.
end if RUBY_VERSION >= '1.9.2'

View file

@ -7,16 +7,4 @@ describe V8::C::Object do
v8_eval('var o = new Object()')
v8_eval('o').should be(v8_eval('o'))
end
it "will return a new peer and not barf if the old peer has been garbage collected" do
v8_eval('var o = {foo: "bar"}')
o = v8_eval('o')
old_id = o.object_id
ruby_gc do
o = nil
v8_eval('o').Get(c::String::New("foo")).Utf8Value().should == "bar"
v8_eval('o').object_id.should_not be(old_id)
end
#can't quite get this to work in 1.8. I'm questioning if it's worth the effort
end if RUBY_VERSION >= "1.9.2"
end

View file

@ -2,6 +2,7 @@
require 'v8'
require 'erb'
require Pathname(__FILE__).dirname.join('ext/ext_spec_helper')
require Pathname(__FILE__).dirname.join('../specmem/spec_helper')
def rputs(msg)
puts "<pre>#{ERB::Util.h(msg)}</pre>"
$stdout.flush

View file

@ -2,7 +2,7 @@ require 'spec_helper'
describe V8::Portal::Proxies do
include V8::ExtSpec
# include V8::MemSpec
context "for Ruby objects which are embedded into javascript" do
@ -27,26 +27,6 @@ describe V8::Portal::Proxies do
subject.register_javascript_proxy c::Object::New(), :for => rb_object
expect {subject.register_javascript_proxy c::Object::New(), :for => rb_object}.should raise_error(V8::Portal::Proxies::DoubleProxyError)
end
context "Memory Management" do
it "holds a hard reference to any ruby object which is linked to a javascript proxy" do
rb_object = Object.new
check_not_finalized(rb_object)
subject.register_javascript_proxy c::Object::New(), :for => rb_object
rb_object = nil
end
it "releases the hard reference if its corresponding javascript object has been garbage collected" do
rb_object = Object.new
js_proxy = c::Object::New()
check_finalized(rb_object)
subject.register_javascript_proxy js_proxy, :for => rb_object
rb_object = nil
ruby_gc do
v8_gc()
end
end
end if RUBY_VERSION >= "1.9.2"
end
context "for a JavaScript objects which are embedded into Ruby" do
@ -73,27 +53,6 @@ describe V8::Portal::Proxies do
subject.rb2js(target).should be(proxy)
end
context "Memory Management" do
it "holds a hard reference to any JavaScript object which is linked to a Ruby proxy" do
js_object = c::Object::New()
check_not_finalized(js_object)
subject.register_ruby_proxy Object.new, :for => js_object
js_object = nil
end
it "clears any strong references to the JavaScript object when it's Ruby proxy is garbage collected" do
js_object = c::Object::New()
rb_proxy = Object.new
subject.register_ruby_proxy rb_proxy, :for => js_object
check_finalized(js_object)
js_object = rb_proxy = nil
ruby_gc do
v8_gc
end
end
end if RUBY_VERSION >= "1.9.2"
context "looking up a Ruby object from a random JavaScript object" do
it "checks first if it's a native Ruby object with a javascript proxy" do
target = Object.new
@ -143,47 +102,5 @@ describe V8::Portal::Proxies do
subject.rb2js(rb).should be(proxy)
end
end
end
private
def finalize(object_id)
@finalized ||= {}
@finalized[object_id] = true
end
def check_finalized(object)
@finalized ||= {}
ObjectSpace.define_finalizer(object, method(:finalize))
id_to_check = object.object_id
object = nil
afterwards do
@finalized[id_to_check].should be_true
end
end
def check_not_finalized(object)
@finalized ||= {}
ObjectSpace.define_finalizer(object, method(:finalize))
id_to_check = object.object_id
object = nil
afterwards do
@finalized[id_to_check].should be_false
end
end
def afterwards(&block)
@after ||= []
@after << block if block_given?
end
after do
ruby_gc do
@after.each do |proc|
proc.call
end if @after
end
end if RUBY_VERSION >= '1.9.2'
end

41
specmem/handle_memspec.rb Normal file
View file

@ -0,0 +1,41 @@
require 'spec_helper'
describe V8::C::Handle do
include V8::MemSpec
context "A JavaScript Object reflected into Ruby" do
before do
@weakref_callback = WeakrefCallback.new
end
it "has a strong reference from the ruby side, which is not released until the Ruby reference goes away" do
handle = c::Handle::New(object = c::Object::New())
handle.MakeWeak(nil, @weakref_callback)
ruby_gc do
v8_gc
@weakref_callback.should_not have_been_invoked
handle.should_not be_dead
end
ruby_gc do
object = nil
v8_gc
@weakref_callback.should have_been_invoked
handle.should be_dead
end
end
private
class WeakrefCallback
def call(value, parameters)
@invoked = true
end
def has_been_invoked?
@invoked
end
end
end
end

16
specmem/object_memspec.rb Normal file
View file

@ -0,0 +1,16 @@
require 'spec_helper'
describe V8::C::Object do
include V8::MemSpec
it "will return a new peer and not barf if the old peer has been garbage collected" do
v8_eval('var o = {foo: "bar"}')
o = v8_eval('o')
old_id = o.object_id
ruby_gc do
o = nil
v8_eval('o').Get(c::String::New("foo")).Utf8Value().should == "bar"
v8_eval('o').object_id.should_not be(old_id)
end
end
end

View file

@ -0,0 +1,86 @@
require 'spec_helper'
describe V8::Portal::Proxies do
include V8::MemSpec
context "A Ruby object embedded into JavaScript" do
it "holds a hard reference to any ruby object which is linked to a javascript proxy" do
rb_object = Object.new
check_not_finalized(rb_object)
subject.register_javascript_proxy c::Object::New(), :for => rb_object
rb_object = nil
end
it "releases the hard reference if its corresponding javascript object has been garbage collected" do
rb_object = Object.new
js_proxy = c::Object::New()
check_finalized(rb_object)
subject.register_javascript_proxy js_proxy, :for => rb_object
rb_object = nil
ruby_gc do
v8_gc()
end
end
end
context "A JavaScript object embedded into Ruby" do
it "holds a hard reference to any JavaScript object which is linked to a Ruby proxy" do
js_object = c::Object::New()
check_not_finalized(js_object)
subject.register_ruby_proxy Object.new, :for => js_object
js_object = nil
end
it "clears any strong references to the JavaScript object when it's Ruby proxy is garbage collected" do
js_object = c::Object::New()
rb_proxy = Object.new
subject.register_ruby_proxy rb_proxy, :for => js_object
check_finalized(js_object)
js_object = rb_proxy = nil
ruby_gc do
v8_gc
GC.start
v8_gc
end
end
end
private
def finalize(object_id)
@finalized ||= {}
@finalized[object_id] = true
end
def check_finalized(object)
@finalized ||= {}
ObjectSpace.define_finalizer(object, method(:finalize))
id_to_check = object.object_id
object = nil
afterwards do
@finalized[id_to_check].should be_true
end
end
def check_not_finalized(object)
@finalized ||= {}
ObjectSpace.define_finalizer(object, method(:finalize))
id_to_check = object.object_id
object = nil
afterwards do
@finalized[id_to_check].should be_false
end
end
def afterwards(&block)
@after ||= []
@after << block if block_given?
end
after do
ruby_gc do
@after.each do |proc|
proc.call
end if @after
end
end
end

24
specmem/spec_helper.rb Normal file
View file

@ -0,0 +1,24 @@
require Pathname(__FILE__).dirname.join('../spec/spec_helper')
module V8::MemSpec
def self.included(cls)
cls.class_eval do
include V8::ExtSpec
before(:all) {V8::C::V8::SetFlagsFromString("--expose-gc")}
end
end
def ruby_gc
current = GC.stress
GC.stress = true
yield
ensure
GC.stress = current
end
def v8_gc
while !c::V8::IdleNotification();end
v8_eval('gc()', 'gc.js')
end
end