Permalink
Browse files

Destroy remaining proxies with the runtime.

This is better than trying to keep the runtime alive longer than the
proxies, because that breaks down during interpreter shutdown -- as
evidenced by the complaints that were appearing as soon as we had a
failing test, and upon an Interrupt.
  • Loading branch information...
1 parent 6074fee commit d02834bbe77181ee9994d9dea63b6c39a78f9816 @matthewd matthewd committed Sep 20, 2009
@@ -462,8 +462,6 @@ static void finalize(RubyLandProxy* proxy)
{
// remove our GC handle on the JS value
JS_RemoveRootRT(proxy->runtime->js, &(proxy->key));
-
- johnson_runtime_unref(proxy->runtime);
}
free(proxy);
@@ -495,17 +493,16 @@ JSBool unwrap_ruby_land_proxy(JohnsonRuntime* runtime, VALUE wrapped, jsval* ret
VALUE make_ruby_land_proxy(JohnsonRuntime* runtime, jsval value, const char const* root_name)
{
- VALUE id = (VALUE)JS_HashTableLookup(runtime->jsids, (void *)value);
+ RubyLandProxy * our_proxy = (RubyLandProxy *)JS_HashTableLookup(runtime->jsids, (void *)value);
- if (id)
+ if (our_proxy)
{
// if we already have a proxy, return it
- return id;
+ return our_proxy->self;
}
else
{
// otherwise make one and cache it
- RubyLandProxy* our_proxy;
VALUE proxy = Data_Make_Struct((strncmp(root_name, "JSScriptProxy", strlen("JSScriptProxy")) ? proxy_class : script_class), RubyLandProxy, 0, finalize, our_proxy);
JSContext * context = johnson_get_current_context(runtime);
@@ -515,14 +512,16 @@ VALUE make_ruby_land_proxy(JohnsonRuntime* runtime, jsval value, const char cons
our_proxy->runtime = runtime;
our_proxy->key = (void *)value;
+ our_proxy->self = proxy;
// root the value for JS GC and lookups
JCHECK(JS_AddNamedRootRT(runtime->js, &(our_proxy->key), root_name));
// put the proxy OID in the id map
- JCHECK(JS_HashTableAdd(runtime->jsids, (void *)value, (void *)proxy));
+ JCHECK(JS_HashTableAdd(runtime->jsids, (void *)value, (void *)our_proxy));
- johnson_runtime_ref(runtime);
+ VALUE rb_runtime = (VALUE)JS_GetRuntimePrivate(runtime->js);
+ rb_iv_set(proxy, "@runtime", rb_runtime);
JRETURN_RUBY(proxy);
}
@@ -21,6 +21,7 @@
typedef struct {
void* key;
JohnsonRuntime* runtime;
+ VALUE self;
} RubyLandProxy;
bool ruby_value_is_proxy(VALUE maybe_proxy);
View
@@ -6,8 +6,6 @@
#include "jroot.h"
#include "ruby_land_proxy.h"
-static VALUE live_runtimes;
-
/*
* call-seq:
* global
@@ -272,8 +270,6 @@ initialize_native(VALUE self, VALUE UNUSED(options))
JohnsonRuntime* runtime;
Data_Get_Struct(self, JohnsonRuntime, runtime);
- runtime->refs = 0;
-
if ((runtime->js = JS_NewRuntime(0x100000))
&& (runtime->jsids = create_id_hash())
&& (runtime->rbids = create_id_hash()))
@@ -310,24 +306,14 @@ JSContext* johnson_get_current_context(JohnsonRuntime * runtime)
return context->js;
}
-void johnson_runtime_ref(JohnsonRuntime* runtime)
+static int proxy_cleanup_enumerator(JSHashEntry *entry, int i, void* arg)
{
- runtime->refs++;
- if (runtime->refs == 1)
- {
- VALUE self = (VALUE)JS_GetRuntimePrivate(runtime->js);
- rb_hash_aset(live_runtimes, self, Qtrue);
- }
-}
-
-void johnson_runtime_unref(JohnsonRuntime* runtime)
-{
- runtime->refs--;
- if (runtime->refs == 0)
- {
- VALUE self = (VALUE)JS_GetRuntimePrivate(runtime->js);
- rb_hash_delete(live_runtimes, self);
- }
+ JohnsonRuntime *runtime = (JohnsonRuntime*)(arg);
+ // entry->key is jsval; entry->value is RubyLandProxy*
+ RubyLandProxy * proxy = (RubyLandProxy *)(entry->value);
+ JS_RemoveRootRT(runtime->js, &(proxy->key));
+ proxy->runtime = NULL;
+ return 0;
}
static void deallocate(JohnsonRuntime* runtime)
@@ -344,6 +330,10 @@ static void deallocate(JohnsonRuntime* runtime)
iterator = NULL;
}
+ JSContext* cleanup = JS_NewContext(runtime->js, 8192L);
+ JS_HashTableEnumerateEntries(runtime->jsids, proxy_cleanup_enumerator, runtime);
+ JS_DestroyContext(cleanup);
+
JS_DestroyRuntime(runtime->js);
free(runtime);
}
@@ -358,9 +348,6 @@ void init_Johnson_SpiderMonkey_Runtime(VALUE spidermonkey)
{
VALUE klass = rb_define_class_under(spidermonkey, "Runtime", rb_cObject);
- live_runtimes = rb_hash_new();
- rb_iv_set(klass, "@live_runtimes", live_runtimes);
-
rb_define_alloc_func(klass, allocate);
rb_define_private_method(klass, "initialize_native", initialize_native, 1);
@@ -19,14 +19,9 @@ typedef struct {
JSHashTable *jsids; // jsid -> rbid
JSHashTable *rbids; // rbid -> jsid
-
- int refs;
} JohnsonRuntime;
JSContext* johnson_get_current_context(JohnsonRuntime* runtime);
void init_Johnson_SpiderMonkey_Runtime(VALUE spidermonkey);
-void johnson_runtime_ref(JohnsonRuntime* runtime);
-void johnson_runtime_unref(JohnsonRuntime* runtime);
-
#endif

0 comments on commit d02834b

Please sign in to comment.