docs/DEVELOPER_README

Tue, 26 Aug 2014 14:30:25 -0700

author
amurillo
date
Tue, 26 Aug 2014 14:30:25 -0700
changeset 972
8dae548f5f27
parent 963
e2497b11a021
child 1068
375a3a3256d0
permissions
-rw-r--r--

Merge

     1 This document describes system properties that are used for internal
     2 debugging and instrumentation purposes, along with the system loggers,
     3 which are used for the same thing.
     5 This document is intended as a developer resource, and it is not
     6 needed as Nashorn documentation for normal usage. Flags and system
     7 properties described herein are subject to change without notice.
     9 =====================================
    10 1. System properties used internally
    11 =====================================
    13 This documentation of the system property flags assume that the
    14 default value of the flag is false, unless otherwise specified.
    16 SYSTEM PROPERTY: -Dnashorn.args=<string>
    18 This property takes as its value a space separated list of Nashorn
    19 command line options that should be passed to Nashorn. This might be
    20 useful in environments where it is hard to tell how a nashorn.jar is
    21 launched.
    23 Example:
    25 > java -Dnashorn.args="--lazy-complation --log=compiler" large-java-app-with-nashorn.jar 
    26 > ant -Dnashorn.args="--log=codegen" antjob
    28 SYSTEM PROPERTY: -Dnashorn.unstable.relink.threshold=x
    30 This property controls how many call site misses are allowed before a 
    31 callsite is relinked with "apply" semantics to never change again. 
    32 In the case of megamorphic callsites, this is necessary, or the 
    33 program would spend all its time swapping out callsite targets. Dynalink 
    34 has a default value (currently 8 relinks) for this property if it 
    35 is not explicitly set.
    38 SYSTEM PROPERTY: -Dnashorn.compiler.splitter.threshold=x
    40 This will change the node weight that requires a subgraph of the IR to
    41 be split into several classes in order not to run out of bytecode space.
    42 The default value is 0x8000 (32768).
    45 SYSTEM PROPERTY: -Dnashorn.compiler.intarithmetic
    47 (and integer arithmetic in general)
    49 <currently disabled - this is being refactored for update releases> 
    51 Arithmetic operations in Nashorn (except bitwise ones) typically
    52 coerce the operands to doubles (as per the JavaScript spec). To switch
    53 this off and remain in integer mode, for example for "var x = a&b; var
    54 y = c&d; var z = x*y;", use this flag. This will force the
    55 multiplication of variables that are ints to be done with the IMUL
    56 bytecode and the result "z" to become an int.
    58 WARNING: Note that is is experimental only to ensure that type support
    59 exists for all primitive types. The generated code is unsound. This
    60 will be the case until we do optimizations based on it. There is a CR
    61 in Nashorn to do better range analysis, and ensure that this is only
    62 done where the operation can't overflow into a wider type. Currently
    63 no overflow checking is done, so at the moment, until range analysis
    64 has been completed, this option is turned off.
    66 We've experimented by using int arithmetic for everything and putting
    67 overflow checks afterwards, which would recompute the operation with
    68 the correct precision, but have yet to find a configuration where this
    69 is faster than just using doubles directly, even if the int operation
    70 does not overflow. Getting access to a JVM intrinsic that does branch
    71 on overflow would probably alleviate this.
    73 The future:
    75 We are transitioning to an optimistic type system that uses int
    76 arithmetic everywhere until proven wrong. The problem here is mostly
    77 catch an overflow exception and rolling back the state to a new method
    78 with less optimistic assumptions for an operation at a particular
    79 program point. This will most likely not be in the Java 8.0 release
    80 but likely end up in an update release
    82 For Java 8, several java.lang.Math methods like addExact, subExact and
    83 mulExact are available to help us. Experiments intrinsifying these
    84 show a lot of promise, and we have devised a system that basically
    85 does on stack replacement with exceptions in bytecode to revert
    86 erroneous assumptions. An explanation of how this works and what we
    87 are doing can be found here:
    88 http://www.slideshare.net/lagergren/lagergren-jvmls2013final
    90 Experiments with this show significant ~x2-3 performance increases on
    91 pretty much everything, provided that optimistic assumptions don't
    92 fail much. It will affect warmup time negatively, depending on how
    93 many erroneous too optimistic assumptions are placed in the code at
    94 compile time. We don't think this will be much of an issue.
    96 For example for a small benchmark that repeatedly executes this
    97 method taken from the Crypto Octane benchmark 
    99 function am3(i,x,w,j,c,n) {
   100   var this_array = this.array;
   101   var w_array    = w.array;
   102   var xl = x&0x3fff, xh = x>>14;
   103   while(--n >= 0) {
   104     var l = this_array[i]&0x3fff;
   105     var h = this_array[i++]>>14;
   106     var m = xh*l+h*xl;
   107     l = xl*l+((m&0x3fff)<<14)+w_array[j]+c;
   108     c = (l>>28)+(m>>14)+xh*h;
   109     w_array[j++] = l&0xfffffff;
   110   }
   112   return c;
   113 }
   115 The performance increase more than doubles. We are also working hard
   116 with the code generation team in the Java Virtual Machine to fix
   117 things that are lacking in invokedynamic performance, which is another
   118 area where a lot of ongoing performance work takes place
   120 "Pessimistic" bytecode for am3, guaranteed to be semantically correct:
   122 // access flags 0x9
   123   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;
   124    L0
   125     LINENUMBER 12 L0
   126     ALOAD 0
   127     INVOKEDYNAMIC dyn:getProp|getElem|getMethod:array(Ljava/lang/Object;)Ljava/lang/Object; [
   128       // handle kind 0x6 : INVOKESTATIC
   129       jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
   130       // arguments:
   131       0
   132     ]
   133     ASTORE 8
   134    L1
   135     LINENUMBER 13 L1
   136     ALOAD 3
   137     INVOKEDYNAMIC dyn:getProp|getElem|getMethod:array(Ljava/lang/Object;)Ljava/lang/Object; [
   138       // handle kind 0x6 : INVOKESTATIC
   139       jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
   140       // arguments:
   141       0
   142     ]
   143     ASTORE 9
   144    L2
   145     LINENUMBER 14 L2
   146     ALOAD 2
   147     INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toInt32 (Ljava/lang/Object;)I
   148     SIPUSH 16383
   149     IAND
   150     ISTORE 10
   151     ALOAD 2
   152     INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toInt32 (Ljava/lang/Object;)I
   153     BIPUSH 14
   154     ISHR
   155     ISTORE 11
   156    L3
   157     LINENUMBER 15 L3
   158     GOTO L4
   159    L5
   160     LINENUMBER 16 L5
   161    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] []
   162     ALOAD 8
   163     ALOAD 1
   164     INVOKEDYNAMIC dyn:getElem|getProp|getMethod(Ljava/lang/Object;Ljava/lang/Object;)I [
   165       // handle kind 0x6 : INVOKESTATIC
   166       jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
   167       // arguments:
   168       0
   169     ]
   170     SIPUSH 16383
   171     IAND
   172     INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;
   173     ASTORE 12
   174    L6
   175     LINENUMBER 17 L6
   176     ALOAD 8
   177     ALOAD 1
   178     INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toNumber (Ljava/lang/Object;)D
   179     DUP2
   180     DCONST_1
   181     DADD
   182     INVOKESTATIC java/lang/Double.valueOf (D)Ljava/lang/Double;
   183     ASTORE 1
   184     INVOKEDYNAMIC dyn:getElem|getProp|getMethod(Ljava/lang/Object;D)I [
   185       // handle kind 0x6 : INVOKESTATIC
   186       jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
   187       // arguments:
   188       0
   189     ]
   190     BIPUSH 14
   191     ISHR
   192     ISTORE 13
   193    L7
   194     LINENUMBER 18 L7
   195     ILOAD 11
   196     I2D
   197     ALOAD 12
   198     INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toNumber (Ljava/lang/Object;)D
   199     DMUL
   200     ILOAD 13
   201     I2D
   202     ILOAD 10
   203     I2D
   204     DMUL
   205     DADD
   206     DSTORE 14
   207    L8
   208     LINENUMBER 19 L8
   209     ILOAD 10
   210     I2D
   211     ALOAD 12
   212     INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toNumber (Ljava/lang/Object;)D
   213     DMUL
   214     DLOAD 14
   215     INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toInt32 (D)I
   216     SIPUSH 16383
   217     IAND
   218     BIPUSH 14
   219     ISHL
   220     I2D
   221     DADD
   222     ALOAD 9
   223     ALOAD 4
   224     INVOKEDYNAMIC dyn:getElem|getProp|getMethod(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; [
   225       // handle kind 0x6 : INVOKESTATIC
   226       jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
   227       // arguments:
   228       0
   229     ]
   230     INVOKEDYNAMIC ADD:ODO_D(DLjava/lang/Object;)Ljava/lang/Object; [
   231       // handle kind 0x6 : INVOKESTATIC
   232       jdk/nashorn/internal/runtime/linker/Bootstrap.runtimeBootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;)
   233       // arguments: none
   234     ]
   235     ALOAD 5
   236     INVOKEDYNAMIC ADD:OOO_I(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; [
   237       // handle kind 0x6 : INVOKESTATIC
   238       jdk/nashorn/internal/runtime/linker/Bootstrap.runtimeBootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;)
   239       // arguments: none
   240     ]
   241     ASTORE 12
   242    L9
   243     LINENUMBER 20 L9
   244     ALOAD 12
   245     INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toInt32 (Ljava/lang/Object;)I
   246     BIPUSH 28
   247     ISHR
   248     I2D
   249     DLOAD 14
   250     INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toInt32 (D)I
   251     BIPUSH 14
   252     ISHR
   253     I2D
   254     DADD
   255     ILOAD 11
   256     I2D
   257     ILOAD 13
   258     I2D
   259     DMUL
   260     DADD
   261     INVOKESTATIC java/lang/Double.valueOf (D)Ljava/lang/Double;
   262     ASTORE 5
   263    L10
   264     LINENUMBER 21 L10
   265     ALOAD 9
   266     ALOAD 4
   267     INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toNumber (Ljava/lang/Object;)D
   268     DUP2
   269     DCONST_1
   270     DADD
   271     INVOKESTATIC java/lang/Double.valueOf (D)Ljava/lang/Double;
   272     ASTORE 4
   273     ALOAD 12
   274     INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toInt32 (Ljava/lang/Object;)I
   275     LDC 268435455
   276     IAND
   277     INVOKEDYNAMIC dyn:setElem|setProp(Ljava/lang/Object;DI)V [
   278       // handle kind 0x6 : INVOKESTATIC
   279       jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
   280       // arguments:
   281       0
   282     ]
   283    L4
   284    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] []
   285     ALOAD 6
   286     INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toNumber (Ljava/lang/Object;)D
   287     LDC -1.0
   288     DADD
   289     DUP2
   290     INVOKESTATIC java/lang/Double.valueOf (D)Ljava/lang/Double;
   291     ASTORE 6
   292     DCONST_0
   293     DCMPL
   294     IFGE L5
   295    L11
   296     LINENUMBER 24 L11
   297     ALOAD 5
   298     ARETURN
   300 "Optimistic" bytecode that requires invalidation on e.g overflow. Factor
   301 x2-3 speedup:
   303 public static am3(Ljava/lang/Object;IILjava/lang/Object;III)I
   304    L0
   305     LINENUMBER 12 L0
   306     ALOAD 0
   307     INVOKEDYNAMIC dyn:getProp|getElem|getMethod:array(Ljava/lang/Object;)Ljava/lang/Object; [
   308       // handle kind 0x6 : INVOKESTATIC
   309       jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
   310       // arguments:
   311       0
   312     ]
   313     ASTORE 8
   314    L1
   315     LINENUMBER 13 L1
   316     ALOAD 3
   317     INVOKEDYNAMIC dyn:getProp|getElem|getMethod:array(Ljava/lang/Object;)Ljava/lang/Object; [
   318       // handle kind 0x6 : INVOKESTATIC
   319       jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
   320       // arguments:
   321       0
   322     ]
   323     ASTORE 9
   324    L2
   325     LINENUMBER 14 L2
   326     ILOAD 2
   327     SIPUSH 16383
   328     IAND
   329     ISTORE 10
   330     ILOAD 2
   331     BIPUSH 14
   332     ISHR
   333     ISTORE 11
   334    L3
   335     LINENUMBER 15 L3
   336     GOTO L4
   337    L5
   338     LINENUMBER 16 L5
   339    FRAME FULL [java/lang/Object I I java/lang/Object I I I T java/lang/Object java/lang/Object I I] []
   340     ALOAD 8
   341     ILOAD 1
   342     INVOKEDYNAMIC dyn:getElem|getProp|getMethod(Ljava/lang/Object;I)I [
   343       // handle kind 0x6 : INVOKESTATIC
   344       jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
   345       // arguments:
   346       0
   347     ]
   348     SIPUSH 16383
   349     IAND
   350     ISTORE 12
   351    L6
   352     LINENUMBER 17 L6
   353     ALOAD 8
   354     ILOAD 1
   355     DUP
   356     ICONST_1
   357     IADD
   358     ISTORE 1
   359     INVOKEDYNAMIC dyn:getElem|getProp|getMethod(Ljava/lang/Object;I)I [
   360       // handle kind 0x6 : INVOKESTATIC
   361       jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
   362       // arguments:
   363       0
   364     ]
   365     BIPUSH 14
   366     ISHR
   367     ISTORE 13
   368    L7
   369     LINENUMBER 18 L7
   370     ILOAD 11
   371     ILOAD 12
   372     BIPUSH 8
   373     INVOKESTATIC jdk/nashorn/internal/runtime/JSType.mulExact (III)I
   374     ILOAD 13
   375     ILOAD 10
   376     BIPUSH 9
   377     INVOKESTATIC jdk/nashorn/internal/runtime/JSType.mulExact (III)I
   378     IADD
   379     ISTORE 14
   380    L8
   381     LINENUMBER 19 L8
   382     ILOAD 10
   383     ILOAD 12
   384     BIPUSH 11
   385     INVOKESTATIC jdk/nashorn/internal/runtime/JSType.mulExact (III)I
   386     ILOAD 14
   387     SIPUSH 16383
   388     IAND
   389     BIPUSH 14
   390     ISHL
   391     IADD
   392     ALOAD 9
   393     ILOAD 4
   394     INVOKEDYNAMIC dyn:getElem|getProp|getMethod(Ljava/lang/Object;I)I [
   395       // handle kind 0x6 : INVOKESTATIC
   396       jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
   397       // arguments:
   398       0
   399     ]
   400     IADD
   401     ILOAD 5
   402     IADD
   403     ISTORE 12
   404    L9
   405     LINENUMBER 20 L9
   406     ILOAD 12
   407     BIPUSH 28
   408     ISHR
   409     ILOAD 14
   410     BIPUSH 14
   411     ISHR
   412     IADD
   413     ILOAD 11
   414     ILOAD 13
   415     BIPUSH 21
   416     INVOKESTATIC jdk/nashorn/internal/runtime/JSType.mulExact (III)I
   417     IADD
   418     ISTORE 5
   419    L10
   420     LINENUMBER 21 L10
   421     ALOAD 9
   422     ILOAD 4
   423     DUP
   424     ICONST_1
   425     IADD
   426     ISTORE 4
   427     ILOAD 12
   428     LDC 268435455
   429     IAND
   430     INVOKEDYNAMIC dyn:setElem|setProp(Ljava/lang/Object;II)V [
   431       // handle kind 0x6 : INVOKESTATIC
   432       jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
   433       // arguments:
   434       0
   435     ]
   436    L4
   437    FRAME SAME
   438     ILOAD 6
   439     ICONST_M1
   440     IADD
   441     DUP
   442     ISTORE 6
   443     ICONST_0
   444     IF_ICMPGE L5
   445    L11
   446     LINENUMBER 24 L11
   447     ILOAD 5
   448     IRETURN
   451 SYSTEM PROPERTY: -Dnashorn.codegen.debug, -Dnashorn.codegen.debug.trace=<x>
   453 See the description of the codegen logger below.
   456 SYSTEM_PROPERTY: -Dnashorn.fields.debug
   458 See the description on the fields logger below.
   461 SYSTEM PROPERTY: -Dnashorn.fields.dual
   463 When this property is true, Nashorn will attempt to use primitive
   464 fields for AccessorProperties (currently just AccessorProperties, not
   465 spill properties). Memory footprint for script objects will increase,
   466 as we need to maintain both a primitive field (a long) as well as an
   467 Object field for the property value. Ints are represented as the 32
   468 low bits of the long fields. Doubles are represented as the
   469 doubleToLongBits of their value. This way a single field can be used
   470 for all primitive types. Packing and unpacking doubles to their bit
   471 representation is intrinsified by the JVM and extremely fast.
   473 While dual fields in theory runs significantly faster than Object
   474 fields due to reduction of boxing and memory allocation overhead,
   475 there is still work to be done to make this a general purpose
   476 solution. Research is ongoing.
   478 In the future, this might complement or be replaced by experimental
   479 feature sun.misc.TaggedArray, which has been discussed on the mlvm
   480 mailing list. TaggedArrays are basically a way to share data space
   481 between primitives and references, and have the GC understand this.
   483 As long as only primitive values are written to the fields and enough
   484 type information exists to make sure that any reads don't have to be
   485 uselessly boxed and unboxed, this is significantly faster than the
   486 standard "Objects only" approach that currently is the default. See
   487 test/examples/dual-fields-micro.js for an example that runs twice as
   488 fast with dual fields as without them. Here, the compiler, can
   489 determine that we are dealing with numbers only throughout the entire
   490 property life span of the properties involved.
   492 If a "real" object (not a boxed primitive) is written to a field that
   493 has a primitive representation, its callsite is relinked and an Object
   494 field is used forevermore for that particular field in that
   495 PropertyMap and its children, even if primitives are later assigned to
   496 it.
   498 As the amount of compile time type information is very small in a
   499 dynamic language like JavaScript, it is frequently the case that
   500 something has to be treated as an object, because we don't know any
   501 better. In reality though, it is often a boxed primitive is stored to
   502 an AccessorProperty. The fastest way to handle this soundly is to use
   503 a callsite typecheck and avoid blowing the field up to an Object. We
   504 never revert object fields to primitives. Ping-pong:ing back and forth
   505 between primitive representation and Object representation would cause
   506 fatal performance overhead, so this is not an option.
   508 For a general application the dual fields approach is still slower
   509 than objects only fields in some places, about the same in most cases,
   510 and significantly faster in very few. This is due the program using
   511 primitives, but we still can't prove it. For example "local_var a =
   512 call(); field = a;" may very well write a double to the field, but the
   513 compiler dare not guess a double type if field is a local variable,
   514 due to bytecode variables being strongly typed and later non
   515 interchangeable. To get around this, the entire method would have to
   516 be replaced and a continuation retained to restart from. We believe
   517 that the next steps we should go through are instead:
   519 1) Implement method specialization based on callsite, as it's quite
   520 frequently the case that numbers are passed around, but currently our
   521 function nodes just have object types visible to the compiler. For
   522 example "var b = 17; func(a,b,17)" is an example where two parameters
   523 can be specialized, but the main version of func might also be called
   524 from another callsite with func(x,y,"string").
   526 2) This requires lazy jitting as the functions have to be specialized
   527 per callsite.
   529 Even though "function square(x) { return x*x }" might look like a
   530 trivial function that can always only take doubles, this is not
   531 true. Someone might have overridden the valueOf for x so that the
   532 toNumber coercion has side effects. To fulfil JavaScript semantics,
   533 the coercion has to run twice for both terms of the multiplication
   534 even if they are the same object. This means that call site
   535 specialization is necessary, not parameter specialization on the form
   536 "function square(x) { var xd = (double)x; return xd*xd; }", as one
   537 might first think.
   539 Generating a method specialization for any variant of a function that
   540 we can determine by types at compile time is a combinatorial explosion
   541 of byte code (try it e.g. on all the variants of am3 in the Octane
   542 benchmark crypto.js). Thus, this needs to be lazy
   544 3) Optimistic callsite writes, something on the form
   546 x = y; //x is a field known to be a primitive. y is only an object as
   547 far as we can tell
   549 turns into
   551 try {
   552   x = (int)y;
   553 } catch (X is not an integer field right now | ClassCastException e) {
   554   x = y;
   555 }
   557 Mini POC shows that this is the key to a lot of dual field performance
   558 in seemingly trivial micros where one unknown object, in reality
   559 actually a primitive, foils it for us. Very common pattern. Once we
   560 are "all primitives", dual fields runs a lot faster than Object fields
   561 only.
   563 We still have to deal with objects vs primitives for local bytecode
   564 slots, possibly through code copying and versioning.
   566 The Future:
   568 We expect the usefulness of dual fields to increase significantly
   569 after the optimistic type system described in the section on 
   570 integer arithmetic above is implemented.
   573 SYSTEM PROPERTY: -Dnashorn.compiler.symbol.trace=[<x>[,*]], 
   574   -Dnashorn.compiler.symbol.stacktrace=[<x>[,*]]
   576 When this property is set, creation and manipulation of any symbol
   577 named "x" will show information about when the compiler changes its
   578 type assumption, bytecode local variable slot assignment and other
   579 data. This is useful if, for example, a symbol shows up as an Object,
   580 when you believe it should be a primitive. Usually there is an
   581 explanation for this, for example that it exists in the global scope
   582 and type analysis has to be more conservative. 
   584 Several symbols names to watch can be specified by comma separation.
   586 If no variable name is specified (and no equals sign), all symbols
   587 will be watched
   589 By using "stacktrace" instead of or together with "trace", stack
   590 traces will be displayed upon symbol changes according to the same
   591 semantics.
   594 SYSTEM PROPERTY: -Dnashorn.lexer.xmlliterals
   596 If this property it set, it means that the Lexer should attempt to
   597 parse XML literals, which would otherwise generate syntax
   598 errors. Warning: there are currently no unit tests for this
   599 functionality.
   601 XML literals, when this is enabled, end up as standard LiteralNodes in
   602 the IR.
   605 SYSTEM_PROPERTY: -Dnashorn.debug
   607 If this property is set to true, Nashorn runs in Debug mode. Debug
   608 mode is slightly slower, as for example statistics counters are enabled
   609 during the run. Debug mode makes available a NativeDebug instance
   610 called "Debug" in the global space that can be used to print property
   611 maps and layout for script objects, as well as a "dumpCounters" method
   612 that will print the current values of the previously mentioned stats
   613 counters.
   615 These functions currently exists for Debug:
   617 "map" - print(Debug.map(x)) will dump the PropertyMap for object x to
   618 stdout (currently there also exist functions called "embedX", where X
   619 is a value from 0 to 3, that will dump the contents of the embed pool
   620 for the first spill properties in any script object and "spill", that
   621 will dump the contents of the growing spill pool of spill properties
   622 in any script object. This is of course subject to change without
   623 notice, should we change the script object layout.
   625 "methodHandle" - this method returns the method handle that is used
   626 for invoking a particular script function.
   628 "identical" - this method compares two script objects for reference
   629 equality. It is a == Java comparison
   631 "dumpCounters" - will dump the debug counters' current values to
   632 stdout.
   634 Currently we count number of ScriptObjects in the system, number of
   635 Scope objects in the system, number of ScriptObject listeners added,
   636 removed and dead (without references).
   638 We also count number of ScriptFunctions, ScriptFunction invocations
   639 and ScriptFunction allocations.
   641 Furthermore we count PropertyMap statistics: how many property maps
   642 exist, how many times were property maps cloned, how many times did
   643 the property map history cache hit, prevent new allocations, how many
   644 prototype invalidations were done, how many time the property map
   645 proto cache hit.
   647 Finally we count callsite misses on a per callsite bases, which occur
   648 when a callsite has to be relinked, due to a previous assumption of
   649 object layout being invalidated.
   652 SYSTEM PROPERTY: -Dnashorn.methodhandles.debug,
   653 -Dnashorn.methodhandles.debug=create
   655 If this property is enabled, each MethodHandle related call that uses
   656 the java.lang.invoke package gets its MethodHandle intercepted and an
   657 instrumentation printout of arguments and return value appended to
   658 it. This shows exactly which method handles are executed and from
   659 where. (Also MethodTypes and SwitchPoints). This can be augmented with
   660 more information, for example, instance count, by subclassing or
   661 further extending the TraceMethodHandleFactory implementation in
   662 MethodHandleFactory.java.
   664 If the property is specialized with "=create" as its option,
   665 instrumentation will be shown for method handles upon creation time
   666 rather than at runtime usage.
   669 SYSTEM PROPERTY: -Dnashorn.methodhandles.debug.stacktrace
   671 This does the same as nashorn.methodhandles.debug, but when enabled
   672 also dumps the stack trace for every instrumented method handle
   673 operation. Warning: This is enormously verbose, but provides a pretty
   674 decent "grep:able" picture of where the calls are coming from.
   676 See the description of the codegen logger below for a more verbose
   677 description of this option
   680 SYSTEM PROPERTY: -Dnashorn.scriptfunction.specialization.disable
   682 There are several "fast path" implementations of constructors and
   683 functions in the NativeObject classes that, in their original form,
   684 take a variable amount of arguments. Said functions are also declared
   685 to take Object parameters in their original form, as this is what the
   686 JavaScript specification mandates.
   687 However, we often know quite a lot more at a callsite of one of these
   688 functions. For example, Math.min is called with a fixed number (2) of
   689 integer arguments. The overhead of boxing these ints to Objects and
   690 folding them into an Object array for the generic varargs Math.min
   691 function is an order of magnitude slower than calling a specialized
   692 implementation of Math.min that takes two integers. Specialized
   693 functions and constructors are identified by the tag
   694 @SpecializedFunction and @SpecializedConstructor in the Nashorn
   695 code. The linker will link in the most appropriate (narrowest types,
   696 right number of types and least number of arguments) specialization if
   697 specializations are available.
   699 Every ScriptFunction may carry specializations that the linker can
   700 choose from. This framework will likely be extended for user defined
   701 functions. The compiler can often infer enough parameter type info
   702 from callsites for in order to generate simpler versions with less
   703 generic Object types. This feature depends on future lazy jitting, as
   704 there tend to be many calls to user defined functions, some where the
   705 callsite can be specialized, some where we mostly see object
   706 parameters even at the callsite.
   708 If this system property is set to true, the linker will not attempt to
   709 use any specialized function or constructor for native objects, but
   710 just call the generic one.
   713 SYSTEM PROPERTY: -Dnashorn.tcs.miss.samplePercent=<x>
   715 When running with the trace callsite option (-tcs), Nashorn will count
   716 and instrument any callsite misses that require relinking. As the
   717 number of relinks is large and usually produces a lot of output, this
   718 system property can be used to constrain the percentage of misses that
   719 should be logged. Typically this is set to 1 or 5 (percent). 1% is the
   720 default value.
   723 SYSTEM_PROPERTY: -Dnashorn.profilefile=<filename>
   725 When running with the profile callsite options (-pcs), Nashorn will
   726 dump profiling data for all callsites to stderr as a shutdown hook. To
   727 instead redirect this to a file, specify the path to the file using
   728 this system property.
   731 SYSTEM_PROPERTY: -Dnashorn.regexp.impl=[jdk|joni]
   733 This property defines the regular expression engine to be used by
   734 Nashorn. Set this flag to "jdk" to get an implementation based on the
   735 JDK's java.util.regex package. Set this property to "joni" to install
   736 an implementation based on Joni, the regular expression engine used by
   737 the JRuby project. The default value for this flag is "joni"
   740 ===============
   741 2. The loggers.
   742 ===============
   744 It is very simple to create your own logger. Use the DebugLogger class
   745 and give the subsystem name as a constructor argument.
   747 The Nashorn loggers can be used to print per-module or per-subsystem
   748 debug information with different levels of verbosity. The loggers for
   749 a given subsystem are available are enabled by using
   751 --log=<systemname>[:<level>]
   753 on the command line.
   755 Here <systemname> identifies the name of the subsystem to be logged
   756 and the optional colon and level argument is a standard
   757 java.util.logging.Level name (severe, warning, info, config, fine,
   758 finer, finest). If the level is left out for a particular subsystem,
   759 it defaults to "info". Any log message logged as the level or a level
   760 that is more important will be output to stderr by the logger.
   762 Several loggers can be enabled by a single command line option, by
   763 putting a comma after each subsystem/level tuple (or each subsystem if
   764 level is unspecified). The --log option can also be given multiple
   765 times on the same command line, with the same effect.
   767 For example: --log=codegen,fields:finest is equivalent to
   768 --log=codegen:info --log=fields:finest
   770 The subsystems that currently support logging are:
   773 * compiler
   775 The compiler is in charge of turning source code and function nodes
   776 into byte code, and installs the classes into a class loader
   777 controlled from the Context. Log messages are, for example, about
   778 things like new compile units being allocated. The compiler has global
   779 settings that all the tiers of codegen (e.g. Lower and CodeGenerator)
   780 use.s
   783 * codegen
   785 The code generator is the emitter stage of the code pipeline, and
   786 turns the lowest tier of a FunctionNode into bytecode. Codegen logging
   787 shows byte codes as they are being emitted, line number information
   788 and jumps. It also shows the contents of the bytecode stack prior to
   789 each instruction being emitted. This is a good debugging aid. For
   790 example:
   792 [codegen] #41                       line:2 (f)_afc824e 
   793 [codegen] #42                           load symbol x slot=2 
   794 [codegen] #43  {1:O}                    load int 0 
   795 [codegen] #44  {2:I O}                  dynamic_runtime_call GT:ZOI_I args=2 returnType=boolean 
   796 [codegen] #45                              signature (Ljava/lang/Object;I)Z 
   797 [codegen] #46  {1:Z}                    ifeq  ternary_false_5402fe28 
   798 [codegen] #47                           load symbol x slot=2 
   799 [codegen] #48  {1:O}                    goto ternary_exit_107c1f2f 
   800 [codegen] #49                       ternary_false_5402fe28 
   801 [codegen] #50                           load symbol x slot=2 
   802 [codegen] #51  {1:O}                    convert object -> double 
   803 [codegen] #52  {1:D}                    neg 
   804 [codegen] #53  {1:D}                    convert double -> object 
   805 [codegen] #54  {1:O}                ternary_exit_107c1f2f 
   806 [codegen] #55  {1:O}                    return object 
   808 shows a ternary node being generated for the sequence "return x > 0 ?
   809 x : -x"
   811 The first number on the log line is a unique monotonically increasing
   812 emission id per bytecode. There is no guarantee this is the same id
   813 between runs.  depending on non deterministic code
   814 execution/compilation, but for small applications it usually is. If
   815 the system variable -Dnashorn.codegen.debug.trace=<x> is set, where x
   816 is a bytecode emission id, a stack trace will be shown as the
   817 particular bytecode is about to be emitted. This can be a quick way to
   818 determine where it comes from without attaching the debugger. "Who
   819 generated that neg?"
   821 The --log=codegen option is equivalent to setting the system variable
   822 "nashorn.codegen.debug" to true.
   824 * fold
   826 Shows constant folding taking place before lowering
   828 * lower
   830 This is the first lowering pass.
   832 Lower is a code generation pass that turns high level IR nodes into
   833 lower level one, for example substituting comparisons to RuntimeNodes
   834 and inlining finally blocks.
   836 Lower is also responsible for determining control flow information
   837 like end points.
   840 * attr
   842 The lowering annotates a FunctionNode with symbols for each identifier
   843 and transforms high level constructs into lower level ones, that the
   844 CodeGenerator consumes.
   846 Lower logging typically outputs things like post pass actions,
   847 insertions of casts because symbol types have been changed and type
   848 specialization information. Currently very little info is generated by
   849 this logger. This will probably change.
   852 * finalize
   854 This --log=finalize log option outputs information for type finalization,
   855 the third tier of the compiler. This means things like placement of 
   856 specialized scope nodes or explicit conversions. 
   859 * fields
   861 The --log=fields option (at info level) is equivalent to setting the
   862 system variable "nashorn.fields.debug" to true. At the info level it
   863 will only show info about type assumptions that were invalidated. If
   864 the level is set to finest, it will also trace every AccessorProperty
   865 getter and setter in the program, show arguments, return values
   866 etc. It will also show the internal representation of respective field
   867 (Object in the normal case, unless running with the dual field
   868 representation)
   870 * time
   872 This enables timers for various phases of script compilation. The timers
   873 will be dumped when the Nashorn process exits. We see a percentage value
   874 of how much time was spent not executing bytecode (i.e. compilation and
   875 internal tasks) at the end of the report. 
   877 A finer level than "info" will show individual compilation timings as they
   878 happen.
   880 Here is an example:
   882 [time] Accumulated complation phase Timings:
   883 [time] 
   884 [time] 'JavaScript Parsing'              1076 ms
   885 [time] 'Constant Folding'                 159 ms
   886 [time] 'Control Flow Lowering'            303 ms
   887 [time] 'Program Point Calculation'        282 ms
   888 [time] 'Builtin Replacement'               71 ms
   889 [time] 'Code Splitting'                   670 ms
   890 [time] 'Symbol Assignment'                474 ms
   891 [time] 'Scope Depth Computation'          249 ms
   892 [time] 'Optimistic Type Assignment'       186 ms
   893 [time] 'Local Variable Type Calculation'  526 ms
   894 [time] 'Bytecode Generation'             5177 ms
   895 [time] 'Class Installation'              1854 ms
   896 [time] 
   897 [time] Total runtime: 11994 ms (Non-runtime: 11027 ms [91%])
   899 =======================
   900 3. Undocumented options
   901 =======================
   903 Here follows a short description of undocumented options for Nashorn.
   904 To see a list of all undocumented options, use the (undocumented) flag
   905 "-xhelp".
   907 i.e. jjs -xhelp or java -jar nashorn.jar -xhelp
   909 Undocumented options are not guaranteed to work, run correctly or be
   910 bug free. They are experimental and for internal or debugging use.
   911 They are also subject to change without notice.
   913 In practice, though, all options below not explicitly documented as
   914 EXPERIMENTAL can be relied upon, for example --dump-on-error is useful
   915 for any JavaScript/Nashorn developer, but there is no guarantee.
   917 A short summary follows:
   919 	-D (-Dname=value. Set a system property. This option can be repeated.)
   921 	-ccs, --class-cache-size (Size of the Class cache size per global scope.)
   923 	-cp, -classpath (-cp path. Specify where to find user class files.)
   925 	-co, --compile-only (Compile without running.)
   926 		param: [true|false]   default: false
   928 	-d, --dump-debug-dir (specify a destination directory to dump class files.)
   929 		param: <path>   
   931 	--debug-lines (Generate line number table in .class files.)
   932 		param: [true|false]   default: true
   934 	--debug-locals (Generate local variable table in .class files.)
   935 		param: [true|false]   default: false
   937 	-doe, -dump-on-error (Dump a stack trace on errors.)
   938 		param: [true|false]   default: false
   940 	--early-lvalue-error (invalid lvalue expressions should be reported as early errors.)
   941 		param: [true|false]   default: true
   943 	--empty-statements (Preserve empty statements in AST.)
   944 		param: [true|false]   default: false
   946 	-fv, -fullversion (Print full version info of Nashorn.)
   947 		param: [true|false]   default: false
   949 	--function-statement-error (Report an error when function declaration is used as a statement.)
   950 		param: [true|false]   default: false
   952 	--function-statement-warning (Warn when function declaration is used as a statement.)
   953 		param: [true|false]   default: false
   955 	-fx (Launch script as an fx application.)
   956 		param: [true|false]   default: false
   958 	--global-per-engine (Use single Global instance per script engine instance.)
   959 		param: [true|false]   default: false
   961 	-h, -help (Print help for command line flags.)
   962 		param: [true|false]   default: false
   964 	--loader-per-compile (Create a new class loader per compile.)
   965 		param: [true|false]   default: true
   967 	-l, --locale (Set Locale for script execution.)
   968 		param: <locale>   default: en-US
   970 	--log (Enable logging of a given level for a given number of sub systems. 
   971 	      [for example: --log=fields:finest,codegen:info].)
   972 		param: <module:level>,*   
   974 	-nj, --no-java (Disable Java support.)
   975 		param: [true|false]   default: false
   977 	-nse, --no-syntax-extensions (Disallow non-standard syntax extensions.)
   978 		param: [true|false]   default: false
   980 	-nta, --no-typed-arrays (Disable typed arrays support.)
   981 		param: [true|false]   default: false
   983 	--parse-only (Parse without compiling.)
   984 		param: [true|false]   default: false
   986 	--print-ast (Print abstract syntax tree.)
   987 		param: [true|false]   default: false
   989 	-pc, --print-code (Print generated bytecode. If a directory is specified, nothing will 
   990 	                  be dumped to stderr. Also, in that case, .dot files will be generated 
   991 	                  for all functions or for the function with the specified name only.)
   992 		param: [dir:<output-dir>,function:<name>]   
   994 	--print-lower-ast (Print lowered abstract syntax tree.)
   995 		param: [true|false]   default: false
   997 	-plp, --print-lower-parse (Print the parse tree after lowering.)
   998 		param: [true|false]   default: false
  1000 	--print-mem-usage (Print memory usage of IR after each compile stage.)
  1001 		param: [true|false]   default: false
  1003 	--print-no-newline (Print function will not print new line char.)
  1004 		param: [true|false]   default: false
  1006 	-pp, --print-parse (Print the parse tree.)
  1007 		param: [true|false]   default: false
  1009 	--print-symbols (Print the symbol table.)
  1010 		param: [true|false]   default: false
  1012 	-pcs, --profile-callsites (Dump callsite profile data.)
  1013 		param: [true|false]   default: false
  1015 	-scripting (Enable scripting features.)
  1016 		param: [true|false]   default: false
  1018 	--stderr (Redirect stderr to a filename or to another tty, e.g. stdout.)
  1019 		param: <output console>   
  1021 	--stdout (Redirect stdout to a filename or to another tty, e.g. stderr.)
  1022 		param: <output console>   
  1024 	-strict (Run scripts in strict mode.)
  1025 		param: [true|false]   default: false
  1027 	-t, -timezone (Set timezone for script execution.)
  1028 		param: <timezone>   default: Europe/Stockholm
  1030 	-tcs, --trace-callsites (Enable callsite trace mode. Options are: miss [trace callsite misses] 
  1031 	                         enterexit [trace callsite enter/exit], objects [print object properties].)
  1032 		param: [=[option,]*]   
  1034 	--verify-code (Verify byte code before running.)
  1035 		param: [true|false]   default: false
  1037 	-v, -version (Print version info of Nashorn.)
  1038 		param: [true|false]   default: false
  1040 	-xhelp (Print extended help for command line flags.)
  1041 		param: [true|false]   default: false

mercurial