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