8046268: compiler/whitebox/ tests fail : must be osr_compiled
Summary: Added code to 'warm up' the methods before triggering OSR compilation by executing them a limited number of times. Like this, the profile information marks the loop exit as taken and we don't add an uncommon trap.
Reviewed-by: kvn, dlong, iignatyev
This document describes system properties that are used for internaldebugging and instrumentation purposes, along with the system loggers,which are used for the same thing.This document is intended as a developer resource, and it is notneeded as Nashorn documentation for normal usage. Flags and systemproperties described herein are subject to change without notice.=====================================1. System properties used internally=====================================This documentation of the system property flags assume that thedefault value of the flag is false, unless otherwise specified.SYSTEM PROPERTY: -Dnashorn.args=<string>This property takes as its value a space separated list of Nashorncommand line options that should be passed to Nashorn. This might beuseful in environments where it is hard to tell how a nashorn.jar islaunched.Example:> java -Dnashorn.args="--lazy-complation --log=compiler" large-java-app-with-nashorn.jar > ant -Dnashorn.args="--log=codegen" antjobSYSTEM PROPERTY: -Dnashorn.unstable.relink.threshold=xThis property controls how many call site misses are allowed before a callsite is relinked with "apply" semantics to never change again. In the case of megamorphic callsites, this is necessary, or the program would spend all its time swapping out callsite targets. Dynalink has a default value (currently 8 relinks) for this property if it is not explicitly set.SYSTEM PROPERTY: -Dnashorn.compiler.splitter.threshold=xThis will change the node weight that requires a subgraph of the IR tobe split into several classes in order not to run out of bytecode space.The default value is 0x8000 (32768).SYSTEM PROPERTY: -Dnashorn.compiler.intarithmetic(and integer arithmetic in general)<currently disabled - this is being refactored for update releases> Arithmetic operations in Nashorn (except bitwise ones) typicallycoerce the operands to doubles (as per the JavaScript spec). To switchthis off and remain in integer mode, for example for "var x = a&b; vary = c&d; var z = x*y;", use this flag. This will force themultiplication of variables that are ints to be done with the IMULbytecode and the result "z" to become an int.WARNING: Note that is is experimental only to ensure that type supportexists for all primitive types. The generated code is unsound. Thiswill be the case until we do optimizations based on it. There is a CRin Nashorn to do better range analysis, and ensure that this is onlydone where the operation can't overflow into a wider type. Currentlyno overflow checking is done, so at the moment, until range analysishas been completed, this option is turned off.We've experimented by using int arithmetic for everything and puttingoverflow checks afterwards, which would recompute the operation withthe correct precision, but have yet to find a configuration where thisis faster than just using doubles directly, even if the int operationdoes not overflow. Getting access to a JVM intrinsic that does branchon overflow would probably alleviate this.The future:We are transitioning to an optimistic type system that uses intarithmetic everywhere until proven wrong. The problem here is mostlycatch an overflow exception and rolling back the state to a new methodwith less optimistic assumptions for an operation at a particularprogram point. This will most likely not be in the Java 8.0 releasebut likely end up in an update releaseFor Java 8, several java.lang.Math methods like addExact, subExact andmulExact are available to help us. Experiments intrinsifying theseshow a lot of promise, and we have devised a system that basicallydoes on stack replacement with exceptions in bytecode to reverterroneous assumptions. An explanation of how this works and what weare doing can be found here:http://www.slideshare.net/lagergren/lagergren-jvmls2013finalExperiments with this show significant ~x2-3 performance increases onpretty much everything, provided that optimistic assumptions don'tfail much. It will affect warmup time negatively, depending on howmany erroneous too optimistic assumptions are placed in the code atcompile time. We don't think this will be much of an issue.For example for a small benchmark that repeatedly executes thismethod taken from the Crypto Octane benchmark function am3(i,x,w,j,c,n) { var this_array = this.array; var w_array = w.array; var xl = x&0x3fff, xh = x>>14; while(--n >= 0) { var l = this_array[i]&0x3fff; var h = this_array[i++]>>14; var m = xh*l+h*xl; l = xl*l+((m&0x3fff)<<14)+w_array[j]+c; c = (l>>28)+(m>>14)+xh*h; w_array[j++] = l&0xfffffff; } return c;}The performance increase more than doubles. We are also working hardwith the code generation team in the Java Virtual Machine to fixthings that are lacking in invokedynamic performance, which is anotherarea where a lot of ongoing performance work takes place"Pessimistic" bytecode for am3, guaranteed to be semantically correct:// access flags 0x9 public static am3(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; L0 LINENUMBER 12 L0 ALOAD 0 INVOKEDYNAMIC dyn:getProp|getElem|getMethod:array(Ljava/lang/Object;)Ljava/lang/Object; [ // handle kind 0x6 : INVOKESTATIC jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;) // arguments: 0 ] ASTORE 8 L1 LINENUMBER 13 L1 ALOAD 3 INVOKEDYNAMIC dyn:getProp|getElem|getMethod:array(Ljava/lang/Object;)Ljava/lang/Object; [ // handle kind 0x6 : INVOKESTATIC jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;) // arguments: 0 ] ASTORE 9 L2 LINENUMBER 14 L2 ALOAD 2 INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toInt32 (Ljava/lang/Object;)I SIPUSH 16383 IAND ISTORE 10 ALOAD 2 INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toInt32 (Ljava/lang/Object;)I BIPUSH 14 ISHR ISTORE 11 L3 LINENUMBER 15 L3 GOTO L4 L5 LINENUMBER 16 L5 FRAME FULL [java/lang/Object java/lang/Object java/lang/Object java/lang/Object java/lang/Object java/lang/Object java/lang/Double T java/lang/Object java/lang/Object I I] [] ALOAD 8 ALOAD 1 INVOKEDYNAMIC dyn:getElem|getProp|getMethod(Ljava/lang/Object;Ljava/lang/Object;)I [ // handle kind 0x6 : INVOKESTATIC jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;) // arguments: 0 ] SIPUSH 16383 IAND INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer; ASTORE 12 L6 LINENUMBER 17 L6 ALOAD 8 ALOAD 1 INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toNumber (Ljava/lang/Object;)D DUP2 DCONST_1 DADD INVOKESTATIC java/lang/Double.valueOf (D)Ljava/lang/Double; ASTORE 1 INVOKEDYNAMIC dyn:getElem|getProp|getMethod(Ljava/lang/Object;D)I [ // handle kind 0x6 : INVOKESTATIC jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;) // arguments: 0 ] BIPUSH 14 ISHR ISTORE 13 L7 LINENUMBER 18 L7 ILOAD 11 I2D ALOAD 12 INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toNumber (Ljava/lang/Object;)D DMUL ILOAD 13 I2D ILOAD 10 I2D DMUL DADD DSTORE 14 L8 LINENUMBER 19 L8 ILOAD 10 I2D ALOAD 12 INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toNumber (Ljava/lang/Object;)D DMUL DLOAD 14 INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toInt32 (D)I SIPUSH 16383 IAND BIPUSH 14 ISHL I2D DADD ALOAD 9 ALOAD 4 INVOKEDYNAMIC dyn:getElem|getProp|getMethod(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; [ // handle kind 0x6 : INVOKESTATIC jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;) // arguments: 0 ] INVOKEDYNAMIC ADD:ODO_D(DLjava/lang/Object;)Ljava/lang/Object; [ // handle kind 0x6 : INVOKESTATIC jdk/nashorn/internal/runtime/linker/Bootstrap.runtimeBootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;) // arguments: none ] ALOAD 5 INVOKEDYNAMIC ADD:OOO_I(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; [ // handle kind 0x6 : INVOKESTATIC jdk/nashorn/internal/runtime/linker/Bootstrap.runtimeBootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;) // arguments: none ] ASTORE 12 L9 LINENUMBER 20 L9 ALOAD 12 INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toInt32 (Ljava/lang/Object;)I BIPUSH 28 ISHR I2D DLOAD 14 INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toInt32 (D)I BIPUSH 14 ISHR I2D DADD ILOAD 11 I2D ILOAD 13 I2D DMUL DADD INVOKESTATIC java/lang/Double.valueOf (D)Ljava/lang/Double; ASTORE 5 L10 LINENUMBER 21 L10 ALOAD 9 ALOAD 4 INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toNumber (Ljava/lang/Object;)D DUP2 DCONST_1 DADD INVOKESTATIC java/lang/Double.valueOf (D)Ljava/lang/Double; ASTORE 4 ALOAD 12 INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toInt32 (Ljava/lang/Object;)I LDC 268435455 IAND INVOKEDYNAMIC dyn:setElem|setProp(Ljava/lang/Object;DI)V [ // handle kind 0x6 : INVOKESTATIC jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;) // arguments: 0 ] L4 FRAME FULL [java/lang/Object java/lang/Object java/lang/Object java/lang/Object java/lang/Object java/lang/Object java/lang/Object T java/lang/Object java/lang/Object I I] [] ALOAD 6 INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toNumber (Ljava/lang/Object;)D LDC -1.0 DADD DUP2 INVOKESTATIC java/lang/Double.valueOf (D)Ljava/lang/Double; ASTORE 6 DCONST_0 DCMPL IFGE L5 L11 LINENUMBER 24 L11 ALOAD 5 ARETURN"Optimistic" bytecode that requires invalidation on e.g overflow. Factorx2-3 speedup:public static am3(Ljava/lang/Object;IILjava/lang/Object;III)I L0 LINENUMBER 12 L0 ALOAD 0 INVOKEDYNAMIC dyn:getProp|getElem|getMethod:array(Ljava/lang/Object;)Ljava/lang/Object; [ // handle kind 0x6 : INVOKESTATIC jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;) // arguments: 0 ] ASTORE 8 L1 LINENUMBER 13 L1 ALOAD 3 INVOKEDYNAMIC dyn:getProp|getElem|getMethod:array(Ljava/lang/Object;)Ljava/lang/Object; [ // handle kind 0x6 : INVOKESTATIC jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;) // arguments: 0 ] ASTORE 9 L2 LINENUMBER 14 L2 ILOAD 2 SIPUSH 16383 IAND ISTORE 10 ILOAD 2 BIPUSH 14 ISHR ISTORE 11 L3 LINENUMBER 15 L3 GOTO L4 L5 LINENUMBER 16 L5 FRAME FULL [java/lang/Object I I java/lang/Object I I I T java/lang/Object java/lang/Object I I] [] ALOAD 8 ILOAD 1 INVOKEDYNAMIC dyn:getElem|getProp|getMethod(Ljava/lang/Object;I)I [ // handle kind 0x6 : INVOKESTATIC jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;) // arguments: 0 ] SIPUSH 16383 IAND ISTORE 12 L6 LINENUMBER 17 L6 ALOAD 8 ILOAD 1 DUP ICONST_1 IADD ISTORE 1 INVOKEDYNAMIC dyn:getElem|getProp|getMethod(Ljava/lang/Object;I)I [ // handle kind 0x6 : INVOKESTATIC jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;) // arguments: 0 ] BIPUSH 14 ISHR ISTORE 13 L7 LINENUMBER 18 L7 ILOAD 11 ILOAD 12 BIPUSH 8 INVOKESTATIC jdk/nashorn/internal/runtime/JSType.mulExact (III)I ILOAD 13 ILOAD 10 BIPUSH 9 INVOKESTATIC jdk/nashorn/internal/runtime/JSType.mulExact (III)I IADD ISTORE 14 L8 LINENUMBER 19 L8 ILOAD 10 ILOAD 12 BIPUSH 11 INVOKESTATIC jdk/nashorn/internal/runtime/JSType.mulExact (III)I ILOAD 14 SIPUSH 16383 IAND BIPUSH 14 ISHL IADD ALOAD 9 ILOAD 4 INVOKEDYNAMIC dyn:getElem|getProp|getMethod(Ljava/lang/Object;I)I [ // handle kind 0x6 : INVOKESTATIC jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;) // arguments: 0 ] IADD ILOAD 5 IADD ISTORE 12 L9 LINENUMBER 20 L9 ILOAD 12 BIPUSH 28 ISHR ILOAD 14 BIPUSH 14 ISHR IADD ILOAD 11 ILOAD 13 BIPUSH 21 INVOKESTATIC jdk/nashorn/internal/runtime/JSType.mulExact (III)I IADD ISTORE 5 L10 LINENUMBER 21 L10 ALOAD 9 ILOAD 4 DUP ICONST_1 IADD ISTORE 4 ILOAD 12 LDC 268435455 IAND INVOKEDYNAMIC dyn:setElem|setProp(Ljava/lang/Object;II)V [ // handle kind 0x6 : INVOKESTATIC jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;) // arguments: 0 ] L4 FRAME SAME ILOAD 6 ICONST_M1 IADD DUP ISTORE 6 ICONST_0 IF_ICMPGE L5 L11 LINENUMBER 24 L11 ILOAD 5 IRETURNSYSTEM PROPERTY: -Dnashorn.codegen.debug, -Dnashorn.codegen.debug.trace=<x>See the description of the codegen logger below.SYSTEM_PROPERTY: -Dnashorn.fields.debugSee the description on the fields logger below.SYSTEM PROPERTY: -Dnashorn.fields.dualWhen this property is true, Nashorn will attempt to use primitivefields for AccessorProperties (currently just AccessorProperties, notspill properties). Memory footprint for script objects will increase,as we need to maintain both a primitive field (a long) as well as anObject field for the property value. Ints are represented as the 32low bits of the long fields. Doubles are represented as thedoubleToLongBits of their value. This way a single field can be usedfor all primitive types. Packing and unpacking doubles to their bitrepresentation is intrinsified by the JVM and extremely fast.While dual fields in theory runs significantly faster than Objectfields due to reduction of boxing and memory allocation overhead,there is still work to be done to make this a general purposesolution. Research is ongoing.In the future, this might complement or be replaced by experimentalfeature sun.misc.TaggedArray, which has been discussed on the mlvmmailing list. TaggedArrays are basically a way to share data spacebetween primitives and references, and have the GC understand this.As long as only primitive values are written to the fields and enoughtype information exists to make sure that any reads don't have to beuselessly boxed and unboxed, this is significantly faster than thestandard "Objects only" approach that currently is the default. Seetest/examples/dual-fields-micro.js for an example that runs twice asfast with dual fields as without them. Here, the compiler, candetermine that we are dealing with numbers only throughout the entireproperty life span of the properties involved.If a "real" object (not a boxed primitive) is written to a field thathas a primitive representation, its callsite is relinked and an Objectfield is used forevermore for that particular field in thatPropertyMap and its children, even if primitives are later assigned toit.As the amount of compile time type information is very small in adynamic language like JavaScript, it is frequently the case thatsomething has to be treated as an object, because we don't know anybetter. In reality though, it is often a boxed primitive is stored toan AccessorProperty. The fastest way to handle this soundly is to usea callsite typecheck and avoid blowing the field up to an Object. Wenever revert object fields to primitives. Ping-pong:ing back and forthbetween primitive representation and Object representation would causefatal performance overhead, so this is not an option.For a general application the dual fields approach is still slowerthan objects only fields in some places, about the same in most cases,and significantly faster in very few. This is due the program usingprimitives, but we still can't prove it. For example "local_var a =call(); field = a;" may very well write a double to the field, but thecompiler dare not guess a double type if field is a local variable,due to bytecode variables being strongly typed and later noninterchangeable. To get around this, the entire method would have tobe replaced and a continuation retained to restart from. We believethat the next steps we should go through are instead:1) Implement method specialization based on callsite, as it's quitefrequently the case that numbers are passed around, but currently ourfunction nodes just have object types visible to the compiler. Forexample "var b = 17; func(a,b,17)" is an example where two parameterscan be specialized, but the main version of func might also be calledfrom another callsite with func(x,y,"string").2) This requires lazy jitting as the functions have to be specializedper callsite.Even though "function square(x) { return x*x }" might look like atrivial function that can always only take doubles, this is nottrue. Someone might have overridden the valueOf for x so that thetoNumber coercion has side effects. To fulfil JavaScript semantics,the coercion has to run twice for both terms of the multiplicationeven if they are the same object. This means that call sitespecialization is necessary, not parameter specialization on the form"function square(x) { var xd = (double)x; return xd*xd; }", as onemight first think.Generating a method specialization for any variant of a function thatwe can determine by types at compile time is a combinatorial explosionof byte code (try it e.g. on all the variants of am3 in the Octanebenchmark crypto.js). Thus, this needs to be lazy3) Optimistic callsite writes, something on the formx = y; //x is a field known to be a primitive. y is only an object asfar as we can tellturns intotry { x = (int)y;} catch (X is not an integer field right now | ClassCastException e) { x = y;}Mini POC shows that this is the key to a lot of dual field performancein seemingly trivial micros where one unknown object, in realityactually a primitive, foils it for us. Very common pattern. Once weare "all primitives", dual fields runs a lot faster than Object fieldsonly.We still have to deal with objects vs primitives for local bytecodeslots, possibly through code copying and versioning.The Future:We expect the usefulness of dual fields to increase significantlyafter the optimistic type system described in the section on integer arithmetic above is implemented.SYSTEM PROPERTY: -Dnashorn.compiler.symbol.trace=[<x>[,*]], -Dnashorn.compiler.symbol.stacktrace=[<x>[,*]]When this property is set, creation and manipulation of any symbolnamed "x" will show information about when the compiler changes itstype assumption, bytecode local variable slot assignment and otherdata. This is useful if, for example, a symbol shows up as an Object,when you believe it should be a primitive. Usually there is anexplanation for this, for example that it exists in the global scopeand type analysis has to be more conservative. Several symbols names to watch can be specified by comma separation.If no variable name is specified (and no equals sign), all symbolswill be watchedBy using "stacktrace" instead of or together with "trace", stacktraces will be displayed upon symbol changes according to the samesemantics.SYSTEM PROPERTY: -Dnashorn.lexer.xmlliteralsIf this property it set, it means that the Lexer should attempt toparse XML literals, which would otherwise generate syntaxerrors. Warning: there are currently no unit tests for thisfunctionality.XML literals, when this is enabled, end up as standard LiteralNodes inthe IR.SYSTEM_PROPERTY: -Dnashorn.debugIf this property is set to true, Nashorn runs in Debug mode. Debugmode is slightly slower, as for example statistics counters are enabledduring the run. Debug mode makes available a NativeDebug instancecalled "Debug" in the global space that can be used to print propertymaps and layout for script objects, as well as a "dumpCounters" methodthat will print the current values of the previously mentioned statscounters.These functions currently exists for Debug:"map" - print(Debug.map(x)) will dump the PropertyMap for object x tostdout (currently there also exist functions called "embedX", where Xis a value from 0 to 3, that will dump the contents of the embed poolfor the first spill properties in any script object and "spill", thatwill dump the contents of the growing spill pool of spill propertiesin any script object. This is of course subject to change withoutnotice, should we change the script object layout."methodHandle" - this method returns the method handle that is usedfor invoking a particular script function."identical" - this method compares two script objects for referenceequality. It is a == Java comparison"dumpCounters" - will dump the debug counters' current values tostdout.Currently we count number of ScriptObjects in the system, number ofScope objects in the system, number of ScriptObject listeners added,removed and dead (without references).We also count number of ScriptFunctions, ScriptFunction invocationsand ScriptFunction allocations.Furthermore we count PropertyMap statistics: how many property mapsexist, how many times were property maps cloned, how many times didthe property map history cache hit, prevent new allocations, how manyprototype invalidations were done, how many time the property mapproto cache hit.Finally we count callsite misses on a per callsite bases, which occurwhen a callsite has to be relinked, due to a previous assumption ofobject layout being invalidated.SYSTEM PROPERTY: -Dnashorn.methodhandles.debug,-Dnashorn.methodhandles.debug=createIf this property is enabled, each MethodHandle related call that usesthe java.lang.invoke package gets its MethodHandle intercepted and aninstrumentation printout of arguments and return value appended toit. This shows exactly which method handles are executed and fromwhere. (Also MethodTypes and SwitchPoints). This can be augmented withmore information, for example, instance count, by subclassing orfurther extending the TraceMethodHandleFactory implementation inMethodHandleFactory.java.If the property is specialized with "=create" as its option,instrumentation will be shown for method handles upon creation timerather than at runtime usage.SYSTEM PROPERTY: -Dnashorn.methodhandles.debug.stacktraceThis does the same as nashorn.methodhandles.debug, but when enabledalso dumps the stack trace for every instrumented method handleoperation. Warning: This is enormously verbose, but provides a prettydecent "grep:able" picture of where the calls are coming from.See the description of the codegen logger below for a more verbosedescription of this optionSYSTEM PROPERTY: -Dnashorn.scriptfunction.specialization.disableThere are several "fast path" implementations of constructors andfunctions in the NativeObject classes that, in their original form,take a variable amount of arguments. Said functions are also declaredto take Object parameters in their original form, as this is what theJavaScript specification mandates.However, we often know quite a lot more at a callsite of one of thesefunctions. For example, Math.min is called with a fixed number (2) ofinteger arguments. The overhead of boxing these ints to Objects andfolding them into an Object array for the generic varargs Math.minfunction is an order of magnitude slower than calling a specializedimplementation of Math.min that takes two integers. Specializedfunctions and constructors are identified by the tag@SpecializedFunction and @SpecializedConstructor in the Nashorncode. The linker will link in the most appropriate (narrowest types,right number of types and least number of arguments) specialization ifspecializations are available.Every ScriptFunction may carry specializations that the linker canchoose from. This framework will likely be extended for user definedfunctions. The compiler can often infer enough parameter type infofrom callsites for in order to generate simpler versions with lessgeneric Object types. This feature depends on future lazy jitting, asthere tend to be many calls to user defined functions, some where thecallsite can be specialized, some where we mostly see objectparameters even at the callsite.If this system property is set to true, the linker will not attempt touse any specialized function or constructor for native objects, butjust call the generic one.SYSTEM PROPERTY: -Dnashorn.tcs.miss.samplePercent=<x>When running with the trace callsite option (-tcs), Nashorn will countand instrument any callsite misses that require relinking. As thenumber of relinks is large and usually produces a lot of output, thissystem property can be used to constrain the percentage of misses thatshould be logged. Typically this is set to 1 or 5 (percent). 1% is thedefault value.SYSTEM_PROPERTY: -Dnashorn.profilefile=<filename>When running with the profile callsite options (-pcs), Nashorn willdump profiling data for all callsites to stderr as a shutdown hook. Toinstead redirect this to a file, specify the path to the file usingthis system property.SYSTEM_PROPERTY: -Dnashorn.regexp.impl=[jdk|joni]This property defines the regular expression engine to be used byNashorn. Set this flag to "jdk" to get an implementation based on theJDK's java.util.regex package. Set this property to "joni" to installan implementation based on Joni, the regular expression engine used bythe JRuby project. The default value for this flag is "joni"===============2. The loggers.===============It is very simple to create your own logger. Use the DebugLogger classand give the subsystem name as a constructor argument.The Nashorn loggers can be used to print per-module or per-subsystemdebug information with different levels of verbosity. The loggers fora given subsystem are available are enabled by using--log=<systemname>[:<level>]on the command line.Here <systemname> identifies the name of the subsystem to be loggedand the optional colon and level argument is a standardjava.util.logging.Level name (severe, warning, info, config, fine,finer, finest). If the level is left out for a particular subsystem,it defaults to "info". Any log message logged as the level or a levelthat is more important will be output to stderr by the logger.Several loggers can be enabled by a single command line option, byputting a comma after each subsystem/level tuple (or each subsystem iflevel is unspecified). The --log option can also be given multipletimes on the same command line, with the same effect.For example: --log=codegen,fields:finest is equivalent to--log=codegen:info --log=fields:finestThe subsystems that currently support logging are:* compilerThe compiler is in charge of turning source code and function nodesinto byte code, and installs the classes into a class loadercontrolled from the Context. Log messages are, for example, aboutthings like new compile units being allocated. The compiler has globalsettings that all the tiers of codegen (e.g. Lower and CodeGenerator)use.s* codegenThe code generator is the emitter stage of the code pipeline, andturns the lowest tier of a FunctionNode into bytecode. Codegen loggingshows byte codes as they are being emitted, line number informationand jumps. It also shows the contents of the bytecode stack prior toeach instruction being emitted. This is a good debugging aid. Forexample:[codegen] #41 line:2 (f)_afc824e [codegen] #42 load symbol x slot=2 [codegen] #43 {1:O} load int 0 [codegen] #44 {2:I O} dynamic_runtime_call GT:ZOI_I args=2 returnType=boolean [codegen] #45 signature (Ljava/lang/Object;I)Z [codegen] #46 {1:Z} ifeq ternary_false_5402fe28 [codegen] #47 load symbol x slot=2 [codegen] #48 {1:O} goto ternary_exit_107c1f2f [codegen] #49 ternary_false_5402fe28 [codegen] #50 load symbol x slot=2 [codegen] #51 {1:O} convert object -> double [codegen] #52 {1:D} neg [codegen] #53 {1:D} convert double -> object [codegen] #54 {1:O} ternary_exit_107c1f2f [codegen] #55 {1:O} return object shows a ternary node being generated for the sequence "return x > 0 ?x : -x"The first number on the log line is a unique monotonically increasingemission id per bytecode. There is no guarantee this is the same idbetween runs. depending on non deterministic codeexecution/compilation, but for small applications it usually is. Ifthe system variable -Dnashorn.codegen.debug.trace=<x> is set, where xis a bytecode emission id, a stack trace will be shown as theparticular bytecode is about to be emitted. This can be a quick way todetermine where it comes from without attaching the debugger. "Whogenerated that neg?"The --log=codegen option is equivalent to setting the system variable"nashorn.codegen.debug" to true.* foldShows constant folding taking place before lowering* lowerThis is the first lowering pass.Lower is a code generation pass that turns high level IR nodes intolower level one, for example substituting comparisons to RuntimeNodesand inlining finally blocks.Lower is also responsible for determining control flow informationlike end points.* attrThe lowering annotates a FunctionNode with symbols for each identifierand transforms high level constructs into lower level ones, that theCodeGenerator consumes.Lower logging typically outputs things like post pass actions,insertions of casts because symbol types have been changed and typespecialization information. Currently very little info is generated bythis logger. This will probably change.* finalizeThis --log=finalize log option outputs information for type finalization,the third tier of the compiler. This means things like placement of specialized scope nodes or explicit conversions. * fieldsThe --log=fields option (at info level) is equivalent to setting thesystem variable "nashorn.fields.debug" to true. At the info level itwill only show info about type assumptions that were invalidated. Ifthe level is set to finest, it will also trace every AccessorPropertygetter and setter in the program, show arguments, return valuesetc. It will also show the internal representation of respective field(Object in the normal case, unless running with the dual fieldrepresentation)* timeThis enables timers for various phases of script compilation. The timerswill be dumped when the Nashorn process exits. We see a percentage valueof how much time was spent not executing bytecode (i.e. compilation andinternal tasks) at the end of the report. A finer level than "info" will show individual compilation timings as theyhappen.Here is an example:[time] Accumulated complation phase Timings:[time] [time] 'JavaScript Parsing' 1076 ms[time] 'Constant Folding' 159 ms[time] 'Control Flow Lowering' 303 ms[time] 'Program Point Calculation' 282 ms[time] 'Builtin Replacement' 71 ms[time] 'Code Splitting' 670 ms[time] 'Symbol Assignment' 474 ms[time] 'Scope Depth Computation' 249 ms[time] 'Optimistic Type Assignment' 186 ms[time] 'Local Variable Type Calculation' 526 ms[time] 'Bytecode Generation' 5177 ms[time] 'Class Installation' 1854 ms[time] [time] Total runtime: 11994 ms (Non-runtime: 11027 ms [91%])=======================3. Undocumented options=======================Here follows a short description of undocumented options for Nashorn.To see a list of all undocumented options, use the (undocumented) flag"-xhelp".i.e. jjs -xhelp or java -jar nashorn.jar -xhelpUndocumented options are not guaranteed to work, run correctly or bebug free. They are experimental and for internal or debugging use.They are also subject to change without notice.In practice, though, all options below not explicitly documented asEXPERIMENTAL can be relied upon, for example --dump-on-error is usefulfor any JavaScript/Nashorn developer, but there is no guarantee.A short summary follows: -D (-Dname=value. Set a system property. This option can be repeated.) -ccs, --class-cache-size (Size of the Class cache size per global scope.) -cp, -classpath (-cp path. Specify where to find user class files.) -co, --compile-only (Compile without running.) param: [true|false] default: false -d, --dump-debug-dir (specify a destination directory to dump class files.) param: <path> --debug-lines (Generate line number table in .class files.) param: [true|false] default: true --debug-locals (Generate local variable table in .class files.) param: [true|false] default: false -doe, -dump-on-error (Dump a stack trace on errors.) param: [true|false] default: false --early-lvalue-error (invalid lvalue expressions should be reported as early errors.) param: [true|false] default: true --empty-statements (Preserve empty statements in AST.) param: [true|false] default: false -fv, -fullversion (Print full version info of Nashorn.) param: [true|false] default: false --function-statement-error (Report an error when function declaration is used as a statement.) param: [true|false] default: false --function-statement-warning (Warn when function declaration is used as a statement.) param: [true|false] default: false -fx (Launch script as an fx application.) param: [true|false] default: false --global-per-engine (Use single Global instance per script engine instance.) param: [true|false] default: false -h, -help (Print help for command line flags.) param: [true|false] default: false --loader-per-compile (Create a new class loader per compile.) param: [true|false] default: true -l, --locale (Set Locale for script execution.) param: <locale> default: en-US --log (Enable logging of a given level for a given number of sub systems. [for example: --log=fields:finest,codegen:info].) param: <module:level>,* -nj, --no-java (Disable Java support.) param: [true|false] default: false -nse, --no-syntax-extensions (Disallow non-standard syntax extensions.) param: [true|false] default: false -nta, --no-typed-arrays (Disable typed arrays support.) param: [true|false] default: false --parse-only (Parse without compiling.) param: [true|false] default: false --print-ast (Print abstract syntax tree.) param: [true|false] default: false -pc, --print-code (Print generated bytecode. If a directory is specified, nothing will be dumped to stderr. Also, in that case, .dot files will be generated for all functions or for the function with the specified name only.) param: [dir:<output-dir>,function:<name>] --print-lower-ast (Print lowered abstract syntax tree.) param: [true|false] default: false -plp, --print-lower-parse (Print the parse tree after lowering.) param: [true|false] default: false --print-mem-usage (Print memory usage of IR after each compile stage.) param: [true|false] default: false --print-no-newline (Print function will not print new line char.) param: [true|false] default: false -pp, --print-parse (Print the parse tree.) param: [true|false] default: false --print-symbols (Print the symbol table.) param: [true|false] default: false -pcs, --profile-callsites (Dump callsite profile data.) param: [true|false] default: false -scripting (Enable scripting features.) param: [true|false] default: false --stderr (Redirect stderr to a filename or to another tty, e.g. stdout.) param: <output console> --stdout (Redirect stdout to a filename or to another tty, e.g. stderr.) param: <output console> -strict (Run scripts in strict mode.) param: [true|false] default: false -t, -timezone (Set timezone for script execution.) param: <timezone> default: Europe/Stockholm -tcs, --trace-callsites (Enable callsite trace mode. Options are: miss [trace callsite misses] enterexit [trace callsite enter/exit], objects [print object properties].) param: [=[option,]*] --verify-code (Verify byte code before running.) param: [true|false] default: false -v, -version (Print version info of Nashorn.) param: [true|false] default: false -xhelp (Print extended help for command line flags.) param: [true|false] default: false