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=<string>

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=<string>

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

NOTE: This property is deprecated in favor of the 
"--unstable-relink-threshold" command line option. It 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. When neither the system property nor the command line
option are specified, defaults to 8, or 16 with optimistic types turned
on.


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=<x>

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=<x>

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=[<x>[,*]], 
  -Dnashorn.compiler.symbol.stacktrace=[<x>[,*]]

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=<x>

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=<x>

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=<value>

This sets the delay between cleanups of the typeInfo cache, in seconds.
The default delay is 20 seconds.


SYSTEM PROPERTY: -Dnashorn.profilefile=<filename>

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=<value>

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.

SYSTEM PROPERTY: -Dnashorn.anonymous.classes.threshold=<value>

Nashorn can use anonymous classes for loading compiled scripts, depending
on the --anonymous-classes=[auto|true|false] option. Anonymous classes load
faster, but the loaded classes get less optimization applied to them and
therefore usually run slower. In the default "auto" setting, scripts are
loaded as anonymous classes if the script size does not exceed 512 bytes.
The above system property allows to set this threshold to a user defined
value.

===============
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=<systemname>[:<level>]

on the command line.

Here <systemname> 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=<x> 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: <path>   

	--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: <locale>   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: <module:level>,*   

	-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:<output-dir>,function:<name>]   

	--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-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: <output console>   

	--stdout (Redirect stdout to a filename or to another tty, e.g. stderr.)
		param: <output console>   

	-strict (Run scripts in strict mode.)
		param: [true|false]   default: false

	-t, -timezone (Set timezone for script execution.)
		param: <timezone>   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,]*]   

	-urt, --unstable-relink-threshold (Number of times a dynamic call site has to be relinked before it 
	                                  is considered unstable, when the runtime will try to link it as 
	                                  if it is megamorphic.)

	--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

