This document describes system properties that are used for internal debugging and instrumentation purposes, along with the system loggers, which are used for the same thing. This document is intended as a developer resource, and it is not needed as Nashorn documentation for normal usage. Flags and system properties described herein are subject to change without notice. ===================================== 1. System properties used internally ===================================== This documentation of the system property flags assume that the default value of the flag is false, unless otherwise specified. SYSTEM PROPERTY: -Dnashorn.args= This property takes as its value a space separated list of Nashorn command line options that should be passed to Nashorn. This might be useful in environments where it is hard to tell how a nashorn.jar is launched. Example: > java -Dnashorn.args="--lazy-complation --log=compiler" large-java-app-with-nashorn.jar > ant -Dnashorn.args="--log=codegen" antjob SYSTEM PROPERTY: -Dnashorn.args.prepend= This property behaves like nashorn.args, but adds the given arguments before the existing ones instead of after them. Later arguments will overwrite earlier ones, so this is useful for setting default arguments that can be overwritten. SYSTEM PROPERTY: -Dnashorn.unstable.relink.threshold=x This property controls how many call site misses are allowed before a callsite is relinked with "apply" semantics to never change again. In the case of megamorphic callsites, this is necessary, or the program would spend all its time swapping out callsite targets. Dynalink has a default value (currently 8 relinks) for this property if it is not explicitly set. SYSTEM PROPERTY: -Dnashorn.compiler.splitter.threshold=x This will change the node weight that requires a subgraph of the IR to be split into several classes in order not to run out of bytecode space. The default value is 0x8000 (32768). SYSTEM PROPERTY: -Dnashorn.serialize.compression= This property sets the compression level used when deflating serialized AST structures of anonymous split functions. Valid values range from 0 to 9, the default value is 4. Higher values will reduce memory size of serialized AST but increase CPU usage required for compression. SYSTEM PROPERTY: -Dnashorn.codegen.debug.trace= See the description of the codegen logger below. SYSTEM PROPERTY: -Dnashorn.fields.objects, -Dnashorn.fields.dual When the nashorn.fields.objects property is true, Nashorn will always use object fields for AccessorProperties, requiring boxing for all primitive property values. When nashorn.fields.dual is set, Nashorn will always use dual long/object fields, which allows primitives to be stored without boxing. When neither system property is set, Nashorn chooses a setting depending on the optimistic types setting (dual fields when optimistic types are enabled, object-only fields otherwise). With dual fields, Nashorn uses long fields to store primitive values. Ints are represented as the 32 low bits of the long fields. Doubles are represented as the doubleToLongBits of their value. This way a single field can be used for all primitive types. Packing and unpacking doubles to their bit representation is intrinsified by the JVM and extremely fast. In the future, this might complement or be replaced by experimental feature sun.misc.TaggedArray, which has been discussed on the mlvm mailing list. TaggedArrays are basically a way to share data space between primitives and references, and have the GC understand this. SYSTEM PROPERTY: -Dnashorn.compiler.symbol.trace=[[,*]], -Dnashorn.compiler.symbol.stacktrace=[[,*]] When this property is set, creation and manipulation of any symbol named "x" will show information about when the compiler changes its type assumption, bytecode local variable slot assignment and other data. This is useful if, for example, a symbol shows up as an Object, when you believe it should be a primitive. Usually there is an explanation for this, for example that it exists in the global scope and type analysis has to be more conservative. Several symbols names to watch can be specified by comma separation. If no variable name is specified (and no equals sign), all symbols will be watched By using "stacktrace" instead of or together with "trace", stack traces will be displayed upon symbol changes according to the same semantics. SYSTEM PROPERTY: -Dnashorn.lexer.xmlliterals If this property it set, it means that the Lexer should attempt to parse XML literals, which would otherwise generate syntax errors. Warning: there are currently no unit tests for this functionality. XML literals, when this is enabled, end up as standard LiteralNodes in the IR. SYSTEM_PROPERTY: -Dnashorn.debug If this property is set to true, Nashorn runs in Debug mode. Debug mode is slightly slower, as for example statistics counters are enabled during the run. Debug mode makes available a NativeDebug instance called "Debug" in the global space that can be used to print property maps and layout for script objects, as well as a "dumpCounters" method that will print the current values of the previously mentioned stats counters. These functions currently exists for Debug: "map" - print(Debug.map(x)) will dump the PropertyMap for object x to stdout (currently there also exist functions called "embedX", where X is a value from 0 to 3, that will dump the contents of the embed pool for the first spill properties in any script object and "spill", that will dump the contents of the growing spill pool of spill properties in any script object. This is of course subject to change without notice, should we change the script object layout. "methodHandle" - this method returns the method handle that is used for invoking a particular script function. "identical" - this method compares two script objects for reference equality. It is a == Java comparison "equals" - Returns true if two objects are either referentially identical or equal as defined by java.lang.Object.equals. "dumpCounters" - will dump the debug counters' current values to stdout. Currently we count number of ScriptObjects in the system, number of Scope objects in the system, number of ScriptObject listeners added, removed and dead (without references). We also count number of ScriptFunctions, ScriptFunction invocations and ScriptFunction allocations. Furthermore we count PropertyMap statistics: how many property maps exist, how many times were property maps cloned, how many times did the property map history cache hit, prevent new allocations, how many prototype invalidations were done, how many time the property map proto cache hit. Finally we count callsite misses on a per callsite bases, which occur when a callsite has to be relinked, due to a previous assumption of object layout being invalidated. "getContext" - return the current Nashorn context. "equalWithoutType" - Returns true if if the two objects are both property maps, and they have identical properties in the same order, but allows the properties to differ in their types. "diffPropertyMaps" Returns a diagnostic string representing the difference of two property maps. "getClass" - Returns the Java class of an object, or undefined if null. "toJavaString" - Returns the Java toString representation of an object. "toIdentString" - Returns a string representation of an object consisting of its java class name and hash code. "getListenerCount" - Return the number of property listeners for a script object. "getEventQueueCapacity" - Get the capacity of the event queue. "setEventQueueCapacity" - Set the event queue capacity. "addRuntimeEvent" - Add a runtime event to the runtime event queue. The queue has a fixed size (see -Dnashorn.runtime.event.queue.size) and the oldest entry will be thrown out of the queue is about to overflow. "expandEventQueueCapacity" - Expands the event queue capacity, or truncates if capacity is lower than current capacity. Then only the newest entries are kept. "clearRuntimeEvents" - Clear the runtime event queue. "removeRuntimeEvent" - Remove a specific runtime event from the event queue. "getRuntimeEvents" - Return all runtime events in the queue as an array. "getLastRuntimeEvent" - Return the last runtime event in the queue. SYSTEM PROPERTY: -Dnashorn.methodhandles.debug.stacktrace This enhances methodhandles logging (see below) to also dump the stack trace for every instrumented method handle operation. Warning: This is enormously verbose, but provides a pretty decent "grep:able" picture of where the calls are coming from. SYSTEM PROPERTY: -Dnashorn.cce Setting this system property causes the Nashorn linker to rely on ClassCastExceptions for triggering a callsite relink. If not set, the linker will add an explicit instanceof guard. SYSTEM PROPERTY: -Dnashorn.spill.threshold= This property sets the number of fields in an object from which to use generic array based spill storage instead of Java fields. The default value is 256. SYSTEM PROPERTY: -Dnashorn.tcs.miss.samplePercent= When running with the trace callsite option (-tcs), Nashorn will count and instrument any callsite misses that require relinking. As the number of relinks is large and usually produces a lot of output, this system property can be used to constrain the percentage of misses that should be logged. Typically this is set to 1 or 5 (percent). 1% is the default value. SYSTEM PROPERTY: -Dnashorn.persistent.code.cache This property can be used to set the directory where Nashorn stores serialized script classes generated with the -pcc/--persistent-code-cache option. The default directory name is "nashorn_code_cache". SYSTEM PROPERTY: -Dnashorn.typeInfo.maxFiles Maximum number of files to store in the type info cache. The type info cache is used to cache type data of JavaScript functions when running with optimistic types (-ot/--optimistic-types). There is one file per JavaScript function in the cache. The default value is 0 which means the feature is disabled. Setting this to something like 20000 is probably good enough for most applications and will usually cap the cache directory to about 80MB presuming a 4kB filesystem allocation unit. Set this to "unlimited" to run without limit. If the value is not 0 or "unlimited", Nashorn will spawn a cleanup thread that makes sure the number of files in the cache does not exceed the given value by deleting the least recently modified files. SYSTEM PROPERTY: -Dnashorn.typeInfo.cacheDir This property can be used to set the directory where Nashorn stores the type info cache when -Dnashorn.typeInfo.maxFiles is set to a nonzero value. The default location is platform specific. On Windows, it is "${java.io.tmpdir}\com.oracle.java.NashornTypeInfo". On Linux and Solaris it is "~/.cache/com.oracle.java.NashornTypeInfo". On Mac OS X, it is "~/Library/Caches/com.oracle.java.NashornTypeInfo". SYSTEM PROPERTY: -Dnashorn.typeInfo.cleanupDelaySeconds= This sets the delay between cleanups of the typeInfo cache, in seconds. The default delay is 20 seconds. SYSTEM PROPERTY: -Dnashorn.profilefile= When running with the profile callsite options (-pcs), Nashorn will dump profiling data for all callsites to stderr as a shutdown hook. To instead redirect this to a file, specify the path to the file using this system property. SYSTEM_PROPERTY: -Dnashorn.regexp.impl=[jdk|joni] This property defines the regular expression engine to be used by Nashorn. Set this flag to "jdk" to get an implementation based on the JDK's java.util.regex package. Set this property to "joni" to install an implementation based on Joni, the regular expression engine used by the JRuby project. The default value for this flag is "joni" SYSTEM PROPERTY: -Dnashorn.runtime.event.queue.size= Nashorn provides a fixed sized runtime event queue for debugging purposes. See -Dnashorn.debug for methods to access the event queue. The default value is 1024. =============== 2. The loggers. =============== It is very simple to create your own logger. Use the DebugLogger class and give the subsystem name as a constructor argument. The Nashorn loggers can be used to print per-module or per-subsystem debug information with different levels of verbosity. The loggers for a given subsystem are available are enabled by using --log=[:] on the command line. Here identifies the name of the subsystem to be logged and the optional colon and level argument is a standard java.util.logging.Level name (severe, warning, info, config, fine, finer, finest). If the level is left out for a particular subsystem, it defaults to "info". Any log message logged as the level or a level that is more important will be output to stderr by the logger. Several loggers can be enabled by a single command line option, by putting a comma after each subsystem/level tuple (or each subsystem if level is unspecified). The --log option can also be given multiple times on the same command line, with the same effect. For example: --log=codegen,fields:finest is equivalent to --log=codegen:info --log=fields:finest The following is an incomplete list of subsystems that currently support logging. Look for classes implementing jdk.nashorn.internal.runtime.logging.Loggable for more loggers. * compiler The compiler is in charge of turning source code and function nodes into byte code, and installs the classes into a class loader controlled from the Context. Log messages are, for example, about things like new compile units being allocated. The compiler has global settings that all the tiers of codegen (e.g. Lower and CodeGenerator) use.s * recompile This logger shows information about recompilation of scripts and functions at runtime. Recompilation may happen because a function was called with different parameter types, or because an optimistic assumption failed while executing a function with -ot/--optimistic-types. * codegen The code generator is the emitter stage of the code pipeline, and turns the lowest tier of a FunctionNode into bytecode. Codegen logging shows byte codes as they are being emitted, line number information and jumps. It also shows the contents of the bytecode stack prior to each instruction being emitted. This is a good debugging aid. For example: [codegen] #41 line:2 (f)_afc824e [codegen] #42 load symbol x slot=2 [codegen] #43 {1:O} load int 0 [codegen] #44 {2:I O} dynamic_runtime_call GT:ZOI_I args=2 returnType=boolean [codegen] #45 signature (Ljava/lang/Object;I)Z [codegen] #46 {1:Z} ifeq ternary_false_5402fe28 [codegen] #47 load symbol x slot=2 [codegen] #48 {1:O} goto ternary_exit_107c1f2f [codegen] #49 ternary_false_5402fe28 [codegen] #50 load symbol x slot=2 [codegen] #51 {1:O} convert object -> double [codegen] #52 {1:D} neg [codegen] #53 {1:D} convert double -> object [codegen] #54 {1:O} ternary_exit_107c1f2f [codegen] #55 {1:O} return object shows a ternary node being generated for the sequence "return x > 0 ? x : -x" The first number on the log line is a unique monotonically increasing emission id per bytecode. There is no guarantee this is the same id between runs. depending on non deterministic code execution/compilation, but for small applications it usually is. If the system variable -Dnashorn.codegen.debug.trace= is set, where x is a bytecode emission id, a stack trace will be shown as the particular bytecode is about to be emitted. This can be a quick way to determine where it comes from without attaching the debugger. "Who generated that neg?" The --log=codegen option is equivalent to setting the system variable "nashorn.codegen.debug" to true. * fold Shows constant folding taking place before lowering * lower This is the first lowering pass. Lower is a code generation pass that turns high level IR nodes into lower level one, for example substituting comparisons to RuntimeNodes and inlining finally blocks. Lower is also responsible for determining control flow information like end points. * symbols The symbols logger tracks the assignment os symbols to identifiers. * scopedepths This logs the calculation of scope depths for non-local symbols. * fields The --log=fields option (at info level) is equivalent to setting the system variable "nashorn.fields.debug" to true. At the info level it will only show info about type assumptions that were invalidated. If the level is set to finest, it will also trace every AccessorProperty getter and setter in the program, show arguments, return values etc. It will also show the internal representation of respective field (Object in the normal case, unless running with the dual field representation) * time This enables timers for various phases of script compilation. The timers will be dumped when the Nashorn process exits. We see a percentage value of how much time was spent not executing bytecode (i.e. compilation and internal tasks) at the end of the report. A finer level than "info" will show individual compilation timings as they happen. Here is an example: [time] Accumulated complation phase Timings: [time] [time] 'JavaScript Parsing' 1076 ms [time] 'Constant Folding' 159 ms [time] 'Control Flow Lowering' 303 ms [time] 'Program Point Calculation' 282 ms [time] 'Builtin Replacement' 71 ms [time] 'Code Splitting' 670 ms [time] 'Symbol Assignment' 474 ms [time] 'Scope Depth Computation' 249 ms [time] 'Optimistic Type Assignment' 186 ms [time] 'Local Variable Type Calculation' 526 ms [time] 'Bytecode Generation' 5177 ms [time] 'Class Installation' 1854 ms [time] [time] Total runtime: 11994 ms (Non-runtime: 11027 ms [91%]) * methodhandles If this logger is enabled, each MethodHandle related call that uses the java.lang.invoke package gets its MethodHandle intercepted and an instrumentation printout of arguments and return value appended to it. This shows exactly which method handles are executed and from where. (Also MethodTypes and SwitchPoints). * classcache This logger shows information about reusing code classes using the in-memory class cache. Nashorn will try to avoid compilation of scripts by using existing classes. This can significantly improve performance when repeatedly evaluating the same script. ======================= 3. Undocumented options ======================= Here follows a short description of undocumented options for Nashorn. To see a list of all undocumented options, use the (undocumented) flag "-xhelp". i.e. jjs -xhelp or java -jar nashorn.jar -xhelp Undocumented options are not guaranteed to work, run correctly or be bug free. They are experimental and for internal or debugging use. They are also subject to change without notice. In practice, though, all options below not explicitly documented as EXPERIMENTAL can be relied upon, for example --dump-on-error is useful for any JavaScript/Nashorn developer, but there is no guarantee. A short summary follows: -D (-Dname=value. Set a system property. This option can be repeated.) -ccs, --class-cache-size (Size of the Class cache size per global scope.) -cp, -classpath (-cp path. Specify where to find user class files.) -co, --compile-only (Compile without running.) param: [true|false] default: false -d, --dump-debug-dir (specify a destination directory to dump class files.) param: --debug-lines (Generate line number table in .class files.) param: [true|false] default: true --debug-locals (Generate local variable table in .class files.) param: [true|false] default: false -doe, -dump-on-error (Dump a stack trace on errors.) param: [true|false] default: false --early-lvalue-error (invalid lvalue expressions should be reported as early errors.) param: [true|false] default: true --empty-statements (Preserve empty statements in AST.) param: [true|false] default: false -fv, -fullversion (Print full version info of Nashorn.) param: [true|false] default: false --function-statement-error (Report an error when function declaration is used as a statement.) param: [true|false] default: false --function-statement-warning (Warn when function declaration is used as a statement.) param: [true|false] default: false -fx (Launch script as an fx application.) param: [true|false] default: false --global-per-engine (Use single Global instance per script engine instance.) param: [true|false] default: false -h, -help (Print help for command line flags.) param: [true|false] default: false --loader-per-compile (Create a new class loader per compile.) param: [true|false] default: true -l, --locale (Set Locale for script execution.) param: default: en-US --log (Enable logging of a given level for a given number of sub systems. [for example: --log=fields:finest,codegen:info].) param: ,* -nj, --no-java (Disable Java support.) param: [true|false] default: false -nse, --no-syntax-extensions (Disallow non-standard syntax extensions.) param: [true|false] default: false -nta, --no-typed-arrays (Disable typed arrays support.) param: [true|false] default: false --parse-only (Parse without compiling.) param: [true|false] default: false --print-ast (Print abstract syntax tree.) param: [true|false] default: false -pc, --print-code (Print generated bytecode. If a directory is specified, nothing will be dumped to stderr. Also, in that case, .dot files will be generated for all functions or for the function with the specified name only.) param: [dir:,function:] --print-lower-ast (Print lowered abstract syntax tree.) param: [true|false] default: false -plp, --print-lower-parse (Print the parse tree after lowering.) param: [true|false] default: false --print-mem-usage (Print memory usage of IR after each compile stage.) param: [true|false] default: false --print-no-newline (Print function will not print new line char.) param: [true|false] default: false -pp, --print-parse (Print the parse tree.) param: [true|false] default: false --print-symbols (Print the symbol table.) param: [true|false] default: false -pcs, --profile-callsites (Dump callsite profile data.) param: [true|false] default: false -scripting (Enable scripting features.) param: [true|false] default: false --stderr (Redirect stderr to a filename or to another tty, e.g. stdout.) param: --stdout (Redirect stdout to a filename or to another tty, e.g. stderr.) param: -strict (Run scripts in strict mode.) param: [true|false] default: false -t, -timezone (Set timezone for script execution.) param: default: Europe/Stockholm -tcs, --trace-callsites (Enable callsite trace mode. Options are: miss [trace callsite misses] enterexit [trace callsite enter/exit], objects [print object properties].) param: [=[option,]*] --verify-code (Verify byte code before running.) param: [true|false] default: false -v, -version (Print version info of Nashorn.) param: [true|false] default: false -xhelp (Print extended help for command line flags.) param: [true|false] default: false