[gjs/wip/ptomato/mozjs52: 1/5] js: Remove JSRuntime
- From: Philip Chimento <pchimento src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs/wip/ptomato/mozjs52: 1/5] js: Remove JSRuntime
- Date: Tue, 27 Jun 2017 02:33:13 +0000 (UTC)
commit 1d81f135df2a5a7f7dd3b3116e90172f644cee93
Author: Philip Chimento <philip chimento gmail com>
Date: Tue May 2 23:15:10 2017 -0700
js: Remove JSRuntime
JSRuntime is merged into JSContext in SpiderMonkey 52.
We reorganize things a bit to reflect the new situation. The files
runtime.cpp and runtime.h are renamed to engine.cpp and engine.h, and
will contain everything having to do with the SpiderMonkey engine:
initializing the JSContext, and any callbacks that the engine requires
embedders to set.
https://bugzilla.gnome.org/show_bug.cgi?id=784196
gi/function.cpp | 4 +-
gi/value.cpp | 5 +-
gjs-srcs.mk | 4 +-
gjs/context-private.h | 6 ++
gjs/context.cpp | 90 ++++++++--------------
gjs/{runtime.cpp => engine.cpp} | 159 +++++++++++++++------------------------
gjs/{runtime.h => engine.h} | 14 ++--
gjs/jsapi-util.h | 1 -
8 files changed, 110 insertions(+), 173 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-srcs.mk b/gjs-srcs.mk
index b7c1efd..5d41951 100644
--- a/gjs-srcs.mk
+++ b/gjs-srcs.mk
@@ -54,6 +54,8 @@ gjs_srcs = \
gjs/context-private.h \
gjs/coverage-internal.h \
gjs/coverage.cpp \
+ gjs/engine.cpp \
+ gjs/engine.h \
gjs/global.cpp \
gjs/global.h \
gjs/importer.cpp \
@@ -77,8 +79,6 @@ gjs_srcs = \
gjs/module.cpp \
gjs/native.cpp \
gjs/native.h \
- gjs/runtime.cpp \
- gjs/runtime.h \
gjs/stack.cpp \
modules/modules.cpp \
modules/modules.h \
diff --git a/gjs/context-private.h b/gjs/context-private.h
index 2d8834d..d6207da 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,11 @@ bool _gjs_context_get_is_owner_thread(GjsContext *js_context);
bool _gjs_context_should_exit(GjsContext *js_context,
uint8_t *exit_code_p);
+void _gjs_context_set_sweeping(GjsContext *js_context,
+ bool sweeping);
+
+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 569b902..b453fcc 100644
--- a/gjs/context.cpp
+++ b/gjs/context.cpp
@@ -28,6 +28,7 @@
#include <gio/gio.h>
#include "context-private.h"
+#include "engine.h"
#include "global.h"
#include "importer.h"
#include "jsapi-private.h"
@@ -35,7 +36,6 @@
#include "jsapi-wrapper.h"
#include "native.h"
#include "byteArray.h"
-#include "runtime.h"
#include "gi/object.h"
#include "gi/repo.h"
@@ -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;
@@ -114,19 +114,6 @@ static GMutex contexts_lock;
static GList *all_contexts = NULL;
static void
-on_garbage_collect(JSContext *cx,
- JSGCStatus status,
- void *data)
-{
- /* We finalize any pending toggle refs before doing any garbage collection,
- * so that we can collect the JS wrapper objects, and in order to minimize
- * the chances of objects having a pending toggle up queued when they are
- * garbage collected. */
- if (status == JSGC_BEGIN)
- gjs_object_clear_toggles();
-}
-
-static void
gjs_context_init(GjsContext *js_context)
{
gjs_context_make_current(js_context);
@@ -243,7 +230,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);
}
}
@@ -283,74 +269,48 @@ 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 */);
- if (js_context->context == NULL)
+ JSContext *cx = gjs_create_js_context(js_context);
+ if (!cx)
g_error("Failed to create javascript context");
+ js_context->context = cx;
for (i = 0; i < GJS_STRING_LAST; i++) {
- js_context->const_strings[i] =
- new JS::PersistentRootedId(js_context->context,
- gjs_intern_string_to_id(js_context->context, const_strings[i]));
- }
-
- JS_BeginRequest(js_context->context);
-
- JS_SetGCCallback(js_context->context, on_garbage_collect, js_context);
-
- /* set ourselves as the private data */
- JS_SetContextPrivate(js_context->context, js_context);
-
- /* setExtraWarnings: Be extra strict about code that might hide a bug */
- if (!g_getenv("GJS_DISABLE_EXTRA_WARNINGS")) {
- gjs_debug(GJS_DEBUG_CONTEXT, "Enabling extra warnings");
- JS::ContextOptionsRef(js_context->context).setExtraWarnings(true);
+ js_context->const_strings[i] = new JS::PersistentRootedId(cx,
+ gjs_intern_string_to_id(cx, const_strings[i]));
}
- if (!g_getenv("GJS_DISABLE_JIT")) {
- gjs_debug(GJS_DEBUG_CONTEXT, "Enabling JIT");
- JS::ContextOptionsRef(js_context->context)
- .setIon(true)
- .setBaseline(true)
- .setAsmJS(true);
- }
+ JS_BeginRequest(cx);
- JS::RootedObject global(js_context->context,
- gjs_create_global_object(js_context->context));
+ JS::RootedObject global(cx, gjs_create_global_object(cx));
if (!global) {
gjs_log_exception(js_context->context);
g_error("Failed to initialize global object");
}
- JSAutoCompartment ac(js_context->context, global);
+ JSAutoCompartment ac(cx, global);
new (&js_context->global) JS::Heap<JSObject *>(global);
- JS_AddExtraGCRootsTracer(js_context->context, gjs_context_tracer,
- js_context);
+ JS_AddExtraGCRootsTracer(cx, gjs_context_tracer, js_context);
- JS::RootedObject importer(js_context->context,
- gjs_create_root_importer(js_context->context, js_context->search_path ?
- js_context->search_path : nullptr));
+ JS::RootedObject importer(cx, gjs_create_root_importer(cx,
+ js_context->search_path ? js_context->search_path : nullptr));
if (!importer)
g_error("Failed to create root importer");
- JS::Value v_importer = gjs_get_global_slot(js_context->context,
- GJS_GLOBAL_SLOT_IMPORTS);
+ JS::Value v_importer = gjs_get_global_slot(cx, GJS_GLOBAL_SLOT_IMPORTS);
g_assert(((void) "Someone else already created root importer",
v_importer.isUndefined()));
- gjs_set_global_slot(js_context->context, GJS_GLOBAL_SLOT_IMPORTS,
- JS::ObjectValue(*importer));
+ gjs_set_global_slot(cx, GJS_GLOBAL_SLOT_IMPORTS, JS::ObjectValue(*importer));
- if (!gjs_define_global_properties(js_context->context, global)) {
- gjs_log_exception(js_context->context);
+ if (!gjs_define_global_properties(cx, global)) {
+ gjs_log_exception(cx);
g_error("Failed to define properties on global object");
}
- JS_EndRequest(js_context->context);
+ JS_EndRequest(cx);
g_mutex_lock (&contexts_lock);
all_contexts = g_list_prepend(all_contexts, object);
@@ -472,6 +432,20 @@ _gjs_context_get_is_owner_thread(GjsContext *js_context)
return js_context->owner_thread == g_thread_self();
}
+void
+_gjs_context_set_sweeping(GjsContext *js_context,
+ bool sweeping)
+{
+ js_context->in_gc_sweep = sweeping;
+}
+
+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/engine.cpp
similarity index 64%
rename from gjs/runtime.cpp
rename to gjs/engine.cpp
index 3f7aaff..9676166 100644
--- a/gjs/runtime.cpp
+++ b/gjs/engine.cpp
@@ -26,27 +26,17 @@
#include "jsapi-wrapper.h"
#include <js/Initialization.h>
+#include "context-private.h"
+#include "engine.h"
+#include "gi/object.h"
#include "jsapi-util.h"
-#include "runtime.h"
+#include "util/log.h"
#ifdef G_OS_WIN32
#define WIN32_LEAN_AND_MEAN
#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 +134,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,
@@ -168,9 +146,9 @@ static void
gjs_finalize_callback(JSFreeOp *fop,
JSFinalizeStatus status,
bool isCompartment,
- void *user_data)
+ void *data)
{
- RuntimeData *data = static_cast<RuntimeData *>(user_data);
+ auto js_context = static_cast<GjsContext *>(data);
/* Implementation note for mozjs 24:
sweeping happens in two phases, in the first phase all
@@ -213,17 +191,22 @@ gjs_finalize_callback(JSFreeOp *fop,
*/
if (status == JSFINALIZE_GROUP_START)
- data->in_gc_sweep = true;
+ _gjs_context_set_sweeping(js_context, true);
else if (status == JSFINALIZE_GROUP_END)
- data->in_gc_sweep = false;
+ _gjs_context_set_sweeping(js_context, 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)
+on_garbage_collect(JSContext *cx,
+ JSGCStatus status,
+ void *data)
{
- g_private_replace(&thread_runtime, NULL);
+ /* We finalize any pending toggle refs before doing any garbage collection,
+ * so that we can collect the JS wrapper objects, and in order to minimize
+ * the chances of objects having a pending toggle up queued when they are
+ * garbage collected. */
+ if (status == JSGC_BEGIN)
+ gjs_object_clear_toggles();
}
#ifdef G_OS_WIN32
@@ -243,7 +226,6 @@ LPVOID lpvReserved)
break;
case DLL_THREAD_DETACH:
- gjs_destroy_runtime_for_current_thread();
JS_ShutDown ();
break;
@@ -264,8 +246,6 @@ public:
}
~GjsInit() {
- /* No-op if the runtime was already destroyed */
- gjs_destroy_runtime_for_current_thread();
JS_ShutDown();
}
@@ -277,69 +257,52 @@ public:
static GjsInit gjs_is_inited;
#endif
-static JSRuntime *
-gjs_runtime_for_current_thread(void)
+JSContext *
+gjs_create_js_context(GjsContext *js_context)
{
- 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::SetWarningReporter(runtime, gjs_warning_reporter);
-
- g_private_set(&thread_runtime, runtime);
+ g_assert(gjs_is_inited);
+ JSContext *cx = JS_NewContext(32 * 1024 * 1024 /* max bytes */);
+ if (!cx)
+ return nullptr;
+
+ // 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);
+
+ /* set ourselves as the private data */
+ JS_SetContextPrivate(cx, js_context);
+
+ JS_AddFinalizeCallback(cx, gjs_finalize_callback, js_context);
+ JS_SetGCCallback(cx, on_garbage_collect, js_context);
+ JS_SetLocaleCallbacks(cx, &gjs_locale_callbacks);
+ JS::SetWarningReporter(cx, gjs_warning_reporter);
+
+ /* setExtraWarnings: Be extra strict about code that might hide a bug */
+ if (!g_getenv("GJS_DISABLE_EXTRA_WARNINGS")) {
+ gjs_debug(GJS_DEBUG_CONTEXT, "Enabling extra warnings");
+ JS::ContextOptionsRef(cx).setExtraWarnings(true);
}
- 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;
-}
+ if (!g_getenv("GJS_DISABLE_JIT")) {
+ gjs_debug(GJS_DEBUG_CONTEXT, "Enabling JIT");
+ JS::ContextOptionsRef(cx)
+ .setIon(true)
+ .setBaseline(true)
+ .setAsmJS(true);
+ }
-/* No-op if there is no runtime */
-void
-gjs_runtime_unref(void)
-{
- 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();
+ return cx;
}
diff --git a/gjs/runtime.h b/gjs/engine.h
similarity index 83%
rename from gjs/runtime.h
rename to gjs/engine.h
index 6f31fd2..46bce81 100644
--- a/gjs/runtime.h
+++ b/gjs/engine.h
@@ -21,14 +21,12 @@
* IN THE SOFTWARE.
*/
-#ifndef __GJS_RUNTIME_H__
-#define __GJS_RUNTIME_H__
+#ifndef GJS_ENGINE_H
+#define GJS_ENGINE_H
-#include <stdbool.h>
+#include "context.h"
+#include "jsapi-wrapper.h"
-JSRuntime *gjs_runtime_ref(void);
-void gjs_runtime_unref(void);
+JSContext *gjs_create_js_context(GjsContext *js_context);
-bool gjs_runtime_is_sweeping (JSRuntime *runtime);
-
-#endif /* __GJS_RUNTIME_H__ */
+#endif /* GJS_ENGINE_H */
diff --git a/gjs/jsapi-util.h b/gjs/jsapi-util.h
index 32b300d..363dc95 100644
--- a/gjs/jsapi-util.h
+++ b/gjs/jsapi-util.h
@@ -30,7 +30,6 @@
#include <glib-object.h>
#include "jsapi-wrapper.h"
-#include "gjs/runtime.h"
#include "gi/gtype.h"
class GjsAutoChar : public std::unique_ptr<char, decltype(&g_free)> {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]