[gjs/wip/ptomato/mozjs52: 34/37] WIP - js: Remove JSRuntime
- From: Philip Chimento <pchimento src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs/wip/ptomato/mozjs52: 34/37] WIP - js: Remove JSRuntime
- Date: Sun, 25 Jun 2017 06:57:08 +0000 (UTC)
commit 14966f67a47193006a1c294b7adbabc42fddb7ee
Author: Philip Chimento <philip chimento gmail com>
Date: Tue May 2 23:15:10 2017 -0700
WIP - js: Remove JSRuntime
JSRuntime is merged into JSContext in SpiderMonkey 52.
FIXME: Should probably reorganize these files since "runtime.cpp" doesn't
make sense anymore.
gi/function.cpp | 4 +-
gi/value.cpp | 5 +-
gjs/context-private.h | 3 +
gjs/context.cpp | 68 +++++++++++++++++--
gjs/runtime.cpp | 182 ++++++++-----------------------------------------
gjs/runtime.h | 8 +--
6 files changed, 100 insertions(+), 170 deletions(-)
---
diff --git a/gi/function.cpp b/gi/function.cpp
index 1a89821..32d518a 100644
--- a/gi/function.cpp
+++ b/gi/function.cpp
@@ -173,7 +173,6 @@ gjs_callback_closure(ffi_cif *cif,
void *data)
{
JSContext *context;
- JSRuntime *runtime;
JSObject *func_obj;
GjsCallbackTrampoline *trampoline;
int i, n_args, n_jsargs, n_outargs;
@@ -186,8 +185,7 @@ gjs_callback_closure(ffi_cif *cif,
gjs_callback_trampoline_ref(trampoline);
context = trampoline->context;
- runtime = JS_GetRuntime(context);
- if (G_UNLIKELY (gjs_runtime_is_sweeping(runtime))) {
+ if (G_UNLIKELY(_gjs_context_is_sweeping(context))) {
g_critical("Attempting to call back into JSAPI during the sweeping phase of GC. "
"This is most likely caused by not destroying a Clutter actor or Gtk+ "
"widget with ::destroy signals connected, but can also be caused by "
diff --git a/gi/value.cpp b/gi/value.cpp
index 9c95ead..2e6032d 100644
--- a/gi/value.cpp
+++ b/gi/value.cpp
@@ -36,6 +36,7 @@
#include "union.h"
#include "gtype.h"
#include "gerror.h"
+#include "gjs/context-private.h"
#include "gjs/jsapi-wrapper.h"
#include <girepository.h>
@@ -118,7 +119,6 @@ closure_marshal(GClosure *closure,
gpointer marshal_data)
{
JSContext *context;
- JSRuntime *runtime;
JSObject *obj;
unsigned i;
GSignalQuery signal_query = { 0, };
@@ -137,8 +137,7 @@ closure_marshal(GClosure *closure,
}
context = gjs_closure_get_context(closure);
- runtime = JS_GetRuntime(context);
- if (G_UNLIKELY (gjs_runtime_is_sweeping(runtime))) {
+ if (G_UNLIKELY(_gjs_context_is_sweeping(context))) {
GSignalInvocationHint *hint = (GSignalInvocationHint*) invocation_hint;
g_critical("Attempting to call back into JSAPI during the sweeping phase of GC. "
diff --git a/gjs/context-private.h b/gjs/context-private.h
index 2d8834d..4006eee 100644
--- a/gjs/context-private.h
+++ b/gjs/context-private.h
@@ -27,6 +27,7 @@
#include <inttypes.h>
#include "context.h"
+#include "jsapi-wrapper.h"
G_BEGIN_DECLS
@@ -42,6 +43,8 @@ bool _gjs_context_get_is_owner_thread(GjsContext *js_context);
bool _gjs_context_should_exit(GjsContext *js_context,
uint8_t *exit_code_p);
+bool _gjs_context_is_sweeping(JSContext *cx);
+
G_END_DECLS
#endif /* __GJS_CONTEXT_PRIVATE_H__ */
diff --git a/gjs/context.cpp b/gjs/context.cpp
index 9d91431..891083a 100644
--- a/gjs/context.cpp
+++ b/gjs/context.cpp
@@ -66,7 +66,6 @@ static void gjs_context_set_property (GObject *object,
struct _GjsContext {
GObject parent;
- JSRuntime *runtime;
JSContext *context;
JS::Heap<JSObject*> global;
GThread *owner_thread;
@@ -76,6 +75,7 @@ struct _GjsContext {
char **search_path;
bool destroying;
+ bool in_gc_sweep;
bool should_exit;
uint8_t exit_code;
@@ -265,6 +265,59 @@ gjs_printerr(JSContext *context,
}
static void
+on_finalize(JSFreeOp *fop,
+ JSFinalizeStatus status,
+ bool isCompartment,
+ void *data)
+{
+ auto js_context = static_cast<GjsContext *>(data);
+ /* Implementation note for mozjs 24:
+ * sweeping happens in two phases, in the first phase all
+ * GC things from the allocation arenas are queued for
+ * sweeping, then the actual sweeping happens.
+ * The first phase is marked by JSFINALIZE_GROUP_START,
+ * the second one by JSFINALIZE_GROUP_END, and finally
+ * we will see JSFINALIZE_COLLECTION_END at the end of
+ * all GC.
+ * (see jsgc.cpp, BeginSweepPhase/BeginSweepingZoneGroup
+ * and SweepPhase, all called from IncrementalCollectSlice).
+ * Incremental GC muds the waters, because BeginSweepPhase
+ * is always run to entirety, but SweepPhase can be run
+ * incrementally and mixed with JS code runs or even
+ * native code, when MaybeGC/IncrementalGC return.
+ *
+ * Luckily for us, objects are treated specially, and
+ * are not really queued for deferred incremental
+ * finalization (unless they are marked for background
+ * sweeping). Instead, they are finalized immediately
+ * during phase 1, so the following guarantees are
+ * true (and we rely on them)
+ * - phase 1 of GC will begin and end in the same JSAPI
+ * call (ie, our callback will be called with GROUP_START
+ * and the triggering JSAPI call will not return until
+ * we see a GROUP_END)
+ * - object finalization will begin and end in the same
+ * JSAPI call
+ * - therefore, if there is a finalizer frame somewhere
+ * in the stack, gjs_runtime_is_sweeping() will return
+ * true.
+ *
+ * Comments in mozjs24 imply that this behavior might
+ * change in the future, but it hasn't changed in
+ * mozilla-central as of 2014-02-23. In addition to
+ * that, the mozilla-central version has a huge comment
+ * in a different portion of the file, explaining
+ * why finalization of objects can't be mixed with JS
+ * code, so we can probably rely on this behavior.
+ */
+
+ if (status == JSFINALIZE_GROUP_START)
+ js_context->in_gc_sweep = true;
+ else if (status == JSFINALIZE_GROUP_END)
+ js_context->in_gc_sweep = false;
+}
+
+static void
on_garbage_collect(JSContext *cx,
JSGCStatus status,
void *data)
@@ -433,7 +486,6 @@ gjs_context_dispose(GObject *object)
/* Tear down JS */
JS_DestroyContext(js_context->context);
js_context->context = NULL;
- g_clear_pointer(&js_context->runtime, gjs_runtime_unref);
}
}
@@ -481,11 +533,9 @@ gjs_context_constructed(GObject *object)
G_OBJECT_CLASS(gjs_context_parent_class)->constructed(object);
- js_context->runtime = gjs_runtime_ref();
-
js_context->owner_thread = g_thread_self();
- js_context->context = JS_NewContext(js_context->runtime, 8192 /* stack chunk size */);
+ js_context->context = gjs_create_js_context(js_context);
if (js_context->context == NULL)
g_error("Failed to create javascript context");
@@ -500,6 +550,7 @@ gjs_context_constructed(GObject *object)
JS_BeginRequest(js_context->context);
+ JS_AddFinalizeCallback(js_context->context, on_finalize, js_context);
JS_SetGCCallback(js_context->context, on_garbage_collect, js_context);
/* set ourselves as the private data */
@@ -669,6 +720,13 @@ _gjs_context_get_is_owner_thread(GjsContext *js_context)
return js_context->owner_thread == g_thread_self();
}
+bool
+_gjs_context_is_sweeping(JSContext *cx)
+{
+ auto js_context = static_cast<GjsContext *>(JS_GetContextPrivate(cx));
+ return js_context->in_gc_sweep;
+}
+
/**
* gjs_context_maybe_gc:
* @context: a #GjsContext
diff --git a/gjs/runtime.cpp b/gjs/runtime.cpp
index 3c9c206..356d687 100644
--- a/gjs/runtime.cpp
+++ b/gjs/runtime.cpp
@@ -26,6 +26,7 @@
#include "jsapi-wrapper.h"
#include <js/Initialization.h>
+#include "context.h"
#include "jsapi-util.h"
#include "runtime.h"
@@ -34,19 +35,6 @@
#include <windows.h>
#endif
-struct RuntimeData {
- unsigned refcount;
- bool in_gc_sweep;
-};
-
-bool
-gjs_runtime_is_sweeping (JSRuntime *runtime)
-{
- RuntimeData *data = (RuntimeData*) JS_GetRuntimePrivate(runtime);
-
- return data->in_gc_sweep;
-}
-
/* Implementations of locale-specific operations; these are used
* in the implementation of String.localeCompare(), Date.toLocaleDateString(),
* and so forth. We take the straight-forward approach of converting
@@ -144,18 +132,6 @@ gjs_locale_to_unicode (JSContext *context,
return success;
}
-static void
-destroy_runtime(gpointer data)
-{
- JSRuntime *runtime = (JSRuntime *) data;
- RuntimeData *rtdata = (RuntimeData *) JS_GetRuntimePrivate(runtime);
-
- JS_DestroyRuntime(runtime);
- g_free(rtdata);
-}
-
-static GPrivate thread_runtime = G_PRIVATE_INIT(destroy_runtime);
-
static JSLocaleCallbacks gjs_locale_callbacks =
{
gjs_locale_to_upper_case,
@@ -164,68 +140,6 @@ static JSLocaleCallbacks gjs_locale_callbacks =
gjs_locale_to_unicode
};
-static void
-gjs_finalize_callback(JSFreeOp *fop,
- JSFinalizeStatus status,
- bool isCompartment,
- void *user_data)
-{
- RuntimeData *data = static_cast<RuntimeData *>(user_data);
-
- /* Implementation note for mozjs 24:
- sweeping happens in two phases, in the first phase all
- GC things from the allocation arenas are queued for
- sweeping, then the actual sweeping happens.
- The first phase is marked by JSFINALIZE_GROUP_START,
- the second one by JSFINALIZE_GROUP_END, and finally
- we will see JSFINALIZE_COLLECTION_END at the end of
- all GC.
- (see jsgc.cpp, BeginSweepPhase/BeginSweepingZoneGroup
- and SweepPhase, all called from IncrementalCollectSlice).
- Incremental GC muds the waters, because BeginSweepPhase
- is always run to entirety, but SweepPhase can be run
- incrementally and mixed with JS code runs or even
- native code, when MaybeGC/IncrementalGC return.
-
- Luckily for us, objects are treated specially, and
- are not really queued for deferred incremental
- finalization (unless they are marked for background
- sweeping). Instead, they are finalized immediately
- during phase 1, so the following guarantees are
- true (and we rely on them)
- - phase 1 of GC will begin and end in the same JSAPI
- call (ie, our callback will be called with GROUP_START
- and the triggering JSAPI call will not return until
- we see a GROUP_END)
- - object finalization will begin and end in the same
- JSAPI call
- - therefore, if there is a finalizer frame somewhere
- in the stack, gjs_runtime_is_sweeping() will return
- true.
-
- Comments in mozjs24 imply that this behavior might
- change in the future, but it hasn't changed in
- mozilla-central as of 2014-02-23. In addition to
- that, the mozilla-central version has a huge comment
- in a different portion of the file, explaining
- why finalization of objects can't be mixed with JS
- code, so we can probably rely on this behavior.
- */
-
- if (status == JSFINALIZE_GROUP_START)
- data->in_gc_sweep = true;
- else if (status == JSFINALIZE_GROUP_END)
- data->in_gc_sweep = false;
-}
-
-/* Destroys the current thread's runtime regardless of refcount. No-op if there
- * is no runtime */
-static void
-gjs_destroy_runtime_for_current_thread(void)
-{
- g_private_replace(&thread_runtime, NULL);
-}
-
#ifdef G_OS_WIN32
HMODULE gjs_dll;
static bool gjs_is_inited = false;
@@ -243,7 +157,6 @@ LPVOID lpvReserved)
break;
case DLL_THREAD_DETACH:
- gjs_destroy_runtime_for_current_thread();
JS_ShutDown ();
break;
@@ -264,8 +177,6 @@ public:
}
~GjsInit() {
- /* No-op if the runtime was already destroyed */
- gjs_destroy_runtime_for_current_thread();
JS_ShutDown();
}
@@ -277,69 +188,32 @@ public:
static GjsInit gjs_is_inited;
#endif
-static JSRuntime *
-gjs_runtime_for_current_thread(void)
-{
- JSRuntime *runtime = (JSRuntime *) g_private_get(&thread_runtime);
- RuntimeData *data;
-
- if (!runtime) {
- g_assert(gjs_is_inited);
- runtime = JS_NewRuntime(32 * 1024 * 1024 /* max bytes */);
- if (runtime == NULL)
- g_error("Failed to create javascript runtime");
-
- data = g_new0(RuntimeData, 1);
- JS_SetRuntimePrivate(runtime, data);
-
- // commented are defaults in moz-24
- JS_SetNativeStackQuota(runtime, 1024*1024);
- JS_SetGCParameter(runtime, JSGC_MAX_MALLOC_BYTES, 128*1024*1024);
- JS_SetGCParameter(runtime, JSGC_MAX_BYTES, -1);
- JS_SetGCParameter(runtime, JSGC_MODE, JSGC_MODE_INCREMENTAL);
- JS_SetGCParameter(runtime, JSGC_SLICE_TIME_BUDGET, 10); /* ms */
- // JS_SetGCParameter(runtime, JSGC_HIGH_FREQUENCY_TIME_LIMIT, 1000); /* ms */
- JS_SetGCParameter(runtime, JSGC_DYNAMIC_MARK_SLICE, true);
- JS_SetGCParameter(runtime, JSGC_DYNAMIC_HEAP_GROWTH, true);
- // JS_SetGCParameter(runtime, JSGC_LOW_FREQUENCY_HEAP_GROWTH, 150);
- // JS_SetGCParameter(runtime, JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MIN, 150);
- // JS_SetGCParameter(runtime, JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX, 300);
- // JS_SetGCParameter(runtime, JSGC_HIGH_FREQUENCY_LOW_LIMIT, 100);
- // JS_SetGCParameter(runtime, JSGC_HIGH_FREQUENCY_HIGH_LIMIT, 500);
- // JS_SetGCParameter(runtime, JSGC_ALLOCATION_THRESHOLD, 30);
- // JS_SetGCParameter(runtime, JSGC_DECOMMIT_THRESHOLD, 32);
- JS_SetLocaleCallbacks(runtime, &gjs_locale_callbacks);
- JS_AddFinalizeCallback(runtime, gjs_finalize_callback, data);
- JS_SetErrorReporter(runtime, gjs_error_reporter);
-
- g_private_set(&thread_runtime, runtime);
- }
-
- return runtime;
-}
-
-/* These two act on the current thread's runtime. In the future they will go
- * away because SpiderMonkey is going to merge JSContext and JSRuntime.
- */
-
-/* Creates a new runtime with one reference if there is no runtime yet */
-JSRuntime *
-gjs_runtime_ref(void)
-{
- JSRuntime *rt = static_cast<JSRuntime *>(gjs_runtime_for_current_thread());
- RuntimeData *data = static_cast<RuntimeData *>(JS_GetRuntimePrivate(rt));
- g_atomic_int_inc(&data->refcount);
- return rt;
-}
-
-/* No-op if there is no runtime */
-void
-gjs_runtime_unref(void)
+JSContext *
+gjs_create_js_context(GjsContext *js_context)
{
- JSRuntime *rt = static_cast<JSRuntime *>(g_private_get(&thread_runtime));
- if (rt == NULL)
- return;
- RuntimeData *data = static_cast<RuntimeData *>(JS_GetRuntimePrivate(rt));
- if (g_atomic_int_dec_and_test(&data->refcount))
- gjs_destroy_runtime_for_current_thread();
+ g_assert(gjs_is_inited);
+ JSContext *cx = JS_NewContext(32 * 1024 * 1024 /* max bytes */);
+ if (!cx)
+ g_error("Failed to create javascript runtime");
+
+ // commented are defaults in moz-24
+ JS_SetNativeStackQuota(cx, 1024 * 1024);
+ JS_SetGCParameter(cx, JSGC_MAX_MALLOC_BYTES, 128 * 1024 * 1024);
+ JS_SetGCParameter(cx, JSGC_MAX_BYTES, -1);
+ JS_SetGCParameter(cx, JSGC_MODE, JSGC_MODE_INCREMENTAL);
+ JS_SetGCParameter(cx, JSGC_SLICE_TIME_BUDGET, 10); /* ms */
+ // JS_SetGCParameter(cx, JSGC_HIGH_FREQUENCY_TIME_LIMIT, 1000); /* ms */
+ JS_SetGCParameter(cx, JSGC_DYNAMIC_MARK_SLICE, true);
+ JS_SetGCParameter(cx, JSGC_DYNAMIC_HEAP_GROWTH, true);
+ // JS_SetGCParameter(cx, JSGC_LOW_FREQUENCY_HEAP_GROWTH, 150);
+ // JS_SetGCParameter(cx, JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MIN, 150);
+ // JS_SetGCParameter(cx, JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX, 300);
+ // JS_SetGCParameter(cx, JSGC_HIGH_FREQUENCY_LOW_LIMIT, 100);
+ // JS_SetGCParameter(cx, JSGC_HIGH_FREQUENCY_HIGH_LIMIT, 500);
+ // JS_SetGCParameter(cx, JSGC_ALLOCATION_THRESHOLD, 30);
+ // JS_SetGCParameter(cx, JSGC_DECOMMIT_THRESHOLD, 32);
+ JS_SetLocaleCallbacks(cx, &gjs_locale_callbacks);
+ JS_SetErrorReporter(cx, gjs_error_reporter);
+
+ return cx;
}
diff --git a/gjs/runtime.h b/gjs/runtime.h
index 6f31fd2..19f55a6 100644
--- a/gjs/runtime.h
+++ b/gjs/runtime.h
@@ -24,11 +24,9 @@
#ifndef __GJS_RUNTIME_H__
#define __GJS_RUNTIME_H__
-#include <stdbool.h>
+#include "context.h"
+#include "jsapi-wrapper.h"
-JSRuntime *gjs_runtime_ref(void);
-void gjs_runtime_unref(void);
-
-bool gjs_runtime_is_sweeping (JSRuntime *runtime);
+JSContext *gjs_create_js_context(GjsContext *js_context);
#endif /* __GJS_RUNTIME_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]