Sun, 28 Apr 2013 08:16:45 +0100
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 useful
20 in environments where it is hard to tell how a nashorn.jar is launched.
22 Example:
24 > java -Dnashorn.args="--lazy-complation --log=compiler" large-java-app-with-nashorn.jar
25 > ant -Dnashorn.args="--log=codegen" antjob
27 SYSTEM PROPERTY: -Dnashorn.unstable.relink.threshold=x
29 This property controls how many call site misses are allowed before a
30 callsite is relinked with "apply" semantics to never change again.
31 In the case of megamorphic callsites, this is necessary, or the
32 program would spend all its time swapping out callsite targets. Dynalink
33 has a default value (currently 8 relinks) for this property if it
34 is not explicitly set.
37 SYSTEM PROPERTY: -Dnashorn.compiler.splitter.threshold=x
39 This will change the node weight that requires a subgraph of the IR to
40 be split into several classes in order not to run out of bytecode space.
41 The default value is 0x8000 (32768).
44 SYSTEM PROPERTY: -Dnashorn.compiler.intarithmetic
46 Arithmetic operations in Nashorn (except bitwise ones) typically
47 coerce the operands to doubles (as per the JavaScript spec). To switch
48 this off and remain in integer mode, for example for "var x = a&b; var
49 y = c&d; var z = x*y;", use this flag. This will force the
50 multiplication of variables that are ints to be done with the IMUL
51 bytecode and the result "z" to become an int.
53 WARNING: Note that is is experimental only to ensure that type support
54 exists for all primitive types. The generated code is unsound. This
55 will be the case until we do optimizations based on it. There is a CR
56 in Nashorn to do better range analysis, and ensure that this is only
57 done where the operation can't overflow into a wider type. Currently
58 no overflow checking is done, so at the moment, until range analysis
59 has been completed, this option is turned off.
61 We've experimented by using int arithmetic for everything and putting
62 overflow checks afterwards, which would recompute the operation with
63 the correct precision, but have yet to find a configuration where this
64 is faster than just using doubles directly, even if the int operation
65 does not overflow. Getting access to a JVM intrinsic that does branch
66 on overflow would probably alleviate this.
68 There is also a problem with this optimistic approach if the symbol
69 happens to reside in a local variable slot in the bytecode, as those
70 are strongly typed. Then we would need to split large sections of
71 control flow, so this is probably not the right way to go, while range
72 analysis is. There is a large difference between integer bytecode
73 without overflow checks and double bytecode. The former is
74 significantly faster.
77 SYSTEM PROPERTY: -Dnashorn.codegen.debug, -Dnashorn.codegen.debug.trace=<x>
79 See the description of the codegen logger below.
82 SYSTEM_PROPERTY: -Dnashorn.fields.debug
84 See the description on the fields logger below.
87 SYSTEM PROPERTY: -Dnashorn.fields.dual
89 When this property is true, Nashorn will attempt to use primitive
90 fields for AccessorProperties (currently just AccessorProperties, not
91 spill properties). Memory footprint for script objects will increase,
92 as we need to maintain both a primitive field (a long) as well as an
93 Object field for the property value. Ints are represented as the 32
94 low bits of the long fields. Doubles are represented as the
95 doubleToLongBits of their value. This way a single field can be used
96 for all primitive types. Packing and unpacking doubles to their bit
97 representation is intrinsified by the JVM and extremely fast.
99 While dual fields in theory runs significantly faster than Object
100 fields due to reduction of boxing and memory allocation overhead,
101 there is still work to be done to make this a general purpose
102 solution. Research is ongoing.
104 In the future, this might complement or be replaced by experimental
105 feature sun.misc.TaggedArray, which has been discussed on the mlvm
106 mailing list. TaggedArrays are basically a way to share data space
107 between primitives and references, and have the GC understand this.
109 As long as only primitive values are written to the fields and enough
110 type information exists to make sure that any reads don't have to be
111 uselessly boxed and unboxed, this is significantly faster than the
112 standard "Objects only" approach that currently is the default. See
113 test/examples/dual-fields-micro.js for an example that runs twice as
114 fast with dual fields as without them. Here, the compiler, can
115 determine that we are dealing with numbers only throughout the entire
116 property life span of the properties involved.
118 If a "real" object (not a boxed primitive) is written to a field that
119 has a primitive representation, its callsite is relinked and an Object
120 field is used forevermore for that particular field in that
121 PropertyMap and its children, even if primitives are later assigned to
122 it.
124 As the amount of compile time type information is very small in a
125 dynamic language like JavaScript, it is frequently the case that
126 something has to be treated as an object, because we don't know any
127 better. In reality though, it is often a boxed primitive is stored to
128 an AccessorProperty. The fastest way to handle this soundly is to use
129 a callsite typecheck and avoid blowing the field up to an Object. We
130 never revert object fields to primitives. Ping-pong:ing back and forth
131 between primitive representation and Object representation would cause
132 fatal performance overhead, so this is not an option.
134 For a general application the dual fields approach is still slower
135 than objects only fields in some places, about the same in most cases,
136 and significantly faster in very few. This is due the program using
137 primitives, but we still can't prove it. For example "local_var a =
138 call(); field = a;" may very well write a double to the field, but the
139 compiler dare not guess a double type if field is a local variable,
140 due to bytecode variables being strongly typed and later non
141 interchangeable. To get around this, the entire method would have to
142 be replaced and a continuation retained to restart from. We believe
143 that the next steps we should go through are instead:
145 1) Implement method specialization based on callsite, as it's quite
146 frequently the case that numbers are passed around, but currently our
147 function nodes just have object types visible to the compiler. For
148 example "var b = 17; func(a,b,17)" is an example where two parameters
149 can be specialized, but the main version of func might also be called
150 from another callsite with func(x,y,"string").
152 2) This requires lazy jitting as the functions have to be specialized
153 per callsite.
155 Even though "function square(x) { return x*x }" might look like a
156 trivial function that can always only take doubles, this is not
157 true. Someone might have overridden the valueOf for x so that the
158 toNumber coercion has side effects. To fulfil JavaScript semantics,
159 the coercion has to run twice for both terms of the multiplication
160 even if they are the same object. This means that call site
161 specialization is necessary, not parameter specialization on the form
162 "function square(x) { var xd = (double)x; return xd*xd; }", as one
163 might first think.
165 Generating a method specialization for any variant of a function that
166 we can determine by types at compile time is a combinatorial explosion
167 of byte code (try it e.g. on all the variants of am3 in the Octane
168 benchmark crypto.js). Thus, this needs to be lazy
170 3) Possibly optimistic callsite writes, something on the form
172 x = y; //x is a field known to be a primitive. y is only an object as
173 far as we can tell
175 turns into
177 try {
178 x = (int)y;
179 } catch (X is not an integer field right now | ClassCastException e) {
180 x = y;
181 }
183 Mini POC shows that this is the key to a lot of dual field performance
184 in seemingly trivial micros where one unknown object, in reality
185 actually a primitive, foils it for us. Very common pattern. Once we
186 are "all primitives", dual fields runs a lot faster than Object fields
187 only.
189 We still have to deal with objects vs primitives for local bytecode
190 slots, possibly through code copying and versioning.
193 SYSTEM PROPERTY: -Dnashorn.compiler.symbol.trace=[<x>[,*]],
194 -Dnashorn.compiler.symbol.stacktrace=[<x>[,*]]
196 When this property is set, creation and manipulation of any symbol
197 named "x" will show information about when the compiler changes its
198 type assumption, bytecode local variable slot assignment and other
199 data. This is useful if, for example, a symbol shows up as an Object,
200 when you believe it should be a primitive. Usually there is an
201 explanation for this, for example that it exists in the global scope
202 and type analysis has to be more conservative.
204 Several symbols names to watch can be specified by comma separation.
206 If no variable name is specified (and no equals sign), all symbols
207 will be watched
209 By using "stacktrace" instead of or together with "trace", stack
210 traces will be displayed upon symbol changes according to the same
211 semantics.
214 SYSTEM PROPERTY: nashorn.lexer.xmlliterals
216 If this property it set, it means that the Lexer should attempt to
217 parse XML literals, which would otherwise generate syntax
218 errors. Warning: there are currently no unit tests for this
219 functionality.
221 XML literals, when this is enabled, end up as standard LiteralNodes in
222 the IR.
225 SYSTEM_PROPERTY: nashorn.debug
227 If this property is set to true, Nashorn runs in Debug mode. Debug
228 mode is slightly slower, as for example statistics counters are enabled
229 during the run. Debug mode makes available a NativeDebug instance
230 called "Debug" in the global space that can be used to print property
231 maps and layout for script objects, as well as a "dumpCounters" method
232 that will print the current values of the previously mentioned stats
233 counters.
235 These functions currently exists for Debug:
237 "map" - print(Debug.map(x)) will dump the PropertyMap for object x to
238 stdout (currently there also exist functions called "embedX", where X
239 is a value from 0 to 3, that will dump the contents of the embed pool
240 for the first spill properties in any script object and "spill", that
241 will dump the contents of the growing spill pool of spill properties
242 in any script object. This is of course subject to change without
243 notice, should we change the script object layout.
245 "methodHandle" - this method returns the method handle that is used
246 for invoking a particular script function.
248 "identical" - this method compares two script objects for reference
249 equality. It is a == Java comparison
251 "dumpCounters" - will dump the debug counters' current values to
252 stdout.
254 Currently we count number of ScriptObjects in the system, number of
255 Scope objects in the system, number of ScriptObject listeners added,
256 removed and dead (without references).
258 We also count number of ScriptFunctions, ScriptFunction invocations
259 and ScriptFunction allocations.
261 Furthermore we count PropertyMap statistics: how many property maps
262 exist, how many times were property maps cloned, how many times did
263 the property map history cache hit, prevent new allocations, how many
264 prototype invalidations were done, how many time the property map
265 proto cache hit.
267 Finally we count callsite misses on a per callsite bases, which occur
268 when a callsite has to be relinked, due to a previous assumption of
269 object layout being invalidated.
272 SYSTEM PROPERTY: nashorn.methodhandles.debug,
273 nashorn.methodhandles.debug=create
275 If this property is enabled, each MethodHandle related call that uses
276 the java.lang.invoke package gets its MethodHandle intercepted and an
277 instrumentation printout of arguments and return value appended to
278 it. This shows exactly which method handles are executed and from
279 where. (Also MethodTypes and SwitchPoints). This can be augmented with
280 more information, for example, instance count, by subclassing or
281 further extending the TraceMethodHandleFactory implementation in
282 MethodHandleFactory.java.
284 If the property is specialized with "=create" as its option,
285 instrumentation will be shown for method handles upon creation time
286 rather than at runtime usage.
289 SYSTEM PROPERTY: nashorn.methodhandles.debug.stacktrace
291 This does the same as nashorn.methodhandles.debug, but when enabled
292 also dumps the stack trace for every instrumented method handle
293 operation. Warning: This is enormously verbose, but provides a pretty
294 decent "grep:able" picture of where the calls are coming from.
296 See the description of the codegen logger below for a more verbose
297 description of this option
300 SYSTEM PROPERTY: nashorn.scriptfunction.specialization.disable
302 There are several "fast path" implementations of constructors and
303 functions in the NativeObject classes that, in their original form,
304 take a variable amount of arguments. Said functions are also declared
305 to take Object parameters in their original form, as this is what the
306 JavaScript specification mandates.
308 However, we often know quite a lot more at a callsite of one of these
309 functions. For example, Math.min is called with a fixed number (2) of
310 integer arguments. The overhead of boxing these ints to Objects and
311 folding them into an Object array for the generic varargs Math.min
312 function is an order of magnitude slower than calling a specialized
313 implementation of Math.min that takes two integers. Specialized
314 functions and constructors are identified by the tag
315 @SpecializedFunction and @SpecializedConstructor in the Nashorn
316 code. The linker will link in the most appropriate (narrowest types,
317 right number of types and least number of arguments) specialization if
318 specializations are available.
320 Every ScriptFunction may carry specializations that the linker can
321 choose from. This framework will likely be extended for user defined
322 functions. The compiler can often infer enough parameter type info
323 from callsites for in order to generate simpler versions with less
324 generic Object types. This feature depends on future lazy jitting, as
325 there tend to be many calls to user defined functions, some where the
326 callsite can be specialized, some where we mostly see object
327 parameters even at the callsite.
329 If this system property is set to true, the linker will not attempt to
330 use any specialized function or constructor for native objects, but
331 just call the generic one.
334 SYSTEM PROPERTY: nashorn.tcs.miss.samplePercent=<x>
336 When running with the trace callsite option (-tcs), Nashorn will count
337 and instrument any callsite misses that require relinking. As the
338 number of relinks is large and usually produces a lot of output, this
339 system property can be used to constrain the percentage of misses that
340 should be logged. Typically this is set to 1 or 5 (percent). 1% is the
341 default value.
344 SYSTEM_PROPERTY: nashorn.profilefile=<filename>
346 When running with the profile callsite options (-pcs), Nashorn will
347 dump profiling data for all callsites to stderr as a shutdown hook. To
348 instead redirect this to a file, specify the path to the file using
349 this system property.
352 SYSTEM_PROPERTY: nashorn.regexp.impl=[jdk|joni]
354 This property defines the regular expression engine to be used by
355 Nashorn. The default implementation is "jdk" which is based on the
356 JDK's java.util.regex package. Set this property to "joni" to install
357 an implementation based on Joni, the regular expression engine used by
358 the JRuby project.
361 ===============
362 2. The loggers.
363 ===============
365 It is very simple to create your own logger. Use the DebugLogger class
366 and give the subsystem name as a constructor argument.
368 The Nashorn loggers can be used to print per-module or per-subsystem
369 debug information with different levels of verbosity. The loggers for
370 a given subsystem are available are enabled by using
372 --log=<systemname>[:<level>]
374 on the command line.
376 Here <systemname> identifies the name of the subsystem to be logged
377 and the optional colon and level argument is a standard
378 java.util.logging.Level name (severe, warning, info, config, fine,
379 finer, finest). If the level is left out for a particular subsystem,
380 it defaults to "info". Any log message logged as the level or a level
381 that is more important will be output to stderr by the logger.
383 Several loggers can be enabled by a single command line option, by
384 putting a comma after each subsystem/level tuple (or each subsystem if
385 level is unspecified). The --log option can also be given multiple
386 times on the same command line, with the same effect.
388 For example: --log=codegen,fields:finest is equivalent to
389 --log=codegen:info --log=fields:finest
391 The subsystems that currently support logging are:
394 * compiler
396 The compiler is in charge of turning source code and function nodes
397 into byte code, and installs the classes into a class loader
398 controlled from the Context. Log messages are, for example, about
399 things like new compile units being allocated. The compiler has global
400 settings that all the tiers of codegen (e.g. Lower and CodeGenerator)
401 use.s
404 * codegen
406 The code generator is the emitter stage of the code pipeline, and
407 turns the lowest tier of a FunctionNode into bytecode. Codegen logging
408 shows byte codes as they are being emitted, line number information
409 and jumps. It also shows the contents of the bytecode stack prior to
410 each instruction being emitted. This is a good debugging aid. For
411 example:
413 [codegen] #41 line:2 (f)_afc824e
414 [codegen] #42 load symbol x slot=2
415 [codegen] #43 {1:O} load int 0
416 [codegen] #44 {2:I O} dynamic_runtime_call GT:ZOI_I args=2 returnType=boolean
417 [codegen] #45 signature (Ljava/lang/Object;I)Z
418 [codegen] #46 {1:Z} ifeq ternary_false_5402fe28
419 [codegen] #47 load symbol x slot=2
420 [codegen] #48 {1:O} goto ternary_exit_107c1f2f
421 [codegen] #49 ternary_false_5402fe28
422 [codegen] #50 load symbol x slot=2
423 [codegen] #51 {1:O} convert object -> double
424 [codegen] #52 {1:D} neg
425 [codegen] #53 {1:D} convert double -> object
426 [codegen] #54 {1:O} ternary_exit_107c1f2f
427 [codegen] #55 {1:O} return object
429 shows a ternary node being generated for the sequence "return x > 0 ?
430 x : -x"
432 The first number on the log line is a unique monotonically increasing
433 emission id per bytecode. There is no guarantee this is the same id
434 between runs. depending on non deterministic code
435 execution/compilation, but for small applications it usually is. If
436 the system variable -Dnashorn.codegen.debug.trace=<x> is set, where x
437 is a bytecode emission id, a stack trace will be shown as the
438 particular bytecode is about to be emitted. This can be a quick way to
439 determine where it comes from without attaching the debugger. "Who
440 generated that neg?"
442 The --log=codegen option is equivalent to setting the system variable
443 "nashorn.codegen.debug" to true.
446 * lower
448 This is the first lowering pass.
450 Lower is a code generation pass that turns high level IR nodes into
451 lower level one, for example substituting comparisons to RuntimeNodes
452 and inlining finally blocks.
454 Lower is also responsible for determining control flow information
455 like end points.
458 * attr
460 The lowering annotates a FunctionNode with symbols for each identifier
461 and transforms high level constructs into lower level ones, that the
462 CodeGenerator consumes.
464 Lower logging typically outputs things like post pass actions,
465 insertions of casts because symbol types have been changed and type
466 specialization information. Currently very little info is generated by
467 this logger. This will probably change.
470 * finalize
472 This --log=finalize log option outputs information for type finalization,
473 the third tier of the compiler. This means things like placement of
474 specialized scope nodes or explicit conversions.
477 * fields
479 The --log=fields option (at info level) is equivalent to setting the
480 system variable "nashorn.fields.debug" to true. At the info level it
481 will only show info about type assumptions that were invalidated. If
482 the level is set to finest, it will also trace every AccessorProperty
483 getter and setter in the program, show arguments, return values
484 etc. It will also show the internal representation of respective field
485 (Object in the normal case, unless running with the dual field
486 representation)