I personally don’t believe anybody will ever be fidgeting with these, but it doesn’t hurt having them configurable, so… +1 :-)
> On Dec 12, 2017, at 2:39 PM, Hannes Wallnöfer <hannes.wallnoe...@oracle.com> > wrote: > > Thanks for the review, Sundar. > > I think making thresholds configurable is a good idea. I’ve uploaded a new > webrev where SHARED_CALL_THRESHOLD and SHARED_GET_THRESHOLD are configurable > via „nashorn.shared.scope.call.threshold“ and > „nashorn.shared.scope.get.threshold“ system properties, respectively. > > http://cr.openjdk.java.net/~hannesw/8069338/webrev.02/ > > Hannes > >> Am 12.12.2017 um 14:00 schrieb Sundararajan Athijegannathan >> <sundararajan.athijegannat...@oracle.com>: >> >> +1 >> >> PS. Not sure if it is worth making SHARED_GET_THRESHOLD configurable via >> System property? >> >> -Sundar >> >> On 12/12/17, 5:51 PM, Hannes Wallnöfer wrote: >>> Thanks for the review, Attila. >>> >>> I’ve uploaded a new webrev with your suggested changes (including making >>> ScriptObject.getProto(int) accept 0 argument and refactoring GET_PROTO code >>> in CodeGenerator into a method). >>> >>> I have also done extensive performance testing over the last days and found >>> that for some reason, shared methods for variable access has a very >>> detrimental effect on performance for some reason. My theory is that we >>> don’t save as much by making property access shared, and the flood of >>> additional methods has some significant cost on codegen, runtime, JIT etc. >>> Based on this I decided to increase the threshold for shared property >>> access again to 100, which performs noticeably better than with the lower >>> threshold in some benchmarks. >>> >>> New webrev is here: >>> >>> http://cr.openjdk.java.net/~hannesw/8069338/webrev.01/ >>> >>> Hannes >>> >>> >>>> Am 11.12.2017 um 11:55 schrieb Attila Szegedi<szege...@gmail.com>: >>>> >>>> Reviewing this now, thanks for going ahead and implementing it! >>>> >>>> So what you are saying about slow scopes is that shared scopes were >>>> disabled anyway with them for some time, so you didn’t really take away >>>> functionality, just cleaned up the remains? >>>> >>>> So, some remarks: >>>> >>>> 1. I see the bytecode shape you wrote around invocation of >>>> ScriptObject.getProto(int), and I realized it’s weird it asserts n> 0 and >>>> it has the first getProto() unrolled before the loop. I’m pretty sure it >>>> can just look like this: >>>> >>>> public final ScriptObject getProto(final int n) { >>>> ScriptObject p = this; >>>> for (int i = n; i--> 0;) { >>>> p = p.getProto(); >>>> } >>>> return p; >>>> } >>>> >>>> That assert was there because we knew that it’s only CodeGenerator that >>>> emits calls to it, and it will always emit invocations with n> 0, but now >>>> we’d have a justification for invoking it with n == 0, so I think it’s >>>> fine to do it and avoid the no_proto_call branch in shared scope call >>>> bytecode. It’s not a big deal even if you leave it as-is, though. >>>> >>>> To be entirely pedantic, that assert in getProto should’ve read “n> 1” >>>> before because the CodeGenerator was guaranteed to emit invocations to it >>>> with n> 1, so a really pedantic implementation of it should’ve read: >>>> >>>> public final ScriptObject getProto(final int n) { >>>> assert n> 1; >>>> ScriptObject p = getProto().getProto(); >>>> for (int i = n - 1; --i> 0;) { >>>> p = p.getProto(); >>>> } >>>> return p; >>>> } >>>> >>>> (God, I really hope everyone reading this realizes I’m joking with this >>>> last one.) >>>> >>>> FWIW, we could also factor out the: >>>> >>>> if (depth> 1) { >>>> method.load(depth); >>>> method.invoke(ScriptObject.GET_PROTO_DEPTH); >>>> } else { >>>> method.invoke(ScriptObject.GET_PROTO); >>>> } >>>> >>>> pattern in CodeGenerator into its own little “emitGetProto(int depth)” >>>> method, as it appears twice (and make sure it asserts on depth> 0 ;-) ) >>>> >>>> 2. For that invocation of UnwarrantedOptimismException.withProgramPoint - >>>> I’d create a Call objects using CompilerConstants.virtualCallNoLookup and >>>> stash it in a static final field either in SharedScopeCall or >>>> UnwarrantedOptimismException; it’s more typesafe than writing type >>>> descriptors as strings. >>>> >>>> 3. So, UOE.hasPrimitiveReturnValue was unused, I take it? >>>> >>>> 3. In getStaticSignature you have another occurrence of number 3 that you >>>> can replace with FIXED_PARAM_COUNT :-) >>>> >>>> But these are all minor points… overall, this looks really good. >>>> >>>> Attila. >>>> >>>>> On Dec 6, 2017, at 6:43 PM, Hannes >>>>> Wallnöfer<hannes.wallnoe...@oracle.com> wrote: >>>>> >>>>> Please review: >>>>> >>>>> Bug: https://bugs.openjdk.java.net/browse/JDK-8069338 >>>>> Webrev: http://cr.openjdk.java.net/~hannesw/8069338/webrev.00/ >>>>> >>>>> This implements shared scope calls for optimistic vars/calls. I followed >>>>> Attila’s blueprint in the bug description to the last detail - thanks for >>>>> figuring it all out. >>>>> >>>>> Some adjustments and cleanups I did along the way: >>>>> >>>>> - Originally shared scope calls were designed to support slow scope vars >>>>> (with/eval). However, that feature was disabled later on. I refactored >>>>> the code to make it clear that we only do shared scope calls for fast >>>>> scope operations. >>>>> - I unified the threshold for all shared scope operations to 5. I don’t >>>>> think there is a reason for different thresholds for different >>>>> operations. I did some testing, using 5 as threshold appeared to be a >>>>> sensible value. >>>>> >>>>> Running all of the octane benchmark I see a decrease in created >>>>> callsites (200 000 to 178 000) and a slight decrease in callsite >>>>> invalidations. >>>>> >>>>> Hannes >