Incremental GC can be told how long to run for. We should inform it of the current frame time from requestAnimationFrame, so that frames are not skipped. For example, at 60fps requestAnimationFrame is called every 17ms. If the current callback took 5ms, then there are 12ms until the next callback, and we can tell IGC it can run for up to 12ms. There may be other things running than requestAnimationFrame however, so this might be a little trickier, but in principle we should be able to benefit from knowing that we need requestAnimationFrame to be called at fixed intervals, and IGC can fill in the gaps without causing any stutter in the animation or game that is running.
So one option is that we do know when the next refresh timer should fire. If GC asked for that information when it starts, we could definitely tell it how much time it has to run for. If it expects to be told without asking.... how does it expect that to happen? What's the API for it right now?
(In reply to Boris Zbarsky (:bz) from comment #1) > So one option is that we do know when the next refresh timer should fire. > If GC asked for that information when it starts, we could definitely tell it > how much time it has to run for. > > If it expects to be told without asking.... how does it expect that to > happen? What's the API for it right now? Right now the only way to set the slice interval is by using JS_SetGCParameter or from about:config. It used to be that the incremental slices were triggered from the refresh driver, and then it was pretty easy to determine how long the slice should be, as Alon is suggesting. However, I later found out that we have multiple refresh drivers per window, so I moved the triggering to paint events. That made it somewhat more difficult and I decided not to bother, for the following reason. In all the sites I was testing on, we never have any "free time" to do GC. We're always painting and running JS code as fast as we can, trying to run at 60fps and usually achieving much less. Some of this may have to do with my graphics card being blacklisted. However, it seems to me like a more practical solution is to downgrade to a more realizable framerate that we can achieve consistently. Then it would be possible to schedule GCs in the empty spaces in between frames. Certainly on mobile this seems like the right way to go.
Note that this bug is similar to bug 765363 where we have some points that we are forced to wait on the GPU with WebGL apps and could run some GC slices.
I have to stress that unless the GC can guarantee collection cycles no longer than 5ms for the general case, that a way to let him know that this is the desired behavior is absolutely crucial. Skipped frames, even if it's just one or 5 or 6 are very noticable to applications that animate things at 60fps. It is usually the case that an application can easily keep track of how often it desires to "tick" and how long it can suggest to a GC to operate. It may be desired by the application to know after invoking the suggestion, how long the GC actually ran (so it can proactively deal with performance issues). A call like: var ran_for = performance.runGC(5); would be sufficient. It would mean to suggest that: 1) now is a good time to run the GC 2) preferably, if at all possible, should take less than 5ms 3) returns the time the GC actually ran The GC would be free to take the hint or discard it if it's counter indicated that the desired window is reasonable (for instance objects piling up while JS requesting the GC to take less time than would've been required to keep the object count at bay over the last couple of cycles).
11 months ago