diff options
author | Philip Chimento <philip.chimento@gmail.com> | 2019-01-02 18:45:18 -0700 |
---|---|---|
committer | Philip Chimento <philip.chimento@gmail.com> | 2019-04-13 10:55:38 -0700 |
commit | c7e383435d487a176248163fe96b91d40659fb36 (patch) | |
tree | 557dd8d1a281bc04ec1da81f257c2e3dc2427fee /gjs | |
parent | f3128176168c5925366e2e2d8ed65132efd2f009 (diff) | |
download | gjs-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.h | 20 | ||||
-rw-r--r-- | gjs/context.cpp | 7 |
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)); |