> On Mar 13, 2016, at 5:22 PM, Steve Fink <[email protected]> wrote:
>
>> This is a good time to bring up the other half of my original email because
>> a number of other people have chimed in with their experiences with GC when
>> attempting to develop more time critical applications without stutter.
>
> I really don't think you want a System.gc() call for that. What if you call
> that after you're placed in a background tab, when you're sharing the JS heap
> with a latency-sensitive foreground tab? Do you really want to stutter the
> foreground tab for (up to) a few seconds? Probably not, in which case the
> name System.gc() would be a lie.
>
> I think the closest you would want to go is to offer hints to the runtime.
> AppIsIdleStartingNowForAtLeast(500)? IDoNotMindIfYouDontCallMeAgainFor(500)?
> (units are milliseconds). The runtime can ignore it, or it can schedule an
> up-to-500ms incremental GC slice, or whatever. That does not negate all of
> the issues Boris was referring to, but IMHO it's a reasonable middle ground.
> We could double-check it against pending timers or whatever.
System.gc() would have a callback; it would block until you regained front
status. That has some edge cases, but that’s something the programmer would
have to be aware of.
// my crazy code that makes a lot of objects that fall out of scope
System.gc(startNonCrazyCode);
// my non-crazy code which allocates next to nothing to reduce GCs to almost nil
…startNonCrazyCode(…) {}
>
>> The second part was a hint to tell the engine to always take the most
>> aggressive route with optimization; for instance, in Safari’s engine, as I
>> remember, I think there are three levels, interpreted, a half-n-half
>> solution, and an actual full compile of the code. This hint would say
>> “always compile to native” or if an engine never goes that far, always
>> compile to the VM soup (though I suspect at this point most engines can do a
>> native version.)
>
> That's a nice simple mental model, but it's inaccurate in some important ways.
>
>> This would be used, again, for trading time in one place for time in
>> another. A longer start-up time is something you want for a thing that will
>> run continually and will almost always be guaranteed to fall into the
>> compile path eventually. It’s not something you’d want for javascript that
>> runs on a normal button click to post a form.
>
> But you may *need* to run it in a slower mode 1 or more times in order for
> that native compilation to be effective. The fastest JIT levels compile the
> code under certain simplifying assumptions to make the generated code more
> efficient -- it may assume that you're not going to randomly add or delete a
> property from an object handled by the compiled code, for example, so it can
> compile in direct offsets to the object's slots. If you violate one of those
> assumptions, the compiled code will need to be discarded and re-generated
> with a new weaker set of assumptions.
>
> So you don't want to go straight to the highest optimization level, as it
> might then not optimize as highly. You need to first run in a slower mode,
> perhaps even one that pays some overhead in order to gather information about
> the types and control paths actually used. And that's the next gotcha -- it's
> reasonable to skip collecting that info on the first time (or few times?) you
> run the code, because the majority of code is only run once so any gathered
> profiling info is useless.
>
> Which is not to say that there's nothing useful you can tell the system. If
> you hinted to it that something was going to be important and run frequently,
> then it could choose to gather profiling information earlier and additionally
> lower the threshold for jumping up optimization levels. As with the GC case,
> though, you do *not* want to tell the VM exactly what to do. The best
> approach might be something like: spawn off a background compile, and in the
> meantime interpret the code without gathering profiling info, then switch to
> the compiled profiling code when it's ready, and then do an optimized compile
> based on that information as soon as you've observed "enough". The user code
> has no way to know how long that background compilation will take, whether
> there are spare resources to do it in the background, etc. And it varies by
> platform. So at best, I think you can drop hints like "this code is going to
> run a lot, and I'm pretty sure its runtime matters to me." In practice,
> people will end up cutting & pasting the magic bits that make things fast
> from stackoverflow and misapplying them all of the place, to the extent that
> engines might end up just completely ignoring them, but it may also turn out
> that they're a good enough signal that engines will pay attention. I don't
> know; I can't predict.
>
>>
>> Being compiled gives you another benefit, say you have this class:
>>
>> class ….
>> {
>> test()
>> {
>> let x,y,z;
>> …
>> ….
>> return(x);
>> }
>>
>> The locals y and z are never move beyond the function scope; in this manner
>> they could be stack based variables that never touch the heap (yes, I know
>> that’s probably a very difficult implementation.) Or even variables that
>> fall into a special section of the heap that only deals with locals that
>> never scope outside the function and are always cleaned up automatically on
>> function exit (basically, reference counting where you know the reference is
>> always 0.)
> I'm a little confused about variables vs values here, but simply storing a
> value into a local does not guarantee that the value is only references by
> that variable. You can sometimes do an escape analysis to figure this sort of
> thing out, and I believe many engines do this or are working on doing this.
> But either way, requesting that something be *compiled* is absolutely the
> wrong signal -- analysis is separate from compilation, and in fact
> information necessary for an analysis is less likely to be collected at the
> highest optimization levels. (It would either be figured out when initially
> compiling to bytecode or whatever, or dynamically gathered during early or
> mid-tier optimization levels.)
>
>
>> This will basically reduce the amount of GCs by a good bit. NOW, you’d also
>> have to track any additional function calls that use these variables (to
>> make sure they aren’t save out to a global.) So everything underneath would
>> be a force compile for this to work. Engines might already do this or stuff
>> like it, and if so, great!
>
> They do stuff like this, but it's independent of (and complicated by)
> compilation.
>
>> This is probably something that is *much more* complicated to implement that
>> most of us might realize, but it’s a thought. Just being able to say “this
>> class is always compiled” would be nice.
>
> I don't think so. It's not even really the right level of granularity. Some
> class methods should be compiled while others are interpreted, for the lowest
> overall time.
>
>> The second part of this is native primitive types; having int/etc means they
>> can be passed by value which means these checks are easier, but that’s
>> probably something others have argued back and forth for a long time :)
>
> The dynamic profiling can figure out whether *in practice* particular values
> are always int/etc while certain code executes, and compile with that
> assumption. Declaring types can give that a head start, but it'll still need
> to be double-checked when not easily statically provable, and may end up just
> wasting time prematurely compiling code with incorrect assumptions. JS right
> now is simply too dynamic to prevent all possibility of strange things
> happening to seemingly simple values. Besides, just observing the types seems
> to work pretty well in practice. The main benefit of type declarations would
> be in preventing errors via type checking, IMO.
Right, I understand all that, and to me, that would be part of compilation. If
a lower level pass through, or if a number of them, is required, than that’ll
will have to be done (before types.) If there are levels before full
compilation that can be skipped, then that’s all this hint would ask for.
I have to apologize because I think people keep thinking I’m asking for
something that solves a specific problem in a specific way; what I’m asking for
is something that is more contactually simpler … “X always gets the most
aggressive compilation”. If that takes multiple slow passes, then that’s fine.
It’s not “NO slow passes” it’s “always strive to maximize speed over start up
time."
I can tell you in my case (http://www.klinksoftware.com/ws/
<http://www.klinksoftware.com/ws/>) there isn’t anything that won’t benefit
from every class (and it’s all classes) being compiled.
[>] Brian_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss