aoqi@0: This document describes system properties that are used for internal aoqi@0: debugging and instrumentation purposes, along with the system loggers, aoqi@0: which are used for the same thing. aoqi@0: aoqi@0: This document is intended as a developer resource, and it is not aoqi@0: needed as Nashorn documentation for normal usage. Flags and system aoqi@0: properties described herein are subject to change without notice. aoqi@0: aoqi@0: ===================================== aoqi@0: 1. System properties used internally aoqi@0: ===================================== aoqi@0: aoqi@0: This documentation of the system property flags assume that the aoqi@0: default value of the flag is false, unless otherwise specified. aoqi@0: aoqi@0: SYSTEM PROPERTY: -Dnashorn.args= aoqi@0: aoqi@0: This property takes as its value a space separated list of Nashorn aoqi@0: command line options that should be passed to Nashorn. This might be aoqi@0: useful in environments where it is hard to tell how a nashorn.jar is aoqi@0: launched. aoqi@0: aoqi@0: Example: aoqi@0: aoqi@0: > java -Dnashorn.args="--lazy-complation --log=compiler" large-java-app-with-nashorn.jar aoqi@0: > ant -Dnashorn.args="--log=codegen" antjob aoqi@0: aoqi@0: SYSTEM PROPERTY: -Dnashorn.unstable.relink.threshold=x aoqi@0: aoqi@0: This property controls how many call site misses are allowed before a aoqi@0: callsite is relinked with "apply" semantics to never change again. aoqi@0: In the case of megamorphic callsites, this is necessary, or the aoqi@0: program would spend all its time swapping out callsite targets. Dynalink aoqi@0: has a default value (currently 8 relinks) for this property if it aoqi@0: is not explicitly set. aoqi@0: aoqi@0: aoqi@0: SYSTEM PROPERTY: -Dnashorn.compiler.splitter.threshold=x aoqi@0: aoqi@0: This will change the node weight that requires a subgraph of the IR to aoqi@0: be split into several classes in order not to run out of bytecode space. aoqi@0: The default value is 0x8000 (32768). aoqi@0: aoqi@0: aoqi@0: SYSTEM PROPERTY: -Dnashorn.compiler.intarithmetic aoqi@0: aoqi@0: (and integer arithmetic in general) aoqi@0: aoqi@0: aoqi@0: aoqi@0: Arithmetic operations in Nashorn (except bitwise ones) typically aoqi@0: coerce the operands to doubles (as per the JavaScript spec). To switch aoqi@0: this off and remain in integer mode, for example for "var x = a&b; var aoqi@0: y = c&d; var z = x*y;", use this flag. This will force the aoqi@0: multiplication of variables that are ints to be done with the IMUL aoqi@0: bytecode and the result "z" to become an int. aoqi@0: aoqi@0: WARNING: Note that is is experimental only to ensure that type support aoqi@0: exists for all primitive types. The generated code is unsound. This aoqi@0: will be the case until we do optimizations based on it. There is a CR aoqi@0: in Nashorn to do better range analysis, and ensure that this is only aoqi@0: done where the operation can't overflow into a wider type. Currently aoqi@0: no overflow checking is done, so at the moment, until range analysis aoqi@0: has been completed, this option is turned off. aoqi@0: aoqi@0: We've experimented by using int arithmetic for everything and putting aoqi@0: overflow checks afterwards, which would recompute the operation with aoqi@0: the correct precision, but have yet to find a configuration where this aoqi@0: is faster than just using doubles directly, even if the int operation aoqi@0: does not overflow. Getting access to a JVM intrinsic that does branch aoqi@0: on overflow would probably alleviate this. aoqi@0: aoqi@0: The future: aoqi@0: aoqi@0: We are transitioning to an optimistic type system that uses int aoqi@0: arithmetic everywhere until proven wrong. The problem here is mostly aoqi@0: catch an overflow exception and rolling back the state to a new method aoqi@0: with less optimistic assumptions for an operation at a particular aoqi@0: program point. This will most likely not be in the Java 8.0 release aoqi@0: but likely end up in an update release aoqi@0: aoqi@0: For Java 8, several java.lang.Math methods like addExact, subExact and aoqi@0: mulExact are available to help us. Experiments intrinsifying these aoqi@0: show a lot of promise, and we have devised a system that basically aoqi@0: does on stack replacement with exceptions in bytecode to revert aoqi@0: erroneous assumptions. An explanation of how this works and what we aoqi@0: are doing can be found here: aoqi@0: http://www.slideshare.net/lagergren/lagergren-jvmls2013final aoqi@0: aoqi@0: Experiments with this show significant ~x2-3 performance increases on aoqi@0: pretty much everything, provided that optimistic assumptions don't aoqi@0: fail much. It will affect warmup time negatively, depending on how aoqi@0: many erroneous too optimistic assumptions are placed in the code at aoqi@0: compile time. We don't think this will be much of an issue. aoqi@0: aoqi@0: For example for a small benchmark that repeatedly executes this aoqi@0: method taken from the Crypto Octane benchmark aoqi@0: aoqi@0: function am3(i,x,w,j,c,n) { aoqi@0: var this_array = this.array; aoqi@0: var w_array = w.array; aoqi@0: var xl = x&0x3fff, xh = x>>14; aoqi@0: while(--n >= 0) { aoqi@0: var l = this_array[i]&0x3fff; aoqi@0: var h = this_array[i++]>>14; aoqi@0: var m = xh*l+h*xl; aoqi@0: l = xl*l+((m&0x3fff)<<14)+w_array[j]+c; aoqi@0: c = (l>>28)+(m>>14)+xh*h; aoqi@0: w_array[j++] = l&0xfffffff; aoqi@0: } aoqi@0: aoqi@0: return c; aoqi@0: } aoqi@0: aoqi@0: The performance increase more than doubles. We are also working hard aoqi@0: with the code generation team in the Java Virtual Machine to fix aoqi@0: things that are lacking in invokedynamic performance, which is another aoqi@0: area where a lot of ongoing performance work takes place aoqi@0: aoqi@0: "Pessimistic" bytecode for am3, guaranteed to be semantically correct: aoqi@0: aoqi@0: // access flags 0x9 aoqi@0: 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; aoqi@0: L0 aoqi@0: LINENUMBER 12 L0 aoqi@0: ALOAD 0 aoqi@0: INVOKEDYNAMIC dyn:getProp|getElem|getMethod:array(Ljava/lang/Object;)Ljava/lang/Object; [ aoqi@0: // handle kind 0x6 : INVOKESTATIC aoqi@0: jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;) aoqi@0: // arguments: aoqi@0: 0 aoqi@0: ] aoqi@0: ASTORE 8 aoqi@0: L1 aoqi@0: LINENUMBER 13 L1 aoqi@0: ALOAD 3 aoqi@0: INVOKEDYNAMIC dyn:getProp|getElem|getMethod:array(Ljava/lang/Object;)Ljava/lang/Object; [ aoqi@0: // handle kind 0x6 : INVOKESTATIC aoqi@0: jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;) aoqi@0: // arguments: aoqi@0: 0 aoqi@0: ] aoqi@0: ASTORE 9 aoqi@0: L2 aoqi@0: LINENUMBER 14 L2 aoqi@0: ALOAD 2 aoqi@0: INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toInt32 (Ljava/lang/Object;)I aoqi@0: SIPUSH 16383 aoqi@0: IAND aoqi@0: ISTORE 10 aoqi@0: ALOAD 2 aoqi@0: INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toInt32 (Ljava/lang/Object;)I aoqi@0: BIPUSH 14 aoqi@0: ISHR aoqi@0: ISTORE 11 aoqi@0: L3 aoqi@0: LINENUMBER 15 L3 aoqi@0: GOTO L4 aoqi@0: L5 aoqi@0: LINENUMBER 16 L5 aoqi@0: 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] [] aoqi@0: ALOAD 8 aoqi@0: ALOAD 1 aoqi@0: INVOKEDYNAMIC dyn:getElem|getProp|getMethod(Ljava/lang/Object;Ljava/lang/Object;)I [ aoqi@0: // handle kind 0x6 : INVOKESTATIC aoqi@0: jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;) aoqi@0: // arguments: aoqi@0: 0 aoqi@0: ] aoqi@0: SIPUSH 16383 aoqi@0: IAND aoqi@0: INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer; aoqi@0: ASTORE 12 aoqi@0: L6 aoqi@0: LINENUMBER 17 L6 aoqi@0: ALOAD 8 aoqi@0: ALOAD 1 aoqi@0: INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toNumber (Ljava/lang/Object;)D aoqi@0: DUP2 aoqi@0: DCONST_1 aoqi@0: DADD aoqi@0: INVOKESTATIC java/lang/Double.valueOf (D)Ljava/lang/Double; aoqi@0: ASTORE 1 aoqi@0: INVOKEDYNAMIC dyn:getElem|getProp|getMethod(Ljava/lang/Object;D)I [ aoqi@0: // handle kind 0x6 : INVOKESTATIC aoqi@0: jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;) aoqi@0: // arguments: aoqi@0: 0 aoqi@0: ] aoqi@0: BIPUSH 14 aoqi@0: ISHR aoqi@0: ISTORE 13 aoqi@0: L7 aoqi@0: LINENUMBER 18 L7 aoqi@0: ILOAD 11 aoqi@0: I2D aoqi@0: ALOAD 12 aoqi@0: INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toNumber (Ljava/lang/Object;)D aoqi@0: DMUL aoqi@0: ILOAD 13 aoqi@0: I2D aoqi@0: ILOAD 10 aoqi@0: I2D aoqi@0: DMUL aoqi@0: DADD aoqi@0: DSTORE 14 aoqi@0: L8 aoqi@0: LINENUMBER 19 L8 aoqi@0: ILOAD 10 aoqi@0: I2D aoqi@0: ALOAD 12 aoqi@0: INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toNumber (Ljava/lang/Object;)D aoqi@0: DMUL aoqi@0: DLOAD 14 aoqi@0: INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toInt32 (D)I aoqi@0: SIPUSH 16383 aoqi@0: IAND aoqi@0: BIPUSH 14 aoqi@0: ISHL aoqi@0: I2D aoqi@0: DADD aoqi@0: ALOAD 9 aoqi@0: ALOAD 4 aoqi@0: INVOKEDYNAMIC dyn:getElem|getProp|getMethod(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; [ aoqi@0: // handle kind 0x6 : INVOKESTATIC aoqi@0: jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;) aoqi@0: // arguments: aoqi@0: 0 aoqi@0: ] aoqi@0: INVOKEDYNAMIC ADD:ODO_D(DLjava/lang/Object;)Ljava/lang/Object; [ aoqi@0: // handle kind 0x6 : INVOKESTATIC aoqi@0: jdk/nashorn/internal/runtime/linker/Bootstrap.runtimeBootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;) aoqi@0: // arguments: none aoqi@0: ] aoqi@0: ALOAD 5 aoqi@0: INVOKEDYNAMIC ADD:OOO_I(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; [ aoqi@0: // handle kind 0x6 : INVOKESTATIC aoqi@0: jdk/nashorn/internal/runtime/linker/Bootstrap.runtimeBootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;) aoqi@0: // arguments: none aoqi@0: ] aoqi@0: ASTORE 12 aoqi@0: L9 aoqi@0: LINENUMBER 20 L9 aoqi@0: ALOAD 12 aoqi@0: INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toInt32 (Ljava/lang/Object;)I aoqi@0: BIPUSH 28 aoqi@0: ISHR aoqi@0: I2D aoqi@0: DLOAD 14 aoqi@0: INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toInt32 (D)I aoqi@0: BIPUSH 14 aoqi@0: ISHR aoqi@0: I2D aoqi@0: DADD aoqi@0: ILOAD 11 aoqi@0: I2D aoqi@0: ILOAD 13 aoqi@0: I2D aoqi@0: DMUL aoqi@0: DADD aoqi@0: INVOKESTATIC java/lang/Double.valueOf (D)Ljava/lang/Double; aoqi@0: ASTORE 5 aoqi@0: L10 aoqi@0: LINENUMBER 21 L10 aoqi@0: ALOAD 9 aoqi@0: ALOAD 4 aoqi@0: INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toNumber (Ljava/lang/Object;)D aoqi@0: DUP2 aoqi@0: DCONST_1 aoqi@0: DADD aoqi@0: INVOKESTATIC java/lang/Double.valueOf (D)Ljava/lang/Double; aoqi@0: ASTORE 4 aoqi@0: ALOAD 12 aoqi@0: INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toInt32 (Ljava/lang/Object;)I aoqi@0: LDC 268435455 aoqi@0: IAND aoqi@0: INVOKEDYNAMIC dyn:setElem|setProp(Ljava/lang/Object;DI)V [ aoqi@0: // handle kind 0x6 : INVOKESTATIC aoqi@0: jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;) aoqi@0: // arguments: aoqi@0: 0 aoqi@0: ] aoqi@0: L4 aoqi@0: 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] [] aoqi@0: ALOAD 6 aoqi@0: INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toNumber (Ljava/lang/Object;)D aoqi@0: LDC -1.0 aoqi@0: DADD aoqi@0: DUP2 aoqi@0: INVOKESTATIC java/lang/Double.valueOf (D)Ljava/lang/Double; aoqi@0: ASTORE 6 aoqi@0: DCONST_0 aoqi@0: DCMPL aoqi@0: IFGE L5 aoqi@0: L11 aoqi@0: LINENUMBER 24 L11 aoqi@0: ALOAD 5 aoqi@0: ARETURN aoqi@0: aoqi@0: "Optimistic" bytecode that requires invalidation on e.g overflow. Factor aoqi@0: x2-3 speedup: aoqi@0: aoqi@0: public static am3(Ljava/lang/Object;IILjava/lang/Object;III)I aoqi@0: L0 aoqi@0: LINENUMBER 12 L0 aoqi@0: ALOAD 0 aoqi@0: INVOKEDYNAMIC dyn:getProp|getElem|getMethod:array(Ljava/lang/Object;)Ljava/lang/Object; [ aoqi@0: // handle kind 0x6 : INVOKESTATIC aoqi@0: jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;) aoqi@0: // arguments: aoqi@0: 0 aoqi@0: ] aoqi@0: ASTORE 8 aoqi@0: L1 aoqi@0: LINENUMBER 13 L1 aoqi@0: ALOAD 3 aoqi@0: INVOKEDYNAMIC dyn:getProp|getElem|getMethod:array(Ljava/lang/Object;)Ljava/lang/Object; [ aoqi@0: // handle kind 0x6 : INVOKESTATIC aoqi@0: jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;) aoqi@0: // arguments: aoqi@0: 0 aoqi@0: ] aoqi@0: ASTORE 9 aoqi@0: L2 aoqi@0: LINENUMBER 14 L2 aoqi@0: ILOAD 2 aoqi@0: SIPUSH 16383 aoqi@0: IAND aoqi@0: ISTORE 10 aoqi@0: ILOAD 2 aoqi@0: BIPUSH 14 aoqi@0: ISHR aoqi@0: ISTORE 11 aoqi@0: L3 aoqi@0: LINENUMBER 15 L3 aoqi@0: GOTO L4 aoqi@0: L5 aoqi@0: LINENUMBER 16 L5 aoqi@0: FRAME FULL [java/lang/Object I I java/lang/Object I I I T java/lang/Object java/lang/Object I I] [] aoqi@0: ALOAD 8 aoqi@0: ILOAD 1 aoqi@0: INVOKEDYNAMIC dyn:getElem|getProp|getMethod(Ljava/lang/Object;I)I [ aoqi@0: // handle kind 0x6 : INVOKESTATIC aoqi@0: jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;) aoqi@0: // arguments: aoqi@0: 0 aoqi@0: ] aoqi@0: SIPUSH 16383 aoqi@0: IAND aoqi@0: ISTORE 12 aoqi@0: L6 aoqi@0: LINENUMBER 17 L6 aoqi@0: ALOAD 8 aoqi@0: ILOAD 1 aoqi@0: DUP aoqi@0: ICONST_1 aoqi@0: IADD aoqi@0: ISTORE 1 aoqi@0: INVOKEDYNAMIC dyn:getElem|getProp|getMethod(Ljava/lang/Object;I)I [ aoqi@0: // handle kind 0x6 : INVOKESTATIC aoqi@0: jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;) aoqi@0: // arguments: aoqi@0: 0 aoqi@0: ] aoqi@0: BIPUSH 14 aoqi@0: ISHR aoqi@0: ISTORE 13 aoqi@0: L7 aoqi@0: LINENUMBER 18 L7 aoqi@0: ILOAD 11 aoqi@0: ILOAD 12 aoqi@0: BIPUSH 8 aoqi@0: INVOKESTATIC jdk/nashorn/internal/runtime/JSType.mulExact (III)I aoqi@0: ILOAD 13 aoqi@0: ILOAD 10 aoqi@0: BIPUSH 9 aoqi@0: INVOKESTATIC jdk/nashorn/internal/runtime/JSType.mulExact (III)I aoqi@0: IADD aoqi@0: ISTORE 14 aoqi@0: L8 aoqi@0: LINENUMBER 19 L8 aoqi@0: ILOAD 10 aoqi@0: ILOAD 12 aoqi@0: BIPUSH 11 aoqi@0: INVOKESTATIC jdk/nashorn/internal/runtime/JSType.mulExact (III)I aoqi@0: ILOAD 14 aoqi@0: SIPUSH 16383 aoqi@0: IAND aoqi@0: BIPUSH 14 aoqi@0: ISHL aoqi@0: IADD aoqi@0: ALOAD 9 aoqi@0: ILOAD 4 aoqi@0: INVOKEDYNAMIC dyn:getElem|getProp|getMethod(Ljava/lang/Object;I)I [ aoqi@0: // handle kind 0x6 : INVOKESTATIC aoqi@0: jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;) aoqi@0: // arguments: aoqi@0: 0 aoqi@0: ] aoqi@0: IADD aoqi@0: ILOAD 5 aoqi@0: IADD aoqi@0: ISTORE 12 aoqi@0: L9 aoqi@0: LINENUMBER 20 L9 aoqi@0: ILOAD 12 aoqi@0: BIPUSH 28 aoqi@0: ISHR aoqi@0: ILOAD 14 aoqi@0: BIPUSH 14 aoqi@0: ISHR aoqi@0: IADD aoqi@0: ILOAD 11 aoqi@0: ILOAD 13 aoqi@0: BIPUSH 21 aoqi@0: INVOKESTATIC jdk/nashorn/internal/runtime/JSType.mulExact (III)I aoqi@0: IADD aoqi@0: ISTORE 5 aoqi@0: L10 aoqi@0: LINENUMBER 21 L10 aoqi@0: ALOAD 9 aoqi@0: ILOAD 4 aoqi@0: DUP aoqi@0: ICONST_1 aoqi@0: IADD aoqi@0: ISTORE 4 aoqi@0: ILOAD 12 aoqi@0: LDC 268435455 aoqi@0: IAND aoqi@0: INVOKEDYNAMIC dyn:setElem|setProp(Ljava/lang/Object;II)V [ aoqi@0: // handle kind 0x6 : INVOKESTATIC aoqi@0: jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;) aoqi@0: // arguments: aoqi@0: 0 aoqi@0: ] aoqi@0: L4 aoqi@0: FRAME SAME aoqi@0: ILOAD 6 aoqi@0: ICONST_M1 aoqi@0: IADD aoqi@0: DUP aoqi@0: ISTORE 6 aoqi@0: ICONST_0 aoqi@0: IF_ICMPGE L5 aoqi@0: L11 aoqi@0: LINENUMBER 24 L11 aoqi@0: ILOAD 5 aoqi@0: IRETURN aoqi@0: aoqi@0: aoqi@0: SYSTEM PROPERTY: -Dnashorn.codegen.debug, -Dnashorn.codegen.debug.trace= aoqi@0: aoqi@0: See the description of the codegen logger below. aoqi@0: aoqi@0: aoqi@0: SYSTEM_PROPERTY: -Dnashorn.fields.debug aoqi@0: aoqi@0: See the description on the fields logger below. aoqi@0: aoqi@0: aoqi@0: SYSTEM PROPERTY: -Dnashorn.fields.dual aoqi@0: aoqi@0: When this property is true, Nashorn will attempt to use primitive aoqi@0: fields for AccessorProperties (currently just AccessorProperties, not aoqi@0: spill properties). Memory footprint for script objects will increase, aoqi@0: as we need to maintain both a primitive field (a long) as well as an aoqi@0: Object field for the property value. Ints are represented as the 32 aoqi@0: low bits of the long fields. Doubles are represented as the aoqi@0: doubleToLongBits of their value. This way a single field can be used aoqi@0: for all primitive types. Packing and unpacking doubles to their bit aoqi@0: representation is intrinsified by the JVM and extremely fast. aoqi@0: aoqi@0: While dual fields in theory runs significantly faster than Object aoqi@0: fields due to reduction of boxing and memory allocation overhead, aoqi@0: there is still work to be done to make this a general purpose aoqi@0: solution. Research is ongoing. aoqi@0: aoqi@0: In the future, this might complement or be replaced by experimental aoqi@0: feature sun.misc.TaggedArray, which has been discussed on the mlvm aoqi@0: mailing list. TaggedArrays are basically a way to share data space aoqi@0: between primitives and references, and have the GC understand this. aoqi@0: aoqi@0: As long as only primitive values are written to the fields and enough aoqi@0: type information exists to make sure that any reads don't have to be aoqi@0: uselessly boxed and unboxed, this is significantly faster than the aoqi@0: standard "Objects only" approach that currently is the default. See aoqi@0: test/examples/dual-fields-micro.js for an example that runs twice as aoqi@0: fast with dual fields as without them. Here, the compiler, can aoqi@0: determine that we are dealing with numbers only throughout the entire aoqi@0: property life span of the properties involved. aoqi@0: aoqi@0: If a "real" object (not a boxed primitive) is written to a field that aoqi@0: has a primitive representation, its callsite is relinked and an Object aoqi@0: field is used forevermore for that particular field in that aoqi@0: PropertyMap and its children, even if primitives are later assigned to aoqi@0: it. aoqi@0: aoqi@0: As the amount of compile time type information is very small in a aoqi@0: dynamic language like JavaScript, it is frequently the case that aoqi@0: something has to be treated as an object, because we don't know any aoqi@0: better. In reality though, it is often a boxed primitive is stored to aoqi@0: an AccessorProperty. The fastest way to handle this soundly is to use aoqi@0: a callsite typecheck and avoid blowing the field up to an Object. We aoqi@0: never revert object fields to primitives. Ping-pong:ing back and forth aoqi@0: between primitive representation and Object representation would cause aoqi@0: fatal performance overhead, so this is not an option. aoqi@0: aoqi@0: For a general application the dual fields approach is still slower aoqi@0: than objects only fields in some places, about the same in most cases, aoqi@0: and significantly faster in very few. This is due the program using aoqi@0: primitives, but we still can't prove it. For example "local_var a = aoqi@0: call(); field = a;" may very well write a double to the field, but the aoqi@0: compiler dare not guess a double type if field is a local variable, aoqi@0: due to bytecode variables being strongly typed and later non aoqi@0: interchangeable. To get around this, the entire method would have to aoqi@0: be replaced and a continuation retained to restart from. We believe aoqi@0: that the next steps we should go through are instead: aoqi@0: aoqi@0: 1) Implement method specialization based on callsite, as it's quite aoqi@0: frequently the case that numbers are passed around, but currently our aoqi@0: function nodes just have object types visible to the compiler. For aoqi@0: example "var b = 17; func(a,b,17)" is an example where two parameters aoqi@0: can be specialized, but the main version of func might also be called aoqi@0: from another callsite with func(x,y,"string"). aoqi@0: aoqi@0: 2) This requires lazy jitting as the functions have to be specialized aoqi@0: per callsite. aoqi@0: aoqi@0: Even though "function square(x) { return x*x }" might look like a aoqi@0: trivial function that can always only take doubles, this is not aoqi@0: true. Someone might have overridden the valueOf for x so that the aoqi@0: toNumber coercion has side effects. To fulfil JavaScript semantics, aoqi@0: the coercion has to run twice for both terms of the multiplication aoqi@0: even if they are the same object. This means that call site aoqi@0: specialization is necessary, not parameter specialization on the form aoqi@0: "function square(x) { var xd = (double)x; return xd*xd; }", as one aoqi@0: might first think. aoqi@0: aoqi@0: Generating a method specialization for any variant of a function that aoqi@0: we can determine by types at compile time is a combinatorial explosion aoqi@0: of byte code (try it e.g. on all the variants of am3 in the Octane aoqi@0: benchmark crypto.js). Thus, this needs to be lazy aoqi@0: aoqi@0: 3) Optimistic callsite writes, something on the form aoqi@0: aoqi@0: x = y; //x is a field known to be a primitive. y is only an object as aoqi@0: far as we can tell aoqi@0: aoqi@0: turns into aoqi@0: aoqi@0: try { aoqi@0: x = (int)y; aoqi@0: } catch (X is not an integer field right now | ClassCastException e) { aoqi@0: x = y; aoqi@0: } aoqi@0: aoqi@0: Mini POC shows that this is the key to a lot of dual field performance aoqi@0: in seemingly trivial micros where one unknown object, in reality aoqi@0: actually a primitive, foils it for us. Very common pattern. Once we aoqi@0: are "all primitives", dual fields runs a lot faster than Object fields aoqi@0: only. aoqi@0: aoqi@0: We still have to deal with objects vs primitives for local bytecode aoqi@0: slots, possibly through code copying and versioning. aoqi@0: aoqi@0: The Future: aoqi@0: aoqi@0: We expect the usefulness of dual fields to increase significantly aoqi@0: after the optimistic type system described in the section on aoqi@0: integer arithmetic above is implemented. aoqi@0: aoqi@0: aoqi@0: SYSTEM PROPERTY: -Dnashorn.compiler.symbol.trace=[[,*]], aoqi@0: -Dnashorn.compiler.symbol.stacktrace=[[,*]] aoqi@0: aoqi@0: When this property is set, creation and manipulation of any symbol aoqi@0: named "x" will show information about when the compiler changes its aoqi@0: type assumption, bytecode local variable slot assignment and other aoqi@0: data. This is useful if, for example, a symbol shows up as an Object, aoqi@0: when you believe it should be a primitive. Usually there is an aoqi@0: explanation for this, for example that it exists in the global scope aoqi@0: and type analysis has to be more conservative. aoqi@0: aoqi@0: Several symbols names to watch can be specified by comma separation. aoqi@0: aoqi@0: If no variable name is specified (and no equals sign), all symbols aoqi@0: will be watched aoqi@0: aoqi@0: By using "stacktrace" instead of or together with "trace", stack aoqi@0: traces will be displayed upon symbol changes according to the same aoqi@0: semantics. aoqi@0: aoqi@0: aoqi@0: SYSTEM PROPERTY: -Dnashorn.lexer.xmlliterals aoqi@0: aoqi@0: If this property it set, it means that the Lexer should attempt to aoqi@0: parse XML literals, which would otherwise generate syntax aoqi@0: errors. Warning: there are currently no unit tests for this aoqi@0: functionality. aoqi@0: aoqi@0: XML literals, when this is enabled, end up as standard LiteralNodes in aoqi@0: the IR. aoqi@0: aoqi@0: aoqi@0: SYSTEM_PROPERTY: -Dnashorn.debug aoqi@0: aoqi@0: If this property is set to true, Nashorn runs in Debug mode. Debug aoqi@0: mode is slightly slower, as for example statistics counters are enabled aoqi@0: during the run. Debug mode makes available a NativeDebug instance aoqi@0: called "Debug" in the global space that can be used to print property aoqi@0: maps and layout for script objects, as well as a "dumpCounters" method aoqi@0: that will print the current values of the previously mentioned stats aoqi@0: counters. aoqi@0: aoqi@0: These functions currently exists for Debug: aoqi@0: aoqi@0: "map" - print(Debug.map(x)) will dump the PropertyMap for object x to aoqi@0: stdout (currently there also exist functions called "embedX", where X aoqi@0: is a value from 0 to 3, that will dump the contents of the embed pool aoqi@0: for the first spill properties in any script object and "spill", that aoqi@0: will dump the contents of the growing spill pool of spill properties aoqi@0: in any script object. This is of course subject to change without aoqi@0: notice, should we change the script object layout. aoqi@0: aoqi@0: "methodHandle" - this method returns the method handle that is used aoqi@0: for invoking a particular script function. aoqi@0: aoqi@0: "identical" - this method compares two script objects for reference aoqi@0: equality. It is a == Java comparison aoqi@0: aoqi@0: "dumpCounters" - will dump the debug counters' current values to aoqi@0: stdout. aoqi@0: aoqi@0: Currently we count number of ScriptObjects in the system, number of aoqi@0: Scope objects in the system, number of ScriptObject listeners added, aoqi@0: removed and dead (without references). aoqi@0: aoqi@0: We also count number of ScriptFunctions, ScriptFunction invocations aoqi@0: and ScriptFunction allocations. aoqi@0: aoqi@0: Furthermore we count PropertyMap statistics: how many property maps aoqi@0: exist, how many times were property maps cloned, how many times did aoqi@0: the property map history cache hit, prevent new allocations, how many aoqi@0: prototype invalidations were done, how many time the property map aoqi@0: proto cache hit. aoqi@0: aoqi@0: Finally we count callsite misses on a per callsite bases, which occur aoqi@0: when a callsite has to be relinked, due to a previous assumption of aoqi@0: object layout being invalidated. aoqi@0: aoqi@0: aoqi@0: SYSTEM PROPERTY: -Dnashorn.methodhandles.debug, aoqi@0: -Dnashorn.methodhandles.debug=create aoqi@0: aoqi@0: If this property is enabled, each MethodHandle related call that uses aoqi@0: the java.lang.invoke package gets its MethodHandle intercepted and an aoqi@0: instrumentation printout of arguments and return value appended to aoqi@0: it. This shows exactly which method handles are executed and from aoqi@0: where. (Also MethodTypes and SwitchPoints). This can be augmented with aoqi@0: more information, for example, instance count, by subclassing or aoqi@0: further extending the TraceMethodHandleFactory implementation in aoqi@0: MethodHandleFactory.java. aoqi@0: aoqi@0: If the property is specialized with "=create" as its option, aoqi@0: instrumentation will be shown for method handles upon creation time aoqi@0: rather than at runtime usage. aoqi@0: aoqi@0: aoqi@0: SYSTEM PROPERTY: -Dnashorn.methodhandles.debug.stacktrace aoqi@0: aoqi@0: This does the same as nashorn.methodhandles.debug, but when enabled aoqi@0: also dumps the stack trace for every instrumented method handle aoqi@0: operation. Warning: This is enormously verbose, but provides a pretty aoqi@0: decent "grep:able" picture of where the calls are coming from. aoqi@0: aoqi@0: See the description of the codegen logger below for a more verbose aoqi@0: description of this option aoqi@0: aoqi@0: aoqi@0: SYSTEM PROPERTY: -Dnashorn.scriptfunction.specialization.disable aoqi@0: aoqi@0: There are several "fast path" implementations of constructors and aoqi@0: functions in the NativeObject classes that, in their original form, aoqi@0: take a variable amount of arguments. Said functions are also declared aoqi@0: to take Object parameters in their original form, as this is what the aoqi@0: JavaScript specification mandates. aoqi@0: However, we often know quite a lot more at a callsite of one of these aoqi@0: functions. For example, Math.min is called with a fixed number (2) of aoqi@0: integer arguments. The overhead of boxing these ints to Objects and aoqi@0: folding them into an Object array for the generic varargs Math.min aoqi@0: function is an order of magnitude slower than calling a specialized aoqi@0: implementation of Math.min that takes two integers. Specialized aoqi@0: functions and constructors are identified by the tag aoqi@0: @SpecializedFunction and @SpecializedConstructor in the Nashorn aoqi@0: code. The linker will link in the most appropriate (narrowest types, aoqi@0: right number of types and least number of arguments) specialization if aoqi@0: specializations are available. aoqi@0: aoqi@0: Every ScriptFunction may carry specializations that the linker can aoqi@0: choose from. This framework will likely be extended for user defined aoqi@0: functions. The compiler can often infer enough parameter type info aoqi@0: from callsites for in order to generate simpler versions with less aoqi@0: generic Object types. This feature depends on future lazy jitting, as aoqi@0: there tend to be many calls to user defined functions, some where the aoqi@0: callsite can be specialized, some where we mostly see object aoqi@0: parameters even at the callsite. aoqi@0: aoqi@0: If this system property is set to true, the linker will not attempt to aoqi@0: use any specialized function or constructor for native objects, but aoqi@0: just call the generic one. aoqi@0: aoqi@0: aoqi@0: SYSTEM PROPERTY: -Dnashorn.tcs.miss.samplePercent= aoqi@0: aoqi@0: When running with the trace callsite option (-tcs), Nashorn will count aoqi@0: and instrument any callsite misses that require relinking. As the aoqi@0: number of relinks is large and usually produces a lot of output, this aoqi@0: system property can be used to constrain the percentage of misses that aoqi@0: should be logged. Typically this is set to 1 or 5 (percent). 1% is the aoqi@0: default value. aoqi@0: aoqi@0: aoqi@0: SYSTEM_PROPERTY: -Dnashorn.profilefile= aoqi@0: aoqi@0: When running with the profile callsite options (-pcs), Nashorn will aoqi@0: dump profiling data for all callsites to stderr as a shutdown hook. To aoqi@0: instead redirect this to a file, specify the path to the file using aoqi@0: this system property. aoqi@0: aoqi@0: aoqi@0: SYSTEM_PROPERTY: -Dnashorn.regexp.impl=[jdk|joni] aoqi@0: aoqi@0: This property defines the regular expression engine to be used by aoqi@0: Nashorn. Set this flag to "jdk" to get an implementation based on the aoqi@0: JDK's java.util.regex package. Set this property to "joni" to install aoqi@0: an implementation based on Joni, the regular expression engine used by aoqi@0: the JRuby project. The default value for this flag is "joni" aoqi@0: aoqi@0: aoqi@0: SYSTEM PROPERTY: -Dnashorn.time aoqi@0: aoqi@0: This enables timers for various phases of script compilation. The timers aoqi@0: will be dumped when the Nashorn process exits. We see a percentage value aoqi@0: of how much time was spent not executing bytecode (i.e. compilation and aoqi@0: internal tasks) at the end of the report. aoqi@0: aoqi@0: Here is an example: aoqi@0: aoqi@0: [JavaScript Parsing] 61 ms aoqi@0: [Constant Folding] 11 ms aoqi@0: [Control Flow Lowering] 26 ms aoqi@0: [Type Attribution] 81 ms aoqi@0: [Range Analysis] 0 ms aoqi@0: [Code Splitting] 29 ms aoqi@0: [Type Finalization] 19 ms aoqi@0: [Bytecode Generation] 189 ms aoqi@0: [Code Installation] 7 ms aoqi@0: Total runtime: 508 ms (Non-runtime: 423 ms [83%]) aoqi@0: aoqi@0: =============== aoqi@0: 2. The loggers. aoqi@0: =============== aoqi@0: aoqi@0: It is very simple to create your own logger. Use the DebugLogger class aoqi@0: and give the subsystem name as a constructor argument. aoqi@0: aoqi@0: The Nashorn loggers can be used to print per-module or per-subsystem aoqi@0: debug information with different levels of verbosity. The loggers for aoqi@0: a given subsystem are available are enabled by using aoqi@0: aoqi@0: --log=[:] aoqi@0: aoqi@0: on the command line. aoqi@0: aoqi@0: Here identifies the name of the subsystem to be logged aoqi@0: and the optional colon and level argument is a standard aoqi@0: java.util.logging.Level name (severe, warning, info, config, fine, aoqi@0: finer, finest). If the level is left out for a particular subsystem, aoqi@0: it defaults to "info". Any log message logged as the level or a level aoqi@0: that is more important will be output to stderr by the logger. aoqi@0: aoqi@0: Several loggers can be enabled by a single command line option, by aoqi@0: putting a comma after each subsystem/level tuple (or each subsystem if aoqi@0: level is unspecified). The --log option can also be given multiple aoqi@0: times on the same command line, with the same effect. aoqi@0: aoqi@0: For example: --log=codegen,fields:finest is equivalent to aoqi@0: --log=codegen:info --log=fields:finest aoqi@0: aoqi@0: The subsystems that currently support logging are: aoqi@0: aoqi@0: aoqi@0: * compiler aoqi@0: aoqi@0: The compiler is in charge of turning source code and function nodes aoqi@0: into byte code, and installs the classes into a class loader aoqi@0: controlled from the Context. Log messages are, for example, about aoqi@0: things like new compile units being allocated. The compiler has global aoqi@0: settings that all the tiers of codegen (e.g. Lower and CodeGenerator) aoqi@0: use.s aoqi@0: aoqi@0: aoqi@0: * codegen aoqi@0: aoqi@0: The code generator is the emitter stage of the code pipeline, and aoqi@0: turns the lowest tier of a FunctionNode into bytecode. Codegen logging aoqi@0: shows byte codes as they are being emitted, line number information aoqi@0: and jumps. It also shows the contents of the bytecode stack prior to aoqi@0: each instruction being emitted. This is a good debugging aid. For aoqi@0: example: aoqi@0: aoqi@0: [codegen] #41 line:2 (f)_afc824e aoqi@0: [codegen] #42 load symbol x slot=2 aoqi@0: [codegen] #43 {1:O} load int 0 aoqi@0: [codegen] #44 {2:I O} dynamic_runtime_call GT:ZOI_I args=2 returnType=boolean aoqi@0: [codegen] #45 signature (Ljava/lang/Object;I)Z aoqi@0: [codegen] #46 {1:Z} ifeq ternary_false_5402fe28 aoqi@0: [codegen] #47 load symbol x slot=2 aoqi@0: [codegen] #48 {1:O} goto ternary_exit_107c1f2f aoqi@0: [codegen] #49 ternary_false_5402fe28 aoqi@0: [codegen] #50 load symbol x slot=2 aoqi@0: [codegen] #51 {1:O} convert object -> double aoqi@0: [codegen] #52 {1:D} neg aoqi@0: [codegen] #53 {1:D} convert double -> object aoqi@0: [codegen] #54 {1:O} ternary_exit_107c1f2f aoqi@0: [codegen] #55 {1:O} return object aoqi@0: aoqi@0: shows a ternary node being generated for the sequence "return x > 0 ? aoqi@0: x : -x" aoqi@0: aoqi@0: The first number on the log line is a unique monotonically increasing aoqi@0: emission id per bytecode. There is no guarantee this is the same id aoqi@0: between runs. depending on non deterministic code aoqi@0: execution/compilation, but for small applications it usually is. If aoqi@0: the system variable -Dnashorn.codegen.debug.trace= is set, where x aoqi@0: is a bytecode emission id, a stack trace will be shown as the aoqi@0: particular bytecode is about to be emitted. This can be a quick way to aoqi@0: determine where it comes from without attaching the debugger. "Who aoqi@0: generated that neg?" aoqi@0: aoqi@0: The --log=codegen option is equivalent to setting the system variable aoqi@0: "nashorn.codegen.debug" to true. aoqi@0: aoqi@0: * fold aoqi@0: aoqi@0: Shows constant folding taking place before lowering aoqi@0: aoqi@0: * lower aoqi@0: aoqi@0: This is the first lowering pass. aoqi@0: aoqi@0: Lower is a code generation pass that turns high level IR nodes into aoqi@0: lower level one, for example substituting comparisons to RuntimeNodes aoqi@0: and inlining finally blocks. aoqi@0: aoqi@0: Lower is also responsible for determining control flow information aoqi@0: like end points. aoqi@0: aoqi@0: aoqi@0: * attr aoqi@0: aoqi@0: The lowering annotates a FunctionNode with symbols for each identifier aoqi@0: and transforms high level constructs into lower level ones, that the aoqi@0: CodeGenerator consumes. aoqi@0: aoqi@0: Lower logging typically outputs things like post pass actions, aoqi@0: insertions of casts because symbol types have been changed and type aoqi@0: specialization information. Currently very little info is generated by aoqi@0: this logger. This will probably change. aoqi@0: aoqi@0: aoqi@0: * finalize aoqi@0: aoqi@0: This --log=finalize log option outputs information for type finalization, aoqi@0: the third tier of the compiler. This means things like placement of aoqi@0: specialized scope nodes or explicit conversions. aoqi@0: aoqi@0: aoqi@0: * fields aoqi@0: aoqi@0: The --log=fields option (at info level) is equivalent to setting the aoqi@0: system variable "nashorn.fields.debug" to true. At the info level it aoqi@0: will only show info about type assumptions that were invalidated. If aoqi@0: the level is set to finest, it will also trace every AccessorProperty aoqi@0: getter and setter in the program, show arguments, return values aoqi@0: etc. It will also show the internal representation of respective field aoqi@0: (Object in the normal case, unless running with the dual field aoqi@0: representation) aoqi@0: aoqi@0: aoqi@0: ======================= aoqi@0: 3. Undocumented options aoqi@0: ======================= aoqi@0: aoqi@0: Here follows a short description of undocumented options for Nashorn. aoqi@0: To see a list of all undocumented options, use the (undocumented) flag aoqi@0: "-xhelp". aoqi@0: aoqi@0: i.e. jjs -xhelp or java -jar nashorn.jar -xhelp aoqi@0: aoqi@0: Undocumented options are not guaranteed to work, run correctly or be aoqi@0: bug free. They are experimental and for internal or debugging use. aoqi@0: They are also subject to change without notice. aoqi@0: aoqi@0: In practice, though, all options below not explicitly documented as aoqi@0: EXPERIMENTAL can be relied upon, for example --dump-on-error is useful aoqi@0: for any JavaScript/Nashorn developer, but there is no guarantee. aoqi@0: aoqi@0: A short summary follows: aoqi@0: aoqi@0: -D (-Dname=value. Set a system property. This option can be repeated.) aoqi@0: aoqi@0: -ccs, --class-cache-size (Size of the Class cache size per global scope.) aoqi@0: aoqi@0: -cp, -classpath (-cp path. Specify where to find user class files.) aoqi@0: aoqi@0: -co, --compile-only (Compile script without running. Exit after compilation) aoqi@0: param: [true|false] default: false aoqi@0: aoqi@0: -d, --dump-debug-dir (specify a destination directory to dump class files. aoqi@0: This must be combined with the --compile-only option to work) aoqi@0: param: aoqi@0: aoqi@0: --debug-lines (Generate line number table in .class files.) aoqi@0: param: [true|false] default: true aoqi@0: aoqi@0: --debug-locals (Generate local variable table in .class files.) aoqi@0: param: [true|false] default: false aoqi@0: aoqi@0: -doe, -dump-on-error (Dump a stack trace on errors.) aoqi@0: param: [true|false] default: false aoqi@0: aoqi@0: --early-lvalue-error (invalid lvalue expressions should be reported as early errors.) aoqi@0: param: [true|false] default: true aoqi@0: aoqi@0: --empty-statements (Preserve empty statements in AST.) aoqi@0: param: [true|false] default: false aoqi@0: aoqi@0: -fv, -fullversion (Print full version info of Nashorn.) aoqi@0: param: [true|false] default: false aoqi@0: aoqi@0: --function-statement-error (Report an error when function declaration is used as a statement.) aoqi@0: param: [true|false] default: false aoqi@0: aoqi@0: --function-statement-warning (Warn when function declaration is used as a statement.) aoqi@0: param: [true|false] default: false aoqi@0: aoqi@0: -fx (Launch script as an fx application.) aoqi@0: param: [true|false] default: false aoqi@0: aoqi@0: --global-per-engine (Use single Global instance per script engine instance.) aoqi@0: param: [true|false] default: false aoqi@0: aoqi@0: -h, -help (Print help for command line flags.) aoqi@0: param: [true|false] default: false aoqi@0: aoqi@0: --lazy-compilation (EXPERIMENTAL: Use lazy code generation strategies - do not compile aoqi@0: the entire script at once.) aoqi@0: param: [true|false] default: false aoqi@0: aoqi@0: --loader-per-compile (Create a new class loader per compile.) aoqi@0: param: [true|false] default: true aoqi@0: aoqi@0: -l, --locale (Set Locale for script execution.) aoqi@0: param: default: en-US aoqi@0: aoqi@0: --log (Enable logging of a given level for a given number of sub systems. aoqi@0: [for example: --log=fields:finest,codegen:info]) aoqi@0: param: ,* aoqi@0: aoqi@0: -nj, --no-java (No Java support) aoqi@0: param: [true|false] default: false aoqi@0: aoqi@0: -nse, --no-syntax-extensions (No non-standard syntax extensions) aoqi@0: param: [true|false] default: false aoqi@0: aoqi@0: -nta, --no-typed-arrays (No Typed arrays support) aoqi@0: param: [true|false] default: false aoqi@0: aoqi@0: --parse-only (Parse without compiling.) aoqi@0: param: [true|false] default: false aoqi@0: aoqi@0: --print-ast (Print abstract syntax tree.) aoqi@0: param: [true|false] default: false aoqi@0: aoqi@0: --print-code (Print bytecode.) aoqi@0: param: [true|false] default: false aoqi@0: aoqi@0: --print-lower-ast (Print lowered abstract syntax tree.) aoqi@0: param: [true|false] default: false aoqi@0: aoqi@0: --print-lower-parse (Print the parse tree after lowering.) aoqi@0: param: [true|false] default: false aoqi@0: aoqi@0: --print-mem-usage (Print memory usage of IR after each compile stage.) aoqi@0: param: [true|false] default: false aoqi@0: aoqi@0: --print-no-newline (Print function will not print new line char.) aoqi@0: param: [true|false] default: false aoqi@0: aoqi@0: --print-parse (Print the parse tree.) aoqi@0: param: [true|false] default: false aoqi@0: aoqi@0: --print-symbols (Print the symbol table.) aoqi@0: param: [true|false] default: false aoqi@0: aoqi@0: -pcs, --profile-callsites (Dump callsite profile data.) aoqi@0: param: [true|false] default: false aoqi@0: aoqi@0: --range-analysis (EXPERIMENTAL: Do range analysis using known compile time types, aoqi@0: and try to narrow number types) aoqi@0: param: [true|false] default: false aoqi@0: aoqi@0: -scripting (Enable scripting features.) aoqi@0: param: [true|false] default: false aoqi@0: aoqi@0: --specialize-calls (EXPERIMENTAL: Specialize all or a set of method according aoqi@0: to callsite parameter types) aoqi@0: param: [=function_1,...,function_n] aoqi@0: aoqi@0: --stderr (Redirect stderr to a filename or to another tty, e.g. stdout) aoqi@0: param: aoqi@0: aoqi@0: --stdout (Redirect stdout to a filename or to another tty, e.g. stderr) aoqi@0: param: aoqi@0: aoqi@0: -strict (Run scripts in strict mode.) aoqi@0: param: [true|false] default: false aoqi@0: aoqi@0: -t, -timezone (Set timezone for script execution.) aoqi@0: param: default: Europe/Stockholm aoqi@0: aoqi@0: -tcs, --trace-callsites (Enable callsite trace mode. Options are: miss [trace callsite misses] aoqi@0: enterexit [trace callsite enter/exit], objects [print object properties]) aoqi@0: param: [=[option,]*] aoqi@0: aoqi@0: --verify-code (Verify byte code before running.) aoqi@0: param: [true|false] default: false aoqi@0: aoqi@0: -v, -version (Print version info of Nashorn.) aoqi@0: param: [true|false] default: false aoqi@0: aoqi@0: -xhelp (Print extended help for command line flags.) aoqi@0: param: [true|false] default: false aoqi@0: