RESOLVED FIXED 60990
JSGlobalContextRelease should not trigger a synchronous garbage collection
https://bugs.webkit.org/show_bug.cgi?id=60990
Summary JSGlobalContextRelease should not trigger a synchronous garbage collection
Sam Weinig
Reported 2011-05-17 14:43:25 PDT
JSGlobalContextRelease should not trigger a synchronous garbage collection
Attachments
Patch (1.94 KB, patch)
2011-05-17 14:47 PDT, Sam Weinig
oliver: review+
Sam Weinig
Comment 1 2011-05-17 14:47:26 PDT
Oliver Hunt
Comment 2 2011-05-17 15:31:19 PDT
Comment on attachment 93818 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=93818&action=review > Source/JavaScriptCore/API/JSContextRef.cpp:142 > + // garbarge collect soon. garbarge?
Sam Weinig
Comment 3 2011-05-17 15:32:51 PDT
Adam Roben (:aroben)
Comment 4 2011-05-17 15:39:52 PDT
What's the motivation for this? Neither this bug nor the ChangeLog say!
Sam Weinig
Comment 5 2011-05-17 15:49:03 PDT
(In reply to comment #4) > What's the motivation for this? Neither this bug nor the ChangeLog say! The motivation is to coalesce garbage collections that are triggered as a result of releasing a global context. Otherwise, repeated calls to JSGlobalContextRelease would each trigger a full collection, where one at the end would be much better. As a general rule, synchronous full garbage collection should be avoided as it is very expensive, and should definitely not happen unexpectedly as was happening with JSGlobalContextRelease.
Alexey Proskuryakov
Comment 6 2011-05-17 20:39:10 PDT
We discussed this in person, but I'm not sure how the landed version avoids leaking objects in a worker context. Worker threads don't even have CFRunLoops to schedule timers on. Is this patch correct?
Geoffrey Garen
Comment 7 2011-05-17 21:36:25 PDT
> We discussed this in person, but I'm not sure how the landed version avoids leaking objects in a worker context. Worker threads don't even have CFRunLoops to schedule timers on. When a worker thread exits, it releases the last reference to its context group (JSGlobalData), which calls Heap::destroy().
Sam Weinig
Comment 8 2011-05-17 21:43:16 PDT
(In reply to comment #6) > We discussed this in person, but I'm not sure how the landed version avoids leaking objects in a worker context. Worker threads don't even have CFRunLoops to schedule timers on. > > Is this patch correct? What Geoff said.
Alexey Proskuryakov
Comment 9 2011-05-17 21:57:57 PDT
Thanks. I verified that "run-webkit-tests fast/workers --leaks" reports no leaks. What about arbitrary clients of JSC API? These still don't need to have a CFRunLoop, which DefaultGCActivityCallback seems to require.
Adam Roben (:aroben)
Comment 10 2011-05-18 06:38:39 PDT
(In reply to comment #5) > (In reply to comment #4) > > What's the motivation for this? Neither this bug nor the ChangeLog say! > > The motivation is to coalesce garbage collections that are triggered as a result of releasing a global context. Otherwise, repeated calls to JSGlobalContextRelease would each trigger a full collection, where one at the end would be much better. > > As a general rule, synchronous full garbage collection should be avoided as it is very expensive, and should definitely not happen unexpectedly as was happening with JSGlobalContextRelease. Thanks, Sam!
Geoffrey Garen
Comment 11 2011-05-18 13:10:30 PDT
> What about arbitrary clients of JSC API? These still don't need to have a CFRunLoop, which DefaultGCActivityCallback seems to require. As we've discussed before, on CF platforms, DefaultGCActivityCallback is optimized for CFRunLoop, but doesn't require it.
Alexey Proskuryakov
Comment 12 2011-05-18 13:20:59 PDT
For my education, could you please describe how it works without CFRunLoop? The only call to heap->collectAllGarbage() in CGActivityCallbackCF.cpp is in DefaultGCActivityCallbackPlatformData::trigger(), and the only call to trigger() is through a CFRunLoopTimer. This is the only GCActivityCallback subclass in JSC.
Geoffrey Garen
Comment 13 2011-05-18 13:23:27 PDT
(In reply to comment #12) > For my education, could you please describe how it works without CFRunLoop? If a CF-configured client doesn't run the CFRunLoop, DefaultGCActivityCallback's optimization to GC from the runloop just doesn't kick in.
Alexey Proskuryakov
Comment 14 2011-05-18 13:54:58 PDT
> DefaultGCActivityCallback's optimization to GC from the runloop just doesn't kick in This patch replaced code that works in such threads (globalData.heap.collectAllGarbage()) with code that's effectively no-op. Are you saying that this is OK?
Geoffrey Garen
Comment 15 2011-05-18 14:00:30 PDT
> This patch replaced code that works in such threads (globalData.heap.collectAllGarbage()) with code that's effectively no-op. Are you saying that this is OK? I don't think that's an accurate characterization. The old code didn't "work." It sometimes eagerly reclaimed memory, sometimes didn't eagerly reclaim memory, and sometimes caused O(N^2) hangs. The new code does coalesced attempts at reclaiming memory on threads that run the CFRunLoop, and nothing on threads that don't. Whether that's OK or not depends on the thread and its requirements. On all the threads that I've observed in WebKit, the new code resolves the O(N^2) issue without a regression in memory use.
Alexey Proskuryakov
Comment 16 2011-05-18 14:54:59 PDT
The code was added a long time ago (http://trac.webkit.org/changeset/35917), and unfortunately, the commit that added it didn't have a lot of detail in ChangeLog. All I remember is that non-WebKit JavaScriptCore API clients' needs dictated when JSGlobalContextRelease should perform GC.
Note You need to log in before you can comment on or make changes to this bug.