Permalink
Browse files

Track gcthings on the runtime, not the context.

Otherwise, we can release our GC reference because the context's thread
goes away, even though rbids still references it. Which is Bad.
  • Loading branch information...
1 parent 7edeccc commit 0795f89d90daab6c753ed9a6877f47e13218d795 @matthewd matthewd committed Jun 17, 2008
@@ -184,6 +184,7 @@ VALUE convert_to_ruby(JohnsonRuntime* runtime, jsval js)
JSContext * context = johnson_get_current_context(runtime);
PREPARE_RUBY_JROOTS(context, 1);
+ JROOT(js);
switch (JS_TypeOfValue(context, js))
{
@@ -192,8 +193,6 @@ VALUE convert_to_ruby(JohnsonRuntime* runtime, jsval js)
case JSTYPE_FUNCTION:
case JSTYPE_OBJECT:
- JROOT(js);
-
if (OBJECT_TO_JSVAL(runtime->global) == js)
// global gets special treatment, since the Prelude might not be loaded
JRETURN_RUBY(make_ruby_land_proxy(runtime, js));
@@ -547,12 +547,12 @@ static void finalize(JSContext* js_context, JSObject* obj)
VALUE self = (VALUE)JS_GetInstancePrivate(context->js, obj,
JS_GET_CLASS(context->js, obj), NULL);
-
+
// remove the proxy OID from the id map
JS_HashTableRemove(runtime->rbids, (void *)self);
// free up the ruby value for GC
- call_ruby_from_js(runtime, NULL, ruby_context, rb_intern("remove_gcthing"), 1, self);
+ call_ruby_from_js(runtime, NULL, ruby_runtime, rb_intern("remove_gcthing"), 1, self);
}
}
@@ -601,8 +601,8 @@ JSBool make_js_land_proxy(JohnsonRuntime* runtime, VALUE value, jsval* retval)
JCHECK(JS_HashTableAdd(runtime->rbids, (void *)value, (void *)(*retval)));
// root the ruby value for GC
- VALUE ruby_context = (VALUE)JS_GetContextPrivate(context);
- rb_funcall(ruby_context, rb_intern("add_gcthing"), 1, value);
+ VALUE ruby_runtime = (VALUE)JS_GetRuntimePrivate(runtime->js);
+ rb_funcall(ruby_runtime, rb_intern("add_gcthing"), 1, value);
JRETURN;
}
@@ -128,9 +128,10 @@ function_p(VALUE self)
RubyLandProxy* proxy;
Data_Get_Struct(self, RubyLandProxy, proxy);
JSContext * context = johnson_get_current_context(proxy->runtime);
- PREPARE_RUBY_JROOTS(context, 0);
+ PREPARE_RUBY_JROOTS(context, 1);
jsval proxy_value;
JCHECK(get_jsval_for_proxy(proxy, &proxy_value));
+ JROOT(proxy_value);
JRETURN_RUBY(JS_TypeOfValue(context, proxy_value) == JSTYPE_FUNCTION ? Qtrue : Qfalse);
}
@@ -3,19 +3,8 @@ module SpiderMonkey #:nodoc:
class Context # native
def initialize(runtime, options={})
@runtime = runtime
- @gcthings = {}
initialize_native(runtime, options)
end
-
- # called from js_land_proxy.c:make_js_land_proxy
- def add_gcthing(thing)
- @gcthings[thing.object_id] = thing
- end
-
- # called from js_land_proxy.c:finalize
- def remove_gcthing(thing)
- @gcthings.delete(thing.object_id)
- end
end
end
end
@@ -4,11 +4,23 @@ class Runtime # native
CONTEXT_MAP_KEY = :johnson_context_map
def initialize(options={})
- initialize_native(options)
@debugger = nil
@compiled_scripts = {}
+ @gcthings = {}
+ initialize_native(options)
self["Ruby"] = Object
end
+
+ # called from js_land_proxy.c:make_js_land_proxy
+ def add_gcthing(thing)
+ @gcthings[thing.object_id] = thing
+ end
+
+ # called from js_land_proxy.c:finalize
+ def remove_gcthing(thing)
+ @gcthings.delete(thing.object_id)
+ end
+
def current_context
contexts = (Thread.current[CONTEXT_MAP_KEY] ||= {})

0 comments on commit 0795f89

Please sign in to comment.