changeset 1540:2b6631f44d56

Merge
author duke
date Wed, 05 Jul 2017 16:43:41 +0200
parents 5db12b3a75ea 46e3f057badf
children 3c53424bbe3b
files
diffstat 184 files changed, 4699 insertions(+), 1471 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags-top-repo	Fri Nov 07 11:45:49 2008 -0800
+++ b/.hgtags-top-repo	Wed Jul 05 16:43:41 2017 +0200
@@ -13,3 +13,4 @@
 4b4f5fea8d7d0743f0c30d91fcd9bf9d96e5d2ad jdk7-b36
 744554f5a3290e11c71cd2ddb1aff49e431f9ed0 jdk7-b37
 cc47a76899ed33a2c513cb688348244c9b5a1288 jdk7-b38
+ab523b49de1fc73fefe6855ce1e0349bdbd7af29 jdk7-b39
--- a/corba/.hgtags	Fri Nov 07 11:45:49 2008 -0800
+++ b/corba/.hgtags	Wed Jul 05 16:43:41 2017 +0200
@@ -13,3 +13,4 @@
 0723891eb8d1c27e67c54163af0b4cea05a4e036 jdk7-b36
 59d5848bdedebe91cc2753acce78911bcb4a66db jdk7-b37
 08be802754b0296c91a7713b6d85a015dbcd5349 jdk7-b38
+55078b6661e286e90387d1d9950bd865f5cc436e jdk7-b39
--- a/hotspot/.hgtags	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/.hgtags	Wed Jul 05 16:43:41 2017 +0200
@@ -13,3 +13,4 @@
 e91159f921a58af3698e6479ea1fc5818da66d09 jdk7-b36
 9ee9cf798b59e7d51f8c0a686959f313867a55d6 jdk7-b37
 d9bc824aa078573829bb66572af847e26e1bd12e jdk7-b38
+49ca90d77f34571b0757ebfcb8a7848ef2696b88 jdk7-b39
--- a/hotspot/make/hotspot_version	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/make/hotspot_version	Wed Jul 05 16:43:41 2017 +0200
@@ -35,7 +35,7 @@
 
 HS_MAJOR_VER=14
 HS_MINOR_VER=0
-HS_BUILD_NUMBER=06
+HS_BUILD_NUMBER=07
 
 JDK_MAJOR_VER=1
 JDK_MINOR_VER=7
--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.cpp	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.cpp	Wed Jul 05 16:43:41 2017 +0200
@@ -2615,7 +2615,8 @@
   }
 }
 
-void MacroAssembler::biased_locking_enter(Register obj_reg, Register mark_reg, Register temp_reg,
+void MacroAssembler::biased_locking_enter(Register obj_reg, Register mark_reg,
+                                          Register temp_reg,
                                           Label& done, Label* slow_case,
                                           BiasedLockingCounters* counters) {
   assert(UseBiasedLocking, "why call this otherwise?");
@@ -2691,8 +2692,7 @@
                   markOopDesc::biased_lock_mask_in_place | markOopDesc::age_mask_in_place | markOopDesc::epoch_mask_in_place,
                   mark_reg);
   or3(G2_thread, mark_reg, temp_reg);
-  casx_under_lock(mark_addr.base(), mark_reg, temp_reg,
-                  (address)StubRoutines::Sparc::atomic_memory_operation_lock_addr());
+  casn(mark_addr.base(), mark_reg, temp_reg);
   // If the biasing toward our thread failed, this means that
   // another thread succeeded in biasing it toward itself and we
   // need to revoke that bias. The revocation will occur in the
@@ -2721,8 +2721,7 @@
   load_klass(obj_reg, temp_reg);
   ld_ptr(Address(temp_reg, 0, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()), temp_reg);
   or3(G2_thread, temp_reg, temp_reg);
-  casx_under_lock(mark_addr.base(), mark_reg, temp_reg,
-                  (address)StubRoutines::Sparc::atomic_memory_operation_lock_addr());
+  casn(mark_addr.base(), mark_reg, temp_reg);
   // If the biasing toward our thread failed, this means that
   // another thread succeeded in biasing it toward itself and we
   // need to revoke that bias. The revocation will occur in the
@@ -2752,8 +2751,7 @@
   // bits in this situation. Should attempt to preserve them.
   load_klass(obj_reg, temp_reg);
   ld_ptr(Address(temp_reg, 0, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()), temp_reg);
-  casx_under_lock(mark_addr.base(), mark_reg, temp_reg,
-                  (address)StubRoutines::Sparc::atomic_memory_operation_lock_addr());
+  casn(mark_addr.base(), mark_reg, temp_reg);
   // Fall through to the normal CAS-based lock, because no matter what
   // the result of the above CAS, some thread must have succeeded in
   // removing the bias bit from the object's header.
@@ -2815,8 +2813,10 @@
 // effect).
 
 
-void MacroAssembler::compiler_lock_object(Register Roop, Register Rmark, Register Rbox, Register Rscratch,
-                                          BiasedLockingCounters* counters) {
+void MacroAssembler::compiler_lock_object(Register Roop, Register Rmark,
+                                          Register Rbox, Register Rscratch,
+                                          BiasedLockingCounters* counters,
+                                          bool try_bias) {
    Address mark_addr(Roop, 0, oopDesc::mark_offset_in_bytes());
 
    verify_oop(Roop);
@@ -2838,7 +2838,7 @@
      // Fetch object's markword
      ld_ptr(mark_addr, Rmark);
 
-     if (UseBiasedLocking) {
+     if (try_bias) {
         biased_locking_enter(Roop, Rmark, Rscratch, done, NULL, counters);
      }
 
@@ -2881,7 +2881,7 @@
 
       ld_ptr (mark_addr, Rmark);           // fetch obj->mark
       // Triage: biased, stack-locked, neutral, inflated
-      if (UseBiasedLocking) {
+      if (try_bias) {
         biased_locking_enter(Roop, Rmark, Rscratch, done, NULL, counters);
         // Invariant: if control reaches this point in the emitted stream
         // then Rmark has not been modified.
@@ -2945,7 +2945,7 @@
       ld_ptr (mark_addr, Rmark);           // fetch obj->mark
       // Triage: biased, stack-locked, neutral, inflated
 
-      if (UseBiasedLocking) {
+      if (try_bias) {
         biased_locking_enter(Roop, Rmark, Rscratch, done, NULL, counters);
         // Invariant: if control reaches this point in the emitted stream
         // then Rmark has not been modified.
@@ -3039,7 +3039,9 @@
    bind   (done) ;
 }
 
-void MacroAssembler::compiler_unlock_object(Register Roop, Register Rmark, Register Rbox, Register Rscratch) {
+void MacroAssembler::compiler_unlock_object(Register Roop, Register Rmark,
+                                            Register Rbox, Register Rscratch,
+                                            bool try_bias) {
    Address mark_addr(Roop, 0, oopDesc::mark_offset_in_bytes());
 
    Label done ;
@@ -3050,7 +3052,7 @@
    }
 
    if (EmitSync & 8) {
-     if (UseBiasedLocking) {
+     if (try_bias) {
         biased_locking_exit(mark_addr, Rscratch, done);
      }
 
@@ -3077,7 +3079,7 @@
    // I$ effects.
    Label LStacked ;
 
-   if (UseBiasedLocking) {
+   if (try_bias) {
       // TODO: eliminate redundant LDs of obj->mark
       biased_locking_exit(mark_addr, Rscratch, done);
    }
--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp	Wed Jul 05 16:43:41 2017 +0200
@@ -2220,9 +2220,13 @@
 
   // These set the icc condition code to equal if the lock succeeded
   // and notEqual if it failed and requires a slow case
-  void compiler_lock_object(Register Roop, Register Rmark, Register Rbox, Register Rscratch,
-                              BiasedLockingCounters* counters = NULL);
-  void compiler_unlock_object(Register Roop, Register Rmark, Register Rbox, Register Rscratch);
+  void compiler_lock_object(Register Roop, Register Rmark, Register Rbox,
+                            Register Rscratch,
+                            BiasedLockingCounters* counters = NULL,
+                            bool try_bias = UseBiasedLocking);
+  void compiler_unlock_object(Register Roop, Register Rmark, Register Rbox,
+                              Register Rscratch,
+                              bool try_bias = UseBiasedLocking);
 
   // Biased locking support
   // Upon entry, lock_reg must point to the lock record on the stack,
--- a/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp	Wed Jul 05 16:43:41 2017 +0200
@@ -906,7 +906,7 @@
 
   // load next super to check
   if (UseCompressedOops) {
-    ld( Rtmp2, arrayOopDesc::base_offset_in_bytes(T_OBJECT), Rtmp3);
+    lduw( Rtmp2, arrayOopDesc::base_offset_in_bytes(T_OBJECT), Rtmp3);
     // Bump array pointer forward one oop
     add( Rtmp2, 4, Rtmp2 );
   } else {
--- a/hotspot/src/cpu/sparc/vm/sparc.ad	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/cpu/sparc/vm/sparc.ad	Wed Jul 05 16:43:41 2017 +0200
@@ -395,6 +395,7 @@
                   );
 
 reg_class g1_regL(R_G1H,R_G1);
+reg_class g3_regL(R_G3H,R_G3);
 reg_class o2_regL(R_O2H,R_O2);
 reg_class o7_regL(R_O7H,R_O7);
 
@@ -1743,7 +1744,7 @@
 //
 // NOTE: If the platform does not provide any short branch variants, then
 //       this method should return false for offset 0.
-bool Matcher::is_short_branch_offset(int offset) {
+bool Matcher::is_short_branch_offset(int rule, int offset) {
   return false;
 }
 
@@ -1926,18 +1927,23 @@
                        $mem$$base, $mem$$disp, $mem$$index, $dst$$reg);
   %}
 
+  enc_class simple_form3_mem_reg( memory mem, iRegI dst ) %{
+    emit_form3_mem_reg(cbuf, this, $primary, -1,
+                       $mem$$base, $mem$$disp, $mem$$index, $dst$$reg);
+  %}
+
   enc_class form3_mem_reg_little( memory mem, iRegI dst) %{
-    emit_form3_mem_reg_asi(cbuf, this, $primary, $tertiary,
+    emit_form3_mem_reg_asi(cbuf, this, $primary, -1,
                      $mem$$base, $mem$$disp, $mem$$index, $dst$$reg, Assembler::ASI_PRIMARY_LITTLE);
   %}
 
   enc_class form3_mem_prefetch_read( memory mem ) %{
-    emit_form3_mem_reg(cbuf, this, $primary, $tertiary,
+    emit_form3_mem_reg(cbuf, this, $primary, -1,
                        $mem$$base, $mem$$disp, $mem$$index, 0/*prefetch function many-reads*/);
   %}
 
   enc_class form3_mem_prefetch_write( memory mem ) %{
-    emit_form3_mem_reg(cbuf, this, $primary, $tertiary,
+    emit_form3_mem_reg(cbuf, this, $primary, -1,
                        $mem$$base, $mem$$disp, $mem$$index, 2/*prefetch function many-writes*/);
   %}
 
@@ -1945,8 +1951,8 @@
     assert( Assembler::is_simm13($mem$$disp  ), "need disp and disp+4" );
     assert( Assembler::is_simm13($mem$$disp+4), "need disp and disp+4" );
     guarantee($mem$$index == R_G0_enc, "double index?");
-    emit_form3_mem_reg(cbuf, this, $primary, $tertiary, $mem$$base, $mem$$disp+4, R_G0_enc, R_O7_enc );
-    emit_form3_mem_reg(cbuf, this, $primary, $tertiary, $mem$$base, $mem$$disp,   R_G0_enc, $reg$$reg );
+    emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp+4, R_G0_enc, R_O7_enc );
+    emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp,   R_G0_enc, $reg$$reg );
     emit3_simm13( cbuf, Assembler::arith_op, $reg$$reg, Assembler::sllx_op3, $reg$$reg, 0x1020 );
     emit3( cbuf, Assembler::arith_op, $reg$$reg, Assembler::or_op3, $reg$$reg, 0, R_O7_enc );
   %}
@@ -1956,14 +1962,14 @@
     assert( Assembler::is_simm13($mem$$disp+4), "need disp and disp+4" );
     guarantee($mem$$index == R_G0_enc, "double index?");
     // Load long with 2 instructions
-    emit_form3_mem_reg(cbuf, this, $primary, $tertiary, $mem$$base, $mem$$disp,   R_G0_enc, $reg$$reg+0 );
-    emit_form3_mem_reg(cbuf, this, $primary, $tertiary, $mem$$base, $mem$$disp+4, R_G0_enc, $reg$$reg+1 );
+    emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp,   R_G0_enc, $reg$$reg+0 );
+    emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp+4, R_G0_enc, $reg$$reg+1 );
   %}
 
   //%%% form3_mem_plus_4_reg is a hack--get rid of it
   enc_class form3_mem_plus_4_reg( memory mem, iRegI dst ) %{
     guarantee($mem$$disp, "cannot offset a reg-reg operand by 4");
-    emit_form3_mem_reg(cbuf, this, $primary, $tertiary, $mem$$base, $mem$$disp + 4, $mem$$index, $dst$$reg);
+    emit_form3_mem_reg(cbuf, this, $primary, -1, $mem$$base, $mem$$disp + 4, $mem$$index, $dst$$reg);
   %}
 
   enc_class form3_g0_rs2_rd_move( iRegI rs2, iRegI rd ) %{
@@ -2683,7 +2689,7 @@
     assert(Rbox  != Rscratch, "");
     assert(Rbox  != Rmark, "");
 
-    __ compiler_lock_object(Roop, Rmark, Rbox, Rscratch, _counters);
+    __ compiler_lock_object(Roop, Rmark, Rbox, Rscratch, _counters, UseBiasedLocking && !UseOptoBiasInlining);
 %}
 
 enc_class Fast_Unlock(iRegP oop, iRegP box, o7RegP scratch, iRegP scratch2) %{
@@ -2699,7 +2705,7 @@
     assert(Rbox  != Rscratch, "");
     assert(Rbox  != Rmark, "");
 
-    __ compiler_unlock_object(Roop, Rmark, Rbox, Rscratch);
+    __ compiler_unlock_object(Roop, Rmark, Rbox, Rscratch, UseBiasedLocking && !UseOptoBiasInlining);
   %}
 
   enc_class enc_cas( iRegP mem, iRegP old, iRegP new ) %{
@@ -2711,8 +2717,7 @@
     // casx_under_lock picks 1 of 3 encodings:
     // For 32-bit pointers you get a 32-bit CAS
     // For 64-bit pointers you get a 64-bit CASX
-    __ casx_under_lock(Rmem, Rold, Rnew, // Swap(*Rmem,Rnew) if *Rmem == Rold
-                        (address) StubRoutines::Sparc::atomic_memory_operation_lock_addr());
+    __ casn(Rmem, Rold, Rnew); // Swap(*Rmem,Rnew) if *Rmem == Rold
     __ cmp( Rold, Rnew );
   %}
 
@@ -3761,6 +3766,14 @@
   interface(REG_INTER);
 %}
 
+operand g3RegL() %{
+  constraint(ALLOC_IN_RC(g3_regL));
+  match(iRegL);
+
+  format %{ %}
+  interface(REG_INTER);
+%}
+
 // Int Register safe
 // This is 64bit safe
 operand iRegIsafe() %{
@@ -5062,7 +5075,7 @@
   size(4);
   format %{ "LDF    $src,$dst\t! stkI to regF" %}
   opcode(Assembler::ldf_op3);
-  ins_encode(form3_mem_reg(src, dst));
+  ins_encode(simple_form3_mem_reg(src, dst));
   ins_pipe(floadF_stk);
 %}
 
@@ -5073,7 +5086,7 @@
   size(4);
   format %{ "LDDF   $src,$dst\t! stkL to regD" %}
   opcode(Assembler::lddf_op3);
-  ins_encode(form3_mem_reg(src, dst));
+  ins_encode(simple_form3_mem_reg(src, dst));
   ins_pipe(floadD_stk);
 %}
 
@@ -5084,7 +5097,7 @@
   size(4);
   format %{ "STF    $src,$dst\t! regF to stkI" %}
   opcode(Assembler::stf_op3);
-  ins_encode(form3_mem_reg(dst, src));
+  ins_encode(simple_form3_mem_reg(dst, src));
   ins_pipe(fstoreF_stk_reg);
 %}
 
@@ -5095,7 +5108,7 @@
   size(4);
   format %{ "STDF   $src,$dst\t! regD to stkL" %}
   opcode(Assembler::stdf_op3);
-  ins_encode(form3_mem_reg(dst, src));
+  ins_encode(simple_form3_mem_reg(dst, src));
   ins_pipe(fstoreD_stk_reg);
 %}
 
@@ -5106,7 +5119,7 @@
   format %{ "STW    $src,$dst.hi\t! long\n\t"
             "STW    R_G0,$dst.lo" %}
   opcode(Assembler::stw_op3);
-  ins_encode(form3_mem_reg(dst, src), form3_mem_plus_4_reg(dst, R_G0));
+  ins_encode(simple_form3_mem_reg(dst, src), form3_mem_plus_4_reg(dst, R_G0));
   ins_pipe(lstoreI_stk_reg);
 %}
 
@@ -5117,7 +5130,7 @@
   size(4);
   format %{ "STX    $src,$dst\t! regL to stkD" %}
   opcode(Assembler::stx_op3);
-  ins_encode( form3_mem_reg( dst, src ) );
+  ins_encode(simple_form3_mem_reg( dst, src ) );
   ins_pipe(istore_stk_reg);
 %}
 
@@ -5131,7 +5144,7 @@
   size(4);
   format %{ "LDUW   $src,$dst\t!stk" %}
   opcode(Assembler::lduw_op3);
-  ins_encode( form3_mem_reg( src, dst ) );
+  ins_encode(simple_form3_mem_reg( src, dst ) );
   ins_pipe(iload_mem);
 %}
 
@@ -5143,7 +5156,7 @@
   size(4);
   format %{ "STW    $src,$dst\t!stk" %}
   opcode(Assembler::stw_op3);
-  ins_encode( form3_mem_reg( dst, src ) );
+  ins_encode(simple_form3_mem_reg( dst, src ) );
   ins_pipe(istore_mem_reg);
 %}
 
@@ -5155,7 +5168,7 @@
   size(4);
   format %{ "LDX    $src,$dst\t! long" %}
   opcode(Assembler::ldx_op3);
-  ins_encode( form3_mem_reg( src, dst ) );
+  ins_encode(simple_form3_mem_reg( src, dst ) );
   ins_pipe(iload_mem);
 %}
 
@@ -5167,7 +5180,7 @@
   size(4);
   format %{ "STX    $src,$dst\t! long" %}
   opcode(Assembler::stx_op3);
-  ins_encode( form3_mem_reg( dst, src ) );
+  ins_encode(simple_form3_mem_reg( dst, src ) );
   ins_pipe(istore_mem_reg);
 %}
 
@@ -5179,7 +5192,7 @@
   size(4);
   format %{ "LDX    $src,$dst\t!ptr" %}
   opcode(Assembler::ldx_op3);
-  ins_encode( form3_mem_reg( src, dst ) );
+  ins_encode(simple_form3_mem_reg( src, dst ) );
   ins_pipe(iload_mem);
 %}
 
@@ -5190,7 +5203,7 @@
   size(4);
   format %{ "STX    $src,$dst\t!ptr" %}
   opcode(Assembler::stx_op3);
-  ins_encode( form3_mem_reg( dst, src ) );
+  ins_encode(simple_form3_mem_reg( dst, src ) );
   ins_pipe(istore_mem_reg);
 %}
 #else // _LP64
@@ -5200,7 +5213,7 @@
   ins_cost(MEMORY_REF_COST);
   format %{ "LDUW   $src,$dst\t!ptr" %}
   opcode(Assembler::lduw_op3, Assembler::ldst_op);
-  ins_encode( form3_mem_reg( src, dst ) );
+  ins_encode(simple_form3_mem_reg( src, dst ) );
   ins_pipe(iload_mem);
 %}
 
@@ -5210,7 +5223,7 @@
   ins_cost(MEMORY_REF_COST);
   format %{ "STW    $src,$dst\t!ptr" %}
   opcode(Assembler::stw_op3, Assembler::ldst_op);
-  ins_encode( form3_mem_reg( dst, src ) );
+  ins_encode(simple_form3_mem_reg( dst, src ) );
   ins_pipe(istore_mem_reg);
 %}
 #endif // _LP64
@@ -5273,7 +5286,7 @@
   size(4);
   format %{ "LDSB   $mem,$dst" %}
   opcode(Assembler::ldsb_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(iload_mask_mem);
 %}
 
@@ -5285,7 +5298,7 @@
   size(4);
   format %{ "LDUB   $mem,$dst" %}
   opcode(Assembler::ldub_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(iload_mask_mem);
 %}
 
@@ -5297,7 +5310,7 @@
   size(4);
   format %{ "LDUB   $mem,$dst" %}
   opcode(Assembler::ldub_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(iload_mask_mem);
 %}
 
@@ -5309,7 +5322,7 @@
   size(4);
   format %{ "LDUH   $mem,$dst" %}
   opcode(Assembler::lduh_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(iload_mask_mem);
 %}
 
@@ -5321,7 +5334,7 @@
   size(4);
   format %{ "LDUH   $mem,$dst" %}
   opcode(Assembler::lduh_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(iload_mask_mem);
 %}
 
@@ -5333,7 +5346,7 @@
 
   format %{ "LDUW   $mem,$dst" %}
   opcode(Assembler::lduw_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(iload_mem);
 %}
 
@@ -5344,7 +5357,7 @@
   size(4);
   format %{ "LDX    $mem,$dst\t! long" %}
   opcode(Assembler::ldx_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(iload_mem);
 %}
 
@@ -5359,7 +5372,7 @@
           "\tSLLX   #32, $dst, $dst\n"
           "\tOR     $dst, R_O7, $dst" %}
   opcode(Assembler::lduw_op3);
-  ins_encode( form3_mem_reg_long_unaligned_marshal( mem, dst ));
+  ins_encode(form3_mem_reg_long_unaligned_marshal( mem, dst ));
   ins_pipe(iload_mem);
 %}
 
@@ -5370,7 +5383,7 @@
   size(4);
   format %{ "LDDF   $mem,$dst\t! packed8B" %}
   opcode(Assembler::lddf_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(floadD_mem);
 %}
 
@@ -5381,7 +5394,7 @@
   size(4);
   format %{ "LDDF   $mem,$dst\t! packed4C" %}
   opcode(Assembler::lddf_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(floadD_mem);
 %}
 
@@ -5392,7 +5405,7 @@
   size(4);
   format %{ "LDDF   $mem,$dst\t! packed4S" %}
   opcode(Assembler::lddf_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(floadD_mem);
 %}
 
@@ -5403,7 +5416,7 @@
   size(4);
   format %{ "LDDF   $mem,$dst\t! packed2I" %}
   opcode(Assembler::lddf_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(floadD_mem);
 %}
 
@@ -5415,7 +5428,7 @@
   size(4);
   format %{ "LDUW   $mem,$dst\t! range" %}
   opcode(Assembler::lduw_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(iload_mem);
 %}
 
@@ -5427,7 +5440,7 @@
 
   format %{ "LDF    $mem,$dst\t! for fitos/fitod" %}
   opcode(Assembler::ldf_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(floadF_mem);
 %}
 
@@ -5514,7 +5527,7 @@
   size(4);
   format %{ "LDSH   $mem,$dst" %}
   opcode(Assembler::ldsh_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(iload_mask_mem);
 %}
 
@@ -5526,7 +5539,7 @@
   size(4);
   format %{ "LDDF   $mem,$dst" %}
   opcode(Assembler::lddf_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(floadD_mem);
 %}
 
@@ -5550,7 +5563,7 @@
   size(4);
   format %{ "LDF    $mem,$dst" %}
   opcode(Assembler::ldf_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(floadF_mem);
 %}
 
@@ -5719,7 +5732,7 @@
   size(4);
   format %{ "STB    $src,$mem\t! byte" %}
   opcode(Assembler::stb_op3);
-  ins_encode( form3_mem_reg( mem, src ) );
+  ins_encode(simple_form3_mem_reg( mem, src ) );
   ins_pipe(istore_mem_reg);
 %}
 
@@ -5730,7 +5743,7 @@
   size(4);
   format %{ "STB    $src,$mem\t! byte" %}
   opcode(Assembler::stb_op3);
-  ins_encode( form3_mem_reg( mem, R_G0 ) );
+  ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
   ins_pipe(istore_mem_zero);
 %}
 
@@ -5741,7 +5754,7 @@
   size(4);
   format %{ "STB    $src,$mem\t! CMS card-mark byte 0" %}
   opcode(Assembler::stb_op3);
-  ins_encode( form3_mem_reg( mem, R_G0 ) );
+  ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
   ins_pipe(istore_mem_zero);
 %}
 
@@ -5753,7 +5766,7 @@
   size(4);
   format %{ "STH    $src,$mem\t! short" %}
   opcode(Assembler::sth_op3);
-  ins_encode( form3_mem_reg( mem, src ) );
+  ins_encode(simple_form3_mem_reg( mem, src ) );
   ins_pipe(istore_mem_reg);
 %}
 
@@ -5764,7 +5777,7 @@
   size(4);
   format %{ "STH    $src,$mem\t! short" %}
   opcode(Assembler::sth_op3);
-  ins_encode( form3_mem_reg( mem, R_G0 ) );
+  ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
   ins_pipe(istore_mem_zero);
 %}
 
@@ -5776,7 +5789,7 @@
   size(4);
   format %{ "STW    $src,$mem" %}
   opcode(Assembler::stw_op3);
-  ins_encode( form3_mem_reg( mem, src ) );
+  ins_encode(simple_form3_mem_reg( mem, src ) );
   ins_pipe(istore_mem_reg);
 %}
 
@@ -5787,7 +5800,7 @@
   size(4);
   format %{ "STX    $src,$mem\t! long" %}
   opcode(Assembler::stx_op3);
-  ins_encode( form3_mem_reg( mem, src ) );
+  ins_encode(simple_form3_mem_reg( mem, src ) );
   ins_pipe(istore_mem_reg);
 %}
 
@@ -5798,7 +5811,7 @@
   size(4);
   format %{ "STW    $src,$mem" %}
   opcode(Assembler::stw_op3);
-  ins_encode( form3_mem_reg( mem, R_G0 ) );
+  ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
   ins_pipe(istore_mem_zero);
 %}
 
@@ -5809,7 +5822,7 @@
   size(4);
   format %{ "STX    $src,$mem" %}
   opcode(Assembler::stx_op3);
-  ins_encode( form3_mem_reg( mem, R_G0 ) );
+  ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
   ins_pipe(istore_mem_zero);
 %}
 
@@ -5821,7 +5834,7 @@
   size(4);
   format %{ "STF    $src,$mem\t! after fstoi/fdtoi" %}
   opcode(Assembler::stf_op3);
-  ins_encode( form3_mem_reg( mem, src ) );
+  ins_encode(simple_form3_mem_reg( mem, src ) );
   ins_pipe(fstoreF_mem_reg);
 %}
 
@@ -5904,7 +5917,7 @@
   size(4);
   format %{ "STDF   $src,$mem" %}
   opcode(Assembler::stdf_op3);
-  ins_encode( form3_mem_reg( mem, src ) );
+  ins_encode(simple_form3_mem_reg( mem, src ) );
   ins_pipe(fstoreD_mem_reg);
 %}
 
@@ -5915,7 +5928,7 @@
   size(4);
   format %{ "STX    $src,$mem" %}
   opcode(Assembler::stx_op3);
-  ins_encode( form3_mem_reg( mem, R_G0 ) );
+  ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
   ins_pipe(fstoreD_mem_zero);
 %}
 
@@ -5927,7 +5940,7 @@
   size(4);
   format %{ "STF    $src,$mem" %}
   opcode(Assembler::stf_op3);
-  ins_encode( form3_mem_reg( mem, src ) );
+  ins_encode(simple_form3_mem_reg( mem, src ) );
   ins_pipe(fstoreF_mem_reg);
 %}
 
@@ -5938,7 +5951,7 @@
   size(4);
   format %{ "STW    $src,$mem\t! storeF0" %}
   opcode(Assembler::stw_op3);
-  ins_encode( form3_mem_reg( mem, R_G0 ) );
+  ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
   ins_pipe(fstoreF_mem_zero);
 %}
 
@@ -5949,7 +5962,7 @@
   size(4);
   format %{ "STDF   $src,$mem\t! packed8B" %}
   opcode(Assembler::stdf_op3);
-  ins_encode( form3_mem_reg( mem, src ) );
+  ins_encode(simple_form3_mem_reg( mem, src ) );
   ins_pipe(fstoreD_mem_reg);
 %}
 
@@ -6004,7 +6017,7 @@
   size(4);
   format %{ "STX    $zero,$mem\t! packed8B" %}
   opcode(Assembler::stx_op3);
-  ins_encode( form3_mem_reg( mem, R_G0 ) );
+  ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
   ins_pipe(fstoreD_mem_zero);
 %}
 
@@ -6015,7 +6028,7 @@
   size(4);
   format %{ "STDF   $src,$mem\t! packed4C" %}
   opcode(Assembler::stdf_op3);
-  ins_encode( form3_mem_reg( mem, src ) );
+  ins_encode(simple_form3_mem_reg( mem, src ) );
   ins_pipe(fstoreD_mem_reg);
 %}
 
@@ -6026,7 +6039,7 @@
   size(4);
   format %{ "STX    $zero,$mem\t! packed4C" %}
   opcode(Assembler::stx_op3);
-  ins_encode( form3_mem_reg( mem, R_G0 ) );
+  ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
   ins_pipe(fstoreD_mem_zero);
 %}
 
@@ -6037,7 +6050,7 @@
   size(4);
   format %{ "STDF   $src,$mem\t! packed2I" %}
   opcode(Assembler::stdf_op3);
-  ins_encode( form3_mem_reg( mem, src ) );
+  ins_encode(simple_form3_mem_reg( mem, src ) );
   ins_pipe(fstoreD_mem_reg);
 %}
 
@@ -6048,7 +6061,7 @@
   size(4);
   format %{ "STX    $zero,$mem\t! packed2I" %}
   opcode(Assembler::stx_op3);
-  ins_encode( form3_mem_reg( mem, R_G0 ) );
+  ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
   ins_pipe(fstoreD_mem_zero);
 %}
 
@@ -6162,7 +6175,7 @@
   ins_cost(MEMORY_REF_COST);
   format %{ "STDF   $src,$stkSlot\t!stk" %}
   opcode(Assembler::stdf_op3);
-  ins_encode(form3_mem_reg(stkSlot, src));
+  ins_encode(simple_form3_mem_reg(stkSlot, src));
   ins_pipe(fstoreD_stk_reg);
 %}
 
@@ -6172,7 +6185,7 @@
   ins_cost(MEMORY_REF_COST);
   format %{ "LDDF   $stkSlot,$dst\t!stk" %}
   opcode(Assembler::lddf_op3);
-  ins_encode(form3_mem_reg(stkSlot, dst));
+  ins_encode(simple_form3_mem_reg(stkSlot, dst));
   ins_pipe(floadD_stk);
 %}
 
@@ -6182,7 +6195,7 @@
   ins_cost(MEMORY_REF_COST);
   format %{ "STF   $src,$stkSlot\t!stk" %}
   opcode(Assembler::stf_op3);
-  ins_encode(form3_mem_reg(stkSlot, src));
+  ins_encode(simple_form3_mem_reg(stkSlot, src));
   ins_pipe(fstoreF_stk_reg);
 %}
 
@@ -6584,7 +6597,7 @@
   size(4);
   format %{ "LDX    $mem,$dst\t! long" %}
   opcode(Assembler::ldx_op3);
-  ins_encode( form3_mem_reg( mem, dst ) );
+  ins_encode(simple_form3_mem_reg( mem, dst ) );
   ins_pipe(iload_mem);
 %}
 
@@ -6597,32 +6610,23 @@
   ins_pipe( long_memory_op );
 %}
 
-instruct storeLConditional_bool(iRegP mem_ptr, iRegL oldval, iRegL newval, iRegI res, o7RegI tmp1, flagsReg ccr ) %{
-  match(Set res (StoreLConditional mem_ptr (Binary oldval newval)));
-  effect( USE mem_ptr, KILL ccr, KILL tmp1);
-  // Marshal the register pairs into V9 64-bit registers, then do the compare-and-swap
-  format %{
-            "MOV    $newval,R_O7\n\t"
-            "CASXA  [$mem_ptr],$oldval,R_O7\t! If $oldval==[$mem_ptr] Then store R_O7 into [$mem_ptr], set R_O7=[$mem_ptr] in any case\n\t"
-            "CMP    $oldval,R_O7\t\t! See if we made progress\n\t"
-            "MOV    1,$res\n\t"
-            "MOVne  xcc,R_G0,$res"
-  %}
-  ins_encode( enc_casx(mem_ptr, oldval, newval),
-              enc_lflags_ne_to_boolean(res) );
+// Conditional-store of an int value.
+instruct storeIConditional( iRegP mem_ptr, iRegI oldval, g3RegI newval, flagsReg icc ) %{
+  match(Set icc (StoreIConditional mem_ptr (Binary oldval newval)));
+  effect( KILL newval );
+  format %{ "CASA   [$mem_ptr],$oldval,$newval\t! If $oldval==[$mem_ptr] Then store $newval into [$mem_ptr], set $newval=[$mem_ptr] in any case\n\t"
+            "CMP    $oldval,$newval\t\t! See if we made progress"  %}
+  ins_encode( enc_cas(mem_ptr,oldval,newval) );
   ins_pipe( long_memory_op );
 %}
 
-instruct storeLConditional_flags(iRegP mem_ptr, iRegL oldval, iRegL newval, flagsRegL xcc, o7RegI tmp1, immI0 zero) %{
-  match(Set xcc (CmpI (StoreLConditional mem_ptr (Binary oldval newval)) zero));
-  effect( USE mem_ptr, KILL tmp1);
-  // Marshal the register pairs into V9 64-bit registers, then do the compare-and-swap
-  format %{
-            "MOV    $newval,R_O7\n\t"
-            "CASXA  [$mem_ptr],$oldval,R_O7\t! If $oldval==[$mem_ptr] Then store R_O7 into [$mem_ptr], set R_O7=[$mem_ptr] in any case\n\t"
-            "CMP    $oldval,R_O7\t\t! See if we made progress"
-  %}
-  ins_encode( enc_casx(mem_ptr, oldval, newval));
+// Conditional-store of a long value.
+instruct storeLConditional( iRegP mem_ptr, iRegL oldval, g3RegL newval, flagsRegL xcc ) %{
+  match(Set xcc (StoreLConditional mem_ptr (Binary oldval newval)));
+  effect( KILL newval );
+  format %{ "CASXA  [$mem_ptr],$oldval,$newval\t! If $oldval==[$mem_ptr] Then store $newval into [$mem_ptr], set $newval=[$mem_ptr] in any case\n\t"
+            "CMP    $oldval,$newval\t\t! See if we made progress"  %}
+  ins_encode( enc_cas(mem_ptr,oldval,newval) );
   ins_pipe( long_memory_op );
 %}
 
@@ -7405,6 +7409,34 @@
   ins_pipe(ialu_reg_imm);
 %}
 
+#ifndef _LP64
+
+// Use sp_ptr_RegP to match G2 (TLS register) without spilling.
+instruct orI_reg_castP2X(iRegI dst, iRegI src1, sp_ptr_RegP src2) %{
+  match(Set dst (OrI src1 (CastP2X src2)));
+
+  size(4);
+  format %{ "OR     $src1,$src2,$dst" %}
+  opcode(Assembler::or_op3, Assembler::arith_op);
+  ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) );
+  ins_pipe(ialu_reg_reg);
+%}
+
+#else
+
+instruct orL_reg_castP2X(iRegL dst, iRegL src1, sp_ptr_RegP src2) %{
+  match(Set dst (OrL src1 (CastP2X src2)));
+
+  ins_cost(DEFAULT_COST);
+  size(4);
+  format %{ "OR     $src1,$src2,$dst\t! long" %}
+  opcode(Assembler::or_op3, Assembler::arith_op);
+  ins_encode( form3_rs1_rs2_rd( src1, src2, dst ) );
+  ins_pipe(ialu_reg_reg);
+%}
+
+#endif
+
 // Xor Instructions
 // Register Xor
 instruct xorI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{
@@ -7666,7 +7698,7 @@
   format %{ "LDF    $mem,$dst\n\t"
             "FITOD  $dst,$dst" %}
   opcode(Assembler::ldf_op3, Assembler::fitod_opf);
-  ins_encode( form3_mem_reg( mem, dst ), form3_convI2F(dst, dst));
+  ins_encode(simple_form3_mem_reg( mem, dst ), form3_convI2F(dst, dst));
   ins_pipe(floadF_mem);
 %}
 
@@ -7696,7 +7728,7 @@
   format %{ "LDF    $mem,$dst\n\t"
             "FITOS  $dst,$dst" %}
   opcode(Assembler::ldf_op3, Assembler::fitos_opf);
-  ins_encode( form3_mem_reg( mem, dst ), form3_convI2F(dst, dst));
+  ins_encode(simple_form3_mem_reg( mem, dst ), form3_convI2F(dst, dst));
   ins_pipe(floadF_mem);
 %}
 
@@ -7738,7 +7770,7 @@
   size(4);
   format %{ "LDUW   $src,$dst\t! MoveF2I" %}
   opcode(Assembler::lduw_op3);
-  ins_encode( form3_mem_reg( src, dst ) );
+  ins_encode(simple_form3_mem_reg( src, dst ) );
   ins_pipe(iload_mem);
 %}
 
@@ -7750,7 +7782,7 @@
   size(4);
   format %{ "LDF    $src,$dst\t! MoveI2F" %}
   opcode(Assembler::ldf_op3);
-  ins_encode(form3_mem_reg(src, dst));
+  ins_encode(simple_form3_mem_reg(src, dst));
   ins_pipe(floadF_stk);
 %}
 
@@ -7762,7 +7794,7 @@
   size(4);
   format %{ "LDX    $src,$dst\t! MoveD2L" %}
   opcode(Assembler::ldx_op3);
-  ins_encode( form3_mem_reg( src, dst ) );
+  ins_encode(simple_form3_mem_reg( src, dst ) );
   ins_pipe(iload_mem);
 %}
 
@@ -7774,7 +7806,7 @@
   size(4);
   format %{ "LDDF   $src,$dst\t! MoveL2D" %}
   opcode(Assembler::lddf_op3);
-  ins_encode(form3_mem_reg(src, dst));
+  ins_encode(simple_form3_mem_reg(src, dst));
   ins_pipe(floadD_stk);
 %}
 
@@ -7786,7 +7818,7 @@
   size(4);
   format %{ "STF   $src,$dst\t!MoveF2I" %}
   opcode(Assembler::stf_op3);
-  ins_encode(form3_mem_reg(dst, src));
+  ins_encode(simple_form3_mem_reg(dst, src));
   ins_pipe(fstoreF_stk_reg);
 %}
 
@@ -7798,7 +7830,7 @@
   size(4);
   format %{ "STW    $src,$dst\t!MoveI2F" %}
   opcode(Assembler::stw_op3);
-  ins_encode( form3_mem_reg( dst, src ) );
+  ins_encode(simple_form3_mem_reg( dst, src ) );
   ins_pipe(istore_mem_reg);
 %}
 
@@ -7810,7 +7842,7 @@
   size(4);
   format %{ "STDF   $src,$dst\t!MoveD2L" %}
   opcode(Assembler::stdf_op3);
-  ins_encode(form3_mem_reg(dst, src));
+  ins_encode(simple_form3_mem_reg(dst, src));
   ins_pipe(fstoreD_stk_reg);
 %}
 
@@ -7822,7 +7854,7 @@
   size(4);
   format %{ "STX    $src,$dst\t!MoveL2D" %}
   opcode(Assembler::stx_op3);
-  ins_encode( form3_mem_reg( dst, src ) );
+  ins_encode(simple_form3_mem_reg( dst, src ) );
   ins_pipe(istore_mem_reg);
 %}
 
--- a/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp	Wed Jul 05 16:43:41 2017 +0200
@@ -956,7 +956,7 @@
     // Load a little early; will load 1 off the end of the array.
     // Ok for now; revisit if we have other uses of this routine.
     if (UseCompressedOops) {
-      __ ld(L1_ary_ptr,0,L2_super);// Will load a little early
+      __ lduw(L1_ary_ptr,0,L2_super);// Will load a little early
     } else {
       __ ld_ptr(L1_ary_ptr,0,L2_super);// Will load a little early
     }
@@ -973,7 +973,7 @@
 #ifdef  _LP64
       __ subcc(L2_super,L4_ooptmp,Rret);   // Check for match; zero in Rret for a hit
       __ br( Assembler::notEqual, false, Assembler::pt, loop );
-      __ delayed()->ld(L1_ary_ptr,0,L2_super);// Will load a little early
+      __ delayed()->lduw(L1_ary_ptr,0,L2_super);// Will load a little early
 #else
       ShouldNotReachHere();
 #endif
--- a/hotspot/src/cpu/x86/vm/assembler_x86.cpp	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.cpp	Wed Jul 05 16:43:41 2017 +0200
@@ -621,6 +621,10 @@
     debug_only(has_disp32 = true);
     break;
 
+  case 0xF0:                    // Lock
+    assert(os::is_MP(), "only on MP");
+    goto again_after_prefix;
+
   case 0xF3:                    // For SSE
   case 0xF2:                    // For SSE2
     switch (0xFF & *ip++) {
--- a/hotspot/src/cpu/x86/vm/assembler_x86.hpp	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.hpp	Wed Jul 05 16:43:41 2017 +0200
@@ -1780,7 +1780,8 @@
   // check info (currently consumed only by C1). If
   // swap_reg_contains_mark is true then returns -1 as it is assumed
   // the calling code has already passed any potential faults.
-  int biased_locking_enter(Register lock_reg, Register obj_reg, Register swap_reg, Register tmp_reg,
+  int biased_locking_enter(Register lock_reg, Register obj_reg,
+                           Register swap_reg, Register tmp_reg,
                            bool swap_reg_contains_mark,
                            Label& done, Label* slow_case = NULL,
                            BiasedLockingCounters* counters = NULL);
--- a/hotspot/src/cpu/x86/vm/x86_32.ad	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/cpu/x86/vm/x86_32.ad	Wed Jul 05 16:43:41 2017 +0200
@@ -495,8 +495,8 @@
 void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
   Compile* C = ra_->C;
   if( C->in_24_bit_fp_mode() ) {
-    tty->print("FLDCW  24 bit fpu control word");
-    tty->print_cr(""); tty->print("\t");
+    st->print("FLDCW  24 bit fpu control word");
+    st->print_cr(""); st->print("\t");
   }
 
   int framesize = C->frame_slots() << LogBytesPerInt;
@@ -510,22 +510,22 @@
   // stack.  But the stack safety zone should account for that.
   // See bugs 4446381, 4468289, 4497237.
   if (C->need_stack_bang(framesize)) {
-    tty->print_cr("# stack bang"); tty->print("\t");
+    st->print_cr("# stack bang"); st->print("\t");
   }
-  tty->print_cr("PUSHL  EBP"); tty->print("\t");
+  st->print_cr("PUSHL  EBP"); st->print("\t");
 
   if( VerifyStackAtCalls ) { // Majik cookie to verify stack depth
-    tty->print("PUSH   0xBADB100D\t# Majik cookie for stack depth check");
-    tty->print_cr(""); tty->print("\t");
+    st->print("PUSH   0xBADB100D\t# Majik cookie for stack depth check");
+    st->print_cr(""); st->print("\t");
     framesize -= wordSize;
   }
 
   if ((C->in_24_bit_fp_mode() || VerifyStackAtCalls ) && framesize < 128 ) {
     if (framesize) {
-      tty->print("SUB    ESP,%d\t# Create frame",framesize);
+      st->print("SUB    ESP,%d\t# Create frame",framesize);
     }
   } else {
-    tty->print("SUB    ESP,%d\t# Create frame",framesize);
+    st->print("SUB    ESP,%d\t# Create frame",framesize);
   }
 }
 #endif
@@ -725,18 +725,19 @@
   return rc_xmm;
 }
 
-static int impl_helper( CodeBuffer *cbuf, bool do_size, bool is_load, int offset, int reg, int opcode, const char *op_str, int size ) {
+static int impl_helper( CodeBuffer *cbuf, bool do_size, bool is_load, int offset, int reg,
+                        int opcode, const char *op_str, int size, outputStream* st ) {
   if( cbuf ) {
     emit_opcode  (*cbuf, opcode );
     encode_RegMem(*cbuf, Matcher::_regEncode[reg], ESP_enc, 0x4, 0, offset, false);
 #ifndef PRODUCT
   } else if( !do_size ) {
-    if( size != 0 ) tty->print("\n\t");
+    if( size != 0 ) st->print("\n\t");
     if( opcode == 0x8B || opcode == 0x89 ) { // MOV
-      if( is_load ) tty->print("%s   %s,[ESP + #%d]",op_str,Matcher::regName[reg],offset);
-      else          tty->print("%s   [ESP + #%d],%s",op_str,offset,Matcher::regName[reg]);
+      if( is_load ) st->print("%s   %s,[ESP + #%d]",op_str,Matcher::regName[reg],offset);
+      else          st->print("%s   [ESP + #%d],%s",op_str,offset,Matcher::regName[reg]);
     } else { // FLD, FST, PUSH, POP
-      tty->print("%s [ESP + #%d]",op_str,offset);
+      st->print("%s [ESP + #%d]",op_str,offset);
     }
 #endif
   }
@@ -746,7 +747,7 @@
 
 // Helper for XMM registers.  Extra opcode bits, limited syntax.
 static int impl_x_helper( CodeBuffer *cbuf, bool do_size, bool is_load,
-                         int offset, int reg_lo, int reg_hi, int size ) {
+                         int offset, int reg_lo, int reg_hi, int size, outputStream* st ) {
   if( cbuf ) {
     if( reg_lo+1 == reg_hi ) { // double move?
       if( is_load && !UseXmmLoadAndClearUpper )
@@ -764,17 +765,17 @@
     encode_RegMem(*cbuf, Matcher::_regEncode[reg_lo], ESP_enc, 0x4, 0, offset, false);
 #ifndef PRODUCT
   } else if( !do_size ) {
-    if( size != 0 ) tty->print("\n\t");
+    if( size != 0 ) st->print("\n\t");
     if( reg_lo+1 == reg_hi ) { // double move?
-      if( is_load ) tty->print("%s %s,[ESP + #%d]",
+      if( is_load ) st->print("%s %s,[ESP + #%d]",
                                UseXmmLoadAndClearUpper ? "MOVSD " : "MOVLPD",
                                Matcher::regName[reg_lo], offset);
-      else          tty->print("MOVSD  [ESP + #%d],%s",
+      else          st->print("MOVSD  [ESP + #%d],%s",
                                offset, Matcher::regName[reg_lo]);
     } else {
-      if( is_load ) tty->print("MOVSS  %s,[ESP + #%d]",
+      if( is_load ) st->print("MOVSS  %s,[ESP + #%d]",
                                Matcher::regName[reg_lo], offset);
-      else          tty->print("MOVSS  [ESP + #%d],%s",
+      else          st->print("MOVSS  [ESP + #%d],%s",
                                offset, Matcher::regName[reg_lo]);
     }
 #endif
@@ -785,7 +786,7 @@
 
 
 static int impl_movx_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo,
-                            int src_hi, int dst_hi, int size ) {
+                            int src_hi, int dst_hi, int size, outputStream* st ) {
   if( UseXmmRegToRegMoveAll ) {//Use movaps,movapd to move between xmm registers
     if( cbuf ) {
       if( (src_lo+1 == src_hi && dst_lo+1 == dst_hi) ) {
@@ -796,11 +797,11 @@
       emit_rm    (*cbuf, 0x3, Matcher::_regEncode[dst_lo], Matcher::_regEncode[src_lo] );
 #ifndef PRODUCT
     } else if( !do_size ) {
-      if( size != 0 ) tty->print("\n\t");
+      if( size != 0 ) st->print("\n\t");
       if( src_lo+1 == src_hi && dst_lo+1 == dst_hi ) { // double move?
-        tty->print("MOVAPD %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
+        st->print("MOVAPD %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
       } else {
-        tty->print("MOVAPS %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
+        st->print("MOVAPS %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
       }
 #endif
     }
@@ -813,11 +814,11 @@
       emit_rm    (*cbuf, 0x3, Matcher::_regEncode[dst_lo], Matcher::_regEncode[src_lo] );
 #ifndef PRODUCT
     } else if( !do_size ) {
-      if( size != 0 ) tty->print("\n\t");
+      if( size != 0 ) st->print("\n\t");
       if( src_lo+1 == src_hi && dst_lo+1 == dst_hi ) { // double move?
-        tty->print("MOVSD  %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
+        st->print("MOVSD  %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
       } else {
-        tty->print("MOVSS  %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
+        st->print("MOVSS  %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
       }
 #endif
     }
@@ -825,28 +826,29 @@
   }
 }
 
-static int impl_mov_helper( CodeBuffer *cbuf, bool do_size, int src, int dst, int size ) {
+static int impl_mov_helper( CodeBuffer *cbuf, bool do_size, int src, int dst, int size, outputStream* st ) {
   if( cbuf ) {
     emit_opcode(*cbuf, 0x8B );
     emit_rm    (*cbuf, 0x3, Matcher::_regEncode[dst], Matcher::_regEncode[src] );
 #ifndef PRODUCT
   } else if( !do_size ) {
-    if( size != 0 ) tty->print("\n\t");
-    tty->print("MOV    %s,%s",Matcher::regName[dst],Matcher::regName[src]);
+    if( size != 0 ) st->print("\n\t");
+    st->print("MOV    %s,%s",Matcher::regName[dst],Matcher::regName[src]);
 #endif
   }
   return size+2;
 }
 
-static int impl_fp_store_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int src_hi, int dst_lo, int dst_hi, int offset, int size ) {
+static int impl_fp_store_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int src_hi, int dst_lo, int dst_hi,
+                                 int offset, int size, outputStream* st ) {
   if( src_lo != FPR1L_num ) {      // Move value to top of FP stack, if not already there
     if( cbuf ) {
       emit_opcode( *cbuf, 0xD9 );  // FLD (i.e., push it)
       emit_d8( *cbuf, 0xC0-1+Matcher::_regEncode[src_lo] );
 #ifndef PRODUCT
     } else if( !do_size ) {
-      if( size != 0 ) tty->print("\n\t");
-      tty->print("FLD    %s",Matcher::regName[src_lo]);
+      if( size != 0 ) st->print("\n\t");
+      st->print("FLD    %s",Matcher::regName[src_lo]);
 #endif
     }
     size += 2;
@@ -864,7 +866,7 @@
     assert( !OptoReg::is_valid(src_hi) && !OptoReg::is_valid(dst_hi), "no non-adjacent float-stores" );
   }
 
-  return impl_helper(cbuf,do_size,false,offset,st_op,op,op_str,size);
+  return impl_helper(cbuf,do_size,false,offset,st_op,op,op_str,size, st);
 }
 
 uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream* st ) const {
@@ -892,16 +894,16 @@
   if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) {
     if( src_second == dst_first ) { // overlapping stack copy ranges
       assert( src_second_rc == rc_stack && dst_second_rc == rc_stack, "we only expect a stk-stk copy here" );
-      size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),ESI_num,0xFF,"PUSH  ",size);
-      size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),EAX_num,0x8F,"POP   ",size);
+      size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),ESI_num,0xFF,"PUSH  ",size, st);
+      size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),EAX_num,0x8F,"POP   ",size, st);
       src_second_rc = dst_second_rc = rc_bad;  // flag as already moved the second bits
     }
     // move low bits
-    size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),ESI_num,0xFF,"PUSH  ",size);
-    size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),EAX_num,0x8F,"POP   ",size);
+    size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),ESI_num,0xFF,"PUSH  ",size, st);
+    size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),EAX_num,0x8F,"POP   ",size, st);
     if( src_second_rc == rc_stack && dst_second_rc == rc_stack ) { // mov second bits
-      size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),ESI_num,0xFF,"PUSH  ",size);
-      size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),EAX_num,0x8F,"POP   ",size);
+      size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),ESI_num,0xFF,"PUSH  ",size, st);
+      size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),EAX_num,0x8F,"POP   ",size, st);
     }
     return size;
   }
@@ -909,15 +911,15 @@
   // --------------------------------------
   // Check for integer reg-reg copy
   if( src_first_rc == rc_int && dst_first_rc == rc_int )
-    size = impl_mov_helper(cbuf,do_size,src_first,dst_first,size);
+    size = impl_mov_helper(cbuf,do_size,src_first,dst_first,size, st);
 
   // Check for integer store
   if( src_first_rc == rc_int && dst_first_rc == rc_stack )
-    size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),src_first,0x89,"MOV ",size);
+    size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),src_first,0x89,"MOV ",size, st);
 
   // Check for integer load
   if( dst_first_rc == rc_int && src_first_rc == rc_stack )
-    size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),dst_first,0x8B,"MOV ",size);
+    size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),dst_first,0x8B,"MOV ",size, st);
 
   // --------------------------------------
   // Check for float reg-reg copy
@@ -951,7 +953,7 @@
 
   // Check for float store
   if( src_first_rc == rc_float && dst_first_rc == rc_stack ) {
-    return impl_fp_store_helper(cbuf,do_size,src_first,src_second,dst_first,dst_second,ra_->reg2offset(dst_first),size);
+    return impl_fp_store_helper(cbuf,do_size,src_first,src_second,dst_first,dst_second,ra_->reg2offset(dst_first),size, st);
   }
 
   // Check for float load
@@ -987,17 +989,17 @@
     assert( (src_second_rc == rc_bad && dst_second_rc == rc_bad) ||
             (src_first+1 == src_second && dst_first+1 == dst_second),
             "no non-adjacent float-moves" );
-    return impl_movx_helper(cbuf,do_size,src_first,dst_first,src_second, dst_second, size);
+    return impl_movx_helper(cbuf,do_size,src_first,dst_first,src_second, dst_second, size, st);
   }
 
   // Check for xmm store
   if( src_first_rc == rc_xmm && dst_first_rc == rc_stack ) {
-    return impl_x_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),src_first, src_second, size);
+    return impl_x_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),src_first, src_second, size, st);
   }
 
   // Check for float xmm load
   if( dst_first_rc == rc_xmm && src_first_rc == rc_stack ) {
-    return impl_x_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),dst_first, dst_second, size);
+    return impl_x_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),dst_first, dst_second, size, st);
   }
 
   // Copy from float reg to xmm reg
@@ -1017,10 +1019,10 @@
     }
     size += 4;
 
-    size = impl_fp_store_helper(cbuf,do_size,src_first,src_second,dst_first,dst_second,0,size);
+    size = impl_fp_store_helper(cbuf,do_size,src_first,src_second,dst_first,dst_second,0,size, st);
 
     // Copy from the temp memory to the xmm reg.
-    size = impl_x_helper(cbuf,do_size,true ,0,dst_first, dst_second, size);
+    size = impl_x_helper(cbuf,do_size,true ,0,dst_first, dst_second, size, st);
 
     if( cbuf ) {
       emit_opcode(*cbuf,0x8D);  // LEA  ESP,[ESP+8]
@@ -1047,15 +1049,15 @@
 
   // Check for second word int-int move
   if( src_second_rc == rc_int && dst_second_rc == rc_int )
-    return impl_mov_helper(cbuf,do_size,src_second,dst_second,size);
+    return impl_mov_helper(cbuf,do_size,src_second,dst_second,size, st);
 
   // Check for second word integer store
   if( src_second_rc == rc_int && dst_second_rc == rc_stack )
-    return impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),src_second,0x89,"MOV ",size);
+    return impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),src_second,0x89,"MOV ",size, st);
 
   // Check for second word integer load
   if( dst_second_rc == rc_int && src_second_rc == rc_stack )
-    return impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),dst_second,0x8B,"MOV ",size);
+    return impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),dst_second,0x8B,"MOV ",size, st);
 
 
   Unimplemented();
@@ -1318,7 +1320,11 @@
 //
 // NOTE: If the platform does not provide any short branch variants, then
 //       this method should return false for offset 0.
-bool Matcher::is_short_branch_offset(int offset) {
+bool Matcher::is_short_branch_offset(int rule, int offset) {
+  // the short version of jmpConUCF2 contains multiple branches,
+  // making the reach slightly less
+  if (rule == jmpConUCF2_rule)
+    return (-126 <= offset && offset <= 125);
   return (-128 <= offset && offset <= 127);
 }
 
@@ -3307,7 +3313,7 @@
       // Beware -- there's a subtle invariant that fetch of the markword
       // at [FETCH], below, will never observe a biased encoding (*101b).
       // If this invariant is not held we risk exclusion (safety) failure.
-      if (UseBiasedLocking) {
+      if (UseBiasedLocking && !UseOptoBiasInlining) {
         masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL, _counters);
       }
 
@@ -3528,7 +3534,7 @@
 
       // Critically, the biased locking test must have precedence over
       // and appear before the (box->dhw == 0) recursive stack-lock test.
-      if (UseBiasedLocking) {
+      if (UseBiasedLocking && !UseOptoBiasInlining) {
          masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL);
       }
       
@@ -5272,6 +5278,15 @@
   interface(REG_INTER);
 %}
 
+operand eFlagsRegUCF() %{
+  constraint(ALLOC_IN_RC(int_flags));
+  match(RegFlags);
+  predicate(false);
+
+  format %{ "EFLAGS_U_CF" %}
+  interface(REG_INTER);
+%}
+
 // Condition Code Register used by long compare
 operand flagsReg_long_LTGE() %{
   constraint(ALLOC_IN_RC(int_flags));
@@ -5749,12 +5764,12 @@
 
   format %{ "" %}
   interface(COND_INTER) %{
-    equal(0x4);
-    not_equal(0x5);
-    less(0xC);
-    greater_equal(0xD);
-    less_equal(0xE);
-    greater(0xF);
+    equal(0x4, "e");
+    not_equal(0x5, "ne");
+    less(0xC, "l");
+    greater_equal(0xD, "ge");
+    less_equal(0xE, "le");
+    greater(0xF, "g");
   %}
 %}
 
@@ -5766,12 +5781,47 @@
 
   format %{ "" %}
   interface(COND_INTER) %{
-    equal(0x4);
-    not_equal(0x5);
-    less(0x2);
-    greater_equal(0x3);
-    less_equal(0x6);
-    greater(0x7);
+    equal(0x4, "e");
+    not_equal(0x5, "ne");
+    less(0x2, "b");
+    greater_equal(0x3, "nb");
+    less_equal(0x6, "be");
+    greater(0x7, "nbe");
+  %}
+%}
+
+// Floating comparisons that don't require any fixup for the unordered case
+operand cmpOpUCF() %{
+  match(Bool);
+  predicate(n->as_Bool()->_test._test == BoolTest::lt ||
+            n->as_Bool()->_test._test == BoolTest::ge ||
+            n->as_Bool()->_test._test == BoolTest::le ||
+            n->as_Bool()->_test._test == BoolTest::gt);
+  format %{ "" %}
+  interface(COND_INTER) %{
+    equal(0x4, "e");
+    not_equal(0x5, "ne");
+    less(0x2, "b");
+    greater_equal(0x3, "nb");
+    less_equal(0x6, "be");
+    greater(0x7, "nbe");
+  %}
+%}
+
+
+// Floating comparisons that can be fixed up with extra conditional jumps
+operand cmpOpUCF2() %{
+  match(Bool);
+  predicate(n->as_Bool()->_test._test == BoolTest::ne ||
+            n->as_Bool()->_test._test == BoolTest::eq);
+  format %{ "" %}
+  interface(COND_INTER) %{
+    equal(0x4, "e");
+    not_equal(0x5, "ne");
+    less(0x2, "b");
+    greater_equal(0x3, "nb");
+    less_equal(0x6, "be");
+    greater(0x7, "nbe");
   %}
 %}
 
@@ -5796,12 +5846,12 @@
 
   format %{ "" %}
   interface(COND_INTER) %{
-    equal(0x4);
-    not_equal(0x5);
-    less(0xF);
-    greater_equal(0xE);
-    less_equal(0xD);
-    greater(0xC);
+    equal(0x4, "e");
+    not_equal(0x5, "ne");
+    less(0xF, "g");
+    greater_equal(0xE, "le");
+    less_equal(0xD, "ge");
+    greater(0xC, "l");
   %}
 %}
 
@@ -7357,7 +7407,7 @@
   ins_pipe( pipe_cmov_reg );
 %}
 
-instruct cmovI_regU( eRegI dst, eRegI src, eFlagsRegU cr, cmpOpU cop ) %{
+instruct cmovI_regU( cmpOpU cop, eFlagsRegU cr, eRegI dst, eRegI src ) %{
   predicate(VM_Version::supports_cmov() );
   match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
   ins_cost(200);
@@ -7367,6 +7417,15 @@
   ins_pipe( pipe_cmov_reg );
 %}
 
+instruct cmovI_regUCF( cmpOpUCF cop, eFlagsRegUCF cr, eRegI dst, eRegI src ) %{
+  predicate(VM_Version::supports_cmov() );
+  match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
+  ins_cost(200);
+  expand %{
+    cmovI_regU(cop, cr, dst, src);
+  %}
+%}
+
 // Conditional move
 instruct cmovI_mem(cmpOp cop, eFlagsReg cr, eRegI dst, memory src) %{
   predicate(VM_Version::supports_cmov() );
@@ -7379,7 +7438,7 @@
 %}
 
 // Conditional move
-instruct cmovI_memu(cmpOpU cop, eFlagsRegU cr, eRegI dst, memory src) %{
+instruct cmovI_memU(cmpOpU cop, eFlagsRegU cr, eRegI dst, memory src) %{
   predicate(VM_Version::supports_cmov() );
   match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
   ins_cost(250);
@@ -7389,6 +7448,15 @@
   ins_pipe( pipe_cmov_mem );
 %}
 
+instruct cmovI_memUCF(cmpOpUCF cop, eFlagsRegUCF cr, eRegI dst, memory src) %{
+  predicate(VM_Version::supports_cmov() );
+  match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
+  ins_cost(250);
+  expand %{
+    cmovI_memU(cop, cr, dst, src);
+  %}
+%}
+
 // Conditional move
 instruct cmovP_reg(eRegP dst, eRegP src, eFlagsReg cr, cmpOp cop ) %{
   predicate(VM_Version::supports_cmov() );
@@ -7416,7 +7484,7 @@
 %}
 
 // Conditional move
-instruct cmovP_regU(eRegP dst, eRegP src, eFlagsRegU cr, cmpOpU cop ) %{
+instruct cmovP_regU(cmpOpU cop, eFlagsRegU cr, eRegP dst, eRegP src ) %{
   predicate(VM_Version::supports_cmov() );
   match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
   ins_cost(200);
@@ -7426,6 +7494,15 @@
   ins_pipe( pipe_cmov_reg );
 %}
 
+instruct cmovP_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, eRegP dst, eRegP src ) %{
+  predicate(VM_Version::supports_cmov() );
+  match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
+  ins_cost(200);
+  expand %{
+    cmovP_regU(cop, cr, dst, src);
+  %}
+%}
+
 // DISABLED: Requires the ADLC to emit a bottom_type call that
 // correctly meets the two pointer arguments; one is an incoming
 // register but the other is a memory operand.  ALSO appears to
@@ -7555,6 +7632,15 @@
   ins_pipe( pipe_slow );
 %}
 
+instruct fcmovX_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, regX dst, regX src) %{
+  predicate (UseSSE>=1);
+  match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
+  ins_cost(200);
+  expand %{
+    fcmovX_regU(cop, cr, dst, src);
+  %}
+%}
+
 // unsigned version
 instruct fcmovXD_regU(cmpOpU cop, eFlagsRegU cr, regXD dst, regXD src) %{
   predicate (UseSSE>=2);
@@ -7573,6 +7659,15 @@
   ins_pipe( pipe_slow );
 %}
 
+instruct fcmovXD_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, regXD dst, regXD src) %{
+  predicate (UseSSE>=2);
+  match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
+  ins_cost(200);
+  expand %{
+    fcmovXD_regU(cop, cr, dst, src);
+  %}
+%}
+
 instruct cmovL_reg(cmpOp cop, eFlagsReg cr, eRegL dst, eRegL src) %{
   predicate(VM_Version::supports_cmov() );
   match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
@@ -7595,6 +7690,15 @@
   ins_pipe( pipe_cmov_reg_long );
 %}
 
+instruct cmovL_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, eRegL dst, eRegL src) %{
+  predicate(VM_Version::supports_cmov() );
+  match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
+  ins_cost(200);
+  expand %{
+    cmovL_regU(cop, cr, dst, src);
+  %}
+%}
+
 //----------Arithmetic Instructions--------------------------------------------
 //----------Addition Instructions----------------------------------------------
 // Integer Addition Instructions
@@ -7826,33 +7930,36 @@
   ins_pipe( pipe_cmpxchg );
 %}
 
-// Conditional-store of a long value
-// Returns a boolean value (0/1) on success.  Implemented with a CMPXCHG8 on Intel.
-// mem_ptr can actually be in either ESI or EDI
-instruct storeLConditional( eRegI res, eSIRegP mem_ptr, eADXRegL oldval, eBCXRegL newval, eFlagsReg cr ) %{
-  match(Set res (StoreLConditional mem_ptr (Binary oldval newval)));
-  effect(KILL cr);
-  // EDX:EAX is killed if there is contention, but then it's also unused.
-  // In the common case of no contention, EDX:EAX holds the new oop address.
-  format %{ "CMPXCHG8 [$mem_ptr],$newval\t# If EDX:EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t"
-            "MOV    $res,0\n\t"
-            "JNE,s  fail\n\t"
-            "MOV    $res,1\n"
-          "fail:" %}
-  ins_encode( enc_cmpxchg8(mem_ptr),
-              enc_flags_ne_to_boolean(res) );
+// Conditional-store of an int value.
+// ZF flag is set on success, reset otherwise.  Implemented with a CMPXCHG on Intel.
+instruct storeIConditional( memory mem, eAXRegI oldval, eRegI newval, eFlagsReg cr ) %{
+  match(Set cr (StoreIConditional mem (Binary oldval newval)));
+  effect(KILL oldval);
+  format %{ "CMPXCHG $mem,$newval\t# If EAX==$mem Then store $newval into $mem" %}
+  ins_encode( lock_prefix, Opcode(0x0F), Opcode(0xB1), RegMem(newval, mem) );
   ins_pipe( pipe_cmpxchg );
 %}
 
-// Conditional-store of a long value
-// ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG8 on Intel.
-// mem_ptr can actually be in either ESI or EDI
-instruct storeLConditional_flags( eSIRegP mem_ptr, eADXRegL oldval, eBCXRegL newval, eFlagsReg cr, immI0 zero ) %{
-  match(Set cr (CmpI (StoreLConditional mem_ptr (Binary oldval newval)) zero));
-  // EDX:EAX is killed if there is contention, but then it's also unused.
-  // In the common case of no contention, EDX:EAX holds the new oop address.
-  format %{ "CMPXCHG8 [$mem_ptr],$newval\t# If EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t" %}
-  ins_encode( enc_cmpxchg8(mem_ptr) );
+// Conditional-store of a long value.
+// ZF flag is set on success, reset otherwise.  Implemented with a CMPXCHG8 on Intel.
+instruct storeLConditional( memory mem, eADXRegL oldval, eBCXRegL newval, eFlagsReg cr ) %{
+  match(Set cr (StoreLConditional mem (Binary oldval newval)));
+  effect(KILL oldval);
+  format %{ "XCHG   EBX,ECX\t# correct order for CMPXCHG8 instruction\n\t"
+            "CMPXCHG8 $mem,ECX:EBX\t# If EDX:EAX==$mem Then store ECX:EBX into $mem\n\t"
+            "XCHG   EBX,ECX"
+  %}
+  ins_encode %{
+    // Note: we need to swap rbx, and rcx before and after the
+    //       cmpxchg8 instruction because the instruction uses
+    //       rcx as the high order word of the new value to store but
+    //       our register encoding uses rbx.
+    __ xchgl(as_Register(EBX_enc), as_Register(ECX_enc));
+    if( os::is_MP() )
+      __ lock();
+    __ cmpxchg8(Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp));
+    __ xchgl(as_Register(EBX_enc), as_Register(ECX_enc));
+  %}
   ins_pipe( pipe_cmpxchg );
 %}
 
@@ -8319,6 +8426,7 @@
   ins_pipe( ialu_reg );
 %}
 
+
 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24.
 // This idiom is used by the compiler for the i2b bytecode.
 instruct i2b(eRegI dst, xRegI src, immI_24 twentyfour, eFlagsReg cr) %{
@@ -8436,6 +8544,18 @@
   ins_pipe( ialu_reg_reg );
 %}
 
+instruct orI_eReg_castP2X(eRegI dst, eRegP src, eFlagsReg cr) %{
+  match(Set dst (OrI dst (CastP2X src)));
+  effect(KILL cr);
+
+  size(2);
+  format %{ "OR     $dst,$src" %}
+  opcode(0x0B);
+  ins_encode( OpcP, RegReg( dst, src) );
+  ins_pipe( ialu_reg_reg );
+%}
+
+
 // Or Register with Immediate
 instruct orI_eReg_imm(eRegI dst, immI src, eFlagsReg cr) %{
   match(Set dst (OrI dst src));
@@ -9200,6 +9320,18 @@
   ins_pipe( pipe_slow );
 %}
 
+instruct cmpD_cc_P6CF(eFlagsRegUCF cr, regD src1, regD src2) %{
+  predicate(VM_Version::supports_cmov() && UseSSE <=1);
+  match(Set cr (CmpD src1 src2));
+  ins_cost(150);
+  format %{ "FLD    $src1\n\t"
+            "FUCOMIP ST,$src2  // P6 instruction" %}
+  opcode(0xDF, 0x05); /* DF E8+i or DF /5 */
+  ins_encode( Push_Reg_D(src1),
+              OpcP, RegOpc(src2));
+  ins_pipe( pipe_slow );
+%}
+
 // Compare & branch
 instruct cmpD_cc(eFlagsRegU cr, regD src1, regD src2, eAXRegI rax) %{
   predicate(UseSSE<=1);
@@ -9264,6 +9396,16 @@
   ins_pipe( pipe_slow );
 %}
 
+instruct cmpXD_ccCF(eFlagsRegUCF cr, regXD dst, regXD src) %{
+  predicate(UseSSE>=2);
+  match(Set cr (CmpD dst src));
+  ins_cost(100);
+  format %{ "COMISD $dst,$src" %}
+  opcode(0x66, 0x0F, 0x2F);
+  ins_encode(OpcP, OpcS, Opcode(tertiary), RegReg(dst, src));
+  ins_pipe( pipe_slow );
+%}
+
 // float compare and set condition codes in EFLAGS by XMM regs
 instruct cmpXD_ccmem(eFlagsRegU cr, regXD dst, memory src, eAXRegI rax) %{
   predicate(UseSSE>=2);
@@ -9280,6 +9422,16 @@
   ins_pipe( pipe_slow );
 %}
 
+instruct cmpXD_ccmemCF(eFlagsRegUCF cr, regXD dst, memory src) %{
+  predicate(UseSSE>=2);
+  match(Set cr (CmpD dst (LoadD src)));
+  ins_cost(100);
+  format %{ "COMISD $dst,$src" %}
+  opcode(0x66, 0x0F, 0x2F);
+  ins_encode(OpcP, OpcS, Opcode(tertiary), RegMem(dst, src));
+  ins_pipe( pipe_slow );
+%}
+
 // Compare into -1,0,1 in XMM
 instruct cmpXD_reg(eRegI dst, regXD src1, regXD src2, eFlagsReg cr) %{
   predicate(UseSSE>=2);
@@ -10167,6 +10319,18 @@
   ins_pipe( pipe_slow );
 %}
 
+instruct cmpF_cc_P6CF(eFlagsRegUCF cr, regF src1, regF src2) %{
+  predicate(VM_Version::supports_cmov() && UseSSE == 0);
+  match(Set cr (CmpF src1 src2));
+  ins_cost(100);
+  format %{ "FLD    $src1\n\t"
+            "FUCOMIP ST,$src2  // P6 instruction" %}
+  opcode(0xDF, 0x05); /* DF E8+i or DF /5 */
+  ins_encode( Push_Reg_D(src1),
+              OpcP, RegOpc(src2));
+  ins_pipe( pipe_slow );
+%}
+
 
 // Compare & branch
 instruct cmpF_cc(eFlagsRegU cr, regF src1, regF src2, eAXRegI rax) %{
@@ -10232,6 +10396,16 @@
   ins_pipe( pipe_slow );
 %}
 
+instruct cmpX_ccCF(eFlagsRegUCF cr, regX dst, regX src) %{
+  predicate(UseSSE>=1);
+  match(Set cr (CmpF dst src));
+  ins_cost(100);
+  format %{ "COMISS $dst,$src" %}
+  opcode(0x0F, 0x2F);
+  ins_encode(OpcP, OpcS, RegReg(dst, src));
+  ins_pipe( pipe_slow );
+%}
+
 // float compare and set condition codes in EFLAGS by XMM regs
 instruct cmpX_ccmem(eFlagsRegU cr, regX dst, memory src, eAXRegI rax) %{
   predicate(UseSSE>=1);
@@ -10248,6 +10422,16 @@
   ins_pipe( pipe_slow );
 %}
 
+instruct cmpX_ccmemCF(eFlagsRegUCF cr, regX dst, memory src) %{
+  predicate(UseSSE>=1);
+  match(Set cr (CmpF dst (LoadF src)));
+  ins_cost(100);
+  format %{ "COMISS $dst,$src" %}
+  opcode(0x0F, 0x2F);
+  ins_encode(OpcP, OpcS, RegMem(dst, src));
+  ins_pipe( pipe_slow );
+%}
+
 // Compare into -1,0,1 in XMM
 instruct cmpX_reg(eRegI dst, regX src1, regX src2, eFlagsReg cr) %{
   predicate(UseSSE>=1);
@@ -12099,6 +12283,19 @@
   ins_pc_relative(1);
 %}
 
+instruct jmpLoopEndUCF(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{
+  match(CountedLoopEnd cop cmp);
+  effect(USE labl);
+
+  ins_cost(200);
+  format %{ "J$cop,u  $labl\t# Loop end" %}
+  size(6);
+  opcode(0x0F, 0x80);
+  ins_encode( Jcc( cop, labl) );
+  ins_pipe( pipe_jcc );
+  ins_pc_relative(1);
+%}
+
 // Jump Direct Conditional - using unsigned comparison
 instruct jmpConU(cmpOpU cop, eFlagsRegU cmp, label labl) %{
   match(If cop cmp);
@@ -12108,8 +12305,63 @@
   format %{ "J$cop,u  $labl" %}
   size(6);
   opcode(0x0F, 0x80);
-  ins_encode( Jcc( cop, labl) );
-  ins_pipe( pipe_jcc );
+  ins_encode(Jcc(cop, labl));
+  ins_pipe(pipe_jcc);
+  ins_pc_relative(1);
+%}
+
+instruct jmpConUCF(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{
+  match(If cop cmp);
+  effect(USE labl);
+
+  ins_cost(200);
+  format %{ "J$cop,u  $labl" %}
+  size(6);
+  opcode(0x0F, 0x80);
+  ins_encode(Jcc(cop, labl));
+  ins_pipe(pipe_jcc);
+  ins_pc_relative(1);
+%}
+
+instruct jmpConUCF2(cmpOpUCF2 cop, eFlagsRegUCF cmp, label labl) %{
+  match(If cop cmp);
+  effect(USE labl);
+
+  ins_cost(200);
+  format %{ $$template
+    if ($cop$$cmpcode == Assembler::notEqual) {
+      $$emit$$"JP,u   $labl\n\t"
+      $$emit$$"J$cop,u   $labl"
+    } else {
+      $$emit$$"JP,u   done\n\t"
+      $$emit$$"J$cop,u   $labl\n\t"
+      $$emit$$"done:"
+    }
+  %}
+  size(12);
+  opcode(0x0F, 0x80);
+  ins_encode %{
+    Label* l = $labl$$label;
+    $$$emit8$primary;
+    emit_cc(cbuf, $secondary, Assembler::parity);
+    int parity_disp = -1;
+    bool ok = false;
+    if ($cop$$cmpcode == Assembler::notEqual) {
+       // the two jumps 6 bytes apart so the jump distances are too
+       parity_disp = l ? (l->loc_pos() - (cbuf.code_size() + 4)) : 0;
+    } else if ($cop$$cmpcode == Assembler::equal) {
+       parity_disp = 6;
+       ok = true;
+    } else {
+       ShouldNotReachHere();
+    }
+    emit_d32(cbuf, parity_disp);
+    $$$emit8$primary;
+    emit_cc(cbuf, $secondary, $cop$$cmpcode);
+    int disp = l ? (l->loc_pos() - (cbuf.code_size() + 4)) : 0;
+    emit_d32(cbuf, disp);
+  %}
+  ins_pipe(pipe_jcc);
   ins_pc_relative(1);
 %}
 
@@ -12208,7 +12460,7 @@
   effect(USE labl);
 
   ins_cost(300);
-  format %{ "J$cop,s  $labl" %}
+  format %{ "J$cop,s  $labl\t# Loop end" %}
   size(2);
   opcode(0x70);
   ins_encode( JccShort( cop, labl) );
@@ -12223,6 +12475,35 @@
   effect(USE labl);
 
   ins_cost(300);
+  format %{ "J$cop,us $labl\t# Loop end" %}
+  size(2);
+  opcode(0x70);
+  ins_encode( JccShort( cop, labl) );
+  ins_pipe( pipe_jcc );
+  ins_pc_relative(1);
+  ins_short_branch(1);
+%}
+
+instruct jmpLoopEndUCF_short(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{
+  match(CountedLoopEnd cop cmp);
+  effect(USE labl);
+
+  ins_cost(300);
+  format %{ "J$cop,us $labl\t# Loop end" %}
+  size(2);
+  opcode(0x70);
+  ins_encode( JccShort( cop, labl) );
+  ins_pipe( pipe_jcc );
+  ins_pc_relative(1);
+  ins_short_branch(1);
+%}
+
+// Jump Direct Conditional - using unsigned comparison
+instruct jmpConU_short(cmpOpU cop, eFlagsRegU cmp, label labl) %{
+  match(If cop cmp);
+  effect(USE labl);
+
+  ins_cost(300);
   format %{ "J$cop,us $labl" %}
   size(2);
   opcode(0x70);
@@ -12232,8 +12513,7 @@
   ins_short_branch(1);
 %}
 
-// Jump Direct Conditional - using unsigned comparison
-instruct jmpConU_short(cmpOpU cop, eFlagsRegU cmp, label labl) %{
+instruct jmpConUCF_short(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{
   match(If cop cmp);
   effect(USE labl);
 
@@ -12247,6 +12527,46 @@
   ins_short_branch(1);
 %}
 
+instruct jmpConUCF2_short(cmpOpUCF2 cop, eFlagsRegUCF cmp, label labl) %{
+  match(If cop cmp);
+  effect(USE labl);
+
+  ins_cost(300);
+  format %{ $$template
+    if ($cop$$cmpcode == Assembler::notEqual) {
+      $$emit$$"JP,u,s   $labl\n\t"
+      $$emit$$"J$cop,u,s   $labl"
+    } else {
+      $$emit$$"JP,u,s   done\n\t"
+      $$emit$$"J$cop,u,s  $labl\n\t"
+      $$emit$$"done:"
+    }
+  %}
+  size(4);
+  opcode(0x70);
+  ins_encode %{
+    Label* l = $labl$$label;
+    emit_cc(cbuf, $primary, Assembler::parity);
+    int parity_disp = -1;
+    if ($cop$$cmpcode == Assembler::notEqual) {
+      parity_disp = l ? (l->loc_pos() - (cbuf.code_size() + 1)) : 0;
+    } else if ($cop$$cmpcode == Assembler::equal) {
+      parity_disp = 2;
+    } else {
+      ShouldNotReachHere();
+    }
+    emit_d8(cbuf, parity_disp);
+    emit_cc(cbuf, $primary, $cop$$cmpcode);
+    int disp = l ? (l->loc_pos() - (cbuf.code_size() + 1)) : 0;
+    emit_d8(cbuf, disp);
+    assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
+    assert(-128 <= parity_disp && parity_disp <= 127, "Displacement too large for short jmp");
+  %}
+  ins_pipe(pipe_jcc);
+  ins_pc_relative(1);
+  ins_short_branch(1);
+%}
+
 // ============================================================================
 // Long Compare
 //
--- a/hotspot/src/cpu/x86/vm/x86_64.ad	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/cpu/x86/vm/x86_64.ad	Wed Jul 05 16:43:41 2017 +0200
@@ -2004,9 +2004,12 @@
 //
 // NOTE: If the platform does not provide any short branch variants, then
 //       this method should return false for offset 0.
-bool Matcher::is_short_branch_offset(int offset)
-{
-  return -0x80 <= offset && offset < 0x80;
+bool Matcher::is_short_branch_offset(int rule, int offset) {
+  // the short version of jmpConUCF2 contains multiple branches,
+  // making the reach slightly less
+  if (rule == jmpConUCF2_rule)
+    return (-126 <= offset && offset <= 125);
+  return (-128 <= offset && offset <= 127);
 }
 
 const bool Matcher::isSimpleConstant64(jlong value) {
@@ -3569,7 +3572,7 @@
         // at [FETCH], below, will never observe a biased encoding (*101b).
         // If this invariant is not held we'll suffer exclusion (safety) failure.
 
-        if (UseBiasedLocking) {
+        if (UseBiasedLocking && !UseOptoBiasInlining) {
           masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, true, DONE_LABEL, NULL, _counters);
           masm.movptr(tmpReg, Address(objReg, 0)) ;        // [FETCH]
         }
@@ -3657,7 +3660,7 @@
     } else {
        Label DONE_LABEL, Stacked, CheckSucc ;
 
-       if (UseBiasedLocking) {
+       if (UseBiasedLocking && !UseOptoBiasInlining) {
          masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL);
        }
         
@@ -5134,6 +5137,15 @@
   interface(REG_INTER);
 %}
 
+operand rFlagsRegUCF() %{
+  constraint(ALLOC_IN_RC(int_flags));
+  match(RegFlags);
+  predicate(false);
+
+  format %{ "RFLAGS_U_CF" %}
+  interface(REG_INTER);
+%}
+
 // Float register operands
 operand regF()
 %{
@@ -5405,12 +5417,12 @@
 
   format %{ "" %}
   interface(COND_INTER) %{
-    equal(0x4);
-    not_equal(0x5);
-    less(0xC);
-    greater_equal(0xD);
-    less_equal(0xE);
-    greater(0xF);
+    equal(0x4, "e");
+    not_equal(0x5, "ne");
+    less(0xC, "l");
+    greater_equal(0xD, "ge");
+    less_equal(0xE, "le");
+    greater(0xF, "g");
   %}
 %}
 
@@ -5423,12 +5435,48 @@
 
   format %{ "" %}
   interface(COND_INTER) %{
-    equal(0x4);
-    not_equal(0x5);
-    less(0x2);
-    greater_equal(0x3);
-    less_equal(0x6);
-    greater(0x7);
+    equal(0x4, "e");
+    not_equal(0x5, "ne");
+    less(0x2, "b");
+    greater_equal(0x3, "nb");
+    less_equal(0x6, "be");
+    greater(0x7, "nbe");
+  %}
+%}
+
+
+// Floating comparisons that don't require any fixup for the unordered case
+operand cmpOpUCF() %{
+  match(Bool);
+  predicate(n->as_Bool()->_test._test == BoolTest::lt ||
+            n->as_Bool()->_test._test == BoolTest::ge ||
+            n->as_Bool()->_test._test == BoolTest::le ||
+            n->as_Bool()->_test._test == BoolTest::gt);
+  format %{ "" %}
+  interface(COND_INTER) %{
+    equal(0x4, "e");
+    not_equal(0x5, "ne");
+    less(0x2, "b");
+    greater_equal(0x3, "nb");
+    less_equal(0x6, "be");
+    greater(0x7, "nbe");
+  %}
+%}
+
+
+// Floating comparisons that can be fixed up with extra conditional jumps
+operand cmpOpUCF2() %{
+  match(Bool);
+  predicate(n->as_Bool()->_test._test == BoolTest::ne ||
+            n->as_Bool()->_test._test == BoolTest::eq);
+  format %{ "" %}
+  interface(COND_INTER) %{
+    equal(0x4, "e");
+    not_equal(0x5, "ne");
+    less(0x2, "b");
+    greater_equal(0x3, "nb");
+    less_equal(0x6, "be");
+    greater(0x7, "nbe");
   %}
 %}
 
@@ -7176,8 +7224,7 @@
   ins_pipe(pipe_cmov_reg);
 %}
 
-instruct cmovI_regU(rRegI dst, rRegI src, rFlagsRegU cr, cmpOpU cop)
-%{
+instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{
   match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
 
   ins_cost(200); // XXX
@@ -7187,9 +7234,16 @@
   ins_pipe(pipe_cmov_reg);
 %}
 
+instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{
+  match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
+  ins_cost(200);
+  expand %{
+    cmovI_regU(cop, cr, dst, src);
+  %}
+%}
+
 // Conditional move
-instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src)
-%{
+instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{
   match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
 
   ins_cost(250); // XXX
@@ -7211,6 +7265,14 @@
   ins_pipe(pipe_cmov_mem);
 %}
 
+instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{
+  match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
+  ins_cost(250);
+  expand %{
+    cmovI_memU(cop, cr, dst, src);
+  %}
+%}
+
 // Conditional move
 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop)
 %{
@@ -7224,7 +7286,7 @@
 %}
 
 // Conditional move
-instruct cmovN_regU(rRegN dst, rRegN src, rFlagsRegU cr, cmpOpU cop)
+instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src)
 %{
   match(Set dst (CMoveN (Binary cop cr) (Binary dst src)));
 
@@ -7235,6 +7297,14 @@
   ins_pipe(pipe_cmov_reg);
 %}
 
+instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{
+  match(Set dst (CMoveN (Binary cop cr) (Binary dst src)));
+  ins_cost(200);
+  expand %{
+    cmovN_regU(cop, cr, dst, src);
+  %}
+%}
+
 // Conditional move
 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop)
 %{
@@ -7248,7 +7318,7 @@
 %}
 
 // Conditional move
-instruct cmovP_regU(rRegP dst, rRegP src, rFlagsRegU cr, cmpOpU cop)
+instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src)
 %{
   match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
 
@@ -7259,6 +7329,14 @@
   ins_pipe(pipe_cmov_reg); // XXX
 %}
 
+instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{
+  match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
+  ins_cost(200);
+  expand %{
+    cmovP_regU(cop, cr, dst, src);
+  %}
+%}
+
 // DISABLED: Requires the ADLC to emit a bottom_type call that
 // correctly meets the two pointer arguments; one is an incoming
 // register but the other is a memory operand.  ALSO appears to
@@ -7319,6 +7397,14 @@
   ins_pipe(pipe_cmov_reg); // XXX
 %}
 
+instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{
+  match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
+  ins_cost(200);
+  expand %{
+    cmovL_regU(cop, cr, dst, src);
+  %}
+%}
+
 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src)
 %{
   match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src))));
@@ -7330,6 +7416,14 @@
   ins_pipe(pipe_cmov_mem); // XXX
 %}
 
+instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{
+  match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src))));
+  ins_cost(200);
+  expand %{
+    cmovL_memU(cop, cr, dst, src);
+  %}
+%}
+
 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src)
 %{
   match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
@@ -7366,6 +7460,14 @@
   ins_pipe(pipe_slow);
 %}
 
+instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{
+  match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
+  ins_cost(200);
+  expand %{
+    cmovF_regU(cop, cr, dst, src);
+  %}
+%}
+
 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src)
 %{
   match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
@@ -7390,6 +7492,14 @@
   ins_pipe(pipe_slow);
 %}
 
+instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{
+  match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
+  ins_cost(200);
+  expand %{
+    cmovD_regU(cop, cr, dst, src);
+  %}
+%}
+
 //----------Arithmetic Instructions--------------------------------------------
 //----------Addition Instructions----------------------------------------------
 
@@ -7735,7 +7845,7 @@
                            rFlagsReg cr)
 %{
   match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval)));
-
+ 
   format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) "
             "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %}
   opcode(0x0F, 0xB1);
@@ -7746,53 +7856,40 @@
   ins_pipe(pipe_cmpxchg);
 %}
 
-// Conditional-store of a long value
-// Returns a boolean value (0/1) on success.  Implemented with a
-// CMPXCHG8 on Intel.  mem_ptr can actually be in either RSI or RDI
-
-instruct storeLConditional(rRegI res,
-                           memory mem_ptr,
-                           rax_RegL oldval, rRegL newval,
-                           rFlagsReg cr)
-%{
-  match(Set res (StoreLConditional mem_ptr (Binary oldval newval)));
-  effect(KILL cr);
-
-  format %{ "cmpxchgq $mem_ptr, $newval\t# (long) "
-            "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
-            "sete    $res\n\t"
-            "movzbl  $res, $res" %}
+// Conditional-store of an int value.
+// ZF flag is set on success, reset otherwise.  Implemented with a CMPXCHG.
+instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr)
+%{
+  match(Set cr (StoreIConditional mem (Binary oldval newval)));
+  effect(KILL oldval);
+
+  format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %}
   opcode(0x0F, 0xB1);
   ins_encode(lock_prefix,
-             REX_reg_mem_wide(newval, mem_ptr),
+             REX_reg_mem(newval, mem),
              OpcP, OpcS,
-             reg_mem(newval, mem_ptr),
-             REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
-             REX_reg_breg(res, res), // movzbl
-             Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
+             reg_mem(newval, mem));
   ins_pipe(pipe_cmpxchg);
 %}
 
-// Conditional-store of a long value
-// ZF flag is set on success, reset otherwise. Implemented with a
-// CMPXCHG8 on Intel.  mem_ptr can actually be in either RSI or RDI
-instruct storeLConditional_flags(memory mem_ptr,
-                                 rax_RegL oldval, rRegL newval,
-                                 rFlagsReg cr,
-                                 immI0 zero)
-%{
-  match(Set cr (CmpI (StoreLConditional mem_ptr (Binary oldval newval)) zero));
-
-  format %{ "cmpxchgq $mem_ptr, $newval\t# (long) "
-            "If rax == $mem_ptr then store $newval into $mem_ptr" %}
+// Conditional-store of a long value.
+// ZF flag is set on success, reset otherwise.  Implemented with a CMPXCHG.
+instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr)
+%{
+  match(Set cr (StoreLConditional mem (Binary oldval newval)));
+  effect(KILL oldval);
+
+  format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %}
   opcode(0x0F, 0xB1);
   ins_encode(lock_prefix,
-             REX_reg_mem_wide(newval, mem_ptr),
+             REX_reg_mem_wide(newval, mem),
              OpcP, OpcS,
-             reg_mem(newval, mem_ptr));
+             reg_mem(newval, mem));
   ins_pipe(pipe_cmpxchg);
 %}
 
+
+// XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
 instruct compareAndSwapP(rRegI res,
                          memory mem_ptr,
                          rax_RegP oldval, rRegP newval,
@@ -7816,7 +7913,6 @@
   ins_pipe( pipe_cmpxchg );
 %}
 
-// XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
 instruct compareAndSwapL(rRegI res,
                          memory mem_ptr,
                          rax_RegL oldval, rRegL newval,
@@ -8766,6 +8862,7 @@
   ins_pipe(ialu_reg);
 %}
 
+
 // Logical Shift Right by 8-bit immediate
 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
 %{
@@ -9475,6 +9572,18 @@
   ins_pipe(ialu_reg_reg);
 %}
 
+// Use any_RegP to match R15 (TLS register) without spilling.
+instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{
+  match(Set dst (OrL dst (CastP2X src)));
+  effect(KILL cr);
+
+  format %{ "orq     $dst, $src\t# long" %}
+  opcode(0x0B);
+  ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
+  ins_pipe(ialu_reg_reg);
+%}
+
+
 // Or Register with Immediate
 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr)
 %{
@@ -9716,6 +9825,17 @@
   ins_pipe(pipe_slow);
 %}
 
+instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{
+  match(Set cr (CmpF src1 src2));
+
+  ins_cost(145);
+  format %{ "ucomiss $src1, $src2" %}
+  ins_encode %{
+    __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister);
+  %}
+  ins_pipe(pipe_slow);
+%}
+
 instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2)
 %{
   match(Set cr (CmpF src1 (LoadF src2)));
@@ -9733,6 +9853,16 @@
   ins_pipe(pipe_slow);
 %}
 
+instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{
+  match(Set cr (CmpF src1 (LoadF src2)));
+
+  ins_cost(100);
+  format %{ "ucomiss $src1, $src2" %}
+  opcode(0x0F, 0x2E);
+  ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, reg_mem(src1, src2));
+  ins_pipe(pipe_slow);
+%}
+
 instruct cmpF_cc_imm(rFlagsRegU cr, regF src1, immF src2)
 %{
   match(Set cr (CmpF src1 src2));
@@ -9750,6 +9880,16 @@
   ins_pipe(pipe_slow);
 %}
 
+instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src1, immF src2) %{
+  match(Set cr (CmpF src1 src2));
+
+  ins_cost(100);
+  format %{ "ucomiss $src1, $src2" %}
+  opcode(0x0F, 0x2E);
+  ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, load_immF(src1, src2));
+  ins_pipe(pipe_slow);
+%}
+
 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2)
 %{
   match(Set cr (CmpD src1 src2));
@@ -9767,6 +9907,17 @@
   ins_pipe(pipe_slow);
 %}
 
+instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{
+  match(Set cr (CmpD src1 src2));
+
+  ins_cost(100);
+  format %{ "ucomisd $src1, $src2 test" %}
+  ins_encode %{
+    __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister);
+  %}
+  ins_pipe(pipe_slow);
+%}
+
 instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2)
 %{
   match(Set cr (CmpD src1 (LoadD src2)));
@@ -9784,6 +9935,16 @@
   ins_pipe(pipe_slow);
 %}
 
+instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{
+  match(Set cr (CmpD src1 (LoadD src2)));
+
+  ins_cost(100);
+  format %{ "ucomisd $src1, $src2" %}
+  opcode(0x66, 0x0F, 0x2E);
+  ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, reg_mem(src1, src2));
+  ins_pipe(pipe_slow);
+%}
+
 instruct cmpD_cc_imm(rFlagsRegU cr, regD src1, immD src2)
 %{
   match(Set cr (CmpD src1 src2));
@@ -9801,6 +9962,16 @@
   ins_pipe(pipe_slow);
 %}
 
+instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src1, immD src2) %{
+  match(Set cr (CmpD src1 src2));
+
+  ins_cost(100);
+  format %{ "ucomisd $src1, [$src2]" %}
+  opcode(0x66, 0x0F, 0x2E);
+  ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, load_immD(src1, src2));
+  ins_pipe(pipe_slow);
+%}
+
 // Compare into -1,0,1
 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr)
 %{
@@ -11406,8 +11577,7 @@
 %}
 
 // Jump Direct Conditional - Label defines a relative address from Jcc+1
-instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl)
-%{
+instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{
   match(CountedLoopEnd cop cmp);
   effect(USE labl);
 
@@ -11420,14 +11590,12 @@
   ins_pc_relative(1);
 %}
 
-// Jump Direct Conditional - using unsigned comparison
-instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl)
-%{
-  match(If cop cmp);
+instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
+  match(CountedLoopEnd cop cmp);
   effect(USE labl);
 
-  ins_cost(300);
-  format %{ "j$cop,u   $labl" %}
+  ins_cost(200);
+  format %{ "j$cop,u   $labl\t# loop end" %}
   size(6);
   opcode(0x0F, 0x80);
   ins_encode(Jcc(cop, labl));
@@ -11435,6 +11603,73 @@
   ins_pc_relative(1);
 %}
 
+// Jump Direct Conditional - using unsigned comparison
+instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{
+  match(If cop cmp);
+  effect(USE labl);
+
+  ins_cost(300);
+  format %{ "j$cop,u  $labl" %}
+  size(6);
+  opcode(0x0F, 0x80);
+  ins_encode(Jcc(cop, labl));
+  ins_pipe(pipe_jcc);
+  ins_pc_relative(1);
+%}
+
+instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
+  match(If cop cmp);
+  effect(USE labl);
+
+  ins_cost(200);
+  format %{ "j$cop,u  $labl" %}
+  size(6);
+  opcode(0x0F, 0x80);
+  ins_encode(Jcc(cop, labl));
+  ins_pipe(pipe_jcc);
+  ins_pc_relative(1);
+%}
+
+instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{
+  match(If cop cmp);
+  effect(USE labl);
+
+  ins_cost(200);
+  format %{ $$template
+    if ($cop$$cmpcode == Assembler::notEqual) {
+      $$emit$$"jp,u   $labl\n\t"
+      $$emit$$"j$cop,u   $labl"
+    } else {
+      $$emit$$"jp,u   done\n\t"
+      $$emit$$"j$cop,u   $labl\n\t"
+      $$emit$$"done:"
+    }
+  %}
+  size(12);
+  opcode(0x0F, 0x80);
+  ins_encode %{
+    Label* l = $labl$$label;
+    $$$emit8$primary;
+    emit_cc(cbuf, $secondary, Assembler::parity);
+    int parity_disp = -1;
+    if ($cop$$cmpcode == Assembler::notEqual) {
+       // the two jumps 6 bytes apart so the jump distances are too
+       parity_disp = l ? (l->loc_pos() - (cbuf.code_size() + 4)) : 0;
+    } else if ($cop$$cmpcode == Assembler::equal) {
+       parity_disp = 6;
+    } else {
+       ShouldNotReachHere();
+    }
+    emit_d32(cbuf, parity_disp);
+    $$$emit8$primary;
+    emit_cc(cbuf, $secondary, $cop$$cmpcode);
+    int disp = l ? (l->loc_pos() - (cbuf.code_size() + 4)) : 0;
+    emit_d32(cbuf, disp);
+  %}
+  ins_pipe(pipe_jcc);
+  ins_pc_relative(1);
+%}
+
 // ============================================================================
 // The 2nd slow-half of a subtype check.  Scan the subklass's 2ndary
 // superklass array for an instance of the superklass.  Set a hidden
@@ -11505,8 +11740,7 @@
 // specific code section of the file.
 
 // Jump Direct - Label defines a relative address from JMP+1
-instruct jmpDir_short(label labl)
-%{
+instruct jmpDir_short(label labl) %{
   match(Goto);
   effect(USE labl);
 
@@ -11521,8 +11755,7 @@
 %}
 
 // Jump Direct Conditional - Label defines a relative address from Jcc+1
-instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl)
-%{
+instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{
   match(If cop cr);
   effect(USE labl);
 
@@ -11537,13 +11770,12 @@
 %}
 
 // Jump Direct Conditional - Label defines a relative address from Jcc+1
-instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl)
-%{
+instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{
   match(CountedLoopEnd cop cr);
   effect(USE labl);
 
   ins_cost(300);
-  format %{ "j$cop,s   $labl" %}
+  format %{ "j$cop,s   $labl\t# loop end" %}
   size(2);
   opcode(0x70);
   ins_encode(JccShort(cop, labl));
@@ -11553,12 +11785,40 @@
 %}
 
 // Jump Direct Conditional - Label defines a relative address from Jcc+1
-instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl)
-%{
+instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{
   match(CountedLoopEnd cop cmp);
   effect(USE labl);
 
   ins_cost(300);
+  format %{ "j$cop,us  $labl\t# loop end" %}
+  size(2);
+  opcode(0x70);
+  ins_encode(JccShort(cop, labl));
+  ins_pipe(pipe_jcc);
+  ins_pc_relative(1);
+  ins_short_branch(1);
+%}
+
+instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
+  match(CountedLoopEnd cop cmp);
+  effect(USE labl);
+
+  ins_cost(300);
+  format %{ "j$cop,us  $labl\t# loop end" %}
+  size(2);
+  opcode(0x70);
+  ins_encode(JccShort(cop, labl));
+  ins_pipe(pipe_jcc);
+  ins_pc_relative(1);
+  ins_short_branch(1);
+%}
+
+// Jump Direct Conditional - using unsigned comparison
+instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{
+  match(If cop cmp);
+  effect(USE labl);
+
+  ins_cost(300);
   format %{ "j$cop,us  $labl" %}
   size(2);
   opcode(0x70);
@@ -11568,9 +11828,7 @@
   ins_short_branch(1);
 %}
 
-// Jump Direct Conditional - using unsigned comparison
-instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl)
-%{
+instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
   match(If cop cmp);
   effect(USE labl);
 
@@ -11584,6 +11842,46 @@
   ins_short_branch(1);
 %}
 
+instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{
+  match(If cop cmp);
+  effect(USE labl);
+
+  ins_cost(300);
+  format %{ $$template
+    if ($cop$$cmpcode == Assembler::notEqual) {
+      $$emit$$"jp,u,s   $labl\n\t"
+      $$emit$$"j$cop,u,s   $labl"
+    } else {
+      $$emit$$"jp,u,s   done\n\t"
+      $$emit$$"j$cop,u,s  $labl\n\t"
+      $$emit$$"done:"
+    }
+  %}
+  size(4);
+  opcode(0x70);
+  ins_encode %{
+    Label* l = $labl$$label;
+    emit_cc(cbuf, $primary, Assembler::parity);
+    int parity_disp = -1;
+    if ($cop$$cmpcode == Assembler::notEqual) {
+      parity_disp = l ? (l->loc_pos() - (cbuf.code_size() + 1)) : 0;
+    } else if ($cop$$cmpcode == Assembler::equal) {
+      parity_disp = 2;
+    } else {
+      ShouldNotReachHere();
+    }
+    emit_d8(cbuf, parity_disp);
+    emit_cc(cbuf, $primary, $cop$$cmpcode);
+    int disp = l ? (l->loc_pos() - (cbuf.code_size() + 1)) : 0;
+    emit_d8(cbuf, disp);
+    assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp");
+    assert(-128 <= parity_disp && parity_disp <= 127, "Displacement too large for short jmp");
+  %}
+  ins_pipe(pipe_jcc);
+  ins_pc_relative(1);
+  ins_short_branch(1);
+%}
+
 // ============================================================================
 // inlined locking and unlocking
 
--- a/hotspot/src/os_cpu/linux_x86/vm/linux_x86_32.ad	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/os_cpu/linux_x86/vm/linux_x86_32.ad	Wed Jul 05 16:43:41 2017 +0200
@@ -103,16 +103,16 @@
 // This name is KNOWN by the ADLC and cannot be changed.
 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type
 // for this guy.
-instruct tlsLoadP(eAXRegP dst, eFlagsReg cr) %{
+instruct tlsLoadP(eRegP dst, eFlagsReg cr) %{
   match(Set dst (ThreadLocal));
   effect(DEF dst, KILL cr);
 
-  format %{ "MOV    EAX, Thread::current()" %}
+  format %{ "MOV    $dst, Thread::current()" %}
   ins_encode( linux_tlsencode(dst) );
   ins_pipe( ialu_reg_fat );
 %}
 
-instruct TLS(eAXRegP dst) %{
+instruct TLS(eRegP dst) %{
   match(Set dst (ThreadLocal));
 
   expand %{
--- a/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_32.ad	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_32.ad	Wed Jul 05 16:43:41 2017 +0200
@@ -110,16 +110,16 @@
 // This name is KNOWN by the ADLC and cannot be changed.
 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type
 // for this guy.
-instruct tlsLoadP(eAXRegP dst, eFlagsReg cr) %{
+instruct tlsLoadP(eRegP dst, eFlagsReg cr) %{
   match(Set dst (ThreadLocal));
   effect(DEF dst, KILL cr);
 
-  format %{ "MOV    EAX, Thread::current()" %}
+  format %{ "MOV    $dst, Thread::current()" %}
   ins_encode( solaris_tlsencode(dst) );
   ins_pipe( ialu_reg_fat );
 %}
 
-instruct TLS(eAXRegP dst) %{
+instruct TLS(eRegP dst) %{
   match(Set dst (ThreadLocal));
 
   expand %{
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponent.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponent.java	Wed Jul 05 16:43:41 2017 +0200
@@ -28,6 +28,7 @@
 import com.sun.hotspot.igv.data.services.InputGraphProvider;
 import java.awt.BorderLayout;
 import java.io.Serializable;
+import javax.swing.SwingUtilities;
 import org.openide.ErrorManager;
 import org.openide.explorer.ExplorerManager;
 import org.openide.explorer.ExplorerUtils;
@@ -151,14 +152,18 @@
     }
 
     public void resultChanged(LookupEvent lookupEvent) {
-        InputGraphProvider p = Lookup.getDefault().lookup(InputGraphProvider.class);
+        final InputGraphProvider p = Lookup.getDefault().lookup(InputGraphProvider.class);
         if (p != null) {
+            SwingUtilities.invokeLater(new Runnable() {
+                public void run() {
             InputGraph graph = p.getGraph();
             if (graph != null) {
                 Group g = graph.getGroup();
                 rootNode.update(graph, g.getMethod());
             }
         }
+            });
+        }
     }
 
     final static class ResolvableHelper implements Serializable {
--- a/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowScene.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowScene.java	Wed Jul 05 16:43:41 2017 +0200
@@ -33,7 +33,7 @@
 import java.awt.Rectangle;
 import java.util.ArrayList;
 import java.util.HashSet;
-import java.util.Hashtable;
+import java.util.HashMap;
 import java.util.Set;
 import javax.swing.BorderFactory;
 import org.netbeans.api.visual.action.ActionFactory;
@@ -44,7 +44,6 @@
 import org.netbeans.api.visual.action.WidgetAction;
 import org.netbeans.api.visual.anchor.AnchorFactory;
 import org.netbeans.api.visual.anchor.AnchorShape;
-import com.sun.hotspot.igv.controlflow.HierarchicalGraphLayout;
 import org.netbeans.api.visual.layout.LayoutFactory;
 import org.netbeans.api.visual.router.RouterFactory;
 import org.netbeans.api.visual.widget.LayerWidget;
@@ -61,8 +60,8 @@
  */
 public class ControlFlowScene extends GraphScene<InputBlock, InputBlockEdge> implements SelectProvider, MoveProvider, RectangularSelectDecorator, RectangularSelectProvider {
 
-    private Set<BlockWidget> selection;
-    private Hashtable<InputBlock, BlockWidget> blockMap;
+    private HashSet<BlockWidget> selection;
+    private HashMap<InputBlock, BlockWidget> blockMap;
     private InputGraph oldGraph;
     private LayerWidget edgeLayer;
     private LayerWidget mainLayer;
--- a/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowTopComponent.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowTopComponent.java	Wed Jul 05 16:43:41 2017 +0200
@@ -28,6 +28,7 @@
 import java.awt.BorderLayout;
 import java.io.Serializable;
 import javax.swing.JScrollPane;
+import javax.swing.SwingUtilities;
 import org.openide.ErrorManager;
 import org.openide.util.Lookup;
 import org.openide.util.LookupEvent;
@@ -143,13 +144,17 @@
 
     public void resultChanged(LookupEvent lookupEvent) {
 
-        InputGraphProvider p = Lookup.getDefault().lookup(InputGraphProvider.class);
+        final InputGraphProvider p = Lookup.getDefault().lookup(InputGraphProvider.class);
         if (p != null) {
+            SwingUtilities.invokeLater(new Runnable() {
+                public void run() {
             InputGraph g = p.getGraph();
             if (g != null) {
                 scene.setGraph(g);
             }
         }
+            });
+        }
     }
 
     @Override
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/FolderNode.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/FolderNode.java	Wed Jul 05 16:43:41 2017 +0200
@@ -24,6 +24,7 @@
 package com.sun.hotspot.igv.coordinator;
 
 import com.sun.hotspot.igv.coordinator.actions.RemoveCookie;
+import com.sun.hotspot.igv.data.ChangedListener;
 import com.sun.hotspot.igv.data.Group;
 import com.sun.hotspot.igv.data.services.GroupOrganizer;
 import com.sun.hotspot.igv.data.InputGraph;
@@ -50,17 +51,24 @@
     private List<String> subFolders;
     private FolderChildren children;
 
-    private static class FolderChildren extends Children.Keys {
+    private static class FolderChildren extends Children.Keys implements ChangedListener<Group> {
 
         private FolderNode parent;
+        private List<Group> registeredGroups;
 
         public void setParent(FolderNode parent) {
             this.parent = parent;
+            this.registeredGroups = new ArrayList<Group>();
         }
 
         @Override
         protected Node[] createNodes(Object arg0) {
 
+            for(Group g : registeredGroups) {
+                g.getChangedEvent().removeListener(this);
+            }
+            registeredGroups.clear();
+
             Pair<String, List<Group>> p = (Pair<String, List<Group>>) arg0;
             if (p.getLeft().length() == 0) {
 
@@ -69,6 +77,8 @@
                     for (InputGraph graph : g.getGraphs()) {
                         curNodes.add(new GraphNode(graph));
                     }
+                    g.getChangedEvent().addListener(this);
+                    registeredGroups.add(g);
                 }
 
                 Node[] result = new Node[curNodes.size()];
@@ -85,7 +95,13 @@
         @Override
         public void addNotify() {
             this.setKeys(parent.structure);
+        }
 
+        public void changed(Group source) {
+            List<Pair<String, List<Group>>> newStructure = new ArrayList<Pair<String, List<Group>>>();
+            for(Pair<String, List<Group>> p : parent.structure) {
+                refreshKey(p);
+            }
         }
     }
 
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/GraphDocument.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/GraphDocument.java	Wed Jul 05 16:43:41 2017 +0200
@@ -31,7 +31,7 @@
  *
  * @author Thomas Wuerthinger
  */
-public class GraphDocument extends Properties.Object implements ChangedEventProvider<GraphDocument> {
+public class GraphDocument extends Properties.Entity implements ChangedEventProvider<GraphDocument> {
 
     private List<Group> groups;
     private ChangedEvent<GraphDocument> changedEvent;
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Group.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Group.java	Wed Jul 05 16:43:41 2017 +0200
@@ -37,7 +37,7 @@
  *
  * @author Thomas Wuerthinger
  */
-public class Group extends Properties.Object implements ChangedEventProvider<Group> {
+public class Group extends Properties.Entity implements ChangedEventProvider<Group> {
 
     private List<InputGraph> graphs;
     private transient ChangedEvent<Group> changedEvent;
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputGraph.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputGraph.java	Wed Jul 05 16:43:41 2017 +0200
@@ -23,26 +23,25 @@
  */
 package com.sun.hotspot.igv.data;
 
-import com.sun.hotspot.igv.data.Properties;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
-import java.util.Hashtable;
+import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 
 /**
  *
  * @author Thomas Wuerthinger
  */
-public class InputGraph extends Properties.Object {
+public class InputGraph extends Properties.Entity {
 
-    private Map<Integer, InputNode> nodes;
-    private Set<InputEdge> edges;
+    private HashMap<Integer, InputNode> nodes;
+    private ArrayList<InputEdge> edges;
     private Group parent;
-    private Map<String, InputBlock> blocks;
-    private Map<Integer, InputBlock> nodeToBlock;
+    private HashMap<String, InputBlock> blocks;
+    private HashMap<Integer, InputBlock> nodeToBlock;
     private boolean isDifferenceGraph;
 
     public InputGraph(Group parent) {
@@ -61,10 +60,10 @@
     public InputGraph(Group parent, InputGraph last, String name) {
         this.parent = parent;
         setName(name);
-        nodes = new Hashtable<Integer, InputNode>();
-        edges = new HashSet<InputEdge>();
-        blocks = new Hashtable<String, InputBlock>();
-        nodeToBlock = new Hashtable<Integer, InputBlock>();
+        nodes = new HashMap<Integer, InputNode>();
+        edges = new ArrayList<InputEdge>();
+        blocks = new HashMap<String, InputBlock>();
+        nodeToBlock = new HashMap<Integer, InputBlock>();
         if (last != null) {
 
             for (InputNode n : last.getNodes()) {
@@ -182,8 +181,8 @@
         return nodes.remove(index);
     }
 
-    public Set<InputEdge> getEdges() {
-        return Collections.unmodifiableSet(edges);
+    public Collection<InputEdge> getEdges() {
+        return Collections.unmodifiableList(edges);
     }
 
     public void removeEdge(InputEdge c) {
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputMethod.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputMethod.java	Wed Jul 05 16:43:41 2017 +0200
@@ -32,7 +32,7 @@
  *
  * @author Thomas Wuerthinger
  */
-public class InputMethod extends Properties.Object {
+public class InputMethod extends Properties.Entity {
 
     private String name;
     private int bci;
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputNode.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputNode.java	Wed Jul 05 16:43:41 2017 +0200
@@ -27,7 +27,7 @@
  *
  * @author Thomas Wuerthinger
  */
-public class InputNode extends Properties.Object {
+public class InputNode extends Properties.Entity {
 
     private int id;
 
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Properties.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Properties.java	Wed Jul 05 16:43:41 2017 +0200
@@ -26,24 +26,22 @@
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
-import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+
 /**
  *
  * @author Thomas Wuerthinger
  */
-public class Properties implements Serializable {
+public class Properties implements Serializable, Iterable<Property> {
 
     public static final long serialVersionUID = 1L;
-    private Map<String, Property> map;
+    private String[] map = new String[4];
 
     public Properties() {
-        map = new HashMap<String, Property>(5);
     }
 
     @Override
@@ -54,10 +52,7 @@
 
         Properties p = (Properties) o;
 
-        if (getProperties().size() != p.getProperties().size()) {
-            return false;
-        }
-        for (Property prop : getProperties()) {
+        for (Property prop : this) {
             String value = p.get(prop.getName());
             if (value == null || !value.equals(prop.getValue())) {
                 return false;
@@ -75,32 +70,33 @@
 
     public Properties(String name, String value) {
         this();
-        this.add(new Property(name, value));
+        this.setProperty(name, value);
     }
 
     public Properties(String name, String value, String name1, String value1) {
         this(name, value);
-        this.add(new Property(name1, value1));
+        this.setProperty(name1, value1);
     }
 
     public Properties(String name, String value, String name1, String value1, String name2, String value2) {
         this(name, value, name1, value1);
-        this.add(new Property(name2, value2));
+        this.setProperty(name2, value2);
     }
 
     public Properties(Properties p) {
-        map = new HashMap<String, Property>(p.map);
+        map = new String[p.map.length];
+        System.arraycopy(map, 0, p.map, 0, p.map.length);
     }
 
-    public static class Object implements Provider {
+    public static class Entity implements Provider {
 
         private Properties properties;
 
-        public Object() {
+        public Entity() {
             properties = new Properties();
         }
 
-        public Object(Properties.Object object) {
+        public Entity(Properties.Entity object) {
             properties = new Properties(object.getProperties());
         }
 
@@ -109,6 +105,14 @@
         }
     }
 
+    private String getProperty(String key) {
+        for (int i = 0; i < map.length; i += 2)
+            if (map[i] != null && map[i].equals(key)) {
+                return map[i + 1];
+            }
+        return null;
+    }
+
     public interface PropertyMatcher {
 
         String getName();
@@ -173,13 +177,15 @@
     }
 
     public Property selectSingle(PropertyMatcher matcher) {
-
-        Property p = this.map.get(matcher.getName());
-        if (p == null) {
-            return null;
+        String value = null;
+        for (int i = 0; i < map.length; i += 2) {
+            if (map[i] != null && matcher.getName().equals(map[i]))  {
+                value = map[i + 1];
+                break;
+            }
         }
-        if (matcher.match(p.getValue())) {
-            return p;
+        if (value != null && matcher.match(value)) {
+            return new Property(matcher.getName(), value);
         } else {
             return null;
         }
@@ -194,8 +200,11 @@
     public String toString() {
         StringBuilder sb = new StringBuilder();
         sb.append("[");
-        for (Property p : map.values()) {
-            sb.append(p.toString());
+        for (int i = 0; i < map.length; i += 2) {
+            if (map[i + 1] != null) {
+                String p = map[i + 1];
+                sb.append(map[i] + " = " + map[i + 1] + "; ");
+            }
         }
         return sb.append("]").toString();
     }
@@ -241,41 +250,51 @@
     }
 
     public String get(String key) {
-        Property p = map.get(key);
-        if (p == null) {
-            return null;
-        } else {
-            return p.getValue();
+        for (int i = 0; i < map.length; i += 2) {
+            if (map[i] != null && map[i].equals(key)) {
+                return map[i + 1];
+            }
         }
+        return null;
     }
 
-    public String getProperty(String string) {
-        return get(string);
+    public void setProperty(String name, String value) {
+        for (int i = 0; i < map.length; i += 2) {
+            if (map[i] != null && map[i].equals(name)) {
+                String p = map[i + 1];
+                if (value == null) {
+                    // remove this property
+                    map[i] = null;
+                    map[i + 1] = null;
+                } else {
+                    map[i + 1] = value;
+                }
+                return;
+            }
+        }
+        if (value == null) {
+            return;
+        }
+        for (int i = 0; i < map.length; i += 2) {
+            if (map[i] == null) {
+                map[i] = name;
+                map[i + 1] = value;
+                return;
+            }
+        }
+        String[] newMap = new String[map.length + 4];
+        System.arraycopy(map, 0, newMap, 0, map.length);
+        newMap[map.length] = name;
+        newMap[map.length + 1] = value;
+        map = newMap;
     }
 
-    public Property setProperty(String name, String value) {
-
-        if (value == null) {
-            // remove this property
-            return map.remove(name);
-        } else {
-            Property p = map.get(name);
-            if (p == null) {
-                p = new Property(name, value);
-                map.put(name, p);
-            } else {
-                p.setValue(value);
-            }
-            return p;
-        }
-    }
-
-    public Collection<Property> getProperties() {
-        return Collections.unmodifiableCollection(map.values());
+    public  Iterator<Property> getProperties() {
+        return iterator();
     }
 
     public void add(Properties properties) {
-        for (Property p : properties.getProperties()) {
+        for (Property p : properties) {
             add(p);
         }
     }
@@ -283,6 +302,35 @@
     public void add(Property property) {
         assert property.getName() != null;
         assert property.getValue() != null;
-        map.put(property.getName(), property);
+        setProperty(property.getName(), property.getValue());
+    }
+    class PropertiesIterator implements Iterator<Property>, Iterable<Property> {
+        public Iterator<Property> iterator() {
+                return this;
+        }
+
+        int index;
+
+        public boolean hasNext() {
+            while (index < map.length && map[index + 1] == null)
+                index += 2;
+            return index < map.length;
+        }
+
+        public Property next() {
+            if (index < map.length) {
+                index += 2;
+                return new Property(map[index - 2], map[index - 1]);
+            }
+            return null;
+        }
+
+        public void remove() {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+    }
+    public Iterator<Property> iterator() {
+        return new PropertiesIterator();
     }
 }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Property.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Property.java	Wed Jul 05 16:43:41 2017 +0200
@@ -32,18 +32,19 @@
 public class Property implements Serializable {
 
     public static final long serialVersionUID = 1L;
+
     private String name;
     private String value;
 
-    public Property() {
+    private Property() {
         this(null, null);
     }
 
-    public Property(Property p) {
+    private Property(Property p) {
         this(p.getName(), p.getValue());
     }
 
-    public Property(String name) {
+    private Property(String name) {
         this(name, null);
     }
 
@@ -60,16 +61,19 @@
         return value;
     }
 
-    public void setName(String s) {
-        this.name = s;
-    }
-
-    public void setValue(String s) {
-        this.value = s;
-    }
-
     @Override
     public String toString() {
         return name + " = " + value + "; ";
     }
+
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof Property)) return false;
+        Property p2 = (Property)o;
+        return name.equals(p2.name) && value.equals(p2.value);
+    }
+    @Override
+    public int hashCode() {
+        return name.hashCode() + value == null ? 0 : value.hashCode();
+    }
 }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/Parser.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/Parser.java	Wed Jul 05 16:43:41 2017 +0200
@@ -38,6 +38,7 @@
 import com.sun.hotspot.igv.data.serialization.XMLParser.ParseMonitor;
 import com.sun.hotspot.igv.data.serialization.XMLParser.TopElementHandler;
 import java.io.IOException;
+import java.util.HashMap;
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
 import org.xml.sax.XMLReader;
@@ -88,6 +89,18 @@
     private TopElementHandler xmlDocument = new TopElementHandler();
     private boolean difference;
     private GroupCallback groupCallback;
+    private HashMap<String, Integer> idCache = new HashMap<String, Integer>();
+    private int maxId = 0;
+
+    private int lookupID(String i) {
+        Integer id = idCache.get(i);
+        if (id == null) {
+            id = maxId++;
+            idCache.put(i, id);
+        }
+        return id.intValue();
+    }
+
     // <graphDocument>
     private ElementHandler<GraphDocument, Object> topHandler = new ElementHandler<GraphDocument, Object>(TOP_ELEMENT) {
 
@@ -187,13 +200,13 @@
                 previous = null;
             }
             InputGraph curGraph = new InputGraph(getParentObject(), previous, name);
-            getParentObject().addGraph(curGraph);
             this.graph = curGraph;
             return curGraph;
         }
 
         @Override
         protected void end(String text) throws SAXException {
+            getParentObject().addGraph(graph);
             graph.resolveBlockLinks();
         }
     };
@@ -207,7 +220,7 @@
         @Override
         protected InputBlock start() throws SAXException {
             InputGraph graph = getParentObject();
-            String name = readRequiredAttribute(BLOCK_NAME_PROPERTY);
+            String name = readRequiredAttribute(BLOCK_NAME_PROPERTY).intern();
             InputBlock b = new InputBlock(getParentObject(), name);
             graph.addBlock(b);
             return b;
@@ -224,7 +237,7 @@
 
             int id = 0;
             try {
-                id = Integer.parseInt(s);
+                id = lookupID(s);
             } catch (NumberFormatException e) {
                 throw new SAXException(e);
             }
@@ -252,7 +265,7 @@
             String s = readRequiredAttribute(NODE_ID_PROPERTY);
             int id = 0;
             try {
-                id = Integer.parseInt(s);
+                id = lookupID(s);
             } catch (NumberFormatException e) {
                 throw new SAXException(e);
             }
@@ -269,7 +282,7 @@
             String s = readRequiredAttribute(NODE_ID_PROPERTY);
             int id = 0;
             try {
-                id = Integer.parseInt(s);
+                id = lookupID(s);
             } catch (NumberFormatException e) {
                 throw new SAXException(e);
             }
@@ -280,7 +293,7 @@
     private HandoverElementHandler<InputGraph> edgesHandler = new HandoverElementHandler<InputGraph>(EDGES_ELEMENT);
 
     // Local class for edge elements
-    private static class EdgeElementHandler extends ElementHandler<InputEdge, InputGraph> {
+    private class EdgeElementHandler extends ElementHandler<InputEdge, InputGraph> {
 
         public EdgeElementHandler(String name) {
             super(name);
@@ -298,8 +311,8 @@
                     toIndex = Integer.parseInt(toIndexString);
                 }
 
-                from = Integer.parseInt(readRequiredAttribute(FROM_PROPERTY));
-                to = Integer.parseInt(readRequiredAttribute(TO_PROPERTY));
+                from = lookupID(readRequiredAttribute(FROM_PROPERTY));
+                to = lookupID(readRequiredAttribute(TO_PROPERTY));
             } catch (NumberFormatException e) {
                 throw new SAXException(e);
             }
@@ -344,18 +357,16 @@
         }
     };
     // <property>
-    private ElementHandler<Property, Properties.Provider> propertyHandler = new XMLParser.ElementHandler<Property, Properties.Provider>(PROPERTY_ELEMENT, true) {
+    private ElementHandler<String, Properties.Provider> propertyHandler = new XMLParser.ElementHandler<String, Properties.Provider>(PROPERTY_ELEMENT, true) {
 
         @Override
-        public Property start() throws SAXException {
-            String value = "";
-            String name = readRequiredAttribute(PROPERTY_NAME_PROPERTY).intern();
-            return getParentObject().getProperties().setProperty(name, value);
+        public String start() throws SAXException {
+            return readRequiredAttribute(PROPERTY_NAME_PROPERTY).intern();
         }
 
         @Override
         public void end(String text) {
-            getObject().setValue(text.trim().intern());
+            getParentObject().getProperties().setProperty(getObject(), text.trim().intern());
         }
     };
 
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/Printer.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/Printer.java	Wed Jul 05 16:43:41 2017 +0200
@@ -67,7 +67,7 @@
 
     private void export(XMLWriter writer, Group g) throws IOException {
         Properties attributes = new Properties();
-        attributes.add(new Property("difference", Boolean.toString(true)));
+        attributes.setProperty("difference", Boolean.toString(true));
         writer.startTag(Parser.GROUP_ELEMENT, attributes);
         writer.writeProperties(g.getProperties());
 
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/XMLParser.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/XMLParser.java	Wed Jul 05 16:43:41 2017 +0200
@@ -25,7 +25,7 @@
 
 import com.sun.hotspot.igv.data.Property;
 import com.sun.hotspot.igv.data.Properties;
-import java.util.Hashtable;
+import java.util.HashMap;
 import java.util.Stack;
 import org.xml.sax.Attributes;
 import org.xml.sax.ContentHandler;
@@ -89,7 +89,7 @@
         private Attributes attr;
         private StringBuilder currentText;
         private ParseMonitor monitor;
-        private Hashtable<String, ElementHandler<?, ? super T>> hashtable;
+        private HashMap<String, ElementHandler<?, ? super T>> hashtable;
         private boolean needsText;
         private ElementHandler<P, ?> parentElement;
 
@@ -110,7 +110,7 @@
         }
 
         public ElementHandler(String name, boolean needsText) {
-            this.hashtable = new Hashtable<String, ElementHandler<?, ? super T>>();
+            this.hashtable = new HashMap<String, ElementHandler<?, ? super T>>();
             this.name = name;
             this.needsText = needsText;
         }
@@ -153,7 +153,7 @@
             for (int i = 0; i < length; i++) {
                 String val = attr.getValue(i).intern();
                 String localName = attr.getLocalName(i).intern();
-                p.add(new Property(val, localName));
+                p.setProperty(val, localName);
             }
         }
 
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/XMLWriter.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/XMLWriter.java	Wed Jul 05 16:43:41 2017 +0200
@@ -89,7 +89,7 @@
         inner.write("<" + name);
         elementStack.push(name);
 
-        for (Property p : attributes.getProperties()) {
+        for (Property p : attributes) {
             inner.write(" " + p.getName() + "=\"");
             write(p.getValue().toCharArray());
             inner.write("\"");
@@ -101,7 +101,7 @@
     public void simpleTag(String name, Properties attributes) throws IOException {
         inner.write("<" + name);
 
-        for (Property p : attributes.getProperties()) {
+        for (Property p : attributes) {
             inner.write(" " + p.getName() + "=\"");
             write(p.getValue().toCharArray());
             inner.write("\"");
@@ -111,13 +111,13 @@
     }
 
     public void writeProperties(Properties props) throws IOException {
-        if (props.getProperties().size() == 0) {
+        if (props.getProperties().hasNext() == false) {
             return;
         }
 
         startTag(Parser.PROPERTIES_ELEMENT);
 
-        for (Property p : props.getProperties()) {
+        for (Property p : props) {
             startTag(Parser.PROPERTY_ELEMENT, new Properties(Parser.PROPERTY_NAME_PROPERTY, p.getName()));
             this.write(p.getValue().toCharArray());
             endTag();
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Difference/src/com/sun/hotspot/igv/difference/Difference.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Difference/src/com/sun/hotspot/igv/difference/Difference.java	Wed Jul 05 16:43:41 2017 +0200
@@ -29,6 +29,7 @@
 import com.sun.hotspot.igv.data.InputGraph;
 import com.sun.hotspot.igv.data.InputNode;
 import com.sun.hotspot.igv.data.Property;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
@@ -124,8 +125,8 @@
             inputNodeMap.put(n, n2);
         }
 
-        Set<InputEdge> edgesA = a.getEdges();
-        Set<InputEdge> edgesB = b.getEdges();
+        Collection<InputEdge> edgesA = a.getEdges();
+        Collection<InputEdge> edgesB = b.getEdges();
 
         Set<InputEdge> newEdges = new HashSet<InputEdge>();
 
@@ -182,7 +183,7 @@
         public double getValue() {
 
             double result = 0.0;
-            for (Property p : n1.getProperties().getProperties()) {
+            for (Property p : n1.getProperties()) {
                 double faktor = 1.0;
                 for (String forbidden : IGNORE_PROPERTIES) {
                     if (p.getName().equals(forbidden)) {
@@ -287,34 +288,34 @@
     private static void markAsChanged(InputNode n, InputNode firstNode, InputNode otherNode) {
 
         boolean difference = false;
-        for (Property p : otherNode.getProperties().getProperties()) {
-            String s = firstNode.getProperties().getProperty(p.getName());
+        for (Property p : otherNode.getProperties()) {
+            String s = firstNode.getProperties().get(p.getName());
             if (!p.getValue().equals(s)) {
                 difference = true;
-                n.getProperties().add(new Property(OLD_PREFIX + p.getName(), p.getValue()));
+                n.getProperties().setProperty(OLD_PREFIX + p.getName(), p.getValue());
             }
         }
 
-        for (Property p : firstNode.getProperties().getProperties()) {
-            String s = otherNode.getProperties().getProperty(p.getName());
+        for (Property p : firstNode.getProperties()) {
+            String s = otherNode.getProperties().get(p.getName());
             if (s == null && p.getValue().length() > 0) {
                 difference = true;
-                n.getProperties().add(new Property(OLD_PREFIX + p.getName(), ""));
+                n.getProperties().setProperty(OLD_PREFIX + p.getName(), "");
             }
         }
 
         if (difference) {
-            n.getProperties().add(new Property(PROPERTY_STATE, VALUE_CHANGED));
+            n.getProperties().setProperty(PROPERTY_STATE, VALUE_CHANGED);
         } else {
-            n.getProperties().add(new Property(PROPERTY_STATE, VALUE_SAME));
+            n.getProperties().setProperty(PROPERTY_STATE, VALUE_SAME);
         }
     }
 
     private static void markAsDeleted(InputNode n) {
-        n.getProperties().add(new Property(PROPERTY_STATE, VALUE_DELETED));
+        n.getProperties().setProperty(PROPERTY_STATE, VALUE_DELETED);
     }
 
     private static void markAsNew(InputNode n) {
-        n.getProperties().add(new Property(PROPERTY_STATE, VALUE_NEW));
+        n.getProperties().setProperty(PROPERTY_STATE, VALUE_NEW);
     }
 }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Filter/manifest.mf	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/manifest.mf	Wed Jul 05 16:43:41 2017 +0200
@@ -1,6 +1,6 @@
-Manifest-Version: 1.0
-OpenIDE-Module: com.sun.hotspot.igv.filter
-OpenIDE-Module-Layer: com/sun/hotspot/igv/filter/layer.xml
-OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/filter/Bundle.properties
-OpenIDE-Module-Specification-Version: 1.0
-
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.filter
+OpenIDE-Module-Layer: com/sun/hotspot/igv/filter/layer.xml
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/filter/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/CustomFilter.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/CustomFilter.java	Wed Jul 05 16:43:41 2017 +0200
@@ -25,7 +25,6 @@
 package com.sun.hotspot.igv.filter;
 
 import com.sun.hotspot.igv.graph.Diagram;
-import com.sun.hotspot.igv.data.Property;
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStream;
@@ -56,7 +55,7 @@
     public CustomFilter(String name, String code) {
         this.name = name;
         this.code = code;
-        getProperties().add(new Property("name", name));
+        getProperties().setProperty("name", name);
     }
 
     public String getName() {
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/SplitFilter.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/SplitFilter.java	Wed Jul 05 16:43:41 2017 +0200
@@ -56,8 +56,8 @@
             for (OutputSlot os : f.getOutputSlots()) {
                 for (Connection c : os.getConnections()) {
                     InputSlot is = c.getInputSlot();
-                    is.setName(f.getProperties().getProperty("dump_spec"));
-                    String s = f.getProperties().getProperty("short_name");
+                    is.setName(f.getProperties().get("dump_spec"));
+                    String s = f.getProperties().get("short_name");
                     if (s != null) {
                         is.setShortName(s);
                     }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Diagram.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Diagram.java	Wed Jul 05 16:43:41 2017 +0200
@@ -35,7 +35,7 @@
 import java.util.Comparator;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Hashtable;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -126,7 +126,7 @@
         d.updateBlocks();
 
         Collection<InputNode> nodes = graph.getNodes();
-        Hashtable<Integer, Figure> figureHash = new Hashtable<Integer, Figure>();
+        HashMap<Integer, Figure> figureHash = new HashMap<Integer, Figure>();
         for (InputNode n : nodes) {
             Figure f = d.createFigure();
             f.getSource().addSourceNode(n);
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Figure.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Figure.java	Wed Jul 05 16:43:41 2017 +0200
@@ -42,7 +42,7 @@
  *
  * @author Thomas Wuerthinger
  */
-public class Figure extends Properties.Object implements Source.Provider, Vertex {
+public class Figure extends Properties.Entity implements Source.Provider, Vertex {
 
     public static final int INSET = 6;
     public static final int SLOT_WIDTH = 10;
--- a/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/Graph.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/Graph.java	Wed Jul 05 16:43:41 2017 +0200
@@ -26,7 +26,7 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.Hashtable;
+import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Queue;
@@ -37,13 +37,13 @@
  */
 public class Graph<N, E> {
 
-    private Hashtable<Object, Node<N, E>> nodes;
-    private Hashtable<Object, Edge<N, E>> edges;
+    private HashMap<Object, Node<N, E>> nodes;
+    private HashMap<Object, Edge<N, E>> edges;
     private List<Node<N, E>> nodeList;
 
     public Graph() {
-        nodes = new Hashtable<Object, Node<N, E>>();
-        edges = new Hashtable<Object, Edge<N, E>>();
+        nodes = new HashMap<Object, Node<N, E>>();
+        edges = new HashMap<Object, Edge<N, E>>();
         nodeList = new ArrayList<Node<N, E>>();
     }
 
--- a/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/HierarchicalClusterLayoutManager.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/HierarchicalClusterLayoutManager.java	Wed Jul 05 16:43:41 2017 +0200
@@ -25,7 +25,7 @@
 
 import java.awt.Point;
 import java.awt.Rectangle;
-import java.util.Hashtable;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Set;
 import java.util.ArrayList;
@@ -69,19 +69,19 @@
 
         assert graph.verify();
 
-        Hashtable<Cluster, List<Vertex>> lists = new Hashtable<Cluster, List<Vertex>>();
-        Hashtable<Cluster, List<Link>> listsConnection = new Hashtable<Cluster, List<Link>>();
-        Hashtable<Cluster, Hashtable<Port, ClusterInputSlotNode>> clusterInputSlotHash = new Hashtable<Cluster, Hashtable<Port, ClusterInputSlotNode>>();
-        Hashtable<Cluster, Hashtable<Port, ClusterOutputSlotNode>> clusterOutputSlotHash = new Hashtable<Cluster, Hashtable<Port, ClusterOutputSlotNode>>();
+        HashMap<Cluster, List<Vertex>> lists = new HashMap<Cluster, List<Vertex>>();
+        HashMap<Cluster, List<Link>> listsConnection = new HashMap<Cluster, List<Link>>();
+        HashMap<Cluster, HashMap<Port, ClusterInputSlotNode>> clusterInputSlotHash = new HashMap<Cluster, HashMap<Port, ClusterInputSlotNode>>();
+        HashMap<Cluster, HashMap<Port, ClusterOutputSlotNode>> clusterOutputSlotHash = new HashMap<Cluster, HashMap<Port, ClusterOutputSlotNode>>();
 
-        Hashtable<Cluster, ClusterNode> clusterNodes = new Hashtable<Cluster, ClusterNode>();
-        Hashtable<Cluster, Set<ClusterInputSlotNode>> clusterInputSlotSet = new Hashtable<Cluster, Set<ClusterInputSlotNode>>();
-        Hashtable<Cluster, Set<ClusterOutputSlotNode>> clusterOutputSlotSet = new Hashtable<Cluster, Set<ClusterOutputSlotNode>>();
+        HashMap<Cluster, ClusterNode> clusterNodes = new HashMap<Cluster, ClusterNode>();
+        HashMap<Cluster, Set<ClusterInputSlotNode>> clusterInputSlotSet = new HashMap<Cluster, Set<ClusterInputSlotNode>>();
+        HashMap<Cluster, Set<ClusterOutputSlotNode>> clusterOutputSlotSet = new HashMap<Cluster, Set<ClusterOutputSlotNode>>();
         Set<Link> clusterEdges = new HashSet<Link>();
         Set<Link> interClusterEdges = new HashSet<Link>();
-        Hashtable<Link, ClusterOutgoingConnection> linkClusterOutgoingConnection = new Hashtable<Link, ClusterOutgoingConnection>();
-        Hashtable<Link, InterClusterConnection> linkInterClusterConnection = new Hashtable<Link, InterClusterConnection>();
-        Hashtable<Link, ClusterIngoingConnection> linkClusterIngoingConnection = new Hashtable<Link, ClusterIngoingConnection>();
+        HashMap<Link, ClusterOutgoingConnection> linkClusterOutgoingConnection = new HashMap<Link, ClusterOutgoingConnection>();
+        HashMap<Link, InterClusterConnection> linkInterClusterConnection = new HashMap<Link, InterClusterConnection>();
+        HashMap<Link, ClusterIngoingConnection> linkClusterIngoingConnection = new HashMap<Link, ClusterIngoingConnection>();
         Set<ClusterNode> clusterNodeSet = new HashSet<ClusterNode>();
 
         Set<Cluster> cluster = graph.getClusters();
@@ -89,8 +89,8 @@
         for (Cluster c : cluster) {
             lists.put(c, new ArrayList<Vertex>());
             listsConnection.put(c, new ArrayList<Link>());
-            clusterInputSlotHash.put(c, new Hashtable<Port, ClusterInputSlotNode>());
-            clusterOutputSlotHash.put(c, new Hashtable<Port, ClusterOutputSlotNode>());
+            clusterInputSlotHash.put(c, new HashMap<Port, ClusterInputSlotNode>());
+            clusterOutputSlotHash.put(c, new HashMap<Port, ClusterOutputSlotNode>());
             clusterOutputSlotSet.put(c, new TreeSet<ClusterOutputSlotNode>());
             clusterInputSlotSet.put(c, new TreeSet<ClusterInputSlotNode>());
             ClusterNode cn = new ClusterNode(c, "" + z);
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Layout/src/com/sun/hotspot/igv/layout/LayoutGraph.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Layout/src/com/sun/hotspot/igv/layout/LayoutGraph.java	Wed Jul 05 16:43:41 2017 +0200
@@ -24,7 +24,7 @@
 package com.sun.hotspot.igv.layout;
 
 import java.util.HashSet;
-import java.util.Hashtable;
+import java.util.HashMap;
 import java.util.Set;
 import java.util.SortedSet;
 import java.util.TreeSet;
@@ -37,9 +37,9 @@
 
     private Set<? extends Link> links;
     private SortedSet<Vertex> vertices;
-    private Hashtable<Vertex, Set<Port>> inputPorts;
-    private Hashtable<Vertex, Set<Port>> outputPorts;
-    private Hashtable<Port, Set<Link>> portLinks;
+    private HashMap<Vertex, Set<Port>> inputPorts;
+    private HashMap<Vertex, Set<Port>> outputPorts;
+    private HashMap<Port, Set<Link>> portLinks;
 
     public LayoutGraph(Set<? extends Link> links) {
         this(links, new HashSet<Vertex>());
@@ -50,9 +50,9 @@
         assert verify();
 
         vertices = new TreeSet<Vertex>();
-        portLinks = new Hashtable<Port, Set<Link>>();
-        inputPorts = new Hashtable<Vertex, Set<Port>>();
-        outputPorts = new Hashtable<Vertex, Set<Port>>();
+        portLinks = new HashMap<Port, Set<Link>>();
+        inputPorts = new HashMap<Vertex, Set<Port>>();
+        outputPorts = new HashMap<Vertex, Set<Port>>();
 
         for (Link l : links) {
             Port p = l.getFrom();
--- a/hotspot/src/share/tools/IdealGraphVisualizer/README	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/README	Wed Jul 05 16:43:41 2017 +0200
@@ -5,21 +5,16 @@
 was the primary target of the tool.  The tool itself is fairly general
 with only a few modules that contain C2 specific elements.
 
-The tool is built on top of the NetBeans 6.0 rich client
+The tool is built on top of the NetBeans 6.1 rich client
 infrastructure and so requires NetBeans to build.  It currently
 requires Java 6 to run as it needs support for JavaScript for its
 filtering mechanism and assumes it's built into the platform.  It
-should build out of the box whit NetBeans 6 and Java 6 or later.  It's
-possible to run it on 1.5 by including Rhino on the classpath though
-that currently isn't working correctly.  Support for exporting graphs
-as SVG can be enabled by adding batik to the classpath which isn't
-included by default.
-
-It can be built on top of NetBeans 6.1 if you change the required
-modules to be platform8 instead of platform7.  The tool could run on
-JDK 1.5 with some reworking of the how the JavaScript support is
-enabled but currently it requires some tweaking of the setup.  This
-will be fixed in a later setup.
+should build out of the box with NetBeans 6.1 and Java 6 or later.
+It's possible to run it on 1.5 by including Rhino on the classpath
+though that currently isn't working correctly.  Support for exporting
+graphs as SVG can be enabled by adding batik to the classpath which
+isn't included by default.  It can be built on top of NetBeans 6.0 if
+you change the required modules to be platform7 instead of platform8.
 
 The JVM support is controlled by the flag -XX:PrintIdealGraphLevel=#
 where # is:
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/PropertiesSheet.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/PropertiesSheet.java	Wed Jul 05 16:43:41 2017 +0200
@@ -36,11 +36,11 @@
  */
 public class PropertiesSheet {
 
-    public static void initializeSheet(Properties properties, Sheet s) {
+    public static void initializeSheet(final Properties properties, Sheet s) {
 
         Sheet.Set set1 = Sheet.createPropertiesSet();
         set1.setDisplayName("Properties");
-        for (final Property p : properties.getProperties()) {
+        for (final Property p : properties) {
             Node.Property<String> prop = new Node.Property<String>(String.class) {
 
                 @Override
@@ -60,7 +60,7 @@
 
                 @Override
                 public void setValue(String arg0) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
-                    p.setValue(arg0);
+                    properties.setProperty(p.getName(), arg0);
                 }
             };
             prop.setName(p.getName());
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/RangeSliderModel.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/RangeSliderModel.java	Wed Jul 05 16:43:41 2017 +0200
@@ -65,13 +65,19 @@
 
     public RangeSliderModel(List<String> positions) {
         assert positions.size() > 0;
-        this.positions = positions;
         this.changedEvent = new ChangedEvent<RangeSliderModel>(this);
         this.colorChangedEvent = new ChangedEvent<RangeSliderModel>(this);
+        setPositions(positions);
+    }
+
+    protected void setPositions(List<String> positions) {
+        this.positions = positions;
         colors = new ArrayList<Color>();
         for (int i = 0; i < positions.size(); i++) {
             colors.add(Color.black);
         }
+        changedEvent.fire();
+        colorChangedEvent.fire();
     }
 
     public void setColors(List<Color> colors) {
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramScene.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramScene.java	Wed Jul 05 16:43:41 2017 +0200
@@ -63,7 +63,7 @@
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Hashtable;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -104,10 +104,10 @@
  */
 public class DiagramScene extends Scene implements ChangedListener<DiagramViewModel> {
 
-    private Hashtable<Figure, FigureWidget> figureWidgets;
-    private Hashtable<Slot, SlotWidget> slotWidgets;
-    private Hashtable<Connection, ConnectionWidget> connectionWidgets;
-    private Hashtable<InputBlock, BlockWidget> blockWidgets;
+    private HashMap<Figure, FigureWidget> figureWidgets;
+    private HashMap<Slot, SlotWidget> slotWidgets;
+    private HashMap<Connection, ConnectionWidget> connectionWidgets;
+    private HashMap<InputBlock, BlockWidget> blockWidgets;
     private Widget hoverWidget;
     private WidgetAction hoverAction;
     private List<FigureWidget> selectedWidgets;
@@ -414,7 +414,7 @@
         this.addChild(selectLayer);
         this.getActions().addAction(ActionFactory.createRectangularSelectAction(rectangularSelectDecorator, selectLayer, rectangularSelectProvider));
 
-        blockWidgets = new Hashtable<InputBlock, BlockWidget>();
+        blockWidgets = new HashMap<InputBlock, BlockWidget>();
 
         boolean b = this.getUndoRedoEnabled();
         this.setUndoRedoEnabled(false);
@@ -543,9 +543,9 @@
         blockLayer.removeChildren();
 
         blockWidgets.clear();
-        figureWidgets = new Hashtable<Figure, FigureWidget>();
-        slotWidgets = new Hashtable<Slot, SlotWidget>();
-        connectionWidgets = new Hashtable<Connection, ConnectionWidget>();
+        figureWidgets = new HashMap<Figure, FigureWidget>();
+        slotWidgets = new HashMap<Slot, SlotWidget>();
+        connectionWidgets = new HashMap<Connection, ConnectionWidget>();
 
         WidgetAction selectAction = new ExtendedSelectAction(selectProvider);
         Diagram d = getModel().getDiagramToView();
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramViewModel.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramViewModel.java	Wed Jul 05 16:43:41 2017 +0200
@@ -55,6 +55,7 @@
     private FilterChain filterChain;
     private FilterChain sequenceFilterChain;
     private Diagram diagram;
+    private ChangedEvent<DiagramViewModel> groupChangedEvent;
     private ChangedEvent<DiagramViewModel> diagramChangedEvent;
     private ChangedEvent<DiagramViewModel> viewChangedEvent;
     private ChangedEvent<DiagramViewModel> viewPropertiesChangedEvent;
@@ -67,6 +68,7 @@
         }
     };
 
+    @Override
     public DiagramViewModel copy() {
         DiagramViewModel result = new DiagramViewModel(group, filterChain, sequenceFilterChain);
         result.setData(this);
@@ -79,6 +81,7 @@
         boolean viewChanged = false;
         boolean viewPropertiesChanged = false;
 
+        boolean groupChanged = (group == newModel.group);
         this.group = newModel.group;
         diagramChanged |= (filterChain != newModel.filterChain);
         this.filterChain = newModel.filterChain;
@@ -97,6 +100,10 @@
         viewPropertiesChanged |= (showNodeHull != newModel.showNodeHull);
         this.showNodeHull = newModel.showNodeHull;
 
+        if(groupChanged) {
+            groupChangedEvent.fire();
+        }
+
         if (diagramChanged) {
             diagramChangedEvent.fire();
         }
@@ -143,11 +150,38 @@
         diagramChangedEvent = new ChangedEvent<DiagramViewModel>(this);
         viewChangedEvent = new ChangedEvent<DiagramViewModel>(this);
         viewPropertiesChangedEvent = new ChangedEvent<DiagramViewModel>(this);
+        groupChangedEvent = new ChangedEvent<DiagramViewModel>(this);
+        groupChangedEvent.addListener(groupChangedListener);
+        groupChangedEvent.fire();
 
         filterChain.getChangedEvent().addListener(filterChainChangedListener);
         sequenceFilterChain.getChangedEvent().addListener(filterChainChangedListener);
     }
 
+    private final ChangedListener<DiagramViewModel> groupChangedListener = new ChangedListener<DiagramViewModel>() {
+
+        private Group oldGroup;
+
+        public void changed(DiagramViewModel source) {
+            if(oldGroup != null) {
+                oldGroup.getChangedEvent().removeListener(groupContentChangedListener);
+            }
+            group.getChangedEvent().addListener(groupContentChangedListener);
+            oldGroup = group;
+        }
+    };
+
+
+    private final ChangedListener<Group> groupContentChangedListener = new ChangedListener<Group>() {
+
+        public void changed(Group source) {
+            assert source == group;
+            setPositions(calculateStringList(source));
+            setSelectedNodes(selectedNodes);
+        }
+
+    };
+
     public ChangedEvent<DiagramViewModel> getDiagramChangedEvent() {
         return diagramChangedEvent;
     }
@@ -268,7 +302,10 @@
     }
 
     public InputGraph getSecondGraph() {
-        return group.getGraphs().get(getSecondPosition());
+        List<InputGraph> graphs = group.getGraphs();
+        if (graphs.size() >= getSecondPosition())
+            return group.getGraphs().get(getSecondPosition());
+        return getFirstGraph();
     }
 
     public void selectGraph(InputGraph g) {
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/FindPanel.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/FindPanel.java	Wed Jul 05 16:43:41 2017 +0200
@@ -67,7 +67,7 @@
 
         for (Figure f : figures) {
             Properties prop = f.getProperties();
-            for (Property p : prop.getProperties()) {
+            for (Property p : prop) {
                 if (!propertyNames.contains(p.getName())) {
                     propertyNames.add(p.getName());
                 }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/nbproject/platform.properties	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/nbproject/platform.properties	Wed Jul 05 16:43:41 2017 +0200
@@ -1,16 +1,16 @@
 # Deprecated since 5.0u1; for compatibility with 5.0:
 disabled.clusters=\
     apisupport1,\
+    gsf1,\
     harness,\
-    ide8,\
-    java1,\
-    nb6.0,\
-    profiler2
+    ide9,\
+    java2,\
+    nb6.1,\
+    profiler3
 disabled.modules=\
     org.netbeans.core.execution,\
     org.netbeans.core.multiview,\
     org.netbeans.core.output2,\
-    org.netbeans.modules.applemenu,\
     org.netbeans.modules.autoupdate.services,\
     org.netbeans.modules.autoupdate.ui,\
     org.netbeans.modules.core.kit,\
@@ -24,6 +24,6 @@
     org.openide.execution,\
     org.openide.util.enumerations
 enabled.clusters=\
-    platform7
+    platform8
 nbjdk.active=default
 nbplatform.active=default
--- a/hotspot/src/share/tools/IdealGraphVisualizer/nbproject/project.properties	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/nbproject/project.properties	Wed Jul 05 16:43:41 2017 +0200
@@ -15,7 +15,6 @@
     ${project.com.sun.hotspot.igv.difference}:\
     ${project.com.sun.hotspot.igv.settings}:\
     ${project.com.sun.hotspot.igv.util}:\
-    ${project.com.sun.hotspot.igv.rhino}:\
     ${project.com.sun.hotspot.igv.svg}:\
     ${project.com.sun.hotspot.connection}:\
     ${project.com.sun.hotspot.igv.servercompilerscheduler}:\
@@ -31,10 +30,10 @@
 project.com.sun.hotspot.igv.graph=Graph
 project.com.sun.hotspot.igv.hierarchicallayout=HierarchicalLayout
 project.com.sun.hotspot.igv.layout=Layout
-project.com.sun.hotspot.igv.rhino=RhinoScriptEngineProxy
 project.com.sun.hotspot.igv.servercompilerscheduler=ServerCompiler
 project.com.sun.hotspot.igv.settings=Settings
 project.com.sun.hotspot.igv.svg=BatikSVGProxy
 project.com.sun.hotspot.igv.view=View
 project.com.sun.hotspot.igv.util=Util
-run.args = -server -J-Xms64m -J-Xmx512m -J-da
+run.args = -J-server -J-Xms64m -J-Xmx1g -J-da
+run.args.extra = -J-server -J-Xms64m -J-Xmx1g -J-da
--- a/hotspot/src/share/vm/adlc/adlparse.cpp	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/vm/adlc/adlparse.cpp	Wed Jul 05 16:43:41 2017 +0200
@@ -33,7 +33,6 @@
     _globalNames(archDesc.globalNames()) {
   _AD._syntax_errs = _AD._semantic_errs = 0; // No errors so far this file
   _AD._warnings    = 0;                      // No warnings either
-  _linenum         = 0;                      // Will increment to first line
   _curline         = _ptr = NULL;            // No pointers into buffer yet
 
   _preproc_depth = 0;
@@ -76,7 +75,7 @@
   }
   if (!_AD._quiet_mode)
     fprintf(stderr,"-----------------------------------------------------------------------------\n");
-  _AD._TotalLines += _linenum-1;     // -1 for overshoot in "nextline" routine
+  _AD._TotalLines += linenum()-1;     // -1 for overshoot in "nextline" routine
 
   // Write out information we have stored
   // // UNIXism == fsync(stderr);
@@ -148,7 +147,7 @@
   if( (ident = get_unique_ident(_globalNames,"instruction")) == NULL )
     return;
   instr = new InstructForm(ident); // Create new instruction form
-  instr->_linenum = _linenum;
+  instr->_linenum = linenum();
   _globalNames.Insert(ident, instr); // Add name to the name table
   // Debugging Stuff
   if (_AD._adl_debug > 1)
@@ -404,7 +403,7 @@
   if( (ident = get_unique_ident(_globalNames,"operand")) == NULL )
     return;
   oper = new OperandForm(ident);        // Create new operand form
-  oper->_linenum = _linenum;
+  oper->_linenum = linenum();
   _globalNames.Insert(ident, oper); // Add name to the name table
 
   // Debugging Stuff
@@ -774,7 +773,7 @@
 
   // Create the RegisterForm for the architecture description.
   RegisterForm *regBlock = new RegisterForm();    // Build new Source object
-  regBlock->_linenum = _linenum;
+  regBlock->_linenum = linenum();
   _AD.addForm(regBlock);
 
   skipws();                       // Skip leading whitespace
@@ -847,7 +846,7 @@
   }
 
   EncClass  *encoding = _AD._encode->add_EncClass(ec_name);
-  encoding->_linenum = _linenum;
+  encoding->_linenum = linenum();
 
   skipws();                      // Skip leading whitespace
   // Check for optional parameter list
@@ -905,7 +904,7 @@
   // Prepend location descriptor, for debugging; cf. ADLParser::find_cpp_block
   if (_AD._adlocation_debug) {
     const char* file     = _AD._ADL_file._name;
-    int         line     = _linenum;
+    int         line     = linenum();
     char*       location = (char *)malloc(strlen(file) + 100);
     sprintf(location, "#line %d \"%s\"\n", line, file);
     encoding->add_code(location);
@@ -2776,7 +2775,7 @@
 
   assert(_AD._encode->encClass(ec_name) == NULL, "shouldn't already exist");
   EncClass  *encoding = _AD._encode->add_EncClass(ec_name);
-  encoding->_linenum = _linenum;
+  encoding->_linenum = linenum();
 
   // synthesize the arguments list for the enc_class from the
   // arguments to the instruct definition.
@@ -2852,7 +2851,7 @@
   skipws();
 
   InsEncode *encrule  = new InsEncode(); // Encode class for instruction
-  encrule->_linenum = _linenum;
+  encrule->_linenum = linenum();
   char      *ec_name  = NULL;      // String representation of encode rule
   // identifier is optional.
   while (_curchar != ')') {
@@ -3203,6 +3202,12 @@
   char *greater_equal;
   char *less_equal;
   char *greater;
+  const char *equal_format = "eq";
+  const char *not_equal_format = "ne";
+  const char *less_format = "lt";
+  const char *greater_equal_format = "ge";
+  const char *less_equal_format = "le";
+  const char *greater_format = "gt";
 
   if (_curchar != '%') {
     parse_err(SYNERR, "Missing '%{' for 'cond_interface' block.\n");
@@ -3222,22 +3227,22 @@
       return NULL;
     }
     if ( strcmp(field,"equal") == 0 ) {
-      equal  = interface_field_parse();
+      equal  = interface_field_parse(&equal_format);
     }
     else if ( strcmp(field,"not_equal") == 0 ) {
-      not_equal = interface_field_parse();
+      not_equal = interface_field_parse(&not_equal_format);
     }
     else if ( strcmp(field,"less") == 0 ) {
-      less = interface_field_parse();
+      less = interface_field_parse(&less_format);
     }
     else if ( strcmp(field,"greater_equal") == 0 ) {
-      greater_equal  = interface_field_parse();
+      greater_equal  = interface_field_parse(&greater_equal_format);
     }
     else if ( strcmp(field,"less_equal") == 0 ) {
-      less_equal = interface_field_parse();
+      less_equal = interface_field_parse(&less_equal_format);
     }
     else if ( strcmp(field,"greater") == 0 ) {
-      greater = interface_field_parse();
+      greater = interface_field_parse(&greater_format);
     }
     else {
       parse_err(SYNERR, "Expected keyword, base|index|scale|disp,  or '%}' ending interface.\n");
@@ -3252,14 +3257,18 @@
   next_char();                  // Skip '}'
 
   // Construct desired object and return
-  Interface *inter = new CondInterface(equal, not_equal, less, greater_equal,
-                                       less_equal, greater);
+  Interface *inter = new CondInterface(equal,         equal_format,
+                                       not_equal,     not_equal_format,
+                                       less,          less_format,
+                                       greater_equal, greater_equal_format,
+                                       less_equal,    less_equal_format,
+                                       greater,       greater_format);
   return inter;
 }
 
 
 //------------------------------interface_field_parse--------------------------
-char *ADLParser::interface_field_parse(void) {
+char *ADLParser::interface_field_parse(const char ** format) {
   char *iface_field = NULL;
 
   // Get interface field
@@ -3280,6 +3289,32 @@
     return NULL;
   }
   skipws();
+  if (format != NULL && _curchar == ',') {
+    next_char();
+    skipws();
+    if (_curchar != '"') {
+      parse_err(SYNERR, "Missing '\"' in field format .\n");
+      return NULL;
+    }
+    next_char();
+    char *start = _ptr;       // Record start of the next string
+    while ((_curchar != '"') && (_curchar != '%') && (_curchar != '\n')) {
+      if (_curchar == '\\')  next_char();  // superquote
+      if (_curchar == '\n')  parse_err(SYNERR, "newline in string");  // unimplemented!
+      next_char();
+    }
+    if (_curchar != '"') {
+      parse_err(SYNERR, "Missing '\"' at end of field format .\n");
+      return NULL;
+    }
+    // If a string was found, terminate it and record in FormatRule
+    if ( start != _ptr ) {
+      *_ptr  = '\0';          // Terminate the string
+      *format = start;
+    }
+    next_char();
+    skipws();
+  }
   if (_curchar != ')') {
     parse_err(SYNERR, "Missing ')' after interface field.\n");
     return NULL;
@@ -3342,6 +3377,12 @@
     next_char();                  // Move past the '{'
 
     skipws();
+    if (_curchar == '$') {
+      char* ident = get_rep_var_ident();
+      if (strcmp(ident, "$$template") == 0) return template_parse();
+      parse_err(SYNERR, "Unknown \"%s\" directive in format", ident);
+      return NULL;
+    }
     // Check for the opening '"' inside the format description
     if ( _curchar == '"' ) {
       next_char();              // Move past the initial '"'
@@ -3433,6 +3474,131 @@
 }
 
 
+//------------------------------template_parse-----------------------------------
+FormatRule* ADLParser::template_parse(void) {
+  char       *desc   = NULL;
+  FormatRule *format = (new FormatRule(desc));
+
+  skipws();
+  while ( (_curchar != '%') && (*(_ptr+1) != '}') ) {
+
+    // (1)
+    // Check if there is a string to pass through to output
+    char *start = _ptr;       // Record start of the next string
+    while ((_curchar != '$') && ((_curchar != '%') || (*(_ptr+1) != '}')) ) {
+      // If at the start of a comment, skip past it
+      if( (_curchar == '/') && ((*(_ptr+1) == '/') || (*(_ptr+1) == '*')) ) {
+        skipws_no_preproc();
+      } else {
+        // ELSE advance to the next character, or start of the next line
+        next_char_or_line();
+      }
+    }
+    // If a string was found, terminate it and record in EncClass
+    if ( start != _ptr ) {
+      *_ptr  = '\0';          // Terminate the string
+      // Add flag to _strings list indicating we should check _rep_vars
+      format->_strings.addName(NameList::_signal2);
+      format->_strings.addName(start);
+    }
+
+    // (2)
+    // If we are at a replacement variable,
+    // copy it and record in EncClass
+    if ( _curchar == '$' ) {
+      // Found replacement Variable
+      char *rep_var = get_rep_var_ident_dup();
+      if (strcmp(rep_var, "$emit") == 0) {
+        // switch to normal format parsing
+        next_char();
+        next_char();
+        skipws();
+        // Check for the opening '"' inside the format description
+        if ( _curchar == '"' ) {
+          next_char();              // Move past the initial '"'
+          if( _curchar == '"' ) {   // Handle empty format string case
+            *_ptr = '\0';           // Terminate empty string
+            format->_strings.addName(_ptr);
+          }
+
+          // Collect the parts of the format description
+          // (1) strings that are passed through to tty->print
+          // (2) replacement/substitution variable, preceeded by a '$'
+          // (3) multi-token ANSIY C style strings
+          while ( true ) {
+            if ( _curchar == '%' || _curchar == '\n' ) {
+              parse_err(SYNERR, "missing '\"' at end of format block");
+              return NULL;
+            }
+
+            // (1)
+            // Check if there is a string to pass through to output
+            char *start = _ptr;       // Record start of the next string
+            while ((_curchar != '$') && (_curchar != '"') && (_curchar != '%') && (_curchar != '\n')) {
+              if (_curchar == '\\')  next_char();  // superquote
+              if (_curchar == '\n')  parse_err(SYNERR, "newline in string");  // unimplemented!
+              next_char();
+            }
+            // If a string was found, terminate it and record in FormatRule
+            if ( start != _ptr ) {
+              *_ptr  = '\0';          // Terminate the string
+              format->_strings.addName(start);
+            }
+
+            // (2)
+            // If we are at a replacement variable,
+            // copy it and record in FormatRule
+            if ( _curchar == '$' ) {
+              next_char();          // Move past the '$'
+              char* rep_var = get_ident(); // Nil terminate the variable name
+              rep_var = strdup(rep_var);// Copy the string
+              *_ptr   = _curchar;     // and replace Nil with original character
+              format->_rep_vars.addName(rep_var);
+              // Add flag to _strings list indicating we should check _rep_vars
+              format->_strings.addName(NameList::_signal);
+            }
+
+            // (3)
+            // Allow very long strings to be broken up,
+            // using the ANSI C syntax "foo\n" <newline> "bar"
+            if ( _curchar == '"') {
+              next_char();           // Move past the '"'
+              skipws();              // Skip white space before next string token
+              if ( _curchar != '"') {
+                break;
+              } else {
+                // Found one.  Skip both " and the whitespace in between.
+                next_char();
+              }
+            }
+          } // end while part of format description
+        }
+      } else {
+        // Add flag to _strings list indicating we should check _rep_vars
+        format->_rep_vars.addName(rep_var);
+        // Add flag to _strings list indicating we should check _rep_vars
+        format->_strings.addName(NameList::_signal3);
+      }
+    } // end while part of format description
+  }
+
+  skipws();
+  // Past format description, at '%'
+  if ( _curchar != '%' || *(_ptr+1) != '}' ) {
+    parse_err(SYNERR, "missing '%}' at end of format block");
+    return NULL;
+  }
+  next_char();                  // Move past the '%'
+  next_char();                  // Move past the '}'
+
+  // Debug Stuff
+  if (_AD._adl_debug > 1) fprintf(stderr,"Format Rule: %s\n", desc);
+
+  skipws();
+  return format;
+}
+
+
 //------------------------------effect_parse-----------------------------------
 void ADLParser::effect_parse(InstructForm *instr) {
   char* desc   = NULL;
@@ -3777,7 +3943,7 @@
     skipws_no_preproc();          // Skip leading whitespace
     cppBlock = _ptr;              // Point to start of expression
     const char* file = _AD._ADL_file._name;
-    int         line = _linenum;
+    int         line = linenum();
     next = _ptr + 1;
     while(((_curchar != '%') || (*next != '}')) && (_curchar != '\0')) {
       next_char_or_line();
@@ -4297,11 +4463,11 @@
 
   va_start(args, fmt);
   if (flag == 1)
-    _AD._syntax_errs += _AD.emit_msg(0, flag, _linenum, fmt, args);
+    _AD._syntax_errs += _AD.emit_msg(0, flag, linenum(), fmt, args);
   else if (flag == 2)
-    _AD._semantic_errs += _AD.emit_msg(0, flag, _linenum, fmt, args);
+    _AD._semantic_errs += _AD.emit_msg(0, flag, linenum(), fmt, args);
   else
-    _AD._warnings += _AD.emit_msg(0, flag, _linenum, fmt, args);
+    _AD._warnings += _AD.emit_msg(0, flag, linenum(), fmt, args);
 
   int error_char = _curchar;
   char* error_ptr = _ptr+1;
@@ -4515,7 +4681,7 @@
 
 //---------------------------next_line-----------------------------------------
 void ADLParser::next_line() {
-  _curline = _buf.get_line(); _linenum++;
+  _curline = _buf.get_line();
 }
 
 //-------------------------is_literal_constant---------------------------------
--- a/hotspot/src/share/vm/adlc/adlparse.hpp	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/vm/adlc/adlparse.hpp	Wed Jul 05 16:43:41 2017 +0200
@@ -70,7 +70,6 @@
 protected:
   char     *_curline;           // Start of current line
   char     *_ptr;               // Pointer into current location in File Buffer
-  int       _linenum;           // Count of line numbers seen so far
   char      _curchar;           // Current character from buffer
   FormDict &_globalNames;       // Global names
 
@@ -160,9 +159,10 @@
   Interface     *interface_parse();      // Parse operand interface rule
   Interface     *mem_interface_parse();  // Parse memory interface rule
   Interface     *cond_interface_parse(); // Parse conditional interface rule
-  char          *interface_field_parse();// Parse field contents
+  char          *interface_field_parse(const char** format = NULL);// Parse field contents
 
   FormatRule    *format_parse(void);     // Parse format rule
+  FormatRule    *template_parse(void);     // Parse format rule
   void           effect_parse(InstructForm *instr); // Parse effect rule
   ExpandRule    *expand_parse(InstructForm *instr); // Parse expand rule
   RewriteRule   *rewrite_parse(void);    // Parse rewrite rule
@@ -263,7 +263,7 @@
 
   void parse(void);             // Do the parsing & build forms lists
 
-  int getlines( ) { return _linenum; }
+  int linenum() { return _buf.linenum(); }
 
   static bool is_literal_constant(const char *hex_string);
   static bool is_hex_digit(char digit);
--- a/hotspot/src/share/vm/adlc/filebuff.cpp	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/vm/adlc/filebuff.cpp	Wed Jul 05 16:43:41 2017 +0200
@@ -41,6 +41,7 @@
     exit(1);                    // Exit on seek error
   }
   _filepos = ftell(_fp->_fp);      // Reset current file position
+  _linenum = 0;
 
   _bigbuf = new char[_bufferSize]; // Create buffer to hold text for parser
   if( !_bigbuf ) {
@@ -76,6 +77,7 @@
   // Check for end of file & return NULL
   if (_bufeol >= _bufmax) return NULL;
 
+  _linenum++;
   retval = ++_bufeol;      // return character following end of previous line
   if (*retval == '\0') return NULL; // Check for EOF sentinal
   // Search for newline character which must end each line
--- a/hotspot/src/share/vm/adlc/filebuff.hpp	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/vm/adlc/filebuff.hpp	Wed Jul 05 16:43:41 2017 +0200
@@ -51,6 +51,7 @@
 
   int   _err;                   // Error flag for file seek/read operations
   long  _filepos;               // Current offset from start of file
+  int   _linenum;
 
   ArchDesc& _AD;                // Reference to Architecture Description
 
@@ -66,6 +67,7 @@
   // This returns a pointer to the start of the current line in the buffer,
   // and increments bufeol and filepos to point at the end of that line.
   char *get_line(void);
+  int linenum() const { return _linenum; }
 
   // This converts a pointer into the buffer to a file offset.  It only works
   // when the pointer is valid (i.e. just obtained from getline()).
--- a/hotspot/src/share/vm/adlc/forms.cpp	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/vm/adlc/forms.cpp	Wed Jul 05 16:43:41 2017 +0200
@@ -35,6 +35,8 @@
 //------------------------------NameList---------------------------------------
 // reserved user-defined string
 const char  *NameList::_signal   = "$$SIGNAL$$";
+const char  *NameList::_signal2  = "$$SIGNAL2$$";
+const char  *NameList::_signal3  = "$$SIGNAL3$$";
 
 // Constructor and Destructor
 NameList::NameList() : _cur(0), _max(4), _iter(0), _justReset(true) {
--- a/hotspot/src/share/vm/adlc/forms.hpp	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/vm/adlc/forms.hpp	Wed Jul 05 16:43:41 2017 +0200
@@ -329,6 +329,8 @@
 
 public:
   static const char *_signal;      // reserved user-defined string
+  static const char *_signal2;      // reserved user-defined string
+  static const char *_signal3;      // reserved user-defined string
   enum               { Not_in_list = -1 };
 
   void  addName(const char *name);
--- a/hotspot/src/share/vm/adlc/formssel.cpp	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/vm/adlc/formssel.cpp	Wed Jul 05 16:43:41 2017 +0200
@@ -1574,10 +1574,10 @@
   return Opcode::NOT_AN_OPCODE;
 }
 
-void Opcode::print_opcode(FILE *fp, Opcode::opcode_type desired_opcode) {
+bool Opcode::print_opcode(FILE *fp, Opcode::opcode_type desired_opcode) {
   // Default values previously provided by MachNode::primary()...
-  const char *description = "default_opcode()";
-  const char *value       = "-1";
+  const char *description = NULL;
+  const char *value       = NULL;
   // Check if user provided any opcode definitions
   if( this != NULL ) {
     // Update 'value' if user provided a definition in the instruction
@@ -1599,7 +1599,10 @@
       break;
     }
   }
-  fprintf(fp, "(%s /*%s*/)", value, description);
+  if (value != NULL) {
+    fprintf(fp, "(%s /*%s*/)", value, description);
+  }
+  return value != NULL;
 }
 
 void Opcode::dump() {
@@ -2610,14 +2613,19 @@
 }
 
 //------------------------------CondInterface----------------------------------
-CondInterface::CondInterface(char *equal,      char *not_equal,
-                             char *less,       char *greater_equal,
-                             char *less_equal, char *greater)
+CondInterface::CondInterface(const char* equal,         const char* equal_format,
+                             const char* not_equal,     const char* not_equal_format,
+                             const char* less,          const char* less_format,
+                             const char* greater_equal, const char* greater_equal_format,
+                             const char* less_equal,    const char* less_equal_format,
+                             const char* greater,       const char* greater_format)
   : Interface("COND_INTER"),
-    _equal(equal), _not_equal(not_equal),
-    _less(less), _greater_equal(greater_equal),
-    _less_equal(less_equal), _greater(greater) {
-      //
+    _equal(equal),                 _equal_format(equal_format),
+    _not_equal(not_equal),         _not_equal_format(not_equal_format),
+    _less(less),                   _less_format(less_format),
+    _greater_equal(greater_equal), _greater_equal_format(greater_equal_format),
+    _less_equal(less_equal),       _less_equal_format(less_equal_format),
+    _greater(greater),             _greater_format(greater_format) {
 }
 CondInterface::~CondInterface() {
   // not owner of any character arrays
@@ -3316,7 +3324,7 @@
     "Load8B" ,"Load4B" ,"Load8C" ,"Load4C" ,"Load2C" ,"Load8S", "Load4S","Load2S",
     "LoadRange", "LoadKlass", "LoadNKlass", "LoadL_unaligned", "LoadD_unaligned",
     "LoadPLocked", "LoadLLocked",
-    "StorePConditional", "StoreLConditional",
+    "StorePConditional", "StoreIConditional", "StoreLConditional",
     "CompareAndSwapI", "CompareAndSwapL", "CompareAndSwapP", "CompareAndSwapN",
     "StoreCM",
     "ClearArray"
--- a/hotspot/src/share/vm/adlc/formssel.hpp	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/vm/adlc/formssel.hpp	Wed Jul 05 16:43:41 2017 +0200
@@ -397,7 +397,7 @@
   void output(FILE *fp);
 
   // --------------------------- FILE *output_routines
-  void print_opcode(FILE *fp, Opcode::opcode_type desired_opcode);
+  bool print_opcode(FILE *fp, Opcode::opcode_type desired_opcode);
 };
 
 //------------------------------InsEncode--------------------------------------
@@ -779,10 +779,20 @@
   const char *_greater_equal;
   const char *_less_equal;
   const char *_greater;
+  const char *_equal_format;
+  const char *_not_equal_format;
+  const char *_less_format;
+  const char *_greater_equal_format;
+  const char *_less_equal_format;
+  const char *_greater_format;
 
   // Public Methods
-  CondInterface(char *equal, char *not_equal, char *less, char *greater_equal,
-                char *less_equal, char *greater);
+  CondInterface(const char* equal,         const char* equal_format,
+                const char* not_equal,     const char* not_equal_format,
+                const char* less,          const char* less_format,
+                const char* greater_equal, const char* greater_equal_format,
+                const char* less_equal,    const char* less_equal_format,
+                const char* greater,       const char* greater_format);
   ~CondInterface();
 
   void dump();
--- a/hotspot/src/share/vm/adlc/output_c.cpp	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/vm/adlc/output_c.cpp	Wed Jul 05 16:43:41 2017 +0200
@@ -1619,6 +1619,7 @@
       }
 
       // Iterate over the new instruction's operands
+      int prev_pos = -1;
       for( expand_instr->reset(); (opid = expand_instr->iter()) != NULL; ) {
         // Use 'parameter' at current position in list of new instruction's formals
         // instead of 'opid' when looking up info internal to new_inst
@@ -1642,6 +1643,18 @@
           // ins = (InstructForm *) _globalNames[new_id];
           exp_pos = node->operand_position_format(opid);
           assert(exp_pos != -1, "Bad expand rule");
+          if (prev_pos > exp_pos && expand_instruction->_matrule != NULL) {
+            // For the add_req calls below to work correctly they need
+            // to added in the same order that a match would add them.
+            // This means that they would need to be in the order of
+            // the components list instead of the formal parameters.
+            // This is a sort of hidden invariant that previously
+            // wasn't checked and could lead to incorrectly
+            // constructed nodes.
+            syntax_err(node->_linenum, "For expand in %s to work, parameter declaration order in %s must follow matchrule\n",
+                       node->_ident, new_inst->_ident);
+          }
+          prev_pos = exp_pos;
 
           new_pos = new_inst->operand_position(parameter,Component::USE);
           if (new_pos != -1) {
@@ -2306,7 +2319,12 @@
     _processing_noninput = false;
     // A replacement variable, originally '$'
     if ( Opcode::as_opcode_type(rep_var) != Opcode::NOT_AN_OPCODE ) {
-      _inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(rep_var) );
+      if (!_inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(rep_var) )) {
+        // Missing opcode
+        _AD.syntax_err( _inst._linenum,
+                        "Missing $%s opcode definition in %s, used by encoding %s\n",
+                        rep_var, _inst._ident, _encoding._name);
+      }
     }
     else {
       // Lookup its position in parameter list
@@ -2348,7 +2366,13 @@
       else if( Opcode::as_opcode_type(inst_rep_var) != Opcode::NOT_AN_OPCODE ) {
         // else check if "primary", "secondary", "tertiary"
         assert( _constant_status == LITERAL_ACCESSED, "Must be processing a literal constant parameter");
-        _inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(inst_rep_var) );
+        if (!_inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(inst_rep_var) )) {
+          // Missing opcode
+          _AD.syntax_err( _inst._linenum,
+                          "Missing $%s opcode definition in %s\n",
+                          rep_var, _inst._ident);
+
+        }
         _constant_status = LITERAL_OUTPUT;
       }
       else if((_AD.get_registers() != NULL ) && (_AD.get_registers()->getRegDef(inst_rep_var) != NULL)) {
--- a/hotspot/src/share/vm/adlc/output_h.cpp	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/vm/adlc/output_h.cpp	Wed Jul 05 16:43:41 2017 +0200
@@ -355,17 +355,19 @@
 // ---------------------------------------------------------------------------
 
 // Generate the format rule for condition codes
-static void defineCCodeDump(FILE *fp, int i) {
-  fprintf(fp, "         if( _c%d == BoolTest::eq ) st->print(\"eq\");\n",i);
-  fprintf(fp, "    else if( _c%d == BoolTest::ne ) st->print(\"ne\");\n",i);
-  fprintf(fp, "    else if( _c%d == BoolTest::le ) st->print(\"le\");\n",i);
-  fprintf(fp, "    else if( _c%d == BoolTest::ge ) st->print(\"ge\");\n",i);
-  fprintf(fp, "    else if( _c%d == BoolTest::lt ) st->print(\"lt\");\n",i);
-  fprintf(fp, "    else if( _c%d == BoolTest::gt ) st->print(\"gt\");\n",i);
+static void defineCCodeDump(OperandForm* oper, FILE *fp, int i) {
+  assert(oper != NULL, "what");
+  CondInterface* cond = oper->_interface->is_CondInterface();
+  fprintf(fp, "         if( _c%d == BoolTest::eq ) st->print(\"%s\");\n",i,cond->_equal_format);
+  fprintf(fp, "    else if( _c%d == BoolTest::ne ) st->print(\"%s\");\n",i,cond->_not_equal_format);
+  fprintf(fp, "    else if( _c%d == BoolTest::le ) st->print(\"%s\");\n",i,cond->_less_equal_format);
+  fprintf(fp, "    else if( _c%d == BoolTest::ge ) st->print(\"%s\");\n",i,cond->_greater_equal_format);
+  fprintf(fp, "    else if( _c%d == BoolTest::lt ) st->print(\"%s\");\n",i,cond->_less_format);
+  fprintf(fp, "    else if( _c%d == BoolTest::gt ) st->print(\"%s\");\n",i,cond->_greater_format);
 }
 
 // Output code that dumps constant values, increment "i" if type is constant
-static uint dump_spec_constant(FILE *fp, const char *ideal_type, uint i) {
+static uint dump_spec_constant(FILE *fp, const char *ideal_type, uint i, OperandForm* oper) {
   if (!strcmp(ideal_type, "ConI")) {
     fprintf(fp,"   st->print(\"#%%d\", _c%d);\n", i);
     ++i;
@@ -375,7 +377,7 @@
     ++i;
   }
   else if (!strcmp(ideal_type, "ConN")) {
-    fprintf(fp,"    _c%d->dump();\n", i);
+    fprintf(fp,"    _c%d->dump_on(st);\n", i);
     ++i;
   }
   else if (!strcmp(ideal_type, "ConL")) {
@@ -391,7 +393,7 @@
     ++i;
   }
   else if (!strcmp(ideal_type, "Bool")) {
-    defineCCodeDump(fp,i);
+    defineCCodeDump(oper, fp,i);
     ++i;
   }
 
@@ -476,7 +478,7 @@
   }
   // ALWAYS! Provide a special case output for condition codes.
   if( oper.is_ideal_bool() ) {
-    defineCCodeDump(fp,0);
+    defineCCodeDump(&oper, fp,0);
   }
   fprintf(fp,"}\n");
 
@@ -549,7 +551,7 @@
   }
   // ALWAYS! Provide a special case output for condition codes.
   if( oper.is_ideal_bool() ) {
-    defineCCodeDump(fp,0);
+    defineCCodeDump(&oper, fp,0);
   }
   fprintf(fp, "}\n");
   fprintf(fp, "#endif\n");
@@ -583,10 +585,53 @@
     while( (string = inst._format->_strings.iter()) != NULL ) {
       fprintf(fp,"    ");
       // Check if this is a standard string or a replacement variable
-      if( string != NameList::_signal )  // Normal string.  Pass through.
+      if( string == NameList::_signal ) { // Replacement variable
+        const char* rep_var =  inst._format->_rep_vars.iter();
+        inst.rep_var_format( fp, rep_var);
+      } else if( string == NameList::_signal3 ) { // Replacement variable in raw text
+        const char* rep_var =  inst._format->_rep_vars.iter();
+        const Form *form   = inst._localNames[rep_var];
+        if (form == NULL) {
+          fprintf(stderr, "unknown replacement variable in format statement: '%s'\n", rep_var);
+          assert(false, "ShouldNotReachHere()");
+        }
+        OpClassForm *opc   = form->is_opclass();
+        assert( opc, "replacement variable was not found in local names");
+        // Lookup the index position of the replacement variable
+        int idx  = inst.operand_position_format(rep_var);
+        if ( idx == -1 ) {
+          assert( strcmp(opc->_ident,"label")==0, "Unimplemented");
+          assert( false, "ShouldNotReachHere()");
+        }
+
+        if (inst.is_noninput_operand(idx)) {
+          assert( false, "ShouldNotReachHere()");
+        } else {
+          // Output the format call for this operand
+          fprintf(fp,"opnd_array(%d)",idx);
+        }
+        rep_var =  inst._format->_rep_vars.iter();
+        inst._format->_strings.iter();
+        if ( strcmp(rep_var,"$constant") == 0 && opc->is_operand()) {
+          Form::DataType constant_type = form->is_operand()->is_base_constant(globals);
+          if ( constant_type == Form::idealD ) {
+            fprintf(fp,"->constantD()");
+          } else if ( constant_type == Form::idealF ) {
+            fprintf(fp,"->constantF()");
+          } else if ( constant_type == Form::idealL ) {
+            fprintf(fp,"->constantL()");
+          } else {
+            fprintf(fp,"->constant()");
+          }
+        } else if ( strcmp(rep_var,"$cmpcode") == 0) {
+            fprintf(fp,"->ccode()");
+        } else {
+          assert( false, "ShouldNotReachHere()");
+        }
+      } else if( string == NameList::_signal2 ) // Raw program text
+        fputs(inst._format->_strings.iter(), fp);
+      else
         fprintf(fp,"st->print(\"%s\");\n", string);
-      else                      // Replacement variable
-        inst.rep_var_format( fp, inst._format->_rep_vars.iter() );
     } // Done with all format strings
   } // Done generating the user-defined portion of the format
 
@@ -1404,7 +1449,7 @@
       oper->_components.reset();
       if ((comp = oper->_components.iter()) == NULL) {
         assert(num_consts == 1, "Bad component list detected.\n");
-        i = dump_spec_constant( fp, type, i );
+        i = dump_spec_constant( fp, type, i, oper );
         // Check that type actually matched
         assert( i != 0, "Non-constant operand lacks component list.");
       } // end if NULL
@@ -1414,7 +1459,7 @@
         oper->_components.reset();
         while((comp = oper->_components.iter()) != NULL) {
           type = comp->base_type(_globalNames);
-          i = dump_spec_constant( fp, type, i );
+          i = dump_spec_constant( fp, type, i, NULL );
         }
       }
       // finish line (3)
--- a/hotspot/src/share/vm/interpreter/bytecodeStream.cpp	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/vm/interpreter/bytecodeStream.cpp	Wed Jul 05 16:43:41 2017 +0200
@@ -28,8 +28,9 @@
 Bytecodes::Code RawBytecodeStream::raw_next_special(Bytecodes::Code code) {
   assert(!is_last_bytecode(), "should have been checked");
   // set next bytecode position
-  address bcp  = RawBytecodeStream::bcp();
-  int l = Bytecodes::raw_special_length_at(bcp);
+  address bcp = RawBytecodeStream::bcp();
+  address end = method()->code_base() + end_bci();
+  int l = Bytecodes::raw_special_length_at(bcp, end);
   if (l <= 0 || (_bci + l) > _end_bci) {
     code = Bytecodes::_illegal;
   } else {
@@ -39,8 +40,12 @@
     _is_wide = false;
     // check for special (uncommon) cases
     if (code == Bytecodes::_wide) {
-      code = (Bytecodes::Code)bcp[1];
-      _is_wide = true;
+      if (bcp + 1 >= end) {
+        code = Bytecodes::_illegal;
+      } else {
+        code = (Bytecodes::Code)bcp[1];
+        _is_wide = true;
+      }
     }
   }
   _code = code;
--- a/hotspot/src/share/vm/interpreter/bytecodes.cpp	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/vm/interpreter/bytecodes.cpp	Wed Jul 05 16:43:41 2017 +0200
@@ -54,13 +54,19 @@
   return method->orig_bytecode_at(method->bci_from(bcp));
 }
 
-int Bytecodes::special_length_at(address bcp) {
+int Bytecodes::special_length_at(address bcp, address end) {
   Code code = code_at(bcp);
   switch (code) {
   case _wide:
+    if (end != NULL && bcp + 1 >= end) {
+      return -1; // don't read past end of code buffer
+    }
     return wide_length_for(cast(*(bcp + 1)));
   case _tableswitch:
     { address aligned_bcp = (address)round_to((intptr_t)bcp + 1, jintSize);
+      if (end != NULL && aligned_bcp + 3*jintSize >= end) {
+        return -1; // don't read past end of code buffer
+      }
       jlong lo = (jint)Bytes::get_Java_u4(aligned_bcp + 1*jintSize);
       jlong hi = (jint)Bytes::get_Java_u4(aligned_bcp + 2*jintSize);
       jlong len = (aligned_bcp - bcp) + (3 + hi - lo + 1)*jintSize;
@@ -73,6 +79,9 @@
   case _fast_binaryswitch: // fall through
   case _fast_linearswitch:
     { address aligned_bcp = (address)round_to((intptr_t)bcp + 1, jintSize);
+      if (end != NULL && aligned_bcp + 2*jintSize >= end) {
+        return -1; // don't read past end of code buffer
+      }
       jlong npairs = (jint)Bytes::get_Java_u4(aligned_bcp + jintSize);
       jlong len = (aligned_bcp - bcp) + (2 + 2*npairs)*jintSize;
       // only return len if it can be represented as a positive int;
@@ -90,14 +99,17 @@
 // verifier when reading in bytecode to verify.  Other mechanisms that
 // run at runtime (such as generateOopMaps) need to iterate over the code
 // and don't expect to see breakpoints: they want to see the instruction
-// which was replaces so that they can get the correct length and find
+// which was replaced so that they can get the correct length and find
 // the next bytecode.
-int Bytecodes::raw_special_length_at(address bcp) {
+//
+// 'end' indicates the end of the code buffer, which we should not try to read
+// past.
+int Bytecodes::raw_special_length_at(address bcp, address end) {
   Code code = code_or_bp_at(bcp);
   if (code == _breakpoint) {
     return 1;
   } else {
-    return special_length_at(bcp);
+    return special_length_at(bcp, end);
   }
 }
 
--- a/hotspot/src/share/vm/interpreter/bytecodes.hpp	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/vm/interpreter/bytecodes.hpp	Wed Jul 05 16:43:41 2017 +0200
@@ -340,8 +340,10 @@
     const char* wf = wide_format(code);
     return (wf == NULL) ? 0 : (int)strlen(wf);
   }
-  static int         special_length_at(address bcp);
-  static int         raw_special_length_at(address bcp);
+  // if 'end' is provided, it indicates the end of the code buffer which
+  // should not be read past when parsing.
+  static int         special_length_at(address bcp, address end = NULL);
+  static int         raw_special_length_at(address bcp, address end = NULL);
   static int         length_at      (address bcp)  { int l = length_for(code_at(bcp)); return l > 0 ? l : special_length_at(bcp); }
   static int         java_length_at (address bcp)  { int l = length_for(java_code_at(bcp)); return l > 0 ? l : special_length_at(bcp); }
   static bool        is_java_code   (Code code)    { return 0 <= code && code < number_of_java_codes; }
--- a/hotspot/src/share/vm/opto/block.cpp	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/vm/opto/block.cpp	Wed Jul 05 16:43:41 2017 +0200
@@ -57,6 +57,14 @@
   _blocks[i] = b;
 }
 
+#ifndef PRODUCT
+void Block_List::print() {
+  for (uint i=0; i < size(); i++) {
+    tty->print("B%d ", _blocks[i]->_pre_order);
+  }
+  tty->print("size = %d\n", size());
+}
+#endif
 
 //=============================================================================
 
@@ -66,6 +74,12 @@
   // Check for Start block
   if( _pre_order == 1 ) return InteriorEntryAlignment;
   // Check for loop alignment
+  if (has_loop_alignment())  return loop_alignment();
+
+  return 1;                     // no particular alignment
+}
+
+uint Block::compute_loop_alignment() {
   Node *h = head();
   if( h->is_Loop() && h->as_Loop()->is_inner_loop() )  {
     // Pre- and post-loops have low trip count so do not bother with
@@ -83,13 +97,15 @@
     }
     return OptoLoopAlignment; // Otherwise align loop head
   }
+
   return 1;                     // no particular alignment
 }
 
 //-----------------------------------------------------------------------------
 // Compute the size of first 'inst_cnt' instructions in this block.
 // Return the number of instructions left to compute if the block has
-// less then 'inst_cnt' instructions.
+// less then 'inst_cnt' instructions. Stop, and return 0 if sum_size
+// exceeds OptoLoopAlignment.
 uint Block::compute_first_inst_size(uint& sum_size, uint inst_cnt,
                                     PhaseRegAlloc* ra) {
   uint last_inst = _nodes.size();
@@ -307,6 +323,8 @@
     tty->print("\tLoop: B%d-B%d ", bhead->_pre_order, bx->_pre_order);
     // Dump any loop-specific bits, especially for CountedLoops.
     loop->dump_spec(tty);
+  } else if (has_loop_alignment()) {
+    tty->print(" top-of-loop");
   }
   tty->print(" Freq: %g",_freq);
   if( Verbose || WizardMode ) {
@@ -509,9 +527,11 @@
   int branch_idx = b->_nodes.size() - b->_num_succs-1;
   if( branch_idx < 1 ) return false;
   Node *bra = b->_nodes[branch_idx];
-  if( bra->is_Catch() ) return true;
+  if( bra->is_Catch() )
+    return true;
   if( bra->is_Mach() ) {
-    if( bra->is_MachNullCheck() ) return true;
+    if( bra->is_MachNullCheck() )
+      return true;
     int iop = bra->as_Mach()->ideal_Opcode();
     if( iop == Op_FastLock || iop == Op_FastUnlock )
       return true;
@@ -557,10 +577,10 @@
     dead->_nodes[k]->del_req(j);
 }
 
-//------------------------------MoveToNext-------------------------------------
+//------------------------------move_to_next-----------------------------------
 // Helper function to move block bx to the slot following b_index. Return
 // true if the move is successful, otherwise false
-bool PhaseCFG::MoveToNext(Block* bx, uint b_index) {
+bool PhaseCFG::move_to_next(Block* bx, uint b_index) {
   if (bx == NULL) return false;
 
   // Return false if bx is already scheduled.
@@ -591,9 +611,9 @@
   return true;
 }
 
-//------------------------------MoveToEnd--------------------------------------
+//------------------------------move_to_end------------------------------------
 // Move empty and uncommon blocks to the end.
-void PhaseCFG::MoveToEnd(Block *b, uint i) {
+void PhaseCFG::move_to_end(Block *b, uint i) {
   int e = b->is_Empty();
   if (e != Block::not_empty) {
     if (e == Block::empty_with_goto) {
@@ -609,15 +629,31 @@
   _blocks.push(b);
 }
 
-//------------------------------RemoveEmpty------------------------------------
-// Remove empty basic blocks and useless branches.
-void PhaseCFG::RemoveEmpty() {
+//---------------------------set_loop_alignment--------------------------------
+// Set loop alignment for every block
+void PhaseCFG::set_loop_alignment() {
+  uint last = _num_blocks;
+  assert( _blocks[0] == _broot, "" );
+
+  for (uint i = 1; i < last; i++ ) {
+    Block *b = _blocks[i];
+    if (b->head()->is_Loop()) {
+      b->set_loop_alignment(b);
+    }
+  }
+}
+
+//-----------------------------remove_empty------------------------------------
+// Make empty basic blocks to be "connector" blocks, Move uncommon blocks
+// to the end.
+void PhaseCFG::remove_empty() {
   // Move uncommon blocks to the end
   uint last = _num_blocks;
-  uint i;
   assert( _blocks[0] == _broot, "" );
-  for( i = 1; i < last; i++ ) {
+
+  for (uint i = 1; i < last; i++) {
     Block *b = _blocks[i];
+    if (b->is_connector()) break;
 
     // Check for NeverBranch at block end.  This needs to become a GOTO to the
     // true target.  NeverBranch are treated as a conditional branch that
@@ -629,37 +665,40 @@
       convert_NeverBranch_to_Goto(b);
 
     // Look for uncommon blocks and move to end.
-    if( b->is_uncommon(_bbs) ) {
-      MoveToEnd(b, i);
-      last--;                   // No longer check for being uncommon!
-      if( no_flip_branch(b) ) { // Fall-thru case must follow?
-        b = _blocks[i];         // Find the fall-thru block
-        MoveToEnd(b, i);
-        last--;
+    if (!C->do_freq_based_layout()) {
+      if( b->is_uncommon(_bbs) ) {
+        move_to_end(b, i);
+        last--;                   // No longer check for being uncommon!
+        if( no_flip_branch(b) ) { // Fall-thru case must follow?
+          b = _blocks[i];         // Find the fall-thru block
+          move_to_end(b, i);
+          last--;
+        }
+        i--;                      // backup block counter post-increment
       }
-      i--;                      // backup block counter post-increment
     }
   }
 
-  // Remove empty blocks
-  uint j1;
+  // Move empty blocks to the end
   last = _num_blocks;
-  for( i=0; i < last; i++ ) {
+  for (uint i = 1; i < last; i++) {
     Block *b = _blocks[i];
-    if (i > 0) {
-      if (b->is_Empty() != Block::not_empty) {
-        MoveToEnd(b, i);
-        last--;
-        i--;
-      }
+    if (b->is_Empty() != Block::not_empty) {
+      move_to_end(b, i);
+      last--;
+      i--;
     }
   } // End of for all blocks
+}
 
+//-----------------------------fixup_flow--------------------------------------
+// Fix up the final control flow for basic blocks.
+void PhaseCFG::fixup_flow() {
   // Fixup final control flow for the blocks.  Remove jump-to-next
   // block.  If neither arm of a IF follows the conditional branch, we
   // have to add a second jump after the conditional.  We place the
   // TRUE branch target in succs[0] for both GOTOs and IFs.
-  for( i=0; i < _num_blocks; i++ ) {
+  for (uint i=0; i < _num_blocks; i++) {
     Block *b = _blocks[i];
     b->_pre_order = i;          // turn pre-order into block-index
 
@@ -700,7 +739,7 @@
         }
       }
       // Remove all CatchProjs
-      for (j1 = 0; j1 < b->_num_succs; j1++) b->_nodes.pop();
+      for (uint j1 = 0; j1 < b->_num_succs; j1++) b->_nodes.pop();
 
     } else if (b->_num_succs == 1) {
       // Block ends in a Goto?
@@ -730,8 +769,7 @@
       // successors after the current one, provided that the
       // successor was previously unscheduled, but moveable
       // (i.e., all paths to it involve a branch).
-      if( bnext != bs0 && bnext != bs1 ) {
-
+      if( !C->do_freq_based_layout() && bnext != bs0 && bnext != bs1 ) {
         // Choose the more common successor based on the probability
         // of the conditional branch.
         Block *bx = bs0;
@@ -751,9 +789,9 @@
         }
 
         // Attempt the more common successor first
-        if (MoveToNext(bx, i)) {
+        if (move_to_next(bx, i)) {
           bnext = bx;
-        } else if (MoveToNext(by, i)) {
+        } else if (move_to_next(by, i)) {
           bnext = by;
         }
       }
@@ -774,10 +812,8 @@
         // Flip projection for each target
         { ProjNode *tmp = proj0; proj0 = proj1; proj1 = tmp; }
 
-      } else if( bnext == bs1 ) { // Fall-thru is already in succs[1]
-
-      } else {                  // Else need a double-branch
-
+      } else if( bnext != bs1 ) {
+        // Need a double-branch
         // The existing conditional branch need not change.
         // Add a unconditional branch to the false target.
         // Alas, it must appear in its own block and adding a
@@ -786,8 +822,9 @@
       }
 
       // Make sure we TRUE branch to the target
-      if( proj0->Opcode() == Op_IfFalse )
+      if( proj0->Opcode() == Op_IfFalse ) {
         iff->negate();
+      }
 
       b->_nodes.pop();          // Remove IfFalse & IfTrue projections
       b->_nodes.pop();
@@ -796,9 +833,7 @@
       // Multi-exit block, e.g. a switch statement
       // But we don't need to do anything here
     }
-
   } // End of for all blocks
-
 }
 
 
@@ -905,7 +940,7 @@
   // Force the Union-Find mapping to be at least this large
   extend(max,0);
   // Initialize to be the ID mapping.
-  for( uint i=0; i<_max; i++ ) map(i,i);
+  for( uint i=0; i<max; i++ ) map(i,i);
 }
 
 //------------------------------Find_compress----------------------------------
@@ -937,7 +972,6 @@
   if( idx >= _max ) return idx;
   uint next = lookup(idx);
   while( next != idx ) {        // Scan chain of equivalences
-    assert( next < idx, "always union smaller" );
     idx = next;                 // until find a fixed-point
     next = lookup(idx);
   }
@@ -956,3 +990,491 @@
   assert( src < dst, "always union smaller" );
   map(dst,src);
 }
+
+#ifndef PRODUCT
+static void edge_dump(GrowableArray<CFGEdge *> *edges) {
+  tty->print_cr("---- Edges ----");
+  for (int i = 0; i < edges->length(); i++) {
+    CFGEdge *e = edges->at(i);
+    if (e != NULL) {
+      edges->at(i)->dump();
+    }
+  }
+}
+
+static void trace_dump(Trace *traces[], int count) {
+  tty->print_cr("---- Traces ----");
+  for (int i = 0; i < count; i++) {
+    Trace *tr = traces[i];
+    if (tr != NULL) {
+      tr->dump();
+    }
+  }
+}
+
+void Trace::dump( ) const {
+  tty->print_cr("Trace (freq %f)", first_block()->_freq);
+  for (Block *b = first_block(); b != NULL; b = next(b)) {
+    tty->print("  B%d", b->_pre_order);
+    if (b->head()->is_Loop()) {
+      tty->print(" (L%d)", b->compute_loop_alignment());
+    }
+    if (b->has_loop_alignment()) {
+      tty->print(" (T%d)", b->code_alignment());
+    }
+  }
+  tty->cr();
+}
+
+void CFGEdge::dump( ) const {
+  tty->print(" B%d  -->  B%d  Freq: %f  out:%3d%%  in:%3d%%  State: ",
+             from()->_pre_order, to()->_pre_order, freq(), _from_pct, _to_pct);
+  switch(state()) {
+  case connected:
+    tty->print("connected");
+    break;
+  case open:
+    tty->print("open");
+    break;
+  case interior:
+    tty->print("interior");
+    break;
+  }
+  if (infrequent()) {
+    tty->print("  infrequent");
+  }
+  tty->cr();
+}
+#endif
+
+//=============================================================================
+
+//------------------------------edge_order-------------------------------------
+// Comparison function for edges
+static int edge_order(CFGEdge **e0, CFGEdge **e1) {
+  float freq0 = (*e0)->freq();
+  float freq1 = (*e1)->freq();
+  if (freq0 != freq1) {
+    return freq0 > freq1 ? -1 : 1;
+  }
+
+  int dist0 = (*e0)->to()->_rpo - (*e0)->from()->_rpo;
+  int dist1 = (*e1)->to()->_rpo - (*e1)->from()->_rpo;
+
+  return dist1 - dist0;
+}
+
+//------------------------------trace_frequency_order--------------------------
+// Comparison function for edges
+static int trace_frequency_order(const void *p0, const void *p1) {
+  Trace *tr0 = *(Trace **) p0;
+  Trace *tr1 = *(Trace **) p1;
+  Block *b0 = tr0->first_block();
+  Block *b1 = tr1->first_block();
+
+  // The trace of connector blocks goes at the end;
+  // we only expect one such trace
+  if (b0->is_connector() != b1->is_connector()) {
+    return b1->is_connector() ? -1 : 1;
+  }
+
+  // Pull more frequently executed blocks to the beginning
+  float freq0 = b0->_freq;
+  float freq1 = b1->_freq;
+  if (freq0 != freq1) {
+    return freq0 > freq1 ? -1 : 1;
+  }
+
+  int diff = tr0->first_block()->_rpo - tr1->first_block()->_rpo;
+
+  return diff;
+}
+
+//------------------------------find_edges-------------------------------------
+// Find edges of interest, i.e, those which can fall through. Presumes that
+// edges which don't fall through are of low frequency and can be generally
+// ignored.  Initialize the list of traces.
+void PhaseBlockLayout::find_edges()
+{
+  // Walk the blocks, creating edges and Traces
+  uint i;
+  Trace *tr = NULL;
+  for (i = 0; i < _cfg._num_blocks; i++) {
+    Block *b = _cfg._blocks[i];
+    tr = new Trace(b, next, prev);
+    traces[tr->id()] = tr;
+
+    // All connector blocks should be at the end of the list
+    if (b->is_connector()) break;
+
+    // If this block and the next one have a one-to-one successor
+    // predecessor relationship, simply append the next block
+    int nfallthru = b->num_fall_throughs();
+    while (nfallthru == 1 &&
+           b->succ_fall_through(0)) {
+      Block *n = b->_succs[0];
+
+      // Skip over single-entry connector blocks, we don't want to
+      // add them to the trace.
+      while (n->is_connector() && n->num_preds() == 1) {
+        n = n->_succs[0];
+      }
+
+      // We see a merge point, so stop search for the next block
+      if (n->num_preds() != 1) break;
+
+      i++;
+      assert(n = _cfg._blocks[i], "expecting next block");
+      tr->append(n);
+      uf->map(n->_pre_order, tr->id());
+      traces[n->_pre_order] = NULL;
+      nfallthru = b->num_fall_throughs();
+      b = n;
+    }
+
+    if (nfallthru > 0) {
+      // Create a CFGEdge for each outgoing
+      // edge that could be a fall-through.
+      for (uint j = 0; j < b->_num_succs; j++ ) {
+        if (b->succ_fall_through(j)) {
+          Block *target = b->non_connector_successor(j);
+          float freq = b->_freq * b->succ_prob(j);
+          int from_pct = (int) ((100 * freq) / b->_freq);
+          int to_pct = (int) ((100 * freq) / target->_freq);
+          edges->append(new CFGEdge(b, target, freq, from_pct, to_pct));
+        }
+      }
+    }
+  }
+
+  // Group connector blocks into one trace
+  for (i++; i < _cfg._num_blocks; i++) {
+    Block *b = _cfg._blocks[i];
+    assert(b->is_connector(), "connector blocks at the end");
+    tr->append(b);
+    uf->map(b->_pre_order, tr->id());
+    traces[b->_pre_order] = NULL;
+  }
+}
+
+//------------------------------union_traces----------------------------------
+// Union two traces together in uf, and null out the trace in the list
+void PhaseBlockLayout::union_traces(Trace* updated_trace, Trace* old_trace)
+{
+  uint old_id = old_trace->id();
+  uint updated_id = updated_trace->id();
+
+  uint lo_id = updated_id;
+  uint hi_id = old_id;
+
+  // If from is greater than to, swap values to meet
+  // UnionFind guarantee.
+  if (updated_id > old_id) {
+    lo_id = old_id;
+    hi_id = updated_id;
+
+    // Fix up the trace ids
+    traces[lo_id] = traces[updated_id];
+    updated_trace->set_id(lo_id);
+  }
+
+  // Union the lower with the higher and remove the pointer
+  // to the higher.
+  uf->Union(lo_id, hi_id);
+  traces[hi_id] = NULL;
+}
+
+//------------------------------grow_traces-------------------------------------
+// Append traces together via the most frequently executed edges
+void PhaseBlockLayout::grow_traces()
+{
+  // Order the edges, and drive the growth of Traces via the most
+  // frequently executed edges.
+  edges->sort(edge_order);
+  for (int i = 0; i < edges->length(); i++) {
+    CFGEdge *e = edges->at(i);
+
+    if (e->state() != CFGEdge::open) continue;
+
+    Block *src_block = e->from();
+    Block *targ_block = e->to();
+
+    // Don't grow traces along backedges?
+    if (!BlockLayoutRotateLoops) {
+      if (targ_block->_rpo <= src_block->_rpo) {
+        targ_block->set_loop_alignment(targ_block);
+        continue;
+      }
+    }
+
+    Trace *src_trace = trace(src_block);
+    Trace *targ_trace = trace(targ_block);
+
+    // If the edge in question can join two traces at their ends,
+    // append one trace to the other.
+   if (src_trace->last_block() == src_block) {
+      if (src_trace == targ_trace) {
+        e->set_state(CFGEdge::interior);
+        if (targ_trace->backedge(e)) {
+          // Reset i to catch any newly eligible edge
+          // (Or we could remember the first "open" edge, and reset there)
+          i = 0;
+        }
+      } else if (targ_trace->first_block() == targ_block) {
+        e->set_state(CFGEdge::connected);
+        src_trace->append(targ_trace);
+        union_traces(src_trace, targ_trace);
+      }
+    }
+  }
+}
+
+//------------------------------merge_traces-----------------------------------
+// Embed one trace into another, if the fork or join points are sufficiently
+// balanced.
+void PhaseBlockLayout::merge_traces(bool fall_thru_only)
+{
+  // Walk the edge list a another time, looking at unprocessed edges.
+  // Fold in diamonds
+  for (int i = 0; i < edges->length(); i++) {
+    CFGEdge *e = edges->at(i);
+
+    if (e->state() != CFGEdge::open) continue;
+    if (fall_thru_only) {
+      if (e->infrequent()) continue;
+    }
+
+    Block *src_block = e->from();
+    Trace *src_trace = trace(src_block);
+    bool src_at_tail = src_trace->last_block() == src_block;
+
+    Block *targ_block  = e->to();
+    Trace *targ_trace  = trace(targ_block);
+    bool targ_at_start = targ_trace->first_block() == targ_block;
+
+    if (src_trace == targ_trace) {
+      // This may be a loop, but we can't do much about it.
+      e->set_state(CFGEdge::interior);
+      continue;
+    }
+
+    if (fall_thru_only) {
+      // If the edge links the middle of two traces, we can't do anything.
+      // Mark the edge and continue.
+      if (!src_at_tail & !targ_at_start) {
+        continue;
+      }
+
+      // Don't grow traces along backedges?
+      if (!BlockLayoutRotateLoops && (targ_block->_rpo <= src_block->_rpo)) {
+          continue;
+      }
+
+      // If both ends of the edge are available, why didn't we handle it earlier?
+      assert(src_at_tail ^ targ_at_start, "Should have caught this edge earlier.");
+
+      if (targ_at_start) {
+        // Insert the "targ" trace in the "src" trace if the insertion point
+        // is a two way branch.
+        // Better profitability check possible, but may not be worth it.
+        // Someday, see if the this "fork" has an associated "join";
+        // then make a policy on merging this trace at the fork or join.
+        // For example, other things being equal, it may be better to place this
+        // trace at the join point if the "src" trace ends in a two-way, but
+        // the insertion point is one-way.
+        assert(src_block->num_fall_throughs() == 2, "unexpected diamond");
+        e->set_state(CFGEdge::connected);
+        src_trace->insert_after(src_block, targ_trace);
+        union_traces(src_trace, targ_trace);
+      } else if (src_at_tail) {
+        if (src_trace != trace(_cfg._broot)) {
+          e->set_state(CFGEdge::connected);
+          targ_trace->insert_before(targ_block, src_trace);
+          union_traces(targ_trace, src_trace);
+        }
+      }
+    } else if (e->state() == CFGEdge::open) {
+      // Append traces, even without a fall-thru connection.
+      // But leave root entry at the begining of the block list.
+      if (targ_trace != trace(_cfg._broot)) {
+        e->set_state(CFGEdge::connected);
+        src_trace->append(targ_trace);
+        union_traces(src_trace, targ_trace);
+      }
+    }
+  }
+}
+
+//----------------------------reorder_traces-----------------------------------
+// Order the sequence of the traces in some desirable way, and fixup the
+// jumps at the end of each block.
+void PhaseBlockLayout::reorder_traces(int count)
+{
+  ResourceArea *area = Thread::current()->resource_area();
+  Trace ** new_traces = NEW_ARENA_ARRAY(area, Trace *, count);
+  Block_List worklist;
+  int new_count = 0;
+
+  // Compact the traces.
+  for (int i = 0; i < count; i++) {
+    Trace *tr = traces[i];
+    if (tr != NULL) {
+      new_traces[new_count++] = tr;
+    }
+  }
+
+  // The entry block should be first on the new trace list.
+  Trace *tr = trace(_cfg._broot);
+  assert(tr == new_traces[0], "entry trace misplaced");
+
+  // Sort the new trace list by frequency
+  qsort(new_traces + 1, new_count - 1, sizeof(new_traces[0]), trace_frequency_order);
+
+  // Patch up the successor blocks
+  _cfg._blocks.reset();
+  _cfg._num_blocks = 0;
+  for (int i = 0; i < new_count; i++) {
+    Trace *tr = new_traces[i];
+    if (tr != NULL) {
+      tr->fixup_blocks(_cfg);
+    }
+  }
+}
+
+//------------------------------PhaseBlockLayout-------------------------------
+// Order basic blocks based on frequency
+PhaseBlockLayout::PhaseBlockLayout(PhaseCFG &cfg) :
+  Phase(BlockLayout),
+  _cfg(cfg)
+{
+  ResourceMark rm;
+  ResourceArea *area = Thread::current()->resource_area();
+
+  // List of traces
+  int size = _cfg._num_blocks + 1;
+  traces = NEW_ARENA_ARRAY(area, Trace *, size);
+  memset(traces, 0, size*sizeof(Trace*));
+  next = NEW_ARENA_ARRAY(area, Block *, size);
+  memset(next,   0, size*sizeof(Block *));
+  prev = NEW_ARENA_ARRAY(area, Block *, size);
+  memset(prev  , 0, size*sizeof(Block *));
+
+  // List of edges
+  edges = new GrowableArray<CFGEdge*>;
+
+  // Mapping block index --> block_trace
+  uf = new UnionFind(size);
+  uf->reset(size);
+
+  // Find edges and create traces.
+  find_edges();
+
+  // Grow traces at their ends via most frequent edges.
+  grow_traces();
+
+  // Merge one trace into another, but only at fall-through points.
+  // This may make diamonds and other related shapes in a trace.
+  merge_traces(true);
+
+  // Run merge again, allowing two traces to be catenated, even if
+  // one does not fall through into the other. This appends loosely
+  // related traces to be near each other.
+  merge_traces(false);
+
+  // Re-order all the remaining traces by frequency
+  reorder_traces(size);
+
+  assert(_cfg._num_blocks >= (uint) (size - 1), "number of blocks can not shrink");
+}
+
+
+//------------------------------backedge---------------------------------------
+// Edge e completes a loop in a trace. If the target block is head of the
+// loop, rotate the loop block so that the loop ends in a conditional branch.
+bool Trace::backedge(CFGEdge *e) {
+  bool loop_rotated = false;
+  Block *src_block  = e->from();
+  Block *targ_block    = e->to();
+
+  assert(last_block() == src_block, "loop discovery at back branch");
+  if (first_block() == targ_block) {
+    if (BlockLayoutRotateLoops && last_block()->num_fall_throughs() < 2) {
+      // Find the last block in the trace that has a conditional
+      // branch.
+      Block *b;
+      for (b = last_block(); b != NULL; b = prev(b)) {
+        if (b->num_fall_throughs() == 2) {
+          break;
+        }
+      }
+
+      if (b != last_block() && b != NULL) {
+        loop_rotated = true;
+
+        // Rotate the loop by doing two-part linked-list surgery.
+        append(first_block());
+        break_loop_after(b);
+      }
+    }
+
+    // Backbranch to the top of a trace
+    // Scroll foward through the trace from the targ_block. If we find
+    // a loop head before another loop top, use the the loop head alignment.
+    for (Block *b = targ_block; b != NULL; b = next(b)) {
+      if (b->has_loop_alignment()) {
+        break;
+      }
+      if (b->head()->is_Loop()) {
+        targ_block = b;
+        break;
+      }
+    }
+
+    first_block()->set_loop_alignment(targ_block);
+
+  } else {
+    // Backbranch into the middle of a trace
+    targ_block->set_loop_alignment(targ_block);
+  }
+
+  return loop_rotated;
+}
+
+//------------------------------fixup_blocks-----------------------------------
+// push blocks onto the CFG list
+// ensure that blocks have the correct two-way branch sense
+void Trace::fixup_blocks(PhaseCFG &cfg) {
+  Block *last = last_block();
+  for (Block *b = first_block(); b != NULL; b = next(b)) {
+    cfg._blocks.push(b);
+    cfg._num_blocks++;
+    if (!b->is_connector()) {
+      int nfallthru = b->num_fall_throughs();
+      if (b != last) {
+        if (nfallthru == 2) {
+          // Ensure that the sense of the branch is correct
+          Block *bnext = next(b);
+          Block *bs0 = b->non_connector_successor(0);
+
+          MachNode *iff = b->_nodes[b->_nodes.size()-3]->as_Mach();
+          ProjNode *proj0 = b->_nodes[b->_nodes.size()-2]->as_Proj();
+          ProjNode *proj1 = b->_nodes[b->_nodes.size()-1]->as_Proj();
+
+          if (bnext == bs0) {
+            // Fall-thru case in succs[0], should be in succs[1]
+
+            // Flip targets in _succs map
+            Block *tbs0 = b->_succs[0];
+            Block *tbs1 = b->_succs[1];
+            b->_succs.map( 0, tbs1 );
+            b->_succs.map( 1, tbs0 );
+
+            // Flip projections to match targets
+            b->_nodes.map(b->_nodes.size()-2, proj1);
+            b->_nodes.map(b->_nodes.size()-1, proj0);
+          }
+        }
+      }
+    }
+  }
+}
--- a/hotspot/src/share/vm/opto/block.hpp	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/vm/opto/block.hpp	Wed Jul 05 16:43:41 2017 +0200
@@ -75,6 +75,7 @@
   void insert( uint i, Block *n );
   uint size() const { return _cnt; }
   void reset() { _cnt = 0; }
+  void print();
 };
 
 
@@ -129,7 +130,11 @@
   uint _rpo;                    // Number in reverse post order walk
 
   virtual bool is_block() { return true; }
-  float succ_prob(uint i); // return probability of i'th successor
+  float succ_prob(uint i);      // return probability of i'th successor
+  int num_fall_throughs();      // How many fall-through candidate this block has
+  void update_uncommon_branch(Block* un); // Lower branch prob to uncommon code
+  bool succ_fall_through(uint i); // Is successor "i" is a fall-through candidate
+  Block* lone_fall_through();   // Return lone fall-through Block or null
 
   Block* dom_lca(Block* that);  // Compute LCA in dominator tree.
 #ifdef ASSERT
@@ -144,6 +149,7 @@
   // Report the alignment required by this block.  Must be a power of 2.
   // The previous block will insert nops to get this alignment.
   uint code_alignment();
+  uint compute_loop_alignment();
 
   // BLOCK_FREQUENCY is a sentinel to mark uses of constant block frequencies.
   // It is currently also used to scale such frequencies relative to
@@ -184,11 +190,12 @@
       int current_alignment = current_offset & max_pad;
       if( current_alignment != 0 ) {
         uint padding = (block_alignment-current_alignment) & max_pad;
-        if( !head()->is_Loop() ||
-            padding <= (uint)MaxLoopPad ||
-            first_inst_size() > padding ) {
-          return padding;
+        if( has_loop_alignment() &&
+            padding > (uint)MaxLoopPad &&
+            first_inst_size() <= padding ) {
+          return 0;
         }
+        return padding;
       }
     }
     return 0;
@@ -202,6 +209,21 @@
   void set_connector() { _connector = true; }
   bool is_connector() const { return _connector; };
 
+  // Loop_alignment will be set for blocks which are at the top of loops.
+  // The block layout pass may rotate loops such that the loop head may not
+  // be the sequentially first block of the loop encountered in the linear
+  // list of blocks.  If the layout pass is not run, loop alignment is set
+  // for each block which is the head of a loop.
+  uint _loop_alignment;
+  void set_loop_alignment(Block *loop_top) {
+    uint new_alignment = loop_top->compute_loop_alignment();
+    if (new_alignment > _loop_alignment) {
+      _loop_alignment = new_alignment;
+    }
+  }
+  uint loop_alignment() const { return _loop_alignment; }
+  bool has_loop_alignment() const { return loop_alignment() > 0; }
+
   // Create a new Block with given head Node.
   // Creates the (empty) predecessor arrays.
   Block( Arena *a, Node *headnode )
@@ -219,7 +241,8 @@
       _raise_LCA_mark(0),
       _raise_LCA_visited(0),
       _first_inst_size(999999),
-      _connector(false) {
+      _connector(false),
+      _loop_alignment(0) {
     _nodes.push(headnode);
   }
 
@@ -275,6 +298,16 @@
     return s;
   }
 
+  // Return true if b is a successor of this block
+  bool has_successor(Block* b) const {
+    for (uint i = 0; i < _num_succs; i++ ) {
+      if (non_connector_successor(i) == b) {
+        return true;
+      }
+    }
+    return false;
+  }
+
   // Successor block, after forwarding through connectors
   Block* non_connector_successor(int i) const {
     return _succs[i]->non_connector();
@@ -319,7 +352,6 @@
 
   // I'll need a few machine-specific GotoNodes.  Clone from this one.
   MachNode *_goto;
-  void insert_goto_at(uint block_no, uint succ_no);
 
   Block* insert_anti_dependences(Block* LCA, Node* load, bool verify = false);
   void verify_anti_dependences(Block* LCA, Node* load) {
@@ -379,10 +411,15 @@
   // Compute the instruction global latency with a backwards walk
   void ComputeLatenciesBackwards(VectorSet &visited, Node_List &stack);
 
+  // Set loop alignment
+  void set_loop_alignment();
+
   // Remove empty basic blocks
-  void RemoveEmpty();
-  bool MoveToNext(Block* bx, uint b_index);
-  void MoveToEnd(Block* bx, uint b_index);
+  void remove_empty();
+  void fixup_flow();
+  bool move_to_next(Block* bx, uint b_index);
+  void move_to_end(Block* bx, uint b_index);
+  void insert_goto_at(uint block_no, uint succ_no);
 
   // Check for NeverBranch at block end.  This needs to become a GOTO to the
   // true target.  NeverBranch are treated as a conditional branch that always
@@ -413,7 +450,7 @@
 };
 
 
-//------------------------------UnionFindInfo----------------------------------
+//------------------------------UnionFind--------------------------------------
 // Map Block indices to a block-index for a cfg-cover.
 // Array lookup in the optimized case.
 class UnionFind : public ResourceObj {
@@ -508,3 +545,166 @@
   void dump_tree() const;
 #endif
 };
+
+
+//----------------------------------CFGEdge------------------------------------
+// A edge between two basic blocks that will be embodied by a branch or a
+// fall-through.
+class CFGEdge : public ResourceObj {
+ private:
+  Block * _from;        // Source basic block
+  Block * _to;          // Destination basic block
+  float _freq;          // Execution frequency (estimate)
+  int   _state;
+  bool  _infrequent;
+  int   _from_pct;
+  int   _to_pct;
+
+  // Private accessors
+  int  from_pct() const { return _from_pct; }
+  int  to_pct()   const { return _to_pct;   }
+  int  from_infrequent() const { return from_pct() < BlockLayoutMinDiamondPercentage; }
+  int  to_infrequent()   const { return to_pct()   < BlockLayoutMinDiamondPercentage; }
+
+ public:
+  enum {
+    open,               // initial edge state; unprocessed
+    connected,          // edge used to connect two traces together
+    interior            // edge is interior to trace (could be backedge)
+  };
+
+  CFGEdge(Block *from, Block *to, float freq, int from_pct, int to_pct) :
+    _from(from), _to(to), _freq(freq),
+    _from_pct(from_pct), _to_pct(to_pct), _state(open) {
+    _infrequent = from_infrequent() || to_infrequent();
+  }
+
+  float  freq() const { return _freq; }
+  Block* from() const { return _from; }
+  Block* to  () const { return _to;   }
+  int  infrequent() const { return _infrequent; }
+  int state() const { return _state; }
+
+  void set_state(int state) { _state = state; }
+
+#ifndef PRODUCT
+  void dump( ) const;
+#endif
+};
+
+
+//-----------------------------------Trace-------------------------------------
+// An ordered list of basic blocks.
+class Trace : public ResourceObj {
+ private:
+  uint _id;             // Unique Trace id (derived from initial block)
+  Block ** _next_list;  // Array mapping index to next block
+  Block ** _prev_list;  // Array mapping index to previous block
+  Block * _first;       // First block in the trace
+  Block * _last;        // Last block in the trace
+
+  // Return the block that follows "b" in the trace.
+  Block * next(Block *b) const { return _next_list[b->_pre_order]; }
+  void set_next(Block *b, Block *n) const { _next_list[b->_pre_order] = n; }
+
+  // Return the block that preceeds "b" in the trace.
+  Block * prev(Block *b) const { return _prev_list[b->_pre_order]; }
+  void set_prev(Block *b, Block *p) const { _prev_list[b->_pre_order] = p; }
+
+  // We've discovered a loop in this trace. Reset last to be "b", and first as
+  // the block following "b
+  void break_loop_after(Block *b) {
+    _last = b;
+    _first = next(b);
+    set_prev(_first, NULL);
+    set_next(_last, NULL);
+  }
+
+ public:
+
+  Trace(Block *b, Block **next_list, Block **prev_list) :
+    _first(b),
+    _last(b),
+    _next_list(next_list),
+    _prev_list(prev_list),
+    _id(b->_pre_order) {
+    set_next(b, NULL);
+    set_prev(b, NULL);
+  };
+
+  // Return the id number
+  uint id() const { return _id; }
+  void set_id(uint id) { _id = id; }
+
+  // Return the first block in the trace
+  Block * first_block() const { return _first; }
+
+  // Return the last block in the trace
+  Block * last_block() const { return _last; }
+
+  // Insert a trace in the middle of this one after b
+  void insert_after(Block *b, Trace *tr) {
+    set_next(tr->last_block(), next(b));
+    if (next(b) != NULL) {
+      set_prev(next(b), tr->last_block());
+    }
+
+    set_next(b, tr->first_block());
+    set_prev(tr->first_block(), b);
+
+    if (b == _last) {
+      _last = tr->last_block();
+    }
+  }
+
+  void insert_before(Block *b, Trace *tr) {
+    Block *p = prev(b);
+    assert(p != NULL, "use append instead");
+    insert_after(p, tr);
+  }
+
+  // Append another trace to this one.
+  void append(Trace *tr) {
+    insert_after(_last, tr);
+  }
+
+  // Append a block at the end of this trace
+  void append(Block *b) {
+    set_next(_last, b);
+    set_prev(b, _last);
+    _last = b;
+  }
+
+  // Adjust the the blocks in this trace
+  void fixup_blocks(PhaseCFG &cfg);
+  bool backedge(CFGEdge *e);
+
+#ifndef PRODUCT
+  void dump( ) const;
+#endif
+};
+
+//------------------------------PhaseBlockLayout-------------------------------
+// Rearrange blocks into some canonical order, based on edges and their frequencies
+class PhaseBlockLayout : public Phase {
+  PhaseCFG &_cfg;               // Control flow graph
+
+  GrowableArray<CFGEdge *> *edges;
+  Trace **traces;
+  Block **next;
+  Block **prev;
+  UnionFind *uf;
+
+  // Given a block, find its encompassing Trace
+  Trace * trace(Block *b) {
+    return traces[uf->Find_compress(b->_pre_order)];
+  }
+ public:
+  PhaseBlockLayout(PhaseCFG &cfg);
+
+  void find_edges();
+  void grow_traces();
+  void merge_traces(bool loose_connections);
+  void reorder_traces(int count);
+  void union_traces(Trace* from, Trace* to);
+};
--- a/hotspot/src/share/vm/opto/c2_globals.hpp	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/vm/opto/c2_globals.hpp	Wed Jul 05 16:43:41 2017 +0200
@@ -388,6 +388,9 @@
   product(intx, EliminateAllocationArraySizeLimit, 64,                      \
           "Array size (number of elements) limit for scalar replacement")   \
                                                                             \
+  product(bool, UseOptoBiasInlining, true,                                 \
+          "Generate biased locking code in C2 ideal graph")                 \
+                                                                            \
   product(intx, ValueSearchLimit, 1000,                                     \
           "Recursion limit in PhaseMacroExpand::value_from_mem_phi")        \
                                                                             \
@@ -396,5 +399,15 @@
                                                                             \
   diagnostic(intx, DominatorSearchLimit, 1000,                              \
           "Iterations limit in Node::dominates")                            \
+                                                                            \
+  product(bool, BlockLayoutByFrequency, true,                               \
+          "Use edge frequencies to drive block ordering")                   \
+                                                                            \
+  product(intx, BlockLayoutMinDiamondPercentage, 20,                        \
+          "Miniumum %% of a successor (predecessor) for which block layout "\
+          "a will allow a fork (join) in a single chain")                   \
+                                                                            \
+  product(bool, BlockLayoutRotateLoops, false,                              \
+          "Allow back branches to be fall throughs in the block layour")    \
 
 C2_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_NOTPRODUCT_FLAG)
--- a/hotspot/src/share/vm/opto/callnode.cpp	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/vm/opto/callnode.cpp	Wed Jul 05 16:43:41 2017 +0200
@@ -967,6 +967,7 @@
   init_class_id(Class_SafePointScalarObject);
 }
 
+bool SafePointScalarObjectNode::pinned() const { return true; }
 
 uint SafePointScalarObjectNode::ideal_reg() const {
   return 0; // No matching to machine instruction
--- a/hotspot/src/share/vm/opto/callnode.hpp	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/vm/opto/callnode.hpp	Wed Jul 05 16:43:41 2017 +0200
@@ -433,6 +433,10 @@
   uint n_fields()    const { return _n_fields; }
   DEBUG_ONLY(AllocateNode* alloc() const { return _alloc; })
 
+  // SafePointScalarObject should be always pinned to the control edge
+  // of the SafePoint node for which it was generated.
+  virtual bool pinned() const; // { return true; }
+
   virtual uint size_of() const { return sizeof(*this); }
 
   // Assumes that "this" is an argument to a safepoint node "s", and that
--- a/hotspot/src/share/vm/opto/chaitin.cpp	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/vm/opto/chaitin.cpp	Wed Jul 05 16:43:41 2017 +0200
@@ -440,9 +440,7 @@
   assert((int)(_matcher._new_SP+_framesize) >= (int)_matcher._out_arg_limit, "framesize must be large enough");
 
   // This frame must preserve the required fp alignment
-  const int stack_alignment_in_words = Matcher::stack_alignment_in_slots();
-  if (stack_alignment_in_words > 0)
-    _framesize = round_to(_framesize, Matcher::stack_alignment_in_bytes());
+  _framesize = round_to(_framesize, Matcher::stack_alignment_in_slots());
   assert( _framesize >= 0 && _framesize <= 1000000, "sanity check" );
 #ifndef PRODUCT
   _total_framesize += _framesize;
--- a/hotspot/src/share/vm/opto/classes.hpp	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/vm/opto/classes.hpp	Wed Jul 05 16:43:41 2017 +0200
@@ -205,6 +205,7 @@
 macro(StoreC)
 macro(StoreCM)
 macro(StorePConditional)
+macro(StoreIConditional)
 macro(StoreLConditional)
 macro(StoreD)
 macro(StoreF)
--- a/hotspot/src/share/vm/opto/compile.cpp	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/vm/opto/compile.cpp	Wed Jul 05 16:43:41 2017 +0200
@@ -551,7 +551,7 @@
       rethrow_exceptions(kit.transfer_exceptions_into_jvms());
     }
 
-    print_method("Before RemoveUseless");
+    print_method("Before RemoveUseless", 3);
 
     // Remove clutter produced by parsing.
     if (!failing()) {
@@ -822,6 +822,7 @@
   Copy::zero_to_bytes(_trap_hist, sizeof(_trap_hist));
   set_decompile_count(0);
 
+  set_do_freq_based_layout(BlockLayoutByFrequency || method_has_option("BlockLayoutByFrequency"));
   // Compilation level related initialization
   if (env()->comp_level() == CompLevel_fast_compile) {
     set_num_loop_opts(Tier1LoopOptsCount);
@@ -1701,8 +1702,14 @@
   // are not adding any new instructions.  If any basic block is empty, we
   // can now safely remove it.
   {
-    NOT_PRODUCT( TracePhase t2("removeEmpty", &_t_removeEmptyBlocks, TimeCompiler); )
-    cfg.RemoveEmpty();
+    NOT_PRODUCT( TracePhase t2("blockOrdering", &_t_blockOrdering, TimeCompiler); )
+    cfg.remove_empty();
+    if (do_freq_based_layout()) {
+      PhaseBlockLayout layout(cfg);
+    } else {
+      cfg.set_loop_alignment();
+    }
+    cfg.fixup_flow();
   }
 
   // Perform any platform dependent postallocation verifications.
@@ -1994,6 +2001,7 @@
   case Op_StorePConditional:
   case Op_StoreI:
   case Op_StoreL:
+  case Op_StoreIConditional:
   case Op_StoreLConditional:
   case Op_CompareAndSwapI:
   case Op_CompareAndSwapL:
--- a/hotspot/src/share/vm/opto/compile.hpp	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/vm/opto/compile.hpp	Wed Jul 05 16:43:41 2017 +0200
@@ -154,6 +154,7 @@
   uint                  _decompile_count;       // Cumulative decompilation counts.
   bool                  _do_inlining;           // True if we intend to do inlining
   bool                  _do_scheduling;         // True if we intend to do scheduling
+  bool                  _do_freq_based_layout;  // True if we intend to do frequency based block layout
   bool                  _do_count_invocations;  // True if we generate code to count invocations
   bool                  _do_method_data_update; // True if we generate code to update methodDataOops
   int                   _AliasLevel;            // Locally-adjusted version of AliasLevel flag.
@@ -307,6 +308,8 @@
   void          set_do_inlining(bool z)         { _do_inlining = z; }
   bool              do_scheduling() const       { return _do_scheduling; }
   void          set_do_scheduling(bool z)       { _do_scheduling = z; }
+  bool              do_freq_based_layout() const{ return _do_freq_based_layout; }
+  void          set_do_freq_based_layout(bool z){ _do_freq_based_layout = z; }
   bool              do_count_invocations() const{ return _do_count_invocations; }
   void          set_do_count_invocations(bool z){ _do_count_invocations = z; }
   bool              do_method_data_update() const { return _do_method_data_update; }
--- a/hotspot/src/share/vm/opto/gcm.cpp	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/vm/opto/gcm.cpp	Wed Jul 05 16:43:41 2017 +0200
@@ -1319,11 +1319,33 @@
 //------------------------------Estimate_Block_Frequency-----------------------
 // Estimate block frequencies based on IfNode probabilities.
 void PhaseCFG::Estimate_Block_Frequency() {
-  int cnts = C->method() ? C->method()->interpreter_invocation_count() : 1;
-  // Most of our algorithms will die horribly if frequency can become
-  // negative so make sure cnts is a sane value.
-  if( cnts <= 0 ) cnts = 1;
-  float f = (float)cnts/(float)FreqCountInvocations;
+
+  // Force conditional branches leading to uncommon traps to be unlikely,
+  // not because we get to the uncommon_trap with less relative frequency,
+  // but because an uncommon_trap typically causes a deopt, so we only get
+  // there once.
+  if (C->do_freq_based_layout()) {
+    Block_List worklist;
+    Block* root_blk = _blocks[0];
+    for (uint i = 1; i < root_blk->num_preds(); i++) {
+      Block *pb = _bbs[root_blk->pred(i)->_idx];
+      if (pb->has_uncommon_code()) {
+        worklist.push(pb);
+      }
+    }
+    while (worklist.size() > 0) {
+      Block* uct = worklist.pop();
+      if (uct == _broot) continue;
+      for (uint i = 1; i < uct->num_preds(); i++) {
+        Block *pb = _bbs[uct->pred(i)->_idx];
+        if (pb->_num_succs == 1) {
+          worklist.push(pb);
+        } else if (pb->num_fall_throughs() == 2) {
+          pb->update_uncommon_branch(uct);
+        }
+      }
+    }
+  }
 
   // Create the loop tree and calculate loop depth.
   _root_loop = create_loop_tree();
@@ -1333,25 +1355,27 @@
   _root_loop->compute_freq();
 
   // Adjust all frequencies to be relative to a single method entry
-  _root_loop->_freq = f * 1.0;
+  _root_loop->_freq = 1.0;
   _root_loop->scale_freq();
 
   // force paths ending at uncommon traps to be infrequent
-  Block_List worklist;
-  Block* root_blk = _blocks[0];
-  for (uint i = 0; i < root_blk->num_preds(); i++) {
-    Block *pb = _bbs[root_blk->pred(i)->_idx];
-    if (pb->has_uncommon_code()) {
-      worklist.push(pb);
+  if (!C->do_freq_based_layout()) {
+    Block_List worklist;
+    Block* root_blk = _blocks[0];
+    for (uint i = 1; i < root_blk->num_preds(); i++) {
+      Block *pb = _bbs[root_blk->pred(i)->_idx];
+      if (pb->has_uncommon_code()) {
+        worklist.push(pb);
+      }
     }
-  }
-  while (worklist.size() > 0) {
-    Block* uct = worklist.pop();
-    uct->_freq = PROB_MIN;
-    for (uint i = 0; i < uct->num_preds(); i++) {
-      Block *pb = _bbs[uct->pred(i)->_idx];
-      if (pb->_num_succs == 1 && pb->_freq > PROB_MIN) {
-        worklist.push(pb);
+    while (worklist.size() > 0) {
+      Block* uct = worklist.pop();
+      uct->_freq = PROB_MIN;
+      for (uint i = 1; i < uct->num_preds(); i++) {
+        Block *pb = _bbs[uct->pred(i)->_idx];
+        if (pb->_num_succs == 1 && pb->_freq > PROB_MIN) {
+          worklist.push(pb);
+        }
       }
     }
   }
@@ -1556,22 +1580,6 @@
     }
   }
 
-#if 0
-  // Raise frequency of the loop backedge block, in an effort
-  // to keep it empty.  Skip the method level "loop".
-  if (_parent != NULL) {
-    CFGElement* s = _members.at(_members.length() - 1);
-    if (s->is_block()) {
-      Block* bk = s->as_Block();
-      if (bk->_num_succs == 1 && bk->_succs[0] == hd) {
-        // almost any value >= 1.0f works
-        // FIXME: raw constant
-        bk->_freq = 1.05f;
-      }
-    }
-  }
-#endif
-
   // For all loops other than the outer, "method" loop,
   // sum and normalize the exit probability. The "method" loop
   // should keep the initial exit probability of 1, so that
@@ -1589,12 +1597,15 @@
     // the probability of exit per loop entry.
     for (int i = 0; i < _exits.length(); i++) {
       Block* et = _exits.at(i).get_target();
-      float new_prob = _exits.at(i).get_prob() / exits_sum;
+      float new_prob = 0.0f;
+      if (_exits.at(i).get_prob() > 0.0f) {
+        new_prob = _exits.at(i).get_prob() / exits_sum;
+      }
       BlockProbPair bpp(et, new_prob);
       _exits.at_put(i, bpp);
     }
 
-    // Save the total, but guard against unreasoable probability,
+    // Save the total, but guard against unreasonable probability,
     // as the value is used to estimate the loop trip count.
     // An infinite trip count would blur relative block
     // frequencies.
@@ -1688,6 +1699,137 @@
   return 0.0f;
 }
 
+//------------------------------num_fall_throughs-----------------------------
+// Return the number of fall-through candidates for a block
+int Block::num_fall_throughs() {
+  int eidx = end_idx();
+  Node *n = _nodes[eidx];  // Get ending Node
+
+  int op = n->Opcode();
+  if (n->is_Mach()) {
+    if (n->is_MachNullCheck()) {
+      // In theory, either side can fall-thru, for simplicity sake,
+      // let's say only the false branch can now.
+      return 1;
+    }
+    op = n->as_Mach()->ideal_Opcode();
+  }
+
+  // Switch on branch type
+  switch( op ) {
+  case Op_CountedLoopEnd:
+  case Op_If:
+    return 2;
+
+  case Op_Root:
+  case Op_Goto:
+    return 1;
+
+  case Op_Catch: {
+    for (uint i = 0; i < _num_succs; i++) {
+      const CatchProjNode *ci = _nodes[i + eidx + 1]->as_CatchProj();
+      if (ci->_con == CatchProjNode::fall_through_index) {
+        return 1;
+      }
+    }
+    return 0;
+  }
+
+  case Op_Jump:
+  case Op_NeverBranch:
+  case Op_TailCall:
+  case Op_TailJump:
+  case Op_Return:
+  case Op_Halt:
+  case Op_Rethrow:
+    return 0;
+
+  default:
+    ShouldNotReachHere();
+  }
+
+  return 0;
+}
+
+//------------------------------succ_fall_through-----------------------------
+// Return true if a specific successor could be fall-through target.
+bool Block::succ_fall_through(uint i) {
+  int eidx = end_idx();
+  Node *n = _nodes[eidx];  // Get ending Node
+
+  int op = n->Opcode();
+  if (n->is_Mach()) {
+    if (n->is_MachNullCheck()) {
+      // In theory, either side can fall-thru, for simplicity sake,
+      // let's say only the false branch can now.
+      return _nodes[i + eidx + 1]->Opcode() == Op_IfFalse;
+    }
+    op = n->as_Mach()->ideal_Opcode();
+  }
+
+  // Switch on branch type
+  switch( op ) {
+  case Op_CountedLoopEnd:
+  case Op_If:
+  case Op_Root:
+  case Op_Goto:
+    return true;
+
+  case Op_Catch: {
+    const CatchProjNode *ci = _nodes[i + eidx + 1]->as_CatchProj();
+    return ci->_con == CatchProjNode::fall_through_index;
+  }
+
+  case Op_Jump:
+  case Op_NeverBranch:
+  case Op_TailCall:
+  case Op_TailJump:
+  case Op_Return:
+  case Op_Halt:
+  case Op_Rethrow:
+    return false;
+
+  default:
+    ShouldNotReachHere();
+  }
+
+  return false;
+}
+
+//------------------------------update_uncommon_branch------------------------
+// Update the probability of a two-branch to be uncommon
+void Block::update_uncommon_branch(Block* ub) {
+  int eidx = end_idx();
+  Node *n = _nodes[eidx];  // Get ending Node
+
+  int op = n->as_Mach()->ideal_Opcode();
+
+  assert(op == Op_CountedLoopEnd || op == Op_If, "must be a If");
+  assert(num_fall_throughs() == 2, "must be a two way branch block");
+
+  // Which successor is ub?
+  uint s;
+  for (s = 0; s <_num_succs; s++) {
+    if (_succs[s] == ub) break;
+  }
+  assert(s < 2, "uncommon successor must be found");
+
+  // If ub is the true path, make the proability small, else
+  // ub is the false path, and make the probability large
+  bool invert = (_nodes[s + eidx + 1]->Opcode() == Op_IfFalse);
+
+  // Get existing probability
+  float p = n->as_MachIf()->_prob;
+
+  if (invert) p = 1.0 - p;
+  if (p > PROB_MIN) {
+    p = PROB_MIN;
+  }
+  if (invert) p = 1.0 - p;
+
+  n->as_MachIf()->_prob = p;
+}
+
 //------------------------------update_succ_freq-------------------------------
 // Update the appropriate frequency associated with block 'b', a succesor of
 // a block in this loop.
--- a/hotspot/src/share/vm/opto/library_call.cpp	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/vm/opto/library_call.cpp	Wed Jul 05 16:43:41 2017 +0200
@@ -3485,11 +3485,32 @@
   const TypePtr *adr_type = _gvn.type(adr)->is_ptr();
   int alias_idx = C->get_alias_index(adr_type);
 
-  Node *result = _gvn.transform(new (C, 5) StoreLConditionalNode(control(), memory(alias_idx), adr, newVal, oldVal));
-  Node *store_proj = _gvn.transform( new (C, 1) SCMemProjNode(result));
+  Node *cas = _gvn.transform(new (C, 5) StoreLConditionalNode(control(), memory(alias_idx), adr, newVal, oldVal));
+  Node *store_proj = _gvn.transform( new (C, 1) SCMemProjNode(cas));
   set_memory(store_proj, alias_idx);
-
-  push(result);
+  Node *bol = _gvn.transform( new (C, 2) BoolNode( cas, BoolTest::eq ) );
+
+  Node *result;
+  // CMove node is not used to be able fold a possible check code
+  // after attemptUpdate() call. This code could be transformed
+  // into CMove node by loop optimizations.
+  {
+    RegionNode *r = new (C, 3) RegionNode(3);
+    result = new (C, 3) PhiNode(r, TypeInt::BOOL);
+
+    Node *iff = create_and_xform_if(control(), bol, PROB_FAIR, COUNT_UNKNOWN);
+    Node *iftrue = opt_iff(r, iff);
+    r->init_req(1, iftrue);
+    result->init_req(1, intcon(1));
+    result->init_req(2, intcon(0));
+
+    set_control(_gvn.transform(r));
+    record_for_igvn(r);
+
+    C->set_has_split_ifs(true); // Has chance for split-if optimization
+  }
+
+  push(_gvn.transform(result));
   return true;
 }
 
--- a/hotspot/src/share/vm/opto/loopTransform.cpp	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/vm/opto/loopTransform.cpp	Wed Jul 05 16:43:41 2017 +0200
@@ -1519,6 +1519,7 @@
         Node *bol = iff->in(1);
         if( bol && bol->req() > 1 && bol->in(1) &&
             ((bol->in(1)->Opcode() == Op_StorePConditional ) ||
+             (bol->in(1)->Opcode() == Op_StoreIConditional ) ||
              (bol->in(1)->Opcode() == Op_StoreLConditional ) ||
              (bol->in(1)->Opcode() == Op_CompareAndSwapI ) ||
              (bol->in(1)->Opcode() == Op_CompareAndSwapL ) ||
--- a/hotspot/src/share/vm/opto/macro.cpp	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/vm/opto/macro.cpp	Wed Jul 05 16:43:41 2017 +0200
@@ -82,16 +82,31 @@
   }
 }
 
-Node* PhaseMacroExpand::opt_iff(Node* region, Node* iff) {
-  IfNode *opt_iff = transform_later(iff)->as_If();
+Node* PhaseMacroExpand::opt_bits_test(Node* ctrl, Node* region, int edge, Node* word, int mask, int bits, bool return_fast_path) {
+  Node* cmp;
+  if (mask != 0) {
+    Node* and_node = transform_later(new (C, 3) AndXNode(word, MakeConX(mask)));
+    cmp = transform_later(new (C, 3) CmpXNode(and_node, MakeConX(bits)));
+  } else {
+    cmp = word;
+  }
+  Node* bol = transform_later(new (C, 2) BoolNode(cmp, BoolTest::ne));
+  IfNode* iff = new (C, 2) IfNode( ctrl, bol, PROB_MIN, COUNT_UNKNOWN );
+  transform_later(iff);
 
-  // Fast path taken; set region slot 2
-  Node *fast_taken = transform_later( new (C, 1) IfFalseNode(opt_iff) );
-  region->init_req(2,fast_taken); // Capture fast-control
+  // Fast path taken.
+  Node *fast_taken = transform_later( new (C, 1) IfFalseNode(iff) );
 
   // Fast path not-taken, i.e. slow path
-  Node *slow_taken = transform_later( new (C, 1) IfTrueNode(opt_iff) );
-  return slow_taken;
+  Node *slow_taken = transform_later( new (C, 1) IfTrueNode(iff) );
+
+  if (return_fast_path) {
+    region->init_req(edge, slow_taken); // Capture slow-control
+    return fast_taken;
+  } else {
+    region->init_req(edge, fast_taken); // Capture fast-control
+    return slow_taken;
+  }
 }
 
 //--------------------copy_predefined_input_for_runtime_call--------------------
@@ -854,7 +869,7 @@
 
 Node* PhaseMacroExpand::make_load(Node* ctl, Node* mem, Node* base, int offset, const Type* value_type, BasicType bt) {
   Node* adr = basic_plus_adr(base, offset);
-  const TypePtr* adr_type = TypeRawPtr::BOTTOM;
+  const TypePtr* adr_type = adr->bottom_type()->is_ptr();
   Node* value = LoadNode::make(_igvn, ctl, mem, adr, adr_type, value_type, bt);
   transform_later(value);
   return value;
@@ -1583,12 +1598,194 @@
   Node* flock = lock->fastlock_node();
 
   // Make the merge point
-  Node *region = new (C, 3) RegionNode(3);
+  Node *region;
+  Node *mem_phi;
+  Node *slow_path;
 
-  Node *bol = transform_later(new (C, 2) BoolNode(flock,BoolTest::ne));
-  Node *iff = new (C, 2) IfNode( ctrl, bol, PROB_MIN, COUNT_UNKNOWN );
-  // Optimize test; set region slot 2
-  Node *slow_path = opt_iff(region,iff);
+  if (UseOptoBiasInlining) {
+    /*
+     *  See the full descrition in MacroAssembler::biased_locking_enter().
+     *
+     *  if( (mark_word & biased_lock_mask) == biased_lock_pattern ) {
+     *    // The object is biased.
+     *    proto_node = klass->prototype_header;
+     *    o_node = thread | proto_node;
+     *    x_node = o_node ^ mark_word;
+     *    if( (x_node & ~age_mask) == 0 ) { // Biased to the current thread ?
+     *      // Done.
+     *    } else {
+     *      if( (x_node & biased_lock_mask) != 0 ) {
+     *        // The klass's prototype header is no longer biased.
+     *        cas(&mark_word, mark_word, proto_node)
+     *        goto cas_lock;
+     *      } else {
+     *        // The klass's prototype header is still biased.
+     *        if( (x_node & epoch_mask) != 0 ) { // Expired epoch?
+     *          old = mark_word;
+     *          new = o_node;
+     *        } else {
+     *          // Different thread or anonymous biased.
+     *          old = mark_word & (epoch_mask | age_mask | biased_lock_mask);
+     *          new = thread | old;
+     *        }
+     *        // Try to rebias.
+     *        if( cas(&mark_word, old, new) == 0 ) {
+     *          // Done.
+     *        } else {
+     *          goto slow_path; // Failed.
+     *        }
+     *      }
+     *    }
+     *  } else {
+     *    // The object is not biased.
+     *    cas_lock:
+     *    if( FastLock(obj) == 0 ) {
+     *      // Done.
+     *    } else {
+     *      slow_path:
+     *      OptoRuntime::complete_monitor_locking_Java(obj);
+     *    }
+     *  }
+     */
+
+    region  = new (C, 5) RegionNode(5);
+    // create a Phi for the memory state
+    mem_phi = new (C, 5) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM);
+
+    Node* fast_lock_region  = new (C, 3) RegionNode(3);
+    Node* fast_lock_mem_phi = new (C, 3) PhiNode( fast_lock_region, Type::MEMORY, TypeRawPtr::BOTTOM);
+
+    // First, check mark word for the biased lock pattern.
+    Node* mark_node = make_load(ctrl, mem, obj, oopDesc::mark_offset_in_bytes(), TypeX_X, TypeX_X->basic_type());
+
+    // Get fast path - mark word has the biased lock pattern.
+    ctrl = opt_bits_test(ctrl, fast_lock_region, 1, mark_node,
+                         markOopDesc::biased_lock_mask_in_place,
+                         markOopDesc::biased_lock_pattern, true);
+    // fast_lock_region->in(1) is set to slow path.
+    fast_lock_mem_phi->init_req(1, mem);
+
+    // Now check that the lock is biased to the current thread and has
+    // the same epoch and bias as Klass::_prototype_header.
+
+    // Special-case a fresh allocation to avoid building nodes:
+    Node* klass_node = AllocateNode::Ideal_klass(obj, &_igvn);
+    if (klass_node == NULL) {
+      Node* k_adr = basic_plus_adr(obj, oopDesc::klass_offset_in_bytes());
+      klass_node = transform_later( LoadKlassNode::make(_igvn, mem, k_adr, _igvn.type(k_adr)->is_ptr()) );
+      klass_node->init_req(0, ctrl);
+    }
+    Node *proto_node = make_load(ctrl, mem, klass_node, Klass::prototype_header_offset_in_bytes() + sizeof(oopDesc), TypeX_X, TypeX_X->basic_type());
+
+    Node* thread = transform_later(new (C, 1) ThreadLocalNode());
+    Node* cast_thread = transform_later(new (C, 2) CastP2XNode(ctrl, thread));
+    Node* o_node = transform_later(new (C, 3) OrXNode(cast_thread, proto_node));
+    Node* x_node = transform_later(new (C, 3) XorXNode(o_node, mark_node));
+
+    // Get slow path - mark word does NOT match the value.
+    Node* not_biased_ctrl =  opt_bits_test(ctrl, region, 3, x_node,
+                                      (~markOopDesc::age_mask_in_place), 0);
+    // region->in(3) is set to fast path - the object is biased to the current thread.
+    mem_phi->init_req(3, mem);
+
+
+    // Mark word does NOT match the value (thread | Klass::_prototype_header).
+
+
+    // First, check biased pattern.
+    // Get fast path - _prototype_header has the same biased lock pattern.
+    ctrl =  opt_bits_test(not_biased_ctrl, fast_lock_region, 2, x_node,
+                          markOopDesc::biased_lock_mask_in_place, 0, true);
+
+    not_biased_ctrl = fast_lock_region->in(2); // Slow path
+    // fast_lock_region->in(2) - the prototype header is no longer biased
+    // and we have to revoke the bias on this object.
+    // We are going to try to reset the mark of this object to the prototype
+    // value and fall through to the CAS-based locking scheme.
+    Node* adr = basic_plus_adr(obj, oopDesc::mark_offset_in_bytes());
+    Node* cas = new (C, 5) StoreXConditionalNode(not_biased_ctrl, mem, adr,
+                                                 proto_node, mark_node);
+    transform_later(cas);
+    Node* proj = transform_later( new (C, 1) SCMemProjNode(cas));
+    fast_lock_mem_phi->init_req(2, proj);
+
+
+    // Second, check epoch bits.
+    Node* rebiased_region  = new (C, 3) RegionNode(3);
+    Node* old_phi = new (C, 3) PhiNode( rebiased_region, TypeX_X);
+    Node* new_phi = new (C, 3) PhiNode( rebiased_region, TypeX_X);
+
+    // Get slow path - mark word does NOT match epoch bits.
+    Node* epoch_ctrl =  opt_bits_test(ctrl, rebiased_region, 1, x_node,
+                                      markOopDesc::epoch_mask_in_place, 0);
+    // The epoch of the current bias is not valid, attempt to rebias the object
+    // toward the current thread.
+    rebiased_region->init_req(2, epoch_ctrl);
+    old_phi->init_req(2, mark_node);
+    new_phi->init_req(2, o_node);
+
+    // rebiased_region->in(1) is set to fast path.
+    // The epoch of the current bias is still valid but we know
+    // nothing about the owner; it might be set or it might be clear.
+    Node* cmask   = MakeConX(markOopDesc::biased_lock_mask_in_place |
+                             markOopDesc::age_mask_in_place |
+                             markOopDesc::epoch_mask_in_place);
+    Node* old = transform_later(new (C, 3) AndXNode(mark_node, cmask));
+    cast_thread = transform_later(new (C, 2) CastP2XNode(ctrl, thread));
+    Node* new_mark = transform_later(new (C, 3) OrXNode(cast_thread, old));
+    old_phi->init_req(1, old);
+    new_phi->init_req(1, new_mark);
+
+    transform_later(rebiased_region);
+    transform_later(old_phi);
+    transform_later(new_phi);
+
+    // Try to acquire the bias of the object using an atomic operation.
+    // If this fails we will go in to the runtime to revoke the object's bias.
+    cas = new (C, 5) StoreXConditionalNode(rebiased_region, mem, adr,
+                                           new_phi, old_phi);
+    transform_later(cas);
+    proj = transform_later( new (C, 1) SCMemProjNode(cas));
+
+    // Get slow path - Failed to CAS.
+    not_biased_ctrl = opt_bits_test(rebiased_region, region, 4, cas, 0, 0);
+    mem_phi->init_req(4, proj);
+    // region->in(4) is set to fast path - the object is rebiased to the current thread.
+
+    // Failed to CAS.
+    slow_path  = new (C, 3) RegionNode(3);
+    Node *slow_mem = new (C, 3) PhiNode( slow_path, Type::MEMORY, TypeRawPtr::BOTTOM);
+
+    slow_path->init_req(1, not_biased_ctrl); // Capture slow-control
+    slow_mem->init_req(1, proj);
+
+    // Call CAS-based locking scheme (FastLock node).
+
+    transform_later(fast_lock_region);
+    transform_later(fast_lock_mem_phi);
+
+    // Get slow path - FastLock failed to lock the object.
+    ctrl = opt_bits_test(fast_lock_region, region, 2, flock, 0, 0);
+    mem_phi->init_req(2, fast_lock_mem_phi);
+    // region->in(2) is set to fast path - the object is locked to the current thread.
+
+    slow_path->init_req(2, ctrl); // Capture slow-control
+    slow_mem->init_req(2, fast_lock_mem_phi);
+
+    transform_later(slow_path);
+    transform_later(slow_mem);
+    // Reset lock's memory edge.
+    lock->set_req(TypeFunc::Memory, slow_mem);
+
+  } else {
+    region  = new (C, 3) RegionNode(3);
+    // create a Phi for the memory state
+    mem_phi = new (C, 3) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM);
+
+    // Optimize test; set region slot 2
+    slow_path = opt_bits_test(ctrl, region, 2, flock, 0, 0);
+    mem_phi->init_req(2, mem);
+  }
 
   // Make slow path call
   CallNode *call = make_slow_call( (CallNode *) lock, OptoRuntime::complete_monitor_enter_Type(), OptoRuntime::complete_monitor_locking_Java(), NULL, slow_path, obj, box );
@@ -1614,16 +1811,11 @@
   transform_later(region);
   _igvn.subsume_node(_fallthroughproj, region);
 
-  // create a Phi for the memory state
-  Node *mem_phi = new (C, 3) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM);
-  Node *memproj = transform_later( new (C, 1) ProjNode(call, TypeFunc::Memory) );
+  Node *memproj = transform_later( new(C, 1) ProjNode(call, TypeFunc::Memory) );
   mem_phi->init_req(1, memproj );
-  mem_phi->init_req(2, mem);
   transform_later(mem_phi);
-    _igvn.hash_delete(_memproj_fallthrough);
+  _igvn.hash_delete(_memproj_fallthrough);
   _igvn.subsume_node(_memproj_fallthrough, mem_phi);
-
-
 }
 
 //------------------------------expand_unlock_node----------------------
@@ -1637,14 +1829,31 @@
   // No need for a null check on unlock
 
   // Make the merge point
-  RegionNode *region = new (C, 3) RegionNode(3);
+  Node *region;
+  Node *mem_phi;
+
+  if (UseOptoBiasInlining) {
+    // Check for biased locking unlock case, which is a no-op.
+    // See the full descrition in MacroAssembler::biased_locking_exit().
+    region  = new (C, 4) RegionNode(4);
+    // create a Phi for the memory state
+    mem_phi = new (C, 4) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM);
+    mem_phi->init_req(3, mem);
+
+    Node* mark_node = make_load(ctrl, mem, obj, oopDesc::mark_offset_in_bytes(), TypeX_X, TypeX_X->basic_type());
+    ctrl = opt_bits_test(ctrl, region, 3, mark_node,
+                         markOopDesc::biased_lock_mask_in_place,
+                         markOopDesc::biased_lock_pattern);
+  } else {
+    region  = new (C, 3) RegionNode(3);
+    // create a Phi for the memory state
+    mem_phi = new (C, 3) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM);
+  }
 
   FastUnlockNode *funlock = new (C, 3) FastUnlockNode( ctrl, obj, box );
   funlock = transform_later( funlock )->as_FastUnlock();
-  Node *bol = transform_later(new (C, 2) BoolNode(funlock,BoolTest::ne));
-  Node *iff = new (C, 2) IfNode( ctrl, bol, PROB_MIN, COUNT_UNKNOWN );
   // Optimize test; set region slot 2
-  Node *slow_path = opt_iff(region,iff);
+  Node *slow_path = opt_bits_test(ctrl, region, 2, funlock, 0, 0);
 
   CallNode *call = make_slow_call( (CallNode *) unlock, OptoRuntime::complete_monitor_exit_Type(), CAST_FROM_FN_PTR(address, SharedRuntime::complete_monitor_unlocking_C), "complete_monitor_unlocking_C", slow_path, obj, box );
 
@@ -1666,16 +1875,12 @@
   transform_later(region);
   _igvn.subsume_node(_fallthroughproj, region);
 
-  // create a Phi for the memory state
-  Node *mem_phi = new (C, 3) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM);
   Node *memproj = transform_later( new(C, 1) ProjNode(call, TypeFunc::Memory) );
   mem_phi->init_req(1, memproj );
   mem_phi->init_req(2, mem);
   transform_later(mem_phi);
-    _igvn.hash_delete(_memproj_fallthrough);
+  _igvn.hash_delete(_memproj_fallthrough);
   _igvn.subsume_node(_memproj_fallthrough, mem_phi);
-
-
 }
 
 //------------------------------expand_macro_nodes----------------------
--- a/hotspot/src/share/vm/opto/macro.hpp	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/vm/opto/macro.hpp	Wed Jul 05 16:43:41 2017 +0200
@@ -93,7 +93,7 @@
 
   int replace_input(Node *use, Node *oldref, Node *newref);
   void copy_call_debug_info(CallNode *oldcall, CallNode * newcall);
-  Node* opt_iff(Node* region, Node* iff);
+  Node* opt_bits_test(Node* ctrl, Node* region, int edge, Node* word, int mask, int bits, bool return_fast_path = false);
   void copy_predefined_input_for_runtime_call(Node * ctrl, CallNode* oldcall, CallNode* call);
   CallNode* make_slow_call(CallNode *oldcall, const TypeFunc* slow_call_type, address slow_call,
                        const char* leaf_name, Node* slow_path, Node* parm0, Node* parm1);
--- a/hotspot/src/share/vm/opto/matcher.cpp	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/vm/opto/matcher.cpp	Wed Jul 05 16:43:41 2017 +0200
@@ -1951,6 +1951,7 @@
       // Now hack a few special opcodes
       switch( n->Opcode() ) {       // Handle some opcodes special
       case Op_StorePConditional:
+      case Op_StoreIConditional:
       case Op_StoreLConditional:
       case Op_CompareAndSwapI:
       case Op_CompareAndSwapL:
--- a/hotspot/src/share/vm/opto/matcher.hpp	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/vm/opto/matcher.hpp	Wed Jul 05 16:43:41 2017 +0200
@@ -324,7 +324,7 @@
   virtual int      regnum_to_fpu_offset(int regnum);
 
   // Is this branch offset small enough to be addressed by a short branch?
-  bool is_short_branch_offset(int offset);
+  bool is_short_branch_offset(int rule, int offset);
 
   // Optional scaling for the parameter to the ClearArray/CopyArray node.
   static const bool init_array_count_is_in_bytes;
--- a/hotspot/src/share/vm/opto/memnode.cpp	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/vm/opto/memnode.cpp	Wed Jul 05 16:43:41 2017 +0200
@@ -227,6 +227,14 @@
   const Type *t_adr = phase->type( address );
   if( t_adr == Type::TOP )              return NodeSentinel; // caller will return NULL
 
+  PhaseIterGVN *igvn = phase->is_IterGVN();
+  if( can_reshape && igvn != NULL && igvn->_worklist.member(address) ) {
+    // The address's base and type may change when the address is processed.
+    // Delay this mem node transformation until the address is processed.
+    phase->is_IterGVN()->_worklist.push(this);
+    return NodeSentinel; // caller will return NULL
+  }
+
   // Avoid independent memory operations
   Node* old_mem = mem;
 
--- a/hotspot/src/share/vm/opto/memnode.hpp	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/vm/opto/memnode.hpp	Wed Jul 05 16:43:41 2017 +0200
@@ -632,6 +632,17 @@
   virtual uint ideal_reg() const { return Op_RegFlags; }
 };
 
+//------------------------------StoreIConditionalNode---------------------------
+// Conditionally store int to memory, if no change since prior
+// load-locked.  Sets flags for success or failure of the store.
+class StoreIConditionalNode : public LoadStoreNode {
+public:
+  StoreIConditionalNode( Node *c, Node *mem, Node *adr, Node *val, Node *ii ) : LoadStoreNode(c, mem, adr, val, ii) { }
+  virtual int Opcode() const;
+  // Produces flags
+  virtual uint ideal_reg() const { return Op_RegFlags; }
+};
+
 //------------------------------StoreLConditionalNode---------------------------
 // Conditionally store long to memory, if no change since prior
 // load-locked.  Sets flags for success or failure of the store.
@@ -639,6 +650,8 @@
 public:
   StoreLConditionalNode( Node *c, Node *mem, Node *adr, Node *val, Node *ll ) : LoadStoreNode(c, mem, adr, val, ll) { }
   virtual int Opcode() const;
+  // Produces flags
+  virtual uint ideal_reg() const { return Op_RegFlags; }
 };
 
 
--- a/hotspot/src/share/vm/opto/output.cpp	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/vm/opto/output.cpp	Wed Jul 05 16:43:41 2017 +0200
@@ -263,7 +263,7 @@
 # endif // ENABLE_ZAP_DEAD_LOCALS
 
 //------------------------------compute_loop_first_inst_sizes------------------
-// Compute the size of first NumberOfLoopInstrToAlign instructions at head
+// Compute the size of first NumberOfLoopInstrToAlign instructions at the top
 // of a loop. When aligning a loop we need to provide enough instructions
 // in cpu's fetch buffer to feed decoders. The loop alignment could be
 // avoided if we have enough instructions in fetch buffer at the head of a loop.
@@ -284,34 +284,23 @@
     for( uint i=1; i <= last_block; i++ ) {
       Block *b = _cfg->_blocks[i];
       // Check the first loop's block which requires an alignment.
-      if( b->head()->is_Loop() &&
-          b->code_alignment() > (uint)relocInfo::addr_unit() ) {
+      if( b->loop_alignment() > (uint)relocInfo::addr_unit() ) {
         uint sum_size = 0;
         uint inst_cnt = NumberOfLoopInstrToAlign;
-        inst_cnt = b->compute_first_inst_size(sum_size, inst_cnt,
-                                              _regalloc);
-        // Check the next fallthrough block if first loop's block does not have
-        // enough instructions.
-        if( inst_cnt > 0 && i < last_block ) {
-          // First, check if the first loop's block contains whole loop.
-          // LoopNode::LoopBackControl == 2.
-          Block *bx = _cfg->_bbs[b->pred(2)->_idx];
-          // Skip connector blocks (with limit in case of irreducible loops).
-          int search_limit = 16;
-          while( bx->is_connector() && search_limit-- > 0) {
-            bx = _cfg->_bbs[bx->pred(1)->_idx];
-          }
-          if( bx != b ) { // loop body is in several blocks.
-            Block *nb = NULL;
-            while( inst_cnt > 0 && i < last_block && nb != bx &&
-                  !_cfg->_blocks[i+1]->head()->is_Loop() ) {
-              i++;
-              nb = _cfg->_blocks[i];
-              inst_cnt  = nb->compute_first_inst_size(sum_size, inst_cnt,
-                                                      _regalloc);
-            } // while( inst_cnt > 0 && i < last_block  )
-          } // if( bx != b )
-        } // if( inst_cnt > 0 && i < last_block )
+        inst_cnt = b->compute_first_inst_size(sum_size, inst_cnt, _regalloc);
+
+        // Check subsequent fallthrough blocks if the loop's first
+        // block(s) does not have enough instructions.
+        Block *nb = b;
+        while( inst_cnt > 0 &&
+               i < last_block &&
+               !_cfg->_blocks[i+1]->has_loop_alignment() &&
+               !nb->has_successor(b) ) {
+          i++;
+          nb = _cfg->_blocks[i];
+          inst_cnt  = nb->compute_first_inst_size(sum_size, inst_cnt, _regalloc);
+        } // while( inst_cnt > 0 && i < last_block  )
+
         b->set_first_inst_size(sum_size);
       } // f( b->head()->is_Loop() )
     } // for( i <= last_block )
@@ -332,6 +321,7 @@
   uint *jmp_end    = NEW_RESOURCE_ARRAY(uint,_cfg->_num_blocks);
   uint *blk_starts = NEW_RESOURCE_ARRAY(uint,_cfg->_num_blocks+1);
   DEBUG_ONLY( uint *jmp_target = NEW_RESOURCE_ARRAY(uint,_cfg->_num_blocks); )
+  DEBUG_ONLY( uint *jmp_rule = NEW_RESOURCE_ARRAY(uint,_cfg->_num_blocks); )
   blk_starts[0]    = 0;
 
   // Initialize the sizes to 0
@@ -443,9 +433,9 @@
         uintptr_t target = blk_starts[bnum];
         if( mach->is_pc_relative() ) {
           int offset = target-(blk_starts[i] + jmp_end[i]);
-          if (_matcher->is_short_branch_offset(offset)) {
+          if (_matcher->is_short_branch_offset(mach->rule(), offset)) {
             // We've got a winner.  Replace this branch.
-            MachNode *replacement = mach->short_branch_version(this);
+            MachNode* replacement = mach->short_branch_version(this);
             b->_nodes.map(j, replacement);
             mach->subsume_by(replacement);
 
@@ -453,6 +443,7 @@
             // next pass.
             jmp_end[i] -= (mach->size(_regalloc) - replacement->size(_regalloc));
             DEBUG_ONLY( jmp_target[i] = bnum; );
+            DEBUG_ONLY( jmp_rule[i] = mach->rule(); );
           }
         } else {
 #ifndef PRODUCT
@@ -510,7 +501,7 @@
       // Get the size of the block
       uint blk_size = adr - blk_starts[i];
 
-      // When the next block starts a loop, we may insert pad NOP
+      // When the next block is the top of a loop, we may insert pad NOP
       // instructions.
       Block *nb = _cfg->_blocks[i+1];
       int current_offset = blk_starts[i] + blk_size;
@@ -524,10 +515,10 @@
   for( i=0; i<_cfg->_num_blocks; i++ ) { // For all blocks
     if( jmp_target[i] != 0 ) {
       int offset = blk_starts[jmp_target[i]]-(blk_starts[i] + jmp_end[i]);
-      if (!_matcher->is_short_branch_offset(offset)) {
+      if (!_matcher->is_short_branch_offset(jmp_rule[i], offset)) {
         tty->print_cr("target (%d) - jmp_end(%d) = offset (%d), jmp_block B%d, target_block B%d", blk_starts[jmp_target[i]], blk_starts[i] + jmp_end[i], offset, i, jmp_target[i]);
       }
-      assert(_matcher->is_short_branch_offset(offset), "Displacement too large for short jmp");
+      assert(_matcher->is_short_branch_offset(jmp_rule[i], offset), "Displacement too large for short jmp");
     }
   }
 #endif
@@ -1069,7 +1060,7 @@
 
   // If this machine supports different size branch offsets, then pre-compute
   // the length of the blocks
-  if( _matcher->is_short_branch_offset(0) ) {
+  if( _matcher->is_short_branch_offset(-1, 0) ) {
     Shorten_branches(blk_labels, code_req, locs_req, stub_req, const_req);
     labels_not_set = false;
   }
@@ -1380,8 +1371,8 @@
 
     } // End for all instructions in block
 
-    // If the next block _starts_ a loop, pad this block out to align
-    // the loop start a little. Helps prevent pipe stalls at loop starts
+    // If the next block is the top of a loop, pad this block out to align
+    // the loop top a little. Helps prevent pipe stalls at loop back branches.
     int nop_size = (new (this) MachNopNode())->size(_regalloc);
     if( i<_cfg->_num_blocks-1 ) {
       Block *nb = _cfg->_blocks[i+1];
--- a/hotspot/src/share/vm/opto/phase.cpp	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/vm/opto/phase.cpp	Wed Jul 05 16:43:41 2017 +0200
@@ -46,7 +46,7 @@
 #ifndef PRODUCT
 elapsedTimer Phase::_t_graphReshaping;
 elapsedTimer Phase::_t_scheduler;
-elapsedTimer Phase::_t_removeEmptyBlocks;
+elapsedTimer Phase::_t_blockOrdering;
 elapsedTimer Phase::_t_macroExpand;
 elapsedTimer Phase::_t_peephole;
 elapsedTimer Phase::_t_codeGeneration;
@@ -128,7 +128,7 @@
     tty->print_cr ("      subtotal     : %3.3f sec,  %3.2f %%", regalloc_subtotal, percent_of_regalloc);
   }
   tty->print_cr ("    macroExpand  : %3.3f sec", Phase::_t_macroExpand.seconds());
-  tty->print_cr ("    removeEmpty  : %3.3f sec", Phase::_t_removeEmptyBlocks.seconds());
+  tty->print_cr ("    blockOrdering: %3.3f sec", Phase::_t_blockOrdering.seconds());
   tty->print_cr ("    peephole     : %3.3f sec", Phase::_t_peephole.seconds());
   tty->print_cr ("    codeGen      : %3.3f sec", Phase::_t_codeGeneration.seconds());
   tty->print_cr ("    install_code : %3.3f sec", Phase::_t_registerMethod.seconds());
@@ -137,7 +137,7 @@
     (DoEscapeAnalysis ? Phase::_t_escapeAnalysis.seconds() : 0.0) +
     Phase::_t_optimizer.seconds() + Phase::_t_graphReshaping.seconds() +
     Phase::_t_matcher.seconds() + Phase::_t_scheduler.seconds() +
-    Phase::_t_registerAllocation.seconds() + Phase::_t_removeEmptyBlocks.seconds() +
+    Phase::_t_registerAllocation.seconds() + Phase::_t_blockOrdering.seconds() +
     Phase::_t_macroExpand.seconds() + Phase::_t_peephole.seconds() +
     Phase::_t_codeGeneration.seconds() + Phase::_t_registerMethod.seconds();
   double percent_of_method_compile = ((phase_subtotal == 0.0) ? 0.0 : phase_subtotal / Phase::_t_methodCompilation.seconds()) * 100.0;
--- a/hotspot/src/share/vm/opto/phase.hpp	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/vm/opto/phase.hpp	Wed Jul 05 16:43:41 2017 +0200
@@ -40,16 +40,12 @@
     Optimistic,                 // Optimistic analysis phase
     GVN,                        // Pessimistic global value numbering phase
     Ins_Select,                 // Instruction selection phase
-    Copy_Elimination,           // Copy Elimination
-    Dead_Code_Elimination,      // DCE and compress Nodes
-    Conditional_Constant,       // Conditional Constant Propagation
     CFG,                        // Build a CFG
-    DefUse,                     // Build Def->Use chains
+    BlockLayout,                // Linear ordering of blocks
     Register_Allocation,        // Register allocation, duh
     LIVE,                       // Dragon-book LIVE range problem
     Interference_Graph,         // Building the IFG
     Coalesce,                   // Coalescing copies
-    Conditional_CProp,          // Conditional Constant Propagation
     Ideal_Loop,                 // Find idealized trip-counted loops
     Macro_Expand,               // Expand macro nodes
     Peephole,                   // Apply peephole optimizations
@@ -80,7 +76,7 @@
 #ifndef PRODUCT
   static elapsedTimer _t_graphReshaping;
   static elapsedTimer _t_scheduler;
-  static elapsedTimer _t_removeEmptyBlocks;
+  static elapsedTimer _t_blockOrdering;
   static elapsedTimer _t_macroExpand;
   static elapsedTimer _t_peephole;
   static elapsedTimer _t_codeGeneration;
--- a/hotspot/src/share/vm/opto/reg_split.cpp	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/vm/opto/reg_split.cpp	Wed Jul 05 16:43:41 2017 +0200
@@ -53,6 +53,7 @@
   // Bail rather than abort
   int ireg = def->ideal_reg();
   if( ireg == 0 || ireg == Op_RegFlags ) {
+    assert(false, "attempted to spill a non-spillable item");
     C->record_method_not_compilable("attempted to spill a non-spillable item");
     return NULL;
   }
--- a/hotspot/src/share/vm/opto/type.cpp	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/vm/opto/type.cpp	Wed Jul 05 16:43:41 2017 +0200
@@ -3541,7 +3541,7 @@
 
 #ifndef PRODUCT
 void TypeNarrowOop::dump2( Dict & d, uint depth, outputStream *st ) const {
-  tty->print("narrowoop: ");
+  st->print("narrowoop: ");
   _ooptype->dump2(d, depth, st);
 }
 #endif
--- a/hotspot/src/share/vm/opto/type.hpp	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/vm/opto/type.hpp	Wed Jul 05 16:43:41 2017 +0200
@@ -1183,6 +1183,9 @@
 #define RShiftXNode  RShiftLNode
 // For card marks and hashcodes
 #define URShiftXNode URShiftLNode
+// UseOptoBiasInlining
+#define XorXNode     XorLNode
+#define StoreXConditionalNode StoreLConditionalNode
 // Opcodes
 #define Op_LShiftX   Op_LShiftL
 #define Op_AndX      Op_AndL
@@ -1222,6 +1225,9 @@
 #define RShiftXNode  RShiftINode
 // For card marks and hashcodes
 #define URShiftXNode URShiftINode
+// UseOptoBiasInlining
+#define XorXNode     XorINode
+#define StoreXConditionalNode StoreIConditionalNode
 // Opcodes
 #define Op_LShiftX   Op_LShiftI
 #define Op_AndX      Op_AndI
--- a/hotspot/src/share/vm/runtime/arguments.cpp	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/vm/runtime/arguments.cpp	Wed Jul 05 16:43:41 2017 +0200
@@ -1365,6 +1365,9 @@
   if (AggressiveOpts && FLAG_IS_DEFAULT(SpecialArraysEquals)) {
     FLAG_SET_DEFAULT(SpecialArraysEquals, true);
   }
+  if (AggressiveOpts && FLAG_IS_DEFAULT(BiasedLockingStartupDelay)) {
+    FLAG_SET_DEFAULT(BiasedLockingStartupDelay, 500);
+  }
 #endif
 
   if (AggressiveOpts) {
@@ -2625,6 +2628,12 @@
   FLAG_SET_DEFAULT(UseBiasedLocking, false);
 #endif /* CC_INTERP */
 
+#ifdef COMPILER2
+  if (!UseBiasedLocking || EmitSync != 0) {
+    UseOptoBiasInlining = false;
+  }
+#endif
+
   if (PrintCommandLineFlags) {
     CommandLineFlags::printSetFlags();
   }
--- a/hotspot/src/share/vm/runtime/frame.cpp	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/vm/runtime/frame.cpp	Wed Jul 05 16:43:41 2017 +0200
@@ -83,12 +83,12 @@
     intptr_t* src = (intptr_t*) location(r);
     if (src != NULL) {
 
-      r->print();
-      tty->print(" [" INTPTR_FORMAT "] = ", src);
+      r->print_on(st);
+      st->print(" [" INTPTR_FORMAT "] = ", src);
       if (((uintptr_t)src & (sizeof(*src)-1)) != 0) {
-        tty->print_cr("<misaligned>");
+        st->print_cr("<misaligned>");
       } else {
-        tty->print_cr(INTPTR_FORMAT, *src);
+        st->print_cr(INTPTR_FORMAT, *src);
       }
     }
   }
--- a/hotspot/src/share/vm/utilities/vmError.cpp	Fri Nov 07 11:45:49 2008 -0800
+++ b/hotspot/src/share/vm/utilities/vmError.cpp	Wed Jul 05 16:43:41 2017 +0200
@@ -263,7 +263,7 @@
          st->print("# java.lang.OutOfMemoryError: ");
          if (_size) {
            st->print("requested ");
-           sprintf(buf,"%d",_size);
+           sprintf(buf,SIZE_FORMAT,_size);
            st->print(buf);
            st->print(" bytes");
            if (_message != NULL) {
--- a/jaxp/.hgtags	Fri Nov 07 11:45:49 2008 -0800
+++ b/jaxp/.hgtags	Wed Jul 05 16:43:41 2017 +0200
@@ -13,3 +13,4 @@
 c84ca638db42a8b6b227b4e3b63bca192c5ca634 jdk7-b36
 af49591bc486d82aa04b832257de0d18adc9af52 jdk7-b37
 e9f750f0a3a00413a7b77028b2ecdabb7129ae32 jdk7-b38
+831b80be6cea8e7d7da197ccdac5fd4c701a5033 jdk7-b39
--- a/jaxws/.hgtags	Fri Nov 07 11:45:49 2008 -0800
+++ b/jaxws/.hgtags	Wed Jul 05 16:43:41 2017 +0200
@@ -13,3 +13,4 @@
 f60187f44a0d62906a5e2f6bd0989b5b24c1ca1e jdk7-b36
 a2a6f9edf761934faf59ea60d7fe7178371302cd jdk7-b37
 9ce439969184c753a9ba3caf8ed277b05230f2e5 jdk7-b38
+077bc9b1b035a409a76bd5366f73ed9dd9846934 jdk7-b39
--- a/jdk/.hgtags	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/.hgtags	Wed Jul 05 16:43:41 2017 +0200
@@ -13,3 +13,4 @@
 134fd1a656ea85acd1f97f6700f75029b9b472a0 jdk7-b36
 14f50aee4989b75934d385c56a83da0c23d2f68b jdk7-b37
 cc5f810b5af8a3a83b0df5a29d9e24d7a0ff8086 jdk7-b38
+4e51997582effa006dde5c6d8b8820b2045b9c7f jdk7-b39
--- a/jdk/make/netbeans/jmx/build.xml	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/make/netbeans/jmx/build.xml	Wed Jul 05 16:43:41 2017 +0200
@@ -44,13 +44,13 @@
         <!-- because they depend on the values of BUILD_DATE and BUILD_DATE_SIMPLE  -->
         <!-- At this time, ./build.properties has not been loaded yet. -->
         <property name="project.build.name" value="openjdk-bXX"/>
-	<property name="project.build.fulltag" 
+	<property name="project.build.fulltag"
                   value="${ant.project.name}-${project.build.name}-${BUILD_DATE}" />
 
         <!-- unchecked warnings will be fixed in JMX 2.0 as part of the work
              being done on JSR 255 new features                              -->
-        <property name="javac.options" 
-                  value="-Xlint -Xlint:-unchecked -Xlint:-deprecation"/>
+        <property name="javac.options"
+                  value="-Xlint -Xlint:-deprecation"/>
     </target>
 
 
@@ -58,13 +58,13 @@
 	<!-- Dir to keep generated stub source -->
         <mkdir dir="${gensrc.dir}" />
     </target>
-    
+
 
     <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~ -->
     <!-- Call rmic-jmx subtargets -->
 
     <target name="-rmic-jmx" depends="-init,-rmic-jmx-jrmp,-rmic-jmx-iiop"
-	    description="Calls -init,-rmic-jmx-jrmp,-rmic-jmx-iiop" 
+	    description="Calls -init,-rmic-jmx-jrmp,-rmic-jmx-iiop"
     />
 
 
@@ -96,7 +96,7 @@
 
     <target name="-rmic-jmx-iiop" depends="-init,-check-jmx-iiop-uptodate" unless="jmx-iiop-uptodate"
             description="Generate RMI IIOP stub class files for remote objects. Do not keep generated java files." >
- 
+
 	<rmic 	base="${classes.dir}"
 		includeAntRuntime="no"
 		includeJavaRuntime="no"
@@ -115,11 +115,11 @@
 
     <target name="-check-jmx-iiop-uptodate" depends="-init">
 
-	<uptodate property="jmx-iiop-uptodate" 
+	<uptodate property="jmx-iiop-uptodate"
 		   srcfile="${classes.dir}/javax/management/remote/rmi/RMIConnectionImpl.class"
 		targetfile="${classes.dir}/org/omg/stub/javax/management/remote/rmi/_RMIConnectionImpl_Tie.class"
 	/>
-	<uptodate property="jmx-iiop-uptodate" 
+	<uptodate property="jmx-iiop-uptodate"
 		   srcfile="${classes.dir}/javax/management/remote/rmi/RMIServerImpl.class"
 		targetfile="${classes.dir}/org/omg/stub/javax/management/remote/rmi/_RMIServerImpl_Tie.class"
 	/>
@@ -131,7 +131,7 @@
     <target name="-post-compile" depends="-init,-rmic-jmx"
             description="Jar JMX class files (including RMI stubs)" >
        <mkdir dir="${dist.dir}/lib"/>
-       <jar jarfile="${dist.dir}/lib/${jar.jmx.name}" 
+       <jar jarfile="${dist.dir}/lib/${jar.jmx.name}"
 	    update="true"
 	    index="false"
 	    duplicate="fail">
@@ -144,7 +144,7 @@
 		    <attribute name="Specification-Version"  value="${jar.jmx.spec.version}" />
 		    <attribute name="Specification-Vendor"   value="${jar.jmx.spec.vendor}" />
 		    <attribute name="Implementation-Title"   value="${jar.jmx.impl.title}" />
-		    <attribute name="Implementation-Version" value="${project.build.fulltag}" /> 
+		    <attribute name="Implementation-Version" value="${project.build.fulltag}" />
 		    <attribute name="Implementation-Vendor"  value="${jar.jmx.impl.vendor}" />
 		</section>
 	    </manifest>
--- a/jdk/src/share/classes/com/sun/jmx/event/LeaseManager.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/com/sun/jmx/event/LeaseManager.java	Wed Jul 05 16:43:41 2017 +0200
@@ -141,7 +141,7 @@
     }
 
     private final Runnable callback;
-    private ScheduledFuture scheduled;  // If null, the lease has expired.
+    private ScheduledFuture<?> scheduled;  // If null, the lease has expired.
 
     private final ScheduledExecutorService executor
             = Executors.newScheduledThreadPool(1,
--- a/jdk/src/share/classes/com/sun/jmx/event/LeaseRenewer.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/com/sun/jmx/event/LeaseRenewer.java	Wed Jul 05 16:43:41 2017 +0200
@@ -128,7 +128,7 @@
     };
 
     private final Callable<Long> doRenew;
-    private ScheduledFuture future;
+    private ScheduledFuture<?> future;
     private boolean closed = false;
     private long nextRenewTime;
 
--- a/jdk/src/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java	Wed Jul 05 16:43:41 2017 +0200
@@ -247,7 +247,7 @@
                MBeanRegistrationException, MBeanException,
                NotCompliantMBeanException, InstanceNotFoundException {
 
-        Class theClass;
+        Class<?> theClass;
 
         if (className == null) {
             final RuntimeException wrapped =
@@ -327,7 +327,7 @@
 
         // ------------------------------
         // ------------------------------
-        Class theClass = object.getClass();
+        Class<?> theClass = object.getClass();
 
         Introspector.checkCompliance(theClass);
 
@@ -808,9 +808,8 @@
             // on each specific attribute
             //
             allowedAttributes = new AttributeList(attributes.size());
-            for (Iterator i = attributes.iterator(); i.hasNext();) {
+            for (Attribute attribute : attributes.asList()) {
                 try {
-                    Attribute attribute = (Attribute) i.next();
                     checkMBeanPermission(mbeanServerName, classname, attribute.getName(),
                                          name, "setAttribute");
                     allowedAttributes.add(attribute);
@@ -1857,7 +1856,7 @@
         }
     }
 
-    private static void checkMBeanTrustPermission(final Class theClass)
+    private static void checkMBeanTrustPermission(final Class<?> theClass)
         throws SecurityException {
         SecurityManager sm = System.getSecurityManager();
         if (sm != null) {
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/ClassLoaderRepositorySupport.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/ClassLoaderRepositorySupport.java	Wed Jul 05 16:43:41 2017 +0200
@@ -136,14 +136,14 @@
         new Hashtable<ObjectName,ClassLoader>(10);
 
     // from javax.management.loading.DefaultLoaderRepository
-    public final Class loadClass(String className)
+    public final Class<?> loadClass(String className)
         throws ClassNotFoundException {
         return  loadClass(loaders, className, null, null);
     }
 
 
     // from javax.management.loading.DefaultLoaderRepository
-    public final Class loadClassWithout(ClassLoader without, String className)
+    public final Class<?> loadClassWithout(ClassLoader without, String className)
             throws ClassNotFoundException {
         if (MBEANSERVER_LOGGER.isLoggable(Level.FINER)) {
             MBEANSERVER_LOGGER.logp(Level.FINER,
@@ -167,7 +167,7 @@
     }
 
 
-    public final Class loadClassBefore(ClassLoader stop, String className)
+    public final Class<?> loadClassBefore(ClassLoader stop, String className)
             throws ClassNotFoundException {
         if (MBEANSERVER_LOGGER.isLoggable(Level.FINER)) {
             MBEANSERVER_LOGGER.logp(Level.FINER,
@@ -187,10 +187,10 @@
     }
 
 
-    private Class loadClass(final LoaderEntry list[],
-                            final String className,
-                            final ClassLoader without,
-                            final ClassLoader stop)
+    private Class<?> loadClass(final LoaderEntry list[],
+                               final String className,
+                               final ClassLoader without,
+                               final ClassLoader stop)
             throws ClassNotFoundException {
         final int size = list.length;
         for(int i=0; i<size; i++) {
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/ConvertingMethod.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/ConvertingMethod.java	Wed Jul 05 16:43:41 2017 +0200
@@ -68,12 +68,12 @@
         return method.getName();
     }
 
-    OpenType getOpenReturnType() {
+    OpenType<?> getOpenReturnType() {
         return returnMapping.getOpenType();
     }
 
-    OpenType[] getOpenParameterTypes() {
-        final OpenType[] types = new OpenType[paramMappings.length];
+    OpenType<?>[] getOpenParameterTypes() {
+        final OpenType<?>[] types = new OpenType<?>[paramMappings.length];
         for (int i = 0; i < paramMappings.length; i++)
             types[i] = paramMappings[i].getOpenType();
         return types;
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/DefaultMXBeanMappingFactory.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/DefaultMXBeanMappingFactory.java	Wed Jul 05 16:43:41 2017 +0200
@@ -26,7 +26,8 @@
 package com.sun.jmx.mbeanserver;
 
 import static com.sun.jmx.mbeanserver.Util.*;
-import java.lang.annotation.ElementType;
+import static com.sun.jmx.mbeanserver.MXBeanIntrospector.typeName;
+
 import javax.management.openmbean.MXBeanMappingClass;
 
 import static javax.management.openmbean.SimpleType.*;
@@ -120,7 +121,7 @@
  */
 public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
     static abstract class NonNullMXBeanMapping extends MXBeanMapping {
-        NonNullMXBeanMapping(Type javaType, OpenType openType) {
+        NonNullMXBeanMapping(Type javaType, OpenType<?> openType) {
             super(javaType, openType);
         }
 
@@ -195,15 +196,15 @@
     static {
         /* Set up the mappings for Java types that map to SimpleType.  */
 
-        final OpenType[] simpleTypes = {
+        final OpenType<?>[] simpleTypes = {
             BIGDECIMAL, BIGINTEGER, BOOLEAN, BYTE, CHARACTER, DATE,
             DOUBLE, FLOAT, INTEGER, LONG, OBJECTNAME, SHORT, STRING,
             VOID,
         };
 
         for (int i = 0; i < simpleTypes.length; i++) {
-            final OpenType t = simpleTypes[i];
-            Class c;
+            final OpenType<?> t = simpleTypes[i];
+            Class<?> c;
             try {
                 c = Class.forName(t.getClassName(), false,
                                   ObjectName.class.getClassLoader());
@@ -224,7 +225,7 @@
                     if (primitiveType != void.class) {
                         final Class<?> primitiveArrayType =
                             Array.newInstance(primitiveType, 0).getClass();
-                        final OpenType primitiveArrayOpenType =
+                        final OpenType<?> primitiveArrayOpenType =
                             ArrayType.getPrimitiveArrayType(primitiveArrayType);
                         final MXBeanMapping primitiveArrayMapping =
                             new IdentityMapping(primitiveArrayType,
@@ -247,8 +248,10 @@
     public synchronized MXBeanMapping mappingForType(Type objType,
                                                      MXBeanMappingFactory factory)
             throws OpenDataException {
-        if (inProgress.containsKey(objType))
-            throw new OpenDataException("Recursive data structure");
+        if (inProgress.containsKey(objType)) {
+            throw new OpenDataException(
+                    "Recursive data structure, including " + typeName(objType));
+        }
 
         MXBeanMapping mapping;
 
@@ -259,6 +262,8 @@
         inProgress.put(objType, objType);
         try {
             mapping = makeMapping(objType, factory);
+        } catch (OpenDataException e) {
+            throw openDataException("Cannot convert type: " + typeName(objType), e);
         } finally {
             inProgress.remove(objType);
         }
@@ -285,13 +290,13 @@
             Type componentType =
                 ((GenericArrayType) objType).getGenericComponentType();
             return makeArrayOrCollectionMapping(objType, componentType, factory);
-        } else if (objType instanceof Class) {
+        } else if (objType instanceof Class<?>) {
             Class<?> objClass = (Class<?>) objType;
             if (objClass.isEnum()) {
                 // Huge hack to avoid compiler warnings here.  The ElementType
                 // parameter is ignored but allows us to obtain a type variable
                 // T that matches <T extends Enum<T>>.
-                return makeEnumMapping((Class) objClass, ElementType.class);
+                return makeEnumMapping((Class<?>) objClass, ElementType.class);
             } else if (objClass.isArray()) {
                 Type componentType = objClass.getComponentType();
                 return makeArrayOrCollectionMapping(objClass, componentType,
@@ -354,7 +359,7 @@
     }
 
     private static <T extends Enum<T>> MXBeanMapping
-            makeEnumMapping(Class enumClass, Class<T> fake) {
+            makeEnumMapping(Class<?> enumClass, Class<T> fake) {
         return new EnumMapping<T>(Util.<Class<T>>cast(enumClass));
     }
 
@@ -411,17 +416,17 @@
                            MXBeanMappingFactory factory)
             throws OpenDataException {
 
-        final String objTypeName = objType.toString();
+        final String objTypeName = typeName(objType);
         final MXBeanMapping keyMapping = factory.mappingForType(keyType, factory);
         final MXBeanMapping valueMapping = factory.mappingForType(valueType, factory);
-        final OpenType keyOpenType = keyMapping.getOpenType();
-        final OpenType valueOpenType = valueMapping.getOpenType();
+        final OpenType<?> keyOpenType = keyMapping.getOpenType();
+        final OpenType<?> valueOpenType = valueMapping.getOpenType();
         final CompositeType rowType =
             new CompositeType(objTypeName,
                               objTypeName,
                               keyValueArray,
                               keyValueArray,
-                              new OpenType[] {keyOpenType, valueOpenType});
+                              new OpenType<?>[] {keyOpenType, valueOpenType});
         final TabularType tabularType =
             new TabularType(objTypeName, objTypeName, rowType, keyArray);
         return new TabularMapping(objType, sortedMap, tabularType,
@@ -440,8 +445,8 @@
 
         final Type rawType = objType.getRawType();
 
-        if (rawType instanceof Class) {
-            Class c = (Class<?>) rawType;
+        if (rawType instanceof Class<?>) {
+            Class<?> c = (Class<?>) rawType;
             if (c == List.class || c == Set.class || c == SortedSet.class) {
                 Type[] actuals = objType.getActualTypeArguments();
                 assert(actuals.length == 1);
@@ -468,7 +473,7 @@
         return new MXBeanRefMapping(t);
     }
 
-    private MXBeanMapping makeCompositeMapping(Class c,
+    private MXBeanMapping makeCompositeMapping(Class<?> c,
                                                MXBeanMappingFactory factory)
             throws OpenDataException {
 
@@ -514,7 +519,7 @@
 
         final Method[] getters = new Method[nitems];
         final String[] itemNames = new String[nitems];
-        final OpenType[] openTypes = new OpenType[nitems];
+        final OpenType<?>[] openTypes = new OpenType<?>[nitems];
         int i = 0;
         for (Map.Entry<String,Method> entry : getterMap.entrySet()) {
             itemNames[i] = entry.getKey();
@@ -546,7 +551,7 @@
        can be directly represented by an ArrayType, and an int needs no mapping
        because reflection takes care of it.  */
     private static final class IdentityMapping extends NonNullMXBeanMapping {
-        IdentityMapping(Type targetType, OpenType openType) {
+        IdentityMapping(Type targetType, OpenType<?> openType) {
             super(targetType, openType);
         }
 
@@ -576,7 +581,7 @@
 
         @Override
         final Object toNonNullOpenValue(Object value) {
-            return ((Enum) value).name();
+            return ((Enum<?>) value).name();
         }
 
         @Override
@@ -595,7 +600,7 @@
 
     private static final class ArrayMapping extends NonNullMXBeanMapping {
         ArrayMapping(Type targetType,
-                     ArrayType openArrayType, Class openArrayClass,
+                     ArrayType<?> openArrayType, Class<?> openArrayClass,
                      MXBeanMapping elementMapping) {
             super(targetType, openArrayType);
             this.elementMapping = elementMapping;
@@ -623,7 +628,7 @@
             if (javaType instanceof GenericArrayType) {
                 componentType =
                     ((GenericArrayType) javaType).getGenericComponentType();
-            } else if (javaType instanceof Class &&
+            } else if (javaType instanceof Class<?> &&
                        ((Class<?>) javaType).isArray()) {
                 componentType = ((Class<?>) javaType).getComponentType();
             } else {
@@ -651,8 +656,8 @@
 
     private static final class CollectionMapping extends NonNullMXBeanMapping {
         CollectionMapping(Type targetType,
-                          ArrayType openArrayType,
-                          Class openArrayClass,
+                          ArrayType<?> openArrayType,
+                          Class<?> openArrayClass,
                           MXBeanMapping elementMapping) {
             super(targetType, openArrayType);
             this.elementMapping = elementMapping;
@@ -662,26 +667,28 @@
                and all Sets to TreeSet.  (TreeSet because it is a SortedSet,
                so works for both Set and SortedSet.)  */
             Type raw = ((ParameterizedType) targetType).getRawType();
-            Class c = (Class<?>) raw;
+            Class<?> c = (Class<?>) raw;
+            final Class<?> collC;
             if (c == List.class)
-                collectionClass = ArrayList.class;
+                collC = ArrayList.class;
             else if (c == Set.class)
-                collectionClass = HashSet.class;
+                collC = HashSet.class;
             else if (c == SortedSet.class)
-                collectionClass = TreeSet.class;
+                collC = TreeSet.class;
             else { // can't happen
                 assert(false);
-                collectionClass = null;
+                collC = null;
             }
+            collectionClass = Util.cast(collC);
         }
 
         @Override
         final Object toNonNullOpenValue(Object value)
                 throws OpenDataException {
-            final Collection valueCollection = (Collection) value;
-            if (valueCollection instanceof SortedSet) {
-                Comparator comparator =
-                    ((SortedSet) valueCollection).comparator();
+            final Collection<?> valueCollection = (Collection<?>) value;
+            if (valueCollection instanceof SortedSet<?>) {
+                Comparator<?> comparator =
+                    ((SortedSet<?>) valueCollection).comparator();
                 if (comparator != null) {
                     final String msg =
                         "Cannot convert SortedSet with non-null comparator: " +
@@ -725,7 +732,7 @@
             elementMapping.checkReconstructible();
         }
 
-        private final Class<? extends Collection> collectionClass;
+        private final Class<? extends Collection<?>> collectionClass;
         private final MXBeanMapping elementMapping;
     }
 
@@ -794,8 +801,8 @@
         @Override
         final Object toNonNullOpenValue(Object value) throws OpenDataException {
             final Map<Object, Object> valueMap = cast(value);
-            if (valueMap instanceof SortedMap) {
-                Comparator comparator = ((SortedMap) valueMap).comparator();
+            if (valueMap instanceof SortedMap<?,?>) {
+                Comparator<?> comparator = ((SortedMap<?,?>) valueMap).comparator();
                 if (comparator != null) {
                     final String msg =
                         "Cannot convert SortedMap with non-null comparator: " +
@@ -806,7 +813,7 @@
             final TabularType tabularType = (TabularType) getOpenType();
             final TabularData table = new TabularDataSupport(tabularType);
             final CompositeType rowType = tabularType.getRowType();
-            for (Map.Entry entry : valueMap.entrySet()) {
+            for (Map.Entry<Object, Object> entry : valueMap.entrySet()) {
                 final Object openKey = keyMapping.toOpenValue(entry.getKey());
                 final Object openValue = valueMapping.toOpenValue(entry.getValue());
                 final CompositeData row;
@@ -852,7 +859,7 @@
     }
 
     private final class CompositeMapping extends NonNullMXBeanMapping {
-        CompositeMapping(Class targetClass,
+        CompositeMapping(Class<?> targetClass,
                          CompositeType compositeType,
                          String[] itemNames,
                          Method[] getters,
@@ -901,7 +908,7 @@
             if (compositeBuilder != null)
                 return;
 
-            Class targetClass = (Class<?>) getJavaType();
+            Class<?> targetClass = (Class<?>) getJavaType();
             /* In this 2D array, each subarray is a set of builders where
                there is no point in consulting the ones after the first if
                the first refuses.  */
@@ -924,6 +931,7 @@
                concatenating each Builder's explanation of why it
                isn't applicable.  */
             final StringBuilder whyNots = new StringBuilder();
+            Throwable possibleCause = null;
         find:
             for (CompositeBuilder[] relatedBuilders : builders) {
                 for (int i = 0; i < relatedBuilders.length; i++) {
@@ -933,6 +941,9 @@
                         foundBuilder = builder;
                         break find;
                     }
+                    Throwable cause = builder.possibleCause();
+                    if (cause != null)
+                        possibleCause = cause;
                     if (whyNot.length() > 0) {
                         if (whyNots.length() > 0)
                             whyNots.append("; ");
@@ -943,10 +954,12 @@
                 }
             }
             if (foundBuilder == null) {
-                final String msg =
+                String msg =
                     "Do not know how to make a " + targetClass.getName() +
                     " from a CompositeData: " + whyNots;
-                throw new InvalidObjectException(msg);
+                if (possibleCause != null)
+                    msg += ". Remaining exceptions show a POSSIBLE cause.";
+                throw invalidObjectException(msg, possibleCause);
             }
             compositeBuilder = foundBuilder;
         }
@@ -973,7 +986,7 @@
 
     /** Converts from a CompositeData to an instance of the targetClass.  */
     private static abstract class CompositeBuilder {
-        CompositeBuilder(Class targetClass, String[] itemNames) {
+        CompositeBuilder(Class<?> targetClass, String[] itemNames) {
             this.targetClass = targetClass;
             this.itemNames = itemNames;
         }
@@ -994,6 +1007,16 @@
         abstract String applicable(Method[] getters)
                 throws InvalidObjectException;
 
+        /** If the subclass returns an explanation of why it is not applicable,
+            it can additionally indicate an exception with details.  This is
+            potentially confusing, because the real problem could be that one
+            of the other subclasses is supposed to be applicable but isn't.
+            But the advantage of less information loss probably outweighs the
+            disadvantage of possible confusion.  */
+        Throwable possibleCause() {
+            return null;
+        }
+
         abstract Object fromCompositeData(CompositeData cd,
                                           String[] itemNames,
                                           MXBeanMapping[] converters)
@@ -1008,7 +1031,7 @@
     private static final class CompositeBuilderViaFrom
             extends CompositeBuilder {
 
-        CompositeBuilderViaFrom(Class targetClass, String[] itemNames) {
+        CompositeBuilderViaFrom(Class<?> targetClass, String[] itemNames) {
             super(targetClass, itemNames);
         }
 
@@ -1018,8 +1041,7 @@
             Class<?> targetClass = getTargetClass();
             try {
                 Method fromMethod =
-                    targetClass.getMethod("from",
-                                          new Class[] {CompositeData.class});
+                    targetClass.getMethod("from", CompositeData.class);
 
                 if (!Modifier.isStatic(fromMethod.getModifiers())) {
                     final String msg =
@@ -1030,8 +1052,8 @@
                 if (fromMethod.getReturnType() != getTargetClass()) {
                     final String msg =
                         "Method from(CompositeData) returns " +
-                        fromMethod.getReturnType().getName() +
-                        " not " + targetClass.getName();
+                        typeName(fromMethod.getReturnType()) +
+                        " not " + typeName(targetClass);
                     throw new InvalidObjectException(msg);
                 }
 
@@ -1071,7 +1093,7 @@
         If all the getters are OK, then the "applicable" method will return
         an empty string and the other builders will be tried.  */
     private static class CompositeBuilderCheckGetters extends CompositeBuilder {
-        CompositeBuilderCheckGetters(Class targetClass, String[] itemNames,
+        CompositeBuilderCheckGetters(Class<?> targetClass, String[] itemNames,
                                      MXBeanMapping[] getterConverters) {
             super(targetClass, itemNames);
             this.getterConverters = getterConverters;
@@ -1082,6 +1104,7 @@
                 try {
                     getterConverters[i].checkReconstructible();
                 } catch (InvalidObjectException e) {
+                    possibleCause = e;
                     return "method " + getters[i].getName() + " returns type " +
                         "that cannot be mapped back from OpenData";
                 }
@@ -1089,6 +1112,11 @@
             return "";
         }
 
+        @Override
+        Throwable possibleCause() {
+            return possibleCause;
+        }
+
         final Object fromCompositeData(CompositeData cd,
                                        String[] itemNames,
                                        MXBeanMapping[] converters) {
@@ -1096,6 +1124,7 @@
         }
 
         private final MXBeanMapping[] getterConverters;
+        private Throwable possibleCause;
     }
 
     /** Builder for when the target class has a setter for every getter. */
@@ -1115,7 +1144,7 @@
             Method[] setters = new Method[getters.length];
             for (int i = 0; i < getters.length; i++) {
                 Method getter = getters[i];
-                Class returnType = getter.getReturnType();
+                Class<?> returnType = getter.getReturnType();
                 String name = propertyName(getter);
                 String setterName = "set" + name;
                 Method setter;
@@ -1163,7 +1192,7 @@
     private static final class CompositeBuilderViaConstructor
             extends CompositeBuilder {
 
-        CompositeBuilderViaConstructor(Class targetClass, String[] itemNames) {
+        CompositeBuilderViaConstructor(Class<?> targetClass, String[] itemNames) {
             super(targetClass, itemNames);
         }
 
@@ -1171,7 +1200,7 @@
 
             final Class<ConstructorProperties> propertyNamesClass = ConstructorProperties.class;
 
-            Class targetClass = getTargetClass();
+            Class<?> targetClass = getTargetClass();
             Constructor<?>[] constrs = targetClass.getConstructors();
 
             // Applicable if and only if there are any annotated constructors
@@ -1226,10 +1255,16 @@
                 for (int i = 0; i < propertyNames.length; i++) {
                     String propertyName = propertyNames[i];
                     if (!getterMap.containsKey(propertyName)) {
-                        final String msg =
+                        String msg =
                             "@ConstructorProperties includes name " + propertyName +
-                            " which does not correspond to a property: " +
-                            constr;
+                            " which does not correspond to a property";
+                        for (String getterName : getterMap.keySet()) {
+                            if (getterName.equalsIgnoreCase(propertyName)) {
+                                msg += " (differs only in case from property " +
+                                        getterName + ")";
+                            }
+                        }
+                        msg += ": " + constr;
                         throw new InvalidObjectException(msg);
                     }
                     int getterIndex = getterMap.get(propertyName);
@@ -1384,12 +1419,12 @@
     private static final class CompositeBuilderViaProxy
             extends CompositeBuilder {
 
-        CompositeBuilderViaProxy(Class targetClass, String[] itemNames) {
+        CompositeBuilderViaProxy(Class<?> targetClass, String[] itemNames) {
             super(targetClass, itemNames);
         }
 
         String applicable(Method[] getters) {
-            Class targetClass = getTargetClass();
+            Class<?> targetClass = getTargetClass();
             if (!targetClass.isInterface())
                 return "not an interface";
             Set<Method> methods =
@@ -1401,7 +1436,7 @@
             String bad = null;
             for (Method m : methods) {
                 String mname = m.getName();
-                Class[] mparams = m.getParameterTypes();
+                Class<?>[] mparams = m.getParameterTypes();
                 try {
                     Method om = Object.class.getMethod(mname, mparams);
                     if (!Modifier.isPublic(om.getModifiers()))
@@ -1422,10 +1457,10 @@
         final Object fromCompositeData(CompositeData cd,
                                        String[] itemNames,
                                        MXBeanMapping[] converters) {
-            final Class targetClass = getTargetClass();
+            final Class<?> targetClass = getTargetClass();
             return
                 Proxy.newProxyInstance(targetClass.getClassLoader(),
-                                       new Class[] {targetClass},
+                                       new Class<?>[] {targetClass},
                                        new CompositeDataInvocationHandler(cd));
         }
     }
@@ -1447,9 +1482,9 @@
         return openDataException(cause.getMessage(), cause);
     }
 
-    static void mustBeComparable(Class collection, Type element)
+    static void mustBeComparable(Class<?> collection, Type element)
             throws OpenDataException {
-        if (!(element instanceof Class)
+        if (!(element instanceof Class<?>)
             || !Comparable.class.isAssignableFrom((Class<?>) element)) {
             final String msg =
                 "Parameter class " + element + " of " +
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java	Wed Jul 05 16:43:41 2017 +0200
@@ -115,7 +115,7 @@
      *         Dynamic MBeans, <code>false</code> otherwise.
      *
      **/
-    public static final boolean isDynamic(final Class c) {
+    public static final boolean isDynamic(final Class<?> c) {
         // Check if the MBean implements the DynamicMBean interface
         return javax.management.DynamicMBean.class.isAssignableFrom(c);
     }
@@ -134,7 +134,7 @@
      *            MBeanServer.
      *
      **/
-    public static void testCreation(Class c)
+    public static void testCreation(Class<?> c)
         throws NotCompliantMBeanException {
         // Check if the class is a concrete class
         final int mods = c.getModifiers();
@@ -143,7 +143,7 @@
         }
 
         // Check if the MBean has a public constructor
-        final Constructor[] consList = c.getConstructors();
+        final Constructor<?>[] consList = c.getConstructors();
         if (consList.length == 0) {
             throw new NotCompliantMBeanException("MBean class must have public constructor");
         }
@@ -253,7 +253,7 @@
      * @exception NotCompliantMBeanException The specified class is not a
      *            JMX compliant MBean
      */
-    public static MBeanInfo testCompliance(Class baseClass)
+    public static MBeanInfo testCompliance(Class<?> baseClass)
         throws NotCompliantMBeanException {
 
         // ------------------------------
@@ -267,7 +267,7 @@
         return testCompliance(baseClass, null);
     }
 
-    public static void testComplianceMXBeanInterface(Class interfaceClass,
+    public static void testComplianceMXBeanInterface(Class<?> interfaceClass,
                                                      MXBeanMappingFactory factory)
             throws NotCompliantMBeanException {
         MXBeanIntrospector.getInstance(factory).getAnalyzer(interfaceClass);
@@ -596,10 +596,10 @@
                 ss[i] = (String) annotationToField(xx[i]);
             return ss;
         }
-        if (x instanceof Class)
+        if (x instanceof Class<?>)
             return ((Class<?>) x).getName();
-        if (x instanceof Enum)
-            return ((Enum) x).name();
+        if (x instanceof Enum<?>)
+            return ((Enum<?>) x).name();
         // The only other possibility is that the value is another
         // annotation, or that the language has evolved since this code
         // was written.  We don't allow for either of those currently.
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/JmxMBeanServer.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/JmxMBeanServer.java	Wed Jul 05 16:43:41 2017 +0200
@@ -33,6 +33,7 @@
 import java.security.Permission;
 import java.security.PrivilegedExceptionAction;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Set;
 import java.util.logging.Level;
 
@@ -1144,7 +1145,7 @@
         // This call requires MBeanPermission 'getClassLoaderRepository'
         final ClassLoaderRepository clr = getClassLoaderRepository();
 
-        Class theClass;
+        Class<?> theClass;
         try {
             if (clr == null) throw new ClassNotFoundException(className);
             theClass = clr.loadClass(className);
@@ -1457,23 +1458,22 @@
      */
     private AttributeList cloneAttributeList(AttributeList list) {
         if (list != null) {
+            List<Attribute> alist = list.asList();
             if (!list.getClass().equals(AttributeList.class)) {
                 // Create new attribute list
                 //
-                AttributeList newList = new AttributeList(list.size());
+                AttributeList newList = new AttributeList(alist.size());
 
                 // Iterate through list and replace non JMX attributes
                 //
-                for (Iterator i = list.iterator(); i.hasNext(); ) {
-                    Attribute attribute = (Attribute) i.next();
+                for (Attribute attribute : alist)
                     newList.add(cloneAttribute(attribute));
-                }
                 return newList;
             } else {
                 // Iterate through list and replace non JMX attributes
                 //
-                for (int i = 0; i < list.size(); i++) {
-                    Attribute attribute = (Attribute) list.get(i);
+                for (int i = 0; i < alist.size(); i++) {
+                    Attribute attribute = alist.get(i);
                     if (!attribute.getClass().equals(Attribute.class)) {
                         list.set(i, cloneAttribute(attribute));
                     }
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanInstantiator.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanInstantiator.java	Wed Jul 05 16:43:41 2017 +0200
@@ -70,7 +70,7 @@
      * instantiate an MBean of this class in the MBeanServer.
      * e.g. it must have a public constructor, be a concrete class...
      */
-    public void testCreation(Class c) throws NotCompliantMBeanException {
+    public void testCreation(Class<?> c) throws NotCompliantMBeanException {
         Introspector.testCreation(c);
     }
 
@@ -78,10 +78,10 @@
      * Loads the class with the specified name using this object's
      * Default Loader Repository.
      **/
-    public Class findClassWithDefaultLoaderRepository(String className)
+    public Class<?> findClassWithDefaultLoaderRepository(String className)
         throws ReflectionException {
 
-        Class theClass;
+        Class<?> theClass;
         if (className == null) {
             throw new RuntimeOperationsException(new
                 IllegalArgumentException("The class name cannot be null"),
@@ -105,7 +105,7 @@
      * Gets the class for the specified class name using the MBean
      * Interceptor's classloader
      */
-    public Class findClass(String className, ClassLoader loader)
+    public Class<?> findClass(String className, ClassLoader loader)
         throws ReflectionException {
 
         return loadClass(className,loader);
@@ -115,7 +115,7 @@
      * Gets the class for the specified class name using the specified
      * class loader
      */
-    public Class findClass(String className, ObjectName aLoader)
+    public Class<?> findClass(String className, ObjectName aLoader)
         throws ReflectionException, InstanceNotFoundException  {
 
         if (aLoader == null)
@@ -140,14 +140,14 @@
      * Return an array of Class corresponding to the given signature, using
      * the specified class loader.
      */
-    public Class[] findSignatureClasses(String signature[],
-                                        ClassLoader loader)
-        throws  ReflectionException {
+    public Class<?>[] findSignatureClasses(String signature[],
+                                           ClassLoader loader)
+        throws ReflectionException {
 
         if (signature == null) return null;
         final ClassLoader aLoader = loader;
         final int length= signature.length;
-        final Class tab[]=new Class[length];
+        final Class<?> tab[]=new Class<?>[length];
 
         if (length == 0) return tab;
         try {
@@ -156,7 +156,7 @@
                 // forth)
                 //
 
-                final Class primCla = primitiveClasses.get(signature[i]);
+                final Class<?> primCla = primitiveClasses.get(signature[i]);
                 if (primCla != null) {
                     tab[i] = primCla;
                     continue;
@@ -203,14 +203,14 @@
      * Instantiates an object given its class, using its empty constructor.
      * The call returns a reference to the newly created object.
      */
-    public Object instantiate(Class theClass)
+    public Object instantiate(Class<?> theClass)
         throws ReflectionException, MBeanException {
         Object moi;
 
 
         // ------------------------------
         // ------------------------------
-        Constructor cons = findConstructor(theClass, null);
+        Constructor<?> cons = findConstructor(theClass, null);
         if (cons == null) {
             throw new ReflectionException(new
                 NoSuchMethodException("No such constructor"));
@@ -257,14 +257,14 @@
      * signature of its constructor The call returns a reference to
      * the newly created object.
      */
-    public Object instantiate(Class theClass, Object params[],
+    public Object instantiate(Class<?> theClass, Object params[],
                               String signature[], ClassLoader loader)
         throws ReflectionException, MBeanException {
         // Instantiate the new object
 
         // ------------------------------
         // ------------------------------
-        final Class[] tab;
+        final Class<?>[] tab;
         Object moi;
         try {
             // Build the signature of the method
@@ -283,7 +283,7 @@
         }
 
         // Query the metadata service to get the right constructor
-        Constructor cons = findConstructor(theClass, tab);
+        Constructor<?> cons = findConstructor(theClass, tab);
 
         if (cons == null) {
             throw new ReflectionException(new
@@ -407,7 +407,7 @@
             throw new  RuntimeOperationsException(new
              IllegalArgumentException(), "Null className passed in parameter");
         }
-        Class theClass;
+        Class<?> theClass;
         if (loaderName == null) {
             // Load the class using the agent class loader
             theClass = findClass(className, loader);
@@ -547,7 +547,7 @@
         throws ReflectionException,
         MBeanException {
 
-        Class theClass = findClassWithDefaultLoaderRepository(className);
+        Class<?> theClass = findClassWithDefaultLoaderRepository(className);
         return instantiate(theClass, params, signature, loader);
     }
 
@@ -595,7 +595,7 @@
 
         // ------------------------------
         // ------------------------------
-        Class theClass;
+        Class<?> theClass;
 
         if (loaderName == null) {
             theClass = findClass(className, loader);
@@ -617,10 +617,10 @@
      * Load a class with the specified loader, or with this object
      * class loader if the specified loader is null.
      **/
-    static Class loadClass(String className, ClassLoader loader)
+    static Class<?> loadClass(String className, ClassLoader loader)
         throws ReflectionException {
 
-        Class theClass;
+        Class<?> theClass;
         if (className == null) {
             throw new RuntimeOperationsException(new
                 IllegalArgumentException("The class name cannot be null"),
@@ -647,15 +647,15 @@
      * Load the classes specified in the signature with the given loader,
      * or with this object class loader.
      **/
-    static Class[] loadSignatureClasses(String signature[],
-                                        ClassLoader loader)
+    static Class<?>[] loadSignatureClasses(String signature[],
+                                           ClassLoader loader)
         throws  ReflectionException {
 
         if (signature == null) return null;
         final ClassLoader aLoader =
            (loader==null?MBeanInstantiator.class.getClassLoader():loader);
         final int length= signature.length;
-        final Class tab[]=new Class[length];
+        final Class<?> tab[]=new Class<?>[length];
 
         if (length == 0) return tab;
         try {
@@ -664,7 +664,7 @@
                 // forth)
                 //
 
-                final Class primCla = primitiveClasses.get(signature[i]);
+                final Class<?> primCla = primitiveClasses.get(signature[i]);
                 if (primCla != null) {
                     tab[i] = primCla;
                     continue;
@@ -710,9 +710,9 @@
 
     private static final Map<String, Class<?>> primitiveClasses = Util.newMap();
     static {
-        for (Class<?> c : new Class[] {byte.class, short.class, int.class,
-                                       long.class, float.class, double.class,
-                                       char.class, boolean.class})
+        for (Class<?> c : new Class<?>[] {byte.class, short.class, int.class,
+                                          long.class, float.class, double.class,
+                                          char.class, boolean.class})
             primitiveClasses.put(c.getName(), c);
     }
 }
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/MXBeanIntrospector.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MXBeanIntrospector.java	Wed Jul 05 16:43:41 2017 +0200
@@ -160,7 +160,7 @@
             // matched to the corresponding Java type, except when that
             // type is primitive.
             Type t = m.getGenericParameterTypes()[paramNo];
-            return (!(t instanceof Class) || !((Class) t).isPrimitive());
+            return (!(t instanceof Class<?>) || !((Class<?>) t).isPrimitive());
         } else {
             Object v;
             try {
@@ -354,7 +354,7 @@
         }
     }
 
-    private static Descriptor typeDescriptor(OpenType openType,
+    private static Descriptor typeDescriptor(OpenType<?> openType,
                                              Type originalType) {
         return new ImmutableDescriptor(
             new String[] {"openType",
@@ -380,37 +380,37 @@
         if (type instanceof GenericArrayType) {
             return canUseOpenInfo(
                 ((GenericArrayType) type).getGenericComponentType());
-        } else if (type instanceof Class && ((Class<?>) type).isArray()) {
+        } else if (type instanceof Class<?> && ((Class<?>) type).isArray()) {
             return canUseOpenInfo(
                 ((Class<?>) type).getComponentType());
         }
-        return (!(type instanceof Class && ((Class<?>) type).isPrimitive()));
+        return (!(type instanceof Class<?> && ((Class<?>) type).isPrimitive()));
     }
 
     private static String originalTypeString(Type type) {
-        if (type instanceof Class)
-            return ((Class) type).getName();
+        if (type instanceof Class<?>)
+            return ((Class<?>) type).getName();
         else
-            return genericTypeString(type);
+            return typeName(type);
     }
 
-    private static String genericTypeString(Type type) {
+    static String typeName(Type type) {
         if (type instanceof Class<?>) {
             Class<?> c = (Class<?>) type;
             if (c.isArray())
-                return genericTypeString(c.getComponentType()) + "[]";
+                return typeName(c.getComponentType()) + "[]";
             else
                 return c.getName();
         } else if (type instanceof GenericArrayType) {
             GenericArrayType gat = (GenericArrayType) type;
-            return genericTypeString(gat.getGenericComponentType()) + "[]";
+            return typeName(gat.getGenericComponentType()) + "[]";
         } else if (type instanceof ParameterizedType) {
             ParameterizedType pt = (ParameterizedType) type;
             StringBuilder sb = new StringBuilder();
-            sb.append(genericTypeString(pt.getRawType())).append("<");
+            sb.append(typeName(pt.getRawType())).append("<");
             String sep = "";
             for (Type t : pt.getActualTypeArguments()) {
-                sb.append(sep).append(genericTypeString(t));
+                sb.append(sep).append(typeName(t));
                 sep = ", ";
             }
             return sb.append(">").toString();
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/ObjectInputStreamWithLoader.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/ObjectInputStreamWithLoader.java	Wed Jul 05 16:43:41 2017 +0200
@@ -54,7 +54,8 @@
         this.loader = theLoader;
     }
 
-    protected Class resolveClass(ObjectStreamClass aClass)
+    @Override
+    protected Class<?> resolveClass(ObjectStreamClass aClass)
             throws IOException, ClassNotFoundException {
         if (loader == null) {
             return super.resolveClass(aClass);
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/SecureClassLoaderRepository.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/SecureClassLoaderRepository.java	Wed Jul 05 16:43:41 2017 +0200
@@ -47,16 +47,16 @@
     public SecureClassLoaderRepository(ClassLoaderRepository clr) {
         this.clr=clr;
     }
-    public final Class loadClass(String className)
+    public final Class<?> loadClass(String className)
         throws ClassNotFoundException {
         return clr.loadClass(className);
     }
-    public final Class loadClassWithout(ClassLoader loader,
+    public final Class<?> loadClassWithout(ClassLoader loader,
                                   String className)
         throws ClassNotFoundException {
         return clr.loadClassWithout(loader,className);
     }
-    public final Class loadClassBefore(ClassLoader loader,
+    public final Class<?> loadClassBefore(ClassLoader loader,
                                  String className)
         throws ClassNotFoundException {
         return clr.loadClassBefore(loader,className);
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/Util.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/Util.java	Wed Jul 05 16:43:41 2017 +0200
@@ -669,7 +669,7 @@
     }
 
     public static <T> Set<T> cloneSet(Set<T> set) {
-        if (set instanceof SortedSet) {
+        if (set instanceof SortedSet<?>) {
             @SuppressWarnings("unchecked")
             SortedSet<T> sset = (SortedSet<T>) set;
             set = new TreeSet<T>(sset.comparator());
@@ -680,7 +680,7 @@
     }
 
     public static <T> Set<T> equivalentEmptySet(Set<T> set) {
-        if (set instanceof SortedSet) {
+        if (set instanceof SortedSet<?>) {
             @SuppressWarnings("unchecked")
             SortedSet<T> sset = (SortedSet<T>) set;
             set = new TreeSet<T>(sset.comparator());
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/WeakIdentityHashMap.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/WeakIdentityHashMap.java	Wed Jul 05 16:43:41 2017 +0200
@@ -118,9 +118,9 @@
         public boolean equals(Object o) {
             if (this == o)
                 return true;
-            if (!(o instanceof IdentityWeakReference))
+            if (!(o instanceof IdentityWeakReference<?>))
                 return false;
-            IdentityWeakReference wr = (IdentityWeakReference) o;
+            IdentityWeakReference<?> wr = (IdentityWeakReference<?>) o;
             Object got = get();
             return (got != null && got == wr.get());
         }
--- a/jdk/src/share/classes/com/sun/jmx/remote/internal/ArrayNotificationBuffer.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/com/sun/jmx/remote/internal/ArrayNotificationBuffer.java	Wed Jul 05 16:43:41 2017 +0200
@@ -120,7 +120,7 @@
     private final Collection<ShareBuffer> sharers = new HashSet<ShareBuffer>(1);
 
     public static NotificationBuffer getNotificationBuffer(
-            MBeanServer mbs, Map env) {
+            MBeanServer mbs, Map<String, ?> env) {
 
         if (env == null)
             env = Collections.emptyMap();
--- a/jdk/src/share/classes/com/sun/jmx/remote/internal/ClientNotifForwarder.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/com/sun/jmx/remote/internal/ClientNotifForwarder.java	Wed Jul 05 16:43:41 2017 +0200
@@ -54,7 +54,7 @@
 
 
 public abstract class ClientNotifForwarder {
-    public ClientNotifForwarder(Map env) {
+    public ClientNotifForwarder(Map<String, ?> env) {
         this(null, env);
     }
 
@@ -113,7 +113,7 @@
         private Thread thread;
     }
 
-    public ClientNotifForwarder(ClassLoader defaultClassLoader, Map env) {
+    public ClientNotifForwarder(ClassLoader defaultClassLoader, Map<String, ?> env) {
         maxNotifications = EnvHelp.getMaxFetchNotifNumber(env);
         timeout = EnvHelp.getFetchTimeout(env);
 
--- a/jdk/src/share/classes/com/sun/jmx/remote/internal/ProxyInputStream.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/com/sun/jmx/remote/internal/ProxyInputStream.java	Wed Jul 05 16:43:41 2017 +0200
@@ -36,7 +36,7 @@
 import org.omg.CORBA.TypeCode;
 import org.omg.CORBA.portable.BoxedValueHelper;
 
-@SuppressWarnings("deprecation")
+@SuppressWarnings({"deprecation", "rawtypes"})
 public class ProxyInputStream extends org.omg.CORBA_2_3.portable.InputStream {
     public ProxyInputStream(org.omg.CORBA.portable.InputStream in) {
         this.in = in;
--- a/jdk/src/share/classes/com/sun/jmx/remote/internal/ServerNotifForwarder.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/com/sun/jmx/remote/internal/ServerNotifForwarder.java	Wed Jul 05 16:43:41 2017 +0200
@@ -59,7 +59,7 @@
 
 
     public ServerNotifForwarder(MBeanServer mbeanServer,
-                                Map env,
+                                Map<String, ?> env,
                                 NotificationBuffer notifBuffer,
                                 String connectionId) {
         this.mbeanServer = mbeanServer;
--- a/jdk/src/share/classes/com/sun/jmx/remote/internal/Unmarshal.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/com/sun/jmx/remote/internal/Unmarshal.java	Wed Jul 05 16:43:41 2017 +0200
@@ -29,6 +29,6 @@
 import java.rmi.MarshalledObject;
 
 public interface Unmarshal {
-    public Object get(MarshalledObject mo)
+    public Object get(MarshalledObject<?> mo)
             throws IOException, ClassNotFoundException;
 }
--- a/jdk/src/share/classes/com/sun/jmx/remote/security/FileLoginModule.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/com/sun/jmx/remote/security/FileLoginModule.java	Wed Jul 05 16:43:41 2017 +0200
@@ -26,6 +26,7 @@
 package com.sun.jmx.remote.security;
 
 import com.sun.jmx.mbeanserver.GetPropertyAction;
+import com.sun.jmx.mbeanserver.Util;
 import java.io.BufferedInputStream;
 import java.io.File;
 import java.io.FileInputStream;
@@ -146,8 +147,8 @@
     // Initial state
     private Subject subject;
     private CallbackHandler callbackHandler;
-    private Map<String, ?> sharedState;
-    private Map options;
+    private Map<String, Object> sharedState;
+    private Map<String, ?> options;
     private String passwordFile;
     private String passwordFileDisplayName;
     private boolean userSuppliedPasswordFile;
@@ -172,7 +173,7 @@
 
         this.subject = subject;
         this.callbackHandler = callbackHandler;
-        this.sharedState = sharedState;
+        this.sharedState = Util.cast(sharedState);
         this.options = options;
 
         // initialize any configured options
@@ -454,8 +455,8 @@
         if (storePass &&
             !sharedState.containsKey(USERNAME_KEY) &&
             !sharedState.containsKey(PASSWORD_KEY)) {
-            ((Map) sharedState).put(USERNAME_KEY, username);
-            ((Map) sharedState).put(PASSWORD_KEY, password);
+            sharedState.put(USERNAME_KEY, username);
+            sharedState.put(PASSWORD_KEY, password);
         }
 
         // Create a new user principal
--- a/jdk/src/share/classes/com/sun/jmx/remote/security/JMXPluggableAuthenticator.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/com/sun/jmx/remote/security/JMXPluggableAuthenticator.java	Wed Jul 05 16:43:41 2017 +0200
@@ -87,7 +87,7 @@
      * @exception SecurityException if the authentication mechanism cannot be
      *            initialized.
      */
-    public JMXPluggableAuthenticator(Map env) {
+    public JMXPluggableAuthenticator(Map<?, ?> env) {
 
         String loginConfigName = null;
         String passwordFile = null;
--- a/jdk/src/share/classes/com/sun/jmx/remote/security/MBeanServerFileAccessController.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/com/sun/jmx/remote/security/MBeanServerFileAccessController.java	Wed Jul 05 16:43:41 2017 +0200
@@ -249,9 +249,8 @@
                     }
                 });
         if (s == null) return; /* security has not been enabled */
-        final Set principals = s.getPrincipals();
-        for (Iterator i = principals.iterator(); i.hasNext(); ) {
-            final Principal p = (Principal) i.next();
+        final Set<Principal> principals = s.getPrincipals();
+        for (Principal p : principals) {
             String grantedAccessLevel;
             synchronized (props) {
                 grantedAccessLevel = props.getProperty(p.getName());
@@ -271,8 +270,8 @@
     }
 
     private void checkValues(Properties props) {
-        Collection c = props.values();
-        for (Iterator i = c.iterator(); i.hasNext(); ) {
+        Collection<?> c = props.values();
+        for (Iterator<?> i = c.iterator(); i.hasNext(); ) {
             final String accessLevel = (String) i.next();
             if (!accessLevel.equals(READONLY) &&
                 !accessLevel.equals(READWRITE)) {
--- a/jdk/src/share/classes/com/sun/jmx/remote/util/ClassLoaderWithRepository.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/com/sun/jmx/remote/util/ClassLoaderWithRepository.java	Wed Jul 05 16:43:41 2017 +0200
@@ -38,7 +38,7 @@
         this.cl2 = cl2;
    }
 
-    protected Class findClass(String name) throws ClassNotFoundException {
+    protected Class<?> findClass(String name) throws ClassNotFoundException {
         try {
             return repository.loadClass(name);
         } catch (ClassNotFoundException cne) {
--- a/jdk/src/share/classes/com/sun/jmx/remote/util/ClassLogger.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/com/sun/jmx/remote/util/ClassLogger.java	Wed Jul 05 16:43:41 2017 +0200
@@ -41,7 +41,7 @@
            people to use at least J2SE 1.4.  */
         boolean loaded = false;
         try {
-            Class c = java.util.logging.Logger.class;
+            Class<?> c = java.util.logging.Logger.class;
             loaded = true;
         } catch (Error e) {
             // OK.
--- a/jdk/src/share/classes/com/sun/jmx/remote/util/EnvHelp.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/com/sun/jmx/remote/util/EnvHelp.java	Wed Jul 05 16:43:41 2017 +0200
@@ -117,7 +117,7 @@
      * <code>jmx.remote.default.class.loader.name</code> is specified
      * and the ClassLoader MBean is not found in <var>mbs</var>.
      */
-    public static ClassLoader resolveServerClassLoader(Map env,
+    public static ClassLoader resolveServerClassLoader(Map<String, ?> env,
                                                        MBeanServer mbs)
         throws InstanceNotFoundException {
 
@@ -194,7 +194,7 @@
      * <code>jmx.remote.default.class.loader</code> is specified
      * and is not an instance of {@link ClassLoader}.
      */
-    public static ClassLoader resolveClientClassLoader(Map env) {
+    public static ClassLoader resolveClientClassLoader(Map<String, ?> env) {
 
         if (env == null)
             return Thread.currentThread().getContextClassLoader();
@@ -241,7 +241,7 @@
 
         try {
             java.lang.reflect.Method getCause =
-                t.getClass().getMethod("getCause", (Class[]) null);
+                t.getClass().getMethod("getCause", (Class<?>[]) null);
             ret = (Throwable)getCause.invoke(t, (Object[]) null);
 
         } catch (Exception e) {
@@ -264,7 +264,7 @@
      * Returns the size of a notification buffer for a connector server.
      * The default value is 1000.
      */
-    public static int getNotifBufferSize(Map env) {
+    public static int getNotifBufferSize(Map<String, ?> env) {
         int defaultQueueSize = 1000; // default value
 
         // keep it for the compability for the fix:
@@ -327,7 +327,7 @@
      * Returns the maximum notification number which a client will
      * fetch every time.
      */
-    public static int getMaxFetchNotifNumber(Map env) {
+    public static int getMaxFetchNotifNumber(Map<String, ?> env) {
         return (int) getIntegerAttribute(env, MAX_FETCH_NOTIFS, 1000, 1,
                                          Integer.MAX_VALUE);
     }
@@ -344,7 +344,7 @@
     /**
      * Returns the timeout for a client to fetch notifications.
      */
-    public static long getFetchTimeout(Map env) {
+    public static long getFetchTimeout(Map<String, ?> env) {
         return getIntegerAttribute(env, FETCH_TIMEOUT, 60000L, 0,
                 Long.MAX_VALUE);
     }
@@ -361,7 +361,7 @@
             "com.sun.jmx.remote.notification.access.controller";
 
     public static NotificationAccessController getNotificationAccessController(
-            Map env) {
+            Map<String, ?> env) {
         return (env == null) ? null :
             (NotificationAccessController) env.get(NOTIF_ACCESS_CONTROLLER);
     }
@@ -378,7 +378,7 @@
      * an entry for <code>name</code> but it does not meet the
      * constraints above.
      */
-    public static long getIntegerAttribute(Map env, String name,
+    public static long getIntegerAttribute(Map<String, ?> env, String name,
                                            long defaultValue, long minValue,
                                            long maxValue) {
         final Object o;
@@ -421,9 +421,8 @@
 
     /* Check that all attributes have a key that is a String.
        Could make further checks, e.g. appropriate types for attributes.  */
-    public static void checkAttributes(Map attributes) {
-        for (Iterator it = attributes.keySet().iterator(); it.hasNext(); ) {
-            Object key = it.next();
+    public static void checkAttributes(Map<?, ?> attributes) {
+        for (Object key : attributes.keySet()) {
             if (!(key instanceof String)) {
                 final String msg =
                     "Attributes contain key that is not a string: " + key;
@@ -455,7 +454,7 @@
         logger.trace("purgeUnserializable", "starts");
         ObjectOutputStream oos = null;
         int i = 0;
-        for (Iterator it = objects.iterator(); it.hasNext(); i++) {
+        for (Iterator<?> it = objects.iterator(); it.hasNext(); i++) {
             Object v = it.next();
 
             if (v == null || v instanceof String) {
@@ -564,18 +563,18 @@
            guarantees that we will never call next() on the corresponding
            iterator.  */
         String sentinelKey = map.lastKey() + "X";
-        Iterator keyIterator = map.keySet().iterator();
-        Iterator stringIterator = hiddenStrings.iterator();
-        Iterator prefixIterator = hiddenPrefixes.iterator();
+        Iterator<String> keyIterator = map.keySet().iterator();
+        Iterator<String> stringIterator = hiddenStrings.iterator();
+        Iterator<String> prefixIterator = hiddenPrefixes.iterator();
 
         String nextString;
         if (stringIterator.hasNext())
-            nextString = (String) stringIterator.next();
+            nextString = stringIterator.next();
         else
             nextString = sentinelKey;
         String nextPrefix;
         if (prefixIterator.hasNext())
-            nextPrefix = (String) prefixIterator.next();
+            nextPrefix = prefixIterator.next();
         else
             nextPrefix = sentinelKey;
 
@@ -583,7 +582,7 @@
            or prefix, remove it. */
     keys:
         while (keyIterator.hasNext()) {
-            String key = (String) keyIterator.next();
+            String key = keyIterator.next();
 
             /* Continue through string-match values until we find one
                that is either greater than the current key, or equal
@@ -591,7 +590,7 @@
             int cmp = +1;
             while ((cmp = nextString.compareTo(key)) < 0) {
                 if (stringIterator.hasNext())
-                    nextString = (String) stringIterator.next();
+                    nextString = stringIterator.next();
                 else
                     nextString = sentinelKey;
             }
@@ -609,7 +608,7 @@
                     continue keys;
                 }
                 if (prefixIterator.hasNext())
-                    nextPrefix = (String) prefixIterator.next();
+                    nextPrefix = prefixIterator.next();
                 else
                     nextPrefix = sentinelKey;
             }
@@ -640,7 +639,7 @@
     /**
      * Returns the server side connection timeout.
      */
-    public static long getServerConnectionTimeout(Map env) {
+    public static long getServerConnectionTimeout(Map<String, ?> env) {
         return getIntegerAttribute(env, SERVER_CONNECTION_TIMEOUT, 120000L,
                                    0, Long.MAX_VALUE);
     }
@@ -656,7 +655,7 @@
     /**
      * Returns the client connection check period.
      */
-    public static long getConnectionCheckPeriod(Map env) {
+    public static long getConnectionCheckPeriod(Map<String, ?> env) {
         return getIntegerAttribute(env, CLIENT_CONNECTION_CHECK_PERIOD, 60000L,
                                    0, Long.MAX_VALUE);
     }
@@ -691,7 +690,7 @@
      * to {@code String}.
      */
     public static boolean computeBooleanFromString(
-            Map env, String prop, boolean systemProperty) {
+            Map<String, ?> env, String prop, boolean systemProperty) {
 
         if (env == null)
             throw new IllegalArgumentException("env map cannot be null");
@@ -744,7 +743,8 @@
      * to {@code String}.
      */
     public static boolean computeBooleanFromString(
-            Map env, String prop, boolean systemProperty, boolean defaultValue) {
+            Map<String, ?> env, String prop,
+            boolean systemProperty, boolean defaultValue) {
 
         if (env == null)
             throw new IllegalArgumentException("env map cannot be null");
@@ -774,7 +774,7 @@
     public static <K, V> Hashtable<K, V> mapToHashtable(Map<K, V> map) {
         HashMap<K, V> m = new HashMap<K, V>(map);
         if (m.containsKey(null)) m.remove(null);
-        for (Iterator i = m.values().iterator(); i.hasNext(); )
+        for (Iterator<?> i = m.values().iterator(); i.hasNext(); )
             if (i.next() == null) i.remove();
         return new Hashtable<K, V>(m);
     }
@@ -783,7 +783,7 @@
      * Returns true if the parameter JMXConnector.USE_EVENT_SERVICE is set to a
      * String equals "true" by ignoring case in the map or in the System.
      */
-    public static boolean eventServiceEnabled(Map env) {
+    public static boolean eventServiceEnabled(Map<String, ?> env) {
         return computeBooleanFromString(env, JMXConnector.USE_EVENT_SERVICE, true);
     }
 
@@ -793,7 +793,7 @@
      * If the property DELEGATE_TO_EVENT_SERVICE is not set, returns
      * a default value of "true".
      */
-    public static boolean delegateToEventService(Map env) {
+    public static boolean delegateToEventService(Map<String, ?> env) {
         return computeBooleanFromString(env,
                 JMXConnectorServer.DELEGATE_TO_EVENT_SERVICE, true, true);
     }
--- a/jdk/src/share/classes/com/sun/jmx/remote/util/EventClientConnection.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/com/sun/jmx/remote/util/EventClientConnection.java	Wed Jul 05 16:43:41 2017 +0200
@@ -138,8 +138,8 @@
             Class<T> interfaceClass, Callable<EventClient> eventClientFactory) {
         final InvocationHandler handler =
                 new EventClientConnection(connection,eventClientFactory);
-        final Class[] interfaces =
-                new Class[] {interfaceClass, EventClientFactory.class};
+        final Class<?>[] interfaces =
+                new Class<?>[] {interfaceClass, EventClientFactory.class};
 
         Object proxy =
                 Proxy.newProxyInstance(interfaceClass.getClassLoader(),
@@ -156,7 +156,7 @@
         // add/remove notification listener are routed to the EventClient
         if (methodName.equals("addNotificationListener")
             || methodName.equals("removeNotificationListener")) {
-            final Class[] sig = method.getParameterTypes();
+            final Class<?>[] sig = method.getParameterTypes();
             if (sig.length>1 &&
                     NotificationListener.class.isAssignableFrom(sig[1])) {
                 return invokeBroadcasterMethod(proxy,method,args);
@@ -164,7 +164,7 @@
         }
 
         // subscribe/unsubscribe are also routed to the EventClient.
-        final Class clazz = method.getDeclaringClass();
+        final Class<?> clazz = method.getDeclaringClass();
         if (clazz.equals(EventClientFactory.class)) {
             return invokeEventClientSubscriberMethod(proxy,method,args);
         }
@@ -319,7 +319,7 @@
             return true;
         if (methodName.equals("equals")
             && Arrays.equals(method.getParameterTypes(),
-                new Class[] {Object.class})
+                new Class<?>[] {Object.class})
                 && isLocal(proxy, method))
             return true;
         return false;
--- a/jdk/src/share/classes/com/sun/jmx/remote/util/OrderClassLoaders.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/com/sun/jmx/remote/util/OrderClassLoaders.java	Wed Jul 05 16:43:41 2017 +0200
@@ -32,7 +32,7 @@
         this.cl2 = cl2;
     }
 
-    protected Class findClass(String name) throws ClassNotFoundException {
+    protected Class<?> findClass(String name) throws ClassNotFoundException {
         try {
             return super.findClass(name);
         } catch (ClassNotFoundException cne) {
--- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/IdResolver.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/IdResolver.java	Wed Jul 05 16:43:41 2017 +0200
@@ -70,10 +70,13 @@
      */
     public static void registerElementById(Element element, String idValue) {
         Document doc = element.getOwnerDocument();
-        WeakHashMap elementMap = (WeakHashMap) docMap.get(doc);
-        if(elementMap == null) {
-            elementMap = new WeakHashMap();
-            docMap.put(doc, elementMap);
+        WeakHashMap elementMap;
+        synchronized (docMap) {
+            elementMap = (WeakHashMap) docMap.get(doc);
+            if (elementMap == null) {
+                elementMap = new WeakHashMap();
+                docMap.put(doc, elementMap);
+            }
         }
         elementMap.put(idValue, new WeakReference(element));
     }
@@ -153,7 +156,10 @@
     private static Element getElementByIdType(Document doc, String id) {
         if (log.isLoggable(java.util.logging.Level.FINE))
             log.log(java.util.logging.Level.FINE, "getElementByIdType() Search for ID " + id);
-        WeakHashMap elementMap = (WeakHashMap) docMap.get(doc);
+        WeakHashMap elementMap;
+        synchronized (docMap) {
+            elementMap = (WeakHashMap) docMap.get(doc);
+        }
         if (elementMap != null) {
             WeakReference weakReference = (WeakReference) elementMap.get(id);
             if (weakReference != null) {
--- a/jdk/src/share/classes/javax/management/AttributeList.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/javax/management/AttributeList.java	Wed Jul 05 16:43:41 2017 +0200
@@ -159,7 +159,7 @@
                 checkTypeSafe(this);
             typeSafe = true;
         }
-        return (List<Attribute>) (List) this;
+        return (List<Attribute>) (List<?>) this;
     }
 
     /**
--- a/jdk/src/share/classes/javax/management/DefaultLoaderRepository.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/javax/management/DefaultLoaderRepository.java	Wed Jul 05 16:43:41 2017 +0200
@@ -62,7 +62,7 @@
      *
      * @exception ClassNotFoundException The specified class could not be found.
      */
-    public static Class loadClass(String className)
+    public static Class<?> loadClass(String className)
         throws ClassNotFoundException {
         return javax.management.loading.DefaultLoaderRepository.loadClass(className);
     }
@@ -82,7 +82,7 @@
      *
      * @exception ClassNotFoundException The specified class could not be found.
      */
-    public static Class loadClassWithout(ClassLoader loader,String className)
+    public static Class<?> loadClassWithout(ClassLoader loader,String className)
         throws ClassNotFoundException {
         return javax.management.loading.DefaultLoaderRepository.loadClassWithout(loader, className);
     }
--- a/jdk/src/share/classes/javax/management/Descriptor.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/javax/management/Descriptor.java	Wed Jul 05 16:43:41 2017 +0200
@@ -101,7 +101,7 @@
  *
  * <tr><th>Name</th><th>Type</th><th>Used in</th><th>Meaning</th></tr>
  *
- * <tr><td><a name="defaultValue"><i>defaultValue</i></a><td>Object</td>
+ * <tr id="defaultValue"><td><i>defaultValue</i><td>Object</td>
  * <td>MBeanAttributeInfo<br>MBeanParameterInfo</td>
  *
  * <td>Default value for an attribute or parameter.  See
@@ -144,7 +144,7 @@
  * might be disabled if it cannot currently be emitted but could be in
  * other circumstances.</td>
  *
- * <tr><td><a name="immutableInfo"><i>immutableInfo</i></a><td>String</td>
+ * <tr id="immutableInfo"><td><i>immutableInfo</i><td>String</td>
  * <td>MBeanInfo</td>
  *
  * <td>The string {@code "true"} or {@code "false"} according as this
@@ -153,20 +153,24 @@
  * the lifetime of the MBean.  Hence, a client can read it once and
  * cache the read value.  When this field is false or absent, there is
  * no such guarantee, although that does not mean that the MBeanInfo
- * will necessarily change.</td>
+ * will necessarily change.  See also the <a
+ * href="MBeanInfo.html#info-changed">{@code "jmx.mbean.info.changed"}</a>
+ * notification.</td>
  *
  * <tr><td>infoTimeout</td><td>String<br>Long</td><td>MBeanInfo</td>
  *
- * <td>The time in milli-seconds that the MBeanInfo can reasonably be
- * expected to be unchanged.  The value can be a {@code Long} or a
- * decimal string.  This provides a hint from a DynamicMBean or any
+ * <td id="infoTimeout">The time in milli-seconds that the MBeanInfo can
+ * reasonably be expected to be unchanged.  The value can be a {@code Long}
+ * or a decimal string.  This provides a hint from a DynamicMBean or any
  * MBean that does not define {@code immutableInfo} as {@code true}
  * that the MBeanInfo is not likely to change within this period and
  * therefore can be cached.  When this field is missing or has the
  * value zero, it is not recommended to cache the MBeanInfo unless it
- * has the {@code immutableInfo} set to {@code true}.</td></tr>
+ * has the {@code immutableInfo} set to {@code true} or it has <a
+ * href="MBeanInfo.html#info-changed">{@code "jmx.mbean.info.changed"}</a> in
+ * its {@link MBeanNotificationInfo} array.</td></tr>
  *
- * <tr><td><a name="interfaceClassName"><i>interfaceClassName</i></a></td>
+ * <tr id="interfaceClassName"><td><i>interfaceClassName</i></td>
  * <td>String</td><td>MBeanInfo</td>
  *
  * <td>The Java interface name for a Standard MBean or MXBean, as
@@ -175,19 +179,19 @@
  * StandardMBean} class will have this field in its MBeanInfo
  * Descriptor.</td>
  *
- * <tr><td><a name="legalValues"><i>legalValues</i></a></td>
+ * <tr id="legalValues"><td><i>legalValues</i></td>
  * <td>{@literal Set<?>}</td><td>MBeanAttributeInfo<br>MBeanParameterInfo</td>
  *
  * <td>Legal values for an attribute or parameter.  See
  * {@link javax.management.openmbean}.</td>
  *
- * <tr><td><a name="maxValue"><i>maxValue</i></a><td>Object</td>
+ * <tr id="maxValue"><td><i>maxValue</i><td>Object</td>
  * <td>MBeanAttributeInfo<br>MBeanParameterInfo</td>
  *
  * <td>Maximum legal value for an attribute or parameter.  See
  * {@link javax.management.openmbean}.</td>
  *
- * <tr><td><a name="metricType">metricType</a><td>String</td>
+ * <tr id="metricType"><td>metricType</td><td>String</td>
  * <td>MBeanAttributeInfo<br>MBeanOperationInfo</td>
  *
  * <td>The type of a metric, one of the strings "counter" or "gauge".
@@ -200,13 +204,13 @@
  * that can increase or decrease.  Examples might be the number of
  * open connections or a cache hit rate or a temperature reading.
  *
- * <tr><td><a name="minValue"><i>minValue</i></a><td>Object</td>
+ * <tr id="minValue"><td><i>minValue</i><td>Object</td>
  * <td>MBeanAttributeInfo<br>MBeanParameterInfo</td>
  *
  * <td>Minimum legal value for an attribute or parameter.  See
  * {@link javax.management.openmbean}.</td>
  *
- * <tr><td><a name="mxbean"><i>mxbean</i></a><td>String</td>
+ * <tr id="mxbean"><td><i>mxbean</i><td>String</td>
  * <td>MBeanInfo</td>
  *
  * <td>The string {@code "true"} or {@code "false"} according as this
@@ -223,7 +227,7 @@
  * MXBean, if it was not the {@linkplain MXBeanMappingFactory#DEFAULT default}
  * one.</td>
  *
- * <tr><td><a name="openType"><i>openType</i></a><td>{@link OpenType}</td>
+ * <tr id="openType"><td><i>openType</i><td>{@link OpenType}</td>
  * <td>MBeanAttributeInfo<br>MBeanOperationInfo<br>MBeanParameterInfo</td>
  *
  * <td><p>The Open Type of this element.  In the case of {@code
@@ -240,7 +244,7 @@
  * which case it indicates the Open Type that the {@link
  * Notification#getUserData() user data} will have.</td>
  *
- * <tr><td><a name="originalType"><i>originalType</i></a><td>String</td>
+ * <tr id="originalType"><td><i>originalType</i><td>String</td>
  * <td>MBeanAttributeInfo<br>MBeanOperationInfo<br>MBeanParameterInfo</td>
  *
  * <td><p>The original Java type of this element as it appeared in the
@@ -282,11 +286,132 @@
  *
  * </table>
  *
- * <p>Some additional fields are defined by Model MBeans.  See
- * {@link javax.management.modelmbean.ModelMBeanInfo ModelMBeanInfo}
- * and related classes and the chapter "Model MBeans" of the
- * <a href="http://java.sun.com/products/JavaManagement/download.html">
- * JMX Specification</a>.</p>
+ * <p>Some additional fields are defined by Model MBeans.  See the
+ * information for <a href="modelmbean/ModelMBeanInfo.html#descriptor"><!--
+ * -->{@code ModelMBeanInfo}</a>,
+ * <a href="modelmbean/ModelMBeanAttributeInfo.html#descriptor"><!--
+ * -->{@code ModelMBeanAttributeInfo}</a>,
+ * <a href="modelmbean/ModelMBeanConstructorInfo.html#descriptor"><!--
+ * -->{@code ModelMBeanConstructorInfo}</a>,
+ * <a href="modelmbean/ModelMBeanNotificationInfo.html#descriptor"><!--
+ * -->{@code ModelMBeanNotificationInfo}</a>, and
+ * <a href="modelmbean/ModelMBeanOperationInfo.html#descriptor"><!--
+ * -->{@code ModelMBeanOperationInfo}</a>, as
+ * well as the chapter "Model MBeans" of the <a
+ * href="http://java.sun.com/products/JavaManagement/download.html">JMX
+ * Specification</a>.  The following table summarizes these fields.  Note
+ * that when the Type in this table is Number, a String that is the decimal
+ * representation of a Long can also be used.</p>
+ *
+ * <p>Nothing prevents the use of these fields in MBeans that are not Model
+ * MBeans.  The <a href="#displayName">displayName</a>, <a href="#severity"><!--
+ * -->severity</a>, and <a href="#visibility">visibility</a> fields are of
+ * interest outside Model MBeans, for example.  But only Model MBeans have
+ * a predefined behavior for these fields.</p>
+ *
+ * <table border="1" cellpadding="5">
+ *
+ * <tr><th>Name</th><th>Type</th><th>Used in</th><th>Meaning</th></tr>
+ *
+ * <tr><td>class</td><td>String</td><td>ModelMBeanOperationInfo</td>
+ *     <td>Class where method is defined (fully qualified).</td></tr>
+ *
+ * <tr><td>currencyTimeLimit</td><td>Number</td>
+ *     <td>ModelMBeanInfo<br>ModelMBeanAttributeInfo<br>ModelMBeanOperationInfo</td>
+ *     <td>How long cached value is valid: &lt;0 never, =0 always,
+ *         &gt;0 seconds.</td></tr>
+ *
+ * <tr><td>default</td><td>Object</td><td>ModelMBeanAttributeInfo</td>
+ *     <td>Default value for attribute.</td></tr>
+ *
+ * <tr><td>descriptorType</td><td>String</td><td>Any</td>
+ *     <td>Type of descriptor, "mbean", "attribute", "constructor", "operation",
+ *         or "notification".</td></tr>
+ *
+ * <tr id="displayName"><td>displayName</td><td>String</td><td>Any</td>
+ *     <td>Human readable name of this item.</td></tr>
+ *
+ * <tr><td>export</td><td>String</td><td>ModelMBeanInfo</td>
+ *     <td>Name to be used to export/expose this MBean so that it is
+ *         findable by other JMX Agents.</td></tr>
+ *
+ * <tr><td>getMethod</td><td>String</td><td>ModelMBeanAttributeInfo</td>
+ *     <td>Name of operation descriptor for get method.</td></tr>
+ *
+ * <tr><td>lastUpdatedTimeStamp</td><td>Number</td>
+ *     <td>ModelMBeanAttributeInfo<br>ModelMBeanOperationInfo</td>
+ *     <td>When <a href="#value-field">value</a> was set.</td></tr>
+ *
+ * <tr><td>log</td><td>String</td><td>ModelMBeanInfo<br>ModelMBeanNotificationInfo</td>
+ *     <td>t or T: log all notifications, f or F: log no notifications.</td></tr>
+ *
+ * <tr><td>logFile</td><td>String</td><td>ModelMBeanInfo<br>ModelMBeanNotificationInfo</td>
+ *     <td>Fully qualified filename to log events to.</td></tr>
+ *
+ * <tr><td>messageID</td><td>String</td><td>ModelMBeanNotificationInfo</td>
+ *     <td>Unique key for message text (to allow translation, analysis).</td></tr>
+ *
+ * <tr><td>messageText</td><td>String</td><td>ModelMBeanNotificationInfo</td>
+ *     <td>Text of notification.</td></tr>
+ *
+ * <tr><td>name</td><td>String</td><td>Any</td>
+ *     <td>Name of this item.</td></tr>
+ *
+ * <tr><td>persistFile</td><td>String</td><td>ModelMBeanInfo</td>
+ *     <td>File name into which the MBean should be persisted.</td></tr>
+ *
+ * <tr><td>persistLocation</td><td>String</td><td>ModelMBeanInfo</td>
+ *     <td>The fully qualified directory name where the MBean should be
+ *         persisted (if appropriate).</td></tr>
+ *
+ * <tr><td>persistPeriod</td><td>Number</td>
+ *     <td>ModelMBeanInfo<br>ModelMBeanAttributeInfo</td>
+ *     <td>Frequency of persist cycle in seconds. Used when persistPolicy is
+ *         "OnTimer" or "NoMoreOftenThan".</td></tr>
+ *
+ * <tr><td>persistPolicy</td><td>String</td>
+ *     <td>ModelMBeanInfo<br>ModelMBeanAttributeInfo</td>
+ *     <td>One of: OnUpdate|OnTimer|NoMoreOftenThan|OnUnregister|Always|Never.
+ *         See the section "MBean Descriptor Fields" in the JMX specification
+ *         document.</td></tr>
+ *
+ * <tr><td>presentationString</td><td>String</td><td>Any</td>
+ *     <td>XML formatted string to allow presentation of data.</td></tr>
+ *
+ * <tr><td>protocolMap</td><td>Descriptor</td><td>ModelMBeanAttributeInfo</td>
+ *     <td>See the section "Protocol Map Support" in the JMX specification
+ *         document.  Mappings must be appropriate for the attribute and entries
+ *         can be updated or augmented at runtime.</td></tr>
+ *
+ * <tr><td>role</td><td>String</td>
+ *     <td>ModelMBeanConstructorInfo<br>ModelMBeanOperationInfo</td>
+ *     <td>One of "constructor", "operation", "getter", or "setter".</td></tr>
+ *
+ * <tr><td>setMethod</td><td>String</td><td>ModelMBeanAttributeInfo</td>
+ *     <td>Name of operation descriptor for set method.</td></tr>
+ *
+ * <tr id="severity"><td>severity</td><td>Number</td>
+ *     <td>ModelMBeanNotificationInfo</td>
+ *     <td>0-6 where 0: unknown; 1: non-recoverable;
+ *         2: critical, failure; 3: major, severe;
+ *         4: minor, marginal, error; 5: warning;
+ *         6: normal, cleared, informative</td></tr>
+ *
+ * <tr><td>targetObject</td><td>Object</td><td>ModelMBeanOperationInfo</td>
+ *     <td>Object on which to execute this method.</td></tr>
+ *
+ * <tr><td>targetType</td><td>String</td><td>ModelMBeanOperationInfo</td>
+ *     <td>type of object reference for targetObject. Can be:
+ *         ObjectReference | Handle | EJBHandle | IOR | RMIReference.</td></tr>
+ *
+ * <tr id="value-field"><td>value</td><td>Object</td>
+ *     <td>ModelMBeanAttributeInfo<br>ModelMBeanOperationInfo</td>
+ *     <td>Current (cached) value for attribute or operation.</td></tr>
+ *
+ * <tr id="visibility"><td>visibility</td><td>Number</td><td>Any</td>
+ *     <td>1-4 where 1: always visible, 4: rarely visible.</td></tr>
+ *
+ * </table>
  *
  * @since 1.5
  */
@@ -439,7 +564,7 @@
     public boolean isValid() throws RuntimeOperationsException;
 
     /**
-     * Compares this descriptor to the given object.  The objects are equal if
+     * <p>Compares this descriptor to the given object.  The objects are equal if
      * the given object is also a Descriptor, and if the two Descriptors have
      * the same field names (possibly differing in case) and the same
      * associated values.  The respective values for a field in the two
--- a/jdk/src/share/classes/javax/management/JMRuntimeException.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/javax/management/JMRuntimeException.java	Wed Jul 05 16:43:41 2017 +0200
@@ -70,7 +70,7 @@
         try {
             java.lang.reflect.Method initCause =
                 Throwable.class.getMethod("initCause",
-                                          new Class[] {Throwable.class});
+                                          new Class<?>[] {Throwable.class});
             initCause.invoke(this, new Object[] {cause});
         } catch (Exception e) {
             // OK: just means we won't have debugging info
--- a/jdk/src/share/classes/javax/management/JMX.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/javax/management/JMX.java	Wed Jul 05 16:43:41 2017 +0200
@@ -463,6 +463,12 @@
      * likewise for the other methods of {@link
      * NotificationBroadcaster} and {@link NotificationEmitter}.</p>
      *
+     * <p>This method is equivalent to {@link
+     * #newMBeanProxy(MBeanServerConnection, ObjectName, Class, JMX.MBeanOptions)
+     * newMBeanProxy(connection, objectName, interfaceClass, opts)}, where
+     * {@code opts} is a {@link JMX.ProxyOptions} representing the
+     * {@code notificationEmitter} parameter.</p>
+     *
      * @param connection the MBean server to forward to.
      * @param objectName the name of the MBean within
      * {@code connection} to forward to.
@@ -555,10 +561,6 @@
      *
      * </ul>
      *
-     * <p>The object returned by this method is a
-     * {@link Proxy} whose {@code InvocationHandler} is an
-     * {@link MBeanServerInvocationHandler}.</p>
-     *
      * <p>This method is equivalent to {@link
      * #newMXBeanProxy(MBeanServerConnection, ObjectName, Class,
      * boolean) newMXBeanProxy(connection, objectName, interfaceClass,
@@ -601,6 +603,17 @@
      * likewise for the other methods of {@link
      * NotificationBroadcaster} and {@link NotificationEmitter}.</p>
      *
+     * <p>This method is equivalent to {@link
+     * #newMBeanProxy(MBeanServerConnection, ObjectName, Class, JMX.MBeanOptions)
+     * newMBeanProxy(connection, objectName, interfaceClass, opts)}, where
+     * {@code opts} is a {@link JMX.ProxyOptions} where the {@link
+     * JMX.ProxyOptions#getMXBeanMappingFactory() MXBeanMappingFactory}
+     * property is
+     * {@link MXBeanMappingFactory#forInterface(Class)
+     * MXBeanMappingFactory.forInterface(interfaceClass)} and the {@link
+     * JMX.ProxyOptions#isNotificationEmitter() notificationEmitter} property
+     * is equal to the {@code notificationEmitter} parameter.</p>
+     *
      * @param connection the MBean server to forward to.
      * @param objectName the name of the MBean within
      * {@code connection} to forward to.
@@ -655,6 +668,36 @@
      *     arbitrary Java types and Open Types.</li>
      * </ul>
      *
+     * <p>The object returned by this method is a
+     * {@link Proxy} whose {@code InvocationHandler} is an
+     * {@link MBeanServerInvocationHandler}.  This means that it is possible
+     * to retrieve the parameters that were used to produce the proxy.  If the
+     * proxy was produced as follows...</p>
+     *
+     * <pre>
+     * FooMBean proxy =
+     *     JMX.newMBeanProxy(connection, objectName, FooMBean.class, opts);
+     * </pre>
+     *
+     * <p>...then you can get the {@code MBeanServerInvocationHandler} like
+     * this...</p>
+     *
+     * <pre>
+     * MBeanServerInvocationHandler mbsih = (MBeanServerInvocationHandler)
+     *     {@link Proxy#getInvocationHandler(Object)
+     *            Proxy.getInvocationHandler}(proxy);
+     * </pre>
+     *
+     * <p>...and you can retrieve {@code connection}, {@code
+     * objectName}, and {@code opts} using the {@link
+     * MBeanServerInvocationHandler#getMBeanServerConnection()
+     * getMBeanServerConnection()}, {@link
+     * MBeanServerInvocationHandler#getObjectName() getObjectName()}, and
+     * {@link MBeanServerInvocationHandler#getMBeanOptions() getMBeanOptions()}
+     * methods on {@code mbsih}.  You can retrieve {@code FooMBean.class}
+     * using {@code proxy.getClass().}{@link
+     * Class#getInterfaces() getInterfaces()}.</p>
+     *
      * @param connection the MBean server to forward to.
      * @param objectName the name of the MBean within
      * {@code connection} to forward to.
@@ -703,12 +746,12 @@
 
         InvocationHandler handler = new MBeanServerInvocationHandler(
                 connection, objectName, opts);
-        final Class[] interfaces;
+        final Class<?>[] interfaces;
         if (notificationEmitter) {
             interfaces =
                 new Class<?>[] {interfaceClass, NotificationEmitter.class};
         } else
-            interfaces = new Class[] {interfaceClass};
+            interfaces = new Class<?>[] {interfaceClass};
         Object proxy = Proxy.newProxyInstance(
                 interfaceClass.getClassLoader(),
                 interfaces,
--- a/jdk/src/share/classes/javax/management/MBeanAttributeInfo.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/javax/management/MBeanAttributeInfo.java	Wed Jul 05 16:43:41 2017 +0200
@@ -316,7 +316,7 @@
      */
     private static String attributeType(Method getter, Method setter)
             throws IntrospectionException {
-        Class type = null;
+        Class<?> type = null;
 
         if (getter != null) {
             if (getter.getParameterTypes().length != 0) {
@@ -330,7 +330,7 @@
         }
 
         if (setter != null) {
-            Class params[] = setter.getParameterTypes();
+            Class<?> params[] = setter.getParameterTypes();
             if (params.length != 1) {
                 throw new IntrospectionException("bad setter arg count");
             }
--- a/jdk/src/share/classes/javax/management/MBeanConstructorInfo.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/javax/management/MBeanConstructorInfo.java	Wed Jul 05 16:43:41 2017 +0200
@@ -64,7 +64,7 @@
      * @param constructor The <CODE>java.lang.reflect.Constructor</CODE>
      * object describing the MBean constructor.
      */
-    public MBeanConstructorInfo(String description, Constructor constructor) {
+    public MBeanConstructorInfo(String description, Constructor<?> constructor) {
         this(constructor.getName(), description,
              constructorSignature(constructor),
              Introspector.descriptorForElement(constructor));
@@ -210,8 +210,8 @@
         return hash;
     }
 
-    private static MBeanParameterInfo[] constructorSignature(Constructor cn) {
-        final Class[] classes = cn.getParameterTypes();
+    private static MBeanParameterInfo[] constructorSignature(Constructor<?> cn) {
+        final Class<?>[] classes = cn.getParameterTypes();
         final Annotation[][] annots = cn.getParameterAnnotations();
         return MBeanOperationInfo.parameters(classes, annots);
     }
--- a/jdk/src/share/classes/javax/management/MBeanInfo.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/javax/management/MBeanInfo.java	Wed Jul 05 16:43:41 2017 +0200
@@ -45,6 +45,17 @@
  * management operations.  Instances of this class are immutable.
  * Subclasses may be mutable but this is not recommended.</p>
  *
+ * <p id="info-changed">Usually the {@code MBeanInfo} for any given MBean does
+ * not change over the lifetime of that MBean.  Dynamic MBeans can change their
+ * {@code MBeanInfo} and in that case it is recommended that they emit a {@link
+ * Notification} with a {@linkplain Notification#getType() type} of {@code
+ * "jmx.mbean.info.changed"} and a {@linkplain Notification#getUserData()
+ * userData} that is the new {@code MBeanInfo}.  This is not required, but
+ * provides a conventional way for clients of the MBean to discover the change.
+ * See also the <a href="Descriptor.html#immutableInfo">immutableInfo</a> and
+ * <a href="Descriptor.html#infoTimeout">infoTimeout</a> fields in the {@code
+ * MBeanInfo} {@link Descriptor}.</p>
+ *
  * <p>The contents of the <code>MBeanInfo</code> for a Dynamic MBean
  * are determined by its {@link DynamicMBean#getMBeanInfo
  * getMBeanInfo()} method.  This includes Open MBeans and Model
@@ -62,27 +73,49 @@
  * constructors in that object;
  *
  * <li>{@link #getAttributes()} returns the list of all attributes
- * whose existence is deduced from the presence in the MBean interface
- * of a <code>get<i>Name</i></code>, <code>is<i>Name</i></code>, or
- * <code>set<i>Name</i></code> method that conforms to the conventions
+ * whose existence is deduced as follows:
+ * <ul>
+ * <li>if the Standard MBean is defined with an MBean interface,
+ * from <code>get<i>Name</i></code>, <code>is<i>Name</i></code>, or
+ * <code>set<i>Name</i></code> methods that conform to the conventions
  * for Standard MBeans;
+ * <li>if the Standard MBean is defined with the {@link MBean &#64;MBean} or
+ * {@link MXBean &#64;MXBean} annotation on a class, from methods with the
+ * {@link ManagedAttribute &#64;ManagedAttribute} annotation;
+ * </ul>
  *
- * <li>{@link #getOperations()} returns the list of all methods in
+ * <li>{@link #getOperations()} returns the list of all operations whose
+ * existence is deduced as follows:
+ * <ul>
+ * <li>if the Standard MBean is defined with an MBean interface, from methods in
  * the MBean interface that do not represent attributes;
+ * <li>if the Standard MBean is defined with the {@link MBean &#64;MBean} or
+ * {@link MXBean &#64;MXBean} annotation on a class, from methods with the
+ * {@link ManagedOperation &#64;ManagedOperation} annotation;
+ * </ul>
  *
- * <li>{@link #getNotifications()} returns an empty array if the MBean
- * does not implement the {@link NotificationBroadcaster} interface,
- * otherwise the result of calling {@link
+ * <li>{@link #getNotifications()} returns:
+ * <ul>
+ * <li>if the MBean implements the {@link NotificationBroadcaster} interface,
+ * the result of calling {@link
  * NotificationBroadcaster#getNotificationInfo()} on it;
+ * <li>otherwise, if there is a {@link NotificationInfo &#64;NotificationInfo}
+ * or {@link NotificationInfos &#64;NotificationInfos} annotation on the
+ * MBean interface or <code>&#64;MBean</code> or <code>&#64;MXBean</code>
+ * class, the array implied by those annotations;
+ * <li>otherwise an empty array;
+ * </ul>
  *
  * <li>{@link #getDescriptor()} returns a descriptor containing the contents
- * of any descriptor annotations in the MBean interface.
+ * of any descriptor annotations in the MBean interface (see
+ * {@link DescriptorFields &#64;DescriptorFields} and
+ * {@link DescriptorKey &#64;DescriptorKey}).
  *
  * </ul>
  *
  * <p>The description returned by {@link #getDescription()} and the
  * descriptions of the contained attributes and operations are determined
- * by the corresponding <!-- link here --> Description annotations if any;
+ * by the corresponding {@link Description} annotations if any;
  * otherwise their contents are not specified.</p>
  *
  * <p>The remaining details of the <code>MBeanInfo</code> for a
@@ -524,8 +557,8 @@
      * a WeakHashMap so that we don't prevent a class from being
      * garbage collected just because we know whether it's immutable.
      */
-    private static final Map<Class, Boolean> arrayGettersSafeMap =
-        new WeakHashMap<Class, Boolean>();
+    private static final Map<Class<?>, Boolean> arrayGettersSafeMap =
+        new WeakHashMap<Class<?>, Boolean>();
 
     /**
      * Return true if <code>subclass</code> is known to preserve the
@@ -537,7 +570,7 @@
      * This is obviously not an infallible test for immutability,
      * but it works for the public interfaces of the MBean*Info classes.
     */
-    static boolean arrayGettersSafe(Class subclass, Class immutableClass) {
+    static boolean arrayGettersSafe(Class<?> subclass, Class<?> immutableClass) {
         if (subclass == immutableClass)
             return true;
         synchronized (arrayGettersSafeMap) {
--- a/jdk/src/share/classes/javax/management/MBeanOperationInfo.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/javax/management/MBeanOperationInfo.java	Wed Jul 05 16:43:41 2017 +0200
@@ -308,17 +308,18 @@
        wrong should be less than the penalty we would pay if it were
        right and we needlessly hashed in the description and the
        parameter array.  */
+    @Override
     public int hashCode() {
         return getName().hashCode() ^ getReturnType().hashCode();
     }
 
     private static MBeanParameterInfo[] methodSignature(Method method) {
-        final Class[] classes = method.getParameterTypes();
+        final Class<?>[] classes = method.getParameterTypes();
         final Annotation[][] annots = method.getParameterAnnotations();
         return parameters(classes, annots);
     }
 
-    static MBeanParameterInfo[] parameters(Class[] classes,
+    static MBeanParameterInfo[] parameters(Class<?>[] classes,
                                            Annotation[][] annots) {
         final MBeanParameterInfo[] params =
             new MBeanParameterInfo[classes.length];
--- a/jdk/src/share/classes/javax/management/MBeanServer.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/javax/management/MBeanServer.java	Wed Jul 05 16:43:41 2017 +0200
@@ -377,19 +377,19 @@
      * MBean will not be registered.
      * @exception RuntimeMBeanException If the <CODE>postRegister</CODE>
      * (<CODE>MBeanRegistration</CODE> interface) method of the MBean throws a
-     * <CODE>RuntimeException</CODE>, the <CODE>registerMBean<CODE> method will
+     * <CODE>RuntimeException</CODE>, the <CODE>registerMBean</CODE> method will
      * throw a <CODE>RuntimeMBeanException</CODE>, although the MBean
      * registration succeeded. In such a case, the MBean will be actually
-     * registered even though the <CODE>registerMBean<CODE> method
+     * registered even though the <CODE>registerMBean</CODE> method
      * threw an exception.  Note that <CODE>RuntimeMBeanException</CODE> can
      * also be thrown by <CODE>preRegister</CODE>, in which case the MBean
      * will not be registered.
      * @exception RuntimeErrorException If the <CODE>postRegister</CODE>
      * (<CODE>MBeanRegistration</CODE> interface) method of the MBean throws an
-     * <CODE>Error</CODE>, the <CODE>registerMBean<CODE> method will
+     * <CODE>Error</CODE>, the <CODE>registerMBean</CODE> method will
      * throw a <CODE>RuntimeErrorException</CODE>, although the MBean
      * registration succeeded. In such a case, the MBean will be actually
-     * registered even though the <CODE>registerMBean<CODE> method
+     * registered even though the <CODE>registerMBean</CODE> method
      * threw an exception.  Note that <CODE>RuntimeErrorException</CODE> can
      * also be thrown by <CODE>preRegister</CODE>, in which case the MBean
      * will not be registered.
@@ -411,6 +411,8 @@
      * is sent as described <a href="#notif">above</a>.</p>
      *
      * @throws RuntimeOperationsException {@inheritDoc}
+     * @throws RuntimeMBeanException {@inheritDoc}
+     * @throws RuntimeErrorException {@inheritDoc}
      */
     public void unregisterMBean(ObjectName name)
             throws InstanceNotFoundException, MBeanRegistrationException;
--- a/jdk/src/share/classes/javax/management/MBeanServerConnection.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/javax/management/MBeanServerConnection.java	Wed Jul 05 16:43:41 2017 +0200
@@ -76,7 +76,9 @@
      * <CODE>preRegister</CODE> (<CODE>MBeanRegistration</CODE>
      * interface) method of the MBean has thrown an exception. The
      * MBean will not be registered.
-     * @exception RuntimeMBeanException If the <CODE>postRegister</CODE>
+     * @exception RuntimeMBeanException If the MBean's constructor or its
+     * {@code preRegister} or {@code postRegister} method threw
+     * a {@code RuntimeException}. If the <CODE>postRegister</CODE>
      * (<CODE>MBeanRegistration</CODE> interface) method of the MBean throws a
      * <CODE>RuntimeException</CODE>, the <CODE>createMBean</CODE> method will
      * throw a <CODE>RuntimeMBeanException</CODE>, although the MBean creation
@@ -148,7 +150,9 @@
      * <CODE>preRegister</CODE> (<CODE>MBeanRegistration</CODE>
      * interface) method of the MBean has thrown an exception. The
      * MBean will not be registered.
-     * @exception RuntimeMBeanException If the <CODE>postRegister</CODE>
+     * @exception RuntimeMBeanException If the MBean's constructor or its
+     * {@code preRegister} or {@code postRegister} method threw
+     * a {@code RuntimeException}. If the <CODE>postRegister</CODE>
      * (<CODE>MBeanRegistration</CODE> interface) method of the MBean throws a
      * <CODE>RuntimeException</CODE>, the <CODE>createMBean</CODE> method will
      * throw a <CODE>RuntimeMBeanException</CODE>, although the MBean creation
@@ -223,7 +227,9 @@
      * <CODE>preRegister</CODE> (<CODE>MBeanRegistration</CODE>
      * interface) method of the MBean has thrown an exception. The
      * MBean will not be registered.
-     * @exception RuntimeMBeanException If the <CODE>postRegister</CODE>
+     * @exception RuntimeMBeanException If the MBean's constructor or its
+     * {@code preRegister} or {@code postRegister} method threw
+     * a {@code RuntimeException}. If the <CODE>postRegister</CODE>
      * (<CODE>MBeanRegistration</CODE> interface) method of the MBean throws a
      * <CODE>RuntimeException</CODE>, the <CODE>createMBean</CODE> method will
      * throw a <CODE>RuntimeMBeanException</CODE>, although the MBean creation
@@ -295,7 +301,9 @@
      * <CODE>preRegister</CODE> (<CODE>MBeanRegistration</CODE>
      * interface) method of the MBean has thrown an exception. The
      * MBean will not be registered.
-     * @exception RuntimeMBeanException If the <CODE>postRegister</CODE>
+     * @exception RuntimeMBeanException The MBean's constructor or its
+     * {@code preRegister} or {@code postRegister} method threw
+     * a {@code RuntimeException}. If the <CODE>postRegister</CODE>
      * (<CODE>MBeanRegistration</CODE> interface) method of the MBean throws a
      * <CODE>RuntimeException</CODE>, the <CODE>createMBean</CODE> method will
      * throw a <CODE>RuntimeMBeanException</CODE>, although the MBean creation
--- a/jdk/src/share/classes/javax/management/MBeanServerFactory.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/javax/management/MBeanServerFactory.java	Wed Jul 05 16:43:41 2017 +0200
@@ -747,7 +747,7 @@
      * Load the builder class through the context class loader.
      * @param builderClassName The name of the builder class.
      **/
-    private static Class loadBuilderClass(String builderClassName)
+    private static Class<?> loadBuilderClass(String builderClassName)
     throws ClassNotFoundException {
         final ClassLoader loader =
                 Thread.currentThread().getContextClassLoader();
@@ -767,7 +767,7 @@
      * If any checked exception needs to be thrown, it is embedded in
      * a JMRuntimeException.
      **/
-    private static MBeanServerBuilder newBuilder(Class builderClass) {
+    private static MBeanServerBuilder newBuilder(Class<?> builderClass) {
         try {
             final Object abuilder = builderClass.newInstance();
             return (MBeanServerBuilder)abuilder;
@@ -792,7 +792,7 @@
             String builderClassName = AccessController.doPrivileged(act);
 
             try {
-                final Class newBuilderClass;
+                final Class<?> newBuilderClass;
                 if (builderClassName == null || builderClassName.length() == 0)
                     newBuilderClass = MBeanServerBuilder.class;
                 else
@@ -800,7 +800,7 @@
 
                 // Check whether a new builder needs to be created
                 if (builder != null) {
-                    final Class builderClass = builder.getClass();
+                    final Class<?> builderClass = builder.getClass();
                     if (newBuilderClass == builderClass)
                         return; // no need to create a new builder...
                 }
--- a/jdk/src/share/classes/javax/management/MBeanServerInvocationHandler.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/javax/management/MBeanServerInvocationHandler.java	Wed Jul 05 16:43:41 2017 +0200
@@ -253,12 +253,12 @@
                                          boolean notificationBroadcaster) {
         final InvocationHandler handler =
             new MBeanServerInvocationHandler(connection, objectName);
-        final Class[] interfaces;
+        final Class<?>[] interfaces;
         if (notificationBroadcaster) {
             interfaces =
-                new Class[] {interfaceClass, NotificationEmitter.class};
+                new Class<?>[] {interfaceClass, NotificationEmitter.class};
         } else
-            interfaces = new Class[] {interfaceClass};
+            interfaces = new Class<?>[] {interfaceClass};
 
         Object proxy =
             Proxy.newProxyInstance(interfaceClass.getClassLoader(),
@@ -269,7 +269,7 @@
 
     public Object invoke(Object proxy, Method method, Object[] args)
             throws Throwable {
-        final Class methodClass = method.getDeclaringClass();
+        final Class<?> methodClass = method.getDeclaringClass();
 
         if (methodClass.equals(NotificationBroadcaster.class)
             || methodClass.equals(NotificationEmitter.class))
@@ -285,8 +285,8 @@
                 return p.invoke(connection, objectName, method, args);
             } else {
                 final String methodName = method.getName();
-                final Class[] paramTypes = method.getParameterTypes();
-                final Class returnType = method.getReturnType();
+                final Class<?>[] paramTypes = method.getParameterTypes();
+                final Class<?> returnType = method.getReturnType();
 
                 /* Inexplicably, InvocationHandler specifies that args is null
                    when the method takes no arguments rather than a
@@ -361,7 +361,13 @@
                 if (p != null)
                     return p;
             }
-            p = new MXBeanProxy(mxbeanInterface, mappingFactory);
+            try {
+                p = new MXBeanProxy(mxbeanInterface, mappingFactory);
+            } catch (IllegalArgumentException e) {
+                String msg = "Cannot make MXBean proxy for " +
+                        mxbeanInterface.getName() + ": " + e.getMessage();
+                throw new IllegalArgumentException(msg, e.getCause());
+            }
             classToProxy.put(mxbeanInterface, new WeakReference<MXBeanProxy>(p));
             return p;
         }
@@ -452,7 +458,7 @@
             return true;
         if (methodName.equals("equals")
             && Arrays.equals(method.getParameterTypes(),
-                             new Class[] {Object.class})
+                             new Class<?>[] {Object.class})
             && isLocal(proxy, method))
             return true;
         return false;
--- a/jdk/src/share/classes/javax/management/NotificationListener.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/javax/management/NotificationListener.java	Wed Jul 05 16:43:41 2017 +0200
@@ -39,11 +39,10 @@
     * blocking its notification broadcaster.
     *
     * @param notification The notification.
-    * @param handback An opaque object which helps the listener to associate information
-    * regarding the MBean emitter. This object is passed to the MBean during the
-    * addListener call and resent, without modification, to the listener. The MBean object
-    * should not use or modify the object.
-    *
+    * @param handback An opaque object which helps the listener to associate
+    * information regarding the MBean emitter. This object is passed to the
+    * addNotificationListener call and resent, without modification, to the
+    * listener.
     */
-    public void handleNotification(Notification notification, Object handback) ;
+    public void handleNotification(Notification notification, Object handback);
 }
--- a/jdk/src/share/classes/javax/management/StandardMBean.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/javax/management/StandardMBean.java	Wed Jul 05 16:43:41 2017 +0200
@@ -689,7 +689,7 @@
                     getImplementationClass().getName());
         }
 
-        MBeanSupport msupport = mbean;
+        MBeanSupport<?> msupport = mbean;
         final MBeanInfo bi = msupport.getMBeanInfo();
         final Object impl = msupport.getWrappedObject();
 
@@ -1391,8 +1391,8 @@
      * garbage collected just because we know whether its MBeanInfo
      * is immutable.
      */
-    private static final Map<Class, Boolean> mbeanInfoSafeMap =
-        new WeakHashMap<Class, Boolean>();
+    private static final Map<Class<?>, Boolean> mbeanInfoSafeMap =
+        new WeakHashMap<Class<?>, Boolean>();
 
     /**
      * Return true if {@code subclass} is known to preserve the immutability
@@ -1438,9 +1438,9 @@
     private static class MBeanInfoSafeAction
             implements PrivilegedAction<Boolean> {
 
-        private final Class subclass;
+        private final Class<?> subclass;
 
-        MBeanInfoSafeAction(Class subclass) {
+        MBeanInfoSafeAction(Class<?> subclass) {
             this.subclass = subclass;
         }
 
@@ -1454,13 +1454,13 @@
             // Check for "MBeanInfo getCachedMBeanInfo()" method.
             //
             if (overrides(subclass, StandardMBean.class,
-                          "getCachedMBeanInfo", (Class[]) null))
+                          "getCachedMBeanInfo", (Class<?>[]) null))
                 return false;
 
             // Check for "MBeanInfo getMBeanInfo()" method.
             //
             if (overrides(subclass, StandardMBean.class,
-                          "getMBeanInfo", (Class[]) null))
+                          "getMBeanInfo", (Class<?>[]) null))
                 return false;
 
             // Check for "MBeanNotificationInfo[] getNotificationInfo()"
@@ -1473,7 +1473,7 @@
             //
             if (StandardEmitterMBean.class.isAssignableFrom(subclass))
                 if (overrides(subclass, StandardEmitterMBean.class,
-                              "getNotificationInfo", (Class[]) null))
+                              "getNotificationInfo", (Class<?>[]) null))
                     return false;
             return true;
         }
--- a/jdk/src/share/classes/javax/management/event/EventClient.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/javax/management/event/EventClient.java	Wed Jul 05 16:43:41 2017 +0200
@@ -117,12 +117,12 @@
     public static final String NONFATAL = "jmx.event.service.nonfatal";
 
     /**
-     * <p>A notification string type used by an {@code EventClient} object to
-     * inform a listener added by {@code #addEventClientListener} that it
-     * has detected that notifications have been lost.  The {@link
-     * Notification#getUserData() userData} of the notification is a Long which
-     * is an upper bound on the number of lost notifications that have just
-     * been detected.</p>
+     * <p>A notification string type used by an {@code EventClient} object
+     * to inform a listener added by {@link #addEventClientListener
+     * addEventClientListener} that it has detected that notifications have
+     * been lost.  The {@link Notification#getUserData() userData} of the
+     * notification is a Long which is an upper bound on the number of lost
+     * notifications that have just been detected.</p>
      *
      * @see #addEventClientListener
      */
@@ -577,8 +577,13 @@
     }
 
     /**
-     * Returns the set of listeners that have been added through
-     * this {@code EventClient} and not subsequently removed.
+     * <p>Returns the collection of listeners that have been added through
+     * this {@code EventClient} and not subsequently removed.  The returned
+     * collection contains one entry for every listener added with
+     * {@link #addNotificationListener addNotificationListener} or
+     * {@link #subscribe subscribe} and not subsequently removed with
+     * {@link #removeNotificationListener removeNotificationListener} or
+     * {@link #unsubscribe unsubscribe}, respectively.</p>
      *
      * @return A collection of listener information. Empty if there are no
      * current listeners or if this {@code EventClient} has been {@linkplain
@@ -927,8 +932,10 @@
     private final static MBeanNotificationInfo[] myInfo =
             new MBeanNotificationInfo[] {
         new MBeanNotificationInfo(
-                new String[] {FAILED, NOTIFS_LOST},
-                Notification.class.getName(), "")};
+                new String[] {FAILED, NONFATAL, NOTIFS_LOST},
+                Notification.class.getName(),
+                "Notifications that can be sent to a listener added with " +
+                "EventClient.addEventClientListener")};
 
     private final NotificationBroadcasterSupport broadcaster =
             new NotificationBroadcasterSupport();
--- a/jdk/src/share/classes/javax/management/event/EventClientDelegate.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/javax/management/event/EventClientDelegate.java	Wed Jul 05 16:43:41 2017 +0200
@@ -104,8 +104,8 @@
     public static EventClientDelegate getEventClientDelegate(MBeanServer server) {
         EventClientDelegate delegate = null;
         synchronized(delegateMap) {
-            final WeakReference wrf = delegateMap.get(server);
-            delegate = (wrf == null) ? null : (EventClientDelegate)wrf.get();
+            final WeakReference<EventClientDelegate> wrf = delegateMap.get(server);
+            delegate = (wrf == null) ? null : wrf.get();
 
             if (delegate == null) {
                 delegate = new EventClientDelegate(server);
@@ -282,7 +282,7 @@
             Constructor<?> foundCons = null;
             if (sig == null)
                 sig = new String[0];
-            for (Constructor cons : c.getConstructors()) {
+            for (Constructor<?> cons : c.getConstructors()) {
                 Class<?>[] types = cons.getParameterTypes();
                 String[] consSig = new String[types.length];
                 for (int i = 0; i < types.length; i++)
--- a/jdk/src/share/classes/javax/management/event/EventSubscriber.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/javax/management/event/EventSubscriber.java	Wed Jul 05 16:43:41 2017 +0200
@@ -350,8 +350,7 @@
     static {
         QueryExp broadcasterExp;
         try {
-            final Method m = Query.class.getMethod("isInstanceOf",
-                    new Class[] {String.class});
+            final Method m = Query.class.getMethod("isInstanceOf", String.class);
             broadcasterExp = (QueryExp)m.invoke(Query.class,
                     new Object[] {NotificationBroadcaster.class.getName()});
         } catch (Exception e) {
--- a/jdk/src/share/classes/javax/management/loading/DefaultLoaderRepository.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/javax/management/loading/DefaultLoaderRepository.java	Wed Jul 05 16:43:41 2017 +0200
@@ -69,7 +69,7 @@
      * @exception ClassNotFoundException The specified class could not be
      *            found.
      */
-    public static Class loadClass(String className)
+    public static Class<?> loadClass(String className)
         throws ClassNotFoundException {
         MBEANSERVER_LOGGER.logp(Level.FINEST,
                 DefaultLoaderRepository.class.getName(),
@@ -93,7 +93,7 @@
      * @exception ClassNotFoundException The specified class could not be
      *    found.
      */
-    public static Class loadClassWithout(ClassLoader loader,
+    public static Class<?> loadClassWithout(ClassLoader loader,
                                          String className)
         throws ClassNotFoundException {
         MBEANSERVER_LOGGER.logp(Level.FINEST,
@@ -102,12 +102,11 @@
         return load(loader, className);
     }
 
-    private static Class load(ClassLoader without, String className)
+    private static Class<?> load(ClassLoader without, String className)
             throws ClassNotFoundException {
-        final List mbsList = MBeanServerFactory.findMBeanServer(null);
+        final List<MBeanServer> mbsList = MBeanServerFactory.findMBeanServer(null);
 
-        for (Iterator it = mbsList.iterator(); it.hasNext(); ) {
-            MBeanServer mbs = (MBeanServer) it.next();
+        for (MBeanServer mbs : mbsList) {
             ClassLoaderRepository clr = mbs.getClassLoaderRepository();
             try {
                 return clr.loadClassWithout(without, className);
--- a/jdk/src/share/classes/javax/management/loading/MLet.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/javax/management/loading/MLet.java	Wed Jul 05 16:43:41 2017 +0200
@@ -1291,7 +1291,7 @@
          if (c != null) {
             try {
                 Constructor<?> cons =
-                    c.getConstructor(new Class[] {String.class});
+                    c.getConstructor(String.class);
                 Object[] oo = new Object[1];
                 oo[0]=param;
                 return(cons.newInstance(oo));
--- a/jdk/src/share/classes/javax/management/loading/MLetObjectInputStream.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/javax/management/loading/MLetObjectInputStream.java	Wed Jul 05 16:43:41 2017 +0200
@@ -55,30 +55,30 @@
         this.loader = loader;
     }
 
-    private Class primitiveType(char c) {
+    private Class<?> primitiveType(char c) {
         switch(c) {
-        case 66: /* 'B' */
+        case 'B':
             return Byte.TYPE;
 
-        case 67: /* 'C' */
+        case 'C':
             return Character.TYPE;
 
-        case 68: /* 'D' */
+        case 'D':
             return Double.TYPE;
 
-        case 70: /* 'F' */
+        case 'F':
             return Float.TYPE;
 
-        case 73: /* 'I' */
+        case 'I':
             return Integer.TYPE;
 
-        case 74: /* 'J' */
+        case 'J':
             return Long.TYPE;
 
-        case 83: /* 'S' */
+        case 'S':
             return Short.TYPE;
 
-        case 90: /* 'Z' */
+        case 'Z':
             return Boolean.TYPE;
         }
         return null;
@@ -87,14 +87,15 @@
     /**
      * Use the given ClassLoader rather than using the system class
      */
-    protected Class resolveClass(ObjectStreamClass objectstreamclass)
+    @Override
+    protected Class<?> resolveClass(ObjectStreamClass objectstreamclass)
         throws IOException, ClassNotFoundException {
 
         String s = objectstreamclass.getName();
         if (s.startsWith("[")) {
             int i;
             for (i = 1; s.charAt(i) == '['; i++);
-            Class class1;
+            Class<?> class1;
             if (s.charAt(i) == 'L') {
                 class1 = loader.loadClass(s.substring(i + 1, s.length() - 1));
             } else {
--- a/jdk/src/share/classes/javax/management/modelmbean/DescriptorSupport.java	Fri Nov 07 11:45:49 2008 -0800
+++ b/jdk/src/share/classes/javax/management/modelmbean/DescriptorSupport.java	Wed Jul 05 16:43:41 2017 +0200
@@ -589,7 +589,7 @@
         int numberOfEntries = descriptorMap.size();
 
         String[] responseFields = new String[numberOfEntries];
-        Set returnedSet = descriptorMap.entrySet();
+        Set<Map.Entry<String, Object>> returnedSet = descriptorMap.entrySet();
 
         int i = 0;
 
@@ -598,8 +598,9 @@
                     DescriptorSupport.class.getName(),
                     "getFields()", "Returning " + numberOfEntries + " fields");
         }
-        for (Iterator iter = returnedSet.iterator(); iter.hasNext(); i++) {
-            Map.Entry currElement = (Map.Entry) iter.next();
+        for (Iterator<Map.Entry<String, Object>> iter = returnedSet.iterator();
+             iter.hasNext(); i++) {