[gjs: 10/26] object: Port object_init_list to GCVector
- From: Cosimo Cecchi <cosimoc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs: 10/26] object: Port object_init_list to GCVector
- Date: Sun, 14 Apr 2019 14:04:13 +0000 (UTC)
commit c5c8d9f5757c591d57557c2b7e0657570148ca81
Author: Philip Chimento <philip chimento gmail com>
Date: Tue Jan 22 22:38:07 2019 -0800
object: Port object_init_list to GCVector
Previously we used a std::stack with individual instances of
JS::PersistentRootedObject in it, to hold a list of JSObjects in between
the time of their creation and the time their GObject instance init
function runs. This is wasteful because each individual PersistentRooted
is part of a linked list of permanently rooted objects. Instead, we can
put them in a GCVector and persistently root the whole thing once.
We also move that storage from a static variable to a member of the
GjsContext class.
gi/gobject.cpp | 17 ++++++++++-------
gi/object.cpp | 10 +++++++---
gi/object.h | 4 ----
gjs/context-private.h | 9 +++++++++
gjs/context.cpp | 1 +
5 files changed, 27 insertions(+), 14 deletions(-)
---
diff --git a/gi/gobject.cpp b/gi/gobject.cpp
index debfa6a5..0c54f4e4 100644
--- a/gi/gobject.cpp
+++ b/gi/gobject.cpp
@@ -80,7 +80,10 @@ static void gjs_object_base_finalize(void* klass) {
static GObject* gjs_object_constructor(
GType type, unsigned n_construct_properties,
GObjectConstructParam* construct_properties) {
- if (!ObjectInstance::object_init_list.empty()) {
+ JSContext* cx = current_context();
+ GjsContextPrivate* gjs = GjsContextPrivate::from_cx(cx);
+
+ if (!gjs->object_init_list().empty()) {
GType parent_type = g_type_parent(type);
/* The object is being constructed from JS:
@@ -98,7 +101,6 @@ static GObject* gjs_object_constructor(
* Construct the JS object from the constructor, then use the GObject
* that was associated in gjs_object_custom_init()
*/
- JSContext *cx = current_context();
JSAutoRequest ar(cx);
JSAutoCompartment ac(cx, gjs_get_import_global(cx));
@@ -182,12 +184,13 @@ static void gjs_object_class_init(void* class_pointer, void* user_data) {
}
static void gjs_object_custom_init(GTypeInstance* instance, void* klass) {
- if (ObjectInstance::object_init_list.empty())
- return;
-
JSContext *cx = current_context();
+ GjsContextPrivate* gjs = GjsContextPrivate::from_cx(cx);
+
+ if (gjs->object_init_list().empty())
+ return;
- JS::RootedObject object(cx, ObjectInstance::object_init_list.top());
+ JS::RootedObject object(cx, gjs->object_init_list().back());
auto* priv_base = ObjectBase::for_js_nocheck(object);
g_assert(priv_base); // Should have been set in init_impl()
ObjectInstance* priv = priv_base->to_instance();
@@ -199,7 +202,7 @@ static void gjs_object_custom_init(GTypeInstance* instance, void* klass) {
return;
}
- ObjectInstance::object_init_list.pop();
+ gjs->object_init_list().popBack();
if (!priv->init_custom_class_from_gobject(cx, object, G_OBJECT(instance)))
gjs_log_exception(cx);
diff --git a/gi/object.cpp b/gi/object.cpp
index 3d9dc25b..1a9cf50c 100644
--- a/gi/object.cpp
+++ b/gi/object.cpp
@@ -69,7 +69,6 @@ static_assert(sizeof(ObjectInstance) <= 88,
"gnome-shell run.");
#endif // x86-64 clang
-std::stack<JS::PersistentRootedObject> ObjectInstance::object_init_list{};
bool ObjectInstance::s_weak_pointer_callback = false;
ObjectInstance *ObjectInstance::wrapped_gobject_list = nullptr;
@@ -1469,8 +1468,13 @@ ObjectInstance::init_impl(JSContext *context,
will be popped in gjs_object_custom_init() later
down.
*/
- if (g_type_get_qdata(gtype(), ObjectInstance::custom_type_quark()))
- object_init_list.emplace(context, object);
+ if (g_type_get_qdata(gtype(), ObjectInstance::custom_type_quark())) {
+ GjsContextPrivate* gjs = GjsContextPrivate::from_cx(context);
+ if (!gjs->object_init_list().append(object)) {
+ JS_ReportOutOfMemory(context);
+ return false;
+ }
+ }
g_assert(names.size() == values.size());
GObject* gobj = g_object_new_with_properties(gtype(), values.size(),
diff --git a/gi/object.h b/gi/object.h
index 8a7be4c5..f8b90785 100644
--- a/gi/object.h
+++ b/gi/object.h
@@ -29,7 +29,6 @@
#include <forward_list>
#include <functional>
-#include <stack>
#include <vector>
#include "gi/wrapperutils.h"
@@ -300,9 +299,6 @@ class ObjectInstance : public GIWrapperInstance<ObjectBase, ObjectPrototype,
static bool s_weak_pointer_callback;
- public:
- static std::stack<JS::PersistentRootedObject> object_init_list;
-
/* Constructors */
private:
diff --git a/gjs/context-private.h b/gjs/context-private.h
index 5474e1e9..24ec33e5 100644
--- a/gjs/context-private.h
+++ b/gjs/context-private.h
@@ -38,6 +38,7 @@
#include "js/SweepingAPI.h"
using JobQueue = JS::GCVector<JSObject*, 0, js::SystemAllocPolicy>;
+using ObjectInitList = JS::GCVector<JSObject*, 0, js::SystemAllocPolicy>;
using FundamentalTable =
JS::GCHashMap<void*, JS::Heap<JSObject*>, js::DefaultHasher<void*>,
js::SystemAllocPolicy>;
@@ -99,6 +100,11 @@ class GjsContextPrivate {
JS::WeakCache<FundamentalTable>* m_fundamental_table;
JS::WeakCache<GTypeTable>* m_gtype_table;
+ // List that holds JSObject GObject wrappers for JS-created classes, from
+ // the time of their creation until their GObject instance init function is
+ // called
+ ObjectInitList m_object_init_list;
+
uint8_t m_exit_code;
/* flags */
@@ -158,6 +164,9 @@ class GjsContextPrivate {
GJS_USE JS::WeakCache<GTypeTable>& gtype_table(void) {
return *m_gtype_table;
}
+ GJS_USE ObjectInitList& object_init_list(void) {
+ return m_object_init_list;
+ }
GJS_USE
static const GjsAtoms& atoms(JSContext* cx) { return from_cx(cx)->m_atoms; }
diff --git a/gjs/context.cpp b/gjs/context.cpp
index e55bc5f9..d90e540c 100644
--- a/gjs/context.cpp
+++ b/gjs/context.cpp
@@ -300,6 +300,7 @@ void GjsContextPrivate::trace(JSTracer* trc, void* data) {
JS::TraceEdge<JSObject*>(trc, &gjs->m_global, "GJS global object");
gjs->m_atoms.trace(trc);
gjs->m_job_queue.trace(trc);
+ gjs->m_object_init_list.trace(trc);
}
void GjsContextPrivate::warn_about_unhandled_promise_rejections(void) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]