summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gi/function.cpp10
-rw-r--r--gi/function.h2
-rw-r--r--gjs/context-private.h3
-rw-r--r--gjs/context.cpp13
-rw-r--r--gjs/jsapi-util-root.h2
-rw-r--r--test/gjs-test-rooting.cpp1
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"