summaryrefslogtreecommitdiff
path: root/gjs
diff options
context:
space:
mode:
authorPhilip Chimento <philip.chimento@gmail.com>2019-01-02 18:45:18 -0700
committerPhilip Chimento <philip.chimento@gmail.com>2019-04-13 10:55:38 -0700
commitc7e383435d487a176248163fe96b91d40659fb36 (patch)
tree557dd8d1a281bc04ec1da81f257c2e3dc2427fee /gjs
parentf3128176168c5925366e2e2d8ed65132efd2f009 (diff)
downloadgjs-c7e383435d487a176248163fe96b91d40659fb36.tar.gz
gtype: Port weak pointer hash table to WeakCache
As in a previous change in fundamental.cpp, JS::WeakCache allows us to get rid of the weak pointer callback, as that is all implemented internally. The hash table is automatically swept when the GType wrapper objects are garbage collected. We move the table to GjsContextPrivate instead of using a static variable. Although there is probably little difference in practice, that is a more accurate place to store it, in case there is more than one GjsContext in use.
Diffstat (limited to 'gjs')
-rw-r--r--gjs/context-private.h20
-rw-r--r--gjs/context.cpp7
2 files changed, 26 insertions, 1 deletions
diff --git a/gjs/context-private.h b/gjs/context-private.h
index 566be990..48131b92 100644
--- a/gjs/context-private.h
+++ b/gjs/context-private.h
@@ -34,17 +34,31 @@
#include "jsapi-wrapper.h"
#include "js/GCHashTable.h"
+#include "js/GCPolicyAPI.h"
#include "js/SweepingAPI.h"
using JobQueue = JS::GCVector<JSObject*, 0, js::SystemAllocPolicy>;
using FundamentalTable =
JS::GCHashMap<void*, JS::Heap<JSObject*>, js::DefaultHasher<void*>,
js::SystemAllocPolicy>;
+using GTypeTable =
+ JS::GCHashMap<GType, JS::Heap<JSObject*>, js::DefaultHasher<GType>,
+ js::SystemAllocPolicy>;
+
+struct Dummy {};
+using GTypeNotUint64 =
+ std::conditional_t<!std::is_same<GType, uint64_t>::value, GType, Dummy>;
-// FundamentalTable's key type is void*, the GC sweep method should ignore it
+// The GC sweep method should ignore FundamentalTable and GTypeTable's key types
namespace JS {
template <>
struct GCPolicy<void*> : public IgnoreGCPolicy<void*> {};
+// We need GCPolicy<GType> for GTypeTable. SpiderMonkey already defines
+// GCPolicy<uint64_t> which is equal to GType on some systems; for others we
+// need to define it. (macOS's uint64_t is unsigned long long, which is a
+// different type from unsigned long, even if they are the same width)
+template <>
+struct GCPolicy<GTypeNotUint64> : public IgnoreGCPolicy<GTypeNotUint64> {};
} // namespace JS
class GjsContextPrivate {
@@ -83,6 +97,7 @@ class GjsContextPrivate {
// Weak pointer mapping from fundamental native pointer to JSObject
JS::WeakCache<FundamentalTable>* m_fundamental_table;
+ JS::WeakCache<GTypeTable>* m_gtype_table;
uint8_t m_exit_code;
@@ -140,6 +155,9 @@ class GjsContextPrivate {
GJS_USE JS::WeakCache<FundamentalTable>& fundamental_table(void) {
return *m_fundamental_table;
}
+ GJS_USE JS::WeakCache<GTypeTable>& gtype_table(void) {
+ return *m_gtype_table;
+ }
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 e99d1af3..b2783375 100644
--- a/gjs/context.cpp
+++ b/gjs/context.cpp
@@ -356,6 +356,8 @@ void GjsContextPrivate::dispose(void) {
gjs_debug(GJS_DEBUG_CONTEXT, "Releasing cached JS wrappers");
m_fundamental_table->clear();
+ m_gtype_table->clear();
+
/* Do a full GC here before tearing down, since once we do
* that we may not have the JS_GetPrivate() to access the
* context
@@ -387,6 +389,7 @@ void GjsContextPrivate::dispose(void) {
gjs_debug(GJS_DEBUG_CONTEXT, "Freeing allocated resources");
delete m_job_queue;
delete m_fundamental_table;
+ delete m_gtype_table;
/* Tear down JS */
JS_DestroyContext(m_cx);
@@ -471,6 +474,10 @@ GjsContextPrivate::GjsContextPrivate(JSContext* cx, GjsContext* public_context)
if (!m_fundamental_table->init())
g_error("Failed to initialize fundamental objects table");
+ m_gtype_table = new JS::WeakCache<GTypeTable>(rt);
+ if (!m_gtype_table->init())
+ g_error("Failed to initialize GType objects table");
+
JS_BeginRequest(m_cx);
JS::RootedObject global(m_cx, gjs_create_global_object(m_cx));