|
Java example source code file (DEVELOPER_README)
The DEVELOPER_README Java example source codeThis 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.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.compiler.intarithmetic (and integer arithmetic in general) <currently disabled - this is being refactored for update releases> Arithmetic operations in Nashorn (except bitwise ones) typically coerce the operands to doubles (as per the JavaScript spec). To switch this off and remain in integer mode, for example for "var x = a&b; var y = c&d; var z = x*y;", use this flag. This will force the multiplication of variables that are ints to be done with the IMUL bytecode and the result "z" to become an int. WARNING: Note that is is experimental only to ensure that type support exists for all primitive types. The generated code is unsound. This will be the case until we do optimizations based on it. There is a CR in Nashorn to do better range analysis, and ensure that this is only done where the operation can't overflow into a wider type. Currently no overflow checking is done, so at the moment, until range analysis has been completed, this option is turned off. We've experimented by using int arithmetic for everything and putting overflow checks afterwards, which would recompute the operation with the correct precision, but have yet to find a configuration where this is faster than just using doubles directly, even if the int operation does not overflow. Getting access to a JVM intrinsic that does branch on overflow would probably alleviate this. The future: We are transitioning to an optimistic type system that uses int arithmetic everywhere until proven wrong. The problem here is mostly catch an overflow exception and rolling back the state to a new method with less optimistic assumptions for an operation at a particular program point. This will most likely not be in the Java 8.0 release but likely end up in an update release For Java 8, several java.lang.Math methods like addExact, subExact and mulExact are available to help us. Experiments intrinsifying these show a lot of promise, and we have devised a system that basically does on stack replacement with exceptions in bytecode to revert erroneous assumptions. An explanation of how this works and what we are doing can be found here: http://www.slideshare.net/lagergren/lagergren-jvmls2013final Experiments with this show significant ~x2-3 performance increases on pretty much everything, provided that optimistic assumptions don't fail much. It will affect warmup time negatively, depending on how many erroneous too optimistic assumptions are placed in the code at compile time. We don't think this will be much of an issue. For example for a small benchmark that repeatedly executes this method taken from the Crypto Octane benchmark function am3(i,x,w,j,c,n) { var this_array = this.array; var w_array = w.array; var xl = x&0x3fff, xh = x>>14; while(--n >= 0) { var l = this_array[i]&0x3fff; var h = this_array[i++]>>14; var m = xh*l+h*xl; l = xl*l+((m&0x3fff)<<14)+w_array[j]+c; c = (l>>28)+(m>>14)+xh*h; w_array[j++] = l&0xfffffff; } return c; } The performance increase more than doubles. We are also working hard with the code generation team in the Java Virtual Machine to fix things that are lacking in invokedynamic performance, which is another area where a lot of ongoing performance work takes place "Pessimistic" bytecode for am3, guaranteed to be semantically correct: // access flags 0x9 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; L0 LINENUMBER 12 L0 ALOAD 0 INVOKEDYNAMIC dyn:getProp|getElem|getMethod:array(Ljava/lang/Object;)Ljava/lang/Object; [ // handle kind 0x6 : INVOKESTATIC jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;) // arguments: 0 ] ASTORE 8 L1 LINENUMBER 13 L1 ALOAD 3 INVOKEDYNAMIC dyn:getProp|getElem|getMethod:array(Ljava/lang/Object;)Ljava/lang/Object; [ // handle kind 0x6 : INVOKESTATIC jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;) // arguments: 0 ] ASTORE 9 L2 LINENUMBER 14 L2 ALOAD 2 INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toInt32 (Ljava/lang/Object;)I SIPUSH 16383 IAND ISTORE 10 ALOAD 2 INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toInt32 (Ljava/lang/Object;)I BIPUSH 14 ISHR ISTORE 11 L3 LINENUMBER 15 L3 GOTO L4 L5 LINENUMBER 16 L5 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] [] ALOAD 8 ALOAD 1 INVOKEDYNAMIC dyn:getElem|getProp|getMethod(Ljava/lang/Object;Ljava/lang/Object;)I [ // handle kind 0x6 : INVOKESTATIC jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;) // arguments: 0 ] SIPUSH 16383 IAND INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer; ASTORE 12 L6 LINENUMBER 17 L6 ALOAD 8 ALOAD 1 INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toNumber (Ljava/lang/Object;)D DUP2 DCONST_1 DADD INVOKESTATIC java/lang/Double.valueOf (D)Ljava/lang/Double; ASTORE 1 INVOKEDYNAMIC dyn:getElem|getProp|getMethod(Ljava/lang/Object;D)I [ // handle kind 0x6 : INVOKESTATIC jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;) // arguments: 0 ] BIPUSH 14 ISHR ISTORE 13 L7 LINENUMBER 18 L7 ILOAD 11 I2D ALOAD 12 INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toNumber (Ljava/lang/Object;)D DMUL ILOAD 13 I2D ILOAD 10 I2D DMUL DADD DSTORE 14 L8 LINENUMBER 19 L8 ILOAD 10 I2D ALOAD 12 INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toNumber (Ljava/lang/Object;)D DMUL DLOAD 14 INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toInt32 (D)I SIPUSH 16383 IAND BIPUSH 14 ISHL I2D DADD ALOAD 9 ALOAD 4 INVOKEDYNAMIC dyn:getElem|getProp|getMethod(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; [ // handle kind 0x6 : INVOKESTATIC jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;) // arguments: 0 ] INVOKEDYNAMIC ADD:ODO_D(DLjava/lang/Object;)Ljava/lang/Object; [ // handle kind 0x6 : INVOKESTATIC jdk/nashorn/internal/runtime/linker/Bootstrap.runtimeBootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;) // arguments: none ] ALOAD 5 INVOKEDYNAMIC ADD:OOO_I(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; [ // handle kind 0x6 : INVOKESTATIC jdk/nashorn/internal/runtime/linker/Bootstrap.runtimeBootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;) // arguments: none ] ASTORE 12 L9 LINENUMBER 20 L9 ALOAD 12 INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toInt32 (Ljava/lang/Object;)I BIPUSH 28 ISHR I2D DLOAD 14 INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toInt32 (D)I BIPUSH 14 ISHR I2D DADD ILOAD 11 I2D ILOAD 13 I2D DMUL DADD INVOKESTATIC java/lang/Double.valueOf (D)Ljava/lang/Double; ASTORE 5 L10 LINENUMBER 21 L10 ALOAD 9 ALOAD 4 INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toNumber (Ljava/lang/Object;)D DUP2 DCONST_1 DADD INVOKESTATIC java/lang/Double.valueOf (D)Ljava/lang/Double; ASTORE 4 ALOAD 12 INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toInt32 (Ljava/lang/Object;)I LDC 268435455 IAND INVOKEDYNAMIC dyn:setElem|setProp(Ljava/lang/Object;DI)V [ // handle kind 0x6 : INVOKESTATIC jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;) // arguments: 0 ] L4 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] [] ALOAD 6 INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toNumber (Ljava/lang/Object;)D LDC -1.0 DADD DUP2 INVOKESTATIC java/lang/Double.valueOf (D)Ljava/lang/Double; ASTORE 6 DCONST_0 DCMPL IFGE L5 L11 LINENUMBER 24 L11 ALOAD 5 ARETURN "Optimistic" bytecode that requires invalidation on e.g overflow. Factor x2-3 speedup: public static am3(Ljava/lang/Object;IILjava/lang/Object;III)I L0 LINENUMBER 12 L0 ALOAD 0 INVOKEDYNAMIC dyn:getProp|getElem|getMethod:array(Ljava/lang/Object;)Ljava/lang/Object; [ // handle kind 0x6 : INVOKESTATIC jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;) // arguments: 0 ] ASTORE 8 L1 LINENUMBER 13 L1 ALOAD 3 INVOKEDYNAMIC dyn:getProp|getElem|getMethod:array(Ljava/lang/Object;)Ljava/lang/Object; [ // handle kind 0x6 : INVOKESTATIC jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;) // arguments: 0 ] ASTORE 9 L2 LINENUMBER 14 L2 ILOAD 2 SIPUSH 16383 IAND ISTORE 10 ILOAD 2 BIPUSH 14 ISHR ISTORE 11 L3 LINENUMBER 15 L3 GOTO L4 L5 LINENUMBER 16 L5 FRAME FULL [java/lang/Object I I java/lang/Object I I I T java/lang/Object java/lang/Object I I] [] ALOAD 8 ILOAD 1 INVOKEDYNAMIC dyn:getElem|getProp|getMethod(Ljava/lang/Object;I)I [ // handle kind 0x6 : INVOKESTATIC jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;) // arguments: 0 ] SIPUSH 16383 IAND ISTORE 12 L6 LINENUMBER 17 L6 ALOAD 8 ILOAD 1 DUP ICONST_1 IADD ISTORE 1 INVOKEDYNAMIC dyn:getElem|getProp|getMethod(Ljava/lang/Object;I)I [ // handle kind 0x6 : INVOKESTATIC jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;) // arguments: 0 ] BIPUSH 14 ISHR ISTORE 13 L7 LINENUMBER 18 L7 ILOAD 11 ILOAD 12 BIPUSH 8 INVOKESTATIC jdk/nashorn/internal/runtime/JSType.mulExact (III)I ILOAD 13 ILOAD 10 BIPUSH 9 INVOKESTATIC jdk/nashorn/internal/runtime/JSType.mulExact (III)I IADD ISTORE 14 L8 LINENUMBER 19 L8 ILOAD 10 ILOAD 12 BIPUSH 11 INVOKESTATIC jdk/nashorn/internal/runtime/JSType.mulExact (III)I ILOAD 14 SIPUSH 16383 IAND BIPUSH 14 ISHL IADD ALOAD 9 ILOAD 4 INVOKEDYNAMIC dyn:getElem|getProp|getMethod(Ljava/lang/Object;I)I [ // handle kind 0x6 : INVOKESTATIC jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;) // arguments: 0 ] IADD ILOAD 5 IADD ISTORE 12 L9 LINENUMBER 20 L9 ILOAD 12 BIPUSH 28 ISHR ILOAD 14 BIPUSH 14 ISHR IADD ILOAD 11 ILOAD 13 BIPUSH 21 INVOKESTATIC jdk/nashorn/internal/runtime/JSType.mulExact (III)I IADD ISTORE 5 L10 LINENUMBER 21 L10 ALOAD 9 ILOAD 4 DUP ICONST_1 IADD ISTORE 4 ILOAD 12 LDC 268435455 IAND INVOKEDYNAMIC dyn:setElem|setProp(Ljava/lang/Object;II)V [ // handle kind 0x6 : INVOKESTATIC jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;) // arguments: 0 ] L4 FRAME SAME ILOAD 6 ICONST_M1 IADD DUP ISTORE 6 ICONST_0 IF_ICMPGE L5 L11 LINENUMBER 24 L11 ILOAD 5 IRETURN SYSTEM PROPERTY: -Dnashorn.codegen.debug, -Dnashorn.codegen.debug.trace=<x> See the description of the codegen logger below. SYSTEM_PROPERTY: -Dnashorn.fields.debug See the description on the fields logger below. SYSTEM PROPERTY: -Dnashorn.fields.dual When this property is true, Nashorn will attempt to use primitive fields for AccessorProperties (currently just AccessorProperties, not spill properties). Memory footprint for script objects will increase, as we need to maintain both a primitive field (a long) as well as an Object field for the property value. 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. While dual fields in theory runs significantly faster than Object fields due to reduction of boxing and memory allocation overhead, there is still work to be done to make this a general purpose solution. Research is ongoing. 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. As long as only primitive values are written to the fields and enough type information exists to make sure that any reads don't have to be uselessly boxed and unboxed, this is significantly faster than the standard "Objects only" approach that currently is the default. See test/examples/dual-fields-micro.js for an example that runs twice as fast with dual fields as without them. Here, the compiler, can determine that we are dealing with numbers only throughout the entire property life span of the properties involved. If a "real" object (not a boxed primitive) is written to a field that has a primitive representation, its callsite is relinked and an Object field is used forevermore for that particular field in that PropertyMap and its children, even if primitives are later assigned to it. As the amount of compile time type information is very small in a dynamic language like JavaScript, it is frequently the case that something has to be treated as an object, because we don't know any better. In reality though, it is often a boxed primitive is stored to an AccessorProperty. The fastest way to handle this soundly is to use a callsite typecheck and avoid blowing the field up to an Object. We never revert object fields to primitives. Ping-pong:ing back and forth between primitive representation and Object representation would cause fatal performance overhead, so this is not an option. For a general application the dual fields approach is still slower than objects only fields in some places, about the same in most cases, and significantly faster in very few. This is due the program using primitives, but we still can't prove it. For example "local_var a = call(); field = a;" may very well write a double to the field, but the compiler dare not guess a double type if field is a local variable, due to bytecode variables being strongly typed and later non interchangeable. To get around this, the entire method would have to be replaced and a continuation retained to restart from. We believe that the next steps we should go through are instead: 1) Implement method specialization based on callsite, as it's quite frequently the case that numbers are passed around, but currently our function nodes just have object types visible to the compiler. For example "var b = 17; func(a,b,17)" is an example where two parameters can be specialized, but the main version of func might also be called from another callsite with func(x,y,"string"). 2) This requires lazy jitting as the functions have to be specialized per callsite. Even though "function square(x) { return x*x }" might look like a trivial function that can always only take doubles, this is not true. Someone might have overridden the valueOf for x so that the toNumber coercion has side effects. To fulfil JavaScript semantics, the coercion has to run twice for both terms of the multiplication even if they are the same object. This means that call site specialization is necessary, not parameter specialization on the form "function square(x) { var xd = (double)x; return xd*xd; }", as one might first think. Generating a method specialization for any variant of a function that we can determine by types at compile time is a combinatorial explosion of byte code (try it e.g. on all the variants of am3 in the Octane benchmark crypto.js). Thus, this needs to be lazy 3) Optimistic callsite writes, something on the form x = y; //x is a field known to be a primitive. y is only an object as far as we can tell turns into try { x = (int)y; } catch (X is not an integer field right now | ClassCastException e) { x = y; } Mini POC shows that this is the key to a lot of dual field performance in seemingly trivial micros where one unknown object, in reality actually a primitive, foils it for us. Very common pattern. Once we are "all primitives", dual fields runs a lot faster than Object fields only. We still have to deal with objects vs primitives for local bytecode slots, possibly through code copying and versioning. The Future: We expect the usefulness of dual fields to increase significantly after the optimistic type system described in the section on integer arithmetic above is implemented. 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 "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. SYSTEM PROPERTY: -Dnashorn.methodhandles.debug, -Dnashorn.methodhandles.debug=create If this property 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). This can be augmented with more information, for example, instance count, by subclassing or further extending the TraceMethodHandleFactory implementation in MethodHandleFactory.java. If the property is specialized with "=create" as its option, instrumentation will be shown for method handles upon creation time rather than at runtime usage. SYSTEM PROPERTY: -Dnashorn.methodhandles.debug.stacktrace This does the same as nashorn.methodhandles.debug, but when enabled also dumps 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. See the description of the codegen logger below for a more verbose description of this option SYSTEM PROPERTY: -Dnashorn.scriptfunction.specialization.disable There are several "fast path" implementations of constructors and functions in the NativeObject classes that, in their original form, take a variable amount of arguments. Said functions are also declared to take Object parameters in their original form, as this is what the JavaScript specification mandates. However, we often know quite a lot more at a callsite of one of these functions. For example, Math.min is called with a fixed number (2) of integer arguments. The overhead of boxing these ints to Objects and folding them into an Object array for the generic varargs Math.min function is an order of magnitude slower than calling a specialized implementation of Math.min that takes two integers. Specialized functions and constructors are identified by the tag @SpecializedFunction and @SpecializedConstructor in the Nashorn code. The linker will link in the most appropriate (narrowest types, right number of types and least number of arguments) specialization if specializations are available. Every ScriptFunction may carry specializations that the linker can choose from. This framework will likely be extended for user defined functions. The compiler can often infer enough parameter type info from callsites for in order to generate simpler versions with less generic Object types. This feature depends on future lazy jitting, as there tend to be many calls to user defined functions, some where the callsite can be specialized, some where we mostly see object parameters even at the callsite. If this system property is set to true, the linker will not attempt to use any specialized function or constructor for native objects, but just call the generic one. 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.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.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. Here is an example: [JavaScript Parsing] 61 ms [Constant Folding] 11 ms [Control Flow Lowering] 26 ms [Type Attribution] 81 ms [Range Analysis] 0 ms [Code Splitting] 29 ms [Type Finalization] 19 ms [Bytecode Generation] 189 ms [Code Installation] 7 ms Total runtime: 508 ms (Non-runtime: 423 ms [83%]) =============== 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>[: Other Java examples (source code examples)Here is a short list of links related to this Java DEVELOPER_README source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.