diff options
-rw-r--r-- | gi/function.cpp | 10 | ||||
-rw-r--r-- | gi/function.h | 2 | ||||
-rw-r--r-- | gjs/context-private.h | 3 | ||||
-rw-r--r-- | gjs/context.cpp | 13 | ||||
-rw-r--r-- | gjs/jsapi-util-root.h | 2 | ||||
-rw-r--r-- | test/gjs-test-rooting.cpp | 1 |
6 files changed, 16 insertions, 15 deletions
diff --git a/gi/function.cpp b/gi/function.cpp index 672a4464..4c9c649a 100644 --- a/gi/function.cpp +++ b/gi/function.cpp @@ -174,12 +174,6 @@ class Function : public CWrapper<Function> { } // namespace Gjs -/* Because we can't free the mmap'd data for a callback - * while it's in use, this list keeps track of ones that - * will be freed the next time we invoke a C function. - */ -static std::vector<Gjs::Closure::Ptr> completed_trampolines; - template <typename T, GITypeTag TAG = GI_TYPE_TAG_VOID> static inline std::enable_if_t<std::is_integral_v<T> && std::is_signed_v<T>> set_ffi_arg(void* result, GIArgument* value) { @@ -339,7 +333,7 @@ void GjsCallbackTrampoline::callback_closure(GIArgument** args, void* result) { // that has been set in gjs_marshal_callback_in() gjs_debug_closure("Saving async closure for gc cleanup %p", trampoline); - completed_trampolines.emplace_back(trampoline); + gjs->async_closure_enqueue_for_gc(trampoline); } gjs->schedule_gc_if_needed(); } @@ -740,8 +734,6 @@ std::string Gjs::Function::format_name() { return retval; } -void gjs_function_clear_async_closures() { completed_trampolines.clear(); } - namespace Gjs { static void* get_return_ffi_pointer_from_giargument( diff --git a/gi/function.h b/gi/function.h index 61868238..498b5481 100644 --- a/gi/function.h +++ b/gi/function.h @@ -157,6 +157,4 @@ bool gjs_invoke_constructor_from_c(JSContext* cx, GIFunctionInfo* info, const JS::CallArgs& args, GIArgument* rvalue); -void gjs_function_clear_async_closures(); - #endif // GI_FUNCTION_H_ diff --git a/gjs/context-private.h b/gjs/context-private.h index b472ef4f..e29b495c 100644 --- a/gjs/context-private.h +++ b/gjs/context-private.h @@ -32,6 +32,7 @@ #include <jsapi.h> // for JS_GetContextPrivate #include <jsfriendapi.h> // for ScriptEnvironmentPreparer +#include "gi/closure.h" #include "gjs/context.h" #include "gjs/jsapi-util.h" #include "gjs/macros.h" @@ -80,6 +81,7 @@ class GjsContextPrivate : public JS::JobQueue { unsigned m_idle_drain_handler; std::vector<std::pair<DestroyNotify, void*>> m_destroy_notifications; + std::vector<Gjs::Closure::Ptr> m_async_closures; std::unordered_map<uint64_t, GjsAutoChar> m_unhandled_rejection_stacks; GjsProfiler* m_profiler; @@ -246,6 +248,7 @@ class GjsContextPrivate : public JS::JobQueue { void register_notifier(DestroyNotify notify_func, void* data); void unregister_notifier(DestroyNotify notify_func, void* data); + void async_closure_enqueue_for_gc(Gjs::Closure*); [[nodiscard]] bool register_module(const char* identifier, const char* filename, GError** error); diff --git a/gjs/context.cpp b/gjs/context.cpp index e5a01fcf..10a80a0c 100644 --- a/gjs/context.cpp +++ b/gjs/context.cpp @@ -61,7 +61,6 @@ #include <mozilla/UniquePtr.h> #include "gi/closure.h" // for Closure::Ptr, Closure -#include "gi/function.h" #include "gi/object.h" #include "gi/private.h" #include "gi/repo.h" @@ -794,7 +793,9 @@ void GjsContextPrivate::on_garbage_collection(JSGCStatus status, JS::GCReason re // order to minimize the chances of objects having a pending toggle // up queued when they are garbage collected. gjs_object_clear_toggles(); - gjs_function_clear_async_closures(); + + m_async_closures.clear(); + m_async_closures.shrink_to_fit(); break; case JSGC_END: if (m_profiler && m_gc_begin_time != 0) { @@ -1089,6 +1090,14 @@ void GjsContextPrivate::unregister_unhandled_promise_rejection(uint64_t id) { "previously marked as unhandled", erased == 1)); } +void GjsContextPrivate::async_closure_enqueue_for_gc(Gjs::Closure* trampoline) { + // Because we can't free the mmap'd data for a callback + // while it's in use, this list keeps track of ones that + // will be freed the next time gc happens + g_assert(!trampoline->context() || trampoline->context() == m_cx); + m_async_closures.emplace_back(trampoline); +} + /** * gjs_context_maybe_gc: * @context: a #GjsContext diff --git a/gjs/jsapi-util-root.h b/gjs/jsapi-util-root.h index bc58ba36..6758c722 100644 --- a/gjs/jsapi-util-root.h +++ b/gjs/jsapi-util-root.h @@ -21,8 +21,6 @@ #include <js/TracingAPI.h> #include <js/TypeDecls.h> -#include "gjs/context-private.h" -#include "gjs/context.h" #include "gjs/macros.h" #include "util/log.h" diff --git a/test/gjs-test-rooting.cpp b/test/gjs-test-rooting.cpp index c3c89eb3..a58753da 100644 --- a/test/gjs-test-rooting.cpp +++ b/test/gjs-test-rooting.cpp @@ -12,6 +12,7 @@ #include <js/Value.h> #include <jsapi.h> // for JS_GetPrivate, JS_NewObject, JS_Set... +#include "gjs/context-private.h" #include "gjs/jsapi-util-root.h" #include "test/gjs-test-utils.h" |