Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP2:Update
gjs
gjs-aggressive-gc.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File gjs-aggressive-gc.patch of Package gjs
diff --git a/gi/object.cpp b/gi/object.cpp index 74121f8..23a1b4f 100644 --- a/gi/object.cpp +++ b/gi/object.cpp @@ -862,12 +862,34 @@ handle_toggle_down(GObject *gobj) * collected by the GC */ if (priv->keep_alive != NULL) { + GjsContext *context; + gjs_debug_lifecycle(GJS_DEBUG_GOBJECT, "Removing object from keep alive"); gjs_keep_alive_remove_child(priv->keep_alive, gobj_no_longer_kept_alive_func, obj, priv); priv->keep_alive = NULL; + + /* During a GC, the collector asks each object which other + * objects that it wants to hold on to so if there's an entire + * section of the heap graph that's not connected to anything + * else, and not reachable from the root set, then it can be + * trashed all at once. + * + * GObjects, however, don't work like that, there's only a + * reference count but no notion of who owns the reference so, + * a JS object that's proxying a GObject is unconditionally held + * alive as long as the GObject has >1 references. + * + * Since we cannot know how many more wrapped GObjects are going + * be marked for garbage collection after the owner is destroyed, + * always queue a garbage collection when a toggle reference goes + * down. + */ + context = gjs_context_get_current(); + if (!_gjs_context_destroying(context)) + _gjs_context_schedule_gc(context); } } diff --git a/gjs/context-private.h b/gjs/context-private.h index 1d4e6e0..0b6fd58 100644 --- a/gjs/context-private.h +++ b/gjs/context-private.h @@ -33,6 +33,8 @@ gboolean _gjs_context_destroying (GjsContext *js_context); void _gjs_context_schedule_gc_if_needed (GjsContext *js_context); +void _gjs_context_schedule_gc(GjsContext *js_context); + G_END_DECLS #endif /* __GJS_CONTEXT_PRIVATE_H__ */ diff --git a/gjs/context.cpp b/gjs/context.cpp index 19120c4..b0cbbd3 100644 --- a/gjs/context.cpp +++ b/gjs/context.cpp @@ -70,6 +70,7 @@ struct _GjsContext { gboolean destroying; guint auto_gc_id; + bool force_gc; jsid const_strings[GJS_STRING_LAST]; }; @@ -535,14 +536,25 @@ static gboolean trigger_gc_if_needed (gpointer user_data) { GjsContext *js_context = GJS_CONTEXT(user_data); + js_context->auto_gc_id = 0; - gjs_gc_if_needed(js_context->context); + + if (js_context->force_gc) + JS_GC(js_context->runtime); + else + gjs_gc_if_needed(js_context->context); + + js_context->force_gc = FALSE; + return FALSE; } -void -_gjs_context_schedule_gc_if_needed (GjsContext *js_context) +static void +_gjs_context_schedule_gc_internal (GjsContext *js_context, + bool force_gc) { + js_context->force_gc |= force_gc; + if (js_context->auto_gc_id > 0) return; @@ -551,6 +563,18 @@ _gjs_context_schedule_gc_if_needed (GjsContext *js_context) js_context, NULL); } +void +_gjs_context_schedule_gc (GjsContext *js_context) +{ + _gjs_context_schedule_gc_internal(js_context, TRUE); +} + +void +_gjs_context_schedule_gc_if_needed (GjsContext *js_context) +{ + _gjs_context_schedule_gc_internal(js_context, FALSE); +} + /** * gjs_context_maybe_gc: * @context: a #GjsContext
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor