aboutsummaryrefslogtreecommitdiff
path: root/docs/DEVELOPER_README
blob: 9a2fffdf84afa6eb14df4822cc6c750b736807c9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
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.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>[:<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 subsystems that currently support logging are:


* 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


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


* attr

The lowering annotates a FunctionNode with symbols for each identifier
and transforms high level constructs into lower level ones, that the
CodeGenerator consumes.

Lower logging typically outputs things like post pass actions,
insertions of casts because symbol types have been changed and type
specialization information. Currently very little info is generated by
this logger. This will probably change.


* finalize

This --log=finalize log option outputs information for type finalization,
the third tier of the compiler. This means things like placement of 
specialized scope nodes or explicit conversions. 


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


=======================
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 script without running. Exit after compilation)
		param: [true|false]   default: false

	-d, --dump-debug-dir (specify a destination directory to dump class files. 
                This must be combined with the --compile-only option to work)
		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

	--lazy-compilation (EXPERIMENTAL: Use lazy code generation strategies - do not compile 
	                   the entire script at once.)
		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 (No Java support)
		param: [true|false]   default: false

	-nse, --no-syntax-extensions (No non-standard syntax extensions)
		param: [true|false]   default: false

	-nta, --no-typed-arrays (No 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

	--print-code (Print bytecode.)
		param: [true|false]   default: false

	--print-lower-ast (Print lowered abstract syntax tree.)
		param: [true|false]   default: false

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

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

	--range-analysis (EXPERIMENTAL: Do range analysis using known compile time types, 
	                 and try to narrow number types)
		param: [true|false]   default: false

	-scripting (Enable scripting features.)
		param: [true|false]   default: false

	--specialize-calls (EXPERIMENTAL: Specialize all or a set of method according
	                    to callsite parameter types)
		param: [=function_1,...,function_n]   

	--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,]*]   

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