After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 697436 - gjs testsuite fails after idle leak handling
gjs testsuite fails after idle leak handling
Status: RESOLVED FIXED
Product: gjs
Classification: Bindings
Component: general
unspecified
Other Linux
: Normal major
: ---
Assigned To: gjs-maint
gjs-maint
: 724976 (view as bug list)
Depends on: 670200
Blocks:
 
 
Reported: 2013-04-06 15:10 UTC by Colin Walters
Modified: 2014-02-24 14:24 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
0001-Synchronously-process-all-idle-object-toggle-referen.patch (3.35 KB, patch)
2013-04-06 16:24 UTC, Colin Walters
reviewed Details | Review
updated patch (3.40 KB, patch)
2013-04-07 15:31 UTC, Colin Walters
reviewed Details | Review

Description Colin Walters 2013-04-06 15:10:49 UTC
In current master, I get:

  /js/EverythingBasic:                                                 FAIL

** (/src/gjs/.libs/lt-gjs-unit:31644): ERROR **: Finalizing proxy for an object that's scheduled to be unrooted: .GLocalFile
Comment 1 Colin Walters 2013-04-06 15:46:17 UTC
(gdb) bt
  • #0 g_logv
    at gmessages.c line 981
  • #1 g_log
    at gmessages.c line 1010
  • #2 object_instance_finalize
    at gi/object.c line 1349
  • #3 finalize
    at /src/js17-17.0.0/js/src/jsobjinlines.h line 235
  • #4 finalize<JSObject>
    at /src/js17-17.0.0/js/src/jsgc.cpp line 348
  • #5 FinalizeTypedArenas<JSObject>
    at /src/js17-17.0.0/js/src/jsgc.cpp line 412
  • #6 js::gc::FinalizeArenas
    at /src/js17-17.0.0/js/src/jsgc.cpp line 449
  • #7 finalizeNow
    at /src/js17-17.0.0/js/src/jsgc.cpp line 1626
  • #8 js::gc::ArenaLists::queueObjectsForSweep
    at /src/js17-17.0.0/js/src/jsgc.cpp line 1722
  • #9 BeginSweepPhase
    at /src/js17-17.0.0/js/src/jsgc.cpp line 3750
  • #10 IncrementalCollectSlice
    at /src/js17-17.0.0/js/src/jsgc.cpp line 4221
  • #11 GCCycle
    at /src/js17-17.0.0/js/src/jsgc.cpp line 4399
  • #12 Collect
    at /src/js17-17.0.0/js/src/jsgc.cpp line 4507
  • #13 js::DestroyContext
    at /src/js17-17.0.0/js/src/jscntxt.cpp line 421
  • #14 gjs_context_dispose
    at gjs/context.c line 389
  • #15 g_object_unref
    at gobject.c line 2987
  • #16 teardown
    at test/gjs-unit.c line 83
  • #17 test_case_run
    at gtestutils.c line 1724
  • #18 g_test_run_suite_internal
    at gtestutils.c line 1767
  • #19 g_test_run_suite_internal
    at gtestutils.c line 1778
  • #20 g_test_run_suite
    at gtestutils.c line 1823
  • #21 main
    at test/gjs-unit.c line 286

Comment 2 Colin Walters 2013-04-06 15:47:49 UTC
In the test suite, we're destroying the context forcibly, and thus collecting all objects.  This is tricky - possibly what we should do is synchronously run all pending object toggle ref notifiers.

To do that we'd need to keep a list of them.
Comment 3 Colin Walters 2013-04-06 16:24:20 UTC
Created attachment 240854 [details] [review]
0001-Synchronously-process-all-idle-object-toggle-referen.patch
Comment 4 Ray Strode [halfline] 2013-04-06 18:15:53 UTC
So let me make sure I understand the problem. When a JSContext is destroyed it's global JSObject gets finalized and then all JSObjects rooted to that JSObject get reaped.  We make the assumption that the global JSObject will always be around to keep the JSObjects rooted until their toggle notify idles get dispatched.  This assumption falls over in a came where th JSContext gets destroyed.  Right?
Comment 5 Ray Strode [halfline] 2013-04-06 18:23:45 UTC
Review of attachment 240854 [details] [review]:

man too bad bug 690126 isn't fixed...

::: gi/object.c
@@ +855,3 @@
 
+    if (source) {
+        g_atomic_int_add(&pending_idle_toggles, -1);

might make more sense to do this when the ToggleRefNotifyOperation is freed.  Since this really a count of pending notify operations.

@@ +961,3 @@
             g_assert_not_reached();
     }
+    g_atomic_int_add(&pending_idle_toggles, -1);

Then you wouldn't need to do it in two places.

@@ +1024,3 @@
     g_object_set_qdata (gobj, qdata_key, source);
     g_source_attach (source, NULL);
+    g_atomic_int_inc(&pending_idle_toggles);

likewise, maybe do this a few lines higher where the operation is created.

@@ +1116,3 @@
+           g_atomic_int_get (&pending_idle_toggles) > 0) {
+        g_main_context_iteration (NULL, FALSE);
+    }

hmm, one thought... If we're going to be keeping a global count of pending operations anyway, maybe we should just go a little further and keep a global async queue of the operations themselves.  Then we could have one idle instead of N idles, and wouldn't need to store the idle source as qdata on each object.

One downside of that idea is it would be harder to know when it's safe to invoke toggle notifies right away, i guess.
Comment 6 Colin Walters 2013-04-07 15:31:42 UTC
Created attachment 240889 [details] [review]
updated patch

Yeah, refcounting in the destroy is cleaner.
Comment 7 Colin Walters 2013-04-07 15:33:10 UTC
(In reply to comment #5)

> One downside of [the global queue] is it would be harder to know when it's safe to
> invoke toggle notifies right away, i guess.

Yeah, it's not clear to me it'd be worth it; having to rescan the list seems like it has the potential to be quite bad for performance.
Comment 8 Jasper St. Pierre (not reading bugmail) 2013-04-07 21:18:43 UTC
Review of attachment 240889 [details] [review]:

::: gi/object.c
@@ +857,2 @@
         g_source_destroy(source);
+    }

Seems unnecessary?

::: gjs/context.c
@@ +394,3 @@
+        JS_GC(js_context->runtime);
+
+        gjs_object_process_pending_toggles();

Why twice?
Comment 9 Ray Strode [halfline] 2013-04-07 23:51:57 UTC
Review of attachment 240889 [details] [review]:

::: gi/object.c
@@ +1107,3 @@
+/* In the case of a synchronous garbage collection from the main
+ * thread, we need to ensure we've cleared the context of any pending
+ * toggle references.

I think I would make it clear this is for the shutdown path specifically.

maybe something like,
"When the JSContext is disposed we need to synchronously finalize all JSObjects. Before a JSObject is finalized all of its pending toggle notifications need to be processed."
Comment 10 Ray Strode [halfline] 2013-04-07 23:55:21 UTC
HI,

> Yeah, it's not clear to me it'd be worth it; having to rescan the list seems
> like it has the potential to be quite bad for performance.

So one idea would be to have a hybrid approach of the global queue, and "has-toggle-up-pending"/"has-toggle-down-pending" object data.

Anyway that optimization is sort of separate from this particular bug, so we can just leave it for another day.
Comment 11 Colin Walters 2013-04-08 01:14:32 UTC
Thanks, pushed with those fixes.
Comment 12 Giovanni Campagna 2014-02-24 14:24:53 UTC
*** Bug 724976 has been marked as a duplicate of this bug. ***