Merge
authorprr
Mon, 01 Jul 2019 14:57:02 -0700
changeset 57523 162f4f1c841c
parent 57522 af678f2593e2 (current diff)
parent 55539 734e58d8477b (diff)
child 57524 0e01b955bfd4
Merge
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GuardedIntrinsicTest.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/WriteBarrierVerificationTest.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/g1/G1ArrayRangePostWriteBarrier.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/g1/G1ArrayRangePreWriteBarrier.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/g1/G1BarrierSet.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/g1/G1PostWriteBarrier.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/g1/G1PreWriteBarrier.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/g1/G1ReferentFieldReadBarrier.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/shared/ArrayRangeWriteBarrier.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/shared/BarrierSet.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/shared/CardTableBarrierSet.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/shared/ObjectWriteBarrier.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/shared/SerialArrayRangeWriteBarrier.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/shared/SerialWriteBarrier.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/WriteBarrier.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/WriteBarrierAdditionPhase.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/WriteBarrierVerificationPhase.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/WriteBarrierSnippets.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/tiers/PhaseContext.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/Log.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/DirectStoreNode.java
test/hotspot/jtreg/compiler/codecache/stress/UnexpectedDeoptimizationAllTest.java
test/hotspot/jtreg/compiler/jvmci/compilerToVM/ResolveConstantInPoolTest.java
test/jdk/ProblemList.txt
test/jdk/sun/security/tools/keytool/PSS.java
--- a/.hgtags	Wed Jun 26 15:34:13 2019 -0700
+++ b/.hgtags	Mon Jul 01 14:57:02 2019 -0700
@@ -567,3 +567,5 @@
 2f4e214781a1d597ed36bf5a36f20928c6c82996 jdk-14+1
 0692b67f54621991ba7afbf23e55b788f3555e69 jdk-13+26
 43627549a488b7d0b4df8fad436e36233df89877 jdk-14+2
+b7f68ddec66f996ae3aad03291d129ca9f02482d jdk-13+27
+e64383344f144217c36196c3c8a2df8f588a2af3 jdk-14+3
--- a/make/common/FindTests.gmk	Wed Jun 26 15:34:13 2019 -0700
+++ b/make/common/FindTests.gmk	Mon Jul 01 14:57:02 2019 -0700
@@ -62,10 +62,8 @@
 
 # If this file is deemed outdated, it will automatically get regenerated
 # by this rule before being included below.
-#
-# When calling TestMake.gmk, override the log level to avoid any kind of debug
-# output being captured into the generated makefile.
-$(FIND_TESTS_CACHE_FILE): $(JTREG_ROOT_FILES) $(JTREG_GROUP_FILES)
+$(FIND_TESTS_CACHE_FILE): $(JTREG_ROOT_FILES) $(JTREG_GROUP_FILES) \
+    $(TOPDIR)/test/make/TestMake.gmk
 	$(call MakeTargetDir)
 	( $(foreach root, $(JTREG_TESTROOTS), \
 	    $(PRINTF) "\n$(root)_JTREG_TEST_GROUPS := " ; \
@@ -73,10 +71,11 @@
 	      $($(root)_JTREG_GROUP_FILES) \
 	      | $(SORT) -u | $(TR) '\n' ' ' ; \
 	  ) \
-	  $(PRINTF) "\nMAKE_TEST_TARGETS := " ; \
-	  $(MAKE) -s --no-print-directory $(MAKE_ARGS) LOG_LEVEL=warn \
-	      SPEC=$(SPEC) -f $(TOPDIR)/test/make/TestMake.gmk print-targets \
 	) > $@
+	$(PRINTF) "\nMAKE_TEST_TARGETS := " >> $@
+	$(MAKE) -s --no-print-directory $(MAKE_ARGS) \
+	    SPEC=$(SPEC) -f $(TOPDIR)/test/make/TestMake.gmk print-targets \
+	    TARGETS_FILE=$@
 
 -include $(FIND_TESTS_CACHE_FILE)
 
--- a/make/common/ProcessMarkdown.gmk	Wed Jun 26 15:34:13 2019 -0700
+++ b/make/common/ProcessMarkdown.gmk	Mon Jul 01 14:57:02 2019 -0700
@@ -103,7 +103,7 @@
 	$$(call LogInfo, Post-processing markdown file $2)
 	$$(call MakeDir, $$(SUPPORT_OUTPUTDIR)/markdown $$($1_$2_TARGET_DIR))
 	$$(call ExecuteWithLog, $$(SUPPORT_OUTPUTDIR)/markdown/$$($1_$2_MARKER)_post, \
-	    $$($1_POST_PROCESS) < $$($1_$2_PANDOC_OUTPUT) > $$($1_$2_OUTPUT_FILE))
+	    ( $$($1_POST_PROCESS) < $$($1_$2_PANDOC_OUTPUT) > $$($1_$2_OUTPUT_FILE) ) )
   endif
 
   $1 += $$($1_$2_OUTPUT_FILE)
--- a/src/hotspot/cpu/aarch64/aarch64.ad	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/cpu/aarch64/aarch64.ad	Mon Jul 01 14:57:02 2019 -0700
@@ -1761,6 +1761,17 @@
   // branch if we need to invalidate the method later
   __ nop();
 
+  if (C->clinit_barrier_on_entry()) {
+    assert(!C->method()->holder()->is_not_initialized(), "initialization should have been started");
+
+    Label L_skip_barrier;
+
+    __ mov_metadata(rscratch2, C->method()->holder()->constant_encoding());
+    __ clinit_barrier(rscratch2, rscratch1, &L_skip_barrier);
+    __ far_jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub()));
+    __ bind(L_skip_barrier);
+  }
+  
   int bangsize = C->bang_size_in_bytes();
   if (C->need_stack_bang(bangsize) && UseStackBanging)
     __ generate_stack_overflow_check(bangsize);
--- a/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -317,7 +317,15 @@
 }
 
 void LIR_Assembler::clinit_barrier(ciMethod* method) {
-  ShouldNotReachHere(); // not implemented
+  assert(VM_Version::supports_fast_class_init_checks(), "sanity");
+  assert(!method->holder()->is_not_initialized(), "initialization should have been started");
+
+  Label L_skip_barrier;
+
+  __ mov_metadata(rscratch2, method->holder()->constant_encoding());
+  __ clinit_barrier(rscratch2, rscratch1, &L_skip_barrier /*L_fast_path*/);
+  __ far_jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub()));
+  __ bind(L_skip_barrier);
 }
 
 void LIR_Assembler::jobject2reg(jobject o, Register reg) {
--- a/src/hotspot/cpu/aarch64/c1_MacroAssembler_aarch64.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/cpu/aarch64/c1_MacroAssembler_aarch64.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -331,11 +331,6 @@
 
 
 void C1_MacroAssembler::build_frame(int framesize, int bang_size_in_bytes) {
-  // If we have to make this method not-entrant we'll overwrite its
-  // first instruction with a jump.  For this action to be legal we
-  // must ensure that this first instruction is a B, BL, NOP, BKPT,
-  // SVC, HVC, or SMC.  Make it a NOP.
-  nop();
   assert(bang_size_in_bytes >= framesize, "stack bang size incorrect");
   // Make sure there is enough stack space for this method's activation.
   // Note that we do this before doing an enter().
@@ -355,6 +350,11 @@
 
 
 void C1_MacroAssembler::verified_entry() {
+  // If we have to make this method not-entrant we'll overwrite its
+  // first instruction with a jump.  For this action to be legal we
+  // must ensure that this first instruction is a B, BL, NOP, BKPT,
+  // SVC, HVC, or SMC.  Make it a NOP.
+  nop();
 }
 
 void C1_MacroAssembler::load_parameter(int offset_in_words, Register reg) {
--- a/src/hotspot/cpu/aarch64/gc/z/zBarrierSetAssembler_aarch64.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/cpu/aarch64/gc/z/zBarrierSetAssembler_aarch64.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -63,27 +63,25 @@
     return;
   }
 
-  // rscratch1 can be passed as src or dst, so don't use it.
-  RegSet savedRegs = RegSet::of(rscratch2, rheapbase);
+  assert_different_registers(rscratch1, rscratch2, src.base());
+  assert_different_registers(rscratch1, rscratch2, dst);
+
+  RegSet savedRegs = RegSet::range(r0,r28) - RegSet::of(dst, rscratch1, rscratch2);
 
   Label done;
-  assert_different_registers(rheapbase, rscratch2, dst);
-  assert_different_registers(rheapbase, rscratch2, src.base());
-
-  __ push(savedRegs, sp);
 
   // Load bad mask into scratch register.
-  __ ldr(rheapbase, address_bad_mask_from_thread(rthread));
+  __ ldr(rscratch1, address_bad_mask_from_thread(rthread));
   __ lea(rscratch2, src);
   __ ldr(dst, src);
 
   // Test reference against bad mask. If mask bad, then we need to fix it up.
-  __ tst(dst, rheapbase);
+  __ tst(dst, rscratch1);
   __ br(Assembler::EQ, done);
 
   __ enter();
 
-  __ push(RegSet::range(r0,r28) - RegSet::of(dst), sp);
+  __ push(savedRegs, sp);
 
   if (c_rarg0 != dst) {
     __ mov(c_rarg0, dst);
@@ -91,13 +89,15 @@
   __ mov(c_rarg1, rscratch2);
 
   int step = 4 * wordSize;
-  __ mov(rscratch1, -step);
+  __ mov(rscratch2, -step);
   __ sub(sp, sp, step);
 
   for (int i = 28; i >= 4; i -= 4) {
     __ st1(as_FloatRegister(i), as_FloatRegister(i+1), as_FloatRegister(i+2),
-        as_FloatRegister(i+3), __ T1D, Address(__ post(sp, rscratch1)));
+        as_FloatRegister(i+3), __ T1D, Address(__ post(sp, rscratch2)));
   }
+  __ st1(as_FloatRegister(0), as_FloatRegister(1), as_FloatRegister(2),
+      as_FloatRegister(3), __ T1D, Address(sp));
 
   __ call_VM_leaf(ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded_addr(decorators), 2);
 
@@ -111,13 +111,10 @@
     __ mov(dst, r0);
   }
 
-  __ pop(RegSet::range(r0,r28) - RegSet::of(dst), sp);
+  __ pop(savedRegs, sp);
   __ leave();
 
   __ bind(done);
-
-  // Restore tmps
-  __ pop(savedRegs, sp);
 }
 
 #ifdef ASSERT
--- a/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -288,6 +288,18 @@
   ldr(klass, Address(klass, Array<Klass*>::base_offset_in_bytes()));
 }
 
+void InterpreterMacroAssembler::load_resolved_method_at_index(int byte_no,
+                                                              Register method,
+                                                              Register cache) {
+  const int method_offset = in_bytes(
+    ConstantPoolCache::base_offset() +
+      ((byte_no == TemplateTable::f2_byte)
+       ? ConstantPoolCacheEntry::f2_offset()
+       : ConstantPoolCacheEntry::f1_offset()));
+
+  ldr(method, Address(cache, method_offset)); // get f1 Method*
+}
+
 // Generate a subtype check: branch to ok_is_subtype if sub_klass is a
 // subtype of super_klass.
 //
--- a/src/hotspot/cpu/aarch64/interp_masm_aarch64.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/cpu/aarch64/interp_masm_aarch64.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -124,6 +124,8 @@
   // load cpool->resolved_klass_at(index);
   void load_resolved_klass_at_offset(Register cpool, Register index, Register klass, Register temp);
 
+  void load_resolved_method_at_index(int byte_no, Register method, Register cache);
+
   void pop_ptr(Register r = r0);
   void pop_i(Register r = r0);
   void pop_l(Register r = r0);
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -1307,6 +1307,35 @@
   bind(L_fallthrough);
 }
 
+void MacroAssembler::clinit_barrier(Register klass, Register scratch, Label* L_fast_path, Label* L_slow_path) {
+  assert(L_fast_path != NULL || L_slow_path != NULL, "at least one is required");
+  assert_different_registers(klass, rthread, scratch);
+
+  Label L_fallthrough, L_tmp;
+  if (L_fast_path == NULL) {
+    L_fast_path = &L_fallthrough;
+  } else if (L_slow_path == NULL) {
+    L_slow_path = &L_fallthrough;
+  }
+  // Fast path check: class is fully initialized
+  ldrb(scratch, Address(klass, InstanceKlass::init_state_offset()));
+  subs(zr, scratch, InstanceKlass::fully_initialized);
+  br(Assembler::EQ, *L_fast_path);
+
+  // Fast path check: current thread is initializer thread
+  ldr(scratch, Address(klass, InstanceKlass::init_thread_offset()));
+  cmp(rthread, scratch);
+
+  if (L_slow_path == &L_fallthrough) {
+    br(Assembler::EQ, *L_fast_path);
+    bind(*L_slow_path);
+  } else if (L_fast_path == &L_fallthrough) {
+    br(Assembler::NE, *L_slow_path);
+    bind(*L_fast_path);
+  } else {
+    Unimplemented();
+  }
+}
 
 void MacroAssembler::verify_oop(Register reg, const char* s) {
   if (!VerifyOops) return;
@@ -3683,6 +3712,12 @@
   bs->obj_equals(this, obj1, obj2);
 }
 
+void MacroAssembler::load_method_holder(Register holder, Register method) {
+  ldr(holder, Address(method, Method::const_offset()));                      // ConstMethod*
+  ldr(holder, Address(holder, ConstMethod::constants_offset()));             // ConstantPool*
+  ldr(holder, Address(holder, ConstantPool::pool_holder_offset_in_bytes())); // InstanceKlass*
+}
+
 void MacroAssembler::load_klass(Register dst, Register src) {
   if (UseCompressedClassPointers) {
     ldrw(dst, Address(src, oopDesc::klass_offset_in_bytes()));
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -788,6 +788,8 @@
   // C 'boolean' to Java boolean: x == 0 ? 0 : 1
   void c2bool(Register x);
 
+  void load_method_holder(Register holder, Register method);
+
   // oop manipulations
   void load_klass(Register dst, Register src);
   void store_klass(Register dst, Register src);
@@ -926,6 +928,11 @@
                            Register temp_reg,
                            Label& L_success);
 
+  void clinit_barrier(Register klass,
+                      Register thread,
+                      Label* L_fast_path = NULL,
+                      Label* L_slow_path = NULL);
+
   Address argument_address(RegisterOrConstant arg_slot, int extra_slot_offset = 0);
 
 
--- a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -799,6 +799,22 @@
   }
 #endif
 
+  // Class initialization barrier for static methods
+  if (VM_Version::supports_fast_class_init_checks()) {
+    Label L_skip_barrier;
+
+    { // Bypass the barrier for non-static methods
+      __ ldrw(rscratch1, Address(rmethod, Method::access_flags_offset()));
+      __ andsw(zr, rscratch1, JVM_ACC_STATIC);
+      __ br(Assembler::EQ, L_skip_barrier); // non-static
+    }
+
+    __ load_method_holder(rscratch2, rmethod);
+    __ clinit_barrier(rscratch2, rscratch1, &L_skip_barrier);
+    __ far_jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub()));
+    __ bind(L_skip_barrier);
+  }
+
   gen_c2i_adapter(masm, total_args_passed, comp_args_on_stack, sig_bt, regs, skip_fixup);
 
   __ flush();
@@ -1580,6 +1596,15 @@
   // SVC, HVC, or SMC.  Make it a NOP.
   __ nop();
 
+  if (VM_Version::supports_fast_class_init_checks() && method->needs_clinit_barrier()) {
+    Label L_skip_barrier;
+    __ mov_metadata(rscratch2, method->method_holder()); // InstanceKlass*
+    __ clinit_barrier(rscratch2, rscratch1, &L_skip_barrier);
+    __ far_jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub()));
+
+    __ bind(L_skip_barrier);
+  }
+
   // Generate stack overflow check
   if (UseStackBanging) {
     __ bang_stack_with_offset(JavaThread::stack_shadow_zone_size());
--- a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -1383,7 +1383,12 @@
       // save regs before copy_memory
       __ push(RegSet::of(d, count), sp);
     }
-    copy_memory(aligned, s, d, count, rscratch1, size);
+    {
+      // UnsafeCopyMemory page error: continue after ucm
+      bool add_entry = !is_oop && (!aligned || sizeof(jlong) == size);
+      UnsafeCopyMemoryMark ucmm(this, add_entry, true);
+      copy_memory(aligned, s, d, count, rscratch1, size);
+    }
 
     if (is_oop) {
       __ pop(RegSet::of(d, count), sp);
@@ -1455,7 +1460,12 @@
       // save regs before copy_memory
       __ push(RegSet::of(d, count), sp);
     }
-    copy_memory(aligned, s, d, count, rscratch1, -size);
+    {
+      // UnsafeCopyMemory page error: continue after ucm
+      bool add_entry = !is_oop && (!aligned || sizeof(jlong) == size);
+      UnsafeCopyMemoryMark ucmm(this, add_entry, true);
+      copy_memory(aligned, s, d, count, rscratch1, -size);
+    }
     if (is_oop) {
       __ pop(RegSet::of(d, count), sp);
       if (VerifyOops)
@@ -5816,6 +5826,10 @@
   }
 }; // end class declaration
 
+#define UCM_TABLE_MAX_ENTRIES 8
 void StubGenerator_generate(CodeBuffer* code, bool all) {
+  if (UnsafeCopyMemory::_table == NULL) {
+    UnsafeCopyMemory::create_table(UCM_TABLE_MAX_ENTRIES);
+  }
   StubGenerator g(code, all);
 }
--- a/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -886,8 +886,8 @@
   }
 
   // Get mirror and store it in the frame as GC root for this Method*
-  __ load_mirror(rscratch1, rmethod);
-  __ stp(rscratch1, zr, Address(sp, 4 * wordSize));
+  __ load_mirror(r10, rmethod);
+  __ stp(r10, zr, Address(sp, 4 * wordSize));
 
   __ ldr(rcpool, Address(rmethod, Method::const_offset()));
   __ ldr(rcpool, Address(rcpool, ConstMethod::constants_offset()));
--- a/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -2323,7 +2323,7 @@
   const Register temp = r19;
   assert_different_registers(Rcache, index, temp);
 
-  Label resolved;
+  Label resolved, clinit_barrier_slow;
 
   Bytecodes::Code code = bytecode();
   switch (code) {
@@ -2338,6 +2338,8 @@
   __ br(Assembler::EQ, resolved);
 
   // resolve first time through
+  // Class initialization barrier slow path lands here as well.
+  __ bind(clinit_barrier_slow);
   address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_from_cache);
   __ mov(temp, (int) code);
   __ call_VM(noreg, entry, temp);
@@ -2347,6 +2349,13 @@
   // n.b. unlike x86 Rcache is now rcpool plus the indexed offset
   // so all clients ofthis method must be modified accordingly
   __ bind(resolved);
+
+  // Class initialization barrier for static methods
+  if (VM_Version::supports_fast_class_init_checks() && bytecode() == Bytecodes::_invokestatic) {
+    __ load_resolved_method_at_index(byte_no, temp, Rcache);
+    __ load_method_holder(temp, temp);
+    __ clinit_barrier(temp, rscratch1, NULL, &clinit_barrier_slow);
+  }
 }
 
 // The Rcache and index registers must be set before call
@@ -3418,9 +3427,8 @@
   __ profile_virtual_call(r3, r13, r19);
 
   // Get declaring interface class from method, and itable index
-  __ ldr(r0, Address(rmethod, Method::const_offset()));
-  __ ldr(r0, Address(r0, ConstMethod::constants_offset()));
-  __ ldr(r0, Address(r0, ConstantPool::pool_holder_offset_in_bytes()));
+
+  __ load_method_holder(r0, rmethod);
   __ ldrw(rmethod, Address(rmethod, Method::itable_index_offset()));
   __ subw(rmethod, rmethod, Method::itable_index_max);
   __ negw(rmethod, rmethod);
--- a/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -124,6 +124,7 @@
   static int dcache_line_size() {
     return (1 << ((_psr_info.ctr_el0 >> 16) & 0x0f)) * 4;
   }
+  static bool supports_fast_class_init_checks() { return true; }
 };
 
 #endif // CPU_AARCH64_VM_VERSION_AARCH64_HPP
--- a/src/hotspot/cpu/arm/stubGenerator_arm.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/cpu/arm/stubGenerator_arm.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -928,7 +928,7 @@
   // Scratches 'count', R3.
   // R4-R10 are preserved (saved/restored).
   //
-  int generate_forward_aligned_copy_loop(Register from, Register to, Register count, int bytes_per_count) {
+  int generate_forward_aligned_copy_loop(Register from, Register to, Register count, int bytes_per_count, bool unsafe_copy = false) {
     assert (from == R0 && to == R1 && count == R2, "adjust the implementation below");
 
     const int bytes_per_loop = 8*wordSize; // 8 registers are read and written on every loop iteration
@@ -954,107 +954,111 @@
 
     Label L_skip_pld;
 
-    // predecrease to exit when there is less than count_per_loop
-    __ sub_32(count, count, count_per_loop);
-
-    if (pld_offset != 0) {
-      pld_offset = (pld_offset < 0) ? -pld_offset : pld_offset;
-
-      prefetch(from, to, 0);
-
-      if (prefetch_before) {
-        // If prefetch is done ahead, final PLDs that overflow the
-        // copied area can be easily avoided. 'count' is predecreased
-        // by the prefetch distance to optimize the inner loop and the
-        // outer loop skips the PLD.
-        __ subs_32(count, count, (bytes_per_loop+pld_offset)/bytes_per_count);
-
-        // skip prefetch for small copies
-        __ b(L_skip_pld, lt);
-      }
-
-      int offset = ArmCopyCacheLineSize;
-      while (offset <= pld_offset) {
-        prefetch(from, to, offset);
-        offset += ArmCopyCacheLineSize;
-      };
-    }
-
     {
-      // 32-bit ARM note: we have tried implementing loop unrolling to skip one
-      // PLD with 64 bytes cache line but the gain was not significant.
-
-      Label L_copy_loop;
-      __ align(OptoLoopAlignment);
-      __ BIND(L_copy_loop);
-
-      if (prefetch_before) {
-        prefetch(from, to, bytes_per_loop + pld_offset);
-        __ BIND(L_skip_pld);
-      }
-
-      if (split_read) {
-        // Split the register set in two sets so that there is less
-        // latency between LDM and STM (R3-R6 available while R7-R10
-        // still loading) and less register locking issue when iterating
-        // on the first LDM.
-        __ ldmia(from, RegisterSet(R3, R6), writeback);
-        __ ldmia(from, RegisterSet(R7, R10), writeback);
-      } else {
-        __ ldmia(from, RegisterSet(R3, R10), writeback);
+      // UnsafeCopyMemory page error: continue after ucm
+      UnsafeCopyMemoryMark ucmm(this, unsafe_copy, true);
+      // predecrease to exit when there is less than count_per_loop
+      __ sub_32(count, count, count_per_loop);
+
+      if (pld_offset != 0) {
+        pld_offset = (pld_offset < 0) ? -pld_offset : pld_offset;
+
+        prefetch(from, to, 0);
+
+        if (prefetch_before) {
+          // If prefetch is done ahead, final PLDs that overflow the
+          // copied area can be easily avoided. 'count' is predecreased
+          // by the prefetch distance to optimize the inner loop and the
+          // outer loop skips the PLD.
+          __ subs_32(count, count, (bytes_per_loop+pld_offset)/bytes_per_count);
+
+          // skip prefetch for small copies
+          __ b(L_skip_pld, lt);
+        }
+
+        int offset = ArmCopyCacheLineSize;
+        while (offset <= pld_offset) {
+          prefetch(from, to, offset);
+          offset += ArmCopyCacheLineSize;
+        };
       }
 
-      __ subs_32(count, count, count_per_loop);
-
-      if (prefetch_after) {
-        prefetch(from, to, pld_offset, bytes_per_loop);
-      }
-
-      if (split_write) {
-        __ stmia(to, RegisterSet(R3, R6), writeback);
-        __ stmia(to, RegisterSet(R7, R10), writeback);
-      } else {
-        __ stmia(to, RegisterSet(R3, R10), writeback);
-      }
-
-      __ b(L_copy_loop, ge);
-
-      if (prefetch_before) {
-        // the inner loop may end earlier, allowing to skip PLD for the last iterations
-        __ cmn_32(count, (bytes_per_loop + pld_offset)/bytes_per_count);
-        __ b(L_skip_pld, ge);
+      {
+        // 32-bit ARM note: we have tried implementing loop unrolling to skip one
+        // PLD with 64 bytes cache line but the gain was not significant.
+
+        Label L_copy_loop;
+        __ align(OptoLoopAlignment);
+        __ BIND(L_copy_loop);
+
+        if (prefetch_before) {
+          prefetch(from, to, bytes_per_loop + pld_offset);
+          __ BIND(L_skip_pld);
+        }
+
+        if (split_read) {
+          // Split the register set in two sets so that there is less
+          // latency between LDM and STM (R3-R6 available while R7-R10
+          // still loading) and less register locking issue when iterating
+          // on the first LDM.
+          __ ldmia(from, RegisterSet(R3, R6), writeback);
+          __ ldmia(from, RegisterSet(R7, R10), writeback);
+        } else {
+          __ ldmia(from, RegisterSet(R3, R10), writeback);
+        }
+
+        __ subs_32(count, count, count_per_loop);
+
+        if (prefetch_after) {
+          prefetch(from, to, pld_offset, bytes_per_loop);
+        }
+
+        if (split_write) {
+          __ stmia(to, RegisterSet(R3, R6), writeback);
+          __ stmia(to, RegisterSet(R7, R10), writeback);
+        } else {
+          __ stmia(to, RegisterSet(R3, R10), writeback);
+        }
+
+        __ b(L_copy_loop, ge);
+
+        if (prefetch_before) {
+          // the inner loop may end earlier, allowing to skip PLD for the last iterations
+          __ cmn_32(count, (bytes_per_loop + pld_offset)/bytes_per_count);
+          __ b(L_skip_pld, ge);
+        }
       }
-    }
-    BLOCK_COMMENT("Remaining bytes:");
-    // still 0..bytes_per_loop-1 aligned bytes to copy, count already decreased by (at least) bytes_per_loop bytes
-
-    // __ add(count, count, ...); // addition useless for the bit tests
-    assert (pld_offset % bytes_per_loop == 0, "decreasing count by pld_offset before loop must not change tested bits");
-
-    __ tst(count, 16 / bytes_per_count);
-    __ ldmia(from, RegisterSet(R3, R6), writeback, ne); // copy 16 bytes
-    __ stmia(to, RegisterSet(R3, R6), writeback, ne);
-
-    __ tst(count, 8 / bytes_per_count);
-    __ ldmia(from, RegisterSet(R3, R4), writeback, ne); // copy 8 bytes
-    __ stmia(to, RegisterSet(R3, R4), writeback, ne);
-
-    if (bytes_per_count <= 4) {
-      __ tst(count, 4 / bytes_per_count);
-      __ ldr(R3, Address(from, 4, post_indexed), ne); // copy 4 bytes
-      __ str(R3, Address(to, 4, post_indexed), ne);
-    }
-
-    if (bytes_per_count <= 2) {
-      __ tst(count, 2 / bytes_per_count);
-      __ ldrh(R3, Address(from, 2, post_indexed), ne); // copy 2 bytes
-      __ strh(R3, Address(to, 2, post_indexed), ne);
-    }
-
-    if (bytes_per_count == 1) {
-      __ tst(count, 1);
-      __ ldrb(R3, Address(from, 1, post_indexed), ne);
-      __ strb(R3, Address(to, 1, post_indexed), ne);
+      BLOCK_COMMENT("Remaining bytes:");
+      // still 0..bytes_per_loop-1 aligned bytes to copy, count already decreased by (at least) bytes_per_loop bytes
+
+      // __ add(count, count, ...); // addition useless for the bit tests
+      assert (pld_offset % bytes_per_loop == 0, "decreasing count by pld_offset before loop must not change tested bits");
+
+      __ tst(count, 16 / bytes_per_count);
+      __ ldmia(from, RegisterSet(R3, R6), writeback, ne); // copy 16 bytes
+      __ stmia(to, RegisterSet(R3, R6), writeback, ne);
+
+      __ tst(count, 8 / bytes_per_count);
+      __ ldmia(from, RegisterSet(R3, R4), writeback, ne); // copy 8 bytes
+      __ stmia(to, RegisterSet(R3, R4), writeback, ne);
+
+      if (bytes_per_count <= 4) {
+        __ tst(count, 4 / bytes_per_count);
+        __ ldr(R3, Address(from, 4, post_indexed), ne); // copy 4 bytes
+        __ str(R3, Address(to, 4, post_indexed), ne);
+      }
+
+      if (bytes_per_count <= 2) {
+        __ tst(count, 2 / bytes_per_count);
+        __ ldrh(R3, Address(from, 2, post_indexed), ne); // copy 2 bytes
+        __ strh(R3, Address(to, 2, post_indexed), ne);
+      }
+
+      if (bytes_per_count == 1) {
+        __ tst(count, 1);
+        __ ldrb(R3, Address(from, 1, post_indexed), ne);
+        __ strb(R3, Address(to, 1, post_indexed), ne);
+      }
     }
 
     __ pop(RegisterSet(R4,R10));
@@ -1083,7 +1087,7 @@
   // Scratches 'count', R3.
   // ARM R4-R10 are preserved (saved/restored).
   //
-  int generate_backward_aligned_copy_loop(Register end_from, Register end_to, Register count, int bytes_per_count) {
+  int generate_backward_aligned_copy_loop(Register end_from, Register end_to, Register count, int bytes_per_count, bool unsafe_copy = false) {
     assert (end_from == R0 && end_to == R1 && count == R2, "adjust the implementation below");
 
     const int bytes_per_loop = 8*wordSize; // 8 registers are read and written on every loop iteration
@@ -1099,102 +1103,105 @@
 
     __ push(RegisterSet(R4,R10));
 
-    __ sub_32(count, count, count_per_loop);
-
-    const bool prefetch_before = pld_offset < 0;
-    const bool prefetch_after = pld_offset > 0;
-
-    Label L_skip_pld;
-
-    if (pld_offset != 0) {
-      pld_offset = (pld_offset < 0) ? -pld_offset : pld_offset;
-
-      prefetch(end_from, end_to, -wordSize);
-
-      if (prefetch_before) {
-        __ subs_32(count, count, (bytes_per_loop + pld_offset) / bytes_per_count);
-        __ b(L_skip_pld, lt);
+    {
+      // UnsafeCopyMemory page error: continue after ucm
+      UnsafeCopyMemoryMark ucmm(this, unsafe_copy, true);
+      __ sub_32(count, count, count_per_loop);
+
+      const bool prefetch_before = pld_offset < 0;
+      const bool prefetch_after = pld_offset > 0;
+
+      Label L_skip_pld;
+
+      if (pld_offset != 0) {
+        pld_offset = (pld_offset < 0) ? -pld_offset : pld_offset;
+
+        prefetch(end_from, end_to, -wordSize);
+
+        if (prefetch_before) {
+          __ subs_32(count, count, (bytes_per_loop + pld_offset) / bytes_per_count);
+          __ b(L_skip_pld, lt);
+        }
+
+        int offset = ArmCopyCacheLineSize;
+        while (offset <= pld_offset) {
+          prefetch(end_from, end_to, -(wordSize + offset));
+          offset += ArmCopyCacheLineSize;
+        };
       }
 
-      int offset = ArmCopyCacheLineSize;
-      while (offset <= pld_offset) {
-        prefetch(end_from, end_to, -(wordSize + offset));
-        offset += ArmCopyCacheLineSize;
-      };
-    }
-
-    {
-      // 32-bit ARM note: we have tried implementing loop unrolling to skip one
-      // PLD with 64 bytes cache line but the gain was not significant.
-
-      Label L_copy_loop;
-      __ align(OptoLoopAlignment);
-      __ BIND(L_copy_loop);
-
-      if (prefetch_before) {
-        prefetch(end_from, end_to, -(wordSize + bytes_per_loop + pld_offset));
-        __ BIND(L_skip_pld);
+      {
+        // 32-bit ARM note: we have tried implementing loop unrolling to skip one
+        // PLD with 64 bytes cache line but the gain was not significant.
+
+        Label L_copy_loop;
+        __ align(OptoLoopAlignment);
+        __ BIND(L_copy_loop);
+
+        if (prefetch_before) {
+          prefetch(end_from, end_to, -(wordSize + bytes_per_loop + pld_offset));
+          __ BIND(L_skip_pld);
+        }
+
+        if (split_read) {
+          __ ldmdb(end_from, RegisterSet(R7, R10), writeback);
+          __ ldmdb(end_from, RegisterSet(R3, R6), writeback);
+        } else {
+          __ ldmdb(end_from, RegisterSet(R3, R10), writeback);
+        }
+
+        __ subs_32(count, count, count_per_loop);
+
+        if (prefetch_after) {
+          prefetch(end_from, end_to, -(wordSize + pld_offset), -bytes_per_loop);
+        }
+
+        if (split_write) {
+          __ stmdb(end_to, RegisterSet(R7, R10), writeback);
+          __ stmdb(end_to, RegisterSet(R3, R6), writeback);
+        } else {
+          __ stmdb(end_to, RegisterSet(R3, R10), writeback);
+        }
+
+        __ b(L_copy_loop, ge);
+
+        if (prefetch_before) {
+          __ cmn_32(count, (bytes_per_loop + pld_offset)/bytes_per_count);
+          __ b(L_skip_pld, ge);
+        }
       }
-
-      if (split_read) {
-        __ ldmdb(end_from, RegisterSet(R7, R10), writeback);
-        __ ldmdb(end_from, RegisterSet(R3, R6), writeback);
-      } else {
-        __ ldmdb(end_from, RegisterSet(R3, R10), writeback);
-      }
-
-      __ subs_32(count, count, count_per_loop);
-
-      if (prefetch_after) {
-        prefetch(end_from, end_to, -(wordSize + pld_offset), -bytes_per_loop);
+      BLOCK_COMMENT("Remaining bytes:");
+      // still 0..bytes_per_loop-1 aligned bytes to copy, count already decreased by (at least) bytes_per_loop bytes
+
+      // __ add(count, count, ...); // addition useless for the bit tests
+      assert (pld_offset % bytes_per_loop == 0, "decreasing count by pld_offset before loop must not change tested bits");
+
+      __ tst(count, 16 / bytes_per_count);
+      __ ldmdb(end_from, RegisterSet(R3, R6), writeback, ne); // copy 16 bytes
+      __ stmdb(end_to, RegisterSet(R3, R6), writeback, ne);
+
+      __ tst(count, 8 / bytes_per_count);
+      __ ldmdb(end_from, RegisterSet(R3, R4), writeback, ne); // copy 8 bytes
+      __ stmdb(end_to, RegisterSet(R3, R4), writeback, ne);
+
+      if (bytes_per_count <= 4) {
+        __ tst(count, 4 / bytes_per_count);
+        __ ldr(R3, Address(end_from, -4, pre_indexed), ne); // copy 4 bytes
+        __ str(R3, Address(end_to, -4, pre_indexed), ne);
       }
 
-      if (split_write) {
-        __ stmdb(end_to, RegisterSet(R7, R10), writeback);
-        __ stmdb(end_to, RegisterSet(R3, R6), writeback);
-      } else {
-        __ stmdb(end_to, RegisterSet(R3, R10), writeback);
+      if (bytes_per_count <= 2) {
+        __ tst(count, 2 / bytes_per_count);
+        __ ldrh(R3, Address(end_from, -2, pre_indexed), ne); // copy 2 bytes
+        __ strh(R3, Address(end_to, -2, pre_indexed), ne);
       }
 
-      __ b(L_copy_loop, ge);
-
-      if (prefetch_before) {
-        __ cmn_32(count, (bytes_per_loop + pld_offset)/bytes_per_count);
-        __ b(L_skip_pld, ge);
+      if (bytes_per_count == 1) {
+        __ tst(count, 1);
+        __ ldrb(R3, Address(end_from, -1, pre_indexed), ne);
+        __ strb(R3, Address(end_to, -1, pre_indexed), ne);
       }
     }
-    BLOCK_COMMENT("Remaining bytes:");
-    // still 0..bytes_per_loop-1 aligned bytes to copy, count already decreased by (at least) bytes_per_loop bytes
-
-    // __ add(count, count, ...); // addition useless for the bit tests
-    assert (pld_offset % bytes_per_loop == 0, "decreasing count by pld_offset before loop must not change tested bits");
-
-    __ tst(count, 16 / bytes_per_count);
-    __ ldmdb(end_from, RegisterSet(R3, R6), writeback, ne); // copy 16 bytes
-    __ stmdb(end_to, RegisterSet(R3, R6), writeback, ne);
-
-    __ tst(count, 8 / bytes_per_count);
-    __ ldmdb(end_from, RegisterSet(R3, R4), writeback, ne); // copy 8 bytes
-    __ stmdb(end_to, RegisterSet(R3, R4), writeback, ne);
-
-    if (bytes_per_count <= 4) {
-      __ tst(count, 4 / bytes_per_count);
-      __ ldr(R3, Address(end_from, -4, pre_indexed), ne); // copy 4 bytes
-      __ str(R3, Address(end_to, -4, pre_indexed), ne);
-    }
-
-    if (bytes_per_count <= 2) {
-      __ tst(count, 2 / bytes_per_count);
-      __ ldrh(R3, Address(end_from, -2, pre_indexed), ne); // copy 2 bytes
-      __ strh(R3, Address(end_to, -2, pre_indexed), ne);
-    }
-
-    if (bytes_per_count == 1) {
-      __ tst(count, 1);
-      __ ldrb(R3, Address(end_from, -1, pre_indexed), ne);
-      __ strb(R3, Address(end_to, -1, pre_indexed), ne);
-    }
-
     __ pop(RegisterSet(R4,R10));
 
     return count_per_loop;
@@ -1749,17 +1756,21 @@
   //
   // Notes:
   //     shifts 'from' and 'to'
-  void copy_small_array(Register from, Register to, Register count, Register tmp, Register tmp2, int bytes_per_count, bool forward, Label & entry) {
+  void copy_small_array(Register from, Register to, Register count, Register tmp, Register tmp2, int bytes_per_count, bool forward, Label & entry, bool unsafe_copy = false) {
     assert_different_registers(from, to, count, tmp);
 
-    __ align(OptoLoopAlignment);
-    Label L_small_loop;
-    __ BIND(L_small_loop);
-    store_one(tmp, to, bytes_per_count, forward, al, tmp2);
-    __ BIND(entry); // entry point
-    __ subs(count, count, 1);
-    load_one(tmp, from, bytes_per_count, forward, ge, tmp2);
-    __ b(L_small_loop, ge);
+    {
+      // UnsafeCopyMemory page error: continue after ucm
+      UnsafeCopyMemoryMark ucmm(this, unsafe_copy, true);
+      __ align(OptoLoopAlignment);
+      Label L_small_loop;
+      __ BIND(L_small_loop);
+      store_one(tmp, to, bytes_per_count, forward, al, tmp2);
+      __ BIND(entry); // entry point
+      __ subs(count, count, 1);
+      load_one(tmp, from, bytes_per_count, forward, ge, tmp2);
+      __ b(L_small_loop, ge);
+    }
   }
 
   // Aligns 'to' by reading one word from 'from' and writting its part to 'to'.
@@ -1876,7 +1887,7 @@
   //
   // Scratches 'from', 'count', R3 and R12.
   // R4-R10 saved for use.
-  int align_dst_and_generate_shifted_copy_loop(Register from, Register to, Register count, int bytes_per_count, bool forward) {
+  int align_dst_and_generate_shifted_copy_loop(Register from, Register to, Register count, int bytes_per_count, bool forward, bool unsafe_copy = false) {
 
     const Register Rval = forward ? R12 : R3; // as generate_{forward,backward}_shifted_copy_loop expect
 
@@ -1886,60 +1897,64 @@
     // then the remainder of 'to' divided by wordSize is one of elements of {seq}.
 
     __ push(RegisterSet(R4,R10));
-    load_one(Rval, from, wordSize, forward);
-
-    switch (bytes_per_count) {
-      case 2:
-        min_copy = align_dst_and_generate_shifted_copy_loop(from, to, count, Rval, 2, bytes_per_count, forward);
-        break;
-      case 1:
-      {
-        Label L1, L2, L3;
-        int min_copy1, min_copy2, min_copy3;
-
-        Label L_loop_finished;
-
-        if (forward) {
-            __ tbz(to, 0, L2);
-            __ tbz(to, 1, L1);
-
-            __ BIND(L3);
-            min_copy3 = align_dst_and_generate_shifted_copy_loop(from, to, count, Rval, 3, bytes_per_count, forward);
-            __ b(L_loop_finished);
-
-            __ BIND(L1);
-            min_copy1 = align_dst_and_generate_shifted_copy_loop(from, to, count, Rval, 1, bytes_per_count, forward);
-            __ b(L_loop_finished);
-
-            __ BIND(L2);
-            min_copy2 = align_dst_and_generate_shifted_copy_loop(from, to, count, Rval, 2, bytes_per_count, forward);
-        } else {
-            __ tbz(to, 0, L2);
-            __ tbnz(to, 1, L3);
-
-            __ BIND(L1);
-            min_copy1 = align_dst_and_generate_shifted_copy_loop(from, to, count, Rval, 1, bytes_per_count, forward);
-            __ b(L_loop_finished);
-
-             __ BIND(L3);
-            min_copy3 = align_dst_and_generate_shifted_copy_loop(from, to, count, Rval, 3, bytes_per_count, forward);
-            __ b(L_loop_finished);
-
-           __ BIND(L2);
-            min_copy2 = align_dst_and_generate_shifted_copy_loop(from, to, count, Rval, 2, bytes_per_count, forward);
+
+    {
+      // UnsafeCopyMemory page error: continue after ucm
+      UnsafeCopyMemoryMark ucmm(this, unsafe_copy, true);
+      load_one(Rval, from, wordSize, forward);
+
+      switch (bytes_per_count) {
+        case 2:
+          min_copy = align_dst_and_generate_shifted_copy_loop(from, to, count, Rval, 2, bytes_per_count, forward);
+          break;
+        case 1:
+        {
+          Label L1, L2, L3;
+          int min_copy1, min_copy2, min_copy3;
+
+          Label L_loop_finished;
+
+          if (forward) {
+              __ tbz(to, 0, L2);
+              __ tbz(to, 1, L1);
+
+              __ BIND(L3);
+              min_copy3 = align_dst_and_generate_shifted_copy_loop(from, to, count, Rval, 3, bytes_per_count, forward);
+              __ b(L_loop_finished);
+
+              __ BIND(L1);
+              min_copy1 = align_dst_and_generate_shifted_copy_loop(from, to, count, Rval, 1, bytes_per_count, forward);
+              __ b(L_loop_finished);
+
+              __ BIND(L2);
+              min_copy2 = align_dst_and_generate_shifted_copy_loop(from, to, count, Rval, 2, bytes_per_count, forward);
+          } else {
+              __ tbz(to, 0, L2);
+              __ tbnz(to, 1, L3);
+
+              __ BIND(L1);
+              min_copy1 = align_dst_and_generate_shifted_copy_loop(from, to, count, Rval, 1, bytes_per_count, forward);
+              __ b(L_loop_finished);
+
+               __ BIND(L3);
+              min_copy3 = align_dst_and_generate_shifted_copy_loop(from, to, count, Rval, 3, bytes_per_count, forward);
+              __ b(L_loop_finished);
+
+             __ BIND(L2);
+              min_copy2 = align_dst_and_generate_shifted_copy_loop(from, to, count, Rval, 2, bytes_per_count, forward);
+          }
+
+          min_copy = MAX2(MAX2(min_copy1, min_copy2), min_copy3);
+
+          __ BIND(L_loop_finished);
+
+          break;
         }
-
-        min_copy = MAX2(MAX2(min_copy1, min_copy2), min_copy3);
-
-        __ BIND(L_loop_finished);
-
-        break;
+        default:
+          ShouldNotReachHere();
+          break;
       }
-      default:
-        ShouldNotReachHere();
-        break;
     }
-
     __ pop(RegisterSet(R4,R10));
 
     return min_copy;
@@ -1963,6 +1978,13 @@
   }
 #endif // !PRODUCT
 
+  address generate_unsafecopy_common_error_exit() {
+    address start_pc = __ pc();
+      __ mov(R0, 0);
+      __ ret();
+    return start_pc;
+  }
+
   //
   //  Generate stub for primitive array copy.  If "aligned" is true, the
   //  "from" and "to" addresses are assumed to be heapword aligned.
@@ -2033,8 +2055,13 @@
         from_is_aligned = true;
     }
 
-    int count_required_to_align = from_is_aligned ? 0 : align_src(from, to, count, tmp1, bytes_per_count, forward);
-    assert (small_copy_limit >= count_required_to_align, "alignment could exhaust count");
+    int count_required_to_align = 0;
+    {
+      // UnsafeCopyMemoryMark page error: continue at UnsafeCopyMemory common_error_exit
+      UnsafeCopyMemoryMark ucmm(this, !aligned, false);
+      count_required_to_align = from_is_aligned ? 0 : align_src(from, to, count, tmp1, bytes_per_count, forward);
+      assert (small_copy_limit >= count_required_to_align, "alignment could exhaust count");
+    }
 
     // now 'from' is aligned
 
@@ -2064,9 +2091,9 @@
 
     int min_copy;
     if (forward) {
-      min_copy = generate_forward_aligned_copy_loop (from, to, count, bytes_per_count);
+      min_copy = generate_forward_aligned_copy_loop(from, to, count, bytes_per_count, !aligned /*add UnsafeCopyMemory entry*/);
     } else {
-      min_copy = generate_backward_aligned_copy_loop(from, to, count, bytes_per_count);
+      min_copy = generate_backward_aligned_copy_loop(from, to, count, bytes_per_count, !aligned /*add UnsafeCopyMemory entry*/);
     }
     assert(small_copy_limit >= count_required_to_align + min_copy, "first loop might exhaust count");
 
@@ -2077,7 +2104,7 @@
     __ ret();
 
     {
-      copy_small_array(from, to, count, tmp1, tmp2, bytes_per_count, forward, L_small_array /* entry */);
+      copy_small_array(from, to, count, tmp1, tmp2, bytes_per_count, forward, L_small_array /* entry */, !aligned /*add UnsafeCopyMemory entry*/);
 
       if (status) {
         __ mov(R0, 0); // OK
@@ -2088,7 +2115,7 @@
 
     if (! to_is_aligned) {
       __ BIND(L_unaligned_dst);
-      int min_copy_shifted = align_dst_and_generate_shifted_copy_loop(from, to, count, bytes_per_count, forward);
+      int min_copy_shifted = align_dst_and_generate_shifted_copy_loop(from, to, count, bytes_per_count, forward, !aligned /*add UnsafeCopyMemory entry*/);
       assert (small_copy_limit >= count_required_to_align + min_copy_shifted, "first loop might exhaust count");
 
       if (status) {
@@ -2873,6 +2900,9 @@
     status = true; // generate a status compatible with C1 calls
 #endif
 
+    address ucm_common_error_exit       =  generate_unsafecopy_common_error_exit();
+    UnsafeCopyMemory::set_common_exit_stub_pc(ucm_common_error_exit);
+
     // these need always status in case they are called from generic_arraycopy
     StubRoutines::_jbyte_disjoint_arraycopy  = generate_primitive_copy(false, "jbyte_disjoint_arraycopy",  true, 1, true);
     StubRoutines::_jshort_disjoint_arraycopy = generate_primitive_copy(false, "jshort_disjoint_arraycopy", true, 2, true);
@@ -3055,6 +3085,10 @@
   }
 }; // end class declaration
 
+#define UCM_TABLE_MAX_ENTRIES 32
 void StubGenerator_generate(CodeBuffer* code, bool all) {
+  if (UnsafeCopyMemory::_table == NULL) {
+    UnsafeCopyMemory::create_table(UCM_TABLE_MAX_ENTRIES);
+  }
   StubGenerator g(code, all);
 }
--- a/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -952,6 +952,20 @@
     // need to copy backwards
   }
 
+  // This is common errorexit stub for UnsafeCopyMemory.
+  address generate_unsafecopy_common_error_exit() {
+    address start_pc = __ pc();
+    Register tmp1 = R6_ARG4;
+    // probably copy stub would have changed value reset it.
+    if (VM_Version::has_mfdscr()) {
+      __ load_const_optimized(tmp1, VM_Version::_dscr_val);
+      __ mtdscr(tmp1);
+    }
+    __ li(R3_RET, 0); // return 0
+    __ blr();
+    return start_pc;
+  }
+
   // The guideline in the implementations of generate_disjoint_xxx_copy
   // (xxx=byte,short,int,long,oop) is to copy as many elements as possible with
   // single instructions, but to avoid alignment interrupts (see subsequent
@@ -989,150 +1003,154 @@
     VectorSRegister tmp_vsr2  = VSR2;
 
     Label l_1, l_2, l_3, l_4, l_5, l_6, l_7, l_8, l_9, l_10;
-
-    // Don't try anything fancy if arrays don't have many elements.
-    __ li(tmp3, 0);
-    __ cmpwi(CCR0, R5_ARG3, 17);
-    __ ble(CCR0, l_6); // copy 4 at a time
-
-    if (!aligned) {
-      __ xorr(tmp1, R3_ARG1, R4_ARG2);
-      __ andi_(tmp1, tmp1, 3);
-      __ bne(CCR0, l_6); // If arrays don't have the same alignment mod 4, do 4 element copy.
-
-      // Copy elements if necessary to align to 4 bytes.
-      __ neg(tmp1, R3_ARG1); // Compute distance to alignment boundary.
-      __ andi_(tmp1, tmp1, 3);
-      __ beq(CCR0, l_2);
-
-      __ subf(R5_ARG3, tmp1, R5_ARG3);
-      __ bind(l_9);
-      __ lbz(tmp2, 0, R3_ARG1);
-      __ addic_(tmp1, tmp1, -1);
-      __ stb(tmp2, 0, R4_ARG2);
-      __ addi(R3_ARG1, R3_ARG1, 1);
-      __ addi(R4_ARG2, R4_ARG2, 1);
-      __ bne(CCR0, l_9);
-
-      __ bind(l_2);
-    }
-
-    // copy 8 elements at a time
-    __ xorr(tmp2, R3_ARG1, R4_ARG2); // skip if src & dest have differing alignment mod 8
-    __ andi_(tmp1, tmp2, 7);
-    __ bne(CCR0, l_7); // not same alignment -> to or from is aligned -> copy 8
-
-    // copy a 2-element word if necessary to align to 8 bytes
-    __ andi_(R0, R3_ARG1, 7);
-    __ beq(CCR0, l_7);
-
-    __ lwzx(tmp2, R3_ARG1, tmp3);
-    __ addi(R5_ARG3, R5_ARG3, -4);
-    __ stwx(tmp2, R4_ARG2, tmp3);
-    { // FasterArrayCopy
-      __ addi(R3_ARG1, R3_ARG1, 4);
-      __ addi(R4_ARG2, R4_ARG2, 4);
-    }
-    __ bind(l_7);
-
-    { // FasterArrayCopy
-      __ cmpwi(CCR0, R5_ARG3, 31);
-      __ ble(CCR0, l_6); // copy 2 at a time if less than 32 elements remain
-
-      __ srdi(tmp1, R5_ARG3, 5);
-      __ andi_(R5_ARG3, R5_ARG3, 31);
-      __ mtctr(tmp1);
-
-     if (!VM_Version::has_vsx()) {
-
-      __ bind(l_8);
-      // Use unrolled version for mass copying (copy 32 elements a time)
-      // Load feeding store gets zero latency on Power6, however not on Power5.
-      // Therefore, the following sequence is made for the good of both.
-      __ ld(tmp1, 0, R3_ARG1);
-      __ ld(tmp2, 8, R3_ARG1);
-      __ ld(tmp3, 16, R3_ARG1);
-      __ ld(tmp4, 24, R3_ARG1);
-      __ std(tmp1, 0, R4_ARG2);
-      __ std(tmp2, 8, R4_ARG2);
-      __ std(tmp3, 16, R4_ARG2);
-      __ std(tmp4, 24, R4_ARG2);
-      __ addi(R3_ARG1, R3_ARG1, 32);
-      __ addi(R4_ARG2, R4_ARG2, 32);
-      __ bdnz(l_8);
-
-    } else { // Processor supports VSX, so use it to mass copy.
-
-      // Prefetch the data into the L2 cache.
-      __ dcbt(R3_ARG1, 0);
-
-      // If supported set DSCR pre-fetch to deepest.
-      if (VM_Version::has_mfdscr()) {
-        __ load_const_optimized(tmp2, VM_Version::_dscr_val | 7);
-        __ mtdscr(tmp2);
+    {
+      // UnsafeCopyMemory page error: continue at UnsafeCopyMemory common_error_exit
+      UnsafeCopyMemoryMark ucmm(this, !aligned, false);
+
+      // Don't try anything fancy if arrays don't have many elements.
+      __ li(tmp3, 0);
+      __ cmpwi(CCR0, R5_ARG3, 17);
+      __ ble(CCR0, l_6); // copy 4 at a time
+
+      if (!aligned) {
+        __ xorr(tmp1, R3_ARG1, R4_ARG2);
+        __ andi_(tmp1, tmp1, 3);
+        __ bne(CCR0, l_6); // If arrays don't have the same alignment mod 4, do 4 element copy.
+
+        // Copy elements if necessary to align to 4 bytes.
+        __ neg(tmp1, R3_ARG1); // Compute distance to alignment boundary.
+        __ andi_(tmp1, tmp1, 3);
+        __ beq(CCR0, l_2);
+
+        __ subf(R5_ARG3, tmp1, R5_ARG3);
+        __ bind(l_9);
+        __ lbz(tmp2, 0, R3_ARG1);
+        __ addic_(tmp1, tmp1, -1);
+        __ stb(tmp2, 0, R4_ARG2);
+        __ addi(R3_ARG1, R3_ARG1, 1);
+        __ addi(R4_ARG2, R4_ARG2, 1);
+        __ bne(CCR0, l_9);
+
+        __ bind(l_2);
+      }
+
+      // copy 8 elements at a time
+      __ xorr(tmp2, R3_ARG1, R4_ARG2); // skip if src & dest have differing alignment mod 8
+      __ andi_(tmp1, tmp2, 7);
+      __ bne(CCR0, l_7); // not same alignment -> to or from is aligned -> copy 8
+
+      // copy a 2-element word if necessary to align to 8 bytes
+      __ andi_(R0, R3_ARG1, 7);
+      __ beq(CCR0, l_7);
+
+      __ lwzx(tmp2, R3_ARG1, tmp3);
+      __ addi(R5_ARG3, R5_ARG3, -4);
+      __ stwx(tmp2, R4_ARG2, tmp3);
+      { // FasterArrayCopy
+        __ addi(R3_ARG1, R3_ARG1, 4);
+        __ addi(R4_ARG2, R4_ARG2, 4);
       }
-
-      __ li(tmp1, 16);
-
-      // Backbranch target aligned to 32-byte. Not 16-byte align as
-      // loop contains < 8 instructions that fit inside a single
-      // i-cache sector.
-      __ align(32);
-
-      __ bind(l_10);
-      // Use loop with VSX load/store instructions to
-      // copy 32 elements a time.
-      __ lxvd2x(tmp_vsr1, R3_ARG1);        // Load src
-      __ stxvd2x(tmp_vsr1, R4_ARG2);       // Store to dst
-      __ lxvd2x(tmp_vsr2, tmp1, R3_ARG1);  // Load src + 16
-      __ stxvd2x(tmp_vsr2, tmp1, R4_ARG2); // Store to dst + 16
-      __ addi(R3_ARG1, R3_ARG1, 32);       // Update src+=32
-      __ addi(R4_ARG2, R4_ARG2, 32);       // Update dsc+=32
-      __ bdnz(l_10);                       // Dec CTR and loop if not zero.
-
-      // Restore DSCR pre-fetch value.
-      if (VM_Version::has_mfdscr()) {
-        __ load_const_optimized(tmp2, VM_Version::_dscr_val);
-        __ mtdscr(tmp2);
+      __ bind(l_7);
+
+      { // FasterArrayCopy
+        __ cmpwi(CCR0, R5_ARG3, 31);
+        __ ble(CCR0, l_6); // copy 2 at a time if less than 32 elements remain
+
+        __ srdi(tmp1, R5_ARG3, 5);
+        __ andi_(R5_ARG3, R5_ARG3, 31);
+        __ mtctr(tmp1);
+
+       if (!VM_Version::has_vsx()) {
+
+        __ bind(l_8);
+        // Use unrolled version for mass copying (copy 32 elements a time)
+        // Load feeding store gets zero latency on Power6, however not on Power5.
+        // Therefore, the following sequence is made for the good of both.
+        __ ld(tmp1, 0, R3_ARG1);
+        __ ld(tmp2, 8, R3_ARG1);
+        __ ld(tmp3, 16, R3_ARG1);
+        __ ld(tmp4, 24, R3_ARG1);
+        __ std(tmp1, 0, R4_ARG2);
+        __ std(tmp2, 8, R4_ARG2);
+        __ std(tmp3, 16, R4_ARG2);
+        __ std(tmp4, 24, R4_ARG2);
+        __ addi(R3_ARG1, R3_ARG1, 32);
+        __ addi(R4_ARG2, R4_ARG2, 32);
+        __ bdnz(l_8);
+
+      } else { // Processor supports VSX, so use it to mass copy.
+
+        // Prefetch the data into the L2 cache.
+        __ dcbt(R3_ARG1, 0);
+
+        // If supported set DSCR pre-fetch to deepest.
+        if (VM_Version::has_mfdscr()) {
+          __ load_const_optimized(tmp2, VM_Version::_dscr_val | 7);
+          __ mtdscr(tmp2);
+        }
+
+        __ li(tmp1, 16);
+
+        // Backbranch target aligned to 32-byte. Not 16-byte align as
+        // loop contains < 8 instructions that fit inside a single
+        // i-cache sector.
+        __ align(32);
+
+        __ bind(l_10);
+        // Use loop with VSX load/store instructions to
+        // copy 32 elements a time.
+        __ lxvd2x(tmp_vsr1, R3_ARG1);        // Load src
+        __ stxvd2x(tmp_vsr1, R4_ARG2);       // Store to dst
+        __ lxvd2x(tmp_vsr2, tmp1, R3_ARG1);  // Load src + 16
+        __ stxvd2x(tmp_vsr2, tmp1, R4_ARG2); // Store to dst + 16
+        __ addi(R3_ARG1, R3_ARG1, 32);       // Update src+=32
+        __ addi(R4_ARG2, R4_ARG2, 32);       // Update dsc+=32
+        __ bdnz(l_10);                       // Dec CTR and loop if not zero.
+
+        // Restore DSCR pre-fetch value.
+        if (VM_Version::has_mfdscr()) {
+          __ load_const_optimized(tmp2, VM_Version::_dscr_val);
+          __ mtdscr(tmp2);
+        }
+
+      } // VSX
+     } // FasterArrayCopy
+
+      __ bind(l_6);
+
+      // copy 4 elements at a time
+      __ cmpwi(CCR0, R5_ARG3, 4);
+      __ blt(CCR0, l_1);
+      __ srdi(tmp1, R5_ARG3, 2);
+      __ mtctr(tmp1); // is > 0
+      __ andi_(R5_ARG3, R5_ARG3, 3);
+
+      { // FasterArrayCopy
+        __ addi(R3_ARG1, R3_ARG1, -4);
+        __ addi(R4_ARG2, R4_ARG2, -4);
+        __ bind(l_3);
+        __ lwzu(tmp2, 4, R3_ARG1);
+        __ stwu(tmp2, 4, R4_ARG2);
+        __ bdnz(l_3);
+        __ addi(R3_ARG1, R3_ARG1, 4);
+        __ addi(R4_ARG2, R4_ARG2, 4);
       }
 
-    } // VSX
-   } // FasterArrayCopy
-
-    __ bind(l_6);
-
-    // copy 4 elements at a time
-    __ cmpwi(CCR0, R5_ARG3, 4);
-    __ blt(CCR0, l_1);
-    __ srdi(tmp1, R5_ARG3, 2);
-    __ mtctr(tmp1); // is > 0
-    __ andi_(R5_ARG3, R5_ARG3, 3);
-
-    { // FasterArrayCopy
-      __ addi(R3_ARG1, R3_ARG1, -4);
-      __ addi(R4_ARG2, R4_ARG2, -4);
-      __ bind(l_3);
-      __ lwzu(tmp2, 4, R3_ARG1);
-      __ stwu(tmp2, 4, R4_ARG2);
-      __ bdnz(l_3);
-      __ addi(R3_ARG1, R3_ARG1, 4);
-      __ addi(R4_ARG2, R4_ARG2, 4);
-    }
-
-    // do single element copy
-    __ bind(l_1);
-    __ cmpwi(CCR0, R5_ARG3, 0);
-    __ beq(CCR0, l_4);
-
-    { // FasterArrayCopy
-      __ mtctr(R5_ARG3);
-      __ addi(R3_ARG1, R3_ARG1, -1);
-      __ addi(R4_ARG2, R4_ARG2, -1);
-
-      __ bind(l_5);
-      __ lbzu(tmp2, 1, R3_ARG1);
-      __ stbu(tmp2, 1, R4_ARG2);
-      __ bdnz(l_5);
+      // do single element copy
+      __ bind(l_1);
+      __ cmpwi(CCR0, R5_ARG3, 0);
+      __ beq(CCR0, l_4);
+
+      { // FasterArrayCopy
+        __ mtctr(R5_ARG3);
+        __ addi(R3_ARG1, R3_ARG1, -1);
+        __ addi(R4_ARG2, R4_ARG2, -1);
+
+        __ bind(l_5);
+        __ lbzu(tmp2, 1, R3_ARG1);
+        __ stbu(tmp2, 1, R4_ARG2);
+        __ bdnz(l_5);
+      }
     }
 
     __ bind(l_4);
@@ -1167,15 +1185,17 @@
     // Do reverse copy. We assume the case of actual overlap is rare enough
     // that we don't have to optimize it.
     Label l_1, l_2;
-
-    __ b(l_2);
-    __ bind(l_1);
-    __ stbx(tmp1, R4_ARG2, R5_ARG3);
-    __ bind(l_2);
-    __ addic_(R5_ARG3, R5_ARG3, -1);
-    __ lbzx(tmp1, R3_ARG1, R5_ARG3);
-    __ bge(CCR0, l_1);
-
+    {
+      // UnsafeCopyMemory page error: continue at UnsafeCopyMemory common_error_exit
+      UnsafeCopyMemoryMark ucmm(this, !aligned, false);
+      __ b(l_2);
+      __ bind(l_1);
+      __ stbx(tmp1, R4_ARG2, R5_ARG3);
+      __ bind(l_2);
+      __ addic_(R5_ARG3, R5_ARG3, -1);
+      __ lbzx(tmp1, R3_ARG1, R5_ARG3);
+      __ bge(CCR0, l_1);
+    }
     __ li(R3_RET, 0); // return 0
     __ blr();
 
@@ -1252,155 +1272,159 @@
     assert_positive_int(R5_ARG3);
 
     Label l_1, l_2, l_3, l_4, l_5, l_6, l_7, l_8, l_9;
-
-    // don't try anything fancy if arrays don't have many elements
-    __ li(tmp3, 0);
-    __ cmpwi(CCR0, R5_ARG3, 9);
-    __ ble(CCR0, l_6); // copy 2 at a time
-
-    if (!aligned) {
-      __ xorr(tmp1, R3_ARG1, R4_ARG2);
-      __ andi_(tmp1, tmp1, 3);
-      __ bne(CCR0, l_6); // if arrays don't have the same alignment mod 4, do 2 element copy
-
-      // At this point it is guaranteed that both, from and to have the same alignment mod 4.
-
-      // Copy 1 element if necessary to align to 4 bytes.
-      __ andi_(tmp1, R3_ARG1, 3);
-      __ beq(CCR0, l_2);
-
-      __ lhz(tmp2, 0, R3_ARG1);
-      __ addi(R3_ARG1, R3_ARG1, 2);
-      __ sth(tmp2, 0, R4_ARG2);
-      __ addi(R4_ARG2, R4_ARG2, 2);
-      __ addi(R5_ARG3, R5_ARG3, -1);
-      __ bind(l_2);
-
-      // At this point the positions of both, from and to, are at least 4 byte aligned.
-
-      // Copy 4 elements at a time.
-      // Align to 8 bytes, but only if both, from and to, have same alignment mod 8.
-      __ xorr(tmp2, R3_ARG1, R4_ARG2);
-      __ andi_(tmp1, tmp2, 7);
-      __ bne(CCR0, l_7); // not same alignment mod 8 -> copy 4, either from or to will be unaligned
-
-      // Copy a 2-element word if necessary to align to 8 bytes.
-      __ andi_(R0, R3_ARG1, 7);
-      __ beq(CCR0, l_7);
-
-      __ lwzx(tmp2, R3_ARG1, tmp3);
-      __ addi(R5_ARG3, R5_ARG3, -2);
-      __ stwx(tmp2, R4_ARG2, tmp3);
+    {
+      // UnsafeCopyMemory page error: continue at UnsafeCopyMemory common_error_exit
+      UnsafeCopyMemoryMark ucmm(this, !aligned, false);
+      // don't try anything fancy if arrays don't have many elements
+      __ li(tmp3, 0);
+      __ cmpwi(CCR0, R5_ARG3, 9);
+      __ ble(CCR0, l_6); // copy 2 at a time
+
+      if (!aligned) {
+        __ xorr(tmp1, R3_ARG1, R4_ARG2);
+        __ andi_(tmp1, tmp1, 3);
+        __ bne(CCR0, l_6); // if arrays don't have the same alignment mod 4, do 2 element copy
+
+        // At this point it is guaranteed that both, from and to have the same alignment mod 4.
+
+        // Copy 1 element if necessary to align to 4 bytes.
+        __ andi_(tmp1, R3_ARG1, 3);
+        __ beq(CCR0, l_2);
+
+        __ lhz(tmp2, 0, R3_ARG1);
+        __ addi(R3_ARG1, R3_ARG1, 2);
+        __ sth(tmp2, 0, R4_ARG2);
+        __ addi(R4_ARG2, R4_ARG2, 2);
+        __ addi(R5_ARG3, R5_ARG3, -1);
+        __ bind(l_2);
+
+        // At this point the positions of both, from and to, are at least 4 byte aligned.
+
+        // Copy 4 elements at a time.
+        // Align to 8 bytes, but only if both, from and to, have same alignment mod 8.
+        __ xorr(tmp2, R3_ARG1, R4_ARG2);
+        __ andi_(tmp1, tmp2, 7);
+        __ bne(CCR0, l_7); // not same alignment mod 8 -> copy 4, either from or to will be unaligned
+
+        // Copy a 2-element word if necessary to align to 8 bytes.
+        __ andi_(R0, R3_ARG1, 7);
+        __ beq(CCR0, l_7);
+
+        __ lwzx(tmp2, R3_ARG1, tmp3);
+        __ addi(R5_ARG3, R5_ARG3, -2);
+        __ stwx(tmp2, R4_ARG2, tmp3);
+        { // FasterArrayCopy
+          __ addi(R3_ARG1, R3_ARG1, 4);
+          __ addi(R4_ARG2, R4_ARG2, 4);
+        }
+      }
+
+      __ bind(l_7);
+
+      // Copy 4 elements at a time; either the loads or the stores can
+      // be unaligned if aligned == false.
+
       { // FasterArrayCopy
+        __ cmpwi(CCR0, R5_ARG3, 15);
+        __ ble(CCR0, l_6); // copy 2 at a time if less than 16 elements remain
+
+        __ srdi(tmp1, R5_ARG3, 4);
+        __ andi_(R5_ARG3, R5_ARG3, 15);
+        __ mtctr(tmp1);
+
+        if (!VM_Version::has_vsx()) {
+
+          __ bind(l_8);
+          // Use unrolled version for mass copying (copy 16 elements a time).
+          // Load feeding store gets zero latency on Power6, however not on Power5.
+          // Therefore, the following sequence is made for the good of both.
+          __ ld(tmp1, 0, R3_ARG1);
+          __ ld(tmp2, 8, R3_ARG1);
+          __ ld(tmp3, 16, R3_ARG1);
+          __ ld(tmp4, 24, R3_ARG1);
+          __ std(tmp1, 0, R4_ARG2);
+          __ std(tmp2, 8, R4_ARG2);
+          __ std(tmp3, 16, R4_ARG2);
+          __ std(tmp4, 24, R4_ARG2);
+          __ addi(R3_ARG1, R3_ARG1, 32);
+          __ addi(R4_ARG2, R4_ARG2, 32);
+          __ bdnz(l_8);
+
+        } else { // Processor supports VSX, so use it to mass copy.
+
+          // Prefetch src data into L2 cache.
+          __ dcbt(R3_ARG1, 0);
+
+          // If supported set DSCR pre-fetch to deepest.
+          if (VM_Version::has_mfdscr()) {
+            __ load_const_optimized(tmp2, VM_Version::_dscr_val | 7);
+            __ mtdscr(tmp2);
+          }
+          __ li(tmp1, 16);
+
+          // Backbranch target aligned to 32-byte. It's not aligned 16-byte
+          // as loop contains < 8 instructions that fit inside a single
+          // i-cache sector.
+          __ align(32);
+
+          __ bind(l_9);
+          // Use loop with VSX load/store instructions to
+          // copy 16 elements a time.
+          __ lxvd2x(tmp_vsr1, R3_ARG1);        // Load from src.
+          __ stxvd2x(tmp_vsr1, R4_ARG2);       // Store to dst.
+          __ lxvd2x(tmp_vsr2, R3_ARG1, tmp1);  // Load from src + 16.
+          __ stxvd2x(tmp_vsr2, R4_ARG2, tmp1); // Store to dst + 16.
+          __ addi(R3_ARG1, R3_ARG1, 32);       // Update src+=32.
+          __ addi(R4_ARG2, R4_ARG2, 32);       // Update dsc+=32.
+          __ bdnz(l_9);                        // Dec CTR and loop if not zero.
+
+          // Restore DSCR pre-fetch value.
+          if (VM_Version::has_mfdscr()) {
+            __ load_const_optimized(tmp2, VM_Version::_dscr_val);
+            __ mtdscr(tmp2);
+          }
+
+        }
+      } // FasterArrayCopy
+      __ bind(l_6);
+
+      // copy 2 elements at a time
+      { // FasterArrayCopy
+        __ cmpwi(CCR0, R5_ARG3, 2);
+        __ blt(CCR0, l_1);
+        __ srdi(tmp1, R5_ARG3, 1);
+        __ andi_(R5_ARG3, R5_ARG3, 1);
+
+        __ addi(R3_ARG1, R3_ARG1, -4);
+        __ addi(R4_ARG2, R4_ARG2, -4);
+        __ mtctr(tmp1);
+
+        __ bind(l_3);
+        __ lwzu(tmp2, 4, R3_ARG1);
+        __ stwu(tmp2, 4, R4_ARG2);
+        __ bdnz(l_3);
+
         __ addi(R3_ARG1, R3_ARG1, 4);
         __ addi(R4_ARG2, R4_ARG2, 4);
       }
+
+      // do single element copy
+      __ bind(l_1);
+      __ cmpwi(CCR0, R5_ARG3, 0);
+      __ beq(CCR0, l_4);
+
+      { // FasterArrayCopy
+        __ mtctr(R5_ARG3);
+        __ addi(R3_ARG1, R3_ARG1, -2);
+        __ addi(R4_ARG2, R4_ARG2, -2);
+
+        __ bind(l_5);
+        __ lhzu(tmp2, 2, R3_ARG1);
+        __ sthu(tmp2, 2, R4_ARG2);
+        __ bdnz(l_5);
+      }
     }
 
-    __ bind(l_7);
-
-    // Copy 4 elements at a time; either the loads or the stores can
-    // be unaligned if aligned == false.
-
-    { // FasterArrayCopy
-      __ cmpwi(CCR0, R5_ARG3, 15);
-      __ ble(CCR0, l_6); // copy 2 at a time if less than 16 elements remain
-
-      __ srdi(tmp1, R5_ARG3, 4);
-      __ andi_(R5_ARG3, R5_ARG3, 15);
-      __ mtctr(tmp1);
-
-      if (!VM_Version::has_vsx()) {
-
-        __ bind(l_8);
-        // Use unrolled version for mass copying (copy 16 elements a time).
-        // Load feeding store gets zero latency on Power6, however not on Power5.
-        // Therefore, the following sequence is made for the good of both.
-        __ ld(tmp1, 0, R3_ARG1);
-        __ ld(tmp2, 8, R3_ARG1);
-        __ ld(tmp3, 16, R3_ARG1);
-        __ ld(tmp4, 24, R3_ARG1);
-        __ std(tmp1, 0, R4_ARG2);
-        __ std(tmp2, 8, R4_ARG2);
-        __ std(tmp3, 16, R4_ARG2);
-        __ std(tmp4, 24, R4_ARG2);
-        __ addi(R3_ARG1, R3_ARG1, 32);
-        __ addi(R4_ARG2, R4_ARG2, 32);
-        __ bdnz(l_8);
-
-      } else { // Processor supports VSX, so use it to mass copy.
-
-        // Prefetch src data into L2 cache.
-        __ dcbt(R3_ARG1, 0);
-
-        // If supported set DSCR pre-fetch to deepest.
-        if (VM_Version::has_mfdscr()) {
-          __ load_const_optimized(tmp2, VM_Version::_dscr_val | 7);
-          __ mtdscr(tmp2);
-        }
-        __ li(tmp1, 16);
-
-        // Backbranch target aligned to 32-byte. It's not aligned 16-byte
-        // as loop contains < 8 instructions that fit inside a single
-        // i-cache sector.
-        __ align(32);
-
-        __ bind(l_9);
-        // Use loop with VSX load/store instructions to
-        // copy 16 elements a time.
-        __ lxvd2x(tmp_vsr1, R3_ARG1);        // Load from src.
-        __ stxvd2x(tmp_vsr1, R4_ARG2);       // Store to dst.
-        __ lxvd2x(tmp_vsr2, R3_ARG1, tmp1);  // Load from src + 16.
-        __ stxvd2x(tmp_vsr2, R4_ARG2, tmp1); // Store to dst + 16.
-        __ addi(R3_ARG1, R3_ARG1, 32);       // Update src+=32.
-        __ addi(R4_ARG2, R4_ARG2, 32);       // Update dsc+=32.
-        __ bdnz(l_9);                        // Dec CTR and loop if not zero.
-
-        // Restore DSCR pre-fetch value.
-        if (VM_Version::has_mfdscr()) {
-          __ load_const_optimized(tmp2, VM_Version::_dscr_val);
-          __ mtdscr(tmp2);
-        }
-
-      }
-    } // FasterArrayCopy
-    __ bind(l_6);
-
-    // copy 2 elements at a time
-    { // FasterArrayCopy
-      __ cmpwi(CCR0, R5_ARG3, 2);
-      __ blt(CCR0, l_1);
-      __ srdi(tmp1, R5_ARG3, 1);
-      __ andi_(R5_ARG3, R5_ARG3, 1);
-
-      __ addi(R3_ARG1, R3_ARG1, -4);
-      __ addi(R4_ARG2, R4_ARG2, -4);
-      __ mtctr(tmp1);
-
-      __ bind(l_3);
-      __ lwzu(tmp2, 4, R3_ARG1);
-      __ stwu(tmp2, 4, R4_ARG2);
-      __ bdnz(l_3);
-
-      __ addi(R3_ARG1, R3_ARG1, 4);
-      __ addi(R4_ARG2, R4_ARG2, 4);
-    }
-
-    // do single element copy
-    __ bind(l_1);
-    __ cmpwi(CCR0, R5_ARG3, 0);
-    __ beq(CCR0, l_4);
-
-    { // FasterArrayCopy
-      __ mtctr(R5_ARG3);
-      __ addi(R3_ARG1, R3_ARG1, -2);
-      __ addi(R4_ARG2, R4_ARG2, -2);
-
-      __ bind(l_5);
-      __ lhzu(tmp2, 2, R3_ARG1);
-      __ sthu(tmp2, 2, R4_ARG2);
-      __ bdnz(l_5);
-    }
     __ bind(l_4);
     __ li(R3_RET, 0); // return 0
     __ blr();
@@ -1432,15 +1456,18 @@
     array_overlap_test(nooverlap_target, 1);
 
     Label l_1, l_2;
-    __ sldi(tmp1, R5_ARG3, 1);
-    __ b(l_2);
-    __ bind(l_1);
-    __ sthx(tmp2, R4_ARG2, tmp1);
-    __ bind(l_2);
-    __ addic_(tmp1, tmp1, -2);
-    __ lhzx(tmp2, R3_ARG1, tmp1);
-    __ bge(CCR0, l_1);
-
+    {
+      // UnsafeCopyMemory page error: continue at UnsafeCopyMemory common_error_exit
+      UnsafeCopyMemoryMark ucmm(this, !aligned, false);
+      __ sldi(tmp1, R5_ARG3, 1);
+      __ b(l_2);
+      __ bind(l_1);
+      __ sthx(tmp2, R4_ARG2, tmp1);
+      __ bind(l_2);
+      __ addic_(tmp1, tmp1, -2);
+      __ lhzx(tmp2, R3_ARG1, tmp1);
+      __ bge(CCR0, l_1);
+    }
     __ li(R3_RET, 0); // return 0
     __ blr();
 
@@ -1588,7 +1615,11 @@
     StubCodeMark mark(this, "StubRoutines", name);
     address start = __ function_entry();
     assert_positive_int(R5_ARG3);
-    generate_disjoint_int_copy_core(aligned);
+    {
+      // UnsafeCopyMemory page error: continue at UnsafeCopyMemory common_error_exit
+      UnsafeCopyMemoryMark ucmm(this, !aligned, false);
+      generate_disjoint_int_copy_core(aligned);
+    }
     __ li(R3_RET, 0); // return 0
     __ blr();
     return start;
@@ -1736,8 +1767,11 @@
       STUB_ENTRY(jint_disjoint_arraycopy);
 
     array_overlap_test(nooverlap_target, 2);
-
-    generate_conjoint_int_copy_core(aligned);
+    {
+      // UnsafeCopyMemory page error: continue at UnsafeCopyMemory common_error_exit
+      UnsafeCopyMemoryMark ucmm(this, !aligned, false);
+      generate_conjoint_int_copy_core(aligned);
+    }
 
     __ li(R3_RET, 0); // return 0
     __ blr();
@@ -1859,11 +1893,15 @@
     StubCodeMark mark(this, "StubRoutines", name);
     address start = __ function_entry();
     assert_positive_int(R5_ARG3);
-    generate_disjoint_long_copy_core(aligned);
+    {
+      // UnsafeCopyMemory page error: continue at UnsafeCopyMemory common_error_exit
+      UnsafeCopyMemoryMark ucmm(this, !aligned, false);
+      generate_disjoint_long_copy_core(aligned);
+    }
     __ li(R3_RET, 0); // return 0
     __ blr();
 
-    return start;
+  return start;
   }
 
   // Generate core code for conjoint long copy (and oop copy on
@@ -1986,8 +2024,11 @@
       STUB_ENTRY(jlong_disjoint_arraycopy);
 
     array_overlap_test(nooverlap_target, 3);
-    generate_conjoint_long_copy_core(aligned);
-
+    {
+      // UnsafeCopyMemory page error: continue at UnsafeCopyMemory common_error_exit
+      UnsafeCopyMemoryMark ucmm(this, !aligned, false);
+      generate_conjoint_long_copy_core(aligned);
+    }
     __ li(R3_RET, 0); // return 0
     __ blr();
 
@@ -3008,6 +3049,9 @@
     // Note: the disjoint stubs must be generated first, some of
     // the conjoint stubs use them.
 
+    address ucm_common_error_exit       =  generate_unsafecopy_common_error_exit();
+    UnsafeCopyMemory::set_common_exit_stub_pc(ucm_common_error_exit);
+
     // non-aligned disjoint versions
     StubRoutines::_jbyte_disjoint_arraycopy       = generate_disjoint_byte_copy(false, "jbyte_disjoint_arraycopy");
     StubRoutines::_jshort_disjoint_arraycopy      = generate_disjoint_short_copy(false, "jshort_disjoint_arraycopy");
@@ -3579,6 +3623,10 @@
   }
 };
 
+#define UCM_TABLE_MAX_ENTRIES 8
 void StubGenerator_generate(CodeBuffer* code, bool all) {
+  if (UnsafeCopyMemory::_table == NULL) {
+    UnsafeCopyMemory::create_table(UCM_TABLE_MAX_ENTRIES);
+  }
   StubGenerator g(code, all);
 }
--- a/src/hotspot/cpu/sparc/stubGenerator_sparc.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/cpu/sparc/stubGenerator_sparc.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -1076,6 +1076,17 @@
       __ delayed()->add(end_from, left_shift, end_from); // restore address
   }
 
+  address generate_unsafecopy_common_error_exit() {
+    address start_pc = __ pc();
+    if (UseBlockCopy) {
+      __ wrasi(G0, Assembler::ASI_PRIMARY_NOFAULT);
+      __ membar(Assembler::StoreLoad);
+    }
+    __ retl();
+    __ delayed()->mov(G0, O0); // return 0
+    return start_pc;
+  }
+
   //
   //  Generate stub for disjoint byte copy.  If "aligned" is true, the
   //  "from" and "to" addresses are assumed to be heapword aligned.
@@ -1107,61 +1118,66 @@
       BLOCK_COMMENT("Entry:");
     }
 
-    // for short arrays, just do single element copy
-    __ cmp(count, 23); // 16 + 7
-    __ brx(Assembler::less, false, Assembler::pn, L_copy_byte);
-    __ delayed()->mov(G0, offset);
-
-    if (aligned) {
-      // 'aligned' == true when it is known statically during compilation
-      // of this arraycopy call site that both 'from' and 'to' addresses
-      // are HeapWordSize aligned (see LibraryCallKit::basictype2arraycopy()).
-      //
-      // Aligned arrays have 4 bytes alignment in 32-bits VM
-      // and 8 bytes - in 64-bits VM. So we do it only for 32-bits VM
-      //
-    } else {
-      // copy bytes to align 'to' on 8 byte boundary
-      __ andcc(to, 7, G1); // misaligned bytes
-      __ br(Assembler::zero, false, Assembler::pt, L_skip_alignment);
-      __ delayed()->neg(G1);
-      __ inc(G1, 8);       // bytes need to copy to next 8-bytes alignment
-      __ sub(count, G1, count);
-    __ BIND(L_align);
-      __ ldub(from, 0, O3);
-      __ deccc(G1);
-      __ inc(from);
-      __ stb(O3, to, 0);
-      __ br(Assembler::notZero, false, Assembler::pt, L_align);
-      __ delayed()->inc(to);
-    __ BIND(L_skip_alignment);
-    }
-    if (!aligned) {
-      // Copy with shift 16 bytes per iteration if arrays do not have
-      // the same alignment mod 8, otherwise fall through to the next
-      // code for aligned copy.
-      // The compare above (count >= 23) guarantes 'count' >= 16 bytes.
-      // Also jump over aligned copy after the copy with shift completed.
-
-      copy_16_bytes_forward_with_shift(from, to, count, 0, L_copy_byte);
-    }
-
-    // Both array are 8 bytes aligned, copy 16 bytes at a time
+    {
+      // UnsafeCopyMemory page error: continue at UnsafeCopyMemory common_error_exit
+      UnsafeCopyMemoryMark ucmm(this, !aligned, false);
+
+      // for short arrays, just do single element copy
+      __ cmp(count, 23); // 16 + 7
+      __ brx(Assembler::less, false, Assembler::pn, L_copy_byte);
+      __ delayed()->mov(G0, offset);
+
+      if (aligned) {
+        // 'aligned' == true when it is known statically during compilation
+        // of this arraycopy call site that both 'from' and 'to' addresses
+        // are HeapWordSize aligned (see LibraryCallKit::basictype2arraycopy()).
+        //
+        // Aligned arrays have 4 bytes alignment in 32-bits VM
+        // and 8 bytes - in 64-bits VM. So we do it only for 32-bits VM
+        //
+      } else {
+        // copy bytes to align 'to' on 8 byte boundary
+        __ andcc(to, 7, G1); // misaligned bytes
+        __ br(Assembler::zero, false, Assembler::pt, L_skip_alignment);
+        __ delayed()->neg(G1);
+        __ inc(G1, 8);       // bytes need to copy to next 8-bytes alignment
+        __ sub(count, G1, count);
+      __ BIND(L_align);
+        __ ldub(from, 0, O3);
+        __ deccc(G1);
+        __ inc(from);
+        __ stb(O3, to, 0);
+        __ br(Assembler::notZero, false, Assembler::pt, L_align);
+        __ delayed()->inc(to);
+      __ BIND(L_skip_alignment);
+      }
+      if (!aligned) {
+        // Copy with shift 16 bytes per iteration if arrays do not have
+        // the same alignment mod 8, otherwise fall through to the next
+        // code for aligned copy.
+        // The compare above (count >= 23) guarantes 'count' >= 16 bytes.
+        // Also jump over aligned copy after the copy with shift completed.
+
+        copy_16_bytes_forward_with_shift(from, to, count, 0, L_copy_byte);
+      }
+
+      // Both array are 8 bytes aligned, copy 16 bytes at a time
       __ and3(count, 7, G4); // Save count
       __ srl(count, 3, count);
-     generate_disjoint_long_copy_core(aligned);
+      generate_disjoint_long_copy_core(aligned);
       __ mov(G4, count);     // Restore count
 
-    // copy tailing bytes
-    __ BIND(L_copy_byte);
-      __ cmp_and_br_short(count, 0, Assembler::equal, Assembler::pt, L_exit);
-      __ align(OptoLoopAlignment);
-    __ BIND(L_copy_byte_loop);
-      __ ldub(from, offset, O3);
-      __ deccc(count);
-      __ stb(O3, to, offset);
-      __ brx(Assembler::notZero, false, Assembler::pt, L_copy_byte_loop);
-      __ delayed()->inc(offset);
+      // copy tailing bytes
+      __ BIND(L_copy_byte);
+        __ cmp_and_br_short(count, 0, Assembler::equal, Assembler::pt, L_exit);
+        __ align(OptoLoopAlignment);
+      __ BIND(L_copy_byte_loop);
+        __ ldub(from, offset, O3);
+        __ deccc(count);
+        __ stb(O3, to, offset);
+        __ brx(Assembler::notZero, false, Assembler::pt, L_copy_byte_loop);
+        __ delayed()->inc(offset);
+    }
 
     __ BIND(L_exit);
       // O3, O4 are used as temp registers
@@ -1207,70 +1223,75 @@
 
     array_overlap_test(nooverlap_target, 0);
 
-    __ add(to, count, end_to);       // offset after last copied element
-
-    // for short arrays, just do single element copy
-    __ cmp(count, 23); // 16 + 7
-    __ brx(Assembler::less, false, Assembler::pn, L_copy_byte);
-    __ delayed()->add(from, count, end_from);
-
     {
-      // Align end of arrays since they could be not aligned even
-      // when arrays itself are aligned.
-
-      // copy bytes to align 'end_to' on 8 byte boundary
-      __ andcc(end_to, 7, G1); // misaligned bytes
-      __ br(Assembler::zero, false, Assembler::pt, L_skip_alignment);
-      __ delayed()->nop();
-      __ sub(count, G1, count);
-    __ BIND(L_align);
-      __ dec(end_from);
-      __ dec(end_to);
-      __ ldub(end_from, 0, O3);
-      __ deccc(G1);
-      __ brx(Assembler::notZero, false, Assembler::pt, L_align);
-      __ delayed()->stb(O3, end_to, 0);
-    __ BIND(L_skip_alignment);
+      // UnsafeCopyMemory page error: continue at UnsafeCopyMemory common_error_exit
+      UnsafeCopyMemoryMark ucmm(this, !aligned, false);
+
+      __ add(to, count, end_to);       // offset after last copied element
+
+      // for short arrays, just do single element copy
+      __ cmp(count, 23); // 16 + 7
+      __ brx(Assembler::less, false, Assembler::pn, L_copy_byte);
+      __ delayed()->add(from, count, end_from);
+
+      {
+        // Align end of arrays since they could be not aligned even
+        // when arrays itself are aligned.
+
+        // copy bytes to align 'end_to' on 8 byte boundary
+        __ andcc(end_to, 7, G1); // misaligned bytes
+        __ br(Assembler::zero, false, Assembler::pt, L_skip_alignment);
+        __ delayed()->nop();
+        __ sub(count, G1, count);
+      __ BIND(L_align);
+        __ dec(end_from);
+        __ dec(end_to);
+        __ ldub(end_from, 0, O3);
+        __ deccc(G1);
+        __ brx(Assembler::notZero, false, Assembler::pt, L_align);
+        __ delayed()->stb(O3, end_to, 0);
+      __ BIND(L_skip_alignment);
+      }
+      if (aligned) {
+        // Both arrays are aligned to 8-bytes in 64-bits VM.
+        // The 'count' is decremented in copy_16_bytes_backward_with_shift()
+        // in unaligned case.
+        __ dec(count, 16);
+      } else {
+        // Copy with shift 16 bytes per iteration if arrays do not have
+        // the same alignment mod 8, otherwise jump to the next
+        // code for aligned copy (and substracting 16 from 'count' before jump).
+        // The compare above (count >= 11) guarantes 'count' >= 16 bytes.
+        // Also jump over aligned copy after the copy with shift completed.
+
+       copy_16_bytes_backward_with_shift(end_from, end_to, count, 16,
+                                          L_aligned_copy, L_copy_byte);
+      }
+      // copy 4 elements (16 bytes) at a time
+        __ align(OptoLoopAlignment);
+      __ BIND(L_aligned_copy);
+        __ dec(end_from, 16);
+        __ ldx(end_from, 8, O3);
+        __ ldx(end_from, 0, O4);
+        __ dec(end_to, 16);
+        __ deccc(count, 16);
+        __ stx(O3, end_to, 8);
+        __ brx(Assembler::greaterEqual, false, Assembler::pt, L_aligned_copy);
+        __ delayed()->stx(O4, end_to, 0);
+        __ inc(count, 16);
+
+      // copy 1 element (2 bytes) at a time
+      __ BIND(L_copy_byte);
+        __ cmp_and_br_short(count, 0, Assembler::equal, Assembler::pt, L_exit);
+        __ align(OptoLoopAlignment);
+      __ BIND(L_copy_byte_loop);
+        __ dec(end_from);
+        __ dec(end_to);
+        __ ldub(end_from, 0, O4);
+        __ deccc(count);
+        __ brx(Assembler::greater, false, Assembler::pt, L_copy_byte_loop);
+        __ delayed()->stb(O4, end_to, 0);
     }
-    if (aligned) {
-      // Both arrays are aligned to 8-bytes in 64-bits VM.
-      // The 'count' is decremented in copy_16_bytes_backward_with_shift()
-      // in unaligned case.
-      __ dec(count, 16);
-    } else {
-      // Copy with shift 16 bytes per iteration if arrays do not have
-      // the same alignment mod 8, otherwise jump to the next
-      // code for aligned copy (and substracting 16 from 'count' before jump).
-      // The compare above (count >= 11) guarantes 'count' >= 16 bytes.
-      // Also jump over aligned copy after the copy with shift completed.
-
-      copy_16_bytes_backward_with_shift(end_from, end_to, count, 16,
-                                        L_aligned_copy, L_copy_byte);
-    }
-    // copy 4 elements (16 bytes) at a time
-      __ align(OptoLoopAlignment);
-    __ BIND(L_aligned_copy);
-      __ dec(end_from, 16);
-      __ ldx(end_from, 8, O3);
-      __ ldx(end_from, 0, O4);
-      __ dec(end_to, 16);
-      __ deccc(count, 16);
-      __ stx(O3, end_to, 8);
-      __ brx(Assembler::greaterEqual, false, Assembler::pt, L_aligned_copy);
-      __ delayed()->stx(O4, end_to, 0);
-      __ inc(count, 16);
-
-    // copy 1 element (2 bytes) at a time
-    __ BIND(L_copy_byte);
-      __ cmp_and_br_short(count, 0, Assembler::equal, Assembler::pt, L_exit);
-      __ align(OptoLoopAlignment);
-    __ BIND(L_copy_byte_loop);
-      __ dec(end_from);
-      __ dec(end_to);
-      __ ldub(end_from, 0, O4);
-      __ deccc(count);
-      __ brx(Assembler::greater, false, Assembler::pt, L_copy_byte_loop);
-      __ delayed()->stb(O4, end_to, 0);
 
     __ BIND(L_exit);
     // O3, O4 are used as temp registers
@@ -1311,68 +1332,72 @@
       BLOCK_COMMENT("Entry:");
     }
 
-    // for short arrays, just do single element copy
-    __ cmp(count, 11); // 8 + 3  (22 bytes)
-    __ brx(Assembler::less, false, Assembler::pn, L_copy_2_bytes);
-    __ delayed()->mov(G0, offset);
-
-    if (aligned) {
-      // 'aligned' == true when it is known statically during compilation
-      // of this arraycopy call site that both 'from' and 'to' addresses
-      // are HeapWordSize aligned (see LibraryCallKit::basictype2arraycopy()).
-      //
-      // Aligned arrays have 4 bytes alignment in 32-bits VM
-      // and 8 bytes - in 64-bits VM.
-      //
-    } else {
-      // copy 1 element if necessary to align 'to' on an 4 bytes
-      __ andcc(to, 3, G0);
-      __ br(Assembler::zero, false, Assembler::pt, L_skip_alignment);
-      __ delayed()->lduh(from, 0, O3);
-      __ inc(from, 2);
-      __ inc(to, 2);
-      __ dec(count);
-      __ sth(O3, to, -2);
-    __ BIND(L_skip_alignment);
-
-      // copy 2 elements to align 'to' on an 8 byte boundary
-      __ andcc(to, 7, G0);
-      __ br(Assembler::zero, false, Assembler::pn, L_skip_alignment2);
-      __ delayed()->lduh(from, 0, O3);
-      __ dec(count, 2);
-      __ lduh(from, 2, O4);
-      __ inc(from, 4);
-      __ inc(to, 4);
-      __ sth(O3, to, -4);
-      __ sth(O4, to, -2);
-    __ BIND(L_skip_alignment2);
+    {
+      // UnsafeCopyMemory page error: continue at UnsafeCopyMemory common_error_exit
+      UnsafeCopyMemoryMark ucmm(this, !aligned, false);
+      // for short arrays, just do single element copy
+      __ cmp(count, 11); // 8 + 3  (22 bytes)
+      __ brx(Assembler::less, false, Assembler::pn, L_copy_2_bytes);
+      __ delayed()->mov(G0, offset);
+
+      if (aligned) {
+        // 'aligned' == true when it is known statically during compilation
+        // of this arraycopy call site that both 'from' and 'to' addresses
+        // are HeapWordSize aligned (see LibraryCallKit::basictype2arraycopy()).
+        //
+        // Aligned arrays have 4 bytes alignment in 32-bits VM
+        // and 8 bytes - in 64-bits VM.
+        //
+      } else {
+        // copy 1 element if necessary to align 'to' on an 4 bytes
+        __ andcc(to, 3, G0);
+        __ br(Assembler::zero, false, Assembler::pt, L_skip_alignment);
+        __ delayed()->lduh(from, 0, O3);
+        __ inc(from, 2);
+        __ inc(to, 2);
+        __ dec(count);
+        __ sth(O3, to, -2);
+      __ BIND(L_skip_alignment);
+
+        // copy 2 elements to align 'to' on an 8 byte boundary
+        __ andcc(to, 7, G0);
+        __ br(Assembler::zero, false, Assembler::pn, L_skip_alignment2);
+        __ delayed()->lduh(from, 0, O3);
+        __ dec(count, 2);
+        __ lduh(from, 2, O4);
+        __ inc(from, 4);
+        __ inc(to, 4);
+        __ sth(O3, to, -4);
+        __ sth(O4, to, -2);
+      __ BIND(L_skip_alignment2);
+      }
+      if (!aligned) {
+        // Copy with shift 16 bytes per iteration if arrays do not have
+        // the same alignment mod 8, otherwise fall through to the next
+        // code for aligned copy.
+        // The compare above (count >= 11) guarantes 'count' >= 16 bytes.
+        // Also jump over aligned copy after the copy with shift completed.
+
+        copy_16_bytes_forward_with_shift(from, to, count, 1, L_copy_2_bytes);
+      }
+
+      // Both array are 8 bytes aligned, copy 16 bytes at a time
+        __ and3(count, 3, G4); // Save
+        __ srl(count, 2, count);
+       generate_disjoint_long_copy_core(aligned);
+        __ mov(G4, count); // restore
+
+      // copy 1 element at a time
+      __ BIND(L_copy_2_bytes);
+        __ cmp_and_br_short(count, 0, Assembler::equal, Assembler::pt, L_exit);
+        __ align(OptoLoopAlignment);
+      __ BIND(L_copy_2_bytes_loop);
+        __ lduh(from, offset, O3);
+        __ deccc(count);
+        __ sth(O3, to, offset);
+        __ brx(Assembler::notZero, false, Assembler::pt, L_copy_2_bytes_loop);
+        __ delayed()->inc(offset, 2);
     }
-    if (!aligned) {
-      // Copy with shift 16 bytes per iteration if arrays do not have
-      // the same alignment mod 8, otherwise fall through to the next
-      // code for aligned copy.
-      // The compare above (count >= 11) guarantes 'count' >= 16 bytes.
-      // Also jump over aligned copy after the copy with shift completed.
-
-      copy_16_bytes_forward_with_shift(from, to, count, 1, L_copy_2_bytes);
-    }
-
-    // Both array are 8 bytes aligned, copy 16 bytes at a time
-      __ and3(count, 3, G4); // Save
-      __ srl(count, 2, count);
-     generate_disjoint_long_copy_core(aligned);
-      __ mov(G4, count); // restore
-
-    // copy 1 element at a time
-    __ BIND(L_copy_2_bytes);
-      __ cmp_and_br_short(count, 0, Assembler::equal, Assembler::pt, L_exit);
-      __ align(OptoLoopAlignment);
-    __ BIND(L_copy_2_bytes_loop);
-      __ lduh(from, offset, O3);
-      __ deccc(count);
-      __ sth(O3, to, offset);
-      __ brx(Assembler::notZero, false, Assembler::pt, L_copy_2_bytes_loop);
-      __ delayed()->inc(offset, 2);
 
     __ BIND(L_exit);
       // O3, O4 are used as temp registers
@@ -1639,79 +1664,83 @@
 
     array_overlap_test(nooverlap_target, 1);
 
-    __ sllx(count, LogBytesPerShort, byte_count);
-    __ add(to, byte_count, end_to);  // offset after last copied element
-
-    // for short arrays, just do single element copy
-    __ cmp(count, 11); // 8 + 3  (22 bytes)
-    __ brx(Assembler::less, false, Assembler::pn, L_copy_2_bytes);
-    __ delayed()->add(from, byte_count, end_from);
-
     {
-      // Align end of arrays since they could be not aligned even
-      // when arrays itself are aligned.
-
-      // copy 1 element if necessary to align 'end_to' on an 4 bytes
-      __ andcc(end_to, 3, G0);
-      __ br(Assembler::zero, false, Assembler::pt, L_skip_alignment);
-      __ delayed()->lduh(end_from, -2, O3);
-      __ dec(end_from, 2);
-      __ dec(end_to, 2);
-      __ dec(count);
-      __ sth(O3, end_to, 0);
-    __ BIND(L_skip_alignment);
-
-      // copy 2 elements to align 'end_to' on an 8 byte boundary
-      __ andcc(end_to, 7, G0);
-      __ br(Assembler::zero, false, Assembler::pn, L_skip_alignment2);
-      __ delayed()->lduh(end_from, -2, O3);
-      __ dec(count, 2);
-      __ lduh(end_from, -4, O4);
-      __ dec(end_from, 4);
-      __ dec(end_to, 4);
-      __ sth(O3, end_to, 2);
-      __ sth(O4, end_to, 0);
-    __ BIND(L_skip_alignment2);
+      // UnsafeCopyMemory page error: continue at UnsafeCopyMemory common_error_exit
+      UnsafeCopyMemoryMark ucmm(this, !aligned, false);
+
+      __ sllx(count, LogBytesPerShort, byte_count);
+      __ add(to, byte_count, end_to);  // offset after last copied element
+
+      // for short arrays, just do single element copy
+      __ cmp(count, 11); // 8 + 3  (22 bytes)
+      __ brx(Assembler::less, false, Assembler::pn, L_copy_2_bytes);
+      __ delayed()->add(from, byte_count, end_from);
+
+      {
+        // Align end of arrays since they could be not aligned even
+        // when arrays itself are aligned.
+
+        // copy 1 element if necessary to align 'end_to' on an 4 bytes
+        __ andcc(end_to, 3, G0);
+        __ br(Assembler::zero, false, Assembler::pt, L_skip_alignment);
+        __ delayed()->lduh(end_from, -2, O3);
+        __ dec(end_from, 2);
+        __ dec(end_to, 2);
+        __ dec(count);
+        __ sth(O3, end_to, 0);
+      __ BIND(L_skip_alignment);
+
+        // copy 2 elements to align 'end_to' on an 8 byte boundary
+        __ andcc(end_to, 7, G0);
+        __ br(Assembler::zero, false, Assembler::pn, L_skip_alignment2);
+        __ delayed()->lduh(end_from, -2, O3);
+        __ dec(count, 2);
+        __ lduh(end_from, -4, O4);
+        __ dec(end_from, 4);
+        __ dec(end_to, 4);
+        __ sth(O3, end_to, 2);
+        __ sth(O4, end_to, 0);
+      __ BIND(L_skip_alignment2);
+      }
+      if (aligned) {
+        // Both arrays are aligned to 8-bytes in 64-bits VM.
+        // The 'count' is decremented in copy_16_bytes_backward_with_shift()
+        // in unaligned case.
+        __ dec(count, 8);
+      } else {
+        // Copy with shift 16 bytes per iteration if arrays do not have
+        // the same alignment mod 8, otherwise jump to the next
+        // code for aligned copy (and substracting 8 from 'count' before jump).
+        // The compare above (count >= 11) guarantes 'count' >= 16 bytes.
+        // Also jump over aligned copy after the copy with shift completed.
+
+        copy_16_bytes_backward_with_shift(end_from, end_to, count, 8,
+                                        L_aligned_copy, L_copy_2_bytes);
+      }
+      // copy 4 elements (16 bytes) at a time
+        __ align(OptoLoopAlignment);
+      __ BIND(L_aligned_copy);
+        __ dec(end_from, 16);
+        __ ldx(end_from, 8, O3);
+        __ ldx(end_from, 0, O4);
+        __ dec(end_to, 16);
+        __ deccc(count, 8);
+        __ stx(O3, end_to, 8);
+        __ brx(Assembler::greaterEqual, false, Assembler::pt, L_aligned_copy);
+        __ delayed()->stx(O4, end_to, 0);
+        __ inc(count, 8);
+
+      // copy 1 element (2 bytes) at a time
+      __ BIND(L_copy_2_bytes);
+        __ cmp_and_br_short(count, 0, Assembler::equal, Assembler::pt, L_exit);
+      __ BIND(L_copy_2_bytes_loop);
+        __ dec(end_from, 2);
+        __ dec(end_to, 2);
+        __ lduh(end_from, 0, O4);
+        __ deccc(count);
+        __ brx(Assembler::greater, false, Assembler::pt, L_copy_2_bytes_loop);
+        __ delayed()->sth(O4, end_to, 0);
     }
-    if (aligned) {
-      // Both arrays are aligned to 8-bytes in 64-bits VM.
-      // The 'count' is decremented in copy_16_bytes_backward_with_shift()
-      // in unaligned case.
-      __ dec(count, 8);
-    } else {
-      // Copy with shift 16 bytes per iteration if arrays do not have
-      // the same alignment mod 8, otherwise jump to the next
-      // code for aligned copy (and substracting 8 from 'count' before jump).
-      // The compare above (count >= 11) guarantes 'count' >= 16 bytes.
-      // Also jump over aligned copy after the copy with shift completed.
-
-      copy_16_bytes_backward_with_shift(end_from, end_to, count, 8,
-                                        L_aligned_copy, L_copy_2_bytes);
-    }
-    // copy 4 elements (16 bytes) at a time
-      __ align(OptoLoopAlignment);
-    __ BIND(L_aligned_copy);
-      __ dec(end_from, 16);
-      __ ldx(end_from, 8, O3);
-      __ ldx(end_from, 0, O4);
-      __ dec(end_to, 16);
-      __ deccc(count, 8);
-      __ stx(O3, end_to, 8);
-      __ brx(Assembler::greaterEqual, false, Assembler::pt, L_aligned_copy);
-      __ delayed()->stx(O4, end_to, 0);
-      __ inc(count, 8);
-
-    // copy 1 element (2 bytes) at a time
-    __ BIND(L_copy_2_bytes);
-      __ cmp_and_br_short(count, 0, Assembler::equal, Assembler::pt, L_exit);
-    __ BIND(L_copy_2_bytes_loop);
-      __ dec(end_from, 2);
-      __ dec(end_to, 2);
-      __ lduh(end_from, 0, O4);
-      __ deccc(count);
-      __ brx(Assembler::greater, false, Assembler::pt, L_copy_2_bytes_loop);
-      __ delayed()->sth(O4, end_to, 0);
-
     __ BIND(L_exit);
     // O3, O4 are used as temp registers
     inc_counter_np(SharedRuntime::_jshort_array_copy_ctr, O3, O4);
@@ -1870,9 +1899,11 @@
       // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
       BLOCK_COMMENT("Entry:");
     }
-
-    generate_disjoint_int_copy_core(aligned);
-
+    {
+      // UnsafeCopyMemory page error: continue at UnsafeCopyMemory common_error_exit
+      UnsafeCopyMemoryMark ucmm(this, !aligned, false);
+      generate_disjoint_int_copy_core(aligned);
+    }
     // O3, O4 are used as temp registers
     inc_counter_np(SharedRuntime::_jint_array_copy_ctr, O3, O4);
     __ retl();
@@ -2005,9 +2036,11 @@
     }
 
     array_overlap_test(nooverlap_target, 2);
-
-    generate_conjoint_int_copy_core(aligned);
-
+    {
+      // UnsafeCopyMemory page error: continue at UnsafeCopyMemory common_error_exit
+      UnsafeCopyMemoryMark ucmm(this, !aligned, false);
+      generate_conjoint_int_copy_core(aligned);
+    }
     // O3, O4 are used as temp registers
     inc_counter_np(SharedRuntime::_jint_array_copy_ctr, O3, O4);
     __ retl();
@@ -2156,8 +2189,11 @@
       BLOCK_COMMENT("Entry:");
     }
 
-    generate_disjoint_long_copy_core(aligned);
-
+    {
+      // UnsafeCopyMemory page error: continue at UnsafeCopyMemory common_error_exit
+      UnsafeCopyMemoryMark ucmm(this, true, false);
+      generate_disjoint_long_copy_core(aligned);
+    }
     // O3, O4 are used as temp registers
     inc_counter_np(SharedRuntime::_jlong_array_copy_ctr, O3, O4);
     __ retl();
@@ -2232,9 +2268,11 @@
     }
 
     array_overlap_test(nooverlap_target, 3);
-
-    generate_conjoint_long_copy_core(aligned);
-
+    {
+      // UnsafeCopyMemory page error: continue at UnsafeCopyMemory common_error_exit
+      UnsafeCopyMemoryMark ucmm(this, true, false);
+      generate_conjoint_long_copy_core(aligned);
+    }
     // O3, O4 are used as temp registers
     inc_counter_np(SharedRuntime::_jlong_array_copy_ctr, O3, O4);
     __ retl();
@@ -2929,6 +2967,9 @@
     address entry_jlong_arraycopy;
     address entry_checkcast_arraycopy;
 
+    address ucm_common_error_exit       =  generate_unsafecopy_common_error_exit();
+    UnsafeCopyMemory::set_common_exit_stub_pc(ucm_common_error_exit);
+
     //*** jbyte
     // Always need aligned and unaligned versions
     StubRoutines::_jbyte_disjoint_arraycopy         = generate_disjoint_byte_copy(false, &entry,
@@ -5821,6 +5862,10 @@
 
 }; // end class declaration
 
+#define UCM_TABLE_MAX_ENTRIES 8
 void StubGenerator_generate(CodeBuffer* code, bool all) {
+  if (UnsafeCopyMemory::_table == NULL) {
+    UnsafeCopyMemory::create_table(UCM_TABLE_MAX_ENTRIES);
+  }
   StubGenerator g(code, all);
 }
--- a/src/hotspot/cpu/x86/assembler_x86.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/cpu/x86/assembler_x86.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -789,6 +789,8 @@
     case 0x59: // mulpd
     case 0x6E: // movd
     case 0x7E: // movd
+    case 0x6F: // movdq
+    case 0x7F: // movdq
     case 0xAE: // ldmxcsr, stmxcsr, fxrstor, fxsave, clflush
     case 0xFE: // paddd
       debug_only(has_disp32 = true);
@@ -4274,6 +4276,7 @@
   emit_operand(dst, src);
   emit_int8(mode & 0xFF);
 }
+
 void Assembler::evshufi64x2(XMMRegister dst, XMMRegister nds, XMMRegister src, int imm8, int vector_len) {
   assert(VM_Version::supports_evex(), "requires EVEX support");
   assert(vector_len == Assembler::AVX_256bit || vector_len == Assembler::AVX_512bit, "");
--- a/src/hotspot/cpu/x86/stubGenerator_x86_32.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/cpu/x86/stubGenerator_x86_32.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -889,91 +889,98 @@
 
     BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
     bs->arraycopy_prologue(_masm, decorators, t, from, to, count);
-
-    __ subptr(to, from); // to --> to_from
-    __ cmpl(count, 2<<shift); // Short arrays (< 8 bytes) copy by element
-    __ jcc(Assembler::below, L_copy_4_bytes); // use unsigned cmp
-    if (!UseUnalignedLoadStores && !aligned && (t == T_BYTE || t == T_SHORT)) {
-      // align source address at 4 bytes address boundary
-      if (t == T_BYTE) {
-        // One byte misalignment happens only for byte arrays
-        __ testl(from, 1);
-        __ jccb(Assembler::zero, L_skip_align1);
-        __ movb(rax, Address(from, 0));
-        __ movb(Address(from, to_from, Address::times_1, 0), rax);
-        __ increment(from);
-        __ decrement(count);
-      __ BIND(L_skip_align1);
+    {
+      bool add_entry = (t != T_OBJECT && (!aligned || t == T_INT));
+      // UnsafeCopyMemory page error: continue after ucm
+      UnsafeCopyMemoryMark ucmm(this, add_entry, true);
+      __ subptr(to, from); // to --> to_from
+      __ cmpl(count, 2<<shift); // Short arrays (< 8 bytes) copy by element
+      __ jcc(Assembler::below, L_copy_4_bytes); // use unsigned cmp
+      if (!UseUnalignedLoadStores && !aligned && (t == T_BYTE || t == T_SHORT)) {
+        // align source address at 4 bytes address boundary
+        if (t == T_BYTE) {
+          // One byte misalignment happens only for byte arrays
+          __ testl(from, 1);
+          __ jccb(Assembler::zero, L_skip_align1);
+          __ movb(rax, Address(from, 0));
+          __ movb(Address(from, to_from, Address::times_1, 0), rax);
+          __ increment(from);
+          __ decrement(count);
+        __ BIND(L_skip_align1);
+        }
+        // Two bytes misalignment happens only for byte and short (char) arrays
+        __ testl(from, 2);
+        __ jccb(Assembler::zero, L_skip_align2);
+        __ movw(rax, Address(from, 0));
+        __ movw(Address(from, to_from, Address::times_1, 0), rax);
+        __ addptr(from, 2);
+        __ subl(count, 1<<(shift-1));
+      __ BIND(L_skip_align2);
       }
-      // Two bytes misalignment happens only for byte and short (char) arrays
-      __ testl(from, 2);
-      __ jccb(Assembler::zero, L_skip_align2);
-      __ movw(rax, Address(from, 0));
-      __ movw(Address(from, to_from, Address::times_1, 0), rax);
-      __ addptr(from, 2);
-      __ subl(count, 1<<(shift-1));
-    __ BIND(L_skip_align2);
-    }
-    if (!VM_Version::supports_mmx()) {
-      __ mov(rax, count);      // save 'count'
-      __ shrl(count, shift); // bytes count
-      __ addptr(to_from, from);// restore 'to'
-      __ rep_mov();
-      __ subptr(to_from, from);// restore 'to_from'
-      __ mov(count, rax);      // restore 'count'
-      __ jmpb(L_copy_2_bytes); // all dwords were copied
-    } else {
-      if (!UseUnalignedLoadStores) {
-        // align to 8 bytes, we know we are 4 byte aligned to start
-        __ testptr(from, 4);
-        __ jccb(Assembler::zero, L_copy_64_bytes);
-        __ movl(rax, Address(from, 0));
-        __ movl(Address(from, to_from, Address::times_1, 0), rax);
+      if (!VM_Version::supports_mmx()) {
+        __ mov(rax, count);      // save 'count'
+        __ shrl(count, shift); // bytes count
+        __ addptr(to_from, from);// restore 'to'
+        __ rep_mov();
+        __ subptr(to_from, from);// restore 'to_from'
+        __ mov(count, rax);      // restore 'count'
+        __ jmpb(L_copy_2_bytes); // all dwords were copied
+      } else {
+        if (!UseUnalignedLoadStores) {
+          // align to 8 bytes, we know we are 4 byte aligned to start
+          __ testptr(from, 4);
+          __ jccb(Assembler::zero, L_copy_64_bytes);
+          __ movl(rax, Address(from, 0));
+          __ movl(Address(from, to_from, Address::times_1, 0), rax);
+          __ addptr(from, 4);
+          __ subl(count, 1<<shift);
+         }
+      __ BIND(L_copy_64_bytes);
+        __ mov(rax, count);
+        __ shrl(rax, shift+1);  // 8 bytes chunk count
+        //
+        // Copy 8-byte chunks through MMX registers, 8 per iteration of the loop
+        //
+        if (UseXMMForArrayCopy) {
+          xmm_copy_forward(from, to_from, rax);
+        } else {
+          mmx_copy_forward(from, to_from, rax);
+        }
+      }
+      // copy tailing dword
+    __ BIND(L_copy_4_bytes);
+      __ testl(count, 1<<shift);
+      __ jccb(Assembler::zero, L_copy_2_bytes);
+      __ movl(rax, Address(from, 0));
+      __ movl(Address(from, to_from, Address::times_1, 0), rax);
+      if (t == T_BYTE || t == T_SHORT) {
         __ addptr(from, 4);
-        __ subl(count, 1<<shift);
-      }
-    __ BIND(L_copy_64_bytes);
-      __ mov(rax, count);
-      __ shrl(rax, shift+1);  // 8 bytes chunk count
-      //
-      // Copy 8-byte chunks through MMX registers, 8 per iteration of the loop
-      //
-      if (UseXMMForArrayCopy) {
-        xmm_copy_forward(from, to_from, rax);
+      __ BIND(L_copy_2_bytes);
+        // copy tailing word
+        __ testl(count, 1<<(shift-1));
+        __ jccb(Assembler::zero, L_copy_byte);
+        __ movw(rax, Address(from, 0));
+        __ movw(Address(from, to_from, Address::times_1, 0), rax);
+        if (t == T_BYTE) {
+          __ addptr(from, 2);
+        __ BIND(L_copy_byte);
+          // copy tailing byte
+          __ testl(count, 1);
+          __ jccb(Assembler::zero, L_exit);
+          __ movb(rax, Address(from, 0));
+          __ movb(Address(from, to_from, Address::times_1, 0), rax);
+        __ BIND(L_exit);
+        } else {
+        __ BIND(L_copy_byte);
+        }
       } else {
-        mmx_copy_forward(from, to_from, rax);
+      __ BIND(L_copy_2_bytes);
       }
     }
-    // copy tailing dword
-  __ BIND(L_copy_4_bytes);
-    __ testl(count, 1<<shift);
-    __ jccb(Assembler::zero, L_copy_2_bytes);
-    __ movl(rax, Address(from, 0));
-    __ movl(Address(from, to_from, Address::times_1, 0), rax);
-    if (t == T_BYTE || t == T_SHORT) {
-      __ addptr(from, 4);
-    __ BIND(L_copy_2_bytes);
-      // copy tailing word
-      __ testl(count, 1<<(shift-1));
-      __ jccb(Assembler::zero, L_copy_byte);
-      __ movw(rax, Address(from, 0));
-      __ movw(Address(from, to_from, Address::times_1, 0), rax);
-      if (t == T_BYTE) {
-        __ addptr(from, 2);
-      __ BIND(L_copy_byte);
-        // copy tailing byte
-        __ testl(count, 1);
-        __ jccb(Assembler::zero, L_exit);
-        __ movb(rax, Address(from, 0));
-        __ movb(Address(from, to_from, Address::times_1, 0), rax);
-      __ BIND(L_exit);
-      } else {
-      __ BIND(L_copy_byte);
-      }
-    } else {
-    __ BIND(L_copy_2_bytes);
+
+    if (VM_Version::supports_mmx() && !UseXMMForArrayCopy) {
+      __ emms();
     }
-
     __ movl(count, Address(rsp, 12+12)); // reread 'count'
     bs->arraycopy_epilogue(_masm, decorators, t, from, to, count);
 
@@ -1079,104 +1086,112 @@
     BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
     bs->arraycopy_prologue(_masm, decorators, t, from, to, count);
 
-    // copy from high to low
-    __ cmpl(count, 2<<shift); // Short arrays (< 8 bytes) copy by element
-    __ jcc(Assembler::below, L_copy_4_bytes); // use unsigned cmp
-    if (t == T_BYTE || t == T_SHORT) {
-      // Align the end of destination array at 4 bytes address boundary
-      __ lea(end, Address(dst, count, sf, 0));
-      if (t == T_BYTE) {
-        // One byte misalignment happens only for byte arrays
-        __ testl(end, 1);
-        __ jccb(Assembler::zero, L_skip_align1);
-        __ decrement(count);
-        __ movb(rdx, Address(from, count, sf, 0));
-        __ movb(Address(to, count, sf, 0), rdx);
-      __ BIND(L_skip_align1);
-      }
-      // Two bytes misalignment happens only for byte and short (char) arrays
-      __ testl(end, 2);
-      __ jccb(Assembler::zero, L_skip_align2);
-      __ subptr(count, 1<<(shift-1));
-      __ movw(rdx, Address(from, count, sf, 0));
-      __ movw(Address(to, count, sf, 0), rdx);
-    __ BIND(L_skip_align2);
+    {
+      bool add_entry = (t != T_OBJECT && (!aligned || t == T_INT));
+      // UnsafeCopyMemory page error: continue after ucm
+      UnsafeCopyMemoryMark ucmm(this, add_entry, true);
+      // copy from high to low
       __ cmpl(count, 2<<shift); // Short arrays (< 8 bytes) copy by element
-      __ jcc(Assembler::below, L_copy_4_bytes);
-    }
-
-    if (!VM_Version::supports_mmx()) {
-      __ std();
-      __ mov(rax, count); // Save 'count'
-      __ mov(rdx, to);    // Save 'to'
-      __ lea(rsi, Address(from, count, sf, -4));
-      __ lea(rdi, Address(to  , count, sf, -4));
-      __ shrptr(count, shift); // bytes count
-      __ rep_mov();
-      __ cld();
-      __ mov(count, rax); // restore 'count'
-      __ andl(count, (1<<shift)-1);      // mask the number of rest elements
-      __ movptr(from, Address(rsp, 12+4)); // reread 'from'
-      __ mov(to, rdx);   // restore 'to'
-      __ jmpb(L_copy_2_bytes); // all dword were copied
-   } else {
-      // Align to 8 bytes the end of array. It is aligned to 4 bytes already.
-      __ testptr(end, 4);
-      __ jccb(Assembler::zero, L_copy_8_bytes);
-      __ subl(count, 1<<shift);
-      __ movl(rdx, Address(from, count, sf, 0));
-      __ movl(Address(to, count, sf, 0), rdx);
-      __ jmpb(L_copy_8_bytes);
-
-      __ align(OptoLoopAlignment);
-      // Move 8 bytes
-    __ BIND(L_copy_8_bytes_loop);
-      if (UseXMMForArrayCopy) {
-        __ movq(xmm0, Address(from, count, sf, 0));
-        __ movq(Address(to, count, sf, 0), xmm0);
+      __ jcc(Assembler::below, L_copy_4_bytes); // use unsigned cmp
+      if (t == T_BYTE || t == T_SHORT) {
+        // Align the end of destination array at 4 bytes address boundary
+        __ lea(end, Address(dst, count, sf, 0));
+        if (t == T_BYTE) {
+          // One byte misalignment happens only for byte arrays
+          __ testl(end, 1);
+          __ jccb(Assembler::zero, L_skip_align1);
+          __ decrement(count);
+          __ movb(rdx, Address(from, count, sf, 0));
+          __ movb(Address(to, count, sf, 0), rdx);
+        __ BIND(L_skip_align1);
+        }
+        // Two bytes misalignment happens only for byte and short (char) arrays
+        __ testl(end, 2);
+        __ jccb(Assembler::zero, L_skip_align2);
+        __ subptr(count, 1<<(shift-1));
+        __ movw(rdx, Address(from, count, sf, 0));
+        __ movw(Address(to, count, sf, 0), rdx);
+      __ BIND(L_skip_align2);
+        __ cmpl(count, 2<<shift); // Short arrays (< 8 bytes) copy by element
+        __ jcc(Assembler::below, L_copy_4_bytes);
+      }
+
+      if (!VM_Version::supports_mmx()) {
+        __ std();
+        __ mov(rax, count); // Save 'count'
+        __ mov(rdx, to);    // Save 'to'
+        __ lea(rsi, Address(from, count, sf, -4));
+        __ lea(rdi, Address(to  , count, sf, -4));
+        __ shrptr(count, shift); // bytes count
+        __ rep_mov();
+        __ cld();
+        __ mov(count, rax); // restore 'count'
+        __ andl(count, (1<<shift)-1);      // mask the number of rest elements
+        __ movptr(from, Address(rsp, 12+4)); // reread 'from'
+        __ mov(to, rdx);   // restore 'to'
+        __ jmpb(L_copy_2_bytes); // all dword were copied
       } else {
-        __ movq(mmx0, Address(from, count, sf, 0));
-        __ movq(Address(to, count, sf, 0), mmx0);
+        // Align to 8 bytes the end of array. It is aligned to 4 bytes already.
+        __ testptr(end, 4);
+        __ jccb(Assembler::zero, L_copy_8_bytes);
+        __ subl(count, 1<<shift);
+        __ movl(rdx, Address(from, count, sf, 0));
+        __ movl(Address(to, count, sf, 0), rdx);
+        __ jmpb(L_copy_8_bytes);
+
+        __ align(OptoLoopAlignment);
+        // Move 8 bytes
+      __ BIND(L_copy_8_bytes_loop);
+        if (UseXMMForArrayCopy) {
+          __ movq(xmm0, Address(from, count, sf, 0));
+          __ movq(Address(to, count, sf, 0), xmm0);
+        } else {
+          __ movq(mmx0, Address(from, count, sf, 0));
+          __ movq(Address(to, count, sf, 0), mmx0);
+        }
+      __ BIND(L_copy_8_bytes);
+        __ subl(count, 2<<shift);
+        __ jcc(Assembler::greaterEqual, L_copy_8_bytes_loop);
+        __ addl(count, 2<<shift);
+        if (!UseXMMForArrayCopy) {
+          __ emms();
+        }
       }
-    __ BIND(L_copy_8_bytes);
-      __ subl(count, 2<<shift);
-      __ jcc(Assembler::greaterEqual, L_copy_8_bytes_loop);
-      __ addl(count, 2<<shift);
-      if (!UseXMMForArrayCopy) {
-        __ emms();
+    __ BIND(L_copy_4_bytes);
+      // copy prefix qword
+      __ testl(count, 1<<shift);
+      __ jccb(Assembler::zero, L_copy_2_bytes);
+      __ movl(rdx, Address(from, count, sf, -4));
+      __ movl(Address(to, count, sf, -4), rdx);
+
+      if (t == T_BYTE || t == T_SHORT) {
+          __ subl(count, (1<<shift));
+        __ BIND(L_copy_2_bytes);
+          // copy prefix dword
+          __ testl(count, 1<<(shift-1));
+          __ jccb(Assembler::zero, L_copy_byte);
+          __ movw(rdx, Address(from, count, sf, -2));
+          __ movw(Address(to, count, sf, -2), rdx);
+          if (t == T_BYTE) {
+            __ subl(count, 1<<(shift-1));
+          __ BIND(L_copy_byte);
+            // copy prefix byte
+            __ testl(count, 1);
+            __ jccb(Assembler::zero, L_exit);
+            __ movb(rdx, Address(from, 0));
+            __ movb(Address(to, 0), rdx);
+          __ BIND(L_exit);
+          } else {
+          __ BIND(L_copy_byte);
+          }
+      } else {
+      __ BIND(L_copy_2_bytes);
       }
     }
-  __ BIND(L_copy_4_bytes);
-    // copy prefix qword
-    __ testl(count, 1<<shift);
-    __ jccb(Assembler::zero, L_copy_2_bytes);
-    __ movl(rdx, Address(from, count, sf, -4));
-    __ movl(Address(to, count, sf, -4), rdx);
-
-    if (t == T_BYTE || t == T_SHORT) {
-        __ subl(count, (1<<shift));
-      __ BIND(L_copy_2_bytes);
-        // copy prefix dword
-        __ testl(count, 1<<(shift-1));
-        __ jccb(Assembler::zero, L_copy_byte);
-        __ movw(rdx, Address(from, count, sf, -2));
-        __ movw(Address(to, count, sf, -2), rdx);
-        if (t == T_BYTE) {
-          __ subl(count, 1<<(shift-1));
-        __ BIND(L_copy_byte);
-          // copy prefix byte
-          __ testl(count, 1);
-          __ jccb(Assembler::zero, L_exit);
-          __ movb(rdx, Address(from, 0));
-          __ movb(Address(to, 0), rdx);
-        __ BIND(L_exit);
-        } else {
-        __ BIND(L_copy_byte);
-        }
-    } else {
-    __ BIND(L_copy_2_bytes);
+
+    if (VM_Version::supports_mmx() && !UseXMMForArrayCopy) {
+      __ emms();
     }
-
     __ movl2ptr(count, Address(rsp, 12+12)); // reread count
     bs->arraycopy_epilogue(_masm, decorators, t, from, to, count);
 
@@ -1212,23 +1227,30 @@
     *entry = __ pc(); // Entry point from conjoint arraycopy stub.
     BLOCK_COMMENT("Entry:");
 
-    __ subptr(to, from); // to --> to_from
-    if (VM_Version::supports_mmx()) {
-      if (UseXMMForArrayCopy) {
-        xmm_copy_forward(from, to_from, count);
+    {
+      // UnsafeCopyMemory page error: continue after ucm
+      UnsafeCopyMemoryMark ucmm(this, true, true);
+      __ subptr(to, from); // to --> to_from
+      if (VM_Version::supports_mmx()) {
+        if (UseXMMForArrayCopy) {
+          xmm_copy_forward(from, to_from, count);
+        } else {
+          mmx_copy_forward(from, to_from, count);
+        }
       } else {
-        mmx_copy_forward(from, to_from, count);
+        __ jmpb(L_copy_8_bytes);
+        __ align(OptoLoopAlignment);
+      __ BIND(L_copy_8_bytes_loop);
+        __ fild_d(Address(from, 0));
+        __ fistp_d(Address(from, to_from, Address::times_1));
+        __ addptr(from, 8);
+      __ BIND(L_copy_8_bytes);
+        __ decrement(count);
+        __ jcc(Assembler::greaterEqual, L_copy_8_bytes_loop);
       }
-    } else {
-      __ jmpb(L_copy_8_bytes);
-      __ align(OptoLoopAlignment);
-    __ BIND(L_copy_8_bytes_loop);
-      __ fild_d(Address(from, 0));
-      __ fistp_d(Address(from, to_from, Address::times_1));
-      __ addptr(from, 8);
-    __ BIND(L_copy_8_bytes);
-      __ decrement(count);
-      __ jcc(Assembler::greaterEqual, L_copy_8_bytes_loop);
+    }
+    if (VM_Version::supports_mmx() && !UseXMMForArrayCopy) {
+      __ emms();
     }
     inc_copy_counter_np(T_LONG);
     __ leave(); // required for proper stackwalking of RuntimeStub frame
@@ -1267,26 +1289,31 @@
     __ movptr(from, Address(rsp, 8));  // from
     __ jump_cc(Assembler::aboveEqual, nooverlap);
 
-    __ jmpb(L_copy_8_bytes);
-
-    __ align(OptoLoopAlignment);
-  __ BIND(L_copy_8_bytes_loop);
-    if (VM_Version::supports_mmx()) {
-      if (UseXMMForArrayCopy) {
-        __ movq(xmm0, Address(from, count, Address::times_8));
-        __ movq(Address(to, count, Address::times_8), xmm0);
+    {
+      // UnsafeCopyMemory page error: continue after ucm
+      UnsafeCopyMemoryMark ucmm(this, true, true);
+
+      __ jmpb(L_copy_8_bytes);
+
+      __ align(OptoLoopAlignment);
+    __ BIND(L_copy_8_bytes_loop);
+      if (VM_Version::supports_mmx()) {
+        if (UseXMMForArrayCopy) {
+          __ movq(xmm0, Address(from, count, Address::times_8));
+          __ movq(Address(to, count, Address::times_8), xmm0);
+        } else {
+          __ movq(mmx0, Address(from, count, Address::times_8));
+          __ movq(Address(to, count, Address::times_8), mmx0);
+        }
       } else {
-        __ movq(mmx0, Address(from, count, Address::times_8));
-        __ movq(Address(to, count, Address::times_8), mmx0);
+        __ fild_d(Address(from, count, Address::times_8));
+        __ fistp_d(Address(to, count, Address::times_8));
       }
-    } else {
-      __ fild_d(Address(from, count, Address::times_8));
-      __ fistp_d(Address(to, count, Address::times_8));
+    __ BIND(L_copy_8_bytes);
+      __ decrement(count);
+      __ jcc(Assembler::greaterEqual, L_copy_8_bytes_loop);
+
     }
-  __ BIND(L_copy_8_bytes);
-    __ decrement(count);
-    __ jcc(Assembler::greaterEqual, L_copy_8_bytes_loop);
-
     if (VM_Version::supports_mmx() && !UseXMMForArrayCopy) {
       __ emms();
     }
@@ -3945,7 +3972,10 @@
   }
 }; // end class declaration
 
-
+#define UCM_TABLE_MAX_ENTRIES 8
 void StubGenerator_generate(CodeBuffer* code, bool all) {
+  if (UnsafeCopyMemory::_table == NULL) {
+    UnsafeCopyMemory::create_table(UCM_TABLE_MAX_ENTRIES);
+  }
   StubGenerator g(code, all);
 }
--- a/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -1433,7 +1433,6 @@
     __ jcc(Assembler::greater, L_copy_8_bytes); // Copy trailing qwords
   }
 
-
   // Arguments:
   //   aligned - true => Input and output aligned on a HeapWord == 8-byte boundary
   //             ignored
@@ -1482,51 +1481,55 @@
     setup_arg_regs(); // from => rdi, to => rsi, count => rdx
                       // r9 and r10 may be used to save non-volatile registers
 
-    // 'from', 'to' and 'count' are now valid
-    __ movptr(byte_count, count);
-    __ shrptr(count, 3); // count => qword_count
-
-    // Copy from low to high addresses.  Use 'to' as scratch.
-    __ lea(end_from, Address(from, qword_count, Address::times_8, -8));
-    __ lea(end_to,   Address(to,   qword_count, Address::times_8, -8));
-    __ negptr(qword_count); // make the count negative
-    __ jmp(L_copy_bytes);
-
-    // Copy trailing qwords
-  __ BIND(L_copy_8_bytes);
-    __ movq(rax, Address(end_from, qword_count, Address::times_8, 8));
-    __ movq(Address(end_to, qword_count, Address::times_8, 8), rax);
-    __ increment(qword_count);
-    __ jcc(Assembler::notZero, L_copy_8_bytes);
-
-    // Check for and copy trailing dword
-  __ BIND(L_copy_4_bytes);
-    __ testl(byte_count, 4);
-    __ jccb(Assembler::zero, L_copy_2_bytes);
-    __ movl(rax, Address(end_from, 8));
-    __ movl(Address(end_to, 8), rax);
-
-    __ addptr(end_from, 4);
-    __ addptr(end_to, 4);
-
-    // Check for and copy trailing word
-  __ BIND(L_copy_2_bytes);
-    __ testl(byte_count, 2);
-    __ jccb(Assembler::zero, L_copy_byte);
-    __ movw(rax, Address(end_from, 8));
-    __ movw(Address(end_to, 8), rax);
-
-    __ addptr(end_from, 2);
-    __ addptr(end_to, 2);
-
-    // Check for and copy trailing byte
-  __ BIND(L_copy_byte);
-    __ testl(byte_count, 1);
-    __ jccb(Assembler::zero, L_exit);
-    __ movb(rax, Address(end_from, 8));
-    __ movb(Address(end_to, 8), rax);
-
+    {
+      // UnsafeCopyMemory page error: continue after ucm
+      UnsafeCopyMemoryMark ucmm(this, !aligned, true);
+      // 'from', 'to' and 'count' are now valid
+      __ movptr(byte_count, count);
+      __ shrptr(count, 3); // count => qword_count
+
+      // Copy from low to high addresses.  Use 'to' as scratch.
+      __ lea(end_from, Address(from, qword_count, Address::times_8, -8));
+      __ lea(end_to,   Address(to,   qword_count, Address::times_8, -8));
+      __ negptr(qword_count); // make the count negative
+      __ jmp(L_copy_bytes);
+
+      // Copy trailing qwords
+    __ BIND(L_copy_8_bytes);
+      __ movq(rax, Address(end_from, qword_count, Address::times_8, 8));
+      __ movq(Address(end_to, qword_count, Address::times_8, 8), rax);
+      __ increment(qword_count);
+      __ jcc(Assembler::notZero, L_copy_8_bytes);
+
+      // Check for and copy trailing dword
+    __ BIND(L_copy_4_bytes);
+      __ testl(byte_count, 4);
+      __ jccb(Assembler::zero, L_copy_2_bytes);
+      __ movl(rax, Address(end_from, 8));
+      __ movl(Address(end_to, 8), rax);
+
+      __ addptr(end_from, 4);
+      __ addptr(end_to, 4);
+
+      // Check for and copy trailing word
+    __ BIND(L_copy_2_bytes);
+      __ testl(byte_count, 2);
+      __ jccb(Assembler::zero, L_copy_byte);
+      __ movw(rax, Address(end_from, 8));
+      __ movw(Address(end_to, 8), rax);
+
+      __ addptr(end_from, 2);
+      __ addptr(end_to, 2);
+
+      // Check for and copy trailing byte
+    __ BIND(L_copy_byte);
+      __ testl(byte_count, 1);
+      __ jccb(Assembler::zero, L_exit);
+      __ movb(rax, Address(end_from, 8));
+      __ movb(Address(end_to, 8), rax);
+    }
   __ BIND(L_exit);
+    address ucme_exit_pc = __ pc();
     restore_arg_regs();
     inc_counter_np(SharedRuntime::_jbyte_array_copy_ctr); // Update counter after rscratch1 is free
     __ xorptr(rax, rax); // return 0
@@ -1534,10 +1537,12 @@
     __ leave(); // required for proper stackwalking of RuntimeStub frame
     __ ret(0);
 
-    // Copy in multi-bytes chunks
-    copy_bytes_forward(end_from, end_to, qword_count, rax, L_copy_bytes, L_copy_8_bytes);
-    __ jmp(L_copy_4_bytes);
-
+    {
+      UnsafeCopyMemoryMark ucmm(this, !aligned, false, ucme_exit_pc);
+      // Copy in multi-bytes chunks
+      copy_bytes_forward(end_from, end_to, qword_count, rax, L_copy_bytes, L_copy_8_bytes);
+      __ jmp(L_copy_4_bytes);
+    }
     return start;
   }
 
@@ -1582,41 +1587,44 @@
     setup_arg_regs(); // from => rdi, to => rsi, count => rdx
                       // r9 and r10 may be used to save non-volatile registers
 
-    // 'from', 'to' and 'count' are now valid
-    __ movptr(byte_count, count);
-    __ shrptr(count, 3);   // count => qword_count
-
-    // Copy from high to low addresses.
-
-    // Check for and copy trailing byte
-    __ testl(byte_count, 1);
-    __ jcc(Assembler::zero, L_copy_2_bytes);
-    __ movb(rax, Address(from, byte_count, Address::times_1, -1));
-    __ movb(Address(to, byte_count, Address::times_1, -1), rax);
-    __ decrement(byte_count); // Adjust for possible trailing word
-
-    // Check for and copy trailing word
-  __ BIND(L_copy_2_bytes);
-    __ testl(byte_count, 2);
-    __ jcc(Assembler::zero, L_copy_4_bytes);
-    __ movw(rax, Address(from, byte_count, Address::times_1, -2));
-    __ movw(Address(to, byte_count, Address::times_1, -2), rax);
-
-    // Check for and copy trailing dword
-  __ BIND(L_copy_4_bytes);
-    __ testl(byte_count, 4);
-    __ jcc(Assembler::zero, L_copy_bytes);
-    __ movl(rax, Address(from, qword_count, Address::times_8));
-    __ movl(Address(to, qword_count, Address::times_8), rax);
-    __ jmp(L_copy_bytes);
-
-    // Copy trailing qwords
-  __ BIND(L_copy_8_bytes);
-    __ movq(rax, Address(from, qword_count, Address::times_8, -8));
-    __ movq(Address(to, qword_count, Address::times_8, -8), rax);
-    __ decrement(qword_count);
-    __ jcc(Assembler::notZero, L_copy_8_bytes);
-
+    {
+      // UnsafeCopyMemory page error: continue after ucm
+      UnsafeCopyMemoryMark ucmm(this, !aligned, true);
+      // 'from', 'to' and 'count' are now valid
+      __ movptr(byte_count, count);
+      __ shrptr(count, 3);   // count => qword_count
+
+      // Copy from high to low addresses.
+
+      // Check for and copy trailing byte
+      __ testl(byte_count, 1);
+      __ jcc(Assembler::zero, L_copy_2_bytes);
+      __ movb(rax, Address(from, byte_count, Address::times_1, -1));
+      __ movb(Address(to, byte_count, Address::times_1, -1), rax);
+      __ decrement(byte_count); // Adjust for possible trailing word
+
+      // Check for and copy trailing word
+    __ BIND(L_copy_2_bytes);
+      __ testl(byte_count, 2);
+      __ jcc(Assembler::zero, L_copy_4_bytes);
+      __ movw(rax, Address(from, byte_count, Address::times_1, -2));
+      __ movw(Address(to, byte_count, Address::times_1, -2), rax);
+
+      // Check for and copy trailing dword
+    __ BIND(L_copy_4_bytes);
+      __ testl(byte_count, 4);
+      __ jcc(Assembler::zero, L_copy_bytes);
+      __ movl(rax, Address(from, qword_count, Address::times_8));
+      __ movl(Address(to, qword_count, Address::times_8), rax);
+      __ jmp(L_copy_bytes);
+
+      // Copy trailing qwords
+    __ BIND(L_copy_8_bytes);
+      __ movq(rax, Address(from, qword_count, Address::times_8, -8));
+      __ movq(Address(to, qword_count, Address::times_8, -8), rax);
+      __ decrement(qword_count);
+      __ jcc(Assembler::notZero, L_copy_8_bytes);
+    }
     restore_arg_regs();
     inc_counter_np(SharedRuntime::_jbyte_array_copy_ctr); // Update counter after rscratch1 is free
     __ xorptr(rax, rax); // return 0
@@ -1624,9 +1632,12 @@
     __ leave(); // required for proper stackwalking of RuntimeStub frame
     __ ret(0);
 
-    // Copy in multi-bytes chunks
-    copy_bytes_backward(from, to, qword_count, rax, L_copy_bytes, L_copy_8_bytes);
-
+    {
+      // UnsafeCopyMemory page error: continue after ucm
+      UnsafeCopyMemoryMark ucmm(this, !aligned, true);
+      // Copy in multi-bytes chunks
+      copy_bytes_backward(from, to, qword_count, rax, L_copy_bytes, L_copy_8_bytes);
+    }
     restore_arg_regs();
     inc_counter_np(SharedRuntime::_jbyte_array_copy_ctr); // Update counter after rscratch1 is free
     __ xorptr(rax, rax); // return 0
@@ -1684,44 +1695,48 @@
     setup_arg_regs(); // from => rdi, to => rsi, count => rdx
                       // r9 and r10 may be used to save non-volatile registers
 
-    // 'from', 'to' and 'count' are now valid
-    __ movptr(word_count, count);
-    __ shrptr(count, 2); // count => qword_count
-
-    // Copy from low to high addresses.  Use 'to' as scratch.
-    __ lea(end_from, Address(from, qword_count, Address::times_8, -8));
-    __ lea(end_to,   Address(to,   qword_count, Address::times_8, -8));
-    __ negptr(qword_count);
-    __ jmp(L_copy_bytes);
-
-    // Copy trailing qwords
-  __ BIND(L_copy_8_bytes);
-    __ movq(rax, Address(end_from, qword_count, Address::times_8, 8));
-    __ movq(Address(end_to, qword_count, Address::times_8, 8), rax);
-    __ increment(qword_count);
-    __ jcc(Assembler::notZero, L_copy_8_bytes);
-
-    // Original 'dest' is trashed, so we can't use it as a
-    // base register for a possible trailing word copy
-
-    // Check for and copy trailing dword
-  __ BIND(L_copy_4_bytes);
-    __ testl(word_count, 2);
-    __ jccb(Assembler::zero, L_copy_2_bytes);
-    __ movl(rax, Address(end_from, 8));
-    __ movl(Address(end_to, 8), rax);
-
-    __ addptr(end_from, 4);
-    __ addptr(end_to, 4);
-
-    // Check for and copy trailing word
-  __ BIND(L_copy_2_bytes);
-    __ testl(word_count, 1);
-    __ jccb(Assembler::zero, L_exit);
-    __ movw(rax, Address(end_from, 8));
-    __ movw(Address(end_to, 8), rax);
-
+    {
+      // UnsafeCopyMemory page error: continue after ucm
+      UnsafeCopyMemoryMark ucmm(this, !aligned, true);
+      // 'from', 'to' and 'count' are now valid
+      __ movptr(word_count, count);
+      __ shrptr(count, 2); // count => qword_count
+
+      // Copy from low to high addresses.  Use 'to' as scratch.
+      __ lea(end_from, Address(from, qword_count, Address::times_8, -8));
+      __ lea(end_to,   Address(to,   qword_count, Address::times_8, -8));
+      __ negptr(qword_count);
+      __ jmp(L_copy_bytes);
+
+      // Copy trailing qwords
+    __ BIND(L_copy_8_bytes);
+      __ movq(rax, Address(end_from, qword_count, Address::times_8, 8));
+      __ movq(Address(end_to, qword_count, Address::times_8, 8), rax);
+      __ increment(qword_count);
+      __ jcc(Assembler::notZero, L_copy_8_bytes);
+
+      // Original 'dest' is trashed, so we can't use it as a
+      // base register for a possible trailing word copy
+
+      // Check for and copy trailing dword
+    __ BIND(L_copy_4_bytes);
+      __ testl(word_count, 2);
+      __ jccb(Assembler::zero, L_copy_2_bytes);
+      __ movl(rax, Address(end_from, 8));
+      __ movl(Address(end_to, 8), rax);
+
+      __ addptr(end_from, 4);
+      __ addptr(end_to, 4);
+
+      // Check for and copy trailing word
+    __ BIND(L_copy_2_bytes);
+      __ testl(word_count, 1);
+      __ jccb(Assembler::zero, L_exit);
+      __ movw(rax, Address(end_from, 8));
+      __ movw(Address(end_to, 8), rax);
+    }
   __ BIND(L_exit);
+    address ucme_exit_pc = __ pc();
     restore_arg_regs();
     inc_counter_np(SharedRuntime::_jshort_array_copy_ctr); // Update counter after rscratch1 is free
     __ xorptr(rax, rax); // return 0
@@ -1729,9 +1744,12 @@
     __ leave(); // required for proper stackwalking of RuntimeStub frame
     __ ret(0);
 
-    // Copy in multi-bytes chunks
-    copy_bytes_forward(end_from, end_to, qword_count, rax, L_copy_bytes, L_copy_8_bytes);
-    __ jmp(L_copy_4_bytes);
+    {
+      UnsafeCopyMemoryMark ucmm(this, !aligned, false, ucme_exit_pc);
+      // Copy in multi-bytes chunks
+      copy_bytes_forward(end_from, end_to, qword_count, rax, L_copy_bytes, L_copy_8_bytes);
+      __ jmp(L_copy_4_bytes);
+    }
 
     return start;
   }
@@ -1798,33 +1816,36 @@
     setup_arg_regs(); // from => rdi, to => rsi, count => rdx
                       // r9 and r10 may be used to save non-volatile registers
 
-    // 'from', 'to' and 'count' are now valid
-    __ movptr(word_count, count);
-    __ shrptr(count, 2); // count => qword_count
-
-    // Copy from high to low addresses.  Use 'to' as scratch.
-
-    // Check for and copy trailing word
-    __ testl(word_count, 1);
-    __ jccb(Assembler::zero, L_copy_4_bytes);
-    __ movw(rax, Address(from, word_count, Address::times_2, -2));
-    __ movw(Address(to, word_count, Address::times_2, -2), rax);
-
-    // Check for and copy trailing dword
-  __ BIND(L_copy_4_bytes);
-    __ testl(word_count, 2);
-    __ jcc(Assembler::zero, L_copy_bytes);
-    __ movl(rax, Address(from, qword_count, Address::times_8));
-    __ movl(Address(to, qword_count, Address::times_8), rax);
-    __ jmp(L_copy_bytes);
-
-    // Copy trailing qwords
-  __ BIND(L_copy_8_bytes);
-    __ movq(rax, Address(from, qword_count, Address::times_8, -8));
-    __ movq(Address(to, qword_count, Address::times_8, -8), rax);
-    __ decrement(qword_count);
-    __ jcc(Assembler::notZero, L_copy_8_bytes);
-
+    {
+      // UnsafeCopyMemory page error: continue after ucm
+      UnsafeCopyMemoryMark ucmm(this, !aligned, true);
+      // 'from', 'to' and 'count' are now valid
+      __ movptr(word_count, count);
+      __ shrptr(count, 2); // count => qword_count
+
+      // Copy from high to low addresses.  Use 'to' as scratch.
+
+      // Check for and copy trailing word
+      __ testl(word_count, 1);
+      __ jccb(Assembler::zero, L_copy_4_bytes);
+      __ movw(rax, Address(from, word_count, Address::times_2, -2));
+      __ movw(Address(to, word_count, Address::times_2, -2), rax);
+
+     // Check for and copy trailing dword
+    __ BIND(L_copy_4_bytes);
+      __ testl(word_count, 2);
+      __ jcc(Assembler::zero, L_copy_bytes);
+      __ movl(rax, Address(from, qword_count, Address::times_8));
+      __ movl(Address(to, qword_count, Address::times_8), rax);
+      __ jmp(L_copy_bytes);
+
+      // Copy trailing qwords
+    __ BIND(L_copy_8_bytes);
+      __ movq(rax, Address(from, qword_count, Address::times_8, -8));
+      __ movq(Address(to, qword_count, Address::times_8, -8), rax);
+      __ decrement(qword_count);
+      __ jcc(Assembler::notZero, L_copy_8_bytes);
+    }
     restore_arg_regs();
     inc_counter_np(SharedRuntime::_jshort_array_copy_ctr); // Update counter after rscratch1 is free
     __ xorptr(rax, rax); // return 0
@@ -1832,9 +1853,12 @@
     __ leave(); // required for proper stackwalking of RuntimeStub frame
     __ ret(0);
 
-    // Copy in multi-bytes chunks
-    copy_bytes_backward(from, to, qword_count, rax, L_copy_bytes, L_copy_8_bytes);
-
+    {
+      // UnsafeCopyMemory page error: continue after ucm
+      UnsafeCopyMemoryMark ucmm(this, !aligned, true);
+      // Copy in multi-bytes chunks
+      copy_bytes_backward(from, to, qword_count, rax, L_copy_bytes, L_copy_8_bytes);
+    }
     restore_arg_regs();
     inc_counter_np(SharedRuntime::_jshort_array_copy_ctr); // Update counter after rscratch1 is free
     __ xorptr(rax, rax); // return 0
@@ -1905,31 +1929,35 @@
     BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
     bs->arraycopy_prologue(_masm, decorators, type, from, to, count);
 
-    // 'from', 'to' and 'count' are now valid
-    __ movptr(dword_count, count);
-    __ shrptr(count, 1); // count => qword_count
-
-    // Copy from low to high addresses.  Use 'to' as scratch.
-    __ lea(end_from, Address(from, qword_count, Address::times_8, -8));
-    __ lea(end_to,   Address(to,   qword_count, Address::times_8, -8));
-    __ negptr(qword_count);
-    __ jmp(L_copy_bytes);
-
-    // Copy trailing qwords
-  __ BIND(L_copy_8_bytes);
-    __ movq(rax, Address(end_from, qword_count, Address::times_8, 8));
-    __ movq(Address(end_to, qword_count, Address::times_8, 8), rax);
-    __ increment(qword_count);
-    __ jcc(Assembler::notZero, L_copy_8_bytes);
-
-    // Check for and copy trailing dword
-  __ BIND(L_copy_4_bytes);
-    __ testl(dword_count, 1); // Only byte test since the value is 0 or 1
-    __ jccb(Assembler::zero, L_exit);
-    __ movl(rax, Address(end_from, 8));
-    __ movl(Address(end_to, 8), rax);
-
+    {
+      // UnsafeCopyMemory page error: continue after ucm
+      UnsafeCopyMemoryMark ucmm(this, !is_oop && !aligned, true);
+      // 'from', 'to' and 'count' are now valid
+      __ movptr(dword_count, count);
+      __ shrptr(count, 1); // count => qword_count
+
+      // Copy from low to high addresses.  Use 'to' as scratch.
+      __ lea(end_from, Address(from, qword_count, Address::times_8, -8));
+      __ lea(end_to,   Address(to,   qword_count, Address::times_8, -8));
+      __ negptr(qword_count);
+      __ jmp(L_copy_bytes);
+
+      // Copy trailing qwords
+    __ BIND(L_copy_8_bytes);
+      __ movq(rax, Address(end_from, qword_count, Address::times_8, 8));
+      __ movq(Address(end_to, qword_count, Address::times_8, 8), rax);
+      __ increment(qword_count);
+      __ jcc(Assembler::notZero, L_copy_8_bytes);
+
+      // Check for and copy trailing dword
+    __ BIND(L_copy_4_bytes);
+      __ testl(dword_count, 1); // Only byte test since the value is 0 or 1
+      __ jccb(Assembler::zero, L_exit);
+      __ movl(rax, Address(end_from, 8));
+      __ movl(Address(end_to, 8), rax);
+    }
   __ BIND(L_exit);
+    address ucme_exit_pc = __ pc();
     bs->arraycopy_epilogue(_masm, decorators, type, from, to, dword_count);
     restore_arg_regs_using_thread();
     inc_counter_np(SharedRuntime::_jint_array_copy_ctr); // Update counter after rscratch1 is free
@@ -1938,9 +1966,12 @@
     __ leave(); // required for proper stackwalking of RuntimeStub frame
     __ ret(0);
 
-    // Copy in multi-bytes chunks
-    copy_bytes_forward(end_from, end_to, qword_count, rax, L_copy_bytes, L_copy_8_bytes);
-    __ jmp(L_copy_4_bytes);
+    {
+      UnsafeCopyMemoryMark ucmm(this, !is_oop && !aligned, false, ucme_exit_pc);
+      // Copy in multi-bytes chunks
+      copy_bytes_forward(end_from, end_to, qword_count, rax, L_copy_bytes, L_copy_8_bytes);
+      __ jmp(L_copy_4_bytes);
+    }
 
     return start;
   }
@@ -2001,26 +2032,29 @@
     bs->arraycopy_prologue(_masm, decorators, type, from, to, count);
 
     assert_clean_int(count, rax); // Make sure 'count' is clean int.
-    // 'from', 'to' and 'count' are now valid
-    __ movptr(dword_count, count);
-    __ shrptr(count, 1); // count => qword_count
-
-    // Copy from high to low addresses.  Use 'to' as scratch.
-
-    // Check for and copy trailing dword
-    __ testl(dword_count, 1);
-    __ jcc(Assembler::zero, L_copy_bytes);
-    __ movl(rax, Address(from, dword_count, Address::times_4, -4));
-    __ movl(Address(to, dword_count, Address::times_4, -4), rax);
-    __ jmp(L_copy_bytes);
-
-    // Copy trailing qwords
-  __ BIND(L_copy_8_bytes);
-    __ movq(rax, Address(from, qword_count, Address::times_8, -8));
-    __ movq(Address(to, qword_count, Address::times_8, -8), rax);
-    __ decrement(qword_count);
-    __ jcc(Assembler::notZero, L_copy_8_bytes);
-
+    {
+      // UnsafeCopyMemory page error: continue after ucm
+      UnsafeCopyMemoryMark ucmm(this, !is_oop && !aligned, true);
+      // 'from', 'to' and 'count' are now valid
+      __ movptr(dword_count, count);
+      __ shrptr(count, 1); // count => qword_count
+
+      // Copy from high to low addresses.  Use 'to' as scratch.
+
+      // Check for and copy trailing dword
+      __ testl(dword_count, 1);
+      __ jcc(Assembler::zero, L_copy_bytes);
+      __ movl(rax, Address(from, dword_count, Address::times_4, -4));
+      __ movl(Address(to, dword_count, Address::times_4, -4), rax);
+      __ jmp(L_copy_bytes);
+
+      // Copy trailing qwords
+    __ BIND(L_copy_8_bytes);
+      __ movq(rax, Address(from, qword_count, Address::times_8, -8));
+      __ movq(Address(to, qword_count, Address::times_8, -8), rax);
+      __ decrement(qword_count);
+      __ jcc(Assembler::notZero, L_copy_8_bytes);
+    }
     if (is_oop) {
       __ jmp(L_exit);
     }
@@ -2031,8 +2065,12 @@
     __ leave(); // required for proper stackwalking of RuntimeStub frame
     __ ret(0);
 
-    // Copy in multi-bytes chunks
-    copy_bytes_backward(from, to, qword_count, rax, L_copy_bytes, L_copy_8_bytes);
+    {
+      // UnsafeCopyMemory page error: continue after ucm
+      UnsafeCopyMemoryMark ucmm(this, !is_oop && !aligned, true);
+      // Copy in multi-bytes chunks
+      copy_bytes_backward(from, to, qword_count, rax, L_copy_bytes, L_copy_8_bytes);
+    }
 
   __ BIND(L_exit);
     bs->arraycopy_epilogue(_masm, decorators, type, from, to, dword_count);
@@ -2102,20 +2140,23 @@
     BasicType type = is_oop ? T_OBJECT : T_LONG;
     BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
     bs->arraycopy_prologue(_masm, decorators, type, from, to, qword_count);
-
-    // Copy from low to high addresses.  Use 'to' as scratch.
-    __ lea(end_from, Address(from, qword_count, Address::times_8, -8));
-    __ lea(end_to,   Address(to,   qword_count, Address::times_8, -8));
-    __ negptr(qword_count);
-    __ jmp(L_copy_bytes);
-
-    // Copy trailing qwords
-  __ BIND(L_copy_8_bytes);
-    __ movq(rax, Address(end_from, qword_count, Address::times_8, 8));
-    __ movq(Address(end_to, qword_count, Address::times_8, 8), rax);
-    __ increment(qword_count);
-    __ jcc(Assembler::notZero, L_copy_8_bytes);
-
+    {
+      // UnsafeCopyMemory page error: continue after ucm
+      UnsafeCopyMemoryMark ucmm(this, !is_oop && !aligned, true);
+
+      // Copy from low to high addresses.  Use 'to' as scratch.
+      __ lea(end_from, Address(from, qword_count, Address::times_8, -8));
+      __ lea(end_to,   Address(to,   qword_count, Address::times_8, -8));
+      __ negptr(qword_count);
+      __ jmp(L_copy_bytes);
+
+      // Copy trailing qwords
+    __ BIND(L_copy_8_bytes);
+      __ movq(rax, Address(end_from, qword_count, Address::times_8, 8));
+      __ movq(Address(end_to, qword_count, Address::times_8, 8), rax);
+      __ increment(qword_count);
+      __ jcc(Assembler::notZero, L_copy_8_bytes);
+    }
     if (is_oop) {
       __ jmp(L_exit);
     } else {
@@ -2127,8 +2168,12 @@
       __ ret(0);
     }
 
-    // Copy in multi-bytes chunks
-    copy_bytes_forward(end_from, end_to, qword_count, rax, L_copy_bytes, L_copy_8_bytes);
+    {
+      // UnsafeCopyMemory page error: continue after ucm
+      UnsafeCopyMemoryMark ucmm(this, !is_oop && !aligned, true);
+      // Copy in multi-bytes chunks
+      copy_bytes_forward(end_from, end_to, qword_count, rax, L_copy_bytes, L_copy_8_bytes);
+    }
 
     __ BIND(L_exit);
     bs->arraycopy_epilogue(_masm, decorators, type, from, to, qword_count);
@@ -2195,16 +2240,19 @@
     BasicType type = is_oop ? T_OBJECT : T_LONG;
     BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
     bs->arraycopy_prologue(_masm, decorators, type, from, to, qword_count);
-
-    __ jmp(L_copy_bytes);
-
-    // Copy trailing qwords
-  __ BIND(L_copy_8_bytes);
-    __ movq(rax, Address(from, qword_count, Address::times_8, -8));
-    __ movq(Address(to, qword_count, Address::times_8, -8), rax);
-    __ decrement(qword_count);
-    __ jcc(Assembler::notZero, L_copy_8_bytes);
-
+    {
+      // UnsafeCopyMemory page error: continue after ucm
+      UnsafeCopyMemoryMark ucmm(this, !is_oop && !aligned, true);
+
+      __ jmp(L_copy_bytes);
+
+      // Copy trailing qwords
+    __ BIND(L_copy_8_bytes);
+      __ movq(rax, Address(from, qword_count, Address::times_8, -8));
+      __ movq(Address(to, qword_count, Address::times_8, -8), rax);
+      __ decrement(qword_count);
+      __ jcc(Assembler::notZero, L_copy_8_bytes);
+    }
     if (is_oop) {
       __ jmp(L_exit);
     } else {
@@ -2215,10 +2263,13 @@
       __ leave(); // required for proper stackwalking of RuntimeStub frame
       __ ret(0);
     }
-
-    // Copy in multi-bytes chunks
-    copy_bytes_backward(from, to, qword_count, rax, L_copy_bytes, L_copy_8_bytes);
-
+    {
+      // UnsafeCopyMemory page error: continue after ucm
+      UnsafeCopyMemoryMark ucmm(this, !is_oop && !aligned, true);
+
+      // Copy in multi-bytes chunks
+      copy_bytes_backward(from, to, qword_count, rax, L_copy_bytes, L_copy_8_bytes);
+    }
     __ BIND(L_exit);
     bs->arraycopy_epilogue(_masm, decorators, type, from, to, qword_count);
     restore_arg_regs_using_thread();
@@ -6036,6 +6087,10 @@
   }
 }; // end class declaration
 
+#define UCM_TABLE_MAX_ENTRIES 16
 void StubGenerator_generate(CodeBuffer* code, bool all) {
+  if (UnsafeCopyMemory::_table == NULL) {
+    UnsafeCopyMemory::create_table(UCM_TABLE_MAX_ENTRIES);
+  }
   StubGenerator g(code, all);
 }
--- a/src/hotspot/cpu/zero/stubGenerator_zero.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/cpu/zero/stubGenerator_zero.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2007, 2008, 2010, 2015 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -156,9 +156,11 @@
     StubRoutines::_oop_arraycopy             = ShouldNotCallThisStub();
 
     StubRoutines::_checkcast_arraycopy       = ShouldNotCallThisStub();
-    StubRoutines::_unsafe_arraycopy          = ShouldNotCallThisStub();
     StubRoutines::_generic_arraycopy         = ShouldNotCallThisStub();
 
+    // Shared code tests for "NULL" to discover the stub is not generated.
+    StubRoutines::_unsafe_arraycopy          = NULL;
+
     // We don't generate specialized code for HeapWord-aligned source
     // arrays, so just use the code we've already generated
     StubRoutines::_arrayof_jbyte_disjoint_arraycopy =
--- a/src/hotspot/os/aix/os_aix.inline.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/os/aix/os_aix.inline.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -37,11 +37,6 @@
 #include <sys/ioctl.h>
 #include <netdb.h>
 
-// File names are case-insensitive on windows only.
-inline int os::file_name_strncmp(const char* s1, const char* s2, size_t num) {
-  return strncmp(s1, s2, num);
-}
-
 inline bool os::uses_stack_guard_pages() {
   return true;
 }
--- a/src/hotspot/os/bsd/os_bsd.inline.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/os/bsd/os_bsd.inline.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -35,11 +35,6 @@
 #include <poll.h>
 #include <netdb.h>
 
-// File names are case-insensitive on windows only
-inline int os::file_name_strncmp(const char* s1, const char* s2, size_t num) {
-  return strncmp(s1, s2, num);
-}
-
 inline bool os::uses_stack_guard_pages() {
   return true;
 }
--- a/src/hotspot/os/linux/os_linux.inline.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/os/linux/os_linux.inline.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -35,11 +35,6 @@
 #include <poll.h>
 #include <netdb.h>
 
-// File names are case-insensitive on windows only
-inline int os::file_name_strncmp(const char* s1, const char* s2, size_t num) {
-  return strncmp(s1, s2, num);
-}
-
 inline bool os::uses_stack_guard_pages() {
   return true;
 }
--- a/src/hotspot/os/posix/os_posix.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/os/posix/os_posix.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -1450,6 +1450,30 @@
   return path;
 }
 
+bool os::same_files(const char* file1, const char* file2) {
+  if (strcmp(file1, file2) == 0) {
+    return true;
+  }
+
+  bool is_same = false;
+  struct stat st1;
+  struct stat st2;
+
+  if (os::stat(file1, &st1) < 0) {
+    return false;
+  }
+
+  if (os::stat(file2, &st2) < 0) {
+    return false;
+  }
+
+  if (st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino) {
+    // same files
+    is_same = true;
+  }
+  return is_same;
+}
+
 // Check minimum allowable stack sizes for thread creation and to initialize
 // the java system classes, including StackOverflowError - depends on page
 // size.
--- a/src/hotspot/os/solaris/os_solaris.inline.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/os/solaris/os_solaris.inline.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -37,11 +37,6 @@
 #include <netdb.h>
 #include <setjmp.h>
 
-// File names are case-insensitive on windows only
-inline int os::file_name_strncmp(const char* s1, const char* s2, size_t num) {
-  return strncmp(s1, s2, num);
-}
-
 inline bool os::uses_stack_guard_pages() {
   return true;
 }
--- a/src/hotspot/os/windows/os_windows.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/os/windows/os_windows.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -2581,10 +2581,18 @@
         CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
         nm = (cb != NULL) ? cb->as_compiled_method_or_null() : NULL;
       }
-      if ((thread->thread_state() == _thread_in_vm &&
+
+      bool is_unsafe_arraycopy = (thread->thread_state() == _thread_in_native || in_java) && UnsafeCopyMemory::contains_pc(pc);
+      if (((thread->thread_state() == _thread_in_vm ||
+           thread->thread_state() == _thread_in_native ||
+           is_unsafe_arraycopy) &&
           thread->doing_unsafe_access()) ||
           (nm != NULL && nm->has_unsafe_access())) {
-        return Handle_Exception(exceptionInfo, SharedRuntime::handle_unsafe_access(thread, (address)Assembler::locate_next_instruction(pc)));
+        address next_pc =  Assembler::locate_next_instruction(pc);
+        if (is_unsafe_arraycopy) {
+          next_pc = UnsafeCopyMemory::page_error_continue_pc(pc);
+        }
+        return Handle_Exception(exceptionInfo, SharedRuntime::handle_unsafe_access(thread, next_pc));
       }
     }
 
@@ -4359,6 +4367,88 @@
   return ret;
 }
 
+static HANDLE create_read_only_file_handle(const char* file) {
+  if (file == NULL) {
+    return INVALID_HANDLE_VALUE;
+  }
+
+  char* nativepath = (char*)os::strdup(file, mtInternal);
+  if (nativepath == NULL) {
+    errno = ENOMEM;
+    return INVALID_HANDLE_VALUE;
+  }
+  os::native_path(nativepath);
+
+  size_t len = strlen(nativepath);
+  HANDLE handle = INVALID_HANDLE_VALUE;
+
+  if (len < MAX_PATH) {
+    handle = ::CreateFile(nativepath, 0, FILE_SHARE_READ,
+                          NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+  } else {
+    errno_t err = ERROR_SUCCESS;
+    wchar_t* wfile = create_unc_path(nativepath, err);
+    if (err != ERROR_SUCCESS) {
+      if (wfile != NULL) {
+        destroy_unc_path(wfile);
+      }
+      os::free(nativepath);
+      return INVALID_HANDLE_VALUE;
+    }
+    handle = ::CreateFileW(wfile, 0, FILE_SHARE_READ,
+                           NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+    destroy_unc_path(wfile);
+  }
+
+  os::free(nativepath);
+  return handle;
+}
+
+bool os::same_files(const char* file1, const char* file2) {
+
+  if (file1 == NULL && file2 == NULL) {
+    return true;
+  }
+
+  if (file1 == NULL || file2 == NULL) {
+    return false;
+  }
+
+  if (strcmp(file1, file2) == 0) {
+    return true;
+  }
+
+  HANDLE handle1 = create_read_only_file_handle(file1);
+  HANDLE handle2 = create_read_only_file_handle(file2);
+  bool result = false;
+
+  // if we could open both paths...
+  if (handle1 != INVALID_HANDLE_VALUE && handle2 != INVALID_HANDLE_VALUE) {
+    BY_HANDLE_FILE_INFORMATION fileInfo1;
+    BY_HANDLE_FILE_INFORMATION fileInfo2;
+    if (::GetFileInformationByHandle(handle1, &fileInfo1) &&
+      ::GetFileInformationByHandle(handle2, &fileInfo2)) {
+      // the paths are the same if they refer to the same file (fileindex) on the same volume (volume serial number)
+      if (fileInfo1.dwVolumeSerialNumber == fileInfo2.dwVolumeSerialNumber &&
+        fileInfo1.nFileIndexHigh == fileInfo2.nFileIndexHigh &&
+        fileInfo1.nFileIndexLow == fileInfo2.nFileIndexLow) {
+        result = true;
+      }
+    }
+  }
+
+  //free the handles
+  if (handle1 != INVALID_HANDLE_VALUE) {
+    ::CloseHandle(handle1);
+  }
+
+  if (handle2 != INVALID_HANDLE_VALUE) {
+    ::CloseHandle(handle2);
+  }
+
+  return result;
+}
+
 
 #define FT2INT64(ft) \
   ((jlong)((jlong)(ft).dwHighDateTime << 32 | (julong)(ft).dwLowDateTime))
--- a/src/hotspot/os/windows/os_windows.inline.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/os/windows/os_windows.inline.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -32,11 +32,6 @@
 
 inline const int os::default_file_open_flags() { return O_BINARY | O_NOINHERIT;}
 
-// File names are case-insensitive on windows only
-inline int os::file_name_strncmp(const char* s, const char* t, size_t num) {
-  return _strnicmp(s, t, num);
-}
-
 inline void  os::dll_unload(void *lib) {
   ::FreeLibrary((HMODULE)lib);
 }
--- a/src/hotspot/os_cpu/aix_ppc/os_aix_ppc.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/os_cpu/aix_ppc/os_aix_ppc.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2012, 2018 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -441,8 +441,12 @@
         // underlying file has been truncated. Do not crash the VM in such a case.
         CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
         CompiledMethod* nm = cb->as_compiled_method_or_null();
-        if (nm != NULL && nm->has_unsafe_access()) {
+        bool is_unsafe_arraycopy = (thread->doing_unsafe_access() && UnsafeCopyMemory::contains_pc(pc));
+        if ((nm != NULL && nm->has_unsafe_access()) || is_unsafe_arraycopy) {
           address next_pc = pc + 4;
+          if (is_unsafe_arraycopy) {
+            next_pc = UnsafeCopyMemory::page_error_continue_pc(pc);
+          }
           next_pc = SharedRuntime::handle_unsafe_access(thread, next_pc);
           os::Aix::ucontext_set_pc(uc, next_pc);
           return 1;
@@ -461,9 +465,13 @@
         stub = pc + 4;  // continue with next instruction.
         goto run_stub;
       }
-      else if (thread->thread_state() == _thread_in_vm &&
+      else if ((thread->thread_state() == _thread_in_vm ||
+                thread->thread_state() == _thread_in_native) &&
                sig == SIGBUS && thread->doing_unsafe_access()) {
         address next_pc = pc + 4;
+        if (UnsafeCopyMemory::contains_pc(pc)) {
+          next_pc = UnsafeCopyMemory::page_error_continue_pc(pc);
+        }
         next_pc = SharedRuntime::handle_unsafe_access(thread, next_pc);
         os::Aix::ucontext_set_pc(uc, next_pc);
         return 1;
--- a/src/hotspot/os_cpu/bsd_x86/os_bsd_x86.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/os_cpu/bsd_x86/os_bsd_x86.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -589,8 +589,12 @@
         // Do not crash the VM in such a case.
         CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
         CompiledMethod* nm = (cb != NULL) ? cb->as_compiled_method_or_null() : NULL;
-        if (nm != NULL && nm->has_unsafe_access()) {
+        bool is_unsafe_arraycopy = thread->doing_unsafe_access() && UnsafeCopyMemory::contains_pc(pc);
+        if ((nm != NULL && nm->has_unsafe_access()) || is_unsafe_arraycopy) {
           address next_pc = Assembler::locate_next_instruction(pc);
+          if (is_unsafe_arraycopy) {
+            next_pc = UnsafeCopyMemory::page_error_continue_pc(pc);
+          }
           stub = SharedRuntime::handle_unsafe_access(thread, next_pc);
         }
       }
@@ -659,10 +663,14 @@
           // Determination of interpreter/vtable stub/compiled code null exception
           stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL);
       }
-    } else if (thread->thread_state() == _thread_in_vm &&
+    } else if ((thread->thread_state() == _thread_in_vm ||
+                thread->thread_state() == _thread_in_native) &&
                sig == SIGBUS && /* info->si_code == BUS_OBJERR && */
                thread->doing_unsafe_access()) {
         address next_pc = Assembler::locate_next_instruction(pc);
+        if (UnsafeCopyMemory::contains_pc(pc)) {
+          next_pc = UnsafeCopyMemory::page_error_continue_pc(pc);
+        }
         stub = SharedRuntime::handle_unsafe_access(thread, next_pc);
     }
 
--- a/src/hotspot/os_cpu/bsd_zero/os_bsd_zero.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/os_cpu/bsd_zero/os_bsd_zero.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2007, 2008, 2009, 2010 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -193,7 +193,8 @@
     /*if (thread->thread_state() == _thread_in_Java) {
       ShouldNotCallThis();
     }
-    else*/ if (thread->thread_state() == _thread_in_vm &&
+    else*/ if ((thread->thread_state() == _thread_in_vm ||
+               thread->thread_state() == _thread_in_native) &&
                sig == SIGBUS && thread->doing_unsafe_access()) {
       ShouldNotCallThis();
     }
--- a/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2014, Red Hat Inc. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -419,8 +419,12 @@
         // Do not crash the VM in such a case.
         CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
         CompiledMethod* nm = (cb != NULL) ? cb->as_compiled_method_or_null() : NULL;
-        if (nm != NULL && nm->has_unsafe_access()) {
+        bool is_unsafe_arraycopy = (thread->doing_unsafe_access() && UnsafeCopyMemory::contains_pc(pc));
+        if ((nm != NULL && nm->has_unsafe_access()) || is_unsafe_arraycopy) {
           address next_pc = pc + NativeCall::instruction_size;
+          if (is_unsafe_arraycopy) {
+            next_pc = UnsafeCopyMemory::page_error_continue_pc(pc);
+          }
           stub = SharedRuntime::handle_unsafe_access(thread, next_pc);
         }
       }
@@ -439,10 +443,14 @@
           // Determination of interpreter/vtable stub/compiled code null exception
           stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL);
       }
-    } else if (thread->thread_state() == _thread_in_vm &&
+    } else if ((thread->thread_state() == _thread_in_vm ||
+                 thread->thread_state() == _thread_in_native) &&
                sig == SIGBUS && /* info->si_code == BUS_OBJERR && */
                thread->doing_unsafe_access()) {
       address next_pc = pc + NativeCall::instruction_size;
+      if (UnsafeCopyMemory::contains_pc(pc)) {
+        next_pc = UnsafeCopyMemory::page_error_continue_pc(pc);
+      }
       stub = SharedRuntime::handle_unsafe_access(thread, next_pc);
     }
 
--- a/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -384,7 +384,7 @@
         // Do not crash the VM in such a case.
         CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
         CompiledMethod* nm = (cb != NULL) ? cb->as_compiled_method_or_null() : NULL;
-        if (nm != NULL && nm->has_unsafe_access()) {
+        if ((nm != NULL && nm->has_unsafe_access()) || (thread->doing_unsafe_access() && UnsafeCopyMemory::contains_pc(pc))) {
           unsafe_access = true;
         }
       } else if (sig == SIGSEGV &&
@@ -398,7 +398,8 @@
         // Zombie
         stub = SharedRuntime::get_handle_wrong_method_stub();
       }
-    } else if (thread->thread_state() == _thread_in_vm &&
+    } else if ((thread->thread_state() == _thread_in_vm ||
+                thread->thread_state() == _thread_in_native) &&
                sig == SIGBUS && thread->doing_unsafe_access()) {
         unsafe_access = true;
     }
@@ -418,6 +419,9 @@
     // any other suitable exception reason,
     // so assume it is an unsafe access.
     address next_pc = pc + Assembler::InstructionSize;
+    if (UnsafeCopyMemory::contains_pc(pc)) {
+      next_pc = UnsafeCopyMemory::page_error_continue_pc(pc);
+    }
 #ifdef __thumb__
     if (uc->uc_mcontext.arm_cpsr & PSR_T_BIT) {
       next_pc = (address)((intptr_t)next_pc | 0x1);
--- a/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -469,8 +469,12 @@
         // underlying file has been truncated. Do not crash the VM in such a case.
         CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
         CompiledMethod* nm = (cb != NULL) ? cb->as_compiled_method_or_null() : NULL;
-        if (nm != NULL && nm->has_unsafe_access()) {
+        bool is_unsafe_arraycopy = (thread->doing_unsafe_access() && UnsafeCopyMemory::contains_pc(pc));
+        if ((nm != NULL && nm->has_unsafe_access()) || is_unsafe_arraycopy) {
           address next_pc = pc + 4;
+          if (is_unsafe_arraycopy) {
+            next_pc = UnsafeCopyMemory::page_error_continue_pc(pc);
+          }
           next_pc = SharedRuntime::handle_unsafe_access(thread, next_pc);
           os::Linux::ucontext_set_pc(uc, next_pc);
           return true;
@@ -485,11 +489,15 @@
                         // flushing of icache is not necessary.
         stub = pc + 4;  // continue with next instruction.
       }
-      else if (thread->thread_state() == _thread_in_vm &&
+      else if ((thread->thread_state() == _thread_in_vm ||
+                thread->thread_state() == _thread_in_native) &&
                sig == SIGBUS && thread->doing_unsafe_access()) {
         address next_pc = pc + 4;
+        if (UnsafeCopyMemory::contains_pc(pc)) {
+          next_pc = UnsafeCopyMemory::page_error_continue_pc(pc);
+        }
         next_pc = SharedRuntime::handle_unsafe_access(thread, next_pc);
-        os::Linux::ucontext_set_pc(uc, pc + 4);
+        os::Linux::ucontext_set_pc(uc, next_pc);
         return true;
       }
     }
--- a/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2016, 2018 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -467,7 +467,8 @@
         // when the vector facility is installed, but operating system support is missing.
         VM_Version::reset_has_VectorFacility();
         stub = pc; // Continue with next instruction.
-      } else if (thread->thread_state() == _thread_in_vm &&
+      } else if ((thread->thread_state() == _thread_in_vm ||
+                  thread->thread_state() == _thread_in_native) &&
                  sig == SIGBUS && thread->doing_unsafe_access()) {
         // We don't really need a stub here! Just set the pending exeption and
         // continue at the next instruction after the faulting read. Returning
--- a/src/hotspot/os_cpu/linux_sparc/os_linux_sparc.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/os_cpu/linux_sparc/os_linux_sparc.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -385,7 +385,11 @@
   // Do not crash the VM in such a case.
   CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
   CompiledMethod* nm = cb->as_compiled_method_or_null();
-  if (nm != NULL && nm->has_unsafe_access()) {
+  bool is_unsafe_arraycopy = (thread->doing_unsafe_access() && UnsafeCopyMemory::contains_pc(pc));
+  if ((nm != NULL && nm->has_unsafe_access()) || is_unsafe_arraycopy) {
+    if (is_unsafe_arraycopy) {
+      npc = UnsafeCopyMemory::page_error_continue_pc(pc);
+    }
     *stub = SharedRuntime::handle_unsafe_access(thread, npc);
     return true;
   }
@@ -550,8 +554,12 @@
     }
 
     if (sig == SIGBUS &&
-        thread->thread_state() == _thread_in_vm &&
+        (thread->thread_state() == _thread_in_vm ||
+         thread->thread_state() == _thread_in_native) &&
         thread->doing_unsafe_access()) {
+      if (UnsafeCopyMemory::contains_pc(pc)) {
+        npc = UnsafeCopyMemory::page_error_continue_pc(pc);
+      }
       stub = SharedRuntime::handle_unsafe_access(thread, npc);
     }
 
--- a/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -435,8 +435,12 @@
         // Do not crash the VM in such a case.
         CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
         CompiledMethod* nm = (cb != NULL) ? cb->as_compiled_method_or_null() : NULL;
-        if (nm != NULL && nm->has_unsafe_access()) {
+        bool is_unsafe_arraycopy = thread->doing_unsafe_access() && UnsafeCopyMemory::contains_pc(pc);
+        if ((nm != NULL && nm->has_unsafe_access()) || is_unsafe_arraycopy) {
           address next_pc = Assembler::locate_next_instruction(pc);
+          if (is_unsafe_arraycopy) {
+            next_pc = UnsafeCopyMemory::page_error_continue_pc(pc);
+          }
           stub = SharedRuntime::handle_unsafe_access(thread, next_pc);
         }
       }
@@ -483,10 +487,14 @@
           // Determination of interpreter/vtable stub/compiled code null exception
           stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL);
       }
-    } else if (thread->thread_state() == _thread_in_vm &&
-               sig == SIGBUS && /* info->si_code == BUS_OBJERR && */
-               thread->doing_unsafe_access()) {
+    } else if ((thread->thread_state() == _thread_in_vm ||
+                thread->thread_state() == _thread_in_native) &&
+               (sig == SIGBUS && /* info->si_code == BUS_OBJERR && */
+               thread->doing_unsafe_access())) {
         address next_pc = Assembler::locate_next_instruction(pc);
+        if (UnsafeCopyMemory::contains_pc(pc)) {
+          next_pc = UnsafeCopyMemory::page_error_continue_pc(pc);
+        }
         stub = SharedRuntime::handle_unsafe_access(thread, next_pc);
     }
 
--- a/src/hotspot/os_cpu/linux_zero/os_linux_zero.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/os_cpu/linux_zero/os_linux_zero.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2007, 2008, 2009, 2010 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -207,7 +207,8 @@
     /*if (thread->thread_state() == _thread_in_Java) {
       ShouldNotCallThis();
     }
-    else*/ if (thread->thread_state() == _thread_in_vm &&
+    else*/ if ((thread->thread_state() == _thread_in_vm ||
+               thread->thread_state() == _thread_in_native) &&
                sig == SIGBUS && thread->doing_unsafe_access()) {
       ShouldNotCallThis();
     }
--- a/src/hotspot/os_cpu/solaris_sparc/os_solaris_sparc.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/os_cpu/solaris_sparc/os_solaris_sparc.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -436,8 +436,12 @@
     }
 
 
-    if (thread->thread_state() == _thread_in_vm) {
+    if (thread->thread_state() == _thread_in_vm ||
+        thread->thread_state() == _thread_in_native) {
       if (sig == SIGBUS && thread->doing_unsafe_access()) {
+        if (UnsafeCopyMemory::contains_pc(pc)) {
+          npc = UnsafeCopyMemory::page_error_continue_pc(pc);
+        }
         stub = SharedRuntime::handle_unsafe_access(thread, npc);
       }
     }
@@ -476,7 +480,11 @@
         // Do not crash the VM in such a case.
         CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
         CompiledMethod* nm = cb->as_compiled_method_or_null();
-        if (nm != NULL && nm->has_unsafe_access()) {
+        bool is_unsafe_arraycopy = (thread->doing_unsafe_access() && UnsafeCopyMemory::contains_pc(pc));
+        if ((nm != NULL && nm->has_unsafe_access()) || is_unsafe_arraycopy) {
+          if (is_unsafe_arraycopy) {
+            npc = UnsafeCopyMemory::page_error_continue_pc(pc);
+          }
           stub = SharedRuntime::handle_unsafe_access(thread, npc);
         }
       }
--- a/src/hotspot/os_cpu/solaris_x86/os_solaris_x86.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/os_cpu/solaris_x86/os_solaris_x86.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -517,9 +517,13 @@
       stub = VM_Version::cpuinfo_cont_addr();
     }
 
-    if (thread->thread_state() == _thread_in_vm) {
+    if (thread->thread_state() == _thread_in_vm ||
+         thread->thread_state() == _thread_in_native) {
       if (sig == SIGBUS && info->si_code == BUS_OBJERR && thread->doing_unsafe_access()) {
         address next_pc = Assembler::locate_next_instruction(pc);
+        if (UnsafeCopyMemory::contains_pc(pc)) {
+          next_pc = UnsafeCopyMemory::page_error_continue_pc(pc);
+        }
         stub = SharedRuntime::handle_unsafe_access(thread, next_pc);
       }
     }
@@ -536,8 +540,12 @@
         CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
         if (cb != NULL) {
           CompiledMethod* nm = cb->as_compiled_method_or_null();
-          if (nm != NULL && nm->has_unsafe_access()) {
+          bool is_unsafe_arraycopy = thread->doing_unsafe_access() && UnsafeCopyMemory::contains_pc(pc);
+          if ((nm != NULL && nm->has_unsafe_access()) || is_unsafe_arraycopy)) {
             address next_pc = Assembler::locate_next_instruction(pc);
+            if (is_unsafe_arraycopy) {
+              next_pc = UnsafeCopyMemory::page_error_continue_pc(pc);
+            }
             stub = SharedRuntime::handle_unsafe_access(thread, next_pc);
           }
         }
--- a/src/hotspot/share/aot/aotCodeHeap.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/aot/aotCodeHeap.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -38,7 +38,6 @@
 #include "memory/universe.hpp"
 #include "oops/compressedOops.hpp"
 #include "oops/method.inline.hpp"
-#include "runtime/deoptimization.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/os.hpp"
 #include "runtime/safepointVerifiers.hpp"
@@ -734,7 +733,8 @@
     }
   }
   if (marked > 0) {
-    Deoptimization::deoptimize_all_marked();
+    VM_Deoptimize op;
+    VMThread::execute(&op);
   }
 }
 
--- a/src/hotspot/share/aot/aotCompiledMethod.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/aot/aotCompiledMethod.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -165,7 +165,7 @@
 
   {
     // Enter critical section.  Does not block for safepoint.
-    MutexLocker pl(CompiledMethod_lock, Mutex::_no_safepoint_check_flag);
+    MutexLocker pl(Patching_lock, Mutex::_no_safepoint_check_flag);
 
     if (*_state_adr == new_state) {
       // another thread already performed this transition so nothing
@@ -188,10 +188,12 @@
 #endif
 
     // Remove AOTCompiledMethod from method.
-    if (method() != NULL) {
-      method()->unlink_code(this);
+    if (method() != NULL && (method()->code() == this ||
+                             method()->from_compiled_entry() == verified_entry_point())) {
+      HandleMark hm;
+      method()->clear_code(false /* already owns Patching_lock */);
     }
-  } // leave critical region under CompiledMethod_lock
+  } // leave critical region under Patching_lock
 
 
   if (TraceCreateZombies) {
@@ -214,7 +216,7 @@
 
   {
     // Enter critical section.  Does not block for safepoint.
-    MutexLocker pl(CompiledMethod_lock, Mutex::_no_safepoint_check_flag);
+    MutexLocker pl(Patching_lock, Mutex::_no_safepoint_check_flag);
 
     if (*_state_adr == in_use) {
       // another thread already performed this transition so nothing
@@ -228,7 +230,7 @@
 
     // Log the transition once
     log_state_change();
-  } // leave critical region under CompiledMethod_lock
+  } // leave critical region under Patching_lock
 
 
   if (TraceCreateZombies) {
--- a/src/hotspot/share/aot/aotCompiledMethod.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/aot/aotCompiledMethod.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -176,7 +176,6 @@
                                                  state() == not_used; }
   virtual bool is_alive() const { return _is_alive(); }
   virtual bool is_in_use() const { return state() == in_use; }
-  virtual bool is_not_installed() const { return state() == not_installed; }
 
   virtual bool is_unloading() { return false; }
 
--- a/src/hotspot/share/ci/ciMethodData.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/ci/ciMethodData.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -81,13 +81,13 @@
 // Check for entries that reference an unloaded method
 class PrepareExtraDataClosure : public CleanExtraDataClosure {
   MethodData*            _mdo;
-  uint64_t               _safepoint_counter;
+  SafepointStateTracker  _safepoint_tracker;
   GrowableArray<Method*> _uncached_methods;
 
 public:
   PrepareExtraDataClosure(MethodData* mdo)
     : _mdo(mdo),
-      _safepoint_counter(SafepointSynchronize::safepoint_counter()),
+      _safepoint_tracker(SafepointSynchronize::safepoint_state_tracker()),
       _uncached_methods()
   { }
 
@@ -103,7 +103,7 @@
   }
 
   bool has_safepointed() {
-    return SafepointSynchronize::safepoint_counter() != _safepoint_counter;
+    return _safepoint_tracker.safepoint_state_changed();
   }
 
   bool finish() {
--- a/src/hotspot/share/classfile/classLoader.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/classfile/classLoader.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -292,11 +292,13 @@
   return NULL;
 }
 
-ClassPathZipEntry::ClassPathZipEntry(jzfile* zip, const char* zip_name, bool is_boot_append) : ClassPathEntry() {
+ClassPathZipEntry::ClassPathZipEntry(jzfile* zip, const char* zip_name,
+                                     bool is_boot_append, bool from_class_path_attr) : ClassPathEntry() {
   _zip = zip;
   char *copy = NEW_C_HEAP_ARRAY(char, strlen(zip_name)+1, mtClass);
   strcpy(copy, zip_name);
   _zip_name = copy;
+  _from_class_path_attr = from_class_path_attr;
 }
 
 ClassPathZipEntry::~ClassPathZipEntry() {
@@ -577,7 +579,7 @@
     strncpy(path, &class_path[start], end - start);
     path[end - start] = '\0';
 
-    update_class_path_entry_list(path, false, false);
+    update_class_path_entry_list(path, false, false, false);
 
     while (class_path[end] == os::path_separator()[0]) {
       end++;
@@ -612,7 +614,7 @@
   // File or directory found
   ClassPathEntry* new_entry = NULL;
   new_entry = create_class_path_entry(path, &st, true /* throw_exception */,
-                                      false /*is_boot_append */, CHECK);
+                                      false /*is_boot_append */, false /* from_class_path_attr */, CHECK);
   if (new_entry == NULL) {
     return;
   }
@@ -668,7 +670,7 @@
       struct stat st;
       if (os::stat(path, &st) == 0) {
         // File or directory found
-        ClassPathEntry* new_entry = create_class_path_entry(path, &st, false, false, CHECK);
+        ClassPathEntry* new_entry = create_class_path_entry(path, &st, false, false, false, CHECK);
         // If the path specification is valid, enter it into this module's list
         if (new_entry != NULL) {
           module_cpl->add_to_list(new_entry);
@@ -737,7 +739,7 @@
       struct stat st;
       if (os::stat(path, &st) == 0) {
         // Directory found
-        ClassPathEntry* new_entry = create_class_path_entry(path, &st, false, false, CHECK);
+        ClassPathEntry* new_entry = create_class_path_entry(path, &st, false, false, false, CHECK);
 
         // Check for a jimage
         if (Arguments::has_jimage()) {
@@ -754,7 +756,7 @@
     } else {
       // Every entry on the system boot class path after the initial base piece,
       // which is set by os::set_boot_path(), is considered an appended entry.
-      update_class_path_entry_list(path, false, true);
+      update_class_path_entry_list(path, false, true, false);
     }
 
     while (class_path[end] == os::path_separator()[0]) {
@@ -782,7 +784,7 @@
   struct stat st;
   if (os::stat(path, &st) == 0) {
     // Directory found
-    ClassPathEntry* new_entry = create_class_path_entry(path, &st, false, false, CHECK);
+    ClassPathEntry* new_entry = create_class_path_entry(path, &st, false, false, false, CHECK);
 
     // If the path specification is valid, enter it into this module's list.
     // There is no need to check for duplicate modules in the exploded entry list,
@@ -802,7 +804,9 @@
 
 ClassPathEntry* ClassLoader::create_class_path_entry(const char *path, const struct stat* st,
                                                      bool throw_exception,
-                                                     bool is_boot_append, TRAPS) {
+                                                     bool is_boot_append,
+                                                     bool from_class_path_attr,
+                                                     TRAPS) {
   JavaThread* thread = JavaThread::current();
   ClassPathEntry* new_entry = NULL;
   if ((st->st_mode & S_IFMT) == S_IFREG) {
@@ -832,7 +836,7 @@
         zip = (*ZipOpen)(canonical_path, &error_msg);
       }
       if (zip != NULL && error_msg == NULL) {
-        new_entry = new ClassPathZipEntry(zip, path, is_boot_append);
+        new_entry = new ClassPathZipEntry(zip, path, is_boot_append, from_class_path_attr);
       } else {
         char *msg;
         if (error_msg == NULL) {
@@ -882,7 +886,7 @@
         }
         if (zip != NULL && error_msg == NULL) {
           // create using canonical path
-          return new ClassPathZipEntry(zip, canonical_path, is_boot_append);
+          return new ClassPathZipEntry(zip, canonical_path, is_boot_append, false);
         }
       }
     }
@@ -956,13 +960,14 @@
 bool ClassLoader::update_class_path_entry_list(const char *path,
                                                bool check_for_duplicates,
                                                bool is_boot_append,
+                                               bool from_class_path_attr,
                                                bool throw_exception) {
   struct stat st;
   if (os::stat(path, &st) == 0) {
     // File or directory found
     ClassPathEntry* new_entry = NULL;
     Thread* THREAD = Thread::current();
-    new_entry = create_class_path_entry(path, &st, throw_exception, is_boot_append, CHECK_(false));
+    new_entry = create_class_path_entry(path, &st, throw_exception, is_boot_append, from_class_path_attr, CHECK_(false));
     if (new_entry == NULL) {
       return false;
     }
--- a/src/hotspot/share/classfile/classLoader.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/classfile/classLoader.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -53,6 +53,8 @@
   void set_next(ClassPathEntry* next);
   virtual bool is_modules_image() const = 0;
   virtual bool is_jar_file() const = 0;
+  // Is this entry created from the "Class-path" attribute from a JAR Manifest?
+  virtual bool from_class_path_attr() const = 0;
   virtual const char* name() const = 0;
   virtual JImageFile* jimage() const = 0;
   virtual void close_jimage() = 0;
@@ -73,6 +75,7 @@
  public:
   bool is_modules_image() const { return false; }
   bool is_jar_file() const { return false;  }
+  bool from_class_path_attr() const { return false; }
   const char* name() const { return _dir; }
   JImageFile* jimage() const { return NULL; }
   void close_jimage() {}
@@ -99,13 +102,15 @@
  private:
   jzfile* _zip;              // The zip archive
   const char*   _zip_name;   // Name of zip archive
+  bool _from_class_path_attr; // From the "Class-path" attribute of a jar file
  public:
   bool is_modules_image() const { return false; }
   bool is_jar_file() const { return true;  }
+  bool from_class_path_attr() const { return _from_class_path_attr; }
   const char* name() const { return _zip_name; }
   JImageFile* jimage() const { return NULL; }
   void close_jimage() {}
-  ClassPathZipEntry(jzfile* zip, const char* zip_name, bool is_boot_append);
+  ClassPathZipEntry(jzfile* zip, const char* zip_name, bool is_boot_append, bool from_class_path_attr);
   virtual ~ClassPathZipEntry();
   u1* open_entry(const char* name, jint* filesize, bool nul_terminate, TRAPS);
   ClassFileStream* open_stream(const char* name, TRAPS);
@@ -122,6 +127,7 @@
 public:
   bool is_modules_image() const;
   bool is_jar_file() const { return false; }
+  bool from_class_path_attr() const { return false; }
   bool is_open() const { return _jimage != NULL; }
   const char* name() const { return _name == NULL ? "" : _name; }
   JImageFile* jimage() const { return _jimage; }
@@ -257,7 +263,8 @@
  public:
   static ClassPathEntry* create_class_path_entry(const char *path, const struct stat* st,
                                                  bool throw_exception,
-                                                 bool is_boot_append, TRAPS);
+                                                 bool is_boot_append,
+                                                 bool from_class_path_attr, TRAPS);
 
   // If the package for the fully qualified class name is in the boot
   // loader's package entry table then add_package() sets the classpath_index
@@ -281,6 +288,7 @@
   static bool update_class_path_entry_list(const char *path,
                                            bool check_for_duplicates,
                                            bool is_boot_append,
+                                           bool from_class_path_attr,
                                            bool throw_exception=true);
   CDS_ONLY(static void update_module_path_entry_list(const char *path, TRAPS);)
   static void print_bootclasspath();
--- a/src/hotspot/share/classfile/classLoaderExt.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/classfile/classLoaderExt.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -213,7 +213,7 @@
         int n = os::snprintf(libname, libname_len + 1, "%.*s%s", dir_len, dir_name, file_start);
         assert((size_t)n == libname_len, "Unexpected number of characters in string");
         trace_class_path("library = ", libname);
-        ClassLoader::update_class_path_entry_list(libname, true, false);
+        ClassLoader::update_class_path_entry_list(libname, true, false, true /* from_class_path_attr */);
       }
 
       file_start = file_end;
@@ -339,7 +339,7 @@
   }
   ClassPathEntry* new_entry = NULL;
 
-  new_entry = create_class_path_entry(path, &st, false, false, CHECK_NULL);
+  new_entry = create_class_path_entry(path, &st, false, false, false, CHECK_NULL);
   if (new_entry == NULL) {
     return NULL;
   }
--- a/src/hotspot/share/classfile/sharedPathsMiscInfo.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/classfile/sharedPathsMiscInfo.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -153,83 +153,10 @@
   return true;
 }
 
-char* skip_first_path_entry(const char* path) {
-  size_t path_sep_len = strlen(os::path_separator());
-  char* p = strstr((char*)path, os::path_separator());
-  if (p != NULL) {
-    debug_only( {
-      size_t image_name_len = strlen(MODULES_IMAGE_NAME);
-      assert(strncmp(p - image_name_len, MODULES_IMAGE_NAME, image_name_len) == 0,
-             "first entry must be the modules image");
-    } );
-    p += path_sep_len;
-  } else {
-    debug_only( {
-      assert(ClassLoader::string_ends_with(path, MODULES_IMAGE_NAME),
-             "first entry must be the modules image");
-    } );
-  }
-  return p;
-}
-
 bool SharedPathsMiscInfo::check(jint type, const char* path, bool is_static) {
   assert(UseSharedSpaces, "runtime only");
   switch (type) {
   case BOOT_PATH:
-    {
-      //
-      // - Archive contains boot classes only - relaxed boot path check:
-      //   Extra path elements appended to the boot path at runtime are allowed.
-      //
-      // - Archive contains application or platform classes - strict boot path check:
-      //   Validate the entire runtime boot path, which must be compactible
-      //   with the dump time boot path. Appending boot path at runtime is not
-      //   allowed.
-      //
-
-      // The first entry in boot path is the modules_image (guaranteed by
-      // ClassLoader::setup_boot_search_path()). Skip the first entry. The
-      // path of the runtime modules_image may be different from the dump
-      // time path (e.g. the JDK image is copied to a different location
-      // after generating the shared archive), which is acceptable. For most
-      // common cases, the dump time boot path might contain modules_image only.
-      char* runtime_boot_path = Arguments::get_sysclasspath();
-      char* rp = skip_first_path_entry(runtime_boot_path);
-      char* dp = skip_first_path_entry(path);
-
-      bool relaxed_check = is_static ?
-                             !FileMapInfo::current_info()->header()->has_platform_or_app_classes() :
-                             !FileMapInfo::dynamic_info()->header()->has_platform_or_app_classes();
-      if (dp == NULL && rp == NULL) {
-        break;   // ok, both runtime and dump time boot paths have modules_images only
-      } else if (dp == NULL && rp != NULL && relaxed_check) {
-        break;   // ok, relaxed check, runtime has extra boot append path entries
-      } else if (dp != NULL && rp != NULL) {
-        size_t num;
-        size_t dp_len = strlen(dp);
-        size_t rp_len = strlen(rp);
-        if (rp_len >= dp_len) {
-          if (relaxed_check) {
-            // only check the leading entries in the runtime boot path, up to
-            // the length of the dump time boot path
-            num = dp_len;
-          } else {
-            // check the full runtime boot path, must match with dump time
-            num = rp_len;
-          }
-
-          if (os::file_name_strncmp(dp, rp, num) == 0) {
-            // make sure it is the end of an entry in the runtime boot path
-            if (rp[dp_len] == '\0' || rp[dp_len] == os::path_separator()[0]) {
-              break; // ok, runtime and dump time paths match
-            }
-          }
-        }
-      }
-
-      // The paths are different
-      return fail("[BOOT classpath mismatch, actual =", runtime_boot_path);
-    }
     break;
   case NON_EXIST:
     {
@@ -242,22 +169,6 @@
     }
     break;
   case APP_PATH:
-    {
-      size_t len = strlen(path);
-      const char *appcp = Arguments::get_appclasspath();
-      assert(appcp != NULL, "NULL app classpath");
-      size_t appcp_len = strlen(appcp);
-      if (appcp_len < len) {
-        return fail("Run time APP classpath is shorter than the one at dump time: ", appcp);
-      }
-      // Prefix is OK: E.g., dump with -cp foo.jar, but run with -cp foo.jar:bar.jar.
-      if (os::file_name_strncmp(path, appcp, len) != 0) {
-        return fail("[APP classpath mismatch, actual: -Djava.class.path=", appcp);
-      }
-      if (appcp[len] != '\0' && appcp[len] != os::path_separator()[0]) {
-        return fail("Dump time APP classpath is not a proper prefix of run time APP classpath: ", appcp);
-      }
-    }
     break;
   default:
     return fail("Corrupted archive file header");
--- a/src/hotspot/share/classfile/stringTable.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/classfile/stringTable.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -79,8 +79,7 @@
 
 // --------------------------------------------------------------------------
 
-typedef ConcurrentHashTable<WeakHandle<vm_string_table_data>,
-                            StringTableConfig, mtSymbol> StringTableHash;
+typedef ConcurrentHashTable<StringTableConfig, mtSymbol> StringTableHash;
 static StringTableHash* _local_table = NULL;
 
 volatile bool StringTable::_has_work = false;
@@ -101,11 +100,12 @@
     java_lang_String::hash_code(s, len);
 }
 
-class StringTableConfig : public StringTableHash::BaseConfig {
+class StringTableConfig : public StackObj {
  private:
  public:
-  static uintx get_hash(WeakHandle<vm_string_table_data> const& value,
-                        bool* is_dead) {
+  typedef WeakHandle<vm_string_table_data> Value;
+
+  static uintx get_hash(Value const& value, bool* is_dead) {
     EXCEPTION_MARK;
     oop val_oop = value.peek();
     if (val_oop == NULL) {
@@ -124,15 +124,13 @@
     return 0;
   }
   // We use default allocation/deallocation but counted
-  static void* allocate_node(size_t size,
-                             WeakHandle<vm_string_table_data> const& value) {
+  static void* allocate_node(size_t size, Value const& value) {
     StringTable::item_added();
-    return StringTableHash::BaseConfig::allocate_node(size, value);
+    return AllocateHeap(size, mtSymbol);
   }
-  static void free_node(void* memory,
-                        WeakHandle<vm_string_table_data> const& value) {
+  static void free_node(void* memory, Value const& value) {
     value.release();
-    StringTableHash::BaseConfig::free_node(memory, value);
+    FreeHeap(memory);
     StringTable::item_removed();
   }
 };
--- a/src/hotspot/share/classfile/symbolTable.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/classfile/symbolTable.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -77,8 +77,7 @@
 
 // --------------------------------------------------------------------------
 
-typedef ConcurrentHashTable<Symbol*,
-                            SymbolTableConfig, mtSymbol> SymbolTableHash;
+typedef ConcurrentHashTable<SymbolTableConfig, mtSymbol> SymbolTableHash;
 static SymbolTableHash* _local_table = NULL;
 
 volatile bool SymbolTable::_has_work = 0;
@@ -121,10 +120,12 @@
 }
 #endif
 
-class SymbolTableConfig : public SymbolTableHash::BaseConfig {
+class SymbolTableConfig : public AllStatic {
 private:
 public:
-  static uintx get_hash(Symbol* const& value, bool* is_dead) {
+  typedef Symbol* Value;  // value of the Node in the hashtable
+
+  static uintx get_hash(Value const& value, bool* is_dead) {
     *is_dead = (value->refcount() == 0);
     if (*is_dead) {
       return 0;
@@ -133,11 +134,11 @@
     }
   }
   // We use default allocation/deallocation but counted
-  static void* allocate_node(size_t size, Symbol* const& value) {
+  static void* allocate_node(size_t size, Value const& value) {
     SymbolTable::item_added();
-    return SymbolTableHash::BaseConfig::allocate_node(size, value);
+    return AllocateHeap(size, mtSymbol);
   }
-  static void free_node(void* memory, Symbol* const& value) {
+  static void free_node(void* memory, Value const& value) {
     // We get here because #1 some threads lost a race to insert a newly created Symbol
     // or #2 we're cleaning up unused symbol.
     // If #1, then the symbol can be either permanent (refcount==PERM_REFCOUNT),
@@ -150,7 +151,7 @@
       assert(value->refcount() == 0, "expected dead symbol");
     }
     SymbolTable::delete_symbol(value);
-    SymbolTableHash::BaseConfig::free_node(memory, value);
+    FreeHeap(memory);
     SymbolTable::item_removed();
   }
 };
--- a/src/hotspot/share/classfile/systemDictionary.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/classfile/systemDictionary.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -2142,7 +2142,7 @@
     // See whether biased locking is enabled and if so set it for this
     // klass.
     // Note that this must be done past the last potential blocking
-    // point / safepoint. We enable biased locking lazily using a
+    // point / safepoint. We might enable biased locking lazily using a
     // VM_Operation to iterate the SystemDictionary and installing the
     // biasable mark word into each InstanceKlass's prototype header.
     // To avoid race conditions where we accidentally miss enabling the
--- a/src/hotspot/share/code/codeCache.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/code/codeCache.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -1142,25 +1142,28 @@
 
   // At least one nmethod has been marked for deoptimization
 
-  Deoptimization::deoptimize_all_marked();
+  // All this already happens inside a VM_Operation, so we'll do all the work here.
+  // Stuff copied from VM_Deoptimize and modified slightly.
+
+  // We do not want any GCs to happen while we are in the middle of this VM operation
+  ResourceMark rm;
+  DeoptimizationMarker dm;
+
+  // Deoptimize all activations depending on marked nmethods
+  Deoptimization::deoptimize_dependents();
+
+  // Make the dependent methods not entrant
+  make_marked_nmethods_not_entrant();
 }
 #endif // INCLUDE_JVMTI
 
-// Mark methods for deopt (if safe or possible).
+// Deoptimize all methods
 void CodeCache::mark_all_nmethods_for_deoptimization() {
   MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
   CompiledMethodIterator iter(CompiledMethodIterator::only_alive_and_not_unloading);
   while(iter.next()) {
     CompiledMethod* nm = iter.method();
-    if (!nm->method()->is_method_handle_intrinsic() &&
-        !nm->is_not_installed() &&
-        nm->is_in_use() &&
-        !nm->is_native_method()) {
-      // Intrinsics and native methods are never deopted. A method that is
-      // not installed yet or is not in use is not safe to deopt; the
-      // is_in_use() check covers the not_entrant and not zombie cases.
-      // Note: A not_entrant method can become a zombie at anytime if it was
-      // made not_entrant before the previous safepoint/handshake.
+    if (!nm->method()->is_method_handle_intrinsic()) {
       nm->mark_for_deoptimization();
     }
   }
@@ -1188,12 +1191,7 @@
   CompiledMethodIterator iter(CompiledMethodIterator::only_alive_and_not_unloading);
   while(iter.next()) {
     CompiledMethod* nm = iter.method();
-    if (nm->is_marked_for_deoptimization() && nm->is_in_use()) {
-      // only_alive_and_not_unloading() can return not_entrant nmethods.
-      // A not_entrant method can become a zombie at anytime if it was
-      // made not_entrant before the previous safepoint/handshake. The
-      // is_in_use() check covers the not_entrant and not zombie cases
-      // that have become true after the method was marked for deopt.
+    if (nm->is_marked_for_deoptimization() && !nm->is_not_entrant()) {
       nm->make_not_entrant();
     }
   }
@@ -1205,12 +1203,17 @@
 
   if (number_of_nmethods_with_dependencies() == 0) return;
 
+  // CodeCache can only be updated by a thread_in_VM and they will all be
+  // stopped during the safepoint so CodeCache will be safe to update without
+  // holding the CodeCache_lock.
+
   KlassDepChange changes(dependee);
 
   // Compute the dependent nmethods
   if (mark_for_deoptimization(changes) > 0) {
     // At least one nmethod has been marked for deoptimization
-    Deoptimization::deoptimize_all_marked();
+    VM_Deoptimize op;
+    VMThread::execute(&op);
   }
 }
 
@@ -1219,9 +1222,26 @@
   // --- Compile_lock is not held. However we are at a safepoint.
   assert_locked_or_safepoint(Compile_lock);
 
+  // CodeCache can only be updated by a thread_in_VM and they will all be
+  // stopped dring the safepoint so CodeCache will be safe to update without
+  // holding the CodeCache_lock.
+
   // Compute the dependent nmethods
   if (mark_for_deoptimization(m_h()) > 0) {
-    Deoptimization::deoptimize_all_marked();
+    // At least one nmethod has been marked for deoptimization
+
+    // All this already happens inside a VM_Operation, so we'll do all the work here.
+    // Stuff copied from VM_Deoptimize and modified slightly.
+
+    // We do not want any GCs to happen while we are in the middle of this VM operation
+    ResourceMark rm;
+    DeoptimizationMarker dm;
+
+    // Deoptimize all activations depending on marked nmethods
+    Deoptimization::deoptimize_dependents();
+
+    // Make the dependent methods not entrant
+    make_marked_nmethods_not_entrant();
   }
 }
 
--- a/src/hotspot/share/code/compiledMethod.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/code/compiledMethod.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -214,7 +214,6 @@
   };
 
   virtual bool  is_in_use() const = 0;
-  virtual bool  is_not_installed() const = 0;
   virtual int   comp_level() const = 0;
   virtual int   compile_id() const = 0;
 
--- a/src/hotspot/share/code/dependencyContext.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/code/dependencyContext.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -99,15 +99,15 @@
   // Safepoints are forbidden during DC lifetime. GC can invalidate
   // _dependency_context_addr if it relocates the holder
   // (e.g. CallSiteContext Java object).
-  uint64_t _safepoint_counter;
+  SafepointStateTracker _safepoint_tracker;
 
   DependencyContext(nmethodBucket* volatile* bucket_addr, volatile uint64_t* last_cleanup_addr)
     : _dependency_context_addr(bucket_addr),
       _last_cleanup_addr(last_cleanup_addr),
-      _safepoint_counter(SafepointSynchronize::safepoint_counter()) {}
+      _safepoint_tracker(SafepointSynchronize::safepoint_state_tracker()) {}
 
   ~DependencyContext() {
-    assert(SafepointSynchronize::is_same_safepoint(_safepoint_counter), "must be the same safepoint");
+    assert(!_safepoint_tracker.safepoint_state_changed(), "must be the same safepoint");
   }
 #else
   DependencyContext(nmethodBucket* volatile* bucket_addr, volatile uint64_t* last_cleanup_addr)
--- a/src/hotspot/share/code/nmethod.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/code/nmethod.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -50,7 +50,6 @@
 #include "oops/oop.inline.hpp"
 #include "prims/jvmtiImpl.hpp"
 #include "runtime/atomic.hpp"
-#include "runtime/deoptimization.hpp"
 #include "runtime/flags/flagSetting.hpp"
 #include "runtime/frame.inline.hpp"
 #include "runtime/handles.inline.hpp"
@@ -1178,7 +1177,11 @@
   // have the Method* live here, in case we unload the nmethod because
   // it is pointing to some oop (other than the Method*) being unloaded.
   if (_method != NULL) {
-    _method->unlink_code(this);
+    // OSR methods point to the Method*, but the Method* does not
+    // point back!
+    if (_method->code() == this) {
+      _method->clear_code(); // Break a cycle
+    }
   }
 
   // Make the class unloaded - i.e., change state and notify sweeper
@@ -1260,9 +1263,16 @@
   }
 }
 
-void nmethod::unlink_from_method() {
-  if (method() != NULL) {
-    method()->unlink_code(this);
+void nmethod::unlink_from_method(bool acquire_lock) {
+  // We need to check if both the _code and _from_compiled_code_entry_point
+  // refer to this nmethod because there is a race in setting these two fields
+  // in Method* as seen in bugid 4947125.
+  // If the vep() points to the zombie nmethod, the memory for the nmethod
+  // could be flushed and the compiler and vtable stubs could still call
+  // through it.
+  if (method() != NULL && (method()->code() == this ||
+                           method()->from_compiled_entry() == verified_entry_point())) {
+    method()->clear_code(acquire_lock);
   }
 }
 
@@ -1289,24 +1299,24 @@
 
   // during patching, depending on the nmethod state we must notify the GC that
   // code has been unloaded, unregistering it. We cannot do this right while
-  // holding the CompiledMethod_lock because we need to use the CodeCache_lock. This
+  // holding the Patching_lock because we need to use the CodeCache_lock. This
   // would be prone to deadlocks.
   // This flag is used to remember whether we need to later lock and unregister.
   bool nmethod_needs_unregister = false;
 
-  // invalidate osr nmethod before acquiring the patching lock since
-  // they both acquire leaf locks and we don't want a deadlock.
-  // This logic is equivalent to the logic below for patching the
-  // verified entry point of regular methods. We check that the
-  // nmethod is in use to ensure that it is invalidated only once.
-  if (is_osr_method() && is_in_use()) {
-    // this effectively makes the osr nmethod not entrant
-    invalidate_osr_method();
-  }
-
   {
+    // invalidate osr nmethod before acquiring the patching lock since
+    // they both acquire leaf locks and we don't want a deadlock.
+    // This logic is equivalent to the logic below for patching the
+    // verified entry point of regular methods. We check that the
+    // nmethod is in use to ensure that it is invalidated only once.
+    if (is_osr_method() && is_in_use()) {
+      // this effectively makes the osr nmethod not entrant
+      invalidate_osr_method();
+    }
+
     // Enter critical section.  Does not block for safepoint.
-    MutexLocker pl(CompiledMethod_lock, Mutex::_no_safepoint_check_flag);
+    MutexLocker pl(Patching_lock, Mutex::_no_safepoint_check_flag);
 
     if (_state == state) {
       // another thread already performed this transition so nothing
@@ -1350,9 +1360,8 @@
     log_state_change();
 
     // Remove nmethod from method.
-    unlink_from_method();
-
-  } // leave critical region under CompiledMethod_lock
+    unlink_from_method(false /* already owns Patching_lock */);
+  } // leave critical region under Patching_lock
 
 #if INCLUDE_JVMCI
   // Invalidate can't occur while holding the Patching lock
--- a/src/hotspot/share/code/nmethod.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/code/nmethod.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -119,7 +119,7 @@
   // used by jvmti to track if an unload event has been posted for this nmethod.
   bool _unload_reported;
 
-  // Protected by CompiledMethod_lock
+  // Protected by Patching_lock
   volatile signed char _state;               // {not_installed, in_use, not_entrant, zombie, unloaded}
 
 #ifdef ASSERT
@@ -387,7 +387,7 @@
 
   int   comp_level() const                        { return _comp_level; }
 
-  void unlink_from_method();
+  void unlink_from_method(bool acquire_lock);
 
   // Support for oops in scopes and relocs:
   // Note: index 0 is reserved for null.
--- a/src/hotspot/share/gc/cms/cmsHeap.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/cms/cmsHeap.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -62,7 +62,7 @@
   }
 
   size_t used_in_bytes() {
-    return _space->used();
+    return _space->used_stable();
   }
 };
 
--- a/src/hotspot/share/gc/cms/compactibleFreeListSpace.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/cms/compactibleFreeListSpace.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -372,6 +372,8 @@
     )
   }
   _dictionary->set_par_lock(&_parDictionaryAllocLock);
+
+  _used_stable = 0;
 }
 
 // Like CompactibleSpace forward() but always calls cross_threshold() to
@@ -577,6 +579,14 @@
   return capacity() - free();
 }
 
+size_t CompactibleFreeListSpace::used_stable() const {
+  return _used_stable;
+}
+
+void CompactibleFreeListSpace::recalculate_used_stable() {
+  _used_stable = used();
+}
+
 size_t CompactibleFreeListSpace::free() const {
   // "MT-safe, but not MT-precise"(TM), if you will: i.e.
   // if you do this while the structures are in flux you
@@ -1374,6 +1384,9 @@
     debug_only(fc->mangleAllocated(size));
   }
 
+  // After allocation, recalculate used space and update used_stable
+  recalculate_used_stable();
+
   return res;
 }
 
--- a/src/hotspot/share/gc/cms/compactibleFreeListSpace.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/cms/compactibleFreeListSpace.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -192,6 +192,9 @@
   // Used to keep track of limit of sweep for the space
   HeapWord* _sweep_limit;
 
+  // Stable value of used().
+  size_t _used_stable;
+
   // Used to make the young collector update the mod union table
   MemRegionClosure* _preconsumptionDirtyCardClosure;
 
@@ -412,6 +415,17 @@
   // which overestimates the region by returning the entire
   // committed region (this is safe, but inefficient).
 
+  // Returns monotonically increasing stable used space bytes for CMS.
+  // This is required for jstat and other memory monitoring tools
+  // that might otherwise see inconsistent used space values during a garbage
+  // collection, promotion or allocation into compactibleFreeListSpace.
+  // The value returned by this function might be smaller than the
+  // actual value.
+  size_t used_stable() const;
+  // Recalculate and cache the current stable used() value. Only to be called
+  // in places where we can be sure that the result is stable.
+  void recalculate_used_stable();
+
   // Returns a subregion of the space containing all the objects in
   // the space.
   MemRegion used_region() const {
--- a/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -692,6 +692,10 @@
   return _cmsSpace->max_alloc_in_words() * HeapWordSize;
 }
 
+size_t ConcurrentMarkSweepGeneration::used_stable() const {
+  return cmsSpace()->used_stable();
+}
+
 size_t ConcurrentMarkSweepGeneration::max_available() const {
   return free() + _virtual_space.uncommitted_size();
 }
@@ -1523,6 +1527,8 @@
   FreelistLocker z(this);
   MetaspaceGC::compute_new_size();
   _cmsGen->compute_new_size_free_list();
+  // recalculate CMS used space after CMS collection
+  _cmsGen->cmsSpace()->recalculate_used_stable();
 }
 
 // A work method used by the foreground collector to do
@@ -2051,6 +2057,7 @@
 
   _capacity_at_prologue = capacity();
   _used_at_prologue = used();
+  _cmsSpace->recalculate_used_stable();
 
   // We enable promotion tracking so that card-scanning can recognize
   // which objects have been promoted during this GC and skip them.
@@ -2123,6 +2130,7 @@
   _eden_chunk_index = 0;
 
   size_t cms_used   = _cmsGen->cmsSpace()->used();
+  _cmsGen->cmsSpace()->recalculate_used_stable();
 
   // update performance counters - this uses a special version of
   // update_counters() that allows the utilization to be passed as a
@@ -2816,6 +2824,8 @@
     rp->enable_discovery();
     _collectorState = Marking;
   }
+
+  _cmsGen->cmsSpace()->recalculate_used_stable();
 }
 
 void CMSCollector::checkpointRootsInitialWork() {
@@ -4177,6 +4187,7 @@
     MutexLocker y(bitMapLock(),
                   Mutex::_no_safepoint_check_flag);
     checkpointRootsFinalWork();
+    _cmsGen->cmsSpace()->recalculate_used_stable();
   }
   verify_work_stacks_empty();
   verify_overflow_empty();
@@ -4250,7 +4261,6 @@
   if (should_unload_classes()) {
     heap->prune_scavengable_nmethods();
   }
-  JvmtiExport::gc_epilogue();
 
   // If we encountered any (marking stack / work queue) overflow
   // events during the current CMS cycle, take appropriate
@@ -5337,9 +5347,14 @@
     // further below.
     {
       CMSTokenSyncWithLocks ts(true, _cmsGen->freelistLock());
+
       // Update heap occupancy information which is used as
       // input to soft ref clearing policy at the next gc.
       Universe::update_heap_info_at_gc();
+
+      // recalculate CMS used space after CMS collection
+      _cmsGen->cmsSpace()->recalculate_used_stable();
+
       _collectorState = Resizing;
     }
   }
@@ -5428,6 +5443,7 @@
     // Gather statistics on the young generation collection.
     collector()->stats().record_gc0_end(used());
   }
+  _cmsSpace->recalculate_used_stable();
 }
 
 void CMSCollector::sweepWork(ConcurrentMarkSweepGeneration* old_gen) {
--- a/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -1112,6 +1112,7 @@
   double occupancy() const { return ((double)used())/((double)capacity()); }
   size_t contiguous_available() const;
   size_t unsafe_max_alloc_nogc() const;
+  size_t used_stable() const;
 
   // over-rides
   MemRegion used_region_at_save_marks() const;
--- a/src/hotspot/share/gc/cms/gSpaceCounters.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/cms/gSpaceCounters.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -59,7 +59,7 @@
   }
 
   inline void update_used() {
-    _used->set_value(_gen->used());
+    _used->set_value(_gen->used_stable());
   }
 
   // special version of update_used() to allow the used value to be
@@ -103,7 +103,7 @@
     GenerationUsedHelper(Generation* g) : _gen(g) { }
 
     inline jlong take_sample() {
-      return _gen->used();
+      return _gen->used_stable();
     }
 };
 
--- a/src/hotspot/share/gc/g1/g1Analytics.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1Analytics.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -38,7 +38,7 @@
   0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
 };
 
-static double cost_per_card_ms_defaults[] = {
+static double cost_per_log_buffer_entry_ms_defaults[] = {
   0.01, 0.005, 0.005, 0.003, 0.003, 0.002, 0.002, 0.0015
 };
 
@@ -47,7 +47,7 @@
   1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0
 };
 
-static double cost_per_entry_ms_defaults[] = {
+static double young_only_cost_per_remset_card_ms_defaults[] = {
   0.015, 0.01, 0.01, 0.008, 0.008, 0.0055, 0.0055, 0.005
 };
 
@@ -77,12 +77,12 @@
     _alloc_rate_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
     _prev_collection_pause_end_ms(0.0),
     _rs_length_diff_seq(new TruncatedSeq(TruncatedSeqLength)),
-    _cost_per_card_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
+    _cost_per_log_buffer_entry_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
     _cost_scan_hcc_seq(new TruncatedSeq(TruncatedSeqLength)),
     _young_cards_per_entry_ratio_seq(new TruncatedSeq(TruncatedSeqLength)),
     _mixed_cards_per_entry_ratio_seq(new TruncatedSeq(TruncatedSeqLength)),
-    _cost_per_entry_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
-    _mixed_cost_per_entry_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
+    _young_only_cost_per_remset_card_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
+    _mixed_cost_per_remset_card_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
     _cost_per_byte_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
     _constant_other_time_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
     _young_other_cost_per_region_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
@@ -101,10 +101,10 @@
   int index = MIN2(ParallelGCThreads - 1, 7u);
 
   _rs_length_diff_seq->add(rs_length_diff_defaults[index]);
-  _cost_per_card_ms_seq->add(cost_per_card_ms_defaults[index]);
+  _cost_per_log_buffer_entry_ms_seq->add(cost_per_log_buffer_entry_ms_defaults[index]);
   _cost_scan_hcc_seq->add(0.0);
   _young_cards_per_entry_ratio_seq->add(young_cards_per_entry_ratio_defaults[index]);
-  _cost_per_entry_ms_seq->add(cost_per_entry_ms_defaults[index]);
+  _young_only_cost_per_remset_card_ms_seq->add(young_only_cost_per_remset_card_ms_defaults[index]);
   _cost_per_byte_ms_seq->add(cost_per_byte_ms_defaults[index]);
   _constant_other_time_ms_seq->add(constant_other_time_ms_defaults[index]);
   _young_other_cost_per_region_ms_seq->add(young_other_cost_per_region_ms_defaults[index]);
@@ -158,19 +158,19 @@
     (pause_time_ms * _recent_prev_end_times_for_all_gcs_sec->num()) / interval_ms;
 }
 
-void G1Analytics::report_cost_per_card_ms(double cost_per_card_ms) {
-  _cost_per_card_ms_seq->add(cost_per_card_ms);
+void G1Analytics::report_cost_per_log_buffer_entry_ms(double cost_per_log_buffer_entry_ms) {
+  _cost_per_log_buffer_entry_ms_seq->add(cost_per_log_buffer_entry_ms);
 }
 
 void G1Analytics::report_cost_scan_hcc(double cost_scan_hcc) {
   _cost_scan_hcc_seq->add(cost_scan_hcc);
 }
 
-void G1Analytics::report_cost_per_entry_ms(double cost_per_entry_ms, bool for_young_gc) {
+void G1Analytics::report_cost_per_remset_card_ms(double cost_per_remset_card_ms, bool for_young_gc) {
   if (for_young_gc) {
-    _cost_per_entry_ms_seq->add(cost_per_entry_ms);
+    _young_only_cost_per_remset_card_ms_seq->add(cost_per_remset_card_ms);
   } else {
-    _mixed_cost_per_entry_ms_seq->add(cost_per_entry_ms);
+    _mixed_cost_per_remset_card_ms_seq->add(cost_per_remset_card_ms);
   }
 }
 
@@ -222,8 +222,8 @@
   return get_new_prediction(_alloc_rate_ms_seq);
 }
 
-double G1Analytics::predict_cost_per_card_ms() const {
-  return get_new_prediction(_cost_per_card_ms_seq);
+double G1Analytics::predict_cost_per_log_buffer_entry_ms() const {
+  return get_new_prediction(_cost_per_log_buffer_entry_ms_seq);
 }
 
 double G1Analytics::predict_scan_hcc_ms() const {
@@ -231,7 +231,7 @@
 }
 
 double G1Analytics::predict_rs_update_time_ms(size_t pending_cards) const {
-  return pending_cards * predict_cost_per_card_ms() + predict_scan_hcc_ms();
+  return pending_cards * predict_cost_per_log_buffer_entry_ms() + predict_scan_hcc_ms();
 }
 
 double G1Analytics::predict_young_cards_per_entry_ratio() const {
@@ -256,17 +256,17 @@
 
 double G1Analytics::predict_rs_scan_time_ms(size_t card_num, bool for_young_gc) const {
   if (for_young_gc) {
-    return card_num * get_new_prediction(_cost_per_entry_ms_seq);
+    return card_num * get_new_prediction(_young_only_cost_per_remset_card_ms_seq);
   } else {
     return predict_mixed_rs_scan_time_ms(card_num);
   }
 }
 
 double G1Analytics::predict_mixed_rs_scan_time_ms(size_t card_num) const {
-  if (_mixed_cost_per_entry_ms_seq->num() < 3) {
-    return card_num * get_new_prediction(_cost_per_entry_ms_seq);
+  if (_mixed_cost_per_remset_card_ms_seq->num() < 3) {
+    return card_num * get_new_prediction(_young_only_cost_per_remset_card_ms_seq);
   } else {
-    return card_num * get_new_prediction(_mixed_cost_per_entry_ms_seq);
+    return card_num * get_new_prediction(_mixed_cost_per_remset_card_ms_seq);
   }
 }
 
--- a/src/hotspot/share/gc/g1/g1Analytics.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1Analytics.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -46,12 +46,12 @@
   double        _prev_collection_pause_end_ms;
 
   TruncatedSeq* _rs_length_diff_seq;
-  TruncatedSeq* _cost_per_card_ms_seq;
+  TruncatedSeq* _cost_per_log_buffer_entry_ms_seq;
   TruncatedSeq* _cost_scan_hcc_seq;
   TruncatedSeq* _young_cards_per_entry_ratio_seq;
   TruncatedSeq* _mixed_cards_per_entry_ratio_seq;
-  TruncatedSeq* _cost_per_entry_ms_seq;
-  TruncatedSeq* _mixed_cost_per_entry_ms_seq;
+  TruncatedSeq* _young_only_cost_per_remset_card_ms_seq;
+  TruncatedSeq* _mixed_cost_per_remset_card_ms_seq;
   TruncatedSeq* _cost_per_byte_ms_seq;
   TruncatedSeq* _constant_other_time_ms_seq;
   TruncatedSeq* _young_other_cost_per_region_ms_seq;
@@ -99,9 +99,9 @@
   void report_concurrent_mark_remark_times_ms(double ms);
   void report_concurrent_mark_cleanup_times_ms(double ms);
   void report_alloc_rate_ms(double alloc_rate);
-  void report_cost_per_card_ms(double cost_per_card_ms);
+  void report_cost_per_log_buffer_entry_ms(double cost_per_log_buffer_entry_ms);
   void report_cost_scan_hcc(double cost_scan_hcc);
-  void report_cost_per_entry_ms(double cost_per_entry_ms, bool for_young_gc);
+  void report_cost_per_remset_card_ms(double cost_per_remset_card_ms, bool for_young_gc);
   void report_cards_per_entry_ratio(double cards_per_entry_ratio, bool for_young_gc);
   void report_rs_length_diff(double rs_length_diff);
   void report_cost_per_byte_ms(double cost_per_byte_ms, bool mark_or_rebuild_in_progress);
@@ -116,7 +116,7 @@
   double predict_alloc_rate_ms() const;
   int num_alloc_rate_ms() const;
 
-  double predict_cost_per_card_ms() const;
+  double predict_cost_per_log_buffer_entry_ms() const;
 
   double predict_scan_hcc_ms() const;
 
--- a/src/hotspot/share/gc/g1/g1CardTable.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1CardTable.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -30,28 +30,6 @@
 #include "runtime/atomic.hpp"
 #include "runtime/orderAccess.hpp"
 
-bool G1CardTable::mark_card_deferred(size_t card_index) {
-  CardValue val = _byte_map[card_index];
-  // It's already processed
-  if ((val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val()) {
-    return false;
-  }
-
-  // Cached bit can be installed either on a clean card or on a claimed card.
-  CardValue new_val = val;
-  if (val == clean_card_val()) {
-    new_val = deferred_card_val();
-  } else {
-    if (val & claimed_card_val()) {
-      new_val = val | deferred_card_val();
-    }
-  }
-  if (new_val != val) {
-    Atomic::cmpxchg(new_val, &_byte_map[card_index], val);
-  }
-  return true;
-}
-
 void G1CardTable::g1_mark_as_young(const MemRegion& mr) {
   CardValue *const first = byte_for(mr.start());
   CardValue *const last = byte_after(mr.last());
--- a/src/hotspot/share/gc/g1/g1CardTable.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1CardTable.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -44,55 +44,65 @@
   virtual void on_commit(uint start_idx, size_t num_regions, bool zero_filled);
 };
 
-class G1CardTable: public CardTable {
+class G1CardTable : public CardTable {
   friend class VMStructs;
   friend class G1CardTableChangedListener;
 
   G1CardTableChangedListener _listener;
 
+public:
   enum G1CardValues {
-    g1_young_gen = CT_MR_BS_last_reserved << 1
+    g1_young_gen = CT_MR_BS_last_reserved << 1,
+
+    // During evacuation we use the card table to consolidate the cards we need to
+    // scan for roots onto the card table from the various sources. Further it is
+    // used to record already completely scanned cards to avoid re-scanning them
+    // when incrementally evacuating the old gen regions of a collection set.
+    // This means that already scanned cards should be preserved.
+    //
+    // The merge at the start of each evacuation round simply sets cards to dirty
+    // that are clean; scanned cards are set to 0x1.
+    //
+    // This means that the LSB determines what to do with the card during evacuation
+    // given the following possible values:
+    //
+    // 11111111 - clean, do not scan
+    // 00000001 - already scanned, do not scan
+    // 00000000 - dirty, needs to be scanned.
+    //
+    g1_card_already_scanned = 0x1
   };
 
-public:
+  static const size_t WordAllClean = SIZE_MAX;
+  static const size_t WordAllDirty = 0;
+
+  STATIC_ASSERT(BitsPerByte == 8);
+  static const size_t WordAlreadyScanned = (SIZE_MAX / 255) * g1_card_already_scanned;
+
   G1CardTable(MemRegion whole_heap): CardTable(whole_heap, /* scanned concurrently */ true), _listener() {
     _listener.set_card_table(this);
   }
-  bool is_card_dirty(size_t card_index) {
-    return _byte_map[card_index] == dirty_card_val();
-  }
 
   static CardValue g1_young_card_val() { return g1_young_gen; }
 
-/*
-   Claimed and deferred bits are used together in G1 during the evacuation
-   pause. These bits can have the following state transitions:
-   1. The claimed bit can be put over any other card state. Except that
-      the "dirty -> dirty and claimed" transition is checked for in
-      G1 code and is not used.
-   2. Deferred bit can be set only if the previous state of the card
-      was either clean or claimed. mark_card_deferred() is wait-free.
-      We do not care if the operation is be successful because if
-      it does not it will only result in duplicate entry in the update
-      buffer because of the "cache-miss". So it's not worth spinning.
- */
-
-  bool is_card_claimed(size_t card_index) {
-    CardValue val = _byte_map[card_index];
-    return (val & (clean_card_mask_val() | claimed_card_val())) == claimed_card_val();
-  }
-
-  inline void set_card_claimed(size_t card_index);
-
   void verify_g1_young_region(MemRegion mr) PRODUCT_RETURN;
   void g1_mark_as_young(const MemRegion& mr);
 
-  bool mark_card_deferred(size_t card_index);
+  size_t index_for_cardvalue(CardValue const* p) const {
+    return pointer_delta(p, _byte_map, sizeof(CardValue));
+  }
+
+  // Mark the given card as Dirty if it is Clean.
+  inline void mark_clean_as_dirty(size_t card_index);
 
-  bool is_card_deferred(size_t card_index) {
-    CardValue val = _byte_map[card_index];
-    return (val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val();
-  }
+  // Change Clean cards in a (large) area on the card table as Dirty, preserving
+  // already scanned cards. Assumes that most cards in that area are Clean.
+  inline void mark_region_dirty(size_t start_card_index, size_t num_cards);
+
+  // Mark the given range of cards as Scanned. All of these cards must be Dirty.
+  inline void mark_as_scanned(size_t start_card_index, size_t num_cards);
+
+  inline uint region_idx_for(CardValue* p);
 
   static size_t compute_size(size_t mem_region_size_in_words) {
     size_t number_of_slots = (mem_region_size_in_words / card_size_in_words);
--- a/src/hotspot/share/gc/g1/g1CardTable.inline.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1CardTable.inline.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -26,15 +26,58 @@
 #define SHARE_GC_G1_G1CARDTABLE_INLINE_HPP
 
 #include "gc/g1/g1CardTable.hpp"
+#include "gc/g1/heapRegion.hpp"
 
-void G1CardTable::set_card_claimed(size_t card_index) {
-  jbyte val = _byte_map[card_index];
-  if (val == clean_card_val()) {
-    val = (jbyte)claimed_card_val();
-  } else {
-    val |= (jbyte)claimed_card_val();
+inline uint G1CardTable::region_idx_for(CardValue* p) {
+  size_t const card_idx = pointer_delta(p, _byte_map, sizeof(CardValue));
+  return (uint)(card_idx >> (HeapRegion::LogOfHRGrainBytes - card_shift));
+}
+
+inline void G1CardTable::mark_clean_as_dirty(size_t card_index) {
+  CardValue value = _byte_map[card_index];
+  if (value == clean_card_val()) {
+    _byte_map[card_index] = dirty_card_val();
   }
-  _byte_map[card_index] = val;
 }
 
-#endif // SHARE_GC_G1_G1CARDTABLE_INLINE_HPP
+inline void G1CardTable::mark_region_dirty(size_t start_card_index, size_t num_cards) {
+  assert(is_aligned(start_card_index, sizeof(size_t)), "Start card index must be aligned.");
+  assert(is_aligned(num_cards, sizeof(size_t)), "Number of cards to change must be evenly divisible.");
+
+  size_t const num_chunks = num_cards / sizeof(size_t);
+
+  size_t* cur_word = (size_t*)&_byte_map[start_card_index];
+  size_t* const end_word_map = cur_word + num_chunks;
+  while (cur_word < end_word_map) {
+    size_t value = *cur_word;
+    if (value == WordAllClean) {
+      *cur_word = WordAllDirty;
+    } else if (value == WordAllDirty) {
+      // do nothing.
+    } else {
+      // There is a mix of cards in there. Tread slowly.
+      CardValue* cur = (CardValue*)cur_word;
+      for (size_t i = 0; i < sizeof(size_t); i++) {
+        CardValue value = *cur;
+        if (value == clean_card_val()) {
+          *cur = dirty_card_val();
+        }
+        cur++;
+      }
+    }
+    cur_word++;
+  }
+}
+
+inline void G1CardTable::mark_as_scanned(size_t start_card_index, size_t num_cards) {
+  CardValue* start = &_byte_map[start_card_index];
+  CardValue* const end = start + num_cards;
+  while (start < end) {
+    CardValue value = *start;
+    assert(value == dirty_card_val(),
+           "Must have been dirty %d start " PTR_FORMAT " " PTR_FORMAT, value, p2i(start), p2i(end));
+    *start++ = g1_card_already_scanned;
+  }
+}
+
+#endif /* SHARE_GC_G1_G1CARDTABLE_INLINE_HPP */
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -1677,7 +1677,6 @@
   _card_table = ct;
 
   G1BarrierSet::satb_mark_queue_set().initialize(this,
-                                                 SATB_Q_CBL_mon,
                                                  &bs->satb_mark_queue_buffer_allocator(),
                                                  G1SATBProcessCompletedThreshold,
                                                  G1SATBBufferEnqueueingThresholdPercent);
@@ -1955,7 +1954,7 @@
     n_completed_buffers++;
   }
   assert(dcqs.completed_buffers_num() == 0, "Completed buffers exist!");
-  phase_times()->record_thread_work_item(G1GCPhaseTimes::UpdateRS, worker_i, n_completed_buffers, G1GCPhaseTimes::UpdateRSProcessedBuffers);
+  phase_times()->record_thread_work_item(G1GCPhaseTimes::MergeLB, worker_i, n_completed_buffers, G1GCPhaseTimes::MergeLBProcessedBuffers);
 }
 
 // Computes the sum of the storage used by the various regions.
@@ -2239,8 +2238,8 @@
   _collection_set.iterate(cl);
 }
 
-void G1CollectedHeap::collection_set_iterate_increment_from(HeapRegionClosure *cl, uint worker_id) {
-  _collection_set.iterate_incremental_part_from(cl, worker_id, workers()->active_workers());
+void G1CollectedHeap::collection_set_iterate_increment_from(HeapRegionClosure *cl, HeapRegionClaimer* hr_claimer, uint worker_id) {
+  _collection_set.iterate_incremental_part_from(cl, hr_claimer, worker_id, workers()->active_workers());
 }
 
 HeapWord* G1CollectedHeap::block_start(const void* addr) const {
@@ -2631,8 +2630,6 @@
   size_t _total_humongous;
   size_t _candidate_humongous;
 
-  G1DirtyCardQueue _dcq;
-
   bool humongous_region_is_candidate(G1CollectedHeap* g1h, HeapRegion* region) const {
     assert(region->is_starts_humongous(), "Must start a humongous object");
 
@@ -2692,8 +2689,7 @@
  public:
   RegisterRegionsWithRegionAttrTableClosure()
   : _total_humongous(0),
-    _candidate_humongous(0),
-    _dcq(&G1BarrierSet::dirty_card_queue_set()) {
+    _candidate_humongous(0) {
   }
 
   virtual bool do_heap_region(HeapRegion* r) {
@@ -2708,49 +2704,9 @@
     uint rindex = r->hrm_index();
     g1h->set_humongous_reclaim_candidate(rindex, is_candidate);
     if (is_candidate) {
+      g1h->register_humongous_region_with_region_attr(rindex);
       _candidate_humongous++;
-      g1h->register_humongous_region_with_region_attr(rindex);
-      // Is_candidate already filters out humongous object with large remembered sets.
-      // If we have a humongous object with a few remembered sets, we simply flush these
-      // remembered set entries into the DCQS. That will result in automatic
-      // re-evaluation of their remembered set entries during the following evacuation
-      // phase.
-      if (!r->rem_set()->is_empty()) {
-        guarantee(r->rem_set()->occupancy_less_or_equal_than(G1RSetSparseRegionEntries),
-                  "Found a not-small remembered set here. This is inconsistent with previous assumptions.");
-        G1CardTable* ct = g1h->card_table();
-        HeapRegionRemSetIterator hrrs(r->rem_set());
-        size_t card_index;
-        while (hrrs.has_next(card_index)) {
-          CardTable::CardValue* card_ptr = ct->byte_for_index(card_index);
-          // The remembered set might contain references to already freed
-          // regions. Filter out such entries to avoid failing card table
-          // verification.
-          if (g1h->is_in(ct->addr_for(card_ptr))) {
-            if (*card_ptr != G1CardTable::dirty_card_val()) {
-              *card_ptr = G1CardTable::dirty_card_val();
-              _dcq.enqueue(card_ptr);
-            }
-          }
-        }
-        assert(hrrs.n_yielded() == r->rem_set()->occupied(),
-               "Remembered set hash maps out of sync, cur: " SIZE_FORMAT " entries, next: " SIZE_FORMAT " entries",
-               hrrs.n_yielded(), r->rem_set()->occupied());
-        // We should only clear the card based remembered set here as we will not
-        // implicitly rebuild anything else during eager reclaim. Note that at the moment
-        // (and probably never) we do not enter this path if there are other kind of
-        // remembered sets for this region.
-        r->rem_set()->clear_locked(true /* only_cardset */);
-        // Clear_locked() above sets the state to Empty. However we want to continue
-        // collecting remembered set entries for humongous regions that were not
-        // reclaimed.
-        r->rem_set()->set_state_complete();
-#ifdef ASSERT
-        G1HeapRegionAttr region_attr = g1h->region_attr(oop(r->bottom()));
-        assert(region_attr.needs_remset_update(), "must be");
-#endif
-      }
-      assert(r->rem_set()->is_empty(), "At this point any humongous candidate remembered set must be empty.");
+      // We will later handle the remembered sets of these regions.
     } else {
       g1h->register_region_with_region_attr(r);
     }
@@ -2761,8 +2717,6 @@
 
   size_t total_humongous() const { return _total_humongous; }
   size_t candidate_humongous() const { return _candidate_humongous; }
-
-  void flush_rem_set_entries() { _dcq.flush(); }
 };
 
 void G1CollectedHeap::register_regions_with_region_attr() {
@@ -2775,9 +2729,6 @@
                                          cl.total_humongous(),
                                          cl.candidate_humongous());
   _has_humongous_reclaim_candidates = cl.candidate_humongous() > 0;
-
-  // Finally flush all remembered set entries to re-check into the global DCQS.
-  cl.flush_rem_set_entries();
 }
 
 #ifndef PRODUCT
@@ -3072,7 +3023,7 @@
                                                   workers()->active_workers(),
                                                   collection_set()->young_region_length(),
                                                   collection_set()->optional_region_length());
-        pre_evacuate_collection_set(evacuation_info);
+        pre_evacuate_collection_set(evacuation_info, &per_thread_states);
 
         // Actually do the work...
         evacuate_initial_collection_set(&per_thread_states);
@@ -3105,9 +3056,7 @@
 
         double sample_end_time_sec = os::elapsedTime();
         double pause_time_ms = (sample_end_time_sec - sample_start_time_sec) * MILLIUNITS;
-        size_t total_cards_scanned = phase_times()->sum_thread_work_items(G1GCPhaseTimes::ScanRS, G1GCPhaseTimes::ScanRSScannedCards) +
-                                     phase_times()->sum_thread_work_items(G1GCPhaseTimes::OptScanRS, G1GCPhaseTimes::ScanRSScannedCards);
-        policy()->record_collection_pause_end(pause_time_ms, total_cards_scanned, heap_used_bytes_before_gc);
+        policy()->record_collection_pause_end(pause_time_ms, heap_used_bytes_before_gc);
       }
 
       verify_after_young_collection(verify_type);
@@ -3581,7 +3530,7 @@
   phase_times()->record_merge_pss_time_ms((os::elapsedTime() - merge_pss_time_start) * 1000.0);
 }
 
-void G1CollectedHeap::pre_evacuate_collection_set(G1EvacuationInfo& evacuation_info) {
+void G1CollectedHeap::pre_evacuate_collection_set(G1EvacuationInfo& evacuation_info, G1ParScanThreadStateSet* per_thread_states) {
   _expand_heap_after_alloc_failure = true;
   _evacuation_failed = false;
 
@@ -3592,10 +3541,15 @@
   // Initialize the GC alloc regions.
   _allocator->init_gc_alloc_regions(evacuation_info);
 
+  {
+    Ticks start = Ticks::now();
+    rem_set()->prepare_for_scan_heap_roots();
+    phase_times()->record_prepare_heap_roots_time_ms((Ticks::now() - start).seconds() * 1000.0);
+  }
+
   register_regions_with_region_attr();
   assert(_verifier->check_region_attr_table(), "Inconsistency in the region attributes table.");
 
-  rem_set()->prepare_for_scan_rem_set();
   _preserved_marks_set.assert_empty();
 
 #if COMPILER2_OR_JVMCI
@@ -3697,8 +3651,8 @@
 
   void scan_roots(G1ParScanThreadState* pss, uint worker_id) {
     _root_processor->evacuate_roots(pss, worker_id);
-    _g1h->rem_set()->update_rem_set(pss, worker_id);
-    _g1h->rem_set()->scan_rem_set(pss, worker_id, G1GCPhaseTimes::ScanRS, G1GCPhaseTimes::ObjCopy, G1GCPhaseTimes::CodeRoots);
+    _g1h->rem_set()->scan_heap_roots(pss, worker_id, G1GCPhaseTimes::ScanHR, G1GCPhaseTimes::ObjCopy);
+    _g1h->rem_set()->scan_collection_set_regions(pss, worker_id, G1GCPhaseTimes::ScanHR, G1GCPhaseTimes::CodeRoots, G1GCPhaseTimes::ObjCopy);
   }
 
   void evacuate_live_objects(G1ParScanThreadState* pss, uint worker_id) {
@@ -3725,6 +3679,14 @@
 };
 
 void G1CollectedHeap::evacuate_initial_collection_set(G1ParScanThreadStateSet* per_thread_states) {
+  G1GCPhaseTimes* p = phase_times();
+
+  {
+    Ticks start = Ticks::now();
+    rem_set()->merge_heap_roots(false /* remset_only */, G1GCPhaseTimes::MergeRS);
+    p->record_merge_heap_roots_time((Ticks::now() - start).seconds() * 1000.0);
+  }
+
   Tickspan task_time;
   const uint num_workers = workers()->active_workers();
 
@@ -3739,7 +3701,6 @@
   }
   Tickspan total_processing = Ticks::now() - start_processing;
 
-  G1GCPhaseTimes* p = phase_times();
   p->record_initial_evac_time(task_time.seconds() * 1000.0);
   p->record_or_add_code_root_fixup_time((total_processing - task_time).seconds() * 1000.0);
 }
@@ -3747,7 +3708,8 @@
 class G1EvacuateOptionalRegionsTask : public G1EvacuateRegionsBaseTask {
 
   void scan_roots(G1ParScanThreadState* pss, uint worker_id) {
-    _g1h->rem_set()->scan_rem_set(pss, worker_id, G1GCPhaseTimes::OptScanRS, G1GCPhaseTimes::OptObjCopy, G1GCPhaseTimes::OptCodeRoots);
+    _g1h->rem_set()->scan_heap_roots(pss, worker_id, G1GCPhaseTimes::OptScanHR, G1GCPhaseTimes::OptObjCopy);
+    _g1h->rem_set()->scan_collection_set_regions(pss, worker_id, G1GCPhaseTimes::OptScanHR, G1GCPhaseTimes::OptCodeRoots, G1GCPhaseTimes::OptObjCopy);
   }
 
   void evacuate_live_objects(G1ParScanThreadState* pss, uint worker_id) {
@@ -3783,8 +3745,6 @@
 void G1CollectedHeap::evacuate_optional_collection_set(G1ParScanThreadStateSet* per_thread_states) {
   const double gc_start_time_ms = phase_times()->cur_collection_start_sec() * 1000.0;
 
-  Ticks start = Ticks::now();
-
   while (!evacuation_failed() && _collection_set.optional_region_length() > 0) {
 
     double time_used_ms = os::elapsedTime() * 1000.0 - gc_start_time_ms;
@@ -3797,18 +3757,24 @@
       break;
     }
 
-    evacuate_next_optional_regions(per_thread_states);
+    {
+      Ticks start = Ticks::now();
+      rem_set()->merge_heap_roots(true /* remset_only */, G1GCPhaseTimes::OptMergeRS);
+      phase_times()->record_or_add_optional_merge_heap_roots_time((Ticks::now() - start).seconds() * 1000.0);
+    }
+
+    {
+      Ticks start = Ticks::now();
+      evacuate_next_optional_regions(per_thread_states);
+      phase_times()->record_or_add_optional_evac_time((Ticks::now() - start).seconds() * 1000.0);
+    }
   }
 
   _collection_set.abandon_optional_collection_set(per_thread_states);
-
-  phase_times()->record_or_add_optional_evac_time((Ticks::now() - start).seconds() * 1000.0);
 }
 
 void G1CollectedHeap::post_evacuate_collection_set(G1EvacuationInfo& evacuation_info, G1ParScanThreadStateSet* per_thread_states) {
-  // Also cleans the card table from temporary duplicate detection information used
-  // during UpdateRS/ScanRS.
-  rem_set()->cleanup_after_scan_rem_set();
+  rem_set()->cleanup_after_scan_heap_roots();
 
   // Process any discovered reference objects - we have
   // to do this _before_ we retire the GC alloc regions
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -78,7 +78,6 @@
 class G1HotCardCache;
 class G1RemSet;
 class G1YoungRemSetSamplingThread;
-class HeapRegionRemSetIterator;
 class G1ConcurrentMark;
 class G1ConcurrentMarkThread;
 class G1ConcurrentRefine;
@@ -757,7 +756,7 @@
   void evacuate_next_optional_regions(G1ParScanThreadStateSet* per_thread_states);
 
 public:
-  void pre_evacuate_collection_set(G1EvacuationInfo& evacuation_info);
+  void pre_evacuate_collection_set(G1EvacuationInfo& evacuation_info, G1ParScanThreadStateSet* pss);
   void post_evacuate_collection_set(G1EvacuationInfo& evacuation_info, G1ParScanThreadStateSet* pss);
 
   void expand_heap_after_young_collection();
@@ -1115,7 +1114,8 @@
 
  public:
 
-  inline G1HeapRegionAttr region_attr(const void* obj);
+  inline G1HeapRegionAttr region_attr(const void* obj) const;
+  inline G1HeapRegionAttr region_attr(uint idx) const;
 
   // Return "TRUE" iff the given object address is in the reserved
   // region of g1.
@@ -1182,7 +1182,12 @@
   // Starts the iteration so that the start regions of a given worker id over the
   // set active_workers are evenly spread across the set of collection set regions
   // to be iterated.
-  void collection_set_iterate_increment_from(HeapRegionClosure *blk, uint worker_id);
+  // The variant with the HeapRegionClaimer guarantees that the closure will be
+  // applied to a particular region exactly once.
+  void collection_set_iterate_increment_from(HeapRegionClosure *blk, uint worker_id) {
+    collection_set_iterate_increment_from(blk, NULL, worker_id);
+  }
+  void collection_set_iterate_increment_from(HeapRegionClosure *blk, HeapRegionClaimer* hr_claimer, uint worker_id);
 
   // Returns the HeapRegion that contains addr. addr must not be NULL.
   template <class T>
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -163,10 +163,14 @@
   return _region_attr.is_in_cset_or_humongous((HeapWord*)obj);
 }
 
-G1HeapRegionAttr G1CollectedHeap::region_attr(const void* addr) {
+G1HeapRegionAttr G1CollectedHeap::region_attr(const void* addr) const {
   return _region_attr.at((HeapWord*)addr);
 }
 
+G1HeapRegionAttr G1CollectedHeap::region_attr(uint idx) const {
+  return _region_attr.get_by_index(idx);
+}
+
 void G1CollectedHeap::register_humongous_region_with_region_attr(uint index) {
   _region_attr.set_humongous(index, region_at(index)->rem_set()->is_tracked());
 }
@@ -177,7 +181,7 @@
 
 void G1CollectedHeap::register_old_region_with_region_attr(HeapRegion* r) {
   _region_attr.set_in_old(r->hrm_index(), r->rem_set()->is_tracked());
-  _rem_set->prepare_for_scan_rem_set(r->hrm_index());
+  _rem_set->prepare_for_scan_heap_roots(r->hrm_index());
 }
 
 void G1CollectedHeap::register_optional_region_with_region_attr(HeapRegion* r) {
--- a/src/hotspot/share/gc/g1/g1CollectionSet.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1CollectionSet.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -217,10 +217,13 @@
   }
 }
 
-void G1CollectionSet::iterate_incremental_part_from(HeapRegionClosure* cl, uint worker_id, uint total_workers) const {
+void G1CollectionSet::iterate_incremental_part_from(HeapRegionClosure* cl,
+                                                    HeapRegionClaimer* hr_claimer,
+                                                    uint worker_id,
+                                                    uint total_workers) const {
   assert_at_safepoint();
 
-  size_t len = _collection_set_cur_length - _inc_part_start;
+  size_t len = increment_length();
   if (len == 0) {
     return;
   }
@@ -229,9 +232,12 @@
   size_t cur_pos = start_pos;
 
   do {
-    HeapRegion* r = _g1h->region_at(_collection_set_regions[cur_pos + _inc_part_start]);
-    bool result = cl->do_heap_region(r);
-    guarantee(!result, "Must not cancel iteration");
+    uint region_idx = _collection_set_regions[cur_pos + _inc_part_start];
+    if (hr_claimer == NULL || hr_claimer->claim_region(region_idx)) {
+      HeapRegion* r = _g1h->region_at(region_idx);
+      bool result = cl->do_heap_region(r);
+      guarantee(!result, "Must not cancel iteration");
+    }
 
     cur_pos++;
     if (cur_pos == len) {
--- a/src/hotspot/share/gc/g1/g1CollectionSet.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1CollectionSet.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -36,6 +36,7 @@
 class G1Policy;
 class G1SurvivorRegions;
 class HeapRegion;
+class HeapRegionClaimer;
 class HeapRegionClosure;
 
 // The collection set.
@@ -279,7 +280,12 @@
 
   // Iterate over the current collection set increment applying the given HeapRegionClosure
   // from a starting position determined by the given worker id.
-  void iterate_incremental_part_from(HeapRegionClosure* cl, uint worker_id, uint total_workers) const;
+  void iterate_incremental_part_from(HeapRegionClosure* cl, HeapRegionClaimer* hr_claimer, uint worker_id, uint total_workers) const;
+
+  // Returns the length of the current increment in number of regions.
+  size_t increment_length() const { return _collection_set_cur_length - _inc_part_start; }
+  // Returns the length of the whole current collection set in number of regions
+  size_t cur_length() const { return _collection_set_cur_length; }
 
   // Iterate over the entire collection set (all increments calculated so far), applying
   // the given HeapRegionClosure on all of them.
--- a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -2419,12 +2419,13 @@
     abort_marking_if_regular_check_fail();
   }
 
+  // Can't assert qset is empty here, even if not aborted.  If concurrent,
+  // some other thread might be adding to the queue.  If not concurrent,
+  // some other thread might have won the race for the last buffer, but
+  // has not yet decremented the count.
+
   _draining_satb_buffers = false;
 
-  assert(has_aborted() ||
-         _cm->concurrent() ||
-         satb_mq_set.completed_buffers_num() == 0, "invariant");
-
   // again, this was a potentially expensive operation, decrease the
   // limits to get the regular clock call early
   decrease_limits();
--- a/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -206,7 +206,7 @@
     // available buffers near green_zone value.  When yellow_size is
     // large we don't want to allow a full step to accumulate before
     // doing any processing, as that might lead to significantly more
-    // than green_zone buffers to be processed by update_rs.
+    // than green_zone buffers to be processed during scanning.
     step = MIN2(step, ParallelGCThreads / 2.0);
   }
   size_t activate_offset = static_cast<size_t>(ceil(step * (worker_i + 1)));
@@ -322,18 +322,18 @@
 }
 
 static size_t calc_new_green_zone(size_t green,
-                                  double update_rs_time,
-                                  size_t update_rs_processed_buffers,
+                                  double log_buffer_scan_time,
+                                  size_t processed_log_buffers,
                                   double goal_ms) {
   // Adjust green zone based on whether we're meeting the time goal.
   // Limit to max_green_zone.
   const double inc_k = 1.1, dec_k = 0.9;
-  if (update_rs_time > goal_ms) {
+  if (log_buffer_scan_time > goal_ms) {
     if (green > 0) {
       green = static_cast<size_t>(green * dec_k);
     }
-  } else if (update_rs_time < goal_ms &&
-             update_rs_processed_buffers > green) {
+  } else if (log_buffer_scan_time < goal_ms &&
+             processed_log_buffers > green) {
     green = static_cast<size_t>(MAX2(green * inc_k, green + 1.0));
     green = MIN2(green, max_green_zone);
   }
@@ -350,20 +350,20 @@
   return MIN2(yellow + (yellow - green), max_red_zone);
 }
 
-void G1ConcurrentRefine::update_zones(double update_rs_time,
-                                      size_t update_rs_processed_buffers,
+void G1ConcurrentRefine::update_zones(double log_buffer_scan_time,
+                                      size_t processed_log_buffers,
                                       double goal_ms) {
   log_trace( CTRL_TAGS )("Updating Refinement Zones: "
-                         "update_rs time: %.3fms, "
-                         "update_rs buffers: " SIZE_FORMAT ", "
-                         "update_rs goal time: %.3fms",
-                         update_rs_time,
-                         update_rs_processed_buffers,
+                         "log buffer scan time: %.3fms, "
+                         "processed buffers: " SIZE_FORMAT ", "
+                         "goal time: %.3fms",
+                         log_buffer_scan_time,
+                         processed_log_buffers,
                          goal_ms);
 
   _green_zone = calc_new_green_zone(_green_zone,
-                                    update_rs_time,
-                                    update_rs_processed_buffers,
+                                    log_buffer_scan_time,
+                                    processed_log_buffers,
                                     goal_ms);
   _yellow_zone = calc_new_yellow_zone(_green_zone, _min_yellow_zone_size);
   _red_zone = calc_new_red_zone(_green_zone, _yellow_zone);
@@ -376,13 +376,13 @@
             _green_zone, _yellow_zone, _red_zone);
 }
 
-void G1ConcurrentRefine::adjust(double update_rs_time,
-                                size_t update_rs_processed_buffers,
+void G1ConcurrentRefine::adjust(double log_buffer_scan_time,
+                                size_t processed_log_buffers,
                                 double goal_ms) {
   G1DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set();
 
   if (G1UseAdaptiveConcRefinement) {
-    update_zones(update_rs_time, update_rs_processed_buffers, goal_ms);
+    update_zones(log_buffer_scan_time, processed_log_buffers, goal_ms);
 
     // Change the barrier params
     if (max_num_threads() == 0) {
--- a/src/hotspot/share/gc/g1/g1ConcurrentRefine.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1ConcurrentRefine.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -97,8 +97,8 @@
                      size_t min_yellow_zone_size);
 
   // Update green/yellow/red zone values based on how well goals are being met.
-  void update_zones(double update_rs_time,
-                    size_t update_rs_processed_buffers,
+  void update_zones(double log_buffer_scan_time,
+                    size_t processed_log_buffers,
                     double goal_ms);
 
   static uint worker_id_offset();
@@ -115,7 +115,7 @@
   void stop();
 
   // Adjust refinement thresholds based on work done during the pause and the goal time.
-  void adjust(double update_rs_time, size_t update_rs_processed_buffers, double goal_ms);
+  void adjust(double log_buffer_scan_time, size_t processed_log_buffers, double goal_ms);
 
   size_t activation_threshold(uint worker_id) const;
   size_t deactivation_threshold(uint worker_id) const;
--- a/src/hotspot/share/gc/g1/g1DirtyCardQueue.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1DirtyCardQueue.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -78,7 +78,14 @@
 }
 
 G1DirtyCardQueueSet::G1DirtyCardQueueSet(bool notify_when_complete) :
-  PtrQueueSet(notify_when_complete),
+  PtrQueueSet(),
+  _cbl_mon(NULL),
+  _completed_buffers_head(NULL),
+  _completed_buffers_tail(NULL),
+  _n_completed_buffers(0),
+  _process_completed_buffers_threshold(ProcessCompletedBuffersThresholdNever),
+  _process_completed_buffers(false),
+  _notify_when_complete(notify_when_complete),
   _max_completed_buffers(MaxCompletedBuffersUnlimited),
   _completed_buffers_padding(0),
   _free_ids(NULL),
@@ -90,6 +97,7 @@
 }
 
 G1DirtyCardQueueSet::~G1DirtyCardQueueSet() {
+  abandon_completed_buffers();
   delete _free_ids;
 }
 
@@ -101,7 +109,9 @@
 void G1DirtyCardQueueSet::initialize(Monitor* cbl_mon,
                                      BufferNode::Allocator* allocator,
                                      bool init_free_ids) {
-  PtrQueueSet::initialize(cbl_mon, allocator);
+  PtrQueueSet::initialize(allocator);
+  assert(_cbl_mon == NULL, "Init order issue?");
+  _cbl_mon = cbl_mon;
   if (init_free_ids) {
     _free_ids = new G1FreeIdSet(0, num_par_ids());
   }
@@ -111,6 +121,123 @@
   G1ThreadLocalData::dirty_card_queue(t).handle_zero_index();
 }
 
+void G1DirtyCardQueueSet::enqueue_completed_buffer(BufferNode* cbn) {
+  MutexLocker x(_cbl_mon, Mutex::_no_safepoint_check_flag);
+  cbn->set_next(NULL);
+  if (_completed_buffers_tail == NULL) {
+    assert(_completed_buffers_head == NULL, "Well-formedness");
+    _completed_buffers_head = cbn;
+    _completed_buffers_tail = cbn;
+  } else {
+    _completed_buffers_tail->set_next(cbn);
+    _completed_buffers_tail = cbn;
+  }
+  _n_completed_buffers++;
+
+  if (!process_completed_buffers() &&
+      (_n_completed_buffers > process_completed_buffers_threshold())) {
+    set_process_completed_buffers(true);
+    if (_notify_when_complete) {
+      _cbl_mon->notify_all();
+    }
+  }
+  assert_completed_buffers_list_len_correct_locked();
+}
+
+BufferNode* G1DirtyCardQueueSet::get_completed_buffer(size_t stop_at) {
+  MutexLocker x(_cbl_mon, Mutex::_no_safepoint_check_flag);
+
+  if (_n_completed_buffers <= stop_at) {
+    return NULL;
+  }
+
+  assert(_n_completed_buffers > 0, "invariant");
+  assert(_completed_buffers_head != NULL, "invariant");
+  assert(_completed_buffers_tail != NULL, "invariant");
+
+  BufferNode* bn = _completed_buffers_head;
+  _n_completed_buffers--;
+  _completed_buffers_head = bn->next();
+  if (_completed_buffers_head == NULL) {
+    assert(_n_completed_buffers == 0, "invariant");
+    _completed_buffers_tail = NULL;
+    set_process_completed_buffers(false);
+  }
+  assert_completed_buffers_list_len_correct_locked();
+  bn->set_next(NULL);
+  return bn;
+}
+
+void G1DirtyCardQueueSet::abandon_completed_buffers() {
+  BufferNode* buffers_to_delete = NULL;
+  {
+    MutexLocker x(_cbl_mon, Mutex::_no_safepoint_check_flag);
+    buffers_to_delete = _completed_buffers_head;
+    _completed_buffers_head = NULL;
+    _completed_buffers_tail = NULL;
+    _n_completed_buffers = 0;
+    set_process_completed_buffers(false);
+  }
+  while (buffers_to_delete != NULL) {
+    BufferNode* bn = buffers_to_delete;
+    buffers_to_delete = bn->next();
+    bn->set_next(NULL);
+    deallocate_buffer(bn);
+  }
+}
+
+void G1DirtyCardQueueSet::notify_if_necessary() {
+  MutexLocker x(_cbl_mon, Mutex::_no_safepoint_check_flag);
+  if (_n_completed_buffers > process_completed_buffers_threshold()) {
+    set_process_completed_buffers(true);
+    if (_notify_when_complete)
+      _cbl_mon->notify();
+  }
+}
+
+#ifdef ASSERT
+void G1DirtyCardQueueSet::assert_completed_buffers_list_len_correct_locked() {
+  assert_lock_strong(_cbl_mon);
+  size_t n = 0;
+  for (BufferNode* bn = _completed_buffers_head; bn != NULL; bn = bn->next()) {
+    ++n;
+  }
+  assert(n == _n_completed_buffers,
+         "Completed buffer length is wrong: counted: " SIZE_FORMAT
+         ", expected: " SIZE_FORMAT, n, _n_completed_buffers);
+}
+#endif // ASSERT
+
+// Merge lists of buffers. Notify the processing threads.
+// The source queue is emptied as a result. The queues
+// must share the monitor.
+void G1DirtyCardQueueSet::merge_bufferlists(G1DirtyCardQueueSet *src) {
+  assert(_cbl_mon == src->_cbl_mon, "Should share the same lock");
+  MutexLocker x(_cbl_mon, Mutex::_no_safepoint_check_flag);
+  if (_completed_buffers_tail == NULL) {
+    assert(_completed_buffers_head == NULL, "Well-formedness");
+    _completed_buffers_head = src->_completed_buffers_head;
+    _completed_buffers_tail = src->_completed_buffers_tail;
+  } else {
+    assert(_completed_buffers_head != NULL, "Well formedness");
+    if (src->_completed_buffers_head != NULL) {
+      _completed_buffers_tail->set_next(src->_completed_buffers_head);
+      _completed_buffers_tail = src->_completed_buffers_tail;
+    }
+  }
+  _n_completed_buffers += src->_n_completed_buffers;
+
+  src->_n_completed_buffers = 0;
+  src->_completed_buffers_head = NULL;
+  src->_completed_buffers_tail = NULL;
+  src->set_process_completed_buffers(false);
+
+  assert(_completed_buffers_head == NULL && _completed_buffers_tail == NULL ||
+         _completed_buffers_head != NULL && _completed_buffers_tail != NULL,
+         "Sanity");
+  assert_completed_buffers_list_len_correct_locked();
+}
+
 bool G1DirtyCardQueueSet::apply_closure_to_buffer(G1CardTableEntryClosure* cl,
                                                   BufferNode* node,
                                                   bool consume,
--- a/src/hotspot/share/gc/g1/g1DirtyCardQueue.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1DirtyCardQueue.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -76,6 +76,21 @@
 };
 
 class G1DirtyCardQueueSet: public PtrQueueSet {
+  Monitor* _cbl_mon;  // Protects the fields below.
+  BufferNode* _completed_buffers_head;
+  BufferNode* _completed_buffers_tail;
+  volatile size_t _n_completed_buffers;
+
+  size_t _process_completed_buffers_threshold;
+  volatile bool _process_completed_buffers;
+
+  // If true, notify_all on _cbl_mon when the threshold is reached.
+  bool _notify_when_complete;
+
+  void assert_completed_buffers_list_len_correct_locked() NOT_DEBUG_RETURN;
+
+  void abandon_completed_buffers();
+
   // Apply the closure to the elements of "node" from it's index to
   // buffer_size.  If all closure applications return true, then
   // returns true.  Stops processing after the first closure
@@ -111,7 +126,7 @@
   // mutator must start doing some of the concurrent refinement work,
   size_t _max_completed_buffers;
   size_t _completed_buffers_padding;
-  static const size_t MaxCompletedBuffersUnlimited = ~size_t(0);
+  static const size_t MaxCompletedBuffersUnlimited = SIZE_MAX;
 
   G1FreeIdSet* _free_ids;
 
@@ -142,6 +157,34 @@
   // it can be reused in place.
   bool process_or_enqueue_completed_buffer(BufferNode* node);
 
+  virtual void enqueue_completed_buffer(BufferNode* node);
+
+  // If the number of completed buffers is > stop_at, then remove and
+  // return a completed buffer from the list.  Otherwise, return NULL.
+  BufferNode* get_completed_buffer(size_t stop_at = 0);
+
+  // The number of buffers in the list.  Racy...
+  size_t completed_buffers_num() const { return _n_completed_buffers; }
+
+  bool process_completed_buffers() { return _process_completed_buffers; }
+  void set_process_completed_buffers(bool x) { _process_completed_buffers = x; }
+
+  // Get/Set the number of completed buffers that triggers log processing.
+  // Log processing should be done when the number of buffers exceeds the
+  // threshold.
+  void set_process_completed_buffers_threshold(size_t sz) {
+    _process_completed_buffers_threshold = sz;
+  }
+  size_t process_completed_buffers_threshold() const {
+    return _process_completed_buffers_threshold;
+  }
+  static const size_t ProcessCompletedBuffersThresholdNever = SIZE_MAX;
+
+  // Notify the consumer if the number of buffers crossed the threshold
+  void notify_if_necessary();
+
+  void merge_bufferlists(G1DirtyCardQueueSet* src);
+
   // Apply G1RefineCardConcurrentlyClosure to completed buffers until there are stop_at
   // completed buffers remaining.
   bool refine_completed_buffer_concurrently(uint worker_i, size_t stop_at);
@@ -150,13 +193,13 @@
   // must never return false. Must only be called during GC.
   bool apply_closure_during_gc(G1CardTableEntryClosure* cl, uint worker_i);
 
-  void reset_for_par_iteration() { _cur_par_buffer_node = completed_buffers_head(); }
+  void reset_for_par_iteration() { _cur_par_buffer_node = _completed_buffers_head; }
   // Applies the current closure to all completed buffers, non-consumptively.
   // Can be used in parallel, all callers using the iteration state initialized
   // by reset_for_par_iteration.
   void par_apply_closure_to_all_completed_buffers(G1CardTableEntryClosure* cl);
 
-  // If a full collection is happening, reset partial logs, and ignore
+  // If a full collection is happening, reset partial logs, and release
   // completed ones: the full collection will make them all irrelevant.
   void abandon_logs();
 
--- a/src/hotspot/share/gc/g1/g1EvacFailure.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1EvacFailure.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -37,15 +37,19 @@
 #include "oops/compressedOops.inline.hpp"
 #include "oops/oop.inline.hpp"
 
-class UpdateRSetDeferred : public BasicOopIterateClosure {
+class UpdateLogBuffersDeferred : public BasicOopIterateClosure {
 private:
   G1CollectedHeap* _g1h;
   G1DirtyCardQueue* _dcq;
   G1CardTable*    _ct;
 
+  // Remember the last enqueued card to avoid enqueuing the same card over and over;
+  // since we only ever handle a card once, this is sufficient.
+  size_t _last_enqueued_card;
+
 public:
-  UpdateRSetDeferred(G1DirtyCardQueue* dcq) :
-    _g1h(G1CollectedHeap::heap()), _dcq(dcq), _ct(_g1h->card_table()) {}
+  UpdateLogBuffersDeferred(G1DirtyCardQueue* dcq) :
+    _g1h(G1CollectedHeap::heap()), _dcq(dcq), _ct(_g1h->card_table()), _last_enqueued_card(SIZE_MAX) {}
 
   virtual void do_oop(narrowOop* p) { do_oop_work(p); }
   virtual void do_oop(      oop* p) { do_oop_work(p); }
@@ -62,8 +66,9 @@
       return;
     }
     size_t card_index = _ct->index_for(p);
-    if (_ct->mark_card_deferred(card_index)) {
+    if (card_index != _last_enqueued_card) {
       _dcq->enqueue(_ct->byte_for_index(card_index));
+      _last_enqueued_card = card_index;
     }
   }
 };
@@ -73,21 +78,21 @@
   G1ConcurrentMark* _cm;
   HeapRegion* _hr;
   size_t _marked_bytes;
-  UpdateRSetDeferred* _update_rset_cl;
+  UpdateLogBuffersDeferred* _log_buffer_cl;
   bool _during_initial_mark;
   uint _worker_id;
   HeapWord* _last_forwarded_object_end;
 
 public:
   RemoveSelfForwardPtrObjClosure(HeapRegion* hr,
-                                 UpdateRSetDeferred* update_rset_cl,
+                                 UpdateLogBuffersDeferred* log_buffer_cl,
                                  bool during_initial_mark,
                                  uint worker_id) :
     _g1h(G1CollectedHeap::heap()),
     _cm(_g1h->concurrent_mark()),
     _hr(hr),
     _marked_bytes(0),
-    _update_rset_cl(update_rset_cl),
+    _log_buffer_cl(log_buffer_cl),
     _during_initial_mark(during_initial_mark),
     _worker_id(worker_id),
     _last_forwarded_object_end(hr->bottom()) { }
@@ -144,7 +149,7 @@
       // The problem is that, if evacuation fails, we might have
       // remembered set entries missing given that we skipped cards on
       // the collection set. So, we'll recreate such entries now.
-      obj->oop_iterate(_update_rset_cl);
+      obj->oop_iterate(_log_buffer_cl);
 
       HeapWord* obj_end = obj_addr + obj_size;
       _last_forwarded_object_end = obj_end;
@@ -193,25 +198,22 @@
 class RemoveSelfForwardPtrHRClosure: public HeapRegionClosure {
   G1CollectedHeap* _g1h;
   uint _worker_id;
-  HeapRegionClaimer* _hrclaimer;
 
   G1DirtyCardQueue _dcq;
-  UpdateRSetDeferred _update_rset_cl;
+  UpdateLogBuffersDeferred _log_buffer_cl;
 
 public:
-  RemoveSelfForwardPtrHRClosure(uint worker_id,
-                                HeapRegionClaimer* hrclaimer) :
+  RemoveSelfForwardPtrHRClosure(uint worker_id) :
     _g1h(G1CollectedHeap::heap()),
     _worker_id(worker_id),
-    _hrclaimer(hrclaimer),
     _dcq(&_g1h->dirty_card_queue_set()),
-    _update_rset_cl(&_dcq){
+    _log_buffer_cl(&_dcq) {
   }
 
   size_t remove_self_forward_ptr_by_walking_hr(HeapRegion* hr,
                                                bool during_initial_mark) {
     RemoveSelfForwardPtrObjClosure rspc(hr,
-                                        &_update_rset_cl,
+                                        &_log_buffer_cl,
                                         during_initial_mark,
                                         _worker_id);
     hr->object_iterate(&rspc);
@@ -225,26 +227,24 @@
     assert(!hr->is_pinned(), "Unexpected pinned region at index %u", hr->hrm_index());
     assert(hr->in_collection_set(), "bad CS");
 
-    if (_hrclaimer->claim_region(hr->hrm_index())) {
-      if (hr->evacuation_failed()) {
-        hr->clear_index_in_opt_cset();
+    if (hr->evacuation_failed()) {
+      hr->clear_index_in_opt_cset();
 
-        bool during_initial_mark = _g1h->collector_state()->in_initial_mark_gc();
-        bool during_conc_mark = _g1h->collector_state()->mark_or_rebuild_in_progress();
+      bool during_initial_mark = _g1h->collector_state()->in_initial_mark_gc();
+      bool during_conc_mark = _g1h->collector_state()->mark_or_rebuild_in_progress();
 
-        hr->note_self_forwarding_removal_start(during_initial_mark,
+      hr->note_self_forwarding_removal_start(during_initial_mark,
                                                during_conc_mark);
-        _g1h->verifier()->check_bitmaps("Self-Forwarding Ptr Removal", hr);
+      _g1h->verifier()->check_bitmaps("Self-Forwarding Ptr Removal", hr);
 
-        hr->reset_bot();
-
-        size_t live_bytes = remove_self_forward_ptr_by_walking_hr(hr, during_initial_mark);
+      hr->reset_bot();
 
-        hr->rem_set()->clean_strong_code_roots(hr);
-        hr->rem_set()->clear_locked(true);
+      size_t live_bytes = remove_self_forward_ptr_by_walking_hr(hr, during_initial_mark);
 
-        hr->note_self_forwarding_removal_end(live_bytes);
-      }
+      hr->rem_set()->clean_strong_code_roots(hr);
+      hr->rem_set()->clear_locked(true);
+
+      hr->note_self_forwarding_removal_end(live_bytes);
     }
     return false;
   }
@@ -256,7 +256,7 @@
   _hrclaimer(_g1h->workers()->active_workers()) { }
 
 void G1ParRemoveSelfForwardPtrsTask::work(uint worker_id) {
-  RemoveSelfForwardPtrHRClosure rsfp_cl(worker_id, &_hrclaimer);
+  RemoveSelfForwardPtrHRClosure rsfp_cl(worker_id);
 
-  _g1h->collection_set_iterate_increment_from(&rsfp_cl, worker_id);
+  _g1h->collection_set_iterate_increment_from(&rsfp_cl, &_hrclaimer, worker_id);
 }
--- a/src/hotspot/share/gc/g1/g1FullCollector.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1FullCollector.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -183,7 +183,6 @@
   update_derived_pointers();
 
   BiasedLocking::restore_marks();
-  JvmtiExport::gc_epilogue();
 
   _heap->prepare_heap_for_mutators();
 
--- a/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -66,14 +66,30 @@
   _gc_par_phases[WaitForStrongCLD] = new WorkerDataArray<double>(max_gc_threads, "Wait For Strong CLD (ms):");
   _gc_par_phases[WeakCLDRoots] = new WorkerDataArray<double>(max_gc_threads, "Weak CLD Roots (ms):");
 
-  _gc_par_phases[UpdateRS] = new WorkerDataArray<double>(max_gc_threads, "Update RS (ms):");
+  _gc_par_phases[MergeRS] = new WorkerDataArray<double>(max_gc_threads, "Remembered Sets (ms):");
+  _merge_rs_merged_sparse = new WorkerDataArray<size_t>(max_gc_threads, "Merged Sparse:");
+  _gc_par_phases[MergeRS]->link_thread_work_items(_merge_rs_merged_sparse, MergeRSMergedSparse);
+  _merge_rs_merged_fine = new WorkerDataArray<size_t>(max_gc_threads, "Merged Fine:");
+  _gc_par_phases[MergeRS]->link_thread_work_items(_merge_rs_merged_fine, MergeRSMergedFine);
+  _merge_rs_merged_coarse = new WorkerDataArray<size_t>(max_gc_threads, "Merged Coarse:");
+  _gc_par_phases[MergeRS]->link_thread_work_items(_merge_rs_merged_coarse, MergeRSMergedCoarse);
+
+  _gc_par_phases[OptMergeRS] = new WorkerDataArray<double>(max_gc_threads, "Optional Remembered Sets (ms):");
+  _opt_merge_rs_merged_sparse = new WorkerDataArray<size_t>(max_gc_threads, "Merged Sparse:");
+  _gc_par_phases[OptMergeRS]->link_thread_work_items(_opt_merge_rs_merged_sparse, MergeRSMergedSparse);
+  _opt_merge_rs_merged_fine = new WorkerDataArray<size_t>(max_gc_threads, "Merged Fine:");
+  _gc_par_phases[OptMergeRS]->link_thread_work_items(_opt_merge_rs_merged_fine, MergeRSMergedFine);
+  _opt_merge_rs_merged_coarse = new WorkerDataArray<size_t>(max_gc_threads, "Merged Coarse:");
+  _gc_par_phases[OptMergeRS]->link_thread_work_items(_opt_merge_rs_merged_coarse, MergeRSMergedCoarse);
+
+  _gc_par_phases[MergeLB] = new WorkerDataArray<double>(max_gc_threads, "Log Buffers (ms):");
   if (G1HotCardCache::default_use_cache()) {
-    _gc_par_phases[ScanHCC] = new WorkerDataArray<double>(max_gc_threads, "Scan HCC (ms):");
+    _gc_par_phases[MergeHCC] = new WorkerDataArray<double>(max_gc_threads, "Hot Card Cache (ms):");
   } else {
-    _gc_par_phases[ScanHCC] = NULL;
+    _gc_par_phases[MergeHCC] = NULL;
   }
-  _gc_par_phases[ScanRS] = new WorkerDataArray<double>(max_gc_threads, "Scan RS (ms):");
-  _gc_par_phases[OptScanRS] = new WorkerDataArray<double>(max_gc_threads, "Optional Scan RS (ms):");
+  _gc_par_phases[ScanHR] = new WorkerDataArray<double>(max_gc_threads, "Scan Heap Roots (ms):");
+  _gc_par_phases[OptScanHR] = new WorkerDataArray<double>(max_gc_threads, "Optional Scan Heap Roots (ms):");
   _gc_par_phases[CodeRoots] = new WorkerDataArray<double>(max_gc_threads, "Code Root Scan (ms):");
   _gc_par_phases[OptCodeRoots] = new WorkerDataArray<double>(max_gc_threads, "Optional Code Root Scan (ms):");
   _gc_par_phases[ObjCopy] = new WorkerDataArray<double>(max_gc_threads, "Object Copy (ms):");
@@ -84,30 +100,30 @@
   _gc_par_phases[GCWorkerEnd] = new WorkerDataArray<double>(max_gc_threads, "GC Worker End (ms):");
   _gc_par_phases[Other] = new WorkerDataArray<double>(max_gc_threads, "GC Worker Other (ms):");
 
-  _scan_rs_scanned_cards = new WorkerDataArray<size_t>(max_gc_threads, "Scanned Cards:");
-  _gc_par_phases[ScanRS]->link_thread_work_items(_scan_rs_scanned_cards, ScanRSScannedCards);
-  _scan_rs_claimed_cards = new WorkerDataArray<size_t>(max_gc_threads, "Claimed Cards:");
-  _gc_par_phases[ScanRS]->link_thread_work_items(_scan_rs_claimed_cards, ScanRSClaimedCards);
-  _scan_rs_skipped_cards = new WorkerDataArray<size_t>(max_gc_threads, "Skipped Cards:");
-  _gc_par_phases[ScanRS]->link_thread_work_items(_scan_rs_skipped_cards, ScanRSSkippedCards);
+  _scan_hr_scanned_cards = new WorkerDataArray<size_t>(max_gc_threads, "Scanned Cards:");
+  _gc_par_phases[ScanHR]->link_thread_work_items(_scan_hr_scanned_cards, ScanHRScannedCards);
+  _scan_hr_scanned_blocks = new WorkerDataArray<size_t>(max_gc_threads, "Scanned Blocks:");
+  _gc_par_phases[ScanHR]->link_thread_work_items(_scan_hr_scanned_blocks, ScanHRScannedBlocks);
+  _scan_hr_claimed_chunks = new WorkerDataArray<size_t>(max_gc_threads, "Claimed Chunks:");
+  _gc_par_phases[ScanHR]->link_thread_work_items(_scan_hr_claimed_chunks, ScanHRClaimedChunks);
 
-  _opt_scan_rs_scanned_cards = new WorkerDataArray<size_t>(max_gc_threads, "Scanned Cards:");
-  _gc_par_phases[OptScanRS]->link_thread_work_items(_opt_scan_rs_scanned_cards, ScanRSScannedCards);
-  _opt_scan_rs_claimed_cards = new WorkerDataArray<size_t>(max_gc_threads, "Claimed Cards:");
-  _gc_par_phases[OptScanRS]->link_thread_work_items(_opt_scan_rs_claimed_cards, ScanRSClaimedCards);
-  _opt_scan_rs_skipped_cards = new WorkerDataArray<size_t>(max_gc_threads, "Skipped Cards:");
-  _gc_par_phases[OptScanRS]->link_thread_work_items(_opt_scan_rs_skipped_cards, ScanRSSkippedCards);
-  _opt_scan_rs_scanned_opt_refs = new WorkerDataArray<size_t>(max_gc_threads, "Scanned Refs:");
-  _gc_par_phases[OptScanRS]->link_thread_work_items(_opt_scan_rs_scanned_opt_refs, ScanRSScannedOptRefs);
-  _opt_scan_rs_used_memory = new WorkerDataArray<size_t>(max_gc_threads, "Used Memory:");
-  _gc_par_phases[OptScanRS]->link_thread_work_items(_opt_scan_rs_used_memory, ScanRSUsedMemory);
+  _opt_scan_hr_scanned_cards = new WorkerDataArray<size_t>(max_gc_threads, "Scanned Cards:");
+  _gc_par_phases[OptScanHR]->link_thread_work_items(_opt_scan_hr_scanned_cards, ScanHRScannedCards);
+  _opt_scan_hr_scanned_blocks = new WorkerDataArray<size_t>(max_gc_threads, "Scanned Blocks:");
+  _gc_par_phases[OptScanHR]->link_thread_work_items(_opt_scan_hr_scanned_blocks, ScanHRScannedBlocks);
+  _opt_scan_hr_claimed_chunks = new WorkerDataArray<size_t>(max_gc_threads, "Claimed Chunks:");
+  _gc_par_phases[OptScanHR]->link_thread_work_items(_opt_scan_hr_claimed_chunks, ScanHRClaimedChunks);
+  _opt_scan_hr_scanned_opt_refs = new WorkerDataArray<size_t>(max_gc_threads, "Scanned Refs:");
+  _gc_par_phases[OptScanHR]->link_thread_work_items(_opt_scan_hr_scanned_opt_refs, ScanHRScannedOptRefs);
+  _opt_scan_hr_used_memory = new WorkerDataArray<size_t>(max_gc_threads, "Used Memory:");
+  _gc_par_phases[OptScanHR]->link_thread_work_items(_opt_scan_hr_used_memory, ScanHRUsedMemory);
 
-  _update_rs_processed_buffers = new WorkerDataArray<size_t>(max_gc_threads, "Processed Buffers:");
-  _gc_par_phases[UpdateRS]->link_thread_work_items(_update_rs_processed_buffers, UpdateRSProcessedBuffers);
-  _update_rs_scanned_cards = new WorkerDataArray<size_t>(max_gc_threads, "Scanned Cards:");
-  _gc_par_phases[UpdateRS]->link_thread_work_items(_update_rs_scanned_cards, UpdateRSScannedCards);
-  _update_rs_skipped_cards = new WorkerDataArray<size_t>(max_gc_threads, "Skipped Cards:");
-  _gc_par_phases[UpdateRS]->link_thread_work_items(_update_rs_skipped_cards, UpdateRSSkippedCards);
+  _merge_lb_processed_buffers = new WorkerDataArray<size_t>(max_gc_threads, "Processed Buffers:");
+  _gc_par_phases[MergeLB]->link_thread_work_items(_merge_lb_processed_buffers, MergeLBProcessedBuffers);
+  _merge_lb_dirty_cards = new WorkerDataArray<size_t>(max_gc_threads, "Dirty Cards:");
+  _gc_par_phases[MergeLB]->link_thread_work_items(_merge_lb_dirty_cards, MergeLBDirtyCards);
+  _merge_lb_skipped_cards = new WorkerDataArray<size_t>(max_gc_threads, "Skipped Cards:");
+  _gc_par_phases[MergeLB]->link_thread_work_items(_merge_lb_skipped_cards, MergeLBSkippedCards);
 
   _obj_copy_lab_waste = new WorkerDataArray<size_t>(max_gc_threads, "LAB Waste");
   _gc_par_phases[ObjCopy]->link_thread_work_items(_obj_copy_lab_waste, ObjCopyLABWaste);
@@ -148,6 +164,8 @@
   _cur_optional_evac_ms = 0.0;
   _cur_collection_code_root_fixup_time_ms = 0.0;
   _cur_strong_code_root_purge_time_ms = 0.0;
+  _cur_merge_heap_roots_time_ms = 0.0;
+  _cur_optional_merge_heap_roots_time_ms = 0.0;
   _cur_evac_fail_recalc_used = 0.0;
   _cur_evac_fail_remove_self_forwards = 0.0;
   _cur_string_deduplication_time_ms = 0.0;
@@ -160,6 +178,7 @@
   _cur_collection_start_sec = 0.0;
   _root_region_scan_wait_time_ms = 0.0;
   _external_accounted_time_ms = 0.0;
+  _recorded_prepare_heap_roots_time_ms = 0.0;
   _recorded_clear_claimed_marks_time_ms = 0.0;
   _recorded_young_cset_choice_time_ms = 0.0;
   _recorded_non_young_cset_choice_time_ms = 0.0;
@@ -219,9 +238,7 @@
       record_time_secs(GCWorkerTotal, i , total_worker_time);
 
       double worker_known_time = worker_time(ExtRootScan, i) +
-                                 worker_time(ScanHCC, i) +
-                                 worker_time(UpdateRS, i) +
-                                 worker_time(ScanRS, i) +
+                                 worker_time(ScanHR, i) +
                                  worker_time(CodeRoots, i) +
                                  worker_time(ObjCopy, i) +
                                  worker_time(Termination, i);
@@ -231,11 +248,15 @@
       // Make sure all slots are uninitialized since this thread did not seem to have been started
       ASSERT_PHASE_UNINITIALIZED(GCWorkerEnd);
       ASSERT_PHASE_UNINITIALIZED(ExtRootScan);
-      ASSERT_PHASE_UNINITIALIZED(ScanHCC);
-      ASSERT_PHASE_UNINITIALIZED(UpdateRS);
-      ASSERT_PHASE_UNINITIALIZED(ScanRS);
+      ASSERT_PHASE_UNINITIALIZED(MergeHCC);
+      ASSERT_PHASE_UNINITIALIZED(MergeRS);
+      ASSERT_PHASE_UNINITIALIZED(OptMergeRS);
+      ASSERT_PHASE_UNINITIALIZED(MergeLB);
+      ASSERT_PHASE_UNINITIALIZED(ScanHR);
       ASSERT_PHASE_UNINITIALIZED(CodeRoots);
+      ASSERT_PHASE_UNINITIALIZED(OptCodeRoots);
       ASSERT_PHASE_UNINITIALIZED(ObjCopy);
+      ASSERT_PHASE_UNINITIALIZED(OptObjCopy);
       ASSERT_PHASE_UNINITIALIZED(Termination);
     }
   }
@@ -365,6 +386,7 @@
                         _recorded_young_cset_choice_time_ms +
                         _recorded_non_young_cset_choice_time_ms +
                         _cur_region_register_time +
+                        _recorded_prepare_heap_roots_time_ms +
                         _recorded_clear_claimed_marks_time_ms;
 
   info_time("Pre Evacuate Collection Set", sum_ms);
@@ -380,6 +402,7 @@
     trace_count("Humongous Candidate", _cur_fast_reclaim_humongous_candidates);
   }
 
+  debug_time("Prepare Heap Roots", _recorded_prepare_heap_roots_time_ms);
   if (_recorded_clear_claimed_marks_time_ms > 0.0) {
     debug_time("Clear Claimed Marks", _recorded_clear_claimed_marks_time_ms);
   }
@@ -387,10 +410,13 @@
 }
 
 double G1GCPhaseTimes::print_evacuate_optional_collection_set() const {
-  const double sum_ms = _cur_optional_evac_ms;
+  const double sum_ms = _cur_optional_evac_ms + _cur_optional_merge_heap_roots_time_ms;
   if (sum_ms > 0) {
-    info_time("Evacuate Optional Collection Set", sum_ms);
-    debug_phase(_gc_par_phases[OptScanRS]);
+    info_time("Merge Optional Heap Roots", _cur_optional_merge_heap_roots_time_ms);
+    debug_phase(_gc_par_phases[OptMergeRS]);
+
+    info_time("Evacuate Optional Collection Set", _cur_optional_evac_ms);
+    debug_phase(_gc_par_phases[OptScanHR]);
     debug_phase(_gc_par_phases[OptObjCopy]);
     debug_phase(_gc_par_phases[OptCodeRoots]);
     debug_phase(_gc_par_phases[OptTermination]);
@@ -398,21 +424,23 @@
   return sum_ms;
 }
 
-double G1GCPhaseTimes::print_evacuate_collection_set() const {
-  const double sum_ms = _cur_collection_initial_evac_time_ms;
+double G1GCPhaseTimes::print_evacuate_initial_collection_set() const {
+  info_time("Merge Heap Roots", _cur_merge_heap_roots_time_ms);
 
-  info_time("Evacuate Collection Set", sum_ms);
+  debug_phase(_gc_par_phases[MergeRS]);
+  if (G1HotCardCache::default_use_cache()) {
+    debug_phase(_gc_par_phases[MergeHCC]);
+  }
+  debug_phase(_gc_par_phases[MergeLB]);
+
+  info_time("Evacuate Collection Set", _cur_collection_initial_evac_time_ms);
 
   trace_phase(_gc_par_phases[GCWorkerStart], false);
   debug_phase(_gc_par_phases[ExtRootScan]);
   for (int i = ExtRootScanSubPhasesFirst; i <= ExtRootScanSubPhasesLast; i++) {
     trace_phase(_gc_par_phases[i]);
   }
-  if (G1HotCardCache::default_use_cache()) {
-    debug_phase(_gc_par_phases[ScanHCC]);
-  }
-  debug_phase(_gc_par_phases[UpdateRS]);
-  debug_phase(_gc_par_phases[ScanRS]);
+  debug_phase(_gc_par_phases[ScanHR]);
   debug_phase(_gc_par_phases[CodeRoots]);
   debug_phase(_gc_par_phases[ObjCopy]);
   debug_phase(_gc_par_phases[Termination]);
@@ -420,7 +448,7 @@
   debug_phase(_gc_par_phases[GCWorkerTotal]);
   trace_phase(_gc_par_phases[GCWorkerEnd], false);
 
-  return sum_ms;
+  return _cur_collection_initial_evac_time_ms + _cur_merge_heap_roots_time_ms;
 }
 
 double G1GCPhaseTimes::print_post_evacuate_collection_set() const {
@@ -503,7 +531,7 @@
 
   double accounted_ms = 0.0;
   accounted_ms += print_pre_evacuate_collection_set();
-  accounted_ms += print_evacuate_collection_set();
+  accounted_ms += print_evacuate_initial_collection_set();
   accounted_ms += print_evacuate_optional_collection_set();
   accounted_ms += print_post_evacuate_collection_set();
   print_other(accounted_ms);
@@ -530,10 +558,12 @@
       "CMRefRoots",
       "WaitForStrongCLD",
       "WeakCLDRoots",
-      "UpdateRS",
-      "ScanHCC",
-      "ScanRS",
-      "OptScanRS",
+      "MergeRS",
+      "OptMergeRS",
+      "MergeLB",
+      "MergeHCC",
+      "ScanHR",
+      "OptScanHR",
       "CodeRoots",
       "OptCodeRoots",
       "ObjCopy",
@@ -580,8 +610,8 @@
   _stopped = true;
 }
 
-G1GCParPhaseTimesTracker::G1GCParPhaseTimesTracker(G1GCPhaseTimes* phase_times, G1GCPhaseTimes::GCParPhases phase, uint worker_id) :
-  _start_time(), _phase(phase), _phase_times(phase_times), _worker_id(worker_id), _event() {
+G1GCParPhaseTimesTracker::G1GCParPhaseTimesTracker(G1GCPhaseTimes* phase_times, G1GCPhaseTimes::GCParPhases phase, uint worker_id, bool must_record) :
+  _start_time(), _phase(phase), _phase_times(phase_times), _worker_id(worker_id), _event(), _must_record(must_record) {
   if (_phase_times != NULL) {
     _start_time = Ticks::now();
   }
@@ -589,7 +619,11 @@
 
 G1GCParPhaseTimesTracker::~G1GCParPhaseTimesTracker() {
   if (_phase_times != NULL) {
-    _phase_times->record_time_secs(_phase, _worker_id, (Ticks::now() - _start_time).seconds());
+    if (_must_record) {
+      _phase_times->record_time_secs(_phase, _worker_id, (Ticks::now() - _start_time).seconds());
+    } else {
+      _phase_times->record_or_add_time_secs(_phase, _worker_id, (Ticks::now() - _start_time).seconds());
+    }
     _event.commit(GCId::current(), _worker_id, G1GCPhaseTimes::phase_name(_phase));
   }
 }
--- a/src/hotspot/share/gc/g1/g1GCPhaseTimes.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1GCPhaseTimes.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -60,10 +60,12 @@
     CMRefRoots,
     WaitForStrongCLD,
     WeakCLDRoots,
-    UpdateRS,
-    ScanHCC,
-    ScanRS,
-    OptScanRS,
+    MergeRS,
+    OptMergeRS,
+    MergeLB,
+    MergeHCC,
+    ScanHR,
+    OptScanHR,
     CodeRoots,
     OptCodeRoots,
     ObjCopy,
@@ -84,18 +86,24 @@
   static const GCParPhases ExtRootScanSubPhasesFirst = ThreadRoots;
   static const GCParPhases ExtRootScanSubPhasesLast = WeakCLDRoots;
 
-  enum GCScanRSWorkItems {
-    ScanRSScannedCards,
-    ScanRSClaimedCards,
-    ScanRSSkippedCards,
-    ScanRSScannedOptRefs,
-    ScanRSUsedMemory
+  enum GCMergeRSWorkTimes {
+    MergeRSMergedSparse,
+    MergeRSMergedFine,
+    MergeRSMergedCoarse
   };
 
-  enum GCUpdateRSWorkItems {
-    UpdateRSProcessedBuffers,
-    UpdateRSScannedCards,
-    UpdateRSSkippedCards
+  enum GCScanHRWorkItems {
+    ScanHRScannedCards,
+    ScanHRScannedBlocks,
+    ScanHRClaimedChunks,
+    ScanHRScannedOptRefs,
+    ScanHRUsedMemory
+  };
+
+  enum GCMergeLBWorkItems {
+    MergeLBProcessedBuffers,
+    MergeLBDirtyCards,
+    MergeLBSkippedCards
   };
 
   enum GCObjCopyWorkItems {
@@ -109,19 +117,27 @@
 
   WorkerDataArray<double>* _gc_par_phases[GCParPhasesSentinel];
 
-  WorkerDataArray<size_t>* _update_rs_processed_buffers;
-  WorkerDataArray<size_t>* _update_rs_scanned_cards;
-  WorkerDataArray<size_t>* _update_rs_skipped_cards;
+  WorkerDataArray<size_t>* _merge_rs_merged_sparse;
+  WorkerDataArray<size_t>* _merge_rs_merged_fine;
+  WorkerDataArray<size_t>* _merge_rs_merged_coarse;
+
+  WorkerDataArray<size_t>* _merge_lb_processed_buffers;
+  WorkerDataArray<size_t>* _merge_lb_dirty_cards;
+  WorkerDataArray<size_t>* _merge_lb_skipped_cards;
 
-  WorkerDataArray<size_t>* _scan_rs_scanned_cards;
-  WorkerDataArray<size_t>* _scan_rs_claimed_cards;
-  WorkerDataArray<size_t>* _scan_rs_skipped_cards;
+  WorkerDataArray<size_t>* _scan_hr_scanned_cards;
+  WorkerDataArray<size_t>* _scan_hr_scanned_blocks;
+  WorkerDataArray<size_t>* _scan_hr_claimed_chunks;
 
-  WorkerDataArray<size_t>* _opt_scan_rs_scanned_cards;
-  WorkerDataArray<size_t>* _opt_scan_rs_claimed_cards;
-  WorkerDataArray<size_t>* _opt_scan_rs_skipped_cards;
-  WorkerDataArray<size_t>* _opt_scan_rs_scanned_opt_refs;
-  WorkerDataArray<size_t>* _opt_scan_rs_used_memory;
+  WorkerDataArray<size_t>* _opt_merge_rs_merged_sparse;
+  WorkerDataArray<size_t>* _opt_merge_rs_merged_fine;
+  WorkerDataArray<size_t>* _opt_merge_rs_merged_coarse;
+
+  WorkerDataArray<size_t>* _opt_scan_hr_scanned_cards;
+  WorkerDataArray<size_t>* _opt_scan_hr_scanned_blocks;
+  WorkerDataArray<size_t>* _opt_scan_hr_claimed_chunks;
+  WorkerDataArray<size_t>* _opt_scan_hr_scanned_opt_refs;
+  WorkerDataArray<size_t>* _opt_scan_hr_used_memory;
 
   WorkerDataArray<size_t>* _obj_copy_lab_waste;
   WorkerDataArray<size_t>* _obj_copy_lab_undo_waste;
@@ -145,6 +161,9 @@
 
   double _cur_string_deduplication_time_ms;
 
+  double _cur_merge_heap_roots_time_ms;
+  double _cur_optional_merge_heap_roots_time_ms;
+
   double _cur_prepare_tlab_time_ms;
   double _cur_resize_tlab_time_ms;
 
@@ -159,6 +178,8 @@
 
   double _external_accounted_time_ms;
 
+  double _recorded_prepare_heap_roots_time_ms;
+
   double _recorded_clear_claimed_marks_time_ms;
 
   double _recorded_young_cset_choice_time_ms;
@@ -208,7 +229,8 @@
   void trace_count(const char* name, size_t value) const;
 
   double print_pre_evacuate_collection_set() const;
-  double print_evacuate_collection_set() const;
+  double print_merge_heap_roots_time() const;
+  double print_evacuate_initial_collection_set() const;
   double print_evacuate_optional_collection_set() const;
   double print_post_evacuate_collection_set() const;
   void print_other(double accounted_ms) const;
@@ -278,6 +300,14 @@
     _cur_strong_code_root_purge_time_ms = ms;
   }
 
+  void record_merge_heap_roots_time(double ms) {
+    _cur_merge_heap_roots_time_ms += ms;
+  }
+
+  void record_or_add_optional_merge_heap_roots_time(double ms) {
+    _cur_optional_merge_heap_roots_time_ms += ms;
+  }
+
   void record_evac_fail_recalc_used_time(double ms) {
     _cur_evac_fail_recalc_used = ms;
   }
@@ -357,6 +387,10 @@
     _external_accounted_time_ms += time_ms;
   }
 
+  void record_prepare_heap_roots_time_ms(double recorded_prepare_heap_roots_time_ms) {
+    _recorded_prepare_heap_roots_time_ms = recorded_prepare_heap_roots_time_ms;
+  }
+
   void record_clear_claimed_marks_time_ms(double recorded_clear_claimed_marks_time_ms) {
     _recorded_clear_claimed_marks_time_ms = recorded_clear_claimed_marks_time_ms;
   }
@@ -397,6 +431,10 @@
     return _cur_fast_reclaim_humongous_time_ms;
   }
 
+  size_t fast_reclaim_humongous_candidates() const {
+    return _cur_fast_reclaim_humongous_candidates;
+  }
+
   ReferenceProcessorPhaseTimes* ref_phase_times() { return &_ref_phase_times; }
 
   WeakProcessorPhaseTimes* weak_phase_times() { return &_weak_phase_times; }
@@ -424,8 +462,10 @@
   G1GCPhaseTimes* _phase_times;
   uint _worker_id;
   EventGCPhaseParallel _event;
+  bool _must_record;
+
 public:
-  G1GCParPhaseTimesTracker(G1GCPhaseTimes* phase_times, G1GCPhaseTimes::GCParPhases phase, uint worker_id);
+  G1GCParPhaseTimesTracker(G1GCPhaseTimes* phase_times, G1GCPhaseTimes::GCParPhases phase, uint worker_id, bool must_record = true);
   virtual ~G1GCParPhaseTimesTracker();
 };
 
--- a/src/hotspot/share/gc/g1/g1HeterogeneousHeapPolicy.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1HeterogeneousHeapPolicy.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -39,8 +39,8 @@
 }
 
 // After a collection pause, young list target length is updated. So we need to make sure we have enough regions in dram for young gen.
-void G1HeterogeneousHeapPolicy::record_collection_pause_end(double pause_time_ms, size_t cards_scanned, size_t heap_used_bytes_before_gc) {
-  G1Policy::record_collection_pause_end(pause_time_ms, cards_scanned, heap_used_bytes_before_gc);
+void G1HeterogeneousHeapPolicy::record_collection_pause_end(double pause_time_ms, size_t heap_used_bytes_before_gc) {
+  G1Policy::record_collection_pause_end(pause_time_ms, heap_used_bytes_before_gc);
   _manager->adjust_dram_regions((uint)young_list_target_length(), G1CollectedHeap::heap()->workers());
 }
 
--- a/src/hotspot/share/gc/g1/g1HeterogeneousHeapPolicy.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1HeterogeneousHeapPolicy.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -38,7 +38,7 @@
   // initialize policy
   virtual void init(G1CollectedHeap* g1h, G1CollectionSet* collection_set);
   // Record end of an evacuation pause.
-  virtual void record_collection_pause_end(double pause_time_ms, size_t cards_scanned, size_t heap_used_bytes_before_gc);
+  virtual void record_collection_pause_end(double pause_time_ms, size_t heap_used_bytes_before_gc);
   // Record the end of full collection.
   virtual void record_full_collection_end();
 
--- a/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -51,6 +51,7 @@
     _tenuring_threshold(g1h->policy()->tenuring_threshold()),
     _scanner(g1h, this),
     _worker_id(worker_id),
+    _last_enqueued_card(SIZE_MAX),
     _stack_trim_upper_threshold(GCDrainStackTargetSize * 2 + 1),
     _stack_trim_lower_threshold(GCDrainStackTargetSize),
     _trim_ticks(),
@@ -371,7 +372,7 @@
     }
 
     size_t used_memory = pss->oops_into_optional_region(hr)->used_memory();
-    _g1h->phase_times()->record_or_add_thread_work_item(G1GCPhaseTimes::OptScanRS, worker_index, used_memory, G1GCPhaseTimes::ScanRSUsedMemory);
+    _g1h->phase_times()->record_or_add_thread_work_item(G1GCPhaseTimes::OptScanHR, worker_index, used_memory, G1GCPhaseTimes::ScanHRUsedMemory);
   }
 }
 
--- a/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -60,6 +60,10 @@
 
   uint _worker_id;
 
+  // Remember the last enqueued card to avoid enqueuing the same card over and over;
+  // since we only ever scan a card once, this is sufficient.
+  size_t _last_enqueued_card;
+
   // Upper and lower threshold to start and end work queue draining.
   uint const _stack_trim_upper_threshold;
   uint const _stack_trim_lower_threshold;
@@ -128,8 +132,9 @@
     }
     size_t card_index = ct()->index_for(p);
     // If the card hasn't been added to the buffer, do it.
-    if (ct()->mark_card_deferred(card_index)) {
+    if (_last_enqueued_card != card_index) {
       dirty_card_queue().enqueue(ct()->byte_for_index(card_index));
+      _last_enqueued_card = card_index;
     }
   }
 
--- a/src/hotspot/share/gc/g1/g1Policy.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1Policy.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -572,10 +572,24 @@
   return result;
 }
 
+double G1Policy::log_buffer_processing_time() const {
+  double all_cards_processing_time = average_time_ms(G1GCPhaseTimes::ScanHR) + average_time_ms(G1GCPhaseTimes::OptScanHR);
+  size_t log_buffer_dirty_cards = phase_times()->sum_thread_work_items(G1GCPhaseTimes::MergeLB, G1GCPhaseTimes::MergeLBDirtyCards);
+  size_t scan_heap_roots_cards = phase_times()->sum_thread_work_items(G1GCPhaseTimes::ScanHR, G1GCPhaseTimes::ScanHRScannedCards) +
+                                 phase_times()->sum_thread_work_items(G1GCPhaseTimes::OptScanHR, G1GCPhaseTimes::ScanHRScannedCards);
+  // This may happen if there are duplicate cards in different log buffers.
+  if (log_buffer_dirty_cards > scan_heap_roots_cards) {
+    return all_cards_processing_time + average_time_ms(G1GCPhaseTimes::MergeLB);
+  }
+  return (all_cards_processing_time * log_buffer_dirty_cards / scan_heap_roots_cards) + average_time_ms(G1GCPhaseTimes::MergeLB);
+}
+
 // Anything below that is considered to be zero
 #define MIN_TIMER_GRANULARITY 0.0000001
 
-void G1Policy::record_collection_pause_end(double pause_time_ms, size_t cards_scanned, size_t heap_used_bytes_before_gc) {
+void G1Policy::record_collection_pause_end(double pause_time_ms, size_t heap_used_bytes_before_gc) {
+  G1GCPhaseTimes* p = phase_times();
+
   double end_time_sec = os::elapsedTime();
 
   assert_used_and_recalculate_used_equal(_g1h);
@@ -645,29 +659,40 @@
   _short_lived_surv_rate_group->start_adding_regions();
   // Do that for any other surv rate groups
 
-  double scan_hcc_time_ms = G1HotCardCache::default_use_cache() ? average_time_ms(G1GCPhaseTimes::ScanHCC) : 0.0;
+  double scan_hcc_time_ms = G1HotCardCache::default_use_cache() ? average_time_ms(G1GCPhaseTimes::MergeHCC) : 0.0;
 
   if (update_stats) {
-    double cost_per_card_ms = 0.0;
-    if (_pending_cards > 0) {
-      cost_per_card_ms = (average_time_ms(G1GCPhaseTimes::UpdateRS)) / (double) _pending_cards;
-      _analytics->report_cost_per_card_ms(cost_per_card_ms);
+    double cost_per_log_buffer_entry = 0.0;
+    size_t const pending_log_buffer_entries = p->sum_thread_work_items(G1GCPhaseTimes::MergeLB, G1GCPhaseTimes::MergeLBDirtyCards);
+    if (pending_log_buffer_entries > 0) {
+      cost_per_log_buffer_entry = log_buffer_processing_time() / pending_log_buffer_entries;
+      _analytics->report_cost_per_log_buffer_entry_ms(cost_per_log_buffer_entry);
     }
     _analytics->report_cost_scan_hcc(scan_hcc_time_ms);
 
-    double cost_per_entry_ms = 0.0;
-    if (cards_scanned > 10) {
-      double avg_time_scan_rs = average_time_ms(G1GCPhaseTimes::ScanRS);
-      if (this_pause_was_young_only) {
-        avg_time_scan_rs += average_time_ms(G1GCPhaseTimes::OptScanRS);
-      }
-      cost_per_entry_ms = avg_time_scan_rs / cards_scanned;
-      _analytics->report_cost_per_entry_ms(cost_per_entry_ms, this_pause_was_young_only);
+    size_t const total_cards_scanned = p->sum_thread_work_items(G1GCPhaseTimes::ScanHR, G1GCPhaseTimes::ScanHRScannedCards) +
+                                       p->sum_thread_work_items(G1GCPhaseTimes::OptScanHR, G1GCPhaseTimes::ScanHRScannedCards);
+    size_t remset_cards_scanned = 0;
+    // There might have been duplicate log buffer entries in the queues which could
+    // increase this value beyond the cards scanned. In this case attribute all cards
+    // to the log buffers.
+    if (pending_log_buffer_entries <= total_cards_scanned) {
+      remset_cards_scanned = total_cards_scanned - pending_log_buffer_entries;
+    }
+
+    double cost_per_remset_card_ms = 0.0;
+    if (remset_cards_scanned > 10) {
+      double avg_time_remset_scan = ((average_time_ms(G1GCPhaseTimes::ScanHR) + average_time_ms(G1GCPhaseTimes::OptScanHR)) *
+                                     remset_cards_scanned / total_cards_scanned) +
+                                    average_time_ms(G1GCPhaseTimes::MergeRS);
+
+      cost_per_remset_card_ms = avg_time_remset_scan / remset_cards_scanned;
+      _analytics->report_cost_per_remset_card_ms(cost_per_remset_card_ms, this_pause_was_young_only);
     }
 
     if (_max_rs_lengths > 0) {
       double cards_per_entry_ratio =
-        (double) cards_scanned / (double) _max_rs_lengths;
+        (double) remset_cards_scanned / (double) _max_rs_lengths;
       _analytics->report_cards_per_entry_ratio(cards_per_entry_ratio, this_pause_was_young_only);
     }
 
@@ -759,20 +784,26 @@
   }
 
   // Note that _mmu_tracker->max_gc_time() returns the time in seconds.
-  double update_rs_time_goal_ms = _mmu_tracker->max_gc_time() * MILLIUNITS * G1RSetUpdatingPauseTimePercent / 100.0;
+  double scan_log_buffer_time_goal_ms = _mmu_tracker->max_gc_time() * MILLIUNITS * G1RSetUpdatingPauseTimePercent / 100.0;
 
-  if (update_rs_time_goal_ms < scan_hcc_time_ms) {
+  if (scan_log_buffer_time_goal_ms < scan_hcc_time_ms) {
     log_debug(gc, ergo, refine)("Adjust concurrent refinement thresholds (scanning the HCC expected to take longer than Update RS time goal)."
-                                "Update RS time goal: %1.2fms Scan HCC time: %1.2fms",
-                                update_rs_time_goal_ms, scan_hcc_time_ms);
+                                "Log Buffer Scan time goal: %1.2fms Scan HCC time: %1.2fms",
+                                scan_log_buffer_time_goal_ms, scan_hcc_time_ms);
 
-    update_rs_time_goal_ms = 0;
+    scan_log_buffer_time_goal_ms = 0;
   } else {
-    update_rs_time_goal_ms -= scan_hcc_time_ms;
+    scan_log_buffer_time_goal_ms -= scan_hcc_time_ms;
   }
-  _g1h->concurrent_refine()->adjust(average_time_ms(G1GCPhaseTimes::UpdateRS),
-                                    phase_times()->sum_thread_work_items(G1GCPhaseTimes::UpdateRS),
-                                    update_rs_time_goal_ms);
+
+  double const log_buffer_time = log_buffer_processing_time();
+
+  log_debug(gc, ergo, refine)("Concurrent refinement times: Log Buffer Scan time goal: %1.2fms Log Buffer Scan time: %1.2fms HCC time: %1.2fms",
+                              scan_log_buffer_time_goal_ms, log_buffer_time, scan_hcc_time_ms);
+
+  _g1h->concurrent_refine()->adjust(log_buffer_time,
+                                    phase_times()->sum_thread_work_items(G1GCPhaseTimes::MergeLB, G1GCPhaseTimes::MergeLBProcessedBuffers),
+                                    scan_log_buffer_time_goal_ms);
 }
 
 G1IHOPControl* G1Policy::create_ihop_control(const G1Predictions* predictor){
--- a/src/hotspot/share/gc/g1/g1Policy.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1Policy.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -111,6 +111,8 @@
   bool should_update_surv_rate_group_predictors() {
     return collector_state()->in_young_only_phase() && !collector_state()->mark_or_rebuild_in_progress();
   }
+
+  double log_buffer_processing_time() const;
 public:
   const G1Predictions& predictor() const { return _predictor; }
   const G1Analytics* analytics()   const { return const_cast<const G1Analytics*>(_analytics); }
@@ -311,7 +313,7 @@
 
   // Record the start and end of an evacuation pause.
   void record_collection_pause_start(double start_time_sec);
-  virtual void record_collection_pause_end(double pause_time_ms, size_t cards_scanned, size_t heap_used_bytes_before_gc);
+  virtual void record_collection_pause_end(double pause_time_ms, size_t heap_used_bytes_before_gc);
 
   // Record the start and end of a full collection.
   void record_full_collection_start();
--- a/src/hotspot/share/gc/g1/g1RemSet.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1RemSet.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -38,7 +38,8 @@
 #include "gc/g1/g1SharedDirtyCardQueue.hpp"
 #include "gc/g1/heapRegion.inline.hpp"
 #include "gc/g1/heapRegionManager.inline.hpp"
-#include "gc/g1/heapRegionRemSet.hpp"
+#include "gc/g1/heapRegionRemSet.inline.hpp"
+#include "gc/g1/sparsePRT.hpp"
 #include "gc/shared/gcTraceTime.inline.hpp"
 #include "gc/shared/suspendibleThreadSet.hpp"
 #include "jfr/jfrEvents.hpp"
@@ -52,40 +53,453 @@
 #include "utilities/stack.inline.hpp"
 #include "utilities/ticks.hpp"
 
-// Collects information about the overall remembered set scan progress during an evacuation.
+// Collects information about the overall heap root scan progress during an evacuation.
+//
+// Scanning the remembered sets works by first merging all sources of cards to be
+// scanned (log buffers, hcc, remembered sets) into a single data structure to remove
+// duplicates and simplify work distribution.
+//
+// During the following card scanning we not only scan this combined set of cards, but
+// also remember that these were completely scanned. The following evacuation passes
+// do not scan these cards again, and so need to be preserved across increments.
+//
+// The representation for all the cards to scan is the card table: cards can have
+// one of three states during GC:
+// - clean: these cards will not be scanned in this pass
+// - dirty: these cards will be scanned in this pass
+// - scanned: these cards have already been scanned in a previous pass
+//
+// After all evacuation is done, we reset the card table to clean.
+//
+// Work distribution occurs on "chunk" basis, i.e. contiguous ranges of cards. As an
+// additional optimization, during card merging we remember which regions and which
+// chunks actually contain cards to be scanned. Threads iterate only across these
+// regions, and only compete for chunks containing any cards.
+//
+// Within these chunks, a worker scans the card table on "blocks" of cards, i.e.
+// contiguous ranges of dirty cards to be scanned. These blocks are converted to actual
+// memory ranges and then passed on to actual scanning.
 class G1RemSetScanState : public CHeapObj<mtGC> {
+  class G1DirtyRegions;
+
+  size_t _max_regions;
+
+  // Has this region that is part of the regions in the collection set been processed yet.
+  typedef bool G1RemsetIterState;
+
+  G1RemsetIterState volatile* _collection_set_iter_state;
+
+  // Card table iteration claim for each heap region, from 0 (completely unscanned)
+  // to (>=) HeapRegion::CardsPerRegion (completely scanned).
+  uint volatile* _card_table_scan_state;
+
+  // Random power of two number of cards we want to claim per thread. This corresponds
+  // to a 64k of memory work chunk area for every thread.
+  // We use the same claim size as Parallel GC. No particular measurements have been
+  // performed to determine an optimal number.
+  static const uint CardsPerChunk = 128;
+
+  uint _scan_chunks_per_region;
+  bool* _region_scan_chunks;
+  uint8_t _scan_chunks_shift;
+public:
+  uint scan_chunk_size() const { return (uint)1 << _scan_chunks_shift; }
+
+  // Returns whether the chunk corresponding to the given region/card in region contain a
+  // dirty card, i.e. actually needs scanning.
+  bool chunk_needs_scan(uint const region_idx, uint const card_in_region) const {
+    size_t const idx = (size_t)region_idx * _scan_chunks_per_region + (card_in_region >> _scan_chunks_shift);
+    assert(idx < (_max_regions * _scan_chunks_per_region), "Index " SIZE_FORMAT " out of bounds " SIZE_FORMAT,
+           idx, _max_regions * _scan_chunks_per_region);
+    return _region_scan_chunks[idx];
+  }
+
 private:
+  // The complete set of regions which card table needs to be cleared at the end of GC because
+  // we scribbled all over them.
+  G1DirtyRegions* _all_dirty_regions;
+  // The set of regions which card table needs to be scanned for new dirty cards
+  // in the current evacuation pass.
+  G1DirtyRegions* _next_dirty_regions;
+
+  // Set of (unique) regions that can be added to concurrently.
+  class G1DirtyRegions : public CHeapObj<mtGC> {
+    uint* _buffer;
+    uint _cur_idx;
+    size_t _max_regions;
+
+    bool* _contains;
+
+  public:
+    G1DirtyRegions(size_t max_regions) :
+      _buffer(NEW_C_HEAP_ARRAY(uint, max_regions, mtGC)),
+      _cur_idx(0),
+      _max_regions(max_regions),
+      _contains(NEW_C_HEAP_ARRAY(bool, max_regions, mtGC)) {
+
+      reset();
+    }
+
+    static size_t chunk_size() { return M; }
+
+    ~G1DirtyRegions() {
+      FREE_C_HEAP_ARRAY(uint, _buffer);
+      FREE_C_HEAP_ARRAY(bool, _contains);
+    }
+
+    void reset() {
+      _cur_idx = 0;
+      ::memset(_contains, false, _max_regions * sizeof(bool));
+    }
+
+    uint size() const { return _cur_idx; }
+
+    uint at(uint idx) const {
+      assert(idx < _cur_idx, "Index %u beyond valid regions", idx);
+      return _buffer[idx];
+    }
+
+    void add_dirty_region(uint region) {
+      if (_contains[region]) {
+        return;
+      }
+
+      bool marked_as_dirty = Atomic::cmpxchg(true, &_contains[region], false) == false;
+      if (marked_as_dirty) {
+        uint allocated = Atomic::add(1u, &_cur_idx) - 1;
+        _buffer[allocated] = region;
+      }
+    }
+
+    // Creates the union of this and the other G1DirtyRegions.
+    void merge(const G1DirtyRegions* other) {
+      for (uint i = 0; i < other->size(); i++) {
+        uint region = other->at(i);
+        if (!_contains[region]) {
+          _buffer[_cur_idx++] = region;
+          _contains[region] = true;
+        }
+      }
+    }
+  };
+
+  // Returns whether the given region contains cards we need to scan. The remembered
+  // set and other sources may contain cards that
+  // - are in uncommitted regions
+  // - are located in the collection set
+  // - are located in free regions
+  // as we do not clean up remembered sets before merging heap roots.
+  bool contains_cards_to_process(uint const region_idx) const {
+    HeapRegion* hr = G1CollectedHeap::heap()->region_at_or_null(region_idx);
+    return (hr != NULL && !hr->in_collection_set() && hr->is_old_or_humongous_or_archive());
+  }
+
+  class G1MergeCardSetClosure : public HeapRegionClosure {
+    G1RemSetScanState* _scan_state;
+    G1CardTable* _ct;
+
+    uint _merged_sparse;
+    uint _merged_fine;
+    uint _merged_coarse;
+
+    // Returns if the region contains cards we need to scan. If so, remember that
+    // region in the current set of dirty regions.
+    bool remember_if_interesting(uint const region_idx) {
+      if (!_scan_state->contains_cards_to_process(region_idx)) {
+        return false;
+      }
+      _scan_state->add_dirty_region(region_idx);
+      return true;
+    }
+  public:
+    G1MergeCardSetClosure(G1RemSetScanState* scan_state) :
+      _scan_state(scan_state),
+      _ct(G1CollectedHeap::heap()->card_table()),
+      _merged_sparse(0),
+      _merged_fine(0),
+      _merged_coarse(0) { }
+
+    void next_coarse_prt(uint const region_idx) {
+      if (!remember_if_interesting(region_idx)) {
+        return;
+      }
+
+      _merged_coarse++;
+
+      size_t region_base_idx = (size_t)region_idx << HeapRegion::LogCardsPerRegion;
+      _ct->mark_region_dirty(region_base_idx, HeapRegion::CardsPerRegion);
+      _scan_state->set_chunk_region_dirty(region_base_idx);
+    }
+
+    void next_fine_prt(uint const region_idx, BitMap* bm) {
+      if (!remember_if_interesting(region_idx)) {
+        return;
+      }
+
+      _merged_fine++;
+
+      size_t const region_base_idx = (size_t)region_idx << HeapRegion::LogCardsPerRegion;
+      BitMap::idx_t cur = bm->get_next_one_offset(0);
+      while (cur != bm->size()) {
+        _ct->mark_clean_as_dirty(region_base_idx + cur);
+        _scan_state->set_chunk_dirty(region_base_idx + cur);
+        cur = bm->get_next_one_offset(cur + 1);
+      }
+    }
+
+    void next_sparse_prt(uint const region_idx, SparsePRTEntry::card_elem_t* cards, uint const num_cards) {
+      if (!remember_if_interesting(region_idx)) {
+        return;
+      }
+
+      _merged_sparse++;
+
+      size_t const region_base_idx = (size_t)region_idx << HeapRegion::LogCardsPerRegion;
+      for (uint i = 0; i < num_cards; i++) {
+        size_t card_idx = region_base_idx + cards[i];
+        _ct->mark_clean_as_dirty(card_idx);
+        _scan_state->set_chunk_dirty(card_idx);
+      }
+    }
+
+    virtual bool do_heap_region(HeapRegion* r) {
+      assert(r->in_collection_set() || r->is_starts_humongous(), "must be");
+
+      HeapRegionRemSet* rem_set = r->rem_set();
+      if (!rem_set->is_empty()) {
+        rem_set->iterate_prts(*this);
+      }
+
+      return false;
+    }
+
+    size_t merged_sparse() const { return _merged_sparse; }
+    size_t merged_fine() const { return _merged_fine; }
+    size_t merged_coarse() const { return _merged_coarse; }
+  };
+
+  // Visitor for the remembered sets of humongous candidate regions to merge their
+  // remembered set into the card table.
+  class G1FlushHumongousCandidateRemSets : public HeapRegionClosure {
+    G1MergeCardSetClosure _cl;
+
+  public:
+    G1FlushHumongousCandidateRemSets(G1RemSetScanState* scan_state) : _cl(scan_state) { }
+
+    virtual bool do_heap_region(HeapRegion* r) {
+      G1CollectedHeap* g1h = G1CollectedHeap::heap();
+
+      if (!r->is_starts_humongous() ||
+          !g1h->region_attr(r->hrm_index()).is_humongous() ||
+          r->rem_set()->is_empty()) {
+        return false;
+      }
+
+      guarantee(r->rem_set()->occupancy_less_or_equal_than(G1RSetSparseRegionEntries),
+                "Found a not-small remembered set here. This is inconsistent with previous assumptions.");
+
+      _cl.do_heap_region(r);
+
+      // We should only clear the card based remembered set here as we will not
+      // implicitly rebuild anything else during eager reclaim. Note that at the moment
+      // (and probably never) we do not enter this path if there are other kind of
+      // remembered sets for this region.
+      r->rem_set()->clear_locked(true /* only_cardset */);
+      // Clear_locked() above sets the state to Empty. However we want to continue
+      // collecting remembered set entries for humongous regions that were not
+      // reclaimed.
+      r->rem_set()->set_state_complete();
+#ifdef ASSERT
+      G1HeapRegionAttr region_attr = g1h->region_attr(r->hrm_index());
+      assert(region_attr.needs_remset_update(), "must be");
+#endif
+      assert(r->rem_set()->is_empty(), "At this point any humongous candidate remembered set must be empty.");
+
+      return false;
+    }
+
+    size_t merged_sparse() const { return _cl.merged_sparse(); }
+    size_t merged_fine() const { return _cl.merged_fine(); }
+    size_t merged_coarse() const { return _cl.merged_coarse(); }
+  };
+
+  // Visitor for the log buffer entries to merge them into the card table.
+  class G1MergeLogBufferCardsClosure : public G1CardTableEntryClosure {
+    G1RemSetScanState* _scan_state;
+    G1CardTable* _ct;
+
+    size_t _cards_dirty;
+    size_t _cards_skipped;
+  public:
+    G1MergeLogBufferCardsClosure(G1CollectedHeap* g1h, G1RemSetScanState* scan_state) :
+      _scan_state(scan_state), _ct(g1h->card_table()), _cards_dirty(0), _cards_skipped(0)
+    {}
+
+    bool do_card_ptr(CardValue* card_ptr, uint worker_i) {
+      // The only time we care about recording cards that
+      // contain references that point into the collection set
+      // is during RSet updating within an evacuation pause.
+      // In this case worker_id should be the id of a GC worker thread.
+      assert(SafepointSynchronize::is_at_safepoint(), "not during an evacuation pause");
+
+      uint const region_idx = _ct->region_idx_for(card_ptr);
+
+      // The second clause must come after - the log buffers might contain cards to uncommited
+      // regions.
+      // This code may count duplicate entries in the log buffers (even if rare) multiple
+      // times.
+      if (_scan_state->contains_cards_to_process(region_idx) && (*card_ptr == G1CardTable::dirty_card_val())) {
+        _scan_state->add_dirty_region(region_idx);
+        _scan_state->set_chunk_dirty(_ct->index_for_cardvalue(card_ptr));
+        _cards_dirty++;
+      } else {
+        // We may have had dirty cards in the (initial) collection set (or the
+        // young regions which are always in the initial collection set). We do
+        // not fix their cards here: we already added these regions to the set of
+        // regions to clear the card table at the end during the prepare() phase.
+        _cards_skipped++;
+      }
+      return true;
+    }
+
+    size_t cards_dirty() const { return _cards_dirty; }
+    size_t cards_skipped() const { return _cards_skipped; }
+  };
+
+  class G1MergeHeapRootsTask : public AbstractGangTask {
+    HeapRegionClaimer _hr_claimer;
+    G1RemSetScanState* _scan_state;
+    bool _remembered_set_only;
+
+    G1GCPhaseTimes::GCParPhases _merge_phase;
+
+    volatile bool _fast_reclaim_handled;
+
+  public:
+    G1MergeHeapRootsTask(G1RemSetScanState* scan_state, uint num_workers, bool remembered_set_only, G1GCPhaseTimes::GCParPhases merge_phase) :
+      AbstractGangTask("G1 Merge Heap Roots"),
+      _hr_claimer(num_workers),
+      _scan_state(scan_state),
+      _remembered_set_only(remembered_set_only),
+      _merge_phase(merge_phase),
+      _fast_reclaim_handled(false) { }
+
+    virtual void work(uint worker_id) {
+      G1CollectedHeap* g1h = G1CollectedHeap::heap();
+      G1GCPhaseTimes* p = g1h->phase_times();
+
+      // We schedule flushing the remembered sets of humongous fast reclaim candidates
+      // onto the card table first to allow the remaining parallelized tasks hide it.
+      if (!_remembered_set_only &&
+          p->fast_reclaim_humongous_candidates() > 0 &&
+          !_fast_reclaim_handled &&
+          !Atomic::cmpxchg(true, &_fast_reclaim_handled, false)) {
+
+        G1FlushHumongousCandidateRemSets cl(_scan_state);
+        g1h->heap_region_iterate(&cl);
+
+        p->record_or_add_thread_work_item(_merge_phase, worker_id, cl.merged_sparse(), G1GCPhaseTimes::MergeRSMergedSparse);
+        p->record_or_add_thread_work_item(_merge_phase, worker_id, cl.merged_fine(), G1GCPhaseTimes::MergeRSMergedFine);
+        p->record_or_add_thread_work_item(_merge_phase, worker_id, cl.merged_coarse(), G1GCPhaseTimes::MergeRSMergedCoarse);
+      }
+
+      // Merge remembered sets of current candidates.
+      {
+        G1GCParPhaseTimesTracker x(p, _merge_phase, worker_id, !_remembered_set_only /* must_record */);
+        G1MergeCardSetClosure cl(_scan_state);
+        g1h->collection_set_iterate_increment_from(&cl, &_hr_claimer, worker_id);
+
+        p->record_or_add_thread_work_item(_merge_phase, worker_id, cl.merged_sparse(), G1GCPhaseTimes::MergeRSMergedSparse);
+        p->record_or_add_thread_work_item(_merge_phase, worker_id, cl.merged_fine(), G1GCPhaseTimes::MergeRSMergedFine);
+        p->record_or_add_thread_work_item(_merge_phase, worker_id, cl.merged_coarse(), G1GCPhaseTimes::MergeRSMergedCoarse);
+      }
+
+      // Apply closure to log entries in the HCC.
+      if (!_remembered_set_only && G1HotCardCache::default_use_cache()) {
+        assert(_merge_phase == G1GCPhaseTimes::MergeRS, "Wrong merge phase");
+        G1GCParPhaseTimesTracker x(p, G1GCPhaseTimes::MergeHCC, worker_id);
+        G1MergeLogBufferCardsClosure cl(g1h, _scan_state);
+        g1h->iterate_hcc_closure(&cl, worker_id);
+      }
+
+      // Now apply the closure to all remaining log entries.
+      if (!_remembered_set_only) {
+        assert(_merge_phase == G1GCPhaseTimes::MergeRS, "Wrong merge phase");
+        G1GCParPhaseTimesTracker x(p, G1GCPhaseTimes::MergeLB, worker_id);
+
+        G1MergeLogBufferCardsClosure cl(g1h, _scan_state);
+        g1h->iterate_dirty_card_closure(&cl, worker_id);
+
+        p->record_thread_work_item(G1GCPhaseTimes::MergeLB, worker_id, cl.cards_dirty(), G1GCPhaseTimes::MergeLBDirtyCards);
+        p->record_thread_work_item(G1GCPhaseTimes::MergeLB, worker_id, cl.cards_skipped(), G1GCPhaseTimes::MergeLBSkippedCards);
+      }
+    }
+  };
+
+  // Creates a snapshot of the current _top values at the start of collection to
+  // filter out card marks that we do not want to scan.
+  class G1ResetScanTopClosure : public HeapRegionClosure {
+    G1RemSetScanState* _scan_state;
+
+  public:
+    G1ResetScanTopClosure(G1RemSetScanState* scan_state) : _scan_state(scan_state) { }
+
+    virtual bool do_heap_region(HeapRegion* r) {
+      uint hrm_index = r->hrm_index();
+      if (r->in_collection_set()) {
+        // Young regions had their card table marked as young at their allocation;
+        // we need to make sure that these marks are cleared at the end of GC, *but*
+        // they should not be scanned for cards.
+        // So directly add them to the "all_dirty_regions".
+        // Same for regions in the (initial) collection set: they may contain cards from
+        // the log buffers, make sure they are cleaned.
+        _scan_state->add_all_dirty_region(hrm_index);
+       } else if (r->is_old_or_humongous_or_archive()) {
+        _scan_state->set_scan_top(hrm_index, r->top());
+       }
+       return false;
+     }
+  };
+  // For each region, contains the maximum top() value to be used during this garbage
+  // collection. Subsumes common checks like filtering out everything but old and
+  // humongous regions outside the collection set.
+  // This is valid because we are not interested in scanning stray remembered set
+  // entries from free or archive regions.
+  HeapWord** _scan_top;
+
   class G1ClearCardTableTask : public AbstractGangTask {
     G1CollectedHeap* _g1h;
-    uint* _dirty_region_list;
-    size_t _num_dirty_regions;
-    size_t _chunk_length;
+    G1DirtyRegions* _regions;
+    uint _chunk_length;
 
-    size_t volatile _cur_dirty_regions;
+    uint volatile _cur_dirty_regions;
+
+    G1RemSetScanState* _scan_state;
+
   public:
     G1ClearCardTableTask(G1CollectedHeap* g1h,
-                         uint* dirty_region_list,
-                         size_t num_dirty_regions,
-                         size_t chunk_length) :
+                         G1DirtyRegions* regions,
+                         uint chunk_length,
+                         G1RemSetScanState* scan_state) :
       AbstractGangTask("G1 Clear Card Table Task"),
       _g1h(g1h),
-      _dirty_region_list(dirty_region_list),
-      _num_dirty_regions(num_dirty_regions),
+      _regions(regions),
       _chunk_length(chunk_length),
-      _cur_dirty_regions(0) {
+      _cur_dirty_regions(0),
+      _scan_state(scan_state) {
 
       assert(chunk_length > 0, "must be");
     }
 
-    static size_t chunk_size() { return M; }
+    static uint chunk_size() { return M; }
 
     void work(uint worker_id) {
-      while (_cur_dirty_regions < _num_dirty_regions) {
-        size_t next = Atomic::add(_chunk_length, &_cur_dirty_regions) - _chunk_length;
-        size_t max = MIN2(next + _chunk_length, _num_dirty_regions);
+      while (_cur_dirty_regions < _regions->size()) {
+        uint next = Atomic::add(_chunk_length, &_cur_dirty_regions) - _chunk_length;
+        uint max = MIN2(next + _chunk_length, _regions->size());
 
-        for (size_t i = next; i < max; i++) {
-          HeapRegion* r = _g1h->region_at(_dirty_region_list[i]);
+        for (uint i = next; i < max; i++) {
+          HeapRegion* r = _g1h->region_at(_regions->at(i));
           if (!r->is_survivor()) {
             r->clear_cardtable();
           }
@@ -94,159 +508,222 @@
     }
   };
 
-  size_t _max_regions;
-
-  // Scan progress for the remembered set of a single region. Transitions from
-  // Unclaimed -> Claimed -> Complete.
-  // At each of the transitions the thread that does the transition needs to perform
-  // some special action once. This is the reason for the extra "Claimed" state.
-  typedef jint G1RemsetIterState;
-
-  static const G1RemsetIterState Unclaimed = 0; // The remembered set has not been scanned yet.
-  static const G1RemsetIterState Claimed = 1;   // The remembered set is currently being scanned.
-  static const G1RemsetIterState Complete = 2;  // The remembered set has been completely scanned.
+  // Clear the card table of "dirty" regions.
+  void clear_card_table(WorkGang* workers) {
+    uint num_regions = _all_dirty_regions->size();
 
-  G1RemsetIterState volatile* _iter_states;
-  // The current location where the next thread should continue scanning in a region's
-  // remembered set.
-  size_t volatile* _iter_claims;
+    if (num_regions == 0) {
+      return;
+    }
 
-  // Temporary buffer holding the regions we used to store remembered set scan duplicate
-  // information. These are also called "dirty". Valid entries are from [0.._cur_dirty_region)
-  uint* _dirty_region_buffer;
-
-  // Flag for every region whether it is in the _dirty_region_buffer already
-  // to avoid duplicates.
-  bool volatile* _in_dirty_region_buffer;
-  size_t _cur_dirty_region;
+    uint const num_chunks = (uint)(align_up((size_t)num_regions << HeapRegion::LogCardsPerRegion, G1ClearCardTableTask::chunk_size()) / G1ClearCardTableTask::chunk_size());
+    uint const num_workers = MIN2(num_chunks, workers->active_workers());
+    uint const chunk_length = G1ClearCardTableTask::chunk_size() / (uint)HeapRegion::CardsPerRegion;
 
-  // Creates a snapshot of the current _top values at the start of collection to
-  // filter out card marks that we do not want to scan.
-  class G1ResetScanTopClosure : public HeapRegionClosure {
-  private:
-    HeapWord** _scan_top;
-  public:
-    G1ResetScanTopClosure(HeapWord** scan_top) : _scan_top(scan_top) { }
+    // Iterate over the dirty cards region list.
+    G1ClearCardTableTask cl(G1CollectedHeap::heap(), _all_dirty_regions, chunk_length, this);
 
-    virtual bool do_heap_region(HeapRegion* r) {
-      uint hrm_index = r->hrm_index();
-      if (!r->in_collection_set() && r->is_old_or_humongous_or_archive() && !r->is_empty()) {
-        _scan_top[hrm_index] = r->top();
-      } else {
-        _scan_top[hrm_index] = NULL;
-      }
-      return false;
-    }
-  };
+    log_debug(gc, ergo)("Running %s using %u workers for %u "
+                        "units of work for %u regions.",
+                        cl.name(), num_workers, num_chunks, num_regions);
+    workers->run_task(&cl, num_workers);
 
-  // For each region, contains the maximum top() value to be used during this garbage
-  // collection. Subsumes common checks like filtering out everything but old and
-  // humongous regions outside the collection set.
-  // This is valid because we are not interested in scanning stray remembered set
-  // entries from free or archive regions.
-  HeapWord** _scan_top;
+#ifndef PRODUCT
+    G1CollectedHeap::heap()->verifier()->verify_card_table_cleanup();
+#endif
+  }
+
 public:
   G1RemSetScanState() :
     _max_regions(0),
-    _iter_states(NULL),
-    _iter_claims(NULL),
-    _dirty_region_buffer(NULL),
-    _in_dirty_region_buffer(NULL),
-    _cur_dirty_region(0),
+    _collection_set_iter_state(NULL),
+    _card_table_scan_state(NULL),
+    _scan_chunks_per_region((uint)(HeapRegion::CardsPerRegion / CardsPerChunk)),
+    _region_scan_chunks(NULL),
+    _scan_chunks_shift(0),
+    _all_dirty_regions(NULL),
+    _next_dirty_regions(NULL),
     _scan_top(NULL) {
   }
 
   ~G1RemSetScanState() {
-    if (_iter_states != NULL) {
-      FREE_C_HEAP_ARRAY(G1RemsetIterState, _iter_states);
-    }
-    if (_iter_claims != NULL) {
-      FREE_C_HEAP_ARRAY(size_t, _iter_claims);
-    }
-    if (_dirty_region_buffer != NULL) {
-      FREE_C_HEAP_ARRAY(uint, _dirty_region_buffer);
-    }
-    if (_in_dirty_region_buffer != NULL) {
-      FREE_C_HEAP_ARRAY(bool, _in_dirty_region_buffer);
-    }
-    if (_scan_top != NULL) {
-      FREE_C_HEAP_ARRAY(HeapWord*, _scan_top);
-    }
+    FREE_C_HEAP_ARRAY(G1RemsetIterState, _collection_set_iter_state);
+    FREE_C_HEAP_ARRAY(uint, _card_table_scan_state);
+    FREE_C_HEAP_ARRAY(bool, _region_scan_chunks);
+    FREE_C_HEAP_ARRAY(HeapWord*, _scan_top);
   }
 
-  void initialize(uint max_regions) {
-    assert(_iter_states == NULL, "Must not be initialized twice");
-    assert(_iter_claims == NULL, "Must not be initialized twice");
+  void initialize(size_t max_regions) {
+    assert(_collection_set_iter_state == NULL, "Must not be initialized twice");
     _max_regions = max_regions;
-    _iter_states = NEW_C_HEAP_ARRAY(G1RemsetIterState, max_regions, mtGC);
-    _iter_claims = NEW_C_HEAP_ARRAY(size_t, max_regions, mtGC);
-    _dirty_region_buffer = NEW_C_HEAP_ARRAY(uint, max_regions, mtGC);
-    _in_dirty_region_buffer = NEW_C_HEAP_ARRAY(bool, max_regions, mtGC);
+    _collection_set_iter_state = NEW_C_HEAP_ARRAY(G1RemsetIterState, max_regions, mtGC);
+    _card_table_scan_state = NEW_C_HEAP_ARRAY(uint, max_regions, mtGC);
+    _region_scan_chunks = NEW_C_HEAP_ARRAY(bool, max_regions * _scan_chunks_per_region, mtGC);
+
+    _scan_chunks_shift = (uint8_t)log2_intptr(HeapRegion::CardsPerRegion / _scan_chunks_per_region);
     _scan_top = NEW_C_HEAP_ARRAY(HeapWord*, max_regions, mtGC);
   }
 
-  void reset() {
-    for (uint i = 0; i < _max_regions; i++) {
-      _iter_states[i] = Unclaimed;
-      clear_scan_top(i);
+  void prepare() {
+    for (size_t i = 0; i < _max_regions; i++) {
+      _collection_set_iter_state[i] = false;
+      clear_scan_top((uint)i);
     }
 
-    G1ResetScanTopClosure cl(_scan_top);
+    _all_dirty_regions = new G1DirtyRegions(_max_regions);
+
+    G1ResetScanTopClosure cl(this);
     G1CollectedHeap::heap()->heap_region_iterate(&cl);
 
-    memset((void*)_iter_claims, 0, _max_regions * sizeof(size_t));
-    memset((void*)_in_dirty_region_buffer, false, _max_regions * sizeof(bool));
-    _cur_dirty_region = 0;
+    _next_dirty_regions = new G1DirtyRegions(_max_regions);
   }
 
-  // Attempt to claim the remembered set of the region for iteration. Returns true
-  // if this call caused the transition from Unclaimed to Claimed.
-  inline bool claim_iter(uint region) {
-    assert(region < _max_regions, "Tried to access invalid region %u", region);
-    if (_iter_states[region] != Unclaimed) {
-      return false;
+  void print_merge_heap_roots_stats() {
+    size_t num_scan_chunks = 0;
+    for (uint i = 0; i < _max_regions * _scan_chunks_per_region; i++) {
+      if (_region_scan_chunks[i]) {
+        num_scan_chunks++;
+      }
     }
-    G1RemsetIterState res = Atomic::cmpxchg(Claimed, &_iter_states[region], Unclaimed);
-    return (res == Unclaimed);
+    size_t num_visited_cards = num_scan_chunks * CardsPerChunk;
+    size_t total_dirty_region_cards = _next_dirty_regions->size() * HeapRegion::CardsPerRegion;
+
+    G1CollectedHeap* g1h = G1CollectedHeap::heap();
+    size_t total_old_region_cards =
+      (g1h->num_regions() - (g1h->num_free_regions() - g1h->collection_set()->cur_length())) * HeapRegion::CardsPerRegion;
+
+    log_debug(gc,remset)("Visited cards " SIZE_FORMAT " Total dirty " SIZE_FORMAT " (%.2lf%%) Total old " SIZE_FORMAT " (%.2lf%%)",
+                         num_visited_cards,
+                         total_dirty_region_cards,
+                         percent_of(num_visited_cards, total_dirty_region_cards),
+                         total_old_region_cards,
+                         percent_of(num_visited_cards, total_old_region_cards));
   }
 
-  // Try to atomically sets the iteration state to "complete". Returns true for the
-  // thread that caused the transition.
-  inline bool set_iter_complete(uint region) {
-    if (iter_is_complete(region)) {
-      return false;
+  void merge_heap_roots(WorkGang* workers, bool remembered_set_only, G1GCPhaseTimes::GCParPhases merge_phase) {
+    {
+      _all_dirty_regions->merge(_next_dirty_regions);
+      _next_dirty_regions->reset();
+      for (size_t i = 0; i < _max_regions; i++) {
+        _card_table_scan_state[i] = 0;
+      }
+
+      ::memset(_region_scan_chunks, false, _max_regions * _scan_chunks_per_region * sizeof(*_region_scan_chunks));
     }
-    G1RemsetIterState res = Atomic::cmpxchg(Complete, &_iter_states[region], Claimed);
-    return (res == Claimed);
+
+    size_t const increment_length = G1CollectedHeap::heap()->collection_set()->increment_length();
+
+    uint const num_workers = !remembered_set_only ? workers->active_workers() :
+                                                    MIN2(workers->active_workers(), (uint)increment_length);
+
+    {
+      G1MergeHeapRootsTask cl(this, num_workers, remembered_set_only, merge_phase);
+      log_debug(gc, ergo)("Running %s using %u workers for " SIZE_FORMAT " regions",
+                          cl.name(), num_workers, increment_length);
+      workers->run_task(&cl, num_workers);
+    }
+
+    if (log_is_enabled(Debug, gc, remset)) {
+      print_merge_heap_roots_stats();
+    }
   }
 
-  // Returns true if the region's iteration is complete.
-  inline bool iter_is_complete(uint region) const {
-    assert(region < _max_regions, "Tried to access invalid region %u", region);
-    return _iter_states[region] == Complete;
+  void set_chunk_region_dirty(size_t const region_card_idx) {
+    size_t chunk_idx = region_card_idx >> _scan_chunks_shift;
+    for (uint i = 0; i < _scan_chunks_per_region; i++) {
+      _region_scan_chunks[chunk_idx++] = true;
+    }
+  }
+
+  void set_chunk_dirty(size_t const card_idx) {
+    assert((card_idx >> _scan_chunks_shift) < (_max_regions * _scan_chunks_per_region),
+           "Trying to access index " SIZE_FORMAT " out of bounds " SIZE_FORMAT,
+           card_idx >> _scan_chunks_shift, _max_regions * _scan_chunks_per_region);
+    size_t const chunk_idx = card_idx >> _scan_chunks_shift;
+    if (!_region_scan_chunks[chunk_idx]) {
+      _region_scan_chunks[chunk_idx] = true;
+    }
   }
 
-  // The current position within the remembered set of the given region.
-  inline size_t iter_claimed(uint region) const {
-    assert(region < _max_regions, "Tried to access invalid region %u", region);
-    return _iter_claims[region];
+  void cleanup(WorkGang* workers) {
+    _all_dirty_regions->merge(_next_dirty_regions);
+
+    clear_card_table(workers);
+
+    delete _all_dirty_regions;
+    _all_dirty_regions = NULL;
+
+    delete _next_dirty_regions;
+    _next_dirty_regions = NULL;
   }
 
-  // Claim the next block of cards within the remembered set of the region with
-  // step size.
-  inline size_t iter_claimed_next(uint region, size_t step) {
-    return Atomic::add(step, &_iter_claims[region]) - step;
-  }
+  void iterate_dirty_regions_from(HeapRegionClosure* cl, uint worker_id) {
+    uint num_regions = _next_dirty_regions->size();
 
-  void add_dirty_region(uint region) {
-    if (_in_dirty_region_buffer[region]) {
+    if (num_regions == 0) {
       return;
     }
 
-    if (!Atomic::cmpxchg(true, &_in_dirty_region_buffer[region], false)) {
-      size_t allocated = Atomic::add(1u, &_cur_dirty_region) - 1;
-      _dirty_region_buffer[allocated] = region;
+    G1CollectedHeap* g1h = G1CollectedHeap::heap();
+
+    WorkGang* workers = g1h->workers();
+    uint const max_workers = workers->active_workers();
+
+    uint const start_pos = num_regions * worker_id / max_workers;
+    uint cur = start_pos;
+
+    do {
+      bool result = cl->do_heap_region(g1h->region_at(_next_dirty_regions->at(cur)));
+      guarantee(!result, "Not allowed to ask for early termination.");
+      cur++;
+      if (cur == _next_dirty_regions->size()) {
+        cur = 0;
+      }
+    } while (cur != start_pos);
+  }
+
+  // Attempt to claim the given region in the collection set for iteration. Returns true
+  // if this call caused the transition from Unclaimed to Claimed.
+  inline bool claim_collection_set_region(uint region) {
+    assert(region < _max_regions, "Tried to access invalid region %u", region);
+    if (_collection_set_iter_state[region]) {
+      return false;
     }
+    return !Atomic::cmpxchg(true, &_collection_set_iter_state[region], false);
+  }
+
+  bool has_cards_to_scan(uint region) {
+    assert(region < _max_regions, "Tried to access invalid region %u", region);
+    return _card_table_scan_state[region] < HeapRegion::CardsPerRegion;
+  }
+
+  uint claim_cards_to_scan(uint region, uint increment) {
+    assert(region < _max_regions, "Tried to access invalid region %u", region);
+    return Atomic::add(increment, &_card_table_scan_state[region]) - increment;
+  }
+
+  void add_dirty_region(uint const region) {
+#ifdef ASSERT
+   HeapRegion* hr = G1CollectedHeap::heap()->region_at(region);
+   assert(!hr->in_collection_set() && hr->is_old_or_humongous_or_archive(),
+          "Region %u is not suitable for scanning, is %sin collection set or %s",
+          hr->hrm_index(), hr->in_collection_set() ? "" : "not ", hr->get_short_type_str());
+#endif
+    _next_dirty_regions->add_dirty_region(region);
+  }
+
+  void add_all_dirty_region(uint region) {
+#ifdef ASSERT
+    HeapRegion* hr = G1CollectedHeap::heap()->region_at(region);
+    assert(hr->in_collection_set(),
+           "Only add young regions to all dirty regions directly but %u is %s",
+           hr->hrm_index(), hr->get_short_type_str());
+#endif
+    _all_dirty_regions->add_dirty_region(region);
+  }
+
+  void set_scan_top(uint region_idx, HeapWord* value) {
+    _scan_top[region_idx] = value;
   }
 
   HeapWord* scan_top(uint region_idx) const {
@@ -254,30 +731,7 @@
   }
 
   void clear_scan_top(uint region_idx) {
-    _scan_top[region_idx] = NULL;
-  }
-
-  // Clear the card table of "dirty" regions.
-  void clear_card_table(WorkGang* workers) {
-    if (_cur_dirty_region == 0) {
-      return;
-    }
-
-    size_t const num_chunks = align_up(_cur_dirty_region * HeapRegion::CardsPerRegion, G1ClearCardTableTask::chunk_size()) / G1ClearCardTableTask::chunk_size();
-    uint const num_workers = (uint)MIN2(num_chunks, (size_t)workers->active_workers());
-    size_t const chunk_length = G1ClearCardTableTask::chunk_size() / HeapRegion::CardsPerRegion;
-
-    // Iterate over the dirty cards region list.
-    G1ClearCardTableTask cl(G1CollectedHeap::heap(), _dirty_region_buffer, _cur_dirty_region, chunk_length);
-
-    log_debug(gc, ergo)("Running %s using %u workers for " SIZE_FORMAT " "
-                        "units of work for " SIZE_FORMAT " regions.",
-                        cl.name(), num_workers, num_chunks, _cur_dirty_region);
-    workers->run_task(&cl, num_workers);
-
-#ifndef PRODUCT
-    G1CollectedHeap::heap()->verifier()->verify_card_table_cleanup();
-#endif
+    set_scan_top(region_idx, NULL);
   }
 };
 
@@ -294,9 +748,7 @@
 }
 
 G1RemSet::~G1RemSet() {
-  if (_scan_state != NULL) {
-    delete _scan_state;
-  }
+  delete _scan_state;
 }
 
 uint G1RemSet::num_par_rem_sets() {
@@ -308,181 +760,252 @@
   _scan_state->initialize(max_regions);
 }
 
-class G1ScanRSForRegionClosure : public HeapRegionClosure {
+// Helper class to scan and detect ranges of cards that need to be scanned on the
+// card table.
+class G1CardTableScanner : public StackObj {
+public:
+  typedef CardTable::CardValue CardValue;
+
+private:
+  CardValue* const _base_addr;
+
+  CardValue* _cur_addr;
+  CardValue* const _end_addr;
+
+  static const size_t ToScanMask = G1CardTable::g1_card_already_scanned;
+  static const size_t ExpandedToScanMask = G1CardTable::WordAlreadyScanned;
+
+  bool cur_addr_aligned() const {
+    return ((uintptr_t)_cur_addr) % sizeof(size_t) == 0;
+  }
+
+  bool cur_card_is_dirty() const {
+    CardValue value = *_cur_addr;
+    return (value & ToScanMask) == 0;
+  }
+
+  bool cur_word_of_cards_contains_any_dirty_card() const {
+    assert(cur_addr_aligned(), "Current address should be aligned");
+    size_t const value = *(size_t*)_cur_addr;
+    return (~value & ExpandedToScanMask) != 0;
+  }
+
+  bool cur_word_of_cards_all_dirty_cards() const {
+    size_t const value = *(size_t*)_cur_addr;
+    return value == G1CardTable::WordAllDirty;
+  }
+
+  size_t get_and_advance_pos() {
+    _cur_addr++;
+    return pointer_delta(_cur_addr, _base_addr, sizeof(CardValue)) - 1;
+  }
+
+public:
+  G1CardTableScanner(CardValue* start_card, size_t size) :
+    _base_addr(start_card),
+    _cur_addr(start_card),
+    _end_addr(start_card + size) {
+
+    assert(is_aligned(start_card, sizeof(size_t)), "Unaligned start addr " PTR_FORMAT, p2i(start_card));
+    assert(is_aligned(size, sizeof(size_t)), "Unaligned size " SIZE_FORMAT, size);
+  }
+
+  size_t find_next_dirty() {
+    while (!cur_addr_aligned()) {
+      if (cur_card_is_dirty()) {
+        return get_and_advance_pos();
+      }
+      _cur_addr++;
+    }
+
+    assert(cur_addr_aligned(), "Current address should be aligned now.");
+    while (_cur_addr != _end_addr) {
+      if (cur_word_of_cards_contains_any_dirty_card()) {
+        for (size_t i = 0; i < sizeof(size_t); i++) {
+          if (cur_card_is_dirty()) {
+            return get_and_advance_pos();
+          }
+          _cur_addr++;
+        }
+        assert(false, "Should not reach here given we detected a dirty card in the word.");
+      }
+      _cur_addr += sizeof(size_t);
+    }
+    return get_and_advance_pos();
+  }
+
+  size_t find_next_non_dirty() {
+    assert(_cur_addr <= _end_addr, "Not allowed to search for marks after area.");
+
+    while (!cur_addr_aligned()) {
+      if (!cur_card_is_dirty()) {
+        return get_and_advance_pos();
+      }
+      _cur_addr++;
+    }
+
+    assert(cur_addr_aligned(), "Current address should be aligned now.");
+    while (_cur_addr != _end_addr) {
+      if (!cur_word_of_cards_all_dirty_cards()) {
+        for (size_t i = 0; i < sizeof(size_t); i++) {
+          if (!cur_card_is_dirty()) {
+            return get_and_advance_pos();
+          }
+          _cur_addr++;
+        }
+        assert(false, "Should not reach here given we detected a non-dirty card in the word.");
+      }
+      _cur_addr += sizeof(size_t);
+    }
+    return get_and_advance_pos();
+  }
+};
+
+// Helper class to claim dirty chunks within the card table.
+class G1CardTableChunkClaimer {
+  G1RemSetScanState* _scan_state;
+  uint _region_idx;
+  uint _cur_claim;
+
+public:
+  G1CardTableChunkClaimer(G1RemSetScanState* scan_state, uint region_idx) :
+    _scan_state(scan_state),
+    _region_idx(region_idx),
+    _cur_claim(0) {
+    guarantee(size() <= HeapRegion::CardsPerRegion, "Should not claim more space than possible.");
+  }
+
+  bool has_next() {
+    while (true) {
+      _cur_claim = _scan_state->claim_cards_to_scan(_region_idx, size());
+      if (_cur_claim >= HeapRegion::CardsPerRegion) {
+        return false;
+      }
+      if (_scan_state->chunk_needs_scan(_region_idx, _cur_claim)) {
+        return true;
+      }
+    }
+  }
+
+  uint value() const { return _cur_claim; }
+  uint size() const { return _scan_state->scan_chunk_size(); }
+};
+
+// Scans a heap region for dirty cards.
+class G1ScanHRForRegionClosure : public HeapRegionClosure {
   G1CollectedHeap* _g1h;
-  G1CardTable *_ct;
+  G1CardTable* _ct;
+  G1BlockOffsetTable* _bot;
 
   G1ParScanThreadState* _pss;
-  G1ScanCardClosure* _scan_objs_on_card_cl;
 
   G1RemSetScanState* _scan_state;
 
   G1GCPhaseTimes::GCParPhases _phase;
 
-  uint   _worker_i;
-
-  size_t _opt_refs_scanned;
-  size_t _opt_refs_memory_used;
+  uint   _worker_id;
 
   size_t _cards_scanned;
-  size_t _cards_claimed;
-  size_t _cards_skipped;
+  size_t _blocks_scanned;
+  size_t _chunks_claimed;
 
   Tickspan _rem_set_root_scan_time;
   Tickspan _rem_set_trim_partially_time;
 
-  Tickspan _strong_code_root_scan_time;
-  Tickspan _strong_code_trim_partially_time;
-
-  void claim_card(size_t card_index, const uint region_idx_for_card) {
-    _ct->set_card_claimed(card_index);
-    _scan_state->add_dirty_region(region_idx_for_card);
-  }
-
-  void scan_card(MemRegion mr, uint region_idx_for_card) {
+  void scan_memregion(uint region_idx_for_card, MemRegion mr) {
     HeapRegion* const card_region = _g1h->region_at(region_idx_for_card);
-    assert(!card_region->is_young(), "Should not scan card in young region %u", region_idx_for_card);
-    card_region->oops_on_card_seq_iterate_careful<true>(mr, _scan_objs_on_card_cl);
-    _scan_objs_on_card_cl->trim_queue_partially();
-    _cards_scanned++;
+    G1ScanCardClosure card_cl(_g1h, _pss);
+    card_region->oops_on_card_seq_iterate_careful<true>(mr, &card_cl);
+    _pss->trim_queue_partially();
   }
 
-  void scan_opt_rem_set_roots(HeapRegion* r) {
-    EventGCPhaseParallel event;
-
-    G1OopStarChunkedList* opt_rem_set_list = _pss->oops_into_optional_region(r);
-
-    G1ScanCardClosure scan_cl(_g1h, _pss);
-    G1ScanRSForOptionalClosure cl(_g1h, &scan_cl);
-    _opt_refs_scanned += opt_rem_set_list->oops_do(&cl, _pss->closures()->raw_strong_oops());
-    _opt_refs_memory_used += opt_rem_set_list->used_memory();
-
-    event.commit(GCId::current(), _worker_i, G1GCPhaseTimes::phase_name(_phase));
-  }
-
-  void scan_rem_set_roots(HeapRegion* r) {
-    EventGCPhaseParallel event;
-    uint const region_idx = r->hrm_index();
-
-    if (_scan_state->claim_iter(region_idx)) {
-      // If we ever free the collection set concurrently, we should also
-      // clear the card table concurrently therefore we won't need to
-      // add regions of the collection set to the dirty cards region.
-      _scan_state->add_dirty_region(region_idx);
-    }
-
-    if (r->rem_set()->cardset_is_empty()) {
+  void do_claimed_block(uint const region_idx_for_card, size_t const first_card, size_t const num_cards) {
+    HeapWord* const card_start = _bot->address_for_index_raw(first_card);
+#ifdef ASSERT
+    HeapRegion* hr = _g1h->region_at_or_null(region_idx_for_card);
+    assert(hr == NULL || hr->is_in_reserved(card_start),
+             "Card start " PTR_FORMAT " to scan outside of region %u", p2i(card_start), _g1h->region_at(region_idx_for_card)->hrm_index());
+#endif
+    HeapWord* const top = _scan_state->scan_top(region_idx_for_card);
+    if (card_start >= top) {
       return;
     }
 
-    // We claim cards in blocks so as to reduce the contention.
-    size_t const block_size = G1RSetScanBlockSize;
-
-    HeapRegionRemSetIterator iter(r->rem_set());
-    size_t card_index;
-
-    size_t claimed_card_block = _scan_state->iter_claimed_next(region_idx, block_size);
-    for (size_t current_card = 0; iter.has_next(card_index); current_card++) {
-      if (current_card >= claimed_card_block + block_size) {
-        claimed_card_block = _scan_state->iter_claimed_next(region_idx, block_size);
-      }
-      if (current_card < claimed_card_block) {
-        _cards_skipped++;
-        continue;
-      }
-      _cards_claimed++;
-
-      HeapWord* const card_start = _g1h->bot()->address_for_index_raw(card_index);
-      uint const region_idx_for_card = _g1h->addr_to_region(card_start);
+    MemRegion mr(card_start, MIN2(card_start + ((size_t)num_cards << BOTConstants::LogN_words), top));
+    scan_memregion(region_idx_for_card, mr);
 
-#ifdef ASSERT
-      HeapRegion* hr = _g1h->region_at_or_null(region_idx_for_card);
-      assert(hr == NULL || hr->is_in_reserved(card_start),
-             "Card start " PTR_FORMAT " to scan outside of region %u", p2i(card_start), _g1h->region_at(region_idx_for_card)->hrm_index());
-#endif
-      HeapWord* const top = _scan_state->scan_top(region_idx_for_card);
-      if (card_start >= top) {
-        continue;
-      }
+    _cards_scanned += num_cards;
+  }
 
-      // If the card is dirty, then G1 will scan it during Update RS.
-      if (_ct->is_card_claimed(card_index) || _ct->is_card_dirty(card_index)) {
-        continue;
-      }
-
-      // We claim lazily (so races are possible but they're benign), which reduces the
-      // number of duplicate scans (the rsets of the regions in the cset can intersect).
-      // Claim the card after checking bounds above: the remembered set may contain
-      // random cards into current survivor, and we would then have an incorrectly
-      // claimed card in survivor space. Card table clear does not reset the card table
-      // of survivor space regions.
-      claim_card(card_index, region_idx_for_card);
-
-      MemRegion const mr(card_start, MIN2(card_start + BOTConstants::N_words, top));
-
-      scan_card(mr, region_idx_for_card);
-    }
-    event.commit(GCId::current(), _worker_i, G1GCPhaseTimes::phase_name(_phase));
+  ALWAYSINLINE void do_card_block(uint const region_idx, size_t const first_card, size_t const num_cards) {
+    _ct->mark_as_scanned(first_card, num_cards);
+    do_claimed_block(region_idx, first_card, num_cards);
+    _blocks_scanned++;
   }
 
-  void scan_strong_code_roots(HeapRegion* r) {
+   void scan_heap_roots(HeapRegion* r) {
     EventGCPhaseParallel event;
-    // We pass a weak code blobs closure to the remembered set scanning because we want to avoid
-    // treating the nmethods visited to act as roots for concurrent marking.
-    // We only want to make sure that the oops in the nmethods are adjusted with regard to the
-    // objects copied by the current evacuation.
-    r->strong_code_roots_do(_pss->closures()->weak_codeblobs());
-    event.commit(GCId::current(), _worker_i, G1GCPhaseTimes::phase_name(G1GCPhaseTimes::CodeRoots));
+    uint const region_idx = r->hrm_index();
+
+    ResourceMark rm;
+
+    G1CardTableChunkClaimer claim(_scan_state, region_idx);
+
+    while (claim.has_next()) {
+      size_t const region_card_base_idx = ((size_t)region_idx << HeapRegion::LogCardsPerRegion) + claim.value();
+      CardTable::CardValue* const base_addr = _ct->byte_for_index(region_card_base_idx);
+
+      G1CardTableScanner scan(base_addr, claim.size());
+
+      size_t first_scan_idx = scan.find_next_dirty();
+      while (first_scan_idx != claim.size()) {
+        assert(*_ct->byte_for_index(region_card_base_idx + first_scan_idx) <= 0x1, "is %d at region %u idx " SIZE_FORMAT, *_ct->byte_for_index(region_card_base_idx + first_scan_idx), region_idx, first_scan_idx);
+
+        size_t const last_scan_idx = scan.find_next_non_dirty();
+        size_t const len = last_scan_idx - first_scan_idx;
+
+        do_card_block(region_idx, region_card_base_idx + first_scan_idx, len);
+
+        if (last_scan_idx == claim.size()) {
+          break;
+        }
+
+        first_scan_idx = scan.find_next_dirty();
+      }
+      _chunks_claimed++;
+    }
+
+    event.commit(GCId::current(), _worker_id, G1GCPhaseTimes::phase_name(G1GCPhaseTimes::ScanHR));
   }
 
 public:
-  G1ScanRSForRegionClosure(G1RemSetScanState* scan_state,
-                           G1ScanCardClosure* scan_obj_on_card,
+  G1ScanHRForRegionClosure(G1RemSetScanState* scan_state,
                            G1ParScanThreadState* pss,
-                           G1GCPhaseTimes::GCParPhases phase,
-                           uint worker_i) :
+                           uint worker_id,
+                           G1GCPhaseTimes::GCParPhases phase) :
     _g1h(G1CollectedHeap::heap()),
     _ct(_g1h->card_table()),
+    _bot(_g1h->bot()),
     _pss(pss),
-    _scan_objs_on_card_cl(scan_obj_on_card),
     _scan_state(scan_state),
     _phase(phase),
-    _worker_i(worker_i),
-    _opt_refs_scanned(0),
-    _opt_refs_memory_used(0),
+    _worker_id(worker_id),
     _cards_scanned(0),
-    _cards_claimed(0),
-    _cards_skipped(0),
+    _blocks_scanned(0),
+    _chunks_claimed(0),
     _rem_set_root_scan_time(),
-    _rem_set_trim_partially_time(),
-    _strong_code_root_scan_time(),
-    _strong_code_trim_partially_time() { }
+    _rem_set_trim_partially_time() {
+  }
 
   bool do_heap_region(HeapRegion* r) {
-    assert(r->in_collection_set(), "Region %u is not in the collection set.", r->hrm_index());
+    assert(!r->in_collection_set() && r->is_old_or_humongous_or_archive(),
+           "Should only be called on old gen non-collection set regions but region %u is not.",
+           r->hrm_index());
     uint const region_idx = r->hrm_index();
 
-    // The individual references for the optional remembered set are per-worker, so we
-    // always need to scan them.
-    if (r->has_index_in_opt_cset()) {
+    if (_scan_state->has_cards_to_scan(region_idx)) {
       G1EvacPhaseWithTrimTimeTracker timer(_pss, _rem_set_root_scan_time, _rem_set_trim_partially_time);
-      scan_opt_rem_set_roots(r);
-    }
-
-    // Do an early out if we know we are complete.
-    if (_scan_state->iter_is_complete(region_idx)) {
-      return false;
-    }
-
-    {
-      G1EvacPhaseWithTrimTimeTracker timer(_pss, _rem_set_root_scan_time, _rem_set_trim_partially_time);
-      scan_rem_set_roots(r);
-    }
-
-    if (_scan_state->set_iter_complete(region_idx)) {
-      G1EvacPhaseWithTrimTimeTracker timer(_pss, _strong_code_root_scan_time, _strong_code_trim_partially_time);
-      // Scan the strong code root list attached to the current region
-      scan_strong_code_roots(r);
+      scan_heap_roots(r);
     }
     return false;
   }
@@ -490,120 +1013,156 @@
   Tickspan rem_set_root_scan_time() const { return _rem_set_root_scan_time; }
   Tickspan rem_set_trim_partially_time() const { return _rem_set_trim_partially_time; }
 
+  size_t cards_scanned() const { return _cards_scanned; }
+  size_t blocks_scanned() const { return _blocks_scanned; }
+  size_t chunks_claimed() const { return _chunks_claimed; }
+};
+
+void G1RemSet::scan_heap_roots(G1ParScanThreadState* pss,
+                            uint worker_id,
+                            G1GCPhaseTimes::GCParPhases scan_phase,
+                            G1GCPhaseTimes::GCParPhases objcopy_phase) {
+  G1ScanHRForRegionClosure cl(_scan_state, pss, worker_id, scan_phase);
+  _scan_state->iterate_dirty_regions_from(&cl, worker_id);
+
+  G1GCPhaseTimes* p = _g1p->phase_times();
+
+  p->record_or_add_time_secs(objcopy_phase, worker_id, cl.rem_set_trim_partially_time().seconds());
+
+  p->record_or_add_time_secs(scan_phase, worker_id, cl.rem_set_root_scan_time().seconds());
+  p->record_or_add_thread_work_item(scan_phase, worker_id, cl.cards_scanned(), G1GCPhaseTimes::ScanHRScannedCards);
+  p->record_or_add_thread_work_item(scan_phase, worker_id, cl.blocks_scanned(), G1GCPhaseTimes::ScanHRScannedBlocks);
+  p->record_or_add_thread_work_item(scan_phase, worker_id, cl.chunks_claimed(), G1GCPhaseTimes::ScanHRClaimedChunks);
+}
+
+// Heap region closure to be applied to all regions in the current collection set
+// increment to fix up non-card related roots.
+class G1ScanCollectionSetRegionClosure : public HeapRegionClosure {
+  G1ParScanThreadState* _pss;
+  G1RemSetScanState* _scan_state;
+
+  G1GCPhaseTimes::GCParPhases _scan_phase;
+  G1GCPhaseTimes::GCParPhases _code_roots_phase;
+
+  uint _worker_id;
+
+  size_t _opt_refs_scanned;
+  size_t _opt_refs_memory_used;
+
+  Tickspan _strong_code_root_scan_time;
+  Tickspan _strong_code_trim_partially_time;
+
+  Tickspan _rem_set_opt_root_scan_time;
+  Tickspan _rem_set_opt_trim_partially_time;
+
+  void scan_opt_rem_set_roots(HeapRegion* r) {
+    EventGCPhaseParallel event;
+
+    G1OopStarChunkedList* opt_rem_set_list = _pss->oops_into_optional_region(r);
+
+    G1ScanCardClosure scan_cl(G1CollectedHeap::heap(), _pss);
+    G1ScanRSForOptionalClosure cl(G1CollectedHeap::heap(), &scan_cl);
+    _opt_refs_scanned += opt_rem_set_list->oops_do(&cl, _pss->closures()->raw_strong_oops());
+    _opt_refs_memory_used += opt_rem_set_list->used_memory();
+
+    event.commit(GCId::current(), _worker_id, G1GCPhaseTimes::phase_name(_scan_phase));
+  }
+
+public:
+  G1ScanCollectionSetRegionClosure(G1RemSetScanState* scan_state,
+                                   G1ParScanThreadState* pss,
+                                   uint worker_i,
+                                   G1GCPhaseTimes::GCParPhases scan_phase,
+                                   G1GCPhaseTimes::GCParPhases code_roots_phase) :
+    _pss(pss),
+    _scan_state(scan_state),
+    _scan_phase(scan_phase),
+    _code_roots_phase(code_roots_phase),
+    _worker_id(worker_i),
+    _opt_refs_scanned(0),
+    _opt_refs_memory_used(0),
+    _strong_code_root_scan_time(),
+    _strong_code_trim_partially_time(),
+    _rem_set_opt_root_scan_time(),
+    _rem_set_opt_trim_partially_time() { }
+
+  bool do_heap_region(HeapRegion* r) {
+    uint const region_idx = r->hrm_index();
+
+    // The individual references for the optional remembered set are per-worker, so we
+    // always need to scan them.
+    if (r->has_index_in_opt_cset()) {
+      G1EvacPhaseWithTrimTimeTracker timer(_pss, _rem_set_opt_root_scan_time, _rem_set_opt_trim_partially_time);
+      scan_opt_rem_set_roots(r);
+    }
+
+    if (_scan_state->claim_collection_set_region(region_idx)) {
+      EventGCPhaseParallel event;
+
+      G1EvacPhaseWithTrimTimeTracker timer(_pss, _strong_code_root_scan_time, _strong_code_trim_partially_time);
+      // Scan the strong code root list attached to the current region
+      r->strong_code_roots_do(_pss->closures()->weak_codeblobs());
+
+      event.commit(GCId::current(), _worker_id, G1GCPhaseTimes::phase_name(_code_roots_phase));
+    }
+
+    return false;
+  }
+
   Tickspan strong_code_root_scan_time() const { return _strong_code_root_scan_time;  }
   Tickspan strong_code_root_trim_partially_time() const { return _strong_code_trim_partially_time; }
 
-  size_t cards_scanned() const { return _cards_scanned; }
-  size_t cards_claimed() const { return _cards_claimed; }
-  size_t cards_skipped() const { return _cards_skipped; }
+  Tickspan rem_set_opt_root_scan_time() const { return _rem_set_opt_root_scan_time; }
+  Tickspan rem_set_opt_trim_partially_time() const { return _rem_set_opt_trim_partially_time; }
 
   size_t opt_refs_scanned() const { return _opt_refs_scanned; }
   size_t opt_refs_memory_used() const { return _opt_refs_memory_used; }
 };
 
-void G1RemSet::scan_rem_set(G1ParScanThreadState* pss,
-                            uint worker_i,
-                            G1GCPhaseTimes::GCParPhases scan_phase,
-                            G1GCPhaseTimes::GCParPhases objcopy_phase,
-                            G1GCPhaseTimes::GCParPhases coderoots_phase) {
-  assert(pss->trim_ticks().value() == 0, "Queues must have been trimmed before entering.");
-
-  G1ScanCardClosure scan_cl(_g1h, pss);
-  G1ScanRSForRegionClosure cl(_scan_state, &scan_cl, pss, scan_phase, worker_i);
-  _g1h->collection_set_iterate_increment_from(&cl, worker_i);
-
-  G1GCPhaseTimes* p = _g1p->phase_times();
-
-  p->record_or_add_time_secs(objcopy_phase, worker_i, cl.rem_set_trim_partially_time().seconds());
+void G1RemSet::scan_collection_set_regions(G1ParScanThreadState* pss,
+                                           uint worker_id,
+                                           G1GCPhaseTimes::GCParPhases scan_phase,
+                                           G1GCPhaseTimes::GCParPhases coderoots_phase,
+                                           G1GCPhaseTimes::GCParPhases objcopy_phase) {
+  G1ScanCollectionSetRegionClosure cl(_scan_state, pss, worker_id, scan_phase, coderoots_phase);
+  _g1h->collection_set_iterate_increment_from(&cl, worker_id);
 
-  p->record_or_add_time_secs(scan_phase, worker_i, cl.rem_set_root_scan_time().seconds());
-  p->record_or_add_thread_work_item(scan_phase, worker_i, cl.cards_scanned(), G1GCPhaseTimes::ScanRSScannedCards);
-  p->record_or_add_thread_work_item(scan_phase, worker_i, cl.cards_claimed(), G1GCPhaseTimes::ScanRSClaimedCards);
-  p->record_or_add_thread_work_item(scan_phase, worker_i, cl.cards_skipped(), G1GCPhaseTimes::ScanRSSkippedCards);
-  // At this time we only record some metrics for the optional remembered set.
-  if (scan_phase == G1GCPhaseTimes::OptScanRS) {
-    p->record_or_add_thread_work_item(scan_phase, worker_i, cl.opt_refs_scanned(), G1GCPhaseTimes::ScanRSScannedOptRefs);
-    p->record_or_add_thread_work_item(scan_phase, worker_i, cl.opt_refs_memory_used(), G1GCPhaseTimes::ScanRSUsedMemory);
-  }
-
-  p->record_or_add_time_secs(coderoots_phase, worker_i, cl.strong_code_root_scan_time().seconds());
-  p->add_time_secs(objcopy_phase, worker_i, cl.strong_code_root_trim_partially_time().seconds());
-}
-
-// Closure used for updating rem sets. Only called during an evacuation pause.
-class G1RefineCardClosure: public G1CardTableEntryClosure {
-  G1RemSet* _g1rs;
-  G1ScanCardClosure* _update_rs_cl;
-
-  size_t _cards_scanned;
-  size_t _cards_skipped;
-public:
-  G1RefineCardClosure(G1CollectedHeap* g1h, G1ScanCardClosure* update_rs_cl) :
-    _g1rs(g1h->rem_set()), _update_rs_cl(update_rs_cl), _cards_scanned(0), _cards_skipped(0)
-  {}
+  G1GCPhaseTimes* p = _g1h->phase_times();
 
-  bool do_card_ptr(CardValue* card_ptr, uint worker_i) {
-    // The only time we care about recording cards that
-    // contain references that point into the collection set
-    // is during RSet updating within an evacuation pause.
-    // In this case worker_i should be the id of a GC worker thread.
-    assert(SafepointSynchronize::is_at_safepoint(), "not during an evacuation pause");
-
-    bool card_scanned = _g1rs->refine_card_during_gc(card_ptr, _update_rs_cl);
-
-    if (card_scanned) {
-      _update_rs_cl->trim_queue_partially();
-      _cards_scanned++;
-    } else {
-      _cards_skipped++;
-    }
-    return true;
-  }
-
-  size_t cards_scanned() const { return _cards_scanned; }
-  size_t cards_skipped() const { return _cards_skipped; }
-};
+  p->record_or_add_time_secs(scan_phase, worker_id, cl.rem_set_opt_root_scan_time().seconds());
+  p->record_or_add_time_secs(scan_phase, worker_id, cl.rem_set_opt_trim_partially_time().seconds());
 
-void G1RemSet::update_rem_set(G1ParScanThreadState* pss, uint worker_i) {
-  G1GCPhaseTimes* p = _g1p->phase_times();
-
-  // Apply closure to log entries in the HCC.
-  if (G1HotCardCache::default_use_cache()) {
-    G1EvacPhaseTimesTracker x(p, pss, G1GCPhaseTimes::ScanHCC, worker_i);
+  p->record_or_add_time_secs(coderoots_phase, worker_id, cl.strong_code_root_scan_time().seconds());
+  p->add_time_secs(objcopy_phase, worker_id, cl.strong_code_root_trim_partially_time().seconds());
 
-    G1ScanCardClosure scan_hcc_cl(_g1h, pss);
-    G1RefineCardClosure refine_card_cl(_g1h, &scan_hcc_cl);
-    _g1h->iterate_hcc_closure(&refine_card_cl, worker_i);
-  }
-
-  // Now apply the closure to all remaining log entries.
-  {
-    G1EvacPhaseTimesTracker x(p, pss, G1GCPhaseTimes::UpdateRS, worker_i);
-
-    G1ScanCardClosure update_rs_cl(_g1h, pss);
-    G1RefineCardClosure refine_card_cl(_g1h, &update_rs_cl);
-    _g1h->iterate_dirty_card_closure(&refine_card_cl, worker_i);
-
-    p->record_thread_work_item(G1GCPhaseTimes::UpdateRS, worker_i, refine_card_cl.cards_scanned(), G1GCPhaseTimes::UpdateRSScannedCards);
-    p->record_thread_work_item(G1GCPhaseTimes::UpdateRS, worker_i, refine_card_cl.cards_skipped(), G1GCPhaseTimes::UpdateRSSkippedCards);
+  // At this time we record some metrics only for the evacuations after the initial one.
+  if (scan_phase == G1GCPhaseTimes::OptScanHR) {
+    p->record_or_add_thread_work_item(scan_phase, worker_id, cl.opt_refs_scanned(), G1GCPhaseTimes::ScanHRScannedOptRefs);
+    p->record_or_add_thread_work_item(scan_phase, worker_id, cl.opt_refs_memory_used(), G1GCPhaseTimes::ScanHRUsedMemory);
   }
 }
 
-void G1RemSet::prepare_for_scan_rem_set() {
-  G1BarrierSet::dirty_card_queue_set().concatenate_logs();
-  _scan_state->reset();
+void G1RemSet::prepare_for_scan_heap_roots() {
+  G1DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set();
+  dcqs.concatenate_logs();
+
+  _scan_state->prepare();
 }
 
-void G1RemSet::prepare_for_scan_rem_set(uint region_idx) {
+void G1RemSet::merge_heap_roots(bool remembered_set_only, G1GCPhaseTimes::GCParPhases merge_phase) {
+  _scan_state->merge_heap_roots(_g1h->workers(), remembered_set_only, merge_phase);
+}
+
+void G1RemSet::prepare_for_scan_heap_roots(uint region_idx) {
   _scan_state->clear_scan_top(region_idx);
 }
 
-void G1RemSet::cleanup_after_scan_rem_set() {
+void G1RemSet::cleanup_after_scan_heap_roots() {
   G1GCPhaseTimes* phase_times = _g1h->phase_times();
 
   // Set all cards back to clean.
   double start = os::elapsedTime();
-  _scan_state->clear_card_table(_g1h->workers());
+  _scan_state->cleanup(_g1h->workers());
   phase_times->record_clear_ct_time((os::elapsedTime() - start) * 1000.0);
 }
 
@@ -759,53 +1318,6 @@
   G1BarrierSet::shared_dirty_card_queue().enqueue(card_ptr);
 }
 
-bool G1RemSet::refine_card_during_gc(CardValue* card_ptr,
-                                     G1ScanCardClosure* update_rs_cl) {
-  assert(_g1h->is_gc_active(), "Only call during GC");
-
-  // Construct the region representing the card.
-  HeapWord* card_start = _ct->addr_for(card_ptr);
-  // And find the region containing it.
-  uint const card_region_idx = _g1h->addr_to_region(card_start);
-
-  HeapWord* scan_limit = _scan_state->scan_top(card_region_idx);
-  if (scan_limit == NULL) {
-    // This is a card into an uncommitted region. We need to bail out early as we
-    // should not access the corresponding card table entry.
-    return false;
-  }
-
-  check_card_ptr(card_ptr, _ct);
-
-  // If the card is no longer dirty, nothing to do. This covers cards that were already
-  // scanned as parts of the remembered sets.
-  if (*card_ptr != G1CardTable::dirty_card_val()) {
-    return false;
-  }
-
-  // We claim lazily (so races are possible but they're benign), which reduces the
-  // number of potential duplicate scans (multiple threads may enqueue the same card twice).
-  *card_ptr = G1CardTable::clean_card_val() | G1CardTable::claimed_card_val();
-
-  _scan_state->add_dirty_region(card_region_idx);
-  if (scan_limit <= card_start) {
-    // If the card starts above the area in the region containing objects to scan, skip it.
-    return false;
-  }
-
-  // Don't use addr_for(card_ptr + 1) which can ask for
-  // a card beyond the heap.
-  HeapWord* card_end = card_start + G1CardTable::card_size_in_words;
-  MemRegion dirty_region(card_start, MIN2(scan_limit, card_end));
-  assert(!dirty_region.is_empty(), "sanity");
-
-  HeapRegion* const card_region = _g1h->region_at(card_region_idx);
-  assert(!card_region->is_young(), "Should not scan card in young region %u", card_region_idx);
-  bool card_processed = card_region->oops_on_card_seq_iterate_careful<true>(dirty_region, update_rs_cl);
-  assert(card_processed, "must be");
-  return true;
-}
-
 void G1RemSet::print_periodic_summary_info(const char* header, uint period_count) {
   if ((G1SummarizeRSetStatsPeriod > 0) && log_is_enabled(Trace, gc, remset) &&
       (period_count % G1SummarizeRSetStatsPeriod == 0)) {
--- a/src/hotspot/share/gc/g1/g1RemSet.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1RemSet.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -46,6 +46,7 @@
 class G1HotCardCache;
 class G1RemSetScanState;
 class G1ParScanThreadState;
+class G1ParScanThreadStateSet;
 class G1Policy;
 class G1ScanCardClosure;
 class HeapRegionClaimer;
@@ -84,39 +85,39 @@
            G1HotCardCache* hot_card_cache);
   ~G1RemSet();
 
-  // Scan all remembered sets of the collection set for references into the collection
-  // set.
-  // Further applies heap_region_codeblobs on the oops of the unmarked nmethods on the strong code
-  // roots list for each region in the collection set.
-  void scan_rem_set(G1ParScanThreadState* pss,
-                    uint worker_i,
-                    G1GCPhaseTimes::GCParPhases scan_phase,
-                    G1GCPhaseTimes::GCParPhases objcopy_phase,
-                    G1GCPhaseTimes::GCParPhases coderoots_phase);
+  // Scan all cards in the non-collection set regions that potentially contain
+  // references into the current whole collection set.
+  void scan_heap_roots(G1ParScanThreadState* pss,
+                       uint worker_id,
+                       G1GCPhaseTimes::GCParPhases scan_phase,
+                       G1GCPhaseTimes::GCParPhases objcopy_phase);
+
+  // Merge cards from various sources (remembered sets, hot card cache, log buffers)
+  // and calculate the cards that need to be scanned later (via scan_heap_roots()).
+  // If remembered_set_only is set, only merge remembered set cards.
+  void merge_heap_roots(bool remembered_set_only, G1GCPhaseTimes::GCParPhases merge_phase);
 
-  // Flush remaining refinement buffers for cross-region references to either evacuate references
-  // into the collection set or update the remembered set.
-  void update_rem_set(G1ParScanThreadState* pss, uint worker_i);
-
-  // Prepare for and cleanup after scanning the remembered sets. Must be called
+  // Prepare for and cleanup after scanning the heap roots. Must be called
   // once before and after in sequential code.
-  void prepare_for_scan_rem_set();
-  void cleanup_after_scan_rem_set();
-  // Prepares the given region for remembered set scanning.
-  void prepare_for_scan_rem_set(uint region_idx);
+  void prepare_for_scan_heap_roots();
+  // Cleans the card table from temporary duplicate detection information.
+  void cleanup_after_scan_heap_roots();
+  // Prepares the given region for heap root scanning.
+  void prepare_for_scan_heap_roots(uint region_idx);
 
-  G1RemSetScanState* scan_state() const { return _scan_state; }
+  // Do work for regions in the current increment of the collection set, scanning
+  // non-card based (heap) roots.
+  void scan_collection_set_regions(G1ParScanThreadState* pss,
+                                   uint worker_id,
+                                   G1GCPhaseTimes::GCParPhases scan_phase,
+                                   G1GCPhaseTimes::GCParPhases coderoots_phase,
+                                   G1GCPhaseTimes::GCParPhases objcopy_phase);
 
   // Refine the card corresponding to "card_ptr". Safe to be called concurrently
   // to the mutator.
   void refine_card_concurrently(CardValue* card_ptr,
                                 uint worker_i);
 
-  // Refine the card corresponding to "card_ptr", applying the given closure to
-  // all references found. Must only be called during gc.
-  // Returns whether the card has been scanned.
-  bool refine_card_during_gc(CardValue* card_ptr, G1ScanCardClosure* update_rs_cl);
-
   // Print accumulated summary info from the start of the VM.
   void print_summary_info();
 
--- a/src/hotspot/share/gc/g1/g1SATBMarkQueueSet.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1SATBMarkQueueSet.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -35,12 +35,10 @@
 G1SATBMarkQueueSet::G1SATBMarkQueueSet() : _g1h(NULL) {}
 
 void G1SATBMarkQueueSet::initialize(G1CollectedHeap* g1h,
-                                    Monitor* cbl_mon,
                                     BufferNode::Allocator* allocator,
                                     size_t process_completed_buffers_threshold,
                                     uint buffer_enqueue_threshold_percentage) {
-  SATBMarkQueueSet::initialize(cbl_mon,
-                               allocator,
+  SATBMarkQueueSet::initialize(allocator,
                                process_completed_buffers_threshold,
                                buffer_enqueue_threshold_percentage);
   _g1h = g1h;
--- a/src/hotspot/share/gc/g1/g1SATBMarkQueueSet.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1SATBMarkQueueSet.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -38,7 +38,6 @@
   G1SATBMarkQueueSet();
 
   void initialize(G1CollectedHeap* g1h,
-                  Monitor* cbl_mon,
                   BufferNode::Allocator* allocator,
                   size_t process_completed_buffers_threshold,
                   uint buffer_enqueue_threshold_percentage);
--- a/src/hotspot/share/gc/g1/heapRegion.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/g1/heapRegion.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -49,6 +49,7 @@
 
 int    HeapRegion::LogOfHRGrainBytes = 0;
 int    HeapRegion::LogOfHRGrainWords = 0;
+int    HeapRegion::LogCardsPerRegion = 0;
 size_t HeapRegion::GrainBytes        = 0;
 size_t HeapRegion::GrainWords        = 0;
 size_t HeapRegion::CardsPerRegion    = 0;
@@ -105,6 +106,8 @@
   guarantee(CardsPerRegion == 0, "we should only set it once");
   CardsPerRegion = GrainBytes >> G1CardTable::card_shift;
 
+  LogCardsPerRegion = log2_long((jlong) CardsPerRegion);
+
   if (G1HeapRegionSize != GrainBytes) {
     FLAG_SET_ERGO(G1HeapRegionSize, GrainBytes);
   }
--- a/src/hotspot/share/gc/g1/heapRegion.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/g1/heapRegion.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -60,7 +60,6 @@
 class G1CMBitMap;
 class G1IsAliveAndApplyClosure;
 class HeapRegionRemSet;
-class HeapRegionRemSetIterator;
 class HeapRegion;
 class HeapRegionSetBase;
 class nmethod;
@@ -315,6 +314,7 @@
 
   static int    LogOfHRGrainBytes;
   static int    LogOfHRGrainWords;
+  static int    LogCardsPerRegion;
 
   static size_t GrainBytes;
   static size_t GrainWords;
--- a/src/hotspot/share/gc/g1/heapRegionRemSet.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/g1/heapRegionRemSet.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -27,7 +27,7 @@
 #include "gc/g1/g1CollectedHeap.inline.hpp"
 #include "gc/g1/g1ConcurrentRefine.hpp"
 #include "gc/g1/heapRegionManager.inline.hpp"
-#include "gc/g1/heapRegionRemSet.hpp"
+#include "gc/g1/heapRegionRemSet.inline.hpp"
 #include "gc/shared/space.inline.hpp"
 #include "memory/allocation.hpp"
 #include "memory/padded.inline.hpp"
@@ -42,195 +42,21 @@
 const char* HeapRegionRemSet::_state_strings[] =  {"Untracked", "Updating", "Complete"};
 const char* HeapRegionRemSet::_short_state_strings[] =  {"UNTRA", "UPDAT", "CMPLT"};
 
-class PerRegionTable: public CHeapObj<mtGC> {
-  friend class OtherRegionsTable;
-  friend class HeapRegionRemSetIterator;
-
-  HeapRegion*     _hr;
-  CHeapBitMap     _bm;
-  jint            _occupied;
-
-  // next pointer for free/allocated 'all' list
-  PerRegionTable* _next;
-
-  // prev pointer for the allocated 'all' list
-  PerRegionTable* _prev;
-
-  // next pointer in collision list
-  PerRegionTable * _collision_list_next;
-
-  // Global free list of PRTs
-  static PerRegionTable* volatile _free_list;
-
-protected:
-  // We need access in order to union things into the base table.
-  BitMap* bm() { return &_bm; }
-
-  PerRegionTable(HeapRegion* hr) :
-    _hr(hr),
-    _bm(HeapRegion::CardsPerRegion, mtGC),
-    _occupied(0),
-    _next(NULL), _prev(NULL),
-    _collision_list_next(NULL)
-  {}
-
-  void add_card_work(CardIdx_t from_card, bool par) {
-    if (!_bm.at(from_card)) {
-      if (par) {
-        if (_bm.par_at_put(from_card, 1)) {
-          Atomic::inc(&_occupied);
-        }
-      } else {
-        _bm.at_put(from_card, 1);
-        _occupied++;
-      }
-    }
-  }
-
-  void add_reference_work(OopOrNarrowOopStar from, bool par) {
-    // Must make this robust in case "from" is not in "_hr", because of
-    // concurrency.
-
-    HeapRegion* loc_hr = hr();
-    // If the test below fails, then this table was reused concurrently
-    // with this operation.  This is OK, since the old table was coarsened,
-    // and adding a bit to the new table is never incorrect.
-    if (loc_hr->is_in_reserved(from)) {
-      CardIdx_t from_card = OtherRegionsTable::card_within_region(from, loc_hr);
-      add_card_work(from_card, par);
+PerRegionTable* PerRegionTable::alloc(HeapRegion* hr) {
+  PerRegionTable* fl = _free_list;
+  while (fl != NULL) {
+    PerRegionTable* nxt = fl->next();
+    PerRegionTable* res = Atomic::cmpxchg(nxt, &_free_list, fl);
+    if (res == fl) {
+      fl->init(hr, true);
+      return fl;
+    } else {
+      fl = _free_list;
     }
   }
-
-public:
-
-  HeapRegion* hr() const { return OrderAccess::load_acquire(&_hr); }
-
-  jint occupied() const {
-    // Overkill, but if we ever need it...
-    // guarantee(_occupied == _bm.count_one_bits(), "Check");
-    return _occupied;
-  }
-
-  void init(HeapRegion* hr, bool clear_links_to_all_list) {
-    if (clear_links_to_all_list) {
-      set_next(NULL);
-      set_prev(NULL);
-    }
-    _collision_list_next = NULL;
-    _occupied = 0;
-    _bm.clear();
-    // Make sure that the bitmap clearing above has been finished before publishing
-    // this PRT to concurrent threads.
-    OrderAccess::release_store(&_hr, hr);
-  }
-
-  void add_reference(OopOrNarrowOopStar from) {
-    add_reference_work(from, /*parallel*/ true);
-  }
-
-  void seq_add_reference(OopOrNarrowOopStar from) {
-    add_reference_work(from, /*parallel*/ false);
-  }
-
-  void add_card(CardIdx_t from_card_index) {
-    add_card_work(from_card_index, /*parallel*/ true);
-  }
-
-  void seq_add_card(CardIdx_t from_card_index) {
-    add_card_work(from_card_index, /*parallel*/ false);
-  }
-
-  // (Destructively) union the bitmap of the current table into the given
-  // bitmap (which is assumed to be of the same size.)
-  void union_bitmap_into(BitMap* bm) {
-    bm->set_union(_bm);
-  }
-
-  // Mem size in bytes.
-  size_t mem_size() const {
-    return sizeof(PerRegionTable) + _bm.size_in_words() * HeapWordSize;
-  }
-
-  // Requires "from" to be in "hr()".
-  bool contains_reference(OopOrNarrowOopStar from) const {
-    assert(hr()->is_in_reserved(from), "Precondition.");
-    size_t card_ind = pointer_delta(from, hr()->bottom(),
-                                    G1CardTable::card_size);
-    return _bm.at(card_ind);
-  }
-
-  // Bulk-free the PRTs from prt to last, assumes that they are
-  // linked together using their _next field.
-  static void bulk_free(PerRegionTable* prt, PerRegionTable* last) {
-    while (true) {
-      PerRegionTable* fl = _free_list;
-      last->set_next(fl);
-      PerRegionTable* res = Atomic::cmpxchg(prt, &_free_list, fl);
-      if (res == fl) {
-        return;
-      }
-    }
-    ShouldNotReachHere();
-  }
-
-  static void free(PerRegionTable* prt) {
-    bulk_free(prt, prt);
-  }
-
-  // Returns an initialized PerRegionTable instance.
-  static PerRegionTable* alloc(HeapRegion* hr) {
-    PerRegionTable* fl = _free_list;
-    while (fl != NULL) {
-      PerRegionTable* nxt = fl->next();
-      PerRegionTable* res = Atomic::cmpxchg(nxt, &_free_list, fl);
-      if (res == fl) {
-        fl->init(hr, true);
-        return fl;
-      } else {
-        fl = _free_list;
-      }
-    }
-    assert(fl == NULL, "Loop condition.");
-    return new PerRegionTable(hr);
-  }
-
-  PerRegionTable* next() const { return _next; }
-  void set_next(PerRegionTable* next) { _next = next; }
-  PerRegionTable* prev() const { return _prev; }
-  void set_prev(PerRegionTable* prev) { _prev = prev; }
-
-  // Accessor and Modification routines for the pointer for the
-  // singly linked collision list that links the PRTs within the
-  // OtherRegionsTable::_fine_grain_regions hash table.
-  //
-  // It might be useful to also make the collision list doubly linked
-  // to avoid iteration over the collisions list during scrubbing/deletion.
-  // OTOH there might not be many collisions.
-
-  PerRegionTable* collision_list_next() const {
-    return _collision_list_next;
-  }
-
-  void set_collision_list_next(PerRegionTable* next) {
-    _collision_list_next = next;
-  }
-
-  PerRegionTable** collision_list_next_addr() {
-    return &_collision_list_next;
-  }
-
-  static size_t fl_mem_size() {
-    PerRegionTable* cur = _free_list;
-    size_t res = 0;
-    while (cur != NULL) {
-      res += cur->mem_size();
-      cur = cur->next();
-    }
-    return res;
-  }
-
-  static void test_fl_mem_size();
-};
+  assert(fl == NULL, "Loop condition.");
+  return new PerRegionTable(hr);
+}
 
 PerRegionTable* volatile PerRegionTable::_free_list = NULL;
 
@@ -696,175 +522,3 @@
 size_t HeapRegionRemSet::strong_code_roots_mem_size() {
   return _code_roots.mem_size();
 }
-
-HeapRegionRemSetIterator:: HeapRegionRemSetIterator(HeapRegionRemSet* hrrs) :
-  _hrrs(hrrs),
-  _coarse_map(&hrrs->_other_regions._coarse_map),
-  _bot(hrrs->_bot),
-  _g1h(G1CollectedHeap::heap()),
-  _n_yielded_fine(0),
-  _n_yielded_coarse(0),
-  _n_yielded_sparse(0),
-  _is(Sparse),
-  _cur_region_card_offset(0),
-  // Set these values so that we increment to the first region.
-  _coarse_cur_region_index(-1),
-  _coarse_cur_region_cur_card(HeapRegion::CardsPerRegion-1),
-  _fine_cur_prt(NULL),
-  _cur_card_in_prt(HeapRegion::CardsPerRegion),
-  _sparse_iter(&hrrs->_other_regions._sparse_table) {}
-
-bool HeapRegionRemSetIterator::coarse_has_next(size_t& card_index) {
-  if (_hrrs->_other_regions._n_coarse_entries == 0) return false;
-  // Go to the next card.
-  _coarse_cur_region_cur_card++;
-  // Was the last the last card in the current region?
-  if (_coarse_cur_region_cur_card == HeapRegion::CardsPerRegion) {
-    // Yes: find the next region.  This may leave _coarse_cur_region_index
-    // Set to the last index, in which case there are no more coarse
-    // regions.
-    _coarse_cur_region_index =
-      (int) _coarse_map->get_next_one_offset(_coarse_cur_region_index + 1);
-    if ((size_t)_coarse_cur_region_index < _coarse_map->size()) {
-      _coarse_cur_region_cur_card = 0;
-      HeapWord* r_bot =
-        _g1h->region_at((uint) _coarse_cur_region_index)->bottom();
-      _cur_region_card_offset = _bot->index_for_raw(r_bot);
-    } else {
-      return false;
-    }
-  }
-  // If we didn't return false above, then we can yield a card.
-  card_index = _cur_region_card_offset + _coarse_cur_region_cur_card;
-  return true;
-}
-
-bool HeapRegionRemSetIterator::fine_has_next(size_t& card_index) {
-  if (fine_has_next()) {
-    _cur_card_in_prt =
-      _fine_cur_prt->_bm.get_next_one_offset(_cur_card_in_prt + 1);
-  }
-  if (_cur_card_in_prt == HeapRegion::CardsPerRegion) {
-    // _fine_cur_prt may still be NULL in case if there are not PRTs at all for
-    // the remembered set.
-    if (_fine_cur_prt == NULL || _fine_cur_prt->next() == NULL) {
-      return false;
-    }
-    PerRegionTable* next_prt = _fine_cur_prt->next();
-    switch_to_prt(next_prt);
-    _cur_card_in_prt = _fine_cur_prt->_bm.get_next_one_offset(_cur_card_in_prt + 1);
-  }
-
-  card_index = _cur_region_card_offset + _cur_card_in_prt;
-  guarantee(_cur_card_in_prt < HeapRegion::CardsPerRegion,
-            "Card index " SIZE_FORMAT " must be within the region", _cur_card_in_prt);
-  return true;
-}
-
-bool HeapRegionRemSetIterator::fine_has_next() {
-  return _cur_card_in_prt != HeapRegion::CardsPerRegion;
-}
-
-void HeapRegionRemSetIterator::switch_to_prt(PerRegionTable* prt) {
-  assert(prt != NULL, "Cannot switch to NULL prt");
-  _fine_cur_prt = prt;
-
-  HeapWord* r_bot = _fine_cur_prt->hr()->bottom();
-  _cur_region_card_offset = _bot->index_for_raw(r_bot);
-
-  // The bitmap scan for the PRT always scans from _cur_region_cur_card + 1.
-  // To avoid special-casing this start case, and not miss the first bitmap
-  // entry, initialize _cur_region_cur_card with -1 instead of 0.
-  _cur_card_in_prt = (size_t)-1;
-}
-
-bool HeapRegionRemSetIterator::has_next(size_t& card_index) {
-  switch (_is) {
-  case Sparse: {
-    if (_sparse_iter.has_next(card_index)) {
-      _n_yielded_sparse++;
-      return true;
-    }
-    // Otherwise, deliberate fall-through
-    _is = Fine;
-    PerRegionTable* initial_fine_prt = _hrrs->_other_regions._first_all_fine_prts;
-    if (initial_fine_prt != NULL) {
-      switch_to_prt(_hrrs->_other_regions._first_all_fine_prts);
-    }
-  }
-  case Fine:
-    if (fine_has_next(card_index)) {
-      _n_yielded_fine++;
-      return true;
-    }
-    // Otherwise, deliberate fall-through
-    _is = Coarse;
-  case Coarse:
-    if (coarse_has_next(card_index)) {
-      _n_yielded_coarse++;
-      return true;
-    }
-    // Otherwise...
-    break;
-  }
-  return false;
-}
-
-#ifndef PRODUCT
-void HeapRegionRemSet::test() {
-  os::sleep(Thread::current(), (jlong)5000, false);
-  G1CollectedHeap* g1h = G1CollectedHeap::heap();
-
-  // Run with "-XX:G1LogRSetRegionEntries=2", so that 1 and 5 end up in same
-  // hash bucket.
-  HeapRegion* hr0 = g1h->region_at(0);
-  HeapRegion* hr1 = g1h->region_at(1);
-  HeapRegion* hr2 = g1h->region_at(5);
-  HeapRegion* hr3 = g1h->region_at(6);
-  HeapRegion* hr4 = g1h->region_at(7);
-  HeapRegion* hr5 = g1h->region_at(8);
-
-  HeapWord* hr1_start = hr1->bottom();
-  HeapWord* hr1_mid = hr1_start + HeapRegion::GrainWords/2;
-  HeapWord* hr1_last = hr1->end() - 1;
-
-  HeapWord* hr2_start = hr2->bottom();
-  HeapWord* hr2_mid = hr2_start + HeapRegion::GrainWords/2;
-  HeapWord* hr2_last = hr2->end() - 1;
-
-  HeapWord* hr3_start = hr3->bottom();
-  HeapWord* hr3_mid = hr3_start + HeapRegion::GrainWords/2;
-  HeapWord* hr3_last = hr3->end() - 1;
-
-  HeapRegionRemSet* hrrs = hr0->rem_set();
-
-  // Make three references from region 0x101...
-  hrrs->add_reference((OopOrNarrowOopStar)hr1_start);
-  hrrs->add_reference((OopOrNarrowOopStar)hr1_mid);
-  hrrs->add_reference((OopOrNarrowOopStar)hr1_last);
-
-  hrrs->add_reference((OopOrNarrowOopStar)hr2_start);
-  hrrs->add_reference((OopOrNarrowOopStar)hr2_mid);
-  hrrs->add_reference((OopOrNarrowOopStar)hr2_last);
-
-  hrrs->add_reference((OopOrNarrowOopStar)hr3_start);
-  hrrs->add_reference((OopOrNarrowOopStar)hr3_mid);
-  hrrs->add_reference((OopOrNarrowOopStar)hr3_last);
-
-  // Now cause a coarsening.
-  hrrs->add_reference((OopOrNarrowOopStar)hr4->bottom());
-  hrrs->add_reference((OopOrNarrowOopStar)hr5->bottom());
-
-  // Now, does iteration yield these three?
-  HeapRegionRemSetIterator iter(hrrs);
-  size_t sum = 0;
-  size_t card_index;
-  while (iter.has_next(card_index)) {
-    HeapWord* card_start = g1h->bot()->address_for_index(card_index);
-    tty->print_cr("  Card " PTR_FORMAT ".", p2i(card_start));
-    sum++;
-  }
-  guarantee(sum == 11 - 3 + 2048, "Failure");
-  guarantee(sum == hrrs->occupied(), "Failure");
-}
-#endif
--- a/src/hotspot/share/gc/g1/heapRegionRemSet.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/g1/heapRegionRemSet.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -28,6 +28,7 @@
 #include "gc/g1/g1CodeCacheRemSet.hpp"
 #include "gc/g1/g1FromCardCache.hpp"
 #include "gc/g1/sparsePRT.hpp"
+#include "utilities/bitMap.hpp"
 
 // Remembered set for a heap region.  Represent a set of "cards" that
 // contain pointers into the owner heap region.  Cards are defined somewhat
@@ -37,7 +38,6 @@
 class G1BlockOffsetTable;
 class G1CardLiveData;
 class HeapRegion;
-class HeapRegionRemSetIterator;
 class PerRegionTable;
 class SparsePRT;
 class nmethod;
@@ -67,8 +67,6 @@
 //      thinking the PRT is for a different region, does no harm.
 
 class OtherRegionsTable {
-  friend class HeapRegionRemSetIterator;
-
   G1CollectedHeap* _g1h;
   Mutex*           _m;
 
@@ -125,6 +123,9 @@
   // Create a new remembered set. The given mutex is used to ensure consistency.
   OtherRegionsTable(Mutex* m);
 
+  template <class Closure>
+  void iterate(Closure& v);
+
   // Returns the card index of the given within_region pointer relative to the bottom
   // of the given heap region.
   static CardIdx_t card_within_region(OopOrNarrowOopStar within_region, HeapRegion* hr);
@@ -157,9 +158,140 @@
   void clear();
 };
 
+class PerRegionTable: public CHeapObj<mtGC> {
+  friend class OtherRegionsTable;
+
+  HeapRegion*     _hr;
+  CHeapBitMap     _bm;
+  jint            _occupied;
+
+  // next pointer for free/allocated 'all' list
+  PerRegionTable* _next;
+
+  // prev pointer for the allocated 'all' list
+  PerRegionTable* _prev;
+
+  // next pointer in collision list
+  PerRegionTable * _collision_list_next;
+
+  // Global free list of PRTs
+  static PerRegionTable* volatile _free_list;
+
+protected:
+  PerRegionTable(HeapRegion* hr) :
+    _hr(hr),
+    _bm(HeapRegion::CardsPerRegion, mtGC),
+    _occupied(0),
+    _next(NULL), _prev(NULL),
+    _collision_list_next(NULL)
+  {}
+
+  inline void add_card_work(CardIdx_t from_card, bool par);
+
+  inline void add_reference_work(OopOrNarrowOopStar from, bool par);
+
+public:
+  // We need access in order to union things into the base table.
+  BitMap* bm() { return &_bm; }
+
+  HeapRegion* hr() const { return OrderAccess::load_acquire(&_hr); }
+
+  jint occupied() const {
+    // Overkill, but if we ever need it...
+    // guarantee(_occupied == _bm.count_one_bits(), "Check");
+    return _occupied;
+  }
+
+  void init(HeapRegion* hr, bool clear_links_to_all_list);
+
+  inline void add_reference(OopOrNarrowOopStar from);
+
+  inline void seq_add_reference(OopOrNarrowOopStar from);
+
+  inline void add_card(CardIdx_t from_card_index);
+
+  void seq_add_card(CardIdx_t from_card_index);
+
+  // (Destructively) union the bitmap of the current table into the given
+  // bitmap (which is assumed to be of the same size.)
+  void union_bitmap_into(BitMap* bm) {
+    bm->set_union(_bm);
+  }
+
+  // Mem size in bytes.
+  size_t mem_size() const {
+    return sizeof(PerRegionTable) + _bm.size_in_words() * HeapWordSize;
+  }
+
+  // Requires "from" to be in "hr()".
+  bool contains_reference(OopOrNarrowOopStar from) const {
+    assert(hr()->is_in_reserved(from), "Precondition.");
+    size_t card_ind = pointer_delta(from, hr()->bottom(),
+                                    G1CardTable::card_size);
+    return _bm.at(card_ind);
+  }
+
+  // Bulk-free the PRTs from prt to last, assumes that they are
+  // linked together using their _next field.
+  static void bulk_free(PerRegionTable* prt, PerRegionTable* last) {
+    while (true) {
+      PerRegionTable* fl = _free_list;
+      last->set_next(fl);
+      PerRegionTable* res = Atomic::cmpxchg(prt, &_free_list, fl);
+      if (res == fl) {
+        return;
+      }
+    }
+    ShouldNotReachHere();
+  }
+
+  static void free(PerRegionTable* prt) {
+    bulk_free(prt, prt);
+  }
+
+  // Returns an initialized PerRegionTable instance.
+  static PerRegionTable* alloc(HeapRegion* hr);
+
+  PerRegionTable* next() const { return _next; }
+  void set_next(PerRegionTable* next) { _next = next; }
+  PerRegionTable* prev() const { return _prev; }
+  void set_prev(PerRegionTable* prev) { _prev = prev; }
+
+  // Accessor and Modification routines for the pointer for the
+  // singly linked collision list that links the PRTs within the
+  // OtherRegionsTable::_fine_grain_regions hash table.
+  //
+  // It might be useful to also make the collision list doubly linked
+  // to avoid iteration over the collisions list during scrubbing/deletion.
+  // OTOH there might not be many collisions.
+
+  PerRegionTable* collision_list_next() const {
+    return _collision_list_next;
+  }
+
+  void set_collision_list_next(PerRegionTable* next) {
+    _collision_list_next = next;
+  }
+
+  PerRegionTable** collision_list_next_addr() {
+    return &_collision_list_next;
+  }
+
+  static size_t fl_mem_size() {
+    PerRegionTable* cur = _free_list;
+    size_t res = 0;
+    while (cur != NULL) {
+      res += cur->mem_size();
+      cur = cur->next();
+    }
+    return res;
+  }
+
+  static void test_fl_mem_size();
+};
+
 class HeapRegionRemSet : public CHeapObj<mtGC> {
   friend class VMStructs;
-  friend class HeapRegionRemSetIterator;
 
 private:
   G1BlockOffsetTable* _bot;
@@ -182,18 +314,23 @@
   // Setup sparse and fine-grain tables sizes.
   static void setup_remset_size();
 
-  bool cardset_is_empty() const {
-    return _other_regions.is_empty();
-  }
-
   bool is_empty() const {
-    return (strong_code_roots_list_length() == 0) && cardset_is_empty();
+    return (strong_code_roots_list_length() == 0) && _other_regions.is_empty();
   }
 
   bool occupancy_less_or_equal_than(size_t occ) const {
     return (strong_code_roots_list_length() == 0) && _other_regions.occupancy_less_or_equal_than(occ);
   }
 
+  // For each PRT in the card (remembered) set call one of the following methods
+  // of the given closure:
+  //
+  // set_full_region_dirty(uint region_idx) - pass the region index for coarse PRTs
+  // set_bitmap_dirty(uint region_idx, BitMap* bitmap) - pass the region index and bitmap for fine PRTs
+  // set_cards_dirty(uint region_idx, elem_t* cards, uint num_cards) - pass region index and cards for sparse PRTs
+  template <class Closure>
+  inline void iterate_prts(Closure& cl);
+
   size_t occupied() {
     MutexLocker x(&_m, Mutex::_no_safepoint_check_flag);
     return occupied_locked();
@@ -339,70 +476,4 @@
 #endif
 };
 
-class HeapRegionRemSetIterator : public StackObj {
-private:
-  // The region RSet over which we are iterating.
-  HeapRegionRemSet* _hrrs;
-
-  // Local caching of HRRS fields.
-  const BitMap*             _coarse_map;
-
-  G1BlockOffsetTable*       _bot;
-  G1CollectedHeap*          _g1h;
-
-  // The number of cards yielded since initialization.
-  size_t _n_yielded_fine;
-  size_t _n_yielded_coarse;
-  size_t _n_yielded_sparse;
-
-  // Indicates what granularity of table that we are currently iterating over.
-  // We start iterating over the sparse table, progress to the fine grain
-  // table, and then finish with the coarse table.
-  enum IterState {
-    Sparse,
-    Fine,
-    Coarse
-  };
-  IterState _is;
-
-  // For both Coarse and Fine remembered set iteration this contains the
-  // first card number of the heap region we currently iterate over.
-  size_t _cur_region_card_offset;
-
-  // Current region index for the Coarse remembered set iteration.
-  int    _coarse_cur_region_index;
-  size_t _coarse_cur_region_cur_card;
-
-  bool coarse_has_next(size_t& card_index);
-
-  // The PRT we are currently iterating over.
-  PerRegionTable* _fine_cur_prt;
-  // Card offset within the current PRT.
-  size_t _cur_card_in_prt;
-
-  // Update internal variables when switching to the given PRT.
-  void switch_to_prt(PerRegionTable* prt);
-  bool fine_has_next();
-  bool fine_has_next(size_t& card_index);
-
-  // The Sparse remembered set iterator.
-  SparsePRTIter _sparse_iter;
-
-public:
-  HeapRegionRemSetIterator(HeapRegionRemSet* hrrs);
-
-  // If there remains one or more cards to be yielded, returns true and
-  // sets "card_index" to one of those cards (which is then considered
-  // yielded.)   Otherwise, returns false (and leaves "card_index"
-  // undefined.)
-  bool has_next(size_t& card_index);
-
-  size_t n_yielded_fine() { return _n_yielded_fine; }
-  size_t n_yielded_coarse() { return _n_yielded_coarse; }
-  size_t n_yielded_sparse() { return _n_yielded_sparse; }
-  size_t n_yielded() {
-    return n_yielded_fine() + n_yielded_coarse() + n_yielded_sparse();
-  }
-};
-
 #endif // SHARE_GC_G1_HEAPREGIONREMSET_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/g1/heapRegionRemSet.inline.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_G1_HEAPREGIONREMSET_INLINE_HPP
+#define SHARE_VM_GC_G1_HEAPREGIONREMSET_INLINE_HPP
+
+#include "gc/g1/heapRegion.inline.hpp"
+#include "gc/g1/heapRegionRemSet.hpp"
+#include "gc/g1/sparsePRT.hpp"
+#include "utilities/bitMap.inline.hpp"
+
+template <class Closure>
+inline void HeapRegionRemSet::iterate_prts(Closure& cl) {
+  _other_regions.iterate(cl);
+}
+
+inline void PerRegionTable::add_card_work(CardIdx_t from_card, bool par) {
+  if (!_bm.at(from_card)) {
+    if (par) {
+      if (_bm.par_set_bit(from_card)) {
+        Atomic::inc(&_occupied);
+      }
+    } else {
+      _bm.set_bit(from_card);
+      _occupied++;
+    }
+  }
+}
+
+inline void PerRegionTable::add_reference_work(OopOrNarrowOopStar from, bool par) {
+  // Must make this robust in case "from" is not in "_hr", because of
+  // concurrency.
+
+  HeapRegion* loc_hr = hr();
+  // If the test below fails, then this table was reused concurrently
+  // with this operation.  This is OK, since the old table was coarsened,
+  // and adding a bit to the new table is never incorrect.
+  if (loc_hr->is_in_reserved(from)) {
+    CardIdx_t from_card = OtherRegionsTable::card_within_region(from, loc_hr);
+    add_card_work(from_card, par);
+  }
+}
+
+inline void PerRegionTable::add_card(CardIdx_t from_card_index) {
+  add_card_work(from_card_index, /*parallel*/ true);
+}
+
+inline void PerRegionTable::seq_add_card(CardIdx_t from_card_index) {
+  add_card_work(from_card_index, /*parallel*/ false);
+}
+
+inline void PerRegionTable::add_reference(OopOrNarrowOopStar from) {
+  add_reference_work(from, /*parallel*/ true);
+}
+
+inline void PerRegionTable::seq_add_reference(OopOrNarrowOopStar from) {
+  add_reference_work(from, /*parallel*/ false);
+}
+
+inline void PerRegionTable::init(HeapRegion* hr, bool clear_links_to_all_list) {
+  if (clear_links_to_all_list) {
+    set_next(NULL);
+    set_prev(NULL);
+  }
+  _collision_list_next = NULL;
+  _occupied = 0;
+  _bm.clear();
+  // Make sure that the bitmap clearing above has been finished before publishing
+  // this PRT to concurrent threads.
+  OrderAccess::release_store(&_hr, hr);
+}
+
+template <class Closure>
+void OtherRegionsTable::iterate(Closure& cl) {
+  if (_n_coarse_entries > 0) {
+    BitMap::idx_t cur = _coarse_map.get_next_one_offset(0);
+    while (cur != _coarse_map.size()) {
+      cl.next_coarse_prt((uint)cur);
+      cur = _coarse_map.get_next_one_offset(cur + 1);
+    }
+  }
+  {
+    PerRegionTable* cur = _first_all_fine_prts;
+    while (cur != NULL) {
+      cl.next_fine_prt(cur->hr()->hrm_index(), cur->bm());
+      cur = cur->next();
+    }
+  }
+  {
+    SparsePRTBucketIter iter(&_sparse_table);
+    SparsePRTEntry* cur;
+    while (iter.has_next(cur)) {
+      cl.next_sparse_prt(cur->r_ind(), cur->cards(), cur->num_valid_cards());
+    }
+  }
+}
+
+#endif // SHARE_VM_GC_G1_HEAPREGIONREMSET_INLINE_HPP
--- a/src/hotspot/share/gc/g1/sparsePRT.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/g1/sparsePRT.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -275,6 +275,19 @@
   return false;
 }
 
+bool RSHashTableBucketIter::has_next(SparsePRTEntry*& entry) {
+  while (_bl_ind == RSHashTable::NullEntry)  {
+    if (_tbl_ind == (int)_rsht->capacity() - 1) {
+      return false;
+    }
+    _tbl_ind++;
+    _bl_ind = _rsht->_buckets[_tbl_ind];
+  }
+  entry = _rsht->entry(_bl_ind);
+  _bl_ind = entry->next_index();
+  return true;
+}
+
 bool RSHashTable::contains_card(RegionIdx_t region_index, CardIdx_t card_index) const {
   SparsePRTEntry* e = get_entry(region_index);
   return (e != NULL && e->contains_card(card_index));
--- a/src/hotspot/share/gc/g1/sparsePRT.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/g1/sparsePRT.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -38,10 +38,11 @@
 // that might contain pointers into the owner region.
 
 class SparsePRTEntry: public CHeapObj<mtGC> {
-private:
+public:
   // The type of a card entry.
   typedef uint16_t card_elem_t;
 
+private:
   // We need to make sizeof(SparsePRTEntry) an even multiple of maximum member size,
   // in order to force correct alignment that could otherwise cause SIGBUS errors
   // when reading the member variables. This calculates the minimum number of card
@@ -96,6 +97,8 @@
   // Copy the current entry's cards into the "_card" array of "e."
   inline void copy_cards(SparsePRTEntry* e) const;
 
+  card_elem_t* cards() { return _cards; }
+
   inline CardIdx_t card(int i) const {
     assert(i >= 0, "must be nonnegative");
     assert(i < cards_num(), "range checking");
@@ -106,7 +109,7 @@
 class RSHashTable : public CHeapObj<mtGC> {
 
   friend class RSHashTableIter;
-
+  friend class RSHashTableBucketIter;
 
   // Inverse maximum hash table occupancy used.
   static float TableOccupancyFactor;
@@ -209,12 +212,29 @@
   bool has_next(size_t& card_index);
 };
 
+// This is embedded in HRRS iterator.
+class RSHashTableBucketIter {
+  int _tbl_ind;         // [-1, 0.._rsht->_capacity)
+  int _bl_ind;          // [-1, 0.._rsht->_capacity)
+
+  RSHashTable* _rsht;
+
+public:
+  RSHashTableBucketIter(RSHashTable* rsht) :
+    _tbl_ind(0),
+    _bl_ind(rsht->_buckets[_tbl_ind]),
+    _rsht(rsht) { }
+
+  bool has_next(SparsePRTEntry*& entry);
+};
+
 // Concurrent access to a SparsePRT must be serialized by some external mutex.
 
 class SparsePRTIter;
 
 class SparsePRT {
   friend class SparsePRTIter;
+  friend class SparsePRTBucketIter;
 
   RSHashTable* _table;
 
@@ -262,4 +282,14 @@
   }
 };
 
+class SparsePRTBucketIter: public RSHashTableBucketIter {
+public:
+  SparsePRTBucketIter(const SparsePRT* sprt) :
+    RSHashTableBucketIter(sprt->_table) {}
+
+  bool has_next(SparsePRTEntry*& entry) {
+    return RSHashTableBucketIter::has_next(entry);
+  }
+};
+
 #endif // SHARE_GC_G1_SPARSEPRT_HPP
--- a/src/hotspot/share/gc/parallel/psMarkSweep.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/parallel/psMarkSweep.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -259,7 +259,6 @@
 
     BiasedLocking::restore_marks();
     heap->prune_scavengable_nmethods();
-    JvmtiExport::gc_epilogue();
 
 #if COMPILER2_OR_JVMCI
     DerivedPointerTable::update_pointers();
--- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -1064,7 +1064,6 @@
   MetaspaceUtils::verify_metrics();
 
   heap->prune_scavengable_nmethods();
-  JvmtiExport::gc_epilogue();
 
 #if COMPILER2_OR_JVMCI
   DerivedPointerTable::update_pointers();
--- a/src/hotspot/share/gc/serial/genMarkSweep.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/serial/genMarkSweep.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -129,7 +129,6 @@
   }
 
   gch->prune_scavengable_nmethods();
-  JvmtiExport::gc_epilogue();
 
   // refs processing: clean slate
   set_ref_processor(NULL);
--- a/src/hotspot/share/gc/shared/c2/barrierSetC2.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/shared/c2/barrierSetC2.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -267,6 +267,7 @@
   virtual bool has_load_barriers() const { return false; }
   virtual bool is_gc_barrier_node(Node* node) const { return false; }
   virtual Node* step_over_gc_barrier(Node* c) const { return c; }
+  virtual Node* step_over_gc_barrier_ctrl(Node* c) const { return c; }
 
   // Support for macro expanded GC barriers
   virtual void register_potential_barrier_node(Node* node) const { }
--- a/src/hotspot/share/gc/shared/cardTable.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/shared/cardTable.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -103,15 +103,11 @@
 
   enum CardValues {
     clean_card                  = (CardValue)-1,
-    // The mask contains zeros in places for all other values.
-    clean_card_mask             = clean_card - 31,
 
     dirty_card                  =  0,
     precleaned_card             =  1,
-    claimed_card                =  2,
-    deferred_card               =  4,
-    last_card                   =  8,
-    CT_MR_BS_last_reserved      = 16
+    last_card                   =  2,
+    CT_MR_BS_last_reserved      =  4
   };
 
   // a word's worth (row) of clean card values
@@ -242,11 +238,8 @@
   };
 
   static CardValue clean_card_val()          { return clean_card; }
-  static CardValue clean_card_mask_val()     { return clean_card_mask; }
   static CardValue dirty_card_val()          { return dirty_card; }
-  static CardValue claimed_card_val()        { return claimed_card; }
   static CardValue precleaned_card_val()     { return precleaned_card; }
-  static CardValue deferred_card_val()       { return deferred_card; }
   static intptr_t clean_card_row_val()   { return clean_card_row; }
 
   // Card marking array base (adjusted for heap low boundary)
--- a/src/hotspot/share/gc/shared/generation.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/shared/generation.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -68,6 +68,12 @@
   return gch->old_gen_spec()->init_size();
 }
 
+// This is for CMS. It returns stable monotonic used space size.
+// Remove this when CMS is removed.
+size_t Generation::used_stable() const {
+  return used();
+}
+
 size_t Generation::max_capacity() const {
   return reserved().byte_size();
 }
--- a/src/hotspot/share/gc/shared/generation.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/shared/generation.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -156,6 +156,7 @@
   virtual size_t capacity() const = 0;  // The maximum number of object bytes the
                                         // generation can currently hold.
   virtual size_t used() const = 0;      // The number of used bytes in the gen.
+  virtual size_t used_stable() const;   // The number of used bytes for memory monitoring tools.
   virtual size_t free() const = 0;      // The number of free bytes in the gen.
 
   // Support for java.lang.Runtime.maxMemory(); see CollectedHeap.
--- a/src/hotspot/share/gc/shared/ptrQueue.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/shared/ptrQueue.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -250,28 +250,15 @@
   return removed;
 }
 
-PtrQueueSet::PtrQueueSet(bool notify_when_complete) :
+PtrQueueSet::PtrQueueSet() :
   _allocator(NULL),
-  _cbl_mon(NULL),
-  _completed_buffers_head(NULL),
-  _completed_buffers_tail(NULL),
-  _n_completed_buffers(0),
-  _process_completed_buffers_threshold(ProcessCompletedBuffersThresholdNever),
-  _process_completed_buffers(false),
-  _notify_when_complete(notify_when_complete),
   _all_active(false)
 {}
 
-PtrQueueSet::~PtrQueueSet() {
-  // There are presently only a couple (derived) instances ever
-  // created, and they are permanent, so no harm currently done by
-  // doing nothing here.
-}
+PtrQueueSet::~PtrQueueSet() {}
 
-void PtrQueueSet::initialize(Monitor* cbl_mon,
-                             BufferNode::Allocator* allocator) {
-  assert(cbl_mon != NULL && allocator != NULL, "Init order issue?");
-  _cbl_mon = cbl_mon;
+void PtrQueueSet::initialize(BufferNode::Allocator* allocator) {
+  assert(allocator != NULL, "Init order issue?");
   _allocator = allocator;
 }
 
@@ -284,121 +271,3 @@
   _allocator->release(node);
 }
 
-void PtrQueueSet::enqueue_completed_buffer(BufferNode* cbn) {
-  MutexLocker x(_cbl_mon, Mutex::_no_safepoint_check_flag);
-  cbn->set_next(NULL);
-  if (_completed_buffers_tail == NULL) {
-    assert(_completed_buffers_head == NULL, "Well-formedness");
-    _completed_buffers_head = cbn;
-    _completed_buffers_tail = cbn;
-  } else {
-    _completed_buffers_tail->set_next(cbn);
-    _completed_buffers_tail = cbn;
-  }
-  _n_completed_buffers++;
-
-  if (!_process_completed_buffers &&
-      (_n_completed_buffers > _process_completed_buffers_threshold)) {
-    _process_completed_buffers = true;
-    if (_notify_when_complete) {
-      _cbl_mon->notify();
-    }
-  }
-  assert_completed_buffers_list_len_correct_locked();
-}
-
-BufferNode* PtrQueueSet::get_completed_buffer(size_t stop_at) {
-  MutexLocker x(_cbl_mon, Mutex::_no_safepoint_check_flag);
-
-  if (_n_completed_buffers <= stop_at) {
-    return NULL;
-  }
-
-  assert(_n_completed_buffers > 0, "invariant");
-  assert(_completed_buffers_head != NULL, "invariant");
-  assert(_completed_buffers_tail != NULL, "invariant");
-
-  BufferNode* bn = _completed_buffers_head;
-  _n_completed_buffers--;
-  _completed_buffers_head = bn->next();
-  if (_completed_buffers_head == NULL) {
-    assert(_n_completed_buffers == 0, "invariant");
-    _completed_buffers_tail = NULL;
-    _process_completed_buffers = false;
-  }
-  assert_completed_buffers_list_len_correct_locked();
-  bn->set_next(NULL);
-  return bn;
-}
-
-void PtrQueueSet::abandon_completed_buffers() {
-  BufferNode* buffers_to_delete = NULL;
-  {
-    MutexLocker x(_cbl_mon, Mutex::_no_safepoint_check_flag);
-    buffers_to_delete = _completed_buffers_head;
-    _completed_buffers_head = NULL;
-    _completed_buffers_tail = NULL;
-    _n_completed_buffers = 0;
-    _process_completed_buffers = false;
-  }
-  while (buffers_to_delete != NULL) {
-    BufferNode* bn = buffers_to_delete;
-    buffers_to_delete = bn->next();
-    bn->set_next(NULL);
-    deallocate_buffer(bn);
-  }
-}
-
-#ifdef ASSERT
-
-void PtrQueueSet::assert_completed_buffers_list_len_correct_locked() {
-  assert_lock_strong(_cbl_mon);
-  size_t n = 0;
-  for (BufferNode* bn = _completed_buffers_head; bn != NULL; bn = bn->next()) {
-    ++n;
-  }
-  assert(n == _n_completed_buffers,
-         "Completed buffer length is wrong: counted: " SIZE_FORMAT
-         ", expected: " SIZE_FORMAT, n, _n_completed_buffers);
-}
-
-#endif // ASSERT
-
-// Merge lists of buffers. Notify the processing threads.
-// The source queue is emptied as a result. The queues
-// must share the monitor.
-void PtrQueueSet::merge_bufferlists(PtrQueueSet *src) {
-  assert(_cbl_mon == src->_cbl_mon, "Should share the same lock");
-  MutexLocker x(_cbl_mon, Mutex::_no_safepoint_check_flag);
-  if (_completed_buffers_tail == NULL) {
-    assert(_completed_buffers_head == NULL, "Well-formedness");
-    _completed_buffers_head = src->_completed_buffers_head;
-    _completed_buffers_tail = src->_completed_buffers_tail;
-  } else {
-    assert(_completed_buffers_head != NULL, "Well formedness");
-    if (src->_completed_buffers_head != NULL) {
-      _completed_buffers_tail->set_next(src->_completed_buffers_head);
-      _completed_buffers_tail = src->_completed_buffers_tail;
-    }
-  }
-  _n_completed_buffers += src->_n_completed_buffers;
-
-  src->_n_completed_buffers = 0;
-  src->_completed_buffers_head = NULL;
-  src->_completed_buffers_tail = NULL;
-  src->_process_completed_buffers = false;
-
-  assert(_completed_buffers_head == NULL && _completed_buffers_tail == NULL ||
-         _completed_buffers_head != NULL && _completed_buffers_tail != NULL,
-         "Sanity");
-  assert_completed_buffers_list_len_correct_locked();
-}
-
-void PtrQueueSet::notify_if_necessary() {
-  MutexLocker x(_cbl_mon, Mutex::_no_safepoint_check_flag);
-  if (_n_completed_buffers > _process_completed_buffers_threshold) {
-    _process_completed_buffers = true;
-    if (_notify_when_complete)
-      _cbl_mon->notify();
-  }
-}
--- a/src/hotspot/share/gc/shared/ptrQueue.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/shared/ptrQueue.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -296,35 +296,16 @@
 class PtrQueueSet {
   BufferNode::Allocator* _allocator;
 
-  Monitor* _cbl_mon;  // Protects the fields below.
-  BufferNode* _completed_buffers_head;
-  BufferNode* _completed_buffers_tail;
-  volatile size_t _n_completed_buffers;
-
-  size_t _process_completed_buffers_threshold;
-  volatile bool _process_completed_buffers;
-
-  // If true, notify_all on _cbl_mon when the threshold is reached.
-  bool _notify_when_complete;
-
-  void assert_completed_buffers_list_len_correct_locked() NOT_DEBUG_RETURN;
-
 protected:
   bool _all_active;
 
   // Create an empty ptr queue set.
-  PtrQueueSet(bool notify_when_complete = false);
+  PtrQueueSet();
   ~PtrQueueSet();
 
   // Because of init-order concerns, we can't pass these as constructor
   // arguments.
-  void initialize(Monitor* cbl_mon, BufferNode::Allocator* allocator);
-
-  // For (unlocked!) iteration over the completed buffers.
-  BufferNode* completed_buffers_head() const { return _completed_buffers_head; }
-
-  // Deallocate all of the completed buffers.
-  void abandon_completed_buffers();
+  void initialize(BufferNode::Allocator* allocator);
 
 public:
 
@@ -339,38 +320,13 @@
   // is ready to be processed by the collector.  It need not be full.
 
   // Adds node to the completed buffer list.
-  void enqueue_completed_buffer(BufferNode* node);
-
-  // If the number of completed buffers is > stop_at, then remove and
-  // return a completed buffer from the list.  Otherwise, return NULL.
-  BufferNode* get_completed_buffer(size_t stop_at = 0);
-
-  bool process_completed_buffers() { return _process_completed_buffers; }
-  void set_process_completed_buffers(bool x) { _process_completed_buffers = x; }
+  virtual void enqueue_completed_buffer(BufferNode* node) = 0;
 
   bool is_active() { return _all_active; }
 
   size_t buffer_size() const {
     return _allocator->buffer_size();
   }
-
-  // Get/Set the number of completed buffers that triggers log processing.
-  // Log processing should be done when the number of buffers exceeds the
-  // threshold.
-  void set_process_completed_buffers_threshold(size_t sz) {
-    _process_completed_buffers_threshold = sz;
-  }
-  size_t process_completed_buffers_threshold() const {
-    return _process_completed_buffers_threshold;
-  }
-  static const size_t ProcessCompletedBuffersThresholdNever = ~size_t(0);
-
-  size_t completed_buffers_num() const { return _n_completed_buffers; }
-
-  void merge_bufferlists(PtrQueueSet* src);
-
-  // Notify the consumer if the number of buffers crossed the threshold
-  void notify_if_necessary();
 };
 
 #endif // SHARE_GC_SHARED_PTRQUEUE_HPP
--- a/src/hotspot/share/gc/shared/satbMarkQueue.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/shared/satbMarkQueue.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -28,12 +28,15 @@
 #include "logging/log.hpp"
 #include "memory/allocation.inline.hpp"
 #include "oops/oop.inline.hpp"
+#include "runtime/atomic.hpp"
 #include "runtime/mutexLocker.hpp"
+#include "runtime/orderAccess.hpp"
 #include "runtime/os.hpp"
 #include "runtime/safepoint.hpp"
 #include "runtime/thread.hpp"
 #include "runtime/threadSMR.hpp"
 #include "runtime/vmThread.hpp"
+#include "utilities/globalCounter.inline.hpp"
 
 SATBMarkQueue::SATBMarkQueue(SATBMarkQueueSet* qset) :
   // SATB queues are only active during marking cycles. We create
@@ -107,15 +110,66 @@
 
 SATBMarkQueueSet::SATBMarkQueueSet() :
   PtrQueueSet(),
+  _list(),
+  _count_and_process_flag(0),
+  _process_completed_buffers_threshold(SIZE_MAX),
   _buffer_enqueue_threshold(0)
 {}
 
-void SATBMarkQueueSet::initialize(Monitor* cbl_mon,
-                                  BufferNode::Allocator* allocator,
+SATBMarkQueueSet::~SATBMarkQueueSet() {
+  abandon_completed_buffers();
+}
+
+// _count_and_process_flag has flag in least significant bit, count in
+// remaining bits.  _process_completed_buffers_threshold is scaled
+// accordingly, with the lsbit set, so a _count_and_process_flag value
+// is directly comparable with the recorded threshold value.  The
+// process flag is set whenever the count exceeds the threshold, and
+// remains set until the count is reduced to zero.
+
+// Increment count.  If count > threshold, set flag, else maintain flag.
+static void increment_count(volatile size_t* cfptr, size_t threshold) {
+  size_t old;
+  size_t value = Atomic::load(cfptr);
+  do {
+    old = value;
+    value += 2;
+    assert(value > old, "overflow");
+    if (value > threshold) value |= 1;
+    value = Atomic::cmpxchg(value, cfptr, old);
+  } while (value != old);
+}
+
+// Decrement count.  If count == 0, clear flag, else maintain flag.
+static void decrement_count(volatile size_t* cfptr) {
+  size_t old;
+  size_t value = Atomic::load(cfptr);
+  do {
+    assert((value >> 1) != 0, "underflow");
+    old = value;
+    value -= 2;
+    if (value <= 1) value = 0;
+    value = Atomic::cmpxchg(value, cfptr, old);
+  } while (value != old);
+}
+
+// Scale requested threshold to align with count field.  If scaling
+// overflows, just use max value.  Set process flag field to make
+// comparison in increment_count exact.
+static size_t scale_threshold(size_t value) {
+  size_t scaled_value = value << 1;
+  if ((scaled_value >> 1) != value) {
+    scaled_value = SIZE_MAX;
+  }
+  return scaled_value | 1;
+}
+
+void SATBMarkQueueSet::initialize(BufferNode::Allocator* allocator,
                                   size_t process_completed_buffers_threshold,
                                   uint buffer_enqueue_threshold_percentage) {
-  PtrQueueSet::initialize(cbl_mon, allocator);
-  set_process_completed_buffers_threshold(process_completed_buffers_threshold);
+  PtrQueueSet::initialize(allocator);
+  _process_completed_buffers_threshold =
+    scale_threshold(process_completed_buffers_threshold);
   assert(buffer_size() != 0, "buffer size not initialized");
   // Minimum threshold of 1 ensures enqueuing of completely full buffers.
   size_t size = buffer_size();
@@ -207,6 +261,38 @@
   }
 }
 
+// SATB buffer life-cycle - Per-thread queues obtain buffers from the
+// qset's buffer allocator, fill them, and push them onto the qset's
+// list.  The GC concurrently pops buffers from the qset, processes
+// them, and returns them to the buffer allocator for re-use.  Both
+// the allocator and the qset use lock-free stacks.  The ABA problem
+// is solved by having both allocation pops and GC pops performed
+// within GlobalCounter critical sections, while the return of buffers
+// to the allocator performs a GlobalCounter synchronize before
+// pushing onto the allocator's list.
+
+void SATBMarkQueueSet::enqueue_completed_buffer(BufferNode* node) {
+  assert(node != NULL, "precondition");
+  // Increment count and update flag appropriately.  Done before
+  // pushing buffer so count is always at least the actual number in
+  // the list, and decrement never underflows.
+  increment_count(&_count_and_process_flag, _process_completed_buffers_threshold);
+  _list.push(*node);
+}
+
+BufferNode* SATBMarkQueueSet::get_completed_buffer() {
+  BufferNode* node;
+  {
+    GlobalCounter::CriticalSection cs(Thread::current());
+    node = _list.pop();
+  }
+  if (node != NULL) {
+    // Got a buffer so decrement count and update flag appropriately.
+    decrement_count(&_count_and_process_flag);
+  }
+  return node;
+}
+
 #ifndef PRODUCT
 // Helpful for debugging
 
@@ -219,7 +305,7 @@
   tty->cr();
   tty->print_cr("SATB BUFFERS [%s]", msg);
 
-  BufferNode* nd = completed_buffers_head();
+  BufferNode* nd = _list.top();
   int i = 0;
   while (nd != NULL) {
     void** buf = BufferNode::make_buffer_from_node(nd);
@@ -248,6 +334,17 @@
 }
 #endif // PRODUCT
 
+void SATBMarkQueueSet::abandon_completed_buffers() {
+  Atomic::store(size_t(0), &_count_and_process_flag);
+  BufferNode* buffers_to_delete = _list.pop_all();
+  while (buffers_to_delete != NULL) {
+    BufferNode* bn = buffers_to_delete;
+    buffers_to_delete = bn->next();
+    bn->set_next(NULL);
+    deallocate_buffer(bn);
+  }
+}
+
 void SATBMarkQueueSet::abandon_partial_marking() {
   assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
   abandon_completed_buffers();
--- a/src/hotspot/share/gc/shared/satbMarkQueue.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/shared/satbMarkQueue.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -27,6 +27,7 @@
 
 #include "gc/shared/ptrQueue.hpp"
 #include "memory/allocation.hpp"
+#include "memory/padded.hpp"
 
 class Thread;
 class Monitor;
@@ -93,7 +94,17 @@
 };
 
 class SATBMarkQueueSet: public PtrQueueSet {
+
+  DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, 0);
+  PaddedEnd<BufferNode::Stack> _list;
+  volatile size_t _count_and_process_flag;
+  // These are rarely (if ever) changed, so same cache line as count.
+  size_t _process_completed_buffers_threshold;
   size_t _buffer_enqueue_threshold;
+  DEFINE_PAD_MINUS_SIZE(2, DEFAULT_CACHE_LINE_SIZE, 3 * sizeof(size_t));
+
+  BufferNode* get_completed_buffer();
+  void abandon_completed_buffers();
 
 #ifdef ASSERT
   void dump_active_states(bool expected_active);
@@ -102,15 +113,14 @@
 
 protected:
   SATBMarkQueueSet();
-  ~SATBMarkQueueSet() {}
+  ~SATBMarkQueueSet();
 
   template<typename Filter>
   void apply_filter(Filter filter, SATBMarkQueue* queue) {
     queue->apply_filter(filter);
   }
 
-  void initialize(Monitor* cbl_mon,
-                  BufferNode::Allocator* allocator,
+  void initialize(BufferNode::Allocator* allocator,
                   size_t process_completed_buffers_threshold,
                   uint buffer_enqueue_threshold_percentage);
 
@@ -132,6 +142,19 @@
   // buffer; the leading entries may be excluded due to filtering.
   bool apply_closure_to_completed_buffer(SATBBufferClosure* cl);
 
+  virtual void enqueue_completed_buffer(BufferNode* node);
+
+  // The number of buffers in the list.  Racy and not updated atomically
+  // with the set of completed buffers.
+  size_t completed_buffers_num() const {
+    return _count_and_process_flag >> 1;
+  }
+
+  // Return true if completed buffers should be processed.
+  bool process_completed_buffers() const {
+    return (_count_and_process_flag & 1) != 0;
+  }
+
 #ifndef PRODUCT
   // Helpful for debugging
   void print_all(const char* msg);
--- a/src/hotspot/share/gc/shared/workerDataArray.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/shared/workerDataArray.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -34,7 +34,7 @@
 class WorkerDataArray  : public CHeapObj<mtGC> {
   friend class WDAPrinter;
 public:
-  static const uint MaxThreadWorkItems = 5;
+  static const uint MaxThreadWorkItems = 6;
 private:
   T*          _data;
   uint        _length;
--- a/src/hotspot/share/gc/shared/workerDataArray.inline.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/shared/workerDataArray.inline.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -101,7 +101,7 @@
 template <typename T>
 void WorkerDataArray<T>::add(uint worker_i, T value) {
   assert(worker_i < _length, "Worker %d is greater than max: %d", worker_i, _length);
-  assert(_data[worker_i] != uninitialized(), "No data to add to for worker %d", worker_i);
+  assert(_data[worker_i] != uninitialized(), "No data to add to %s for worker %d", _title, worker_i);
   _data[worker_i] += value;
 }
 
--- a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -31,6 +31,7 @@
 #include "gc/shared/gcTimer.hpp"
 #include "gc/shared/referenceProcessor.hpp"
 #include "gc/shared/referenceProcessorPhaseTimes.hpp"
+#include "gc/shared/strongRootsScope.hpp"
 
 #include "gc/shenandoah/shenandoahBarrierSet.inline.hpp"
 #include "gc/shenandoah/shenandoahClosures.inline.hpp"
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -348,7 +348,6 @@
   // The call below uses stuff (the SATB* things) that are in G1, but probably
   // belong into a shared location.
   ShenandoahBarrierSet::satb_mark_queue_set().initialize(this,
-                                                         SATB_Q_CBL_mon,
                                                          20 /* G1SATBProcessCompletedThreshold */,
                                                          60 /* G1SATBBufferEnqueueingThresholdPercent */);
 
@@ -1513,7 +1512,9 @@
       // From here on, we need to update references.
       set_has_forwarded_objects(true);
 
-      evacuate_and_update_roots();
+      if (!is_degenerated_gc_in_progress()) {
+        evacuate_and_update_roots();
+      }
 
       if (ShenandoahPacing) {
         pacer()->setup_for_evac();
@@ -1521,7 +1522,9 @@
 
       if (ShenandoahVerify) {
         if (ShenandoahConcurrentRoots::should_do_concurrent_roots()) {
-          verifier()->verify_roots_no_forwarded_except(ShenandoahRootVerifier::JNIHandleRoots);
+          ShenandoahRootVerifier::RootTypes types = ShenandoahRootVerifier::combine(ShenandoahRootVerifier::JNIHandleRoots, ShenandoahRootVerifier::WeakRoots);
+          types = ShenandoahRootVerifier::combine(types, ShenandoahRootVerifier::CLDGRoots);
+          verifier()->verify_roots_no_forwarded_except(types);
         } else {
           verifier()->verify_roots_no_forwarded();
         }
@@ -1588,6 +1591,8 @@
 class ShenandoahConcurrentRootsEvacUpdateTask : public AbstractGangTask {
 private:
   ShenandoahJNIHandleRoots<true /*concurrent*/> _jni_roots;
+  ShenandoahWeakRoots<true /*concurrent*/>      _weak_roots;
+  ShenandoahClassLoaderDataRoots<true /*concurrent*/, false /*single threaded*/> _cld_roots;
 
 public:
   ShenandoahConcurrentRootsEvacUpdateTask() :
@@ -1597,7 +1602,11 @@
   void work(uint worker_id) {
     ShenandoahEvacOOMScope oom;
     ShenandoahEvacuateUpdateRootsClosure cl;
+    CLDToOopClosure clds(&cl, ClassLoaderData::_claim_strong);
+
     _jni_roots.oops_do<ShenandoahEvacuateUpdateRootsClosure>(&cl);
+    _cld_roots.cld_do(&clds);
+    _weak_roots.oops_do<ShenandoahEvacuateUpdateRootsClosure>(&cl);
   }
 };
 
--- a/src/hotspot/share/gc/shenandoah/shenandoahMarkCompact.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/shenandoah/shenandoahMarkCompact.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -175,8 +175,6 @@
     _preserved_marks->restore(&exec);
     BiasedLocking::restore_marks();
     _preserved_marks->reclaim();
-
-    JvmtiExport::gc_epilogue();
   }
 
   // Resize metaspace
--- a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -27,16 +27,13 @@
 #include "classfile/stringTable.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "code/codeCache.hpp"
-#include "gc/shenandoah/shenandoahClosures.inline.hpp"
 #include "gc/shenandoah/shenandoahRootProcessor.inline.hpp"
 #include "gc/shenandoah/shenandoahHeap.hpp"
-#include "gc/shenandoah/shenandoahHeuristics.hpp"
 #include "gc/shenandoah/shenandoahPhaseTimings.hpp"
 #include "gc/shenandoah/shenandoahStringDedup.hpp"
 #include "gc/shenandoah/shenandoahTimingTracker.hpp"
 #include "gc/shenandoah/shenandoahVMOperations.hpp"
-#include "gc/shared/weakProcessor.inline.hpp"
-#include "memory/allocation.inline.hpp"
+#include "jfr/jfr.hpp"
 #include "memory/iterator.hpp"
 #include "memory/resourceArea.hpp"
 #include "memory/universe.hpp"
@@ -71,6 +68,40 @@
   _jvmti_root.oops_do(cl, worker_id);
 }
 
+ShenandoahWeakSerialRoot::ShenandoahWeakSerialRoot(ShenandoahWeakSerialRoot::WeakOopsDo weak_oops_do, ShenandoahPhaseTimings::GCParPhases phase) :
+  _weak_oops_do(weak_oops_do), _phase(phase) {
+}
+
+void ShenandoahWeakSerialRoot::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, uint worker_id) {
+  if (_claimed.try_set()) {
+    ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
+    ShenandoahWorkerTimingsTracker timer(worker_times, _phase, worker_id);
+    _weak_oops_do(is_alive, keep_alive);
+  }
+}
+
+#if INCLUDE_JVMTI
+ShenandoahJVMTIWeakRoot::ShenandoahJVMTIWeakRoot() :
+  ShenandoahWeakSerialRoot(&JvmtiExport::weak_oops_do, ShenandoahPhaseTimings::JVMTIWeakRoots) {
+}
+#endif // INCLUDE_JVMTI
+
+#if INCLUDE_JFR
+ShenandoahJFRWeakRoot::ShenandoahJFRWeakRoot() :
+  ShenandoahWeakSerialRoot(&Jfr::weak_oops_do, ShenandoahPhaseTimings::JFRWeakRoots) {
+}
+#endif // INCLUDE_JFR
+
+void ShenandoahSerialWeakRoots::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, uint worker_id) {
+  JVMTI_ONLY(_jvmti_weak_roots.weak_oops_do(is_alive, keep_alive, worker_id);)
+  JFR_ONLY(_jfr_weak_roots.weak_oops_do(is_alive, keep_alive, worker_id);)
+}
+
+void ShenandoahSerialWeakRoots::weak_oops_do(OopClosure* cl, uint worker_id) {
+  AlwaysTrueClosure always_true;
+  weak_oops_do(&always_true, cl, worker_id);
+}
+
 ShenandoahThreadRoots::ShenandoahThreadRoots(bool is_par) : _is_par(is_par) {
   Threads::change_thread_claim_token();
 }
@@ -93,17 +124,6 @@
   Threads::assert_all_threads_claimed();
 }
 
-ShenandoahWeakRoots::ShenandoahWeakRoots(uint n_workers) :
-  _process_timings(n_workers),
-  _task(&_process_timings, n_workers) {
-}
-
-ShenandoahWeakRoots::~ShenandoahWeakRoots() {
-  ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
-  ShenandoahTimingConverter::weak_processing_timing_to_shenandoah_timing(&_process_timings,
-                                                                         worker_times);
-}
-
 ShenandoahStringDedupRoots::ShenandoahStringDedupRoots() {
   if (ShenandoahStringDedup::is_enabled()) {
     StringDedup::gc_prologue(false);
@@ -137,39 +157,37 @@
 ShenandoahRootEvacuator::ShenandoahRootEvacuator(uint n_workers, ShenandoahPhaseTimings::Phase phase, bool include_concurrent_roots) :
   ShenandoahRootProcessor(phase),
   _thread_roots(n_workers > 1),
-  _weak_roots(n_workers),
   _include_concurrent_roots(include_concurrent_roots) {
 }
 
 void ShenandoahRootEvacuator::roots_do(uint worker_id, OopClosure* oops) {
   MarkingCodeBlobClosure blobsCl(oops, CodeBlobToOopClosure::FixRelocations);
-  CLDToOopClosure clds(oops, ClassLoaderData::_claim_strong);
   AlwaysTrueClosure always_true;
 
   _serial_roots.oops_do(oops, worker_id);
+  _serial_weak_roots.weak_oops_do(oops, worker_id);
   if (_include_concurrent_roots) {
+    CLDToOopClosure clds(oops, ClassLoaderData::_claim_strong);
     _jni_roots.oops_do<OopClosure>(oops, worker_id);
+    _cld_roots.cld_do(&clds, worker_id);
+    _weak_roots.oops_do<OopClosure>(oops, worker_id);
   }
 
   _thread_roots.oops_do(oops, NULL, worker_id);
-  _cld_roots.cld_do(&clds, worker_id);
   _code_roots.code_blobs_do(&blobsCl, worker_id);
 
-  _weak_roots.oops_do<AlwaysTrueClosure, OopClosure>(&always_true, oops, worker_id);
   _dedup_roots.oops_do(&always_true, oops, worker_id);
 }
 
 ShenandoahRootUpdater::ShenandoahRootUpdater(uint n_workers, ShenandoahPhaseTimings::Phase phase, bool update_code_cache) :
   ShenandoahRootProcessor(phase),
   _thread_roots(n_workers > 1),
-  _weak_roots(n_workers),
   _update_code_cache(update_code_cache) {
 }
 
 ShenandoahRootAdjuster::ShenandoahRootAdjuster(uint n_workers, ShenandoahPhaseTimings::Phase phase) :
   ShenandoahRootProcessor(phase),
-  _thread_roots(n_workers > 1),
-  _weak_roots(n_workers) {
+  _thread_roots(n_workers > 1) {
   assert(ShenandoahHeap::heap()->is_full_gc_in_progress(), "Full GC only");
 }
 
@@ -185,7 +203,8 @@
   _cld_roots.cld_do(&adjust_cld_closure, worker_id);
   _code_roots.code_blobs_do(&adjust_code_closure, worker_id);
 
-  _weak_roots.oops_do<AlwaysTrueClosure, OopClosure>(&always_true, oops, worker_id);
+  _serial_weak_roots.weak_oops_do(oops, worker_id);
+  _weak_roots.oops_do<OopClosure>(oops, worker_id);
   _dedup_roots.oops_do(&always_true, oops, worker_id);
 }
 
--- a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -29,11 +29,7 @@
 #include "gc/shenandoah/shenandoahCodeRoots.hpp"
 #include "gc/shenandoah/shenandoahHeap.hpp"
 #include "gc/shenandoah/shenandoahPhaseTimings.hpp"
-#include "gc/shared/strongRootsScope.hpp"
-#include "gc/shared/weakProcessor.hpp"
-#include "gc/shared/weakProcessorPhaseTimes.hpp"
-#include "gc/shared/workgroup.hpp"
-#include "memory/allocation.hpp"
+#include "gc/shenandoah/shenandoahSharedVariables.hpp"
 #include "memory/iterator.hpp"
 
 class ShenandoahSerialRoot {
@@ -61,10 +57,102 @@
   void oops_do(OopClosure* cl, uint worker_id);
 };
 
+class ShenandoahWeakSerialRoot {
+  typedef void (*WeakOopsDo)(BoolObjectClosure*, OopClosure*);
+private:
+  ShenandoahSharedFlag                      _claimed;
+  const WeakOopsDo                          _weak_oops_do;
+  const ShenandoahPhaseTimings::GCParPhases _phase;
+
+public:
+  ShenandoahWeakSerialRoot(WeakOopsDo oops_do, ShenandoahPhaseTimings::GCParPhases);
+  void weak_oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, uint worker_id);
+};
+
+#if INCLUDE_JVMTI
+class ShenandoahJVMTIWeakRoot : public ShenandoahWeakSerialRoot {
+public:
+  ShenandoahJVMTIWeakRoot();
+};
+#endif // INCLUDE_JVMTI
+
+#if INCLUDE_JFR
+class ShenandoahJFRWeakRoot : public ShenandoahWeakSerialRoot {
+public:
+  ShenandoahJFRWeakRoot();
+};
+#endif // INCLUDE_JFR
+
+class ShenandoahSerialWeakRoots {
+private:
+  JVMTI_ONLY(ShenandoahJVMTIWeakRoot _jvmti_weak_roots;)
+  JFR_ONLY(ShenandoahJFRWeakRoot     _jfr_weak_roots;)
+public:
+  void weak_oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, uint worker_id);
+  void weak_oops_do(OopClosure* cl, uint worker_id);
+};
+
+template <bool CONCURRENT>
+class ShenandoahWeakRoot {
+private:
+  OopStorage::ParState<CONCURRENT, false /* is_const */> _itr;
+  const ShenandoahPhaseTimings::GCParPhases _phase;
+public:
+  ShenandoahWeakRoot(OopStorage* storage, ShenandoahPhaseTimings::GCParPhases phase);
+
+  template <typename Closure>
+  void oops_do(Closure* cl, uint worker_id);
+};
+
+template <>
+class ShenandoahWeakRoot<false /*concurrent*/> {
+private:
+  OopStorage::ParState<false /*concurrent*/, false /*is_const*/> _itr;
+  const ShenandoahPhaseTimings::GCParPhases _phase;
+
+public:
+  ShenandoahWeakRoot(OopStorage* storage, ShenandoahPhaseTimings::GCParPhases phase);
+
+  template <typename IsAliveClosure, typename KeepAliveClosure>
+  void weak_oops_do(IsAliveClosure* is_alive, KeepAliveClosure* keep_alive, uint worker_id);
+};
+
+template <bool CONCURRENT>
+class ShenandoahWeakRoots {
+private:
+  ShenandoahWeakRoot<CONCURRENT>  _jni_roots;
+  ShenandoahWeakRoot<CONCURRENT>  _string_table_roots;
+  ShenandoahWeakRoot<CONCURRENT>  _resolved_method_table_roots;
+  ShenandoahWeakRoot<CONCURRENT>  _vm_roots;
+
+public:
+  ShenandoahWeakRoots();
+
+  template <typename Closure>
+  void oops_do(Closure* cl, uint worker_id = 0);
+};
+
+template <>
+class ShenandoahWeakRoots<false /*concurrent */> {
+private:
+  ShenandoahWeakRoot<false /*concurrent*/>  _jni_roots;
+  ShenandoahWeakRoot<false /*concurrent*/>  _string_table_roots;
+  ShenandoahWeakRoot<false /*concurrent*/>  _resolved_method_table_roots;
+  ShenandoahWeakRoot<false /*concurrent*/>  _vm_roots;
+public:
+  ShenandoahWeakRoots();
+
+  template <typename Closure>
+  void oops_do(Closure* cl, uint worker_id = 0);
+
+  template <typename IsAliveClosure, typename KeepAliveClosure>
+  void weak_oops_do(IsAliveClosure* is_alive, KeepAliveClosure* keep_alive, uint worker_id);
+};
+
 template <bool CONCURRENT>
 class ShenandoahJNIHandleRoots {
 private:
-  OopStorage::ParState<CONCURRENT, false /* is_const */> _itr;
+  OopStorage::ParState<CONCURRENT, false /*is_const*/> _itr;
 public:
   ShenandoahJNIHandleRoots();
 
@@ -83,18 +171,6 @@
   void threads_do(ThreadClosure* tc, uint worker_id);
 };
 
-class ShenandoahWeakRoots {
-private:
-  WeakProcessorPhaseTimes _process_timings;
-  WeakProcessor::Task     _task;
-public:
-  ShenandoahWeakRoots(uint n_workers);
-  ~ShenandoahWeakRoots();
-
-  template <typename IsAlive, typename KeepAlive>
-  void oops_do(IsAlive* is_alive, KeepAlive* keep_alive, uint worker_id);
-};
-
 class ShenandoahStringDedupRoots {
 public:
   ShenandoahStringDedupRoots();
@@ -114,13 +190,14 @@
   void code_blobs_do(CodeBlobClosure* blob_cl, uint worker_id);
 };
 
-template <bool SINGLE_THREADED>
+template <bool CONCURRENT, bool SINGLE_THREADED>
 class ShenandoahClassLoaderDataRoots {
 public:
   ShenandoahClassLoaderDataRoots();
+  ~ShenandoahClassLoaderDataRoots();
 
-  void always_strong_cld_do(CLDClosure* clds, uint worker_id);
-  void cld_do(CLDClosure* clds, uint worker_id);
+  void always_strong_cld_do(CLDClosure* clds, uint worker_id = 0);
+  void cld_do(CLDClosure* clds, uint worker_id = 0);
 };
 
 class ShenandoahRootProcessor : public StackObj {
@@ -141,7 +218,8 @@
   ShenandoahThreadRoots                                     _thread_roots;
   ShenandoahCodeCacheRoots<ITR>                             _code_roots;
   ShenandoahJNIHandleRoots<false /*concurrent*/ >           _jni_roots;
-  ShenandoahClassLoaderDataRoots<false /*single threaded*/> _cld_roots;
+  ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/>
+                                                            _cld_roots;
 public:
   ShenandoahRootScanner(uint n_workers, ShenandoahPhaseTimings::Phase phase);
 
@@ -166,7 +244,8 @@
   ShenandoahSerialRoots                                    _serial_roots;
   ShenandoahThreadRoots                                    _thread_roots;
   ShenandoahJNIHandleRoots<false /*concurrent*/>           _jni_roots;
-  ShenandoahClassLoaderDataRoots<true /*single threaded*/> _cld_roots;
+  ShenandoahClassLoaderDataRoots<false /*concurrent*/, true /*single threaded*/>
+                                                           _cld_roots;
   ShenandoahCodeCacheRoots<ShenandoahAllCodeRootsIterator> _code_roots;
 
 public:
@@ -181,9 +260,11 @@
 private:
   ShenandoahSerialRoots                                     _serial_roots;
   ShenandoahJNIHandleRoots<false /*concurrent*/>            _jni_roots;
-  ShenandoahClassLoaderDataRoots<false /*single threaded*/> _cld_roots;
+  ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/>
+                                                            _cld_roots;
   ShenandoahThreadRoots                                     _thread_roots;
-  ShenandoahWeakRoots                                       _weak_roots;
+  ShenandoahSerialWeakRoots                                 _serial_weak_roots;
+  ShenandoahWeakRoots<false /*concurrent*/>                 _weak_roots;
   ShenandoahStringDedupRoots                                _dedup_roots;
   ShenandoahCodeCacheRoots<ShenandoahCsetCodeRootsIterator> _code_roots;
   bool                                                      _include_concurrent_roots;
@@ -199,9 +280,11 @@
 private:
   ShenandoahSerialRoots                                     _serial_roots;
   ShenandoahJNIHandleRoots<false /*concurrent*/>            _jni_roots;
-  ShenandoahClassLoaderDataRoots<false /*single threaded*/> _cld_roots;
+  ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/>
+                                                            _cld_roots;
   ShenandoahThreadRoots                                     _thread_roots;
-  ShenandoahWeakRoots                                       _weak_roots;
+  ShenandoahSerialWeakRoots                                 _serial_weak_roots;
+  ShenandoahWeakRoots<false /*concurrent*/>                 _weak_roots;
   ShenandoahStringDedupRoots                                _dedup_roots;
   ShenandoahCodeCacheRoots<ShenandoahCsetCodeRootsIterator> _code_roots;
   const bool                                                _update_code_cache;
@@ -218,9 +301,11 @@
 private:
   ShenandoahSerialRoots                                     _serial_roots;
   ShenandoahJNIHandleRoots<false /*concurrent*/>            _jni_roots;
-  ShenandoahClassLoaderDataRoots<false /*single threaded*/> _cld_roots;
+  ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/>
+                                                            _cld_roots;
   ShenandoahThreadRoots                                     _thread_roots;
-  ShenandoahWeakRoots                                       _weak_roots;
+  ShenandoahSerialWeakRoots                                 _serial_weak_roots;
+  ShenandoahWeakRoots<false /*concurrent*/>                 _weak_roots;
   ShenandoahStringDedupRoots                                _dedup_roots;
   ShenandoahCodeCacheRoots<ShenandoahAllCodeRootsIterator>  _code_roots;
 
--- a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -25,15 +25,84 @@
 #define SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_INLINE_HPP
 
 #include "classfile/classLoaderDataGraph.hpp"
+#include "classfile/stringTable.hpp"
+#include "classfile/systemDictionary.hpp"
 #include "gc/shared/oopStorageParState.inline.hpp"
 #include "gc/shenandoah/shenandoahHeuristics.hpp"
 #include "gc/shenandoah/shenandoahRootProcessor.hpp"
 #include "gc/shenandoah/shenandoahTimingTracker.hpp"
 #include "gc/shenandoah/shenandoahUtils.hpp"
 #include "memory/resourceArea.hpp"
+#include "prims/resolvedMethodTable.hpp"
 #include "runtime/safepoint.hpp"
 
 template <bool CONCURRENT>
+inline ShenandoahWeakRoot<CONCURRENT>::ShenandoahWeakRoot(OopStorage* storage, ShenandoahPhaseTimings::GCParPhases phase) :
+  _itr(storage), _phase(phase) {
+}
+
+template <bool CONCURRENT>
+template <typename Closure>
+inline void ShenandoahWeakRoot<CONCURRENT>::oops_do(Closure* cl, uint worker_id) {
+  if (CONCURRENT) {
+    _itr.oops_do(cl);
+  } else {
+    ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
+    ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::ThreadRoots, worker_id);
+    _itr.oops_do(cl);
+  }
+}
+
+inline ShenandoahWeakRoot<false>::ShenandoahWeakRoot(OopStorage* storage, ShenandoahPhaseTimings::GCParPhases phase) :
+  _itr(storage), _phase(phase) {
+}
+
+template <typename IsAliveClosure, typename KeepAliveClosure>
+void ShenandoahWeakRoot<false /* concurrent */>::weak_oops_do(IsAliveClosure* is_alive, KeepAliveClosure* keep_alive, uint worker_id) {
+  ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
+  ShenandoahWorkerTimingsTracker timer(worker_times, _phase, worker_id);
+  _itr.weak_oops_do(is_alive, keep_alive);
+}
+
+template <bool CONCURRENT>
+ShenandoahWeakRoots<CONCURRENT>::ShenandoahWeakRoots() :
+  _jni_roots(JNIHandles::weak_global_handles(), ShenandoahPhaseTimings::JNIWeakRoots),
+  _string_table_roots(StringTable::weak_storage(), ShenandoahPhaseTimings::StringTableRoots),
+  _resolved_method_table_roots(ResolvedMethodTable::weak_storage(), ShenandoahPhaseTimings::ResolvedMethodTableRoots),
+  _vm_roots(SystemDictionary::vm_weak_oop_storage(), ShenandoahPhaseTimings::VMWeakRoots) {
+}
+
+template <bool CONCURRENT>
+template <typename Closure>
+void ShenandoahWeakRoots<CONCURRENT>::oops_do(Closure* cl, uint worker_id) {
+  _jni_roots.oops_do(cl, worker_id);
+  _string_table_roots.oops_do(cl, worker_id);
+  _resolved_method_table_roots.oops_do(cl, worker_id);
+  _vm_roots.oops_do(cl, worker_id);
+}
+
+inline ShenandoahWeakRoots<false /* concurrent */>::ShenandoahWeakRoots() :
+  _jni_roots(JNIHandles::weak_global_handles(), ShenandoahPhaseTimings::JNIWeakRoots),
+  _string_table_roots(StringTable::weak_storage(), ShenandoahPhaseTimings::StringTableRoots),
+  _resolved_method_table_roots(ResolvedMethodTable::weak_storage(), ShenandoahPhaseTimings::ResolvedMethodTableRoots),
+  _vm_roots(SystemDictionary::vm_weak_oop_storage(), ShenandoahPhaseTimings::VMWeakRoots) {
+}
+
+template <typename IsAliveClosure, typename KeepAliveClosure>
+void ShenandoahWeakRoots<false /* concurrent*/>::weak_oops_do(IsAliveClosure* is_alive, KeepAliveClosure* keep_alive, uint worker_id) {
+  _jni_roots.weak_oops_do(is_alive, keep_alive, worker_id);
+  _string_table_roots.weak_oops_do(is_alive, keep_alive, worker_id);
+  _resolved_method_table_roots.weak_oops_do(is_alive, keep_alive, worker_id);
+  _vm_roots.weak_oops_do(is_alive, keep_alive, worker_id);
+}
+
+template <typename Closure>
+void ShenandoahWeakRoots<false /* concurrent */>::oops_do(Closure* cl, uint worker_id) {
+  AlwaysTrueClosure always_true;
+  weak_oops_do<AlwaysTrueClosure, Closure>(&always_true, cl, worker_id);
+}
+
+template <bool CONCURRENT>
 ShenandoahJNIHandleRoots<CONCURRENT>::ShenandoahJNIHandleRoots() :
   _itr(JNIHandles::global_handles()) {
 }
@@ -50,24 +119,32 @@
   }
 }
 
-template <typename IsAlive, typename KeepAlive>
-void ShenandoahWeakRoots::oops_do(IsAlive* is_alive, KeepAlive* keep_alive, uint worker_id) {
-  _task.work<IsAlive, KeepAlive>(worker_id, is_alive, keep_alive);
-}
-
-template <bool SINGLE_THREADED>
-ShenandoahClassLoaderDataRoots<SINGLE_THREADED>::ShenandoahClassLoaderDataRoots() {
+template <bool CONCURRENT, bool SINGLE_THREADED>
+ShenandoahClassLoaderDataRoots<CONCURRENT, SINGLE_THREADED>::ShenandoahClassLoaderDataRoots() {
   if (!SINGLE_THREADED) {
     ClassLoaderDataGraph::clear_claimed_marks();
   }
+  if (CONCURRENT) {
+    ClassLoaderDataGraph_lock->lock();
+  }
 }
 
-template <bool SINGLE_THREADED>
-void ShenandoahClassLoaderDataRoots<SINGLE_THREADED>::always_strong_cld_do(CLDClosure* clds, uint worker_id) {
+template <bool CONCURRENT, bool SINGLE_THREADED>
+ShenandoahClassLoaderDataRoots<CONCURRENT, SINGLE_THREADED>::~ShenandoahClassLoaderDataRoots() {
+  if (CONCURRENT) {
+    ClassLoaderDataGraph_lock->unlock();
+  }
+}
+
+
+template <bool CONCURRENT, bool SINGLE_THREADED>
+void ShenandoahClassLoaderDataRoots<CONCURRENT, SINGLE_THREADED>::always_strong_cld_do(CLDClosure* clds, uint worker_id) {
   if (SINGLE_THREADED) {
     assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint");
     assert(Thread::current()->is_VM_thread(), "Single threaded CLDG iteration can only be done by VM thread");
     ClassLoaderDataGraph::always_strong_cld_do(clds);
+  } else if (CONCURRENT) {
+     ClassLoaderDataGraph::always_strong_cld_do(clds);
   } else {
    ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
    ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::CLDGRoots, worker_id);
@@ -75,13 +152,15 @@
   }
 }
 
-template <bool SINGLE_THREADED>
-void ShenandoahClassLoaderDataRoots<SINGLE_THREADED>::cld_do(CLDClosure* clds, uint worker_id) {
+template <bool CONCURRENT, bool SINGLE_THREADED>
+void ShenandoahClassLoaderDataRoots<CONCURRENT, SINGLE_THREADED>::cld_do(CLDClosure* clds, uint worker_id) {
   if (SINGLE_THREADED) {
     assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint");
     assert(Thread::current()->is_VM_thread(), "Single threaded CLDG iteration can only be done by VM thread");
     ClassLoaderDataGraph::cld_do(clds);
-  } else {
+  } else if (CONCURRENT) {
+    ClassLoaderDataGraph::cld_do(clds);
+  }  else {
     ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
     ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::CLDGRoots, worker_id);
     ClassLoaderDataGraph::cld_do(clds);
@@ -197,7 +276,8 @@
     _code_roots.code_blobs_do(&update_blobs, worker_id);
   }
 
-  _weak_roots.oops_do<IsAlive, KeepAlive>(is_alive, keep_alive, worker_id);
+  _serial_weak_roots.weak_oops_do(is_alive, keep_alive, worker_id);
+  _weak_roots.weak_oops_do(is_alive, keep_alive, worker_id);
   _dedup_roots.oops_do(is_alive, keep_alive, worker_id);
 }
 
--- a/src/hotspot/share/gc/shenandoah/shenandoahRootVerifier.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/shenandoah/shenandoahRootVerifier.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -54,6 +54,10 @@
   return (_types & type) != 0;
 }
 
+ShenandoahRootVerifier::RootTypes ShenandoahRootVerifier::combine(RootTypes t1, RootTypes t2) {
+  return static_cast<ShenandoahRootVerifier::RootTypes>(static_cast<uint>(t1) | static_cast<uint>(t2));
+}
+
 void ShenandoahRootVerifier::oops_do(OopClosure* oops) {
   CodeBlobToOopClosure blobs(oops, !CodeBlobToOopClosure::FixRelocations);
   if (verify(CodeRoots)) {
--- a/src/hotspot/share/gc/shenandoah/shenandoahRootVerifier.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/shenandoah/shenandoahRootVerifier.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -52,6 +52,8 @@
   // Used to seed ShenandoahVerifier, do not honor root type filter
   void roots_do(OopClosure* cl);
   void strong_roots_do(OopClosure* cl);
+
+  static RootTypes combine(RootTypes t1, RootTypes t2);
 private:
   bool verify(RootTypes type) const;
 };
--- a/src/hotspot/share/gc/shenandoah/shenandoahSATBMarkQueueSet.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/shenandoah/shenandoahSATBMarkQueueSet.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -33,11 +33,9 @@
 {}
 
 void ShenandoahSATBMarkQueueSet::initialize(ShenandoahHeap* const heap,
-                                            Monitor* cbl_mon,
                                             int process_completed_threshold,
                                             uint buffer_enqueue_threshold_percentage) {
-  SATBMarkQueueSet::initialize(cbl_mon,
-                               &_satb_mark_queue_buffer_allocator,
+  SATBMarkQueueSet::initialize(&_satb_mark_queue_buffer_allocator,
                                process_completed_threshold,
                                buffer_enqueue_threshold_percentage);
   _heap = heap;
--- a/src/hotspot/share/gc/shenandoah/shenandoahSATBMarkQueueSet.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/shenandoah/shenandoahSATBMarkQueueSet.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -44,7 +44,6 @@
   ShenandoahSATBMarkQueueSet();
 
   void initialize(ShenandoahHeap* const heap,
-                  Monitor* cbl_mon,
                   int process_completed_threshold,
                   uint buffer_enqueue_threshold_percentage);
 
--- a/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -364,10 +364,6 @@
   diagnostic(bool, ShenandoahLoadRefBarrier, true,                          \
           "Turn on/off load-reference barriers in Shenandoah")              \
                                                                             \
-  diagnostic(bool, ShenandoahStoreCheck, false,                             \
-          "Emit additional code that checks objects are written to only"    \
-          " in to-space")                                                   \
-                                                                            \
   experimental(bool, ShenandoahConcurrentScanCodeRoots, true,               \
           "Scan code roots concurrently, instead of during a pause")        \
                                                                             \
--- a/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -522,7 +522,7 @@
   Node* in_val = barrier->in(LoadBarrierNode::Oop);
   Node* in_adr = barrier->in(LoadBarrierNode::Address);
 
-  Node* out_ctrl = barrier->proj_out_or_null(LoadBarrierNode::Control);
+  Node* out_ctrl = barrier->proj_out(LoadBarrierNode::Control);
   Node* out_res = barrier->proj_out(LoadBarrierNode::Oop);
 
   assert(barrier->in(LoadBarrierNode::Oop) != NULL, "oop to loadbarrier node cannot be null");
@@ -552,9 +552,8 @@
   result_phi->set_req(1, new_loadp);
   result_phi->set_req(2, barrier->in(LoadBarrierNode::Oop));
 
-  if (out_ctrl != NULL) {
-    igvn.replace_node(out_ctrl, result_region);
-  }
+
+  igvn.replace_node(out_ctrl, result_region);
   igvn.replace_node(out_res, result_phi);
 
   assert(barrier->outcnt() == 0,"LoadBarrier macro node has non-null outputs after expansion!");
@@ -640,6 +639,22 @@
   return c;
 }
 
+Node* ZBarrierSetC2::step_over_gc_barrier_ctrl(Node* c) const {
+  Node* node = c;
+
+  // 1. This step follows potential ctrl projections of a load barrier before expansion
+  if (node->is_Proj()) {
+    node = node->in(0);
+  }
+
+  // 2. This step checks for unexpanded load barriers
+  if (node->is_LoadBarrier()) {
+    return node->in(LoadBarrierNode::Control);
+  }
+
+  return c;
+}
+
 bool ZBarrierSetC2::array_copy_requires_gc_barriers(bool tightly_coupled_alloc, BasicType type, bool is_clone, ArrayCopyPhase phase) const {
   return type == T_OBJECT || type == T_ARRAY;
 }
--- a/src/hotspot/share/gc/z/c2/zBarrierSetC2.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/z/c2/zBarrierSetC2.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -182,6 +182,7 @@
   virtual bool has_load_barriers() const { return true; }
   virtual bool is_gc_barrier_node(Node* node) const;
   virtual Node* step_over_gc_barrier(Node* c) const;
+  virtual Node* step_over_gc_barrier_ctrl(Node* c) const;
 
   virtual void register_potential_barrier_node(Node* node) const;
   virtual void unregister_potential_barrier_node(Node* node) const;
--- a/src/hotspot/share/gc/z/zBarrierSetNMethod.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/z/zBarrierSetNMethod.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -45,7 +45,7 @@
     // We don't need to take the lock when unlinking nmethods from
     // the Method, because it is only concurrently unlinked by
     // the entry barrier, which acquires the per nmethod lock.
-    nm->unlink_from_method();
+    nm->unlink_from_method(false /* acquire_lock */);
 
     // We can end up calling nmethods that are unloading
     // since we clear compiled ICs lazily. Returning false
--- a/src/hotspot/share/gc/z/zNMethod.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/z/zNMethod.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -285,7 +285,7 @@
       // We don't need to take the lock when unlinking nmethods from
       // the Method, because it is only concurrently unlinked by
       // the entry barrier, which acquires the per nmethod lock.
-      nm->unlink_from_method();
+      nm->unlink_from_method(false /* acquire_lock */);
       return;
     }
 
--- a/src/hotspot/share/gc/z/zRootsIterator.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/gc/z/zRootsIterator.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -198,7 +198,6 @@
   } else {
     ZNMethod::oops_do_end();
   }
-  JvmtiExport::gc_epilogue();
 
   COMPILER2_PRESENT(DerivedPointerTable::update_pointers());
   Threads::assert_all_threads_claimed();
--- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -568,6 +568,33 @@
   return JVMCIENV->get_jobject(result);
 C2V_END
 
+C2V_VMENTRY_NULL(jobject, getArrayType, (JNIEnv* env, jobject, jobject jvmci_type))
+  if (jvmci_type == NULL) {
+    JVMCI_THROW_0(NullPointerException);
+  }
+
+  JVMCIObject jvmci_type_object = JVMCIENV->wrap(jvmci_type);
+  JVMCIKlassHandle array_klass(THREAD);
+  if (JVMCIENV->isa_HotSpotResolvedPrimitiveType(jvmci_type_object)) {
+    BasicType type = JVMCIENV->kindToBasicType(JVMCIENV->get_HotSpotResolvedPrimitiveType_kind(jvmci_type_object), JVMCI_CHECK_0);
+    if (type == T_VOID) {
+      return NULL;
+    }
+    array_klass = Universe::typeArrayKlassObj(type);
+    if (array_klass == NULL) {
+      JVMCI_THROW_MSG_NULL(InternalError, err_msg("No array klass for primitive type %s", type2name(type)));
+    }
+  } else {
+    Klass* klass = JVMCIENV->asKlass(jvmci_type);
+    if (klass == NULL) {
+      JVMCI_THROW_0(NullPointerException);
+    }
+    array_klass = klass->array_klass(CHECK_NULL);
+  }
+  JVMCIObject result = JVMCIENV->get_jvmci_type(array_klass, JVMCI_CHECK_NULL);
+  return JVMCIENV->get_jobject(result);
+C2V_END
+
 C2V_VMENTRY_NULL(jobject, lookupClass, (JNIEnv* env, jobject, jclass mirror))
   requireInHotSpot("lookupClass", JVMCI_CHECK_NULL);
   if (mirror == NULL) {
@@ -582,12 +609,6 @@
   return JVMCIENV->get_jobject(result);
 }
 
-C2V_VMENTRY_NULL(jobject, resolveConstantInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
-  constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
-  oop result = cp->resolve_constant_at(index, CHECK_NULL);
-  return JVMCIENV->get_jobject(JVMCIENV->get_object_constant(result));
-C2V_END
-
 C2V_VMENTRY_NULL(jobject, resolvePossiblyCachedConstantInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
   constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
   oop result = cp->resolve_possibly_cached_constant_at(index, CHECK_NULL);
@@ -2578,6 +2599,18 @@
   return FailedSpeculation::add_failed_speculation(NULL, (FailedSpeculation**)(address) failed_speculations_address, (address) speculation, speculation_len);
 }
 
+C2V_VMENTRY(void, callSystemExit, (JNIEnv* env, jobject, jint status))
+  JavaValue result(T_VOID);
+  JavaCallArguments jargs(1);
+  jargs.push_int(status);
+  JavaCalls::call_static(&result,
+                       SystemDictionary::System_klass(),
+                       vmSymbols::exit_method_name(),
+                       vmSymbols::int_void_signature(),
+                       &jargs,
+                       CHECK);
+}
+
 #define CC (char*)  /*cast a literal from (const char*)*/
 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(c2v_ ## f))
 
@@ -2624,6 +2657,7 @@
   {CC "hasNeverInlineDirective",                      CC "(" HS_RESOLVED_METHOD ")Z",                                                       FN_PTR(hasNeverInlineDirective)},
   {CC "shouldInlineMethod",                           CC "(" HS_RESOLVED_METHOD ")Z",                                                       FN_PTR(shouldInlineMethod)},
   {CC "lookupType",                                   CC "(" STRING HS_RESOLVED_KLASS "Z)" HS_RESOLVED_TYPE,                                FN_PTR(lookupType)},
+  {CC "getArrayType",                                 CC "(" HS_RESOLVED_TYPE ")" HS_RESOLVED_KLASS,                                        FN_PTR(getArrayType)},
   {CC "lookupClass",                                  CC "(" CLASS ")" HS_RESOLVED_TYPE,                                                    FN_PTR(lookupClass)},
   {CC "lookupNameInPool",                             CC "(" HS_CONSTANT_POOL "I)" STRING,                                                  FN_PTR(lookupNameInPool)},
   {CC "lookupNameAndTypeRefIndexInPool",              CC "(" HS_CONSTANT_POOL "I)I",                                                        FN_PTR(lookupNameAndTypeRefIndexInPool)},
@@ -2633,7 +2667,6 @@
   {CC "lookupAppendixInPool",                         CC "(" HS_CONSTANT_POOL "I)" OBJECTCONSTANT,                                          FN_PTR(lookupAppendixInPool)},
   {CC "lookupMethodInPool",                           CC "(" HS_CONSTANT_POOL "IB)" HS_RESOLVED_METHOD,                                     FN_PTR(lookupMethodInPool)},
   {CC "constantPoolRemapInstructionOperandFromCache", CC "(" HS_CONSTANT_POOL "I)I",                                                        FN_PTR(constantPoolRemapInstructionOperandFromCache)},
-  {CC "resolveConstantInPool",                        CC "(" HS_CONSTANT_POOL "I)" OBJECTCONSTANT,                                          FN_PTR(resolveConstantInPool)},
   {CC "resolvePossiblyCachedConstantInPool",          CC "(" HS_CONSTANT_POOL "I)" OBJECTCONSTANT,                                          FN_PTR(resolvePossiblyCachedConstantInPool)},
   {CC "resolveTypeInPool",                            CC "(" HS_CONSTANT_POOL "I)" HS_RESOLVED_KLASS,                                       FN_PTR(resolveTypeInPool)},
   {CC "resolveFieldInPool",                           CC "(" HS_CONSTANT_POOL "I" HS_RESOLVED_METHOD "B[I)" HS_RESOLVED_KLASS,              FN_PTR(resolveFieldInPool)},
@@ -2723,6 +2756,7 @@
   {CC "getFailedSpeculationsAddress",                 CC "(" HS_RESOLVED_METHOD ")J",                                                       FN_PTR(getFailedSpeculationsAddress)},
   {CC "releaseFailedSpeculations",                    CC "(J)V",                                                                            FN_PTR(releaseFailedSpeculations)},
   {CC "addFailedSpeculation",                         CC "(J[B)Z",                                                                          FN_PTR(addFailedSpeculation)},
+  {CC "callSystemExit",                               CC "(I)V",                                                                            FN_PTR(callSystemExit)},
 };
 
 int CompilerToVM::methods_count() {
--- a/src/hotspot/share/jvmci/jvmciEnv.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/jvmci/jvmciEnv.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -31,7 +31,6 @@
 #include "memory/universe.hpp"
 #include "oops/objArrayKlass.hpp"
 #include "oops/typeArrayOop.inline.hpp"
-#include "runtime/deoptimization.hpp"
 #include "runtime/jniHandles.inline.hpp"
 #include "runtime/javaCalls.hpp"
 #include "jvmci/jniAccessMark.inline.hpp"
@@ -1361,6 +1360,9 @@
     return Handle(THREAD, obj);
   } else if (isa_IndirectHotSpotObjectConstantImpl(constant)) {
     jlong object_handle = get_IndirectHotSpotObjectConstantImpl_objectHandle(constant);
+    if (object_handle == 0L) {
+      JVMCI_THROW_MSG_(NullPointerException, "Foreign object reference has been cleared", Handle());
+    }
     oop result = resolve_handle(object_handle);
     if (result == NULL) {
       JVMCI_THROW_MSG_(InternalError, "Constant was unexpectedly NULL", Handle());
@@ -1490,7 +1492,8 @@
     // Invalidating the HotSpotNmethod means we want the nmethod
     // to be deoptimized.
     nm->mark_for_deoptimization();
-    Deoptimization::deoptimize_all_marked();
+    VM_Deoptimize op;
+    VMThread::execute(&op);
   }
 
   // A HotSpotNmethod instance can only reference a single nmethod
--- a/src/hotspot/share/memory/filemap.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/memory/filemap.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -75,7 +75,7 @@
 // an archive file should stop the process.  Unrecoverable errors during
 // the reading of the archive file should stop the process.
 
-static void fail(const char *msg, va_list ap) {
+static void fail_exit(const char *msg, va_list ap) {
   // This occurs very early during initialization: tty is not initialized.
   jio_fprintf(defaultStream::error_stream(),
               "An error has occurred while processing the"
@@ -90,7 +90,7 @@
 void FileMapInfo::fail_stop(const char *msg, ...) {
         va_list ap;
   va_start(ap, msg);
-  fail(msg, ap);        // Never returns.
+  fail_exit(msg, ap);   // Never returns.
   va_end(ap);           // for completeness.
 }
 
@@ -118,7 +118,7 @@
     tty->print_cr("]");
   } else {
     if (RequireSharedSpaces) {
-      fail(msg, ap);
+      fail_exit(msg, ap);
     } else {
       if (log_is_enabled(Info, cds)) {
         ResourceMark rm;
@@ -252,13 +252,15 @@
   _base_archive_is_default = false;
 }
 
-void SharedClassPathEntry::init(const char* name, bool is_modules_image, TRAPS) {
+void SharedClassPathEntry::init(bool is_modules_image,
+                                ClassPathEntry* cpe, TRAPS) {
   assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "dump time only");
   _timestamp = 0;
   _filesize  = 0;
+  _from_class_path_attr = false;
 
   struct stat st;
-  if (os::stat(name, &st) == 0) {
+  if (os::stat(cpe->name(), &st) == 0) {
     if ((st.st_mode & S_IFMT) == S_IFDIR) {
       _type = dir_entry;
     } else {
@@ -268,6 +270,7 @@
       } else {
         _type = jar_entry;
         _timestamp = st.st_mtime;
+        _from_class_path_attr = cpe->from_class_path_attr();
       }
       _filesize = st.st_size;
     }
@@ -277,12 +280,12 @@
     //
     // If we can't access a jar file in the boot path, then we can't
     // make assumptions about where classes get loaded from.
-    FileMapInfo::fail_stop("Unable to open file %s.", name);
+    FileMapInfo::fail_stop("Unable to open file %s.", cpe->name());
   }
 
-  size_t len = strlen(name) + 1;
+  size_t len = strlen(cpe->name()) + 1;
   _name = MetadataFactory::new_array<char>(ClassLoaderData::the_null_class_loader_data(), (int)len, THREAD);
-  strcpy(_name->data(), name);
+  strcpy(_name->data(), cpe->name());
 }
 
 bool SharedClassPathEntry::validate(bool is_class_path) {
@@ -381,7 +384,7 @@
     const char* type = (is_jrt ? "jrt" : (cpe->is_jar_file() ? "jar" : "dir"));
     log_info(class, path)("add main shared path (%s) %s", type, cpe->name());
     SharedClassPathEntry* ent = shared_path(i);
-    ent->init(cpe->name(), is_jrt, THREAD);
+    ent->init(is_jrt, cpe, THREAD);
     if (!is_jrt) {    // No need to do the modules image.
       EXCEPTION_MARK; // The following call should never throw, but would exit VM on error.
       update_shared_classpath(cpe, ent, THREAD);
@@ -397,7 +400,7 @@
   while (acpe != NULL) {
     log_info(class, path)("add app shared path %s", acpe->name());
     SharedClassPathEntry* ent = shared_path(i);
-    ent->init(acpe->name(), false, THREAD);
+    ent->init(false, acpe, THREAD);
     EXCEPTION_MARK;
     update_shared_classpath(acpe, ent, THREAD);
     acpe = acpe->next();
@@ -409,7 +412,7 @@
   while (mpe != NULL) {
     log_info(class, path)("add module path %s",mpe->name());
     SharedClassPathEntry* ent = shared_path(i);
-    ent->init(mpe->name(), false, THREAD);
+    ent->init(false, mpe, THREAD);
     EXCEPTION_MARK;
     update_shared_classpath(mpe, ent, THREAD);
     mpe = mpe->next();
@@ -520,6 +523,182 @@
   }
 }
 
+char* FileMapInfo::skip_first_path_entry(const char* path) {
+  size_t path_sep_len = strlen(os::path_separator());
+  char* p = strstr((char*)path, os::path_separator());
+  if (p != NULL) {
+    debug_only( {
+      size_t image_name_len = strlen(MODULES_IMAGE_NAME);
+      assert(strncmp(p - image_name_len, MODULES_IMAGE_NAME, image_name_len) == 0,
+             "first entry must be the modules image");
+    } );
+    p += path_sep_len;
+  } else {
+    debug_only( {
+      assert(ClassLoader::string_ends_with(path, MODULES_IMAGE_NAME),
+             "first entry must be the modules image");
+    } );
+  }
+  return p;
+}
+
+int FileMapInfo::num_paths(const char* path) {
+  if (path == NULL) {
+    return 0;
+  }
+  int npaths = 1;
+  char* p = (char*)path;
+  while (p != NULL) {
+    char* prev = p;
+    p = strstr((char*)p, os::path_separator());
+    if (p != NULL) {
+      p++;
+      // don't count empty path
+      if ((p - prev) > 1) {
+       npaths++;
+      }
+    }
+  }
+  return npaths;
+}
+
+GrowableArray<char*>* FileMapInfo::create_path_array(const char* path) {
+  GrowableArray<char*>* path_array =  new(ResourceObj::RESOURCE_AREA, mtInternal)
+      GrowableArray<char*>(10);
+  char* begin_ptr = (char*)path;
+  char* end_ptr = strchr((char*)path, os::path_separator()[0]);
+  if (end_ptr == NULL) {
+    end_ptr = strchr((char*)path, '\0');
+  }
+  while (end_ptr != NULL) {
+    if ((end_ptr - begin_ptr) > 1) {
+      struct stat st;
+      char* temp_name = NEW_RESOURCE_ARRAY(char, (size_t)(end_ptr - begin_ptr + 1));
+      strncpy(temp_name, begin_ptr, end_ptr - begin_ptr);
+      temp_name[end_ptr - begin_ptr] = '\0';
+      if (os::stat(temp_name, &st) == 0) {
+        path_array->append(temp_name);
+      }
+    }
+    if (end_ptr < (path + strlen(path))) {
+      begin_ptr = ++end_ptr;
+      end_ptr = strchr(begin_ptr, os::path_separator()[0]);
+      if (end_ptr == NULL) {
+        end_ptr = strchr(begin_ptr, '\0');
+      }
+    } else {
+      break;
+    }
+  }
+  return path_array;
+}
+
+bool FileMapInfo::fail(const char* msg, const char* name) {
+  ClassLoader::trace_class_path(msg, name);
+  MetaspaceShared::set_archive_loading_failed();
+  return false;
+}
+
+bool FileMapInfo::check_paths(int shared_path_start_idx, int num_paths, GrowableArray<char*>* rp_array) {
+  int i = 0;
+  int j = shared_path_start_idx;
+  bool mismatch = false;
+  while (i < num_paths && !mismatch) {
+    while (shared_path(j)->from_class_path_attr()) {
+      // shared_path(j) was expanded from the JAR file attribute "Class-Path:"
+      // during dump time. It's not included in the -classpath VM argument.
+      j++;
+    }
+    if (!os::same_files(shared_path(j)->name(), rp_array->at(i))) {
+      mismatch = true;
+    }
+    i++;
+    j++;
+  }
+  return mismatch;
+}
+
+bool FileMapInfo::validate_boot_class_paths() {
+  //
+  // - Archive contains boot classes only - relaxed boot path check:
+  //   Extra path elements appended to the boot path at runtime are allowed.
+  //
+  // - Archive contains application or platform classes - strict boot path check:
+  //   Validate the entire runtime boot path, which must be compatible
+  //   with the dump time boot path. Appending boot path at runtime is not
+  //   allowed.
+  //
+
+  // The first entry in boot path is the modules_image (guaranteed by
+  // ClassLoader::setup_boot_search_path()). Skip the first entry. The
+  // path of the runtime modules_image may be different from the dump
+  // time path (e.g. the JDK image is copied to a different location
+  // after generating the shared archive), which is acceptable. For most
+  // common cases, the dump time boot path might contain modules_image only.
+  char* runtime_boot_path = Arguments::get_sysclasspath();
+  char* rp = skip_first_path_entry(runtime_boot_path);
+  assert(shared_path(0)->is_modules_image(), "first shared_path must be the modules image");
+  int dp_len = _header->_app_class_paths_start_index - 1; // ignore the first path to the module image
+  bool mismatch = false;
+
+  bool relaxed_check = !header()->has_platform_or_app_classes();
+  if (dp_len == 0 && rp == NULL) {
+    return true;   // ok, both runtime and dump time boot paths have modules_images only
+  } else if (dp_len == 0 && rp != NULL) {
+    if (relaxed_check) {
+      return true;   // ok, relaxed check, runtime has extra boot append path entries
+    } else {
+      mismatch = true;
+    }
+  } else if (dp_len > 0 && rp != NULL) {
+    int num;
+    ResourceMark rm;
+    GrowableArray<char*>* rp_array = create_path_array(rp);
+    int rp_len = rp_array->length();
+    if (rp_len >= dp_len) {
+      if (relaxed_check) {
+        // only check the leading entries in the runtime boot path, up to
+        // the length of the dump time boot path
+        num = dp_len;
+      } else {
+        // check the full runtime boot path, must match with dump time
+        num = rp_len;
+      }
+      mismatch = check_paths(1, num, rp_array);
+    }
+  }
+
+  if (mismatch) {
+    // The paths are different
+    return fail("[BOOT classpath mismatch, actual =", runtime_boot_path);
+  }
+  return true;
+}
+
+bool FileMapInfo::validate_app_class_paths(int shared_app_paths_len) {
+  const char *appcp = Arguments::get_appclasspath();
+  assert(appcp != NULL, "NULL app classpath");
+  int rp_len = num_paths(appcp);
+  bool mismatch = false;
+  if (rp_len < shared_app_paths_len) {
+    return fail("Run time APP classpath is shorter than the one at dump time: ", appcp);
+  }
+  if (shared_app_paths_len != 0 && rp_len != 0) {
+    // Prefix is OK: E.g., dump with -cp foo.jar, but run with -cp foo.jar:bar.jar.
+    ResourceMark rm;
+    GrowableArray<char*>* rp_array = create_path_array(appcp);
+    if (rp_array->length() == 0) {
+      // None of the jar file specified in the runtime -cp exists.
+      return fail("None of the jar file specified in the runtime -cp exists: -Djava.class.path=", appcp);
+    }
+    int j = _header->_app_class_paths_start_index;
+    mismatch = check_paths(j, shared_app_paths_len, rp_array);
+    if (mismatch) {
+      return fail("[APP classpath mismatch, actual: -Djava.class.path=", appcp);
+    }
+  }
+  return true;
+}
 
 bool FileMapInfo::validate_shared_path_table() {
   assert(UseSharedSpaces, "runtime only");
@@ -550,11 +729,16 @@
   }
 
   int module_paths_start_index = _header->_app_module_paths_start_index;
+  int shared_app_paths_len = 0;
 
   // validate the path entries up to the _max_used_path_index
   for (int i=0; i < _header->_max_used_path_index + 1; i++) {
     if (i < module_paths_start_index) {
       if (shared_path(i)->validate()) {
+        // Only count the app class paths not from the "Class-path" attribute of a jar manifest.
+        if (!shared_path(i)->from_class_path_attr() && i >= _header->_app_class_paths_start_index) {
+          shared_app_paths_len++;
+        }
         log_info(class, path)("ok");
       } else {
         if (_dynamic_archive_info != NULL && _dynamic_archive_info->_is_static) {
@@ -574,6 +758,16 @@
     }
   }
 
+  if (_header->_max_used_path_index == 0) {
+    // default archive only contains the module image in the bootclasspath
+    assert(shared_path(0)->is_modules_image(), "first shared_path must be the modules image");
+  } else {
+    if (!validate_boot_class_paths() || !validate_app_class_paths(shared_app_paths_len)) {
+      fail_continue("shared class paths mismatch (hint: enable -Xlog:class+path=info to diagnose the failure)");
+      return false;
+    }
+  }
+
   _validating_shared_path_table = false;
 
 #if INCLUDE_JVMTI
@@ -588,39 +782,6 @@
   return true;
 }
 
-bool FileMapInfo::same_files(const char* file1, const char* file2) {
-  if (strcmp(file1, file2) == 0) {
-    return true;
-  }
-
-  bool is_same = false;
-  // if the two paths diff only in case
-  struct stat st1;
-  struct stat st2;
-  int ret1;
-  int ret2;
-  ret1 = os::stat(file1, &st1);
-  ret2 = os::stat(file2, &st2);
-  if (ret1 < 0 || ret2 < 0) {
-    // one of the files is invalid. So they are not the same.
-    is_same = false;
-  } else if (st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino) {
-    // different files
-    is_same = false;
-#ifndef _WINDOWS
-  } else if (st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino) {
-    // same files
-    is_same = true;
-#else
-  } else if ((st1.st_size == st2.st_size) && (st1.st_ctime == st2.st_ctime) &&
-             (st1.st_mtime == st2.st_mtime)) {
-    // same files
-    is_same = true;
-#endif
-  }
-  return is_same;
-}
-
 bool FileMapInfo::check_archive(const char* archive_name, bool is_static) {
   int fd = os::open(archive_name, O_RDONLY | O_BINARY, 0);
   if (fd < 0) {
@@ -1749,7 +1910,7 @@
         jio_snprintf(msg, strlen(path) + 127, "error in opening JAR file %s", path);
         THROW_MSG_(vmSymbols::java_io_IOException(), msg, NULL);
       } else {
-        ent = ClassLoader::create_class_path_entry(path, &st, /*throw_exception=*/true, false, CHECK_NULL);
+        ent = ClassLoader::create_class_path_entry(path, &st, /*throw_exception=*/true, false, false, CHECK_NULL);
       }
     }
 
--- a/src/hotspot/share/memory/filemap.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/memory/filemap.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -53,13 +53,14 @@
   };
 protected:
   u1     _type;
+  bool   _from_class_path_attr;
   time_t _timestamp;          // jar timestamp,  0 if is directory, modules image or other
   long   _filesize;           // jar/jimage file size, -1 if is directory, -2 if other
   Array<char>* _name;
   Array<u1>*   _manifest;
 
 public:
-  void init(const char* name, bool is_modules_image, TRAPS);
+  void init(bool is_modules_image, ClassPathEntry* cpe, TRAPS);
   void metaspace_pointers_do(MetaspaceClosure* it);
   bool validate(bool is_class_path = true);
 
@@ -74,6 +75,7 @@
   void set_is_signed()     {
     _type = signed_jar_entry;
   }
+  bool from_class_path_attr() { return _from_class_path_attr; }
   time_t timestamp() const { return _timestamp; }
   long   filesize()  const { return _filesize; }
   const char* name() const { return _name->data(); }
@@ -240,7 +242,6 @@
   static bool get_base_archive_name_from_header(const char* archive_name,
                                                 int* size, char** base_archive_name);
   static bool check_archive(const char* archive_name, bool is_static);
-  static bool  same_files(const char* file1, const char* file2);
   void restore_shared_path_table();
   bool  init_from_file(int fd, bool is_static);
   static void metaspace_pointers_do(MetaspaceClosure* it);
@@ -376,6 +377,15 @@
   char* region_addr(int idx);
 
  private:
+  char* skip_first_path_entry(const char* path) NOT_CDS_RETURN_(NULL);
+  int   num_paths(const char* path) NOT_CDS_RETURN_(0);
+  GrowableArray<char*>* create_path_array(const char* path) NOT_CDS_RETURN_(NULL);
+  bool  fail(const char* msg, const char* name) NOT_CDS_RETURN_(false);
+  bool  check_paths(int shared_path_start_idx,
+                    int num_paths,
+                    GrowableArray<char*>* rp_array) NOT_CDS_RETURN_(false);
+  bool  validate_boot_class_paths() NOT_CDS_RETURN_(false);
+  bool  validate_app_class_paths(int shared_app_paths_len) NOT_CDS_RETURN_(false);
   bool  map_heap_data(MemRegion **heap_mem, int first, int max, int* num,
                       bool is_open = false) NOT_CDS_JAVA_HEAP_RETURN_(false);
   bool  region_crc_check(char* buf, size_t size, int expected_crc) NOT_CDS_RETURN_(false);
--- a/src/hotspot/share/oops/method.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/oops/method.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -103,7 +103,7 @@
   // Fix and bury in Method*
   set_interpreter_entry(NULL); // sets i2i entry and from_int
   set_adapter_entry(NULL);
-  Method::clear_code(); // from_c/from_i get set to c2i/i2i
+  clear_code(false /* don't need a lock */); // from_c/from_i get set to c2i/i2i
 
   if (access_flags.is_native()) {
     clear_native_function();
@@ -819,7 +819,7 @@
   set_native_function(
     SharedRuntime::native_method_throw_unsatisfied_link_error_entry(),
     !native_bind_event_is_interesting);
-  this->unlink_code();
+  clear_code();
 }
 
 address Method::critical_native_function() {
@@ -943,7 +943,8 @@
 }
 
 // Revert to using the interpreter and clear out the nmethod
-void Method::clear_code() {
+void Method::clear_code(bool acquire_lock /* = true */) {
+  MutexLocker pl(acquire_lock ? Patching_lock : NULL, Mutex::_no_safepoint_check_flag);
   // this may be NULL if c2i adapters have not been made yet
   // Only should happen at allocate time.
   if (adapter() == NULL) {
@@ -957,25 +958,6 @@
   _code = NULL;
 }
 
-void Method::unlink_code(CompiledMethod *compare) {
-  MutexLocker ml(CompiledMethod_lock->owned_by_self() ? NULL : CompiledMethod_lock, Mutex::_no_safepoint_check_flag);
-  // We need to check if either the _code or _from_compiled_code_entry_point
-  // refer to this nmethod because there is a race in setting these two fields
-  // in Method* as seen in bugid 4947125.
-  // If the vep() points to the zombie nmethod, the memory for the nmethod
-  // could be flushed and the compiler and vtable stubs could still call
-  // through it.
-  if (code() == compare ||
-      from_compiled_entry() == compare->verified_entry_point()) {
-    clear_code();
-  }
-}
-
-void Method::unlink_code() {
-  MutexLocker ml(CompiledMethod_lock->owned_by_self() ? NULL : CompiledMethod_lock, Mutex::_no_safepoint_check_flag);
-  clear_code();
-}
-
 #if INCLUDE_CDS
 // Called by class data sharing to remove any entry points (which are not shared)
 void Method::unlink_method() {
@@ -1202,7 +1184,7 @@
 
 // Install compiled code.  Instantly it can execute.
 void Method::set_code(const methodHandle& mh, CompiledMethod *code) {
-  MutexLocker pl(CompiledMethod_lock, Mutex::_no_safepoint_check_flag);
+  MutexLocker pl(Patching_lock, Mutex::_no_safepoint_check_flag);
   assert( code, "use clear_code to remove code" );
   assert( mh->check_code(), "" );
 
--- a/src/hotspot/share/oops/method.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/oops/method.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -463,17 +463,7 @@
   address verified_code_entry();
   bool check_code() const;      // Not inline to avoid circular ref
   CompiledMethod* volatile code() const;
-
-  // Locks CompiledMethod_lock if not held.
-  void unlink_code(CompiledMethod *compare);
-  // Locks CompiledMethod_lock if not held.
-  void unlink_code();
-
-private:
-  // Either called with CompiledMethod_lock held or from constructor.
-  void clear_code();
-
-public:
+  void clear_code(bool acquire_lock = true);    // Clear out any compiled code
   static void set_code(const methodHandle& mh, CompiledMethod* code);
   void set_adapter_entry(AdapterHandlerEntry* adapter) {
     constMethod()->set_adapter_entry(adapter);
--- a/src/hotspot/share/opto/library_call.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/opto/library_call.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -4240,6 +4240,14 @@
   // Do not let writes of the copy source or destination float below the copy.
   insert_mem_bar(Op_MemBarCPUOrder);
 
+  Node* thread = _gvn.transform(new ThreadLocalNode());
+  Node* doing_unsafe_access_addr = basic_plus_adr(top(), thread, in_bytes(JavaThread::doing_unsafe_access_offset()));
+  BasicType doing_unsafe_access_bt = T_BYTE;
+  assert((sizeof(bool) * CHAR_BIT) == 8, "not implemented");
+
+  // update volatile field
+  store_to_memory(control(), doing_unsafe_access_addr, intcon(1), doing_unsafe_access_bt, Compile::AliasIdxRaw, MemNode::unordered);
+
   // Call it.  Note that the length argument is not scaled.
   make_runtime_call(RC_LEAF|RC_NO_FP,
                     OptoRuntime::fast_arraycopy_Type(),
@@ -4248,6 +4256,8 @@
                     TypeRawPtr::BOTTOM,
                     src, dst, size XTOP);
 
+  store_to_memory(control(), doing_unsafe_access_addr, intcon(0), doing_unsafe_access_bt, Compile::AliasIdxRaw, MemNode::unordered);
+
   // Do not let reads of the copy destination float above the copy.
   insert_mem_bar(Op_MemBarCPUOrder);
 
--- a/src/hotspot/share/opto/macro.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/opto/macro.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -1008,8 +1008,17 @@
         assert(init->outcnt() <= 2, "only a control and memory projection expected");
         Node *ctrl_proj = init->proj_out_or_null(TypeFunc::Control);
         if (ctrl_proj != NULL) {
-           assert(init->in(TypeFunc::Control) == _fallthroughcatchproj, "allocation control projection");
-          _igvn.replace_node(ctrl_proj, _fallthroughcatchproj);
+          _igvn.replace_node(ctrl_proj, init->in(TypeFunc::Control));
+#ifdef ASSERT
+          BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
+          Node* tmp = init->in(TypeFunc::Control);
+          while (bs->is_gc_barrier_node(tmp)) {
+            Node* tmp2 = bs->step_over_gc_barrier_ctrl(tmp);
+            assert(tmp != tmp2, "Must make progress");
+            tmp = tmp2;
+          }
+          assert(tmp == _fallthroughcatchproj, "allocation control projection");
+#endif
         }
         Node *mem_proj = init->proj_out_or_null(TypeFunc::Memory);
         if (mem_proj != NULL) {
--- a/src/hotspot/share/opto/type.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/opto/type.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -730,8 +730,11 @@
   // Since we just discovered a new Type, compute its dual right now.
   assert( !_dual, "" );         // No dual yet
   _dual = xdual();              // Compute the dual
-  if( cmp(this,_dual)==0 ) {    // Handle self-symmetric
-    _dual = this;
+  if (cmp(this, _dual) == 0) {  // Handle self-symmetric
+    if (_dual != this) {
+      delete _dual;
+      _dual = this;
+    }
     return this;
   }
   assert( !_dual->_dual, "" );  // No reverse dual yet
--- a/src/hotspot/share/prims/jvmtiEventController.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/prims/jvmtiEventController.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -32,7 +32,6 @@
 #include "prims/jvmtiExport.hpp"
 #include "prims/jvmtiImpl.hpp"
 #include "prims/jvmtiThreadState.inline.hpp"
-#include "runtime/deoptimization.hpp"
 #include "runtime/frame.hpp"
 #include "runtime/thread.inline.hpp"
 #include "runtime/threadSMR.hpp"
@@ -240,7 +239,8 @@
       }
     }
     if (num_marked > 0) {
-      Deoptimization::deoptimize_all_marked();
+      VM_Deoptimize op;
+      VMThread::execute(&op);
     }
   }
 }
--- a/src/hotspot/share/prims/jvmtiExport.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/prims/jvmtiExport.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -2615,10 +2615,6 @@
   JvmtiTagMap::weak_oops_do(is_alive, f);
 }
 
-void JvmtiExport::gc_epilogue() {
-  JvmtiCurrentBreakpoints::gc_epilogue();
-}
-
 // Onload raw monitor transition.
 void JvmtiExport::transition_pending_onload_raw_monitors() {
   JvmtiPendingMonitors::transition_raw_monitors();
--- a/src/hotspot/share/prims/jvmtiExport.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/prims/jvmtiExport.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -388,7 +388,6 @@
 
   static void oops_do(OopClosure* f) NOT_JVMTI_RETURN;
   static void weak_oops_do(BoolObjectClosure* b, OopClosure* f) NOT_JVMTI_RETURN;
-  static void gc_epilogue() NOT_JVMTI_RETURN;
 
   static void transition_pending_onload_raw_monitors() NOT_JVMTI_RETURN;
 
--- a/src/hotspot/share/prims/jvmtiImpl.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/prims/jvmtiImpl.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -225,13 +225,6 @@
   }
 }
 
-void GrowableCache::gc_epilogue() {
-  int len = _elements->length();
-  for (int i=0; i<len; i++) {
-    _cache[i] = _elements->at(i)->getCacheValue();
-  }
-}
-
 //
 // class JvmtiBreakpoint
 //
@@ -389,10 +382,6 @@
   _bps.metadata_do(f);
 }
 
-void JvmtiBreakpoints::gc_epilogue() {
-  _bps.gc_epilogue();
-}
-
 void JvmtiBreakpoints::print() {
 #ifndef PRODUCT
   LogTarget(Trace, jvmti) log;
@@ -514,12 +503,6 @@
   }
 }
 
-void JvmtiCurrentBreakpoints::gc_epilogue() {
-  if (_jvmti_breakpoints != NULL) {
-    _jvmti_breakpoints->gc_epilogue();
-  }
-}
-
 ///////////////////////////////////////////////////////////////
 //
 // class VM_GetOrSetLocal
--- a/src/hotspot/share/prims/jvmtiImpl.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/prims/jvmtiImpl.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -120,8 +120,6 @@
   void oops_do(OopClosure* f);
   // walk metadata to preserve for RedefineClasses
   void metadata_do(void f(Metadata*));
-  // update the cache after a full gc
-  void gc_epilogue();
 };
 
 
@@ -154,7 +152,6 @@
   void clear()                          { _cache.clear(); }
   void oops_do(OopClosure* f)           { _cache.oops_do(f); }
   void metadata_do(void f(Metadata*))   { _cache.metadata_do(f); }
-  void gc_epilogue()                    { _cache.gc_epilogue(); }
 };
 
 
@@ -257,7 +254,6 @@
   int  set(JvmtiBreakpoint& bp);
   int  clear(JvmtiBreakpoint& bp);
   void clearall_in_class_at_safepoint(Klass* klass);
-  void gc_epilogue();
 };
 
 
@@ -299,7 +295,6 @@
 
   static void oops_do(OopClosure* f);
   static void metadata_do(void f(Metadata*)) NOT_JVMTI_RETURN;
-  static void gc_epilogue();
 };
 
 ///////////////////////////////////////////////////////////////
--- a/src/hotspot/share/prims/methodHandles.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/prims/methodHandles.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -42,7 +42,6 @@
 #include "oops/typeArrayOop.inline.hpp"
 #include "prims/methodHandles.hpp"
 #include "runtime/compilationPolicy.hpp"
-#include "runtime/deoptimization.hpp"
 #include "runtime/fieldDescriptor.inline.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/interfaceSupport.inline.hpp"
@@ -1110,7 +1109,8 @@
   }
   if (marked > 0) {
     // At least one nmethod has been marked for deoptimization.
-    Deoptimization::deoptimize_all_marked();
+    VM_Deoptimize op;
+    VMThread::execute(&op);
   }
 }
 
@@ -1506,7 +1506,8 @@
     }
     if (marked > 0) {
       // At least one nmethod has been marked for deoptimization
-      Deoptimization::deoptimize_all_marked();
+      VM_Deoptimize op;
+      VMThread::execute(&op);
     }
   }
 }
--- a/src/hotspot/share/prims/resolvedMethodTable.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/prims/resolvedMethodTable.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -56,15 +56,15 @@
   return name_hash ^ signature_hash;
 }
 
-typedef ConcurrentHashTable<WeakHandle<vm_resolved_method_table_data>,
-                            ResolvedMethodTableConfig,
+typedef ConcurrentHashTable<ResolvedMethodTableConfig,
                             mtClass> ResolvedMethodTableHash;
 
-class ResolvedMethodTableConfig : public ResolvedMethodTableHash::BaseConfig {
+class ResolvedMethodTableConfig : public AllStatic {
  private:
  public:
-  static uintx get_hash(WeakHandle<vm_resolved_method_table_data> const& value,
-                        bool* is_dead) {
+  typedef WeakHandle<vm_resolved_method_table_data> Value;
+
+  static uintx get_hash(Value const& value, bool* is_dead) {
     oop val_oop = value.peek();
     if (val_oop == NULL) {
       *is_dead = true;
@@ -76,13 +76,13 @@
   }
 
   // We use default allocation/deallocation but counted
-  static void* allocate_node(size_t size, WeakHandle<vm_resolved_method_table_data> const& value) {
+  static void* allocate_node(size_t size, Value const& value) {
     ResolvedMethodTable::item_added();
-    return ResolvedMethodTableHash::BaseConfig::allocate_node(size, value);
+    return AllocateHeap(size, mtClass);
   }
-  static void free_node(void* memory, WeakHandle<vm_resolved_method_table_data> const& value) {
+  static void free_node(void* memory, Value const& value) {
     value.release();
-    ResolvedMethodTableHash::BaseConfig::free_node(memory, value);
+    FreeHeap(memory);
     ResolvedMethodTable::item_removed();
   }
 };
--- a/src/hotspot/share/prims/unsafe.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/prims/unsafe.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -149,6 +149,25 @@
 ///// Data read/writes on the Java heap and in native (off-heap) memory
 
 /**
+ * Helper class to wrap memory accesses in JavaThread::doing_unsafe_access()
+ */
+class GuardUnsafeAccess {
+  JavaThread* _thread;
+
+public:
+  GuardUnsafeAccess(JavaThread* thread) : _thread(thread) {
+    // native/off-heap access which may raise SIGBUS if accessing
+    // memory mapped file data in a region of the file which has
+    // been truncated and is now invalid.
+    _thread->set_doing_unsafe_access(true);
+  }
+
+  ~GuardUnsafeAccess() {
+    _thread->set_doing_unsafe_access(false);
+  }
+};
+
+/**
  * Helper class for accessing memory.
  *
  * Normalizes values and wraps accesses in
@@ -189,25 +208,6 @@
     return x != 0;
   }
 
-  /**
-   * Helper class to wrap memory accesses in JavaThread::doing_unsafe_access()
-   */
-  class GuardUnsafeAccess {
-    JavaThread* _thread;
-
-  public:
-    GuardUnsafeAccess(JavaThread* thread) : _thread(thread) {
-      // native/off-heap access which may raise SIGBUS if accessing
-      // memory mapped file data in a region of the file which has
-      // been truncated and is now invalid
-      _thread->set_doing_unsafe_access(true);
-    }
-
-    ~GuardUnsafeAccess() {
-      _thread->set_doing_unsafe_access(false);
-    }
-  };
-
 public:
   MemoryAccess(JavaThread* thread, jobject obj, jlong offset)
     : _thread(thread), _obj(JNIHandles::resolve(obj)), _offset((ptrdiff_t)offset) {
@@ -399,8 +399,14 @@
 
   void* src = index_oop_from_field_offset_long(srcp, srcOffset);
   void* dst = index_oop_from_field_offset_long(dstp, dstOffset);
-
-  Copy::conjoint_memory_atomic(src, dst, sz);
+  {
+    GuardUnsafeAccess guard(thread);
+    if (StubRoutines::unsafe_arraycopy() != NULL) {
+      StubRoutines::UnsafeArrayCopy_stub()(src, dst, sz);
+    } else {
+      Copy::conjoint_memory_atomic(src, dst, sz);
+    }
+  }
 } UNSAFE_END
 
 // This function is a leaf since if the source and destination are both in native memory
@@ -416,7 +422,11 @@
     address src = (address)srcOffset;
     address dst = (address)dstOffset;
 
-    Copy::conjoint_swap(src, dst, sz, esz);
+    {
+      JavaThread* thread = JavaThread::thread_from_jni_environment(env);
+      GuardUnsafeAccess guard(thread);
+      Copy::conjoint_swap(src, dst, sz, esz);
+    }
   } else {
     // At least one of src/dst are on heap, transition to VM to access raw pointers
 
@@ -427,7 +437,10 @@
       address src = (address)index_oop_from_field_offset_long(srcp, srcOffset);
       address dst = (address)index_oop_from_field_offset_long(dstp, dstOffset);
 
-      Copy::conjoint_swap(src, dst, sz, esz);
+      {
+        GuardUnsafeAccess guard(thread);
+        Copy::conjoint_swap(src, dst, sz, esz);
+      }
     } JVM_END
   }
 } UNSAFE_END
--- a/src/hotspot/share/prims/whitebox.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/prims/whitebox.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -822,8 +822,10 @@
 WB_END
 
 WB_ENTRY(void, WB_DeoptimizeAll(JNIEnv* env, jobject o))
+  MutexLocker mu(Compile_lock);
   CodeCache::mark_all_nmethods_for_deoptimization();
-  Deoptimization::deoptimize_all_marked();
+  VM_Deoptimize op;
+  VMThread::execute(&op);
 WB_END
 
 WB_ENTRY(jint, WB_DeoptimizeMethod(JNIEnv* env, jobject o, jobject method, jboolean is_osr))
@@ -840,7 +842,8 @@
   }
   result += CodeCache::mark_for_deoptimization(mh());
   if (result > 0) {
-    Deoptimization::deoptimize_all_marked();
+    VM_Deoptimize op;
+    VMThread::execute(&op);
   }
   return result;
 WB_END
--- a/src/hotspot/share/runtime/arguments.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/runtime/arguments.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -1815,6 +1815,10 @@
       // was not specified.
       if (reasonable_max > max_coop_heap) {
         if (FLAG_IS_ERGO(UseCompressedOops) && override_coop_limit) {
+          log_info(cds)("UseCompressedOops and UseCompressedClassPointers have been disabled due to"
+            " max heap " SIZE_FORMAT " > compressed oop heap " SIZE_FORMAT ". "
+            "Please check the setting of MaxRAMPercentage %5.2f."
+            ,(size_t)reasonable_max, (size_t)max_coop_heap, MaxRAMPercentage);
           FLAG_SET_ERGO(UseCompressedOops, false);
           FLAG_SET_ERGO(UseCompressedClassPointers, false);
         } else {
@@ -3567,7 +3571,7 @@
           "Cannot have more than 1 archive file specified in -XX:SharedArchiveFile during CDS dumping");
       }
       if (DynamicDumpSharedSpaces) {
-        if (FileMapInfo::same_files(SharedArchiveFile, ArchiveClassesAtExit)) {
+        if (os::same_files(SharedArchiveFile, ArchiveClassesAtExit)) {
           vm_exit_during_initialization(
             "Cannot have the same archive file specified for -XX:SharedArchiveFile and -XX:ArchiveClassesAtExit",
             SharedArchiveFile);
--- a/src/hotspot/share/runtime/biasedLocking.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/runtime/biasedLocking.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -52,23 +52,24 @@
   k->set_prototype_header(markOopDesc::biased_locking_prototype());
 }
 
+static void enable_biased_locking() {
+  _biased_locking_enabled = true;
+  log_info(biasedlocking)("Biased locking enabled");
+}
+
 class VM_EnableBiasedLocking: public VM_Operation {
- private:
-  bool _is_cheap_allocated;
  public:
-  VM_EnableBiasedLocking(bool is_cheap_allocated) { _is_cheap_allocated = is_cheap_allocated; }
+  VM_EnableBiasedLocking() {}
   VMOp_Type type() const          { return VMOp_EnableBiasedLocking; }
-  Mode evaluation_mode() const    { return _is_cheap_allocated ? _async_safepoint : _safepoint; }
-  bool is_cheap_allocated() const { return _is_cheap_allocated; }
+  Mode evaluation_mode() const    { return _async_safepoint; }
+  bool is_cheap_allocated() const { return true; }
 
   void doit() {
     // Iterate the class loader data dictionaries enabling biased locking for all
     // currently loaded classes.
     ClassLoaderDataGraph::dictionary_classes_do(enable_biased_locking);
     // Indicate that future instances should enable it as well
-    _biased_locking_enabled = true;
-
-    log_info(biasedlocking)("Biased locking enabled");
+    enable_biased_locking();
   }
 
   bool allow_nested_vm_operations() const        { return false; }
@@ -83,7 +84,7 @@
   virtual void task() {
     // Use async VM operation to avoid blocking the Watcher thread.
     // VM Thread will free C heap storage.
-    VM_EnableBiasedLocking *op = new VM_EnableBiasedLocking(true);
+    VM_EnableBiasedLocking *op = new VM_EnableBiasedLocking();
     VMThread::execute(op);
 
     // Reclaim our storage and disenroll ourself
@@ -93,27 +94,29 @@
 
 
 void BiasedLocking::init() {
-  // If biased locking is enabled, schedule a task to fire a few
-  // seconds into the run which turns on biased locking for all
-  // currently loaded classes as well as future ones. This is a
-  // workaround for startup time regressions due to a large number of
-  // safepoints being taken during VM startup for bias revocation.
-  // Ideally we would have a lower cost for individual bias revocation
-  // and not need a mechanism like this.
+  // If biased locking is enabled and BiasedLockingStartupDelay is set,
+  // schedule a task to fire after the specified delay which turns on
+  // biased locking for all currently loaded classes as well as future
+  // ones. This could be a workaround for startup time regressions
+  // due to large number of safepoints being taken during VM startup for
+  // bias revocation.
   if (UseBiasedLocking) {
     if (BiasedLockingStartupDelay > 0) {
       EnableBiasedLockingTask* task = new EnableBiasedLockingTask(BiasedLockingStartupDelay);
       task->enroll();
     } else {
-      VM_EnableBiasedLocking op(false);
-      VMThread::execute(&op);
+      enable_biased_locking();
     }
   }
 }
 
 
 bool BiasedLocking::enabled() {
-  return _biased_locking_enabled;
+  assert(UseBiasedLocking, "precondition");
+  // We check "BiasedLockingStartupDelay == 0" here to cover the
+  // possibility of calls to BiasedLocking::enabled() before
+  // BiasedLocking::init().
+  return _biased_locking_enabled || BiasedLockingStartupDelay == 0;
 }
 
 // Returns MonitorInfos for all objects locked on this thread in youngest to oldest order
@@ -548,7 +551,7 @@
       if (biased_locker != NULL) {
         _biased_locker_id = JFR_THREAD_ID(biased_locker);
       }
-      _safepoint_id = SafepointSynchronize::safepoint_counter();
+      _safepoint_id = SafepointSynchronize::safepoint_id();
       clean_up_cached_monitor_info();
       return;
     } else {
@@ -589,7 +592,7 @@
 
   virtual void doit() {
     _status_code = bulk_revoke_or_rebias_at_safepoint((*_obj)(), _bulk_rebias, _attempt_rebias_of_object, _requesting_thread);
-    _safepoint_id = SafepointSynchronize::safepoint_counter();
+    _safepoint_id = SafepointSynchronize::safepoint_id();
     clean_up_cached_monitor_info();
   }
 
@@ -628,29 +631,6 @@
   event->commit();
 }
 
-BiasedLocking::Condition BiasedLocking::revoke_own_locks_in_handshake(Handle obj, TRAPS) {
-  markOop mark = obj->mark();
-
-  if (!mark->has_bias_pattern()) {
-    return NOT_BIASED;
-  }
-
-  Klass *k = obj->klass();
-  markOop prototype_header = k->prototype_header();
-  assert(mark->biased_locker() == THREAD &&
-         prototype_header->bias_epoch() == mark->bias_epoch(), "Revoke failed, unhandled biased lock state");
-  ResourceMark rm;
-  log_info(biasedlocking)("Revoking bias by walking my own stack:");
-  EventBiasedLockSelfRevocation event;
-  BiasedLocking::Condition cond = revoke_bias(obj(), false, false, (JavaThread*) THREAD, NULL);
-  ((JavaThread*) THREAD)->set_cached_monitor_info(NULL);
-  assert(cond == BIAS_REVOKED, "why not?");
-  if (event.should_commit()) {
-    post_self_revocation_event(&event, k);
-  }
-  return cond;
-}
-
 BiasedLocking::Condition BiasedLocking::revoke_and_rebias(Handle obj, bool attempt_rebias, TRAPS) {
   assert(!SafepointSynchronize::is_at_safepoint(), "must not be called while at safepoint");
 
--- a/src/hotspot/share/runtime/biasedLocking.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/runtime/biasedLocking.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -175,7 +175,6 @@
 
   // This should be called by JavaThreads to revoke the bias of an object
   static Condition revoke_and_rebias(Handle obj, bool attempt_rebias, TRAPS);
-  static Condition revoke_own_locks_in_handshake(Handle obj, TRAPS);
 
   // These do not allow rebiasing; they are used by deoptimization to
   // ensure that monitors on the stack can be migrated
--- a/src/hotspot/share/runtime/deoptimization.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/runtime/deoptimization.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -779,35 +779,10 @@
   return bt;
 JRT_END
 
-class DeoptimizeMarkedTC : public ThreadClosure {
-  bool _in_handshake;
- public:
-  DeoptimizeMarkedTC(bool in_handshake) : _in_handshake(in_handshake) {}
-  virtual void do_thread(Thread* thread) {
-    assert(thread->is_Java_thread(), "must be");
-    JavaThread* jt = (JavaThread*)thread;
-    jt->deoptimize_marked_methods(_in_handshake);
-  }
-};
 
-void Deoptimization::deoptimize_all_marked() {
-  ResourceMark rm;
-  DeoptimizationMarker dm;
-
-  if (SafepointSynchronize::is_at_safepoint()) {
-    DeoptimizeMarkedTC deopt(false);
-    // Make the dependent methods not entrant
-    CodeCache::make_marked_nmethods_not_entrant();
-    Threads::java_threads_do(&deopt);
-  } else {
-    // Make the dependent methods not entrant
-    {
-      MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
-      CodeCache::make_marked_nmethods_not_entrant();
-    }
-    DeoptimizeMarkedTC deopt(true);
-    Handshake::execute(&deopt);
-  }
+int Deoptimization::deoptimize_dependents() {
+  Threads::deoptimized_wrt_marked_nmethods();
+  return 0;
 }
 
 Deoptimization::DeoptAction Deoptimization::_unloaded_action
@@ -1412,7 +1387,14 @@
   }
 }
 
-static void get_monitors_from_stack(GrowableArray<Handle>* objects_to_revoke, JavaThread* thread, frame fr, RegisterMap* map) {
+
+void Deoptimization::revoke_biases_of_monitors(JavaThread* thread, frame fr, RegisterMap* map) {
+  if (!UseBiasedLocking) {
+    return;
+  }
+
+  GrowableArray<Handle>* objects_to_revoke = new GrowableArray<Handle>();
+
   // Unfortunately we don't have a RegisterMap available in most of
   // the places we want to call this routine so we need to walk the
   // stack again to update the register map.
@@ -1436,14 +1418,6 @@
     cvf = compiledVFrame::cast(cvf->sender());
   }
   collect_monitors(cvf, objects_to_revoke);
-}
-
-void Deoptimization::revoke_using_safepoint(JavaThread* thread, frame fr, RegisterMap* map) {
-  if (!UseBiasedLocking) {
-    return;
-  }
-  GrowableArray<Handle>* objects_to_revoke = new GrowableArray<Handle>();
-  get_monitors_from_stack(objects_to_revoke, thread, fr, map);
 
   if (SafepointSynchronize::is_at_safepoint()) {
     BiasedLocking::revoke_at_safepoint(objects_to_revoke);
@@ -1452,21 +1426,6 @@
   }
 }
 
-void Deoptimization::revoke_using_handshake(JavaThread* thread, frame fr, RegisterMap* map) {
-  if (!UseBiasedLocking) {
-    return;
-  }
-  GrowableArray<Handle>* objects_to_revoke = new GrowableArray<Handle>();
-  get_monitors_from_stack(objects_to_revoke, thread, fr, map);
-
-  int len = objects_to_revoke->length();
-  for (int i = 0; i < len; i++) {
-    oop obj = (objects_to_revoke->at(i))();
-    BiasedLocking::revoke_own_locks_in_handshake(objects_to_revoke->at(i), thread);
-    assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now");
-  }
-}
-
 
 void Deoptimization::deoptimize_single_frame(JavaThread* thread, frame fr, Deoptimization::DeoptReason reason) {
   assert(fr.can_be_deoptimized(), "checking frame type");
@@ -1495,16 +1454,11 @@
   fr.deoptimize(thread);
 }
 
-void Deoptimization::deoptimize(JavaThread* thread, frame fr, RegisterMap *map, bool in_handshake) {
-  deopt_thread(in_handshake, thread, fr, map, Reason_constraint);
+void Deoptimization::deoptimize(JavaThread* thread, frame fr, RegisterMap *map) {
+  deoptimize(thread, fr, map, Reason_constraint);
 }
 
 void Deoptimization::deoptimize(JavaThread* thread, frame fr, RegisterMap *map, DeoptReason reason) {
-  deopt_thread(false, thread, fr, map, reason);
-}
-
-void Deoptimization::deopt_thread(bool in_handshake, JavaThread* thread,
-                                  frame fr, RegisterMap *map, DeoptReason reason) {
   // Deoptimize only if the frame comes from compile code.
   // Do not deoptimize the frame which is already patched
   // during the execution of the loops below.
@@ -1514,11 +1468,7 @@
   ResourceMark rm;
   DeoptimizationMarker dm;
   if (UseBiasedLocking) {
-    if (in_handshake) {
-      revoke_using_handshake(thread, fr, map);
-    } else {
-      revoke_using_safepoint(thread, fr, map);
-    }
+    revoke_biases_of_monitors(thread, fr, map);
   }
   deoptimize_single_frame(thread, fr, reason);
 
--- a/src/hotspot/share/runtime/deoptimization.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/runtime/deoptimization.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -137,19 +137,12 @@
     Unpack_LIMIT                = 4
   };
 
-  static void deoptimize_all_marked();
-
- private:
   // Checks all compiled methods. Invalid methods are deleted and
   // corresponding activations are deoptimized.
   static int deoptimize_dependents();
-  static void revoke_using_handshake(JavaThread* thread, frame fr, RegisterMap* map);
-  static void revoke_using_safepoint(JavaThread* thread, frame fr, RegisterMap* map);
-  static void deopt_thread(bool in_handshake, JavaThread* thread, frame fr, RegisterMap *map, DeoptReason reason);
 
- public:
   // Deoptimizes a frame lazily. nmethod gets patched deopt happens on return to the frame
-  static void deoptimize(JavaThread* thread, frame fr, RegisterMap *map, bool in_handshake = false);
+  static void deoptimize(JavaThread* thread, frame fr, RegisterMap *reg_map);
   static void deoptimize(JavaThread* thread, frame fr, RegisterMap *reg_map, DeoptReason reason);
 
 #if INCLUDE_JVMCI
@@ -163,9 +156,7 @@
 
   // Helper function to revoke biases of all monitors in frame if UseBiasedLocking
   // is enabled
-  static void revoke_biases_of_monitors(JavaThread* thread, frame fr, RegisterMap* map) {
-    revoke_using_safepoint(thread, fr, map);
-  }
+  static void revoke_biases_of_monitors(JavaThread* thread, frame fr, RegisterMap* map);
 
 #if COMPILER2_OR_JVMCI
 JVMCI_ONLY(public:)
--- a/src/hotspot/share/runtime/mutex.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/runtime/mutex.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -62,7 +62,7 @@
        event,
        access         = event          +   1,
        tty            = access         +   2,
-       special        = tty            +   2,
+       special        = tty            +   1,
        suspend_resume = special        +   1,
        vmweak         = suspend_resume +   2,
        leaf           = vmweak         +   2,
--- a/src/hotspot/share/runtime/mutexLocker.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/runtime/mutexLocker.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -39,7 +39,6 @@
 // Consider using GCC's __read_mostly.
 
 Mutex*   Patching_lock                = NULL;
-Mutex*   CompiledMethod_lock          = NULL;
 Monitor* SystemDictionary_lock        = NULL;
 Mutex*   ProtectionDomainSet_lock     = NULL;
 Mutex*   SharedDictionary_lock        = NULL;
@@ -83,7 +82,6 @@
 Monitor* CGC_lock                     = NULL;
 Monitor* STS_lock                     = NULL;
 Monitor* FullGCCount_lock             = NULL;
-Monitor* SATB_Q_CBL_mon               = NULL;
 Monitor* DirtyCardQ_CBL_mon           = NULL;
 Mutex*   Shared_DirtyCardQ_lock       = NULL;
 Mutex*   MarkStackFreeList_lock       = NULL;
@@ -229,8 +227,6 @@
 
   def(FullGCCount_lock             , PaddedMonitor, leaf,        true,  Monitor::_safepoint_check_never);      // in support of ExplicitGCInvokesConcurrent
   if (UseG1GC) {
-    def(SATB_Q_CBL_mon             , PaddedMonitor, access,      true,  Monitor::_safepoint_check_never);
-
     def(DirtyCardQ_CBL_mon         , PaddedMonitor, access,      true,  Monitor::_safepoint_check_never);
     def(Shared_DirtyCardQ_lock     , PaddedMutex  , access + 1,  true,  Monitor::_safepoint_check_never);
 
@@ -247,8 +243,6 @@
     def(MonitoringSupport_lock     , PaddedMutex  , native   ,   true,  Monitor::_safepoint_check_never);      // used for serviceability monitoring support
   }
   if (UseShenandoahGC) {
-    def(SATB_Q_CBL_mon             , PaddedMonitor, access,      true,  Monitor::_safepoint_check_never);
-
     def(StringDedupQueue_lock      , PaddedMonitor, leaf,        true,  Monitor::_safepoint_check_never);
     def(StringDedupTable_lock      , PaddedMutex  , leaf,        true,  Monitor::_safepoint_check_never);
   }
@@ -262,8 +256,6 @@
   def(ClassLoaderDataGraph_lock    , PaddedMutex  , nonleaf,     true,  Monitor::_safepoint_check_always);
 
   def(Patching_lock                , PaddedMutex  , special,     true,  Monitor::_safepoint_check_never);      // used for safepointing and code patching.
-  def(OsrList_lock                 , PaddedMutex  , special-1,   true,  Monitor::_safepoint_check_never);
-  def(CompiledMethod_lock          , PaddedMutex  , special-1,   true,  Monitor::_safepoint_check_never);
   def(Service_lock                 , PaddedMonitor, special,     true,  Monitor::_safepoint_check_never);      // used for service thread operations
   def(JmethodIdCreation_lock       , PaddedMutex  , leaf,        true,  Monitor::_safepoint_check_always); // used for creating jmethodIDs.
 
@@ -279,6 +271,7 @@
   def(SymbolArena_lock             , PaddedMutex  , leaf+2,      true,  Monitor::_safepoint_check_never);
   def(ProfilePrint_lock            , PaddedMutex  , leaf,        false, Monitor::_safepoint_check_always); // serial profile printing
   def(ExceptionCache_lock          , PaddedMutex  , leaf,        false, Monitor::_safepoint_check_always); // serial profile printing
+  def(OsrList_lock                 , PaddedMutex  , leaf,        true,  Monitor::_safepoint_check_never);
   def(Debug1_lock                  , PaddedMutex  , leaf,        true,  Monitor::_safepoint_check_never);
 #ifndef PRODUCT
   def(FullGCALot_lock              , PaddedMutex  , leaf,        false, Monitor::_safepoint_check_always); // a lock to make FullGCALot MT safe
--- a/src/hotspot/share/runtime/mutexLocker.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/runtime/mutexLocker.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -32,7 +32,6 @@
 // Mutexes used in the VM.
 
 extern Mutex*   Patching_lock;                   // a lock used to guard code patching of compiled code
-extern Mutex*   CompiledMethod_lock;             // a lock used to guard a compiled method
 extern Monitor* SystemDictionary_lock;           // a lock on the system dictionary
 extern Mutex*   ProtectionDomainSet_lock;        // a lock on the pd_set list in the system dictionary
 extern Mutex*   SharedDictionary_lock;           // a lock on the CDS shared dictionary
@@ -78,8 +77,6 @@
                                                  // fore- & background GC threads.
 extern Monitor* STS_lock;                        // used for joining/leaving SuspendibleThreadSet.
 extern Monitor* FullGCCount_lock;                // in support of "concurrent" full gc
-extern Monitor* SATB_Q_CBL_mon;                  // Protects SATB Q
-                                                 // completed buffer queue.
 extern Monitor* DirtyCardQ_CBL_mon;              // Protects dirty card Q
                                                  // completed buffer queue.
 extern Mutex*   Shared_DirtyCardQ_lock;          // Lock protecting dirty card
--- a/src/hotspot/share/runtime/os.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/runtime/os.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -171,10 +171,6 @@
     init_globals_ext();
   }
 
-  // File names are case-insensitive on windows only
-  // Override me as needed
-  static int    file_name_strncmp(const char* s1, const char* s2, size_t num);
-
   // unset environment variable
   static bool unsetenv(const char* name);
 
@@ -544,6 +540,8 @@
 
   static int compare_file_modified_times(const char* file1, const char* file2);
 
+  static bool same_files(const char* file1, const char* file2);
+
   //File i/o operations
 
   static ssize_t read(int fd, void *buf, unsigned int nBytes);
--- a/src/hotspot/share/runtime/safepoint.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/runtime/safepoint.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -118,12 +118,22 @@
   }
 }
 
+// SafepointCheck
+SafepointStateTracker::SafepointStateTracker(uint64_t safepoint_id, bool at_safepoint)
+  : _safepoint_id(safepoint_id), _at_safepoint(at_safepoint) {}
+
+bool SafepointStateTracker::safepoint_state_changed() {
+  return _safepoint_id != SafepointSynchronize::safepoint_id() ||
+    _at_safepoint != SafepointSynchronize::is_at_safepoint();
+}
+
 // --------------------------------------------------------------------------------------------------
 // Implementation of Safepoint begin/end
 
 SafepointSynchronize::SynchronizeState volatile SafepointSynchronize::_state = SafepointSynchronize::_not_synchronized;
 int SafepointSynchronize::_waiting_to_block = 0;
 volatile uint64_t SafepointSynchronize::_safepoint_counter = 0;
+uint64_t SafepointSynchronize::_safepoint_id = 0;
 const uint64_t SafepointSynchronize::InactiveSafepointCounter = 0;
 int SafepointSynchronize::_current_jni_active_count = 0;
 
@@ -154,7 +164,7 @@
   --_waiting_to_block;
 }
 
-static bool thread_not_running(ThreadSafepointState *cur_state) {
+bool SafepointSynchronize::thread_not_running(ThreadSafepointState *cur_state) {
   if (!cur_state->is_running()) {
     return true;
   }
@@ -408,6 +418,9 @@
 
   OrderAccess::fence();
 
+  // Set the new id
+  ++_safepoint_id;
+
 #ifdef ASSERT
   // Make sure all the threads were visited.
   for (JavaThreadIteratorWithHandle jtiwh; JavaThread *cur = jtiwh.next(); ) {
@@ -419,7 +432,7 @@
   GCLocker::set_jni_lock_count(_current_jni_active_count);
 
   post_safepoint_synchronize_event(sync_event,
-                                   _safepoint_counter,
+                                   _safepoint_id,
                                    initial_running,
                                    _waiting_to_block, iterations);
 
@@ -429,14 +442,14 @@
   // needs cleanup to be completed before running the GC op.
   EventSafepointCleanup cleanup_event;
   do_cleanup_tasks();
-  post_safepoint_cleanup_event(cleanup_event, _safepoint_counter);
+  post_safepoint_cleanup_event(cleanup_event, _safepoint_id);
 
-  post_safepoint_begin_event(begin_event, _safepoint_counter, nof_threads, _current_jni_active_count);
+  post_safepoint_begin_event(begin_event, _safepoint_id, nof_threads, _current_jni_active_count);
   SafepointTracing::cleanup();
 }
 
 void SafepointSynchronize::disarm_safepoint() {
-  uint64_t safepoint_id = _safepoint_counter;
+  uint64_t active_safepoint_counter = _safepoint_counter;
   {
     JavaThreadIteratorWithHandle jtiwh;
 #ifdef ASSERT
@@ -475,7 +488,7 @@
     jtiwh.rewind();
     for (; JavaThread *current = jtiwh.next(); ) {
       // Clear the visited flag to ensure that the critical counts are collected properly.
-      DEBUG_ONLY(current->reset_visited_for_critical_count(safepoint_id);)
+      DEBUG_ONLY(current->reset_visited_for_critical_count(active_safepoint_counter);)
       ThreadSafepointState* cur_state = current->safepoint_state();
       assert(!cur_state->is_running(), "Thread not suspended at safepoint");
       cur_state->restart(); // TSS _running
@@ -497,7 +510,6 @@
 void SafepointSynchronize::end() {
   assert(Threads_lock->owned_by_self(), "must hold Threads_lock");
   EventSafepointEnd event;
-  uint64_t safepoint_id = _safepoint_counter;
   assert(Thread::current()->is_VM_thread(), "Only VM thread can execute a safepoint");
 
   disarm_safepoint();
@@ -506,7 +518,7 @@
 
   SafepointTracing::end();
 
-  post_safepoint_end_event(event, safepoint_id);
+  post_safepoint_end_event(event, safepoint_id());
 }
 
 bool SafepointSynchronize::is_cleanup_needed() {
@@ -554,7 +566,7 @@
     _counters(counters) {}
 
   void work(uint worker_id) {
-    uint64_t safepoint_id = SafepointSynchronize::safepoint_counter();
+    uint64_t safepoint_id = SafepointSynchronize::safepoint_id();
     // All threads deflate monitors and mark nmethods (if necessary).
     Threads::possibly_parallel_threads_do(true, &_cleanup_threads_cl);
 
--- a/src/hotspot/share/runtime/safepoint.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/runtime/safepoint.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -48,6 +48,14 @@
 
 class ThreadSafepointState;
 
+class SafepointStateTracker {
+  uint64_t _safepoint_id;
+  bool     _at_safepoint;
+public:
+  SafepointStateTracker(uint64_t safepoint_id, bool at_safepoint);
+  bool safepoint_state_changed();
+};
+
 //
 // Implements roll-forward to safepoint (safepoint synchronization)
 //
@@ -77,6 +85,7 @@
   friend class SafepointMechanism;
   friend class ThreadSafepointState;
   friend class HandshakeState;
+  friend class SafepointStateTracker;
 
   // Threads might read this flag directly, without acquiring the Threads_lock:
   static volatile SynchronizeState _state;
@@ -91,6 +100,11 @@
   // safepoint.
   static volatile uint64_t _safepoint_counter;
 
+  // A change in this counter or a change in the result of
+  // is_at_safepoint() are used by SafepointStateTracker::
+  // safepoint_state_changed() to determine its answer.
+  static uint64_t _safepoint_id;
+
   // JavaThreads that need to block for the safepoint will stop on the
   // _wait_barrier, where they can quickly be started again.
   static WaitBarrier* _wait_barrier;
@@ -114,6 +128,7 @@
   static void disarm_safepoint();
   static void increment_jni_active_count();
   static void decrement_waiting_to_block();
+  static bool thread_not_running(ThreadSafepointState *cur_state);
 
   // Used in safepoint_safe to do a stable load of the thread state.
   static bool try_stable_load_state(JavaThreadState *state,
@@ -127,6 +142,8 @@
   // If true the VMThread may safely process the handshake operation for the JavaThread.
   static bool handshake_safe(JavaThread *thread);
 
+  static uint64_t safepoint_counter()             { return _safepoint_counter; }
+
 public:
 
   static void init(Thread* vmthread);
@@ -141,8 +158,15 @@
   // Query
   static bool is_at_safepoint()                   { return _state == _synchronized; }
   static bool is_synchronizing()                  { return _state == _synchronizing; }
-  static uint64_t safepoint_counter()             { return _safepoint_counter; }
-  static bool is_same_safepoint(uint64_t counter) { return (SafepointSynchronize::safepoint_counter() - counter) < 2; }
+
+  static uint64_t safepoint_id() {
+    return _safepoint_id;
+  }
+
+  static SafepointStateTracker safepoint_state_tracker() {
+    return SafepointStateTracker(safepoint_id(), is_at_safepoint());
+  }
+
   // Exception handling for page polling
   static void handle_polling_page_exception(JavaThread *thread);
 
--- a/src/hotspot/share/runtime/sharedRuntime.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/runtime/sharedRuntime.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -2020,7 +2020,7 @@
   const char* caster_name = caster_klass->external_name();
 
   assert(target_klass != NULL || target_klass_name != NULL, "one must be provided");
-  const char* target_name = target_klass == NULL ? target_klass_name->as_C_string() :
+  const char* target_name = target_klass == NULL ? target_klass_name->as_klass_external_name() :
                                                    target_klass->external_name();
 
   size_t msglen = strlen(caster_name) + strlen("class ") + strlen(" cannot be cast to class ") + strlen(target_name) + 1;
--- a/src/hotspot/share/runtime/stubRoutines.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/runtime/stubRoutines.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -24,6 +24,7 @@
 
 #include "precompiled.hpp"
 #include "asm/codeBuffer.hpp"
+#include "asm/macroAssembler.inline.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/access.inline.hpp"
 #include "oops/oop.inline.hpp"
@@ -38,6 +39,10 @@
 #include "opto/runtime.hpp"
 #endif
 
+UnsafeCopyMemory* UnsafeCopyMemory::_table                      = NULL;
+int UnsafeCopyMemory::_table_length                             = 0;
+int UnsafeCopyMemory::_table_max_length                         = 0;
+address UnsafeCopyMemory::_common_exit_stub_pc                  = NULL;
 
 // Implementation of StubRoutines - for a description
 // of how to extend it, see the header file.
@@ -113,7 +118,6 @@
 address StubRoutines::_unsafe_arraycopy                  = NULL;
 address StubRoutines::_generic_arraycopy                 = NULL;
 
-
 address StubRoutines::_jbyte_fill;
 address StubRoutines::_jshort_fill;
 address StubRoutines::_jint_fill;
@@ -177,6 +181,31 @@
 
 extern void StubGenerator_generate(CodeBuffer* code, bool all); // only interface to generators
 
+void UnsafeCopyMemory::create_table(int max_size) {
+  UnsafeCopyMemory::_table = new UnsafeCopyMemory[max_size];
+  UnsafeCopyMemory::_table_max_length = max_size;
+}
+
+bool UnsafeCopyMemory::contains_pc(address pc) {
+  for (int i = 0; i < UnsafeCopyMemory::_table_length; i++) {
+    UnsafeCopyMemory* entry = &UnsafeCopyMemory::_table[i];
+    if (pc >= entry->start_pc() && pc < entry->end_pc()) {
+      return true;
+    }
+  }
+  return false;
+}
+
+address UnsafeCopyMemory::page_error_continue_pc(address pc) {
+  for (int i = 0; i < UnsafeCopyMemory::_table_length; i++) {
+    UnsafeCopyMemory* entry = &UnsafeCopyMemory::_table[i];
+    if (pc >= entry->start_pc() && pc < entry->end_pc()) {
+      return entry->error_exit_pc();
+    }
+  }
+  return NULL;
+}
+
 void StubRoutines::initialize1() {
   if (_code1 == NULL) {
     ResourceMark rm;
@@ -569,3 +598,25 @@
 #undef RETURN_STUB
 #undef RETURN_STUB_PARM
 }
+
+UnsafeCopyMemoryMark::UnsafeCopyMemoryMark(StubCodeGenerator* cgen, bool add_entry, bool continue_at_scope_end, address error_exit_pc) {
+  _cgen = cgen;
+  _ucm_entry = NULL;
+  if (add_entry) {
+    address err_exit_pc = NULL;
+    if (!continue_at_scope_end) {
+      err_exit_pc = error_exit_pc != NULL ? error_exit_pc : UnsafeCopyMemory::common_exit_stub_pc();
+    }
+    assert(err_exit_pc != NULL || continue_at_scope_end, "error exit not set");
+    _ucm_entry = UnsafeCopyMemory::add_to_table(_cgen->assembler()->pc(), NULL, err_exit_pc);
+  }
+}
+
+UnsafeCopyMemoryMark::~UnsafeCopyMemoryMark() {
+  if (_ucm_entry != NULL) {
+    _ucm_entry->set_end_pc(_cgen->assembler()->pc());
+    if (_ucm_entry->error_exit_pc() == NULL) {
+      _ucm_entry->set_error_exit_pc(_cgen->assembler()->pc());
+    }
+  }
+}
--- a/src/hotspot/share/runtime/stubRoutines.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/runtime/stubRoutines.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -74,6 +74,51 @@
 // 4. implement the corresponding generator function in the platform-dependent
 //    stubGenerator_<arch>.cpp file and call the function in generate_all() of that file
 
+class UnsafeCopyMemory : public CHeapObj<mtCode> {
+ private:
+  address _start_pc;
+  address _end_pc;
+  address _error_exit_pc;
+ public:
+  static address           _common_exit_stub_pc;
+  static UnsafeCopyMemory* _table;
+  static int               _table_length;
+  static int               _table_max_length;
+  UnsafeCopyMemory() : _start_pc(NULL), _end_pc(NULL), _error_exit_pc(NULL) {}
+  void    set_start_pc(address pc)      { _start_pc = pc; }
+  void    set_end_pc(address pc)        { _end_pc = pc; }
+  void    set_error_exit_pc(address pc) { _error_exit_pc = pc; }
+  address start_pc()      const { return _start_pc; }
+  address end_pc()        const { return _end_pc; }
+  address error_exit_pc() const { return _error_exit_pc; }
+
+  static void    set_common_exit_stub_pc(address pc) { _common_exit_stub_pc = pc; }
+  static address common_exit_stub_pc()               { return _common_exit_stub_pc; }
+
+  static UnsafeCopyMemory* add_to_table(address start_pc, address end_pc, address error_exit_pc) {
+    guarantee(_table_length < _table_max_length, "Incorrect UnsafeCopyMemory::_table_max_length");
+    UnsafeCopyMemory* entry = &_table[_table_length];
+    entry->set_start_pc(start_pc);
+    entry->set_end_pc(end_pc);
+    entry->set_error_exit_pc(error_exit_pc);
+
+    _table_length++;
+    return entry;
+  }
+
+  static bool    contains_pc(address pc);
+  static address page_error_continue_pc(address pc);
+  static void    create_table(int max_size);
+};
+
+class UnsafeCopyMemoryMark : public StackObj {
+ private:
+  UnsafeCopyMemory*  _ucm_entry;
+  StubCodeGenerator* _cgen;
+ public:
+  UnsafeCopyMemoryMark(StubCodeGenerator* cgen, bool add_entry, bool continue_at_scope_end, address error_exit_pc = NULL);
+  ~UnsafeCopyMemoryMark();
+};
 
 class StubRoutines: AllStatic {
 
@@ -310,11 +355,14 @@
   static address arrayof_oop_disjoint_arraycopy(bool dest_uninitialized = false) {
     return dest_uninitialized ? _arrayof_oop_disjoint_arraycopy_uninit : _arrayof_oop_disjoint_arraycopy;
   }
-
   static address checkcast_arraycopy(bool dest_uninitialized = false) {
     return dest_uninitialized ? _checkcast_arraycopy_uninit : _checkcast_arraycopy;
   }
-  static address unsafe_arraycopy()    { return _unsafe_arraycopy; }
+  static address unsafe_arraycopy()     { return _unsafe_arraycopy; }
+
+  typedef void (*UnsafeArrayCopyStub)(const void* src, void* dst, size_t count);
+  static UnsafeArrayCopyStub UnsafeArrayCopy_stub()         { return CAST_TO_FN_PTR(UnsafeArrayCopyStub,  _unsafe_arraycopy); }
+
   static address generic_arraycopy()   { return _generic_arraycopy; }
 
   static address jbyte_fill()          { return _jbyte_fill; }
--- a/src/hotspot/share/runtime/thread.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/runtime/thread.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -2903,17 +2903,18 @@
 #endif // PRODUCT
 
 
-void JavaThread::deoptimize_marked_methods(bool in_handshake) {
+void JavaThread::deoptimized_wrt_marked_nmethods() {
   if (!has_last_Java_frame()) return;
   // BiasedLocking needs an updated RegisterMap for the revoke monitors pass
   StackFrameStream fst(this, UseBiasedLocking);
   for (; !fst.is_done(); fst.next()) {
     if (fst.current()->should_be_deoptimized()) {
-      Deoptimization::deoptimize(this, *fst.current(), fst.register_map(), in_handshake);
+      Deoptimization::deoptimize(this, *fst.current(), fst.register_map());
     }
   }
 }
 
+
 // If the caller is a NamedThread, then remember, in the current scope,
 // the given JavaThread in its _processed_thread field.
 class RememberProcessedThread: public StackObj {
@@ -4652,6 +4653,13 @@
   threads_do(&handles_closure);
 }
 
+void Threads::deoptimized_wrt_marked_nmethods() {
+  ALL_JAVA_THREADS(p) {
+    p->deoptimized_wrt_marked_nmethods();
+  }
+}
+
+
 // Get count Java threads that are waiting to enter the specified monitor.
 GrowableArray<JavaThread*>* Threads::get_pending_threads(ThreadsList * t_list,
                                                          int count,
--- a/src/hotspot/share/runtime/thread.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/runtime/thread.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -1794,6 +1794,7 @@
   static ByteSize should_post_on_exceptions_flag_offset() {
     return byte_offset_of(JavaThread, _should_post_on_exceptions_flag);
   }
+  static ByteSize doing_unsafe_access_offset() { return byte_offset_of(JavaThread, _doing_unsafe_access); }
 
   // Returns the jni environment for this thread
   JNIEnv* jni_environment()                      { return &_jni_environment; }
@@ -1923,7 +1924,7 @@
   void deoptimize();
   void make_zombies();
 
-  void deoptimize_marked_methods(bool in_handshake);
+  void deoptimized_wrt_marked_nmethods();
 
  public:
   // Returns the running thread as a JavaThread
--- a/src/hotspot/share/runtime/vmOperations.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/runtime/vmOperations.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -118,6 +118,18 @@
   }
 }
 
+void VM_Deoptimize::doit() {
+  // We do not want any GCs to happen while we are in the middle of this VM operation
+  ResourceMark rm;
+  DeoptimizationMarker dm;
+
+  // Deoptimize all activations depending on marked nmethods
+  Deoptimization::deoptimize_dependents();
+
+  // Make the dependent methods not entrant
+  CodeCache::make_marked_nmethods_not_entrant();
+}
+
 void VM_MarkActiveNMethods::doit() {
   NMethodSweeper::mark_active_nmethods();
 }
--- a/src/hotspot/share/runtime/vmOperations.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/runtime/vmOperations.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -49,6 +49,7 @@
   template(ClearICs)                              \
   template(ForceSafepoint)                        \
   template(ForceAsyncSafepoint)                   \
+  template(Deoptimize)                            \
   template(DeoptimizeFrame)                       \
   template(DeoptimizeAll)                         \
   template(ZombieAll)                             \
@@ -318,6 +319,14 @@
   VM_GTestExecuteAtSafepoint() {}
 };
 
+class VM_Deoptimize: public VM_Operation {
+ public:
+  VM_Deoptimize() {}
+  VMOp_Type type() const                        { return VMOp_Deoptimize; }
+  void doit();
+  bool allow_nested_vm_operations() const        { return true; }
+};
+
 class VM_MarkActiveNMethods: public VM_Operation {
  public:
   VM_MarkActiveNMethods() {}
--- a/src/hotspot/share/runtime/vmThread.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/runtime/vmThread.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -388,7 +388,7 @@
   // For concurrent vm operations, the thread id is set to 0 indicating thread is unknown.
   // This is because the caller thread could have exited already.
   event->set_caller(is_concurrent ? 0 : JFR_THREAD_ID(op->calling_thread()));
-  event->set_safepointId(evaluate_at_safepoint ? SafepointSynchronize::safepoint_counter() : 0);
+  event->set_safepointId(evaluate_at_safepoint ? SafepointSynchronize::safepoint_id() : 0);
   event->commit();
 }
 
--- a/src/hotspot/share/services/diagnosticCommand.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/services/diagnosticCommand.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -129,7 +129,7 @@
 
   // Debug on cmd (only makes sense with JVMTI since the agentlib needs it).
 #if INCLUDE_JVMTI
-  DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<DebugOnCmdStartDCmd>(full_export, true, false));
+  DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<DebugOnCmdStartDCmd>(full_export, true, true));
 #endif // INCLUDE_JVMTI
 
 }
--- a/src/hotspot/share/services/dtraceAttacher.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/services/dtraceAttacher.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,6 +33,23 @@
 
 #ifdef SOLARIS
 
+class VM_DeoptimizeTheWorld : public VM_Operation {
+ public:
+  VMOp_Type type() const {
+    return VMOp_DeoptimizeTheWorld;
+  }
+  void doit() {
+    CodeCache::mark_all_nmethods_for_deoptimization();
+    ResourceMark rm;
+    DeoptimizationMarker dm;
+    // Deoptimize all activations depending on marked methods
+    Deoptimization::deoptimize_dependents();
+
+    // Mark the dependent methods non entrant
+    CodeCache::make_marked_nmethods_not_entrant();
+  }
+};
+
 static void set_bool_flag(const char* flag, bool value) {
   JVMFlag::boolAtPut((char*)flag, strlen(flag), &value,
                               JVMFlag::ATTACH_ON_DEMAND);
@@ -57,8 +74,8 @@
 
   if (changed) {
     // one or more flags changed, need to deoptimize
-    CodeCache::mark_all_nmethods_for_deoptimization();
-    Deoptimization::deoptimize_all_marked();
+    VM_DeoptimizeTheWorld op;
+    VMThread::execute(&op);
   }
 }
 
@@ -80,8 +97,8 @@
   }
   if (changed) {
     // one or more flags changed, need to deoptimize
-    CodeCache::mark_all_nmethods_for_deoptimization();
-    Deoptimization::deoptimize_all_marked();
+    VM_DeoptimizeTheWorld op;
+    VMThread::execute(&op);
   }
 }
 
--- a/src/hotspot/share/utilities/concurrentHashTable.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/utilities/concurrentHashTable.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -38,8 +38,9 @@
 class Thread;
 class Mutex;
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
+template <typename CONFIG, MEMFLAGS F>
 class ConcurrentHashTable : public CHeapObj<F> {
+  typedef typename CONFIG::Value VALUE;
  private:
   // This is the internal node structure.
   // Only constructed with placement new from memory allocated with MEMFLAGS of
@@ -252,10 +253,10 @@
   class ScopedCS: public StackObj {
    protected:
     Thread* _thread;
-    ConcurrentHashTable<VALUE, CONFIG, F>* _cht;
+    ConcurrentHashTable<CONFIG, F>* _cht;
     GlobalCounter::CSContext _cs_context;
    public:
-    ScopedCS(Thread* thread, ConcurrentHashTable<VALUE, CONFIG, F>* cht);
+    ScopedCS(Thread* thread, ConcurrentHashTable<CONFIG, F>* cht);
     ~ScopedCS();
   };
 
@@ -473,26 +474,12 @@
                      const char* table_name);
 
   // Moves all nodes from this table to to_cht
-  bool try_move_nodes_to(Thread* thread, ConcurrentHashTable<VALUE, CONFIG, F>* to_cht);
-
-  // This is a Curiously Recurring Template Pattern (CRPT) interface for the
-  // specialization.
-  struct BaseConfig {
-   public:
-    // Called when the hash table needs the hash for a VALUE.
-    static uintx get_hash(const VALUE& value, bool* dead) {
-      return CONFIG::get_hash(value, dead);
-    }
-    // Default node allocation.
-    static void* allocate_node(size_t size, const VALUE& value);
-    // Default node reclamation.
-    static void free_node(void* memory, const VALUE& value);
-  };
+  bool try_move_nodes_to(Thread* thread, ConcurrentHashTable<CONFIG, F>* to_cht);
 
   // Scoped multi getter.
   class MultiGetHandle : private ScopedCS {
    public:
-    MultiGetHandle(Thread* thread, ConcurrentHashTable<VALUE, CONFIG, F>* cht)
+    MultiGetHandle(Thread* thread, ConcurrentHashTable<CONFIG, F>* cht)
       : ScopedCS(thread, cht) {}
     // In the MultiGetHandle scope you can lookup items matching LOOKUP_FUNC.
     // The VALUEs are safe as long as you never save the VALUEs outside the
--- a/src/hotspot/share/utilities/concurrentHashTable.inline.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/utilities/concurrentHashTable.inline.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -53,28 +53,28 @@
 #endif
 
 // Node
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-inline typename ConcurrentHashTable<VALUE, CONFIG, F>::Node*
-ConcurrentHashTable<VALUE, CONFIG, F>::
+template <typename CONFIG, MEMFLAGS F>
+inline typename ConcurrentHashTable<CONFIG, F>::Node*
+ConcurrentHashTable<CONFIG, F>::
   Node::next() const
 {
   return OrderAccess::load_acquire(&_next);
 }
 
 // Bucket
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-inline typename ConcurrentHashTable<VALUE, CONFIG, F>::Node*
-ConcurrentHashTable<VALUE, CONFIG, F>::
+template <typename CONFIG, MEMFLAGS F>
+inline typename ConcurrentHashTable<CONFIG, F>::Node*
+ConcurrentHashTable<CONFIG, F>::
   Bucket::first_raw() const
 {
   return OrderAccess::load_acquire(&_first);
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-inline void ConcurrentHashTable<VALUE, CONFIG, F>::
+template <typename CONFIG, MEMFLAGS F>
+inline void ConcurrentHashTable<CONFIG, F>::
   Bucket::release_assign_node_ptr(
-    typename ConcurrentHashTable<VALUE, CONFIG, F>::Node* const volatile * dst,
-    typename ConcurrentHashTable<VALUE, CONFIG, F>::Node* node) const
+    typename ConcurrentHashTable<CONFIG, F>::Node* const volatile * dst,
+    typename ConcurrentHashTable<CONFIG, F>::Node* node) const
 {
   // Due to this assert this methods is not static.
   assert(is_locked(), "Must be locked.");
@@ -82,31 +82,31 @@
   OrderAccess::release_store(tmp, clear_set_state(node, *dst));
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-inline typename ConcurrentHashTable<VALUE, CONFIG, F>::Node*
-ConcurrentHashTable<VALUE, CONFIG, F>::
+template <typename CONFIG, MEMFLAGS F>
+inline typename ConcurrentHashTable<CONFIG, F>::Node*
+ConcurrentHashTable<CONFIG, F>::
   Bucket::first() const
 {
   // We strip the states bit before returning the ptr.
   return clear_state(OrderAccess::load_acquire(&_first));
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-inline bool ConcurrentHashTable<VALUE, CONFIG, F>::
+template <typename CONFIG, MEMFLAGS F>
+inline bool ConcurrentHashTable<CONFIG, F>::
   Bucket::have_redirect() const
 {
   return is_state(first_raw(), STATE_REDIRECT_BIT);
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-inline bool ConcurrentHashTable<VALUE, CONFIG, F>::
+template <typename CONFIG, MEMFLAGS F>
+inline bool ConcurrentHashTable<CONFIG, F>::
   Bucket::is_locked() const
 {
   return is_state(first_raw(), STATE_LOCK_BIT);
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-inline void ConcurrentHashTable<VALUE, CONFIG, F>::
+template <typename CONFIG, MEMFLAGS F>
+inline void ConcurrentHashTable<CONFIG, F>::
   Bucket::lock()
 {
   int i = 0;
@@ -123,10 +123,10 @@
   }
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-inline void ConcurrentHashTable<VALUE, CONFIG, F>::
+template <typename CONFIG, MEMFLAGS F>
+inline void ConcurrentHashTable<CONFIG, F>::
   Bucket::release_assign_last_node_next(
-     typename ConcurrentHashTable<VALUE, CONFIG, F>::Node* node)
+     typename ConcurrentHashTable<CONFIG, F>::Node* node)
 {
   assert(is_locked(), "Must be locked.");
   Node* const volatile * ret = first_ptr();
@@ -136,10 +136,10 @@
   release_assign_node_ptr(ret, node);
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-inline bool ConcurrentHashTable<VALUE, CONFIG, F>::
-  Bucket::cas_first(typename ConcurrentHashTable<VALUE, CONFIG, F>::Node* node,
-                    typename ConcurrentHashTable<VALUE, CONFIG, F>::Node* expect
+template <typename CONFIG, MEMFLAGS F>
+inline bool ConcurrentHashTable<CONFIG, F>::
+  Bucket::cas_first(typename ConcurrentHashTable<CONFIG, F>::Node* node,
+                    typename ConcurrentHashTable<CONFIG, F>::Node* expect
                     )
 {
   if (is_locked()) {
@@ -151,8 +151,8 @@
   return false;
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-inline bool ConcurrentHashTable<VALUE, CONFIG, F>::
+template <typename CONFIG, MEMFLAGS F>
+inline bool ConcurrentHashTable<CONFIG, F>::
   Bucket::trylock()
 {
   if (is_locked()) {
@@ -166,8 +166,8 @@
   return false;
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-inline void ConcurrentHashTable<VALUE, CONFIG, F>::
+template <typename CONFIG, MEMFLAGS F>
+inline void ConcurrentHashTable<CONFIG, F>::
   Bucket::unlock()
 {
   assert(is_locked(), "Must be locked.");
@@ -176,8 +176,8 @@
   OrderAccess::release_store(&_first, clear_state(first()));
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-inline void ConcurrentHashTable<VALUE, CONFIG, F>::
+template <typename CONFIG, MEMFLAGS F>
+inline void ConcurrentHashTable<CONFIG, F>::
   Bucket::redirect()
 {
   assert(is_locked(), "Must be locked.");
@@ -185,8 +185,8 @@
 }
 
 // InternalTable
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-inline ConcurrentHashTable<VALUE, CONFIG, F>::
+template <typename CONFIG, MEMFLAGS F>
+inline ConcurrentHashTable<CONFIG, F>::
   InternalTable::InternalTable(size_t log2_size)
     : _log2_size(log2_size), _size(((size_t)1ul) << _log2_size),
       _hash_mask(~(~((size_t)0) << _log2_size))
@@ -201,17 +201,17 @@
   }
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-inline ConcurrentHashTable<VALUE, CONFIG, F>::
+template <typename CONFIG, MEMFLAGS F>
+inline ConcurrentHashTable<CONFIG, F>::
   InternalTable::~InternalTable()
 {
   FREE_C_HEAP_ARRAY(Bucket, _buckets);
 }
 
 // ScopedCS
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-inline ConcurrentHashTable<VALUE, CONFIG, F>::
-  ScopedCS::ScopedCS(Thread* thread, ConcurrentHashTable<VALUE, CONFIG, F>* cht)
+template <typename CONFIG, MEMFLAGS F>
+inline ConcurrentHashTable<CONFIG, F>::
+  ScopedCS::ScopedCS(Thread* thread, ConcurrentHashTable<CONFIG, F>* cht)
     : _thread(thread),
       _cht(cht),
       _cs_context(GlobalCounter::critical_section_begin(_thread))
@@ -222,40 +222,25 @@
   }
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-inline ConcurrentHashTable<VALUE, CONFIG, F>::
+template <typename CONFIG, MEMFLAGS F>
+inline ConcurrentHashTable<CONFIG, F>::
   ScopedCS::~ScopedCS()
 {
   GlobalCounter::critical_section_end(_thread, _cs_context);
 }
 
-// BaseConfig
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-inline void* ConcurrentHashTable<VALUE, CONFIG, F>::
-  BaseConfig::allocate_node(size_t size, const VALUE& value)
-{
-  return AllocateHeap(size, F);
-}
-
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-inline void ConcurrentHashTable<VALUE, CONFIG, F>::
-  BaseConfig::free_node(void* memory, const VALUE& value)
-{
-  FreeHeap(memory);
-}
-
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
+template <typename CONFIG, MEMFLAGS F>
 template <typename LOOKUP_FUNC>
-inline VALUE* ConcurrentHashTable<VALUE, CONFIG, F>::
+inline typename CONFIG::Value* ConcurrentHashTable<CONFIG, F>::
   MultiGetHandle::get(LOOKUP_FUNC& lookup_f, bool* grow_hint)
 {
   return ScopedCS::_cht->internal_get(ScopedCS::_thread, lookup_f, grow_hint);
 }
 
 // HaveDeletables
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
+template <typename CONFIG, MEMFLAGS F>
 template <typename EVALUATE_FUNC>
-inline bool ConcurrentHashTable<VALUE, CONFIG, F>::
+inline bool ConcurrentHashTable<CONFIG, F>::
   HaveDeletables<true, EVALUATE_FUNC>::have_deletable(Bucket* bucket,
                                                       EVALUATE_FUNC& eval_f,
                                                       Bucket* prefetch_bucket)
@@ -281,9 +266,9 @@
   return false;
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
+template <typename CONFIG, MEMFLAGS F>
 template <bool b, typename EVALUATE_FUNC>
-inline bool ConcurrentHashTable<VALUE, CONFIG, F>::
+inline bool ConcurrentHashTable<CONFIG, F>::
   HaveDeletables<b, EVALUATE_FUNC>::have_deletable(Bucket* bucket,
                                                    EVALUATE_FUNC& eval_f,
                                                    Bucket* preb)
@@ -297,8 +282,8 @@
 }
 
 // ConcurrentHashTable
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-inline void ConcurrentHashTable<VALUE, CONFIG, F>::
+template <typename CONFIG, MEMFLAGS F>
+inline void ConcurrentHashTable<CONFIG, F>::
   write_synchonize_on_visible_epoch(Thread* thread)
 {
   assert(_resize_lock_owner == thread, "Re-size lock not held");
@@ -314,8 +299,8 @@
   GlobalCounter::write_synchronize();
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-inline bool ConcurrentHashTable<VALUE, CONFIG, F>::
+template <typename CONFIG, MEMFLAGS F>
+inline bool ConcurrentHashTable<CONFIG, F>::
   try_resize_lock(Thread* locker)
 {
   if (_resize_lock->try_lock()) {
@@ -333,8 +318,8 @@
   return true;
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-inline void ConcurrentHashTable<VALUE, CONFIG, F>::
+template <typename CONFIG, MEMFLAGS F>
+inline void ConcurrentHashTable<CONFIG, F>::
   lock_resize_lock(Thread* locker)
 {
   size_t i = 0;
@@ -358,8 +343,8 @@
   _invisible_epoch = 0;
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-inline void ConcurrentHashTable<VALUE, CONFIG, F>::
+template <typename CONFIG, MEMFLAGS F>
+inline void ConcurrentHashTable<CONFIG, F>::
   unlock_resize_lock(Thread* locker)
 {
   _invisible_epoch = 0;
@@ -368,8 +353,8 @@
   _resize_lock->unlock();
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-inline void ConcurrentHashTable<VALUE, CONFIG, F>::
+template <typename CONFIG, MEMFLAGS F>
+inline void ConcurrentHashTable<CONFIG, F>::
   free_nodes()
 {
   // We assume we are not MT during freeing.
@@ -384,25 +369,25 @@
   }
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-inline typename ConcurrentHashTable<VALUE, CONFIG, F>::InternalTable*
-ConcurrentHashTable<VALUE, CONFIG, F>::
+template <typename CONFIG, MEMFLAGS F>
+inline typename ConcurrentHashTable<CONFIG, F>::InternalTable*
+ConcurrentHashTable<CONFIG, F>::
   get_table() const
 {
   return OrderAccess::load_acquire(&_table);
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-inline typename ConcurrentHashTable<VALUE, CONFIG, F>::InternalTable*
-ConcurrentHashTable<VALUE, CONFIG, F>::
+template <typename CONFIG, MEMFLAGS F>
+inline typename ConcurrentHashTable<CONFIG, F>::InternalTable*
+ConcurrentHashTable<CONFIG, F>::
   get_new_table() const
 {
   return OrderAccess::load_acquire(&_new_table);
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-inline typename ConcurrentHashTable<VALUE, CONFIG, F>::InternalTable*
-ConcurrentHashTable<VALUE, CONFIG, F>::
+template <typename CONFIG, MEMFLAGS F>
+inline typename ConcurrentHashTable<CONFIG, F>::InternalTable*
+ConcurrentHashTable<CONFIG, F>::
   set_table_from_new()
 {
   InternalTable* old_table = _table;
@@ -416,8 +401,8 @@
   return old_table;
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-inline void ConcurrentHashTable<VALUE, CONFIG, F>::
+template <typename CONFIG, MEMFLAGS F>
+inline void ConcurrentHashTable<CONFIG, F>::
   internal_grow_range(Thread* thread, size_t start, size_t stop)
 {
   assert(stop <= _table->_size, "Outside backing array");
@@ -456,9 +441,9 @@
   }
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
+template <typename CONFIG, MEMFLAGS F>
 template <typename LOOKUP_FUNC, typename DELETE_FUNC>
-inline bool ConcurrentHashTable<VALUE, CONFIG, F>::
+inline bool ConcurrentHashTable<CONFIG, F>::
   internal_remove(Thread* thread, LOOKUP_FUNC& lookup_f, DELETE_FUNC& delete_f)
 {
   Bucket* bucket = get_bucket_locked(thread, lookup_f.get_hash());
@@ -489,9 +474,9 @@
   return true;
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
+template <typename CONFIG, MEMFLAGS F>
 template <typename EVALUATE_FUNC, typename DELETE_FUNC>
-inline void ConcurrentHashTable<VALUE, CONFIG, F>::
+inline void ConcurrentHashTable<CONFIG, F>::
   do_bulk_delete_locked_for(Thread* thread, size_t start_idx, size_t stop_idx,
                             EVALUATE_FUNC& eval_f, DELETE_FUNC& del_f, bool is_mt)
 {
@@ -542,9 +527,9 @@
   GlobalCounter::critical_section_end(thread, cs_context);
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
+template <typename CONFIG, MEMFLAGS F>
 template <typename LOOKUP_FUNC>
-inline void ConcurrentHashTable<VALUE, CONFIG, F>::
+inline void ConcurrentHashTable<CONFIG, F>::
   delete_in_bucket(Thread* thread, Bucket* bucket, LOOKUP_FUNC& lookup_f)
 {
   assert(bucket->is_locked(), "Must be locked.");
@@ -579,9 +564,9 @@
   }
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-inline typename ConcurrentHashTable<VALUE, CONFIG, F>::Bucket*
-ConcurrentHashTable<VALUE, CONFIG, F>::
+template <typename CONFIG, MEMFLAGS F>
+inline typename ConcurrentHashTable<CONFIG, F>::Bucket*
+ConcurrentHashTable<CONFIG, F>::
   get_bucket(uintx hash) const
 {
   InternalTable* table = get_table();
@@ -593,9 +578,9 @@
   return bucket;
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-inline typename ConcurrentHashTable<VALUE, CONFIG, F>::Bucket*
-ConcurrentHashTable<VALUE, CONFIG, F>::
+template <typename CONFIG, MEMFLAGS F>
+inline typename ConcurrentHashTable<CONFIG, F>::Bucket*
+ConcurrentHashTable<CONFIG, F>::
   get_bucket_locked(Thread* thread, const uintx hash)
 {
   Bucket* bucket;
@@ -624,10 +609,10 @@
 }
 
 // Always called within critical section
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
+template <typename CONFIG, MEMFLAGS F>
 template <typename LOOKUP_FUNC>
-typename ConcurrentHashTable<VALUE, CONFIG, F>::Node*
-ConcurrentHashTable<VALUE, CONFIG, F>::
+typename ConcurrentHashTable<CONFIG, F>::Node*
+ConcurrentHashTable<CONFIG, F>::
   get_node(const Bucket* const bucket, LOOKUP_FUNC& lookup_f,
            bool* have_dead, size_t* loops) const
 {
@@ -650,8 +635,8 @@
   return node;
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-inline bool ConcurrentHashTable<VALUE, CONFIG, F>::
+template <typename CONFIG, MEMFLAGS F>
+inline bool ConcurrentHashTable<CONFIG, F>::
   unzip_bucket(Thread* thread, InternalTable* old_table,
                InternalTable* new_table, size_t even_index, size_t odd_index)
 {
@@ -708,8 +693,8 @@
   return true;
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-inline bool ConcurrentHashTable<VALUE, CONFIG, F>::
+template <typename CONFIG, MEMFLAGS F>
+inline bool ConcurrentHashTable<CONFIG, F>::
   internal_shrink_prolog(Thread* thread, size_t log2_size)
 {
   if (!try_resize_lock(thread)) {
@@ -725,8 +710,8 @@
   return true;
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-inline void ConcurrentHashTable<VALUE, CONFIG, F>::
+template <typename CONFIG, MEMFLAGS F>
+inline void ConcurrentHashTable<CONFIG, F>::
   internal_shrink_epilog(Thread* thread)
 {
   assert(_resize_lock_owner == thread, "Re-size lock not held");
@@ -744,8 +729,8 @@
   delete old_table;
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-inline void ConcurrentHashTable<VALUE, CONFIG, F>::
+template <typename CONFIG, MEMFLAGS F>
+inline void ConcurrentHashTable<CONFIG, F>::
   internal_shrink_range(Thread* thread, size_t start, size_t stop)
 {
   // The state is also copied here.
@@ -781,8 +766,8 @@
   }
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-inline bool ConcurrentHashTable<VALUE, CONFIG, F>::
+template <typename CONFIG, MEMFLAGS F>
+inline bool ConcurrentHashTable<CONFIG, F>::
   internal_shrink(Thread* thread, size_t log2_size)
 {
   if (!internal_shrink_prolog(thread, log2_size)) {
@@ -796,8 +781,8 @@
   return true;
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-inline bool ConcurrentHashTable<VALUE, CONFIG, F>::
+template <typename CONFIG, MEMFLAGS F>
+inline bool ConcurrentHashTable<CONFIG, F>::
   internal_grow_prolog(Thread* thread, size_t log2_size)
 {
   // This double checking of _size_limit_reached/is_max_size_reached()
@@ -825,8 +810,8 @@
   return true;
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-inline void ConcurrentHashTable<VALUE, CONFIG, F>::
+template <typename CONFIG, MEMFLAGS F>
+inline void ConcurrentHashTable<CONFIG, F>::
   internal_grow_epilog(Thread* thread)
 {
   assert(_resize_lock_owner == thread, "Should be locked");
@@ -843,8 +828,8 @@
   delete old_table;
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-inline bool ConcurrentHashTable<VALUE, CONFIG, F>::
+template <typename CONFIG, MEMFLAGS F>
+inline bool ConcurrentHashTable<CONFIG, F>::
   internal_grow(Thread* thread, size_t log2_size)
 {
   if (!internal_grow_prolog(thread, log2_size)) {
@@ -859,9 +844,9 @@
 }
 
 // Always called within critical section
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
+template <typename CONFIG, MEMFLAGS F>
 template <typename LOOKUP_FUNC>
-inline VALUE* ConcurrentHashTable<VALUE, CONFIG, F>::
+inline typename CONFIG::Value* ConcurrentHashTable<CONFIG, F>::
   internal_get(Thread* thread, LOOKUP_FUNC& lookup_f, bool* grow_hint)
 {
   bool clean = false;
@@ -880,9 +865,9 @@
   return ret;
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
+template <typename CONFIG, MEMFLAGS F>
 template <typename LOOKUP_FUNC>
-inline bool ConcurrentHashTable<VALUE, CONFIG, F>::
+inline bool ConcurrentHashTable<CONFIG, F>::
   internal_insert(Thread* thread, LOOKUP_FUNC& lookup_f, const VALUE& value,
                   bool* grow_hint, bool* clean_hint)
 {
@@ -945,9 +930,9 @@
   return ret;
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
+template <typename CONFIG, MEMFLAGS F>
 template <typename FUNC>
-inline bool ConcurrentHashTable<VALUE, CONFIG, F>::
+inline bool ConcurrentHashTable<CONFIG, F>::
   visit_nodes(Bucket* bucket, FUNC& visitor_f)
 {
   Node* current_node = bucket->first();
@@ -960,9 +945,9 @@
   return true;
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
+template <typename CONFIG, MEMFLAGS F>
 template <typename FUNC>
-inline void ConcurrentHashTable<VALUE, CONFIG, F>::
+inline void ConcurrentHashTable<CONFIG, F>::
   do_scan_locked(Thread* thread, FUNC& scan_f)
 {
   assert(_resize_lock_owner == thread, "Re-size lock not held");
@@ -977,9 +962,9 @@
   } /* ends critical section */
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
+template <typename CONFIG, MEMFLAGS F>
 template <typename EVALUATE_FUNC>
-inline size_t ConcurrentHashTable<VALUE, CONFIG, F>::
+inline size_t ConcurrentHashTable<CONFIG, F>::
   delete_check_nodes(Bucket* bucket, EVALUATE_FUNC& eval_f,
                      size_t num_del, Node** ndel)
 {
@@ -1004,8 +989,8 @@
 }
 
 // Constructor
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-inline ConcurrentHashTable<VALUE, CONFIG, F>::
+template <typename CONFIG, MEMFLAGS F>
+inline ConcurrentHashTable<CONFIG, F>::
   ConcurrentHashTable(size_t log2size, size_t log2size_limit, size_t grow_hint)
     : _new_table(NULL), _log2_size_limit(log2size_limit),
        _log2_start_size(log2size), _grow_hint(grow_hint),
@@ -1021,8 +1006,8 @@
   _size_limit_reached = _table->_log2_size == _log2_size_limit;
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-inline ConcurrentHashTable<VALUE, CONFIG, F>::
+template <typename CONFIG, MEMFLAGS F>
+inline ConcurrentHashTable<CONFIG, F>::
   ~ConcurrentHashTable()
 {
   delete _resize_lock;
@@ -1030,16 +1015,16 @@
   delete _table;
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-inline size_t ConcurrentHashTable<VALUE, CONFIG, F>::
+template <typename CONFIG, MEMFLAGS F>
+inline size_t ConcurrentHashTable<CONFIG, F>::
   get_size_log2(Thread* thread)
 {
   ScopedCS cs(thread, this);
   return _table->_log2_size;
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-inline bool ConcurrentHashTable<VALUE, CONFIG, F>::
+template <typename CONFIG, MEMFLAGS F>
+inline bool ConcurrentHashTable<CONFIG, F>::
   shrink(Thread* thread, size_t size_limit_log2)
 {
   size_t tmp = size_limit_log2 == 0 ? _log2_start_size : size_limit_log2;
@@ -1047,17 +1032,17 @@
   return ret;
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-inline bool ConcurrentHashTable<VALUE, CONFIG, F>::
+template <typename CONFIG, MEMFLAGS F>
+inline bool ConcurrentHashTable<CONFIG, F>::
   grow(Thread* thread, size_t size_limit_log2)
 {
   size_t tmp = size_limit_log2 == 0 ? _log2_size_limit : size_limit_log2;
   return internal_grow(thread, tmp);
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
+template <typename CONFIG, MEMFLAGS F>
 template <typename LOOKUP_FUNC, typename FOUND_FUNC>
-inline bool ConcurrentHashTable<VALUE, CONFIG, F>::
+inline bool ConcurrentHashTable<CONFIG, F>::
   get(Thread* thread, LOOKUP_FUNC& lookup_f, FOUND_FUNC& found_f, bool* grow_hint)
 {
   bool ret = false;
@@ -1070,8 +1055,8 @@
   return ret;
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-inline bool ConcurrentHashTable<VALUE, CONFIG, F>::
+template <typename CONFIG, MEMFLAGS F>
+inline bool ConcurrentHashTable<CONFIG, F>::
   unsafe_insert(const VALUE& value) {
   bool dead_hash = false;
   size_t hash = CONFIG::get_hash(value, &dead_hash);
@@ -1090,9 +1075,9 @@
   return true;
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
+template <typename CONFIG, MEMFLAGS F>
 template <typename SCAN_FUNC>
-inline bool ConcurrentHashTable<VALUE, CONFIG, F>::
+inline bool ConcurrentHashTable<CONFIG, F>::
   try_scan(Thread* thread, SCAN_FUNC& scan_f)
 {
   if (!try_resize_lock(thread)) {
@@ -1103,9 +1088,9 @@
   return true;
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
+template <typename CONFIG, MEMFLAGS F>
 template <typename SCAN_FUNC>
-inline void ConcurrentHashTable<VALUE, CONFIG, F>::
+inline void ConcurrentHashTable<CONFIG, F>::
   do_scan(Thread* thread, SCAN_FUNC& scan_f)
 {
   assert(!SafepointSynchronize::is_at_safepoint(),
@@ -1117,9 +1102,9 @@
   assert(_resize_lock_owner != thread, "Re-size lock held");
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
+template <typename CONFIG, MEMFLAGS F>
 template <typename SCAN_FUNC>
-inline void ConcurrentHashTable<VALUE, CONFIG, F>::
+inline void ConcurrentHashTable<CONFIG, F>::
   do_safepoint_scan(SCAN_FUNC& scan_f)
 {
   // We only allow this method to be used during a safepoint.
@@ -1160,9 +1145,9 @@
   }
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
+template <typename CONFIG, MEMFLAGS F>
 template <typename EVALUATE_FUNC, typename DELETE_FUNC>
-inline bool ConcurrentHashTable<VALUE, CONFIG, F>::
+inline bool ConcurrentHashTable<CONFIG, F>::
   try_bulk_delete(Thread* thread, EVALUATE_FUNC& eval_f, DELETE_FUNC& del_f)
 {
   if (!try_resize_lock(thread)) {
@@ -1174,9 +1159,9 @@
   return true;
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
+template <typename CONFIG, MEMFLAGS F>
 template <typename EVALUATE_FUNC, typename DELETE_FUNC>
-inline void ConcurrentHashTable<VALUE, CONFIG, F>::
+inline void ConcurrentHashTable<CONFIG, F>::
   bulk_delete(Thread* thread, EVALUATE_FUNC& eval_f, DELETE_FUNC& del_f)
 {
   assert(!SafepointSynchronize::is_at_safepoint(),
@@ -1186,9 +1171,9 @@
   unlock_resize_lock(thread);
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
+template <typename CONFIG, MEMFLAGS F>
 template <typename VALUE_SIZE_FUNC>
-inline TableStatistics ConcurrentHashTable<VALUE, CONFIG, F>::
+inline TableStatistics ConcurrentHashTable<CONFIG, F>::
   statistics_calculate(Thread* thread, VALUE_SIZE_FUNC& vs_f)
 {
   NumberSeq summary;
@@ -1213,9 +1198,9 @@
   return TableStatistics(_stats_rate, summary, literal_bytes, sizeof(Bucket), sizeof(Node));
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
+template <typename CONFIG, MEMFLAGS F>
 template <typename VALUE_SIZE_FUNC>
-inline TableStatistics ConcurrentHashTable<VALUE, CONFIG, F>::
+inline TableStatistics ConcurrentHashTable<CONFIG, F>::
   statistics_get(Thread* thread, VALUE_SIZE_FUNC& vs_f, TableStatistics old)
 {
   if (!try_resize_lock(thread)) {
@@ -1228,9 +1213,9 @@
   return ts;
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
+template <typename CONFIG, MEMFLAGS F>
 template <typename VALUE_SIZE_FUNC>
-inline void ConcurrentHashTable<VALUE, CONFIG, F>::
+inline void ConcurrentHashTable<CONFIG, F>::
   statistics_to(Thread* thread, VALUE_SIZE_FUNC& vs_f,
                 outputStream* st, const char* table_name)
 {
@@ -1245,9 +1230,9 @@
   ts.print(st, table_name);
 }
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-inline bool ConcurrentHashTable<VALUE, CONFIG, F>::
-  try_move_nodes_to(Thread* thread, ConcurrentHashTable<VALUE, CONFIG, F>* to_cht)
+template <typename CONFIG, MEMFLAGS F>
+inline bool ConcurrentHashTable<CONFIG, F>::
+  try_move_nodes_to(Thread* thread, ConcurrentHashTable<CONFIG, F>* to_cht)
 {
   if (!try_resize_lock(thread)) {
     return false;
--- a/src/hotspot/share/utilities/concurrentHashTableTasks.inline.hpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/hotspot/share/utilities/concurrentHashTableTasks.inline.hpp	Mon Jul 01 14:57:02 2019 -0700
@@ -32,10 +32,10 @@
 // operations, which they are serialized with each other.
 
 // Base class for pause and/or parallel bulk operations.
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-class ConcurrentHashTable<VALUE, CONFIG, F>::BucketsOperation {
+template <typename CONFIG, MEMFLAGS F>
+class ConcurrentHashTable<CONFIG, F>::BucketsOperation {
  protected:
-  ConcurrentHashTable<VALUE, CONFIG, F>* _cht;
+  ConcurrentHashTable<CONFIG, F>* _cht;
 
   // Default size of _task_size_log2
   static const size_t DEFAULT_TASK_SIZE_LOG2 = 12;
@@ -47,7 +47,7 @@
   size_t _size_log2;      // Table size.
   bool   _is_mt;
 
-  BucketsOperation(ConcurrentHashTable<VALUE, CONFIG, F>* cht, bool is_mt = false)
+  BucketsOperation(ConcurrentHashTable<CONFIG, F>* cht, bool is_mt = false)
     : _cht(cht), _next_to_claim(0), _task_size_log2(DEFAULT_TASK_SIZE_LOG2),
     _stop_task(0), _size_log2(0), _is_mt(is_mt) {}
 
@@ -116,12 +116,12 @@
 };
 
 // For doing pausable/parallel bulk delete.
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-class ConcurrentHashTable<VALUE, CONFIG, F>::BulkDeleteTask :
+template <typename CONFIG, MEMFLAGS F>
+class ConcurrentHashTable<CONFIG, F>::BulkDeleteTask :
   public BucketsOperation
 {
  public:
-  BulkDeleteTask(ConcurrentHashTable<VALUE, CONFIG, F>* cht, bool is_mt = false)
+  BulkDeleteTask(ConcurrentHashTable<CONFIG, F>* cht, bool is_mt = false)
     : BucketsOperation(cht, is_mt) {
   }
   // Before start prepare must be called.
@@ -160,12 +160,12 @@
   }
 };
 
-template <typename VALUE, typename CONFIG, MEMFLAGS F>
-class ConcurrentHashTable<VALUE, CONFIG, F>::GrowTask :
+template <typename CONFIG, MEMFLAGS F>
+class ConcurrentHashTable<CONFIG, F>::GrowTask :
   public BucketsOperation
 {
  public:
-  GrowTask(ConcurrentHashTable<VALUE, CONFIG, F>* cht) : BucketsOperation(cht) {
+  GrowTask(ConcurrentHashTable<CONFIG, F>* cht) : BucketsOperation(cht) {
   }
   // Before start prepare must be called.
   bool prepare(Thread* thread) {
--- a/src/java.base/aix/native/libjli/java_md_aix.c	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.base/aix/native/libjli/java_md_aix.c	Mon Jul 01 14:57:02 2019 -0700
@@ -27,7 +27,7 @@
 
 #include "java_md_aix.h"
 
-static unsigned char dladdr_buffer[0x4000];
+static unsigned char dladdr_buffer[0x8000];
 
 static int fill_dll_info(void) {
     return loadquery(L_GETINFO, dladdr_buffer, sizeof(dladdr_buffer));
--- a/src/java.base/share/classes/com/sun/crypto/provider/PBES1Core.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.base/share/classes/com/sun/crypto/provider/PBES1Core.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -268,17 +268,20 @@
 
         if (algo.equals("DES")) {
             // P || S (password concatenated with salt)
-            byte[] concat = new byte[Math.addExact(passwdBytes.length, salt.length)];
-            System.arraycopy(passwdBytes, 0, concat, 0, passwdBytes.length);
-            System.arraycopy(salt, 0, concat, passwdBytes.length, salt.length);
-
-            // digest P || S with c iterations
-            byte[] toBeHashed = concat;
-            for (int i = 0; i < iCount; i++) {
+            md.update(passwdBytes);
+            md.update(salt);
+            // digest P || S with iCount iterations
+            // first iteration
+            byte[] toBeHashed = md.digest(); // this resets the digest
+            // remaining (iCount - 1) iterations
+            for (int i = 1; i < iCount; ++i) {
                 md.update(toBeHashed);
-                toBeHashed = md.digest(); // this resets the digest
+                try {
+                    md.digest(toBeHashed, 0, toBeHashed.length);
+                } catch (DigestException e) {
+                    throw new ProviderException("Internal error", e);
+                }
             }
-            Arrays.fill(concat, (byte)0x00);
             result = toBeHashed;
         } else if (algo.equals("DESede")) {
             // if the 2 salt halves are the same, invert one of them
@@ -305,13 +308,19 @@
             result = new byte[DESedeKeySpec.DES_EDE_KEY_LEN +
                               DESConstants.DES_BLOCK_SIZE];
             for (i = 0; i < 2; i++) {
-                toBeHashed = new byte[salt.length/2];
-                System.arraycopy(salt, i*(salt.length/2), toBeHashed, 0,
-                                 toBeHashed.length);
-                for (int j=0; j < iCount; j++) {
+                // first iteration
+                md.update(salt, i * (salt.length / 2), salt.length / 2);
+                md.update(passwdBytes);
+                toBeHashed = md.digest();
+                // remaining (iCount - 1) iterations
+                for (int j = 1; j < iCount; ++j) {
                     md.update(toBeHashed);
                     md.update(passwdBytes);
-                    toBeHashed = md.digest();
+                    try {
+                        md.digest(toBeHashed, 0, toBeHashed.length);
+                    } catch (DigestException e) {
+                        throw new ProviderException("Internal error", e);
+                    }
                 }
                 System.arraycopy(toBeHashed, 0, result, i*16,
                                  toBeHashed.length);
--- a/src/java.base/share/classes/java/lang/Throwable.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.base/share/classes/java/lang/Throwable.java	Mon Jul 01 14:57:02 2019 -0700
@@ -693,7 +693,7 @@
                                          Set<Throwable> dejaVu) {
         assert Thread.holdsLock(s.lock());
         if (dejaVu.contains(this)) {
-            s.println("\t[CIRCULAR REFERENCE:" + this + "]");
+            s.println(prefix + caption + "[CIRCULAR REFERENCE: " + this + "]");
         } else {
             dejaVu.add(this);
             // Compute number of frames in common between this and enclosing trace
--- a/src/java.base/share/classes/java/lang/constant/MethodTypeDescImpl.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.base/share/classes/java/lang/constant/MethodTypeDescImpl.java	Mon Jul 01 14:57:02 2019 -0700
@@ -131,8 +131,14 @@
     }
 
     @Override
-    public MethodType resolveConstantDesc(MethodHandles.Lookup lookup) {
-        return MethodType.fromMethodDescriptorString(descriptorString(), lookup.lookupClass().getClassLoader());
+    public MethodType resolveConstantDesc(MethodHandles.Lookup lookup) throws ReflectiveOperationException {
+        MethodType mtype = MethodType.fromMethodDescriptorString(descriptorString(), lookup.lookupClass().getClassLoader());
+        // let's check that the lookup has access to all the types in the method type
+        lookup.accessClass(mtype.returnType());
+        for (Class<?> paramType: mtype.parameterArray()) {
+            lookup.accessClass(paramType);
+        }
+        return mtype;
     }
 
     /**
--- a/src/java.base/share/classes/java/net/DatagramSocketImpl.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.base/share/classes/java/net/DatagramSocketImpl.java	Mon Jul 01 14:57:02 2019 -0700
@@ -268,7 +268,7 @@
      *
      * @implSpec
      * The default implementation of this method first checks that the given
-     * socket option {code name} is not null, then throws {@code
+     * socket option {@code name} is not null, then throws {@code
      * UnsupportedOperationException}. Subclasses should override this method
      * with an appropriate implementation.
      *
@@ -296,7 +296,7 @@
      *
      * @implSpec
      * The default implementation of this method first checks that the given
-     * socket option {code name} is not null, then throws {@code
+     * socket option {@code name} is not null, then throws {@code
      * UnsupportedOperationException}. Subclasses should override this method
      * with an appropriate implementation.
      *
--- a/src/java.base/share/classes/java/net/URLStreamHandler.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.base/share/classes/java/net/URLStreamHandler.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1995, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -81,7 +81,7 @@
      *
      * @implSpec
      * The default implementation of this method first checks that the given
-     * {code URL} and {code Proxy} are not null, then throws {@code
+     * {@code URL} and {@code Proxy} are not null, then throws {@code
      * UnsupportedOperationException}. Subclasses should override this method
      * with an appropriate implementation.
      *
--- a/src/java.base/share/classes/java/nio/MappedByteBuffer.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.base/share/classes/java/nio/MappedByteBuffer.java	Mon Jul 01 14:57:02 2019 -0700
@@ -235,8 +235,11 @@
      * is made.
      *
      * <p> If this buffer was not mapped in read/write mode ({@link
-     * java.nio.channels.FileChannel.MapMode#READ_WRITE}) then invoking this
-     * method has no effect. </p>
+     * java.nio.channels.FileChannel.MapMode#READ_WRITE}) then
+     * invoking this method may have no effect. In particular, the
+     * method has no effect for buffers mapped in read-only or private
+     * mapping modes. This method may or may not have an effect for
+     * implementation-specific mapping modes. </p>
      *
      * @return  This buffer
      */
@@ -271,7 +274,10 @@
      *
      * <p> If this buffer was not mapped in read/write mode ({@link
      * java.nio.channels.FileChannel.MapMode#READ_WRITE}) then
-     * invoking this method has no effect. </p>
+     * invoking this method may have no effect. In particular, the
+     * method has no effect for buffers mapped in read-only or private
+     * mapping modes. This method may or may not have an effect for
+     * implementation-specific mapping modes. </p>
      *
      * @param index
      *        The index of the first byte in the buffer region that is
--- a/src/java.base/share/classes/java/util/DoubleSummaryStatistics.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.base/share/classes/java/util/DoubleSummaryStatistics.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -59,6 +59,8 @@
  * implementation of {@link java.util.stream.Stream#collect Stream.collect()}
  * provides the necessary partitioning, isolation, and merging of results for
  * safe and efficient parallel execution.
+ *
+ * <p>This implementation does not check for overflow of the count.
  * @since 1.8
  */
 public class DoubleSummaryStatistics implements DoubleConsumer {
--- a/src/java.base/share/classes/java/util/IntSummaryStatistics.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.base/share/classes/java/util/IntSummaryStatistics.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -59,7 +59,7 @@
  * provides the necessary partitioning, isolation, and merging of results for
  * safe and efficient parallel execution.
  *
- * <p>This implementation does not check for overflow of the sum.
+ * <p>This implementation does not check for overflow of the count or the sum.
  * @since 1.8
  */
 public class IntSummaryStatistics implements IntConsumer {
--- a/src/java.base/share/classes/java/util/LongSummaryStatistics.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.base/share/classes/java/util/LongSummaryStatistics.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -60,7 +60,7 @@
  * provides the necessary partitioning, isolation, and merging of results for
  * safe and efficient parallel execution.
  *
- * <p>This implementation does not check for overflow of the sum.
+ * <p>This implementation does not check for overflow of the count or the sum.
  * @since 1.8
  */
 public class LongSummaryStatistics implements LongConsumer, IntConsumer {
--- a/src/java.base/share/classes/java/util/regex/Pattern.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.base/share/classes/java/util/regex/Pattern.java	Mon Jul 01 14:57:02 2019 -0700
@@ -357,11 +357,11 @@
  * <a href="#UNIX_LINES">d</a> <a href="#MULTILINE">m</a> <a href="#DOTALL">s</a>
  * <a href="#UNICODE_CASE">u</a> <a href="#COMMENTS">x</a> <a href="#UNICODE_CHARACTER_CLASS">U</a>
  * on - off</td></tr>
- * <tr><th style="vertical-align:top; font-weight:normal" id="non_capture_group_flags"><code>(?idmsux-idmsux:</code><i>X</i>{@code )}&nbsp;&nbsp;</th>
+ * <tr><th style="vertical-align:top; font-weight:normal" id="non_capture_group_flags"><code>(?idmsuxU-idmsuxU:</code><i>X</i>{@code )}&nbsp;&nbsp;</th>
  *     <td headers="matches special non_capture_group_flags"><i>X</i>, as a <a href="#cg">non-capturing group</a> with the
  *         given flags <a href="#CASE_INSENSITIVE">i</a> <a href="#UNIX_LINES">d</a>
  * <a href="#MULTILINE">m</a> <a href="#DOTALL">s</a> <a href="#UNICODE_CASE">u</a >
- * <a href="#COMMENTS">x</a> on - off</td></tr>
+ * <a href="#COMMENTS">x</a> <a href="#UNICODE_CHARACTER_CLASS">U</a> on - off</td></tr>
  * <tr><th style="vertical-align:top; font-weight:normal" id="pos_lookahead">{@code (?=}<i>X</i>{@code )}</th>
  *     <td headers="matches special pos_lookahead"><i>X</i>, via zero-width positive lookahead</td></tr>
  * <tr><th style="vertical-align:top; font-weight:normal" id="neg_lookahead">{@code (?!}<i>X</i>{@code )}</th>
--- a/src/java.base/share/classes/javax/net/ssl/KeyManagerFactory.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.base/share/classes/javax/net/ssl/KeyManagerFactory.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -127,9 +127,10 @@
      *
      * @param algorithm the standard name of the requested algorithm.
      *          See the <a href=
-     *          "{@docRoot}/../specs/security/standard-names.html">
-     *          Java Security Standard Algorithm Names</a> document
-     *          for information about standard algorithm names.
+     *          "{@docRoot}/../specs/security/standard-names.html#keymanagerfactory-algorithms">
+     *          KeyManagerFactory section</a> in the Java Security Standard
+     *          Algorithm Names Specification for information about standard
+     *          algorithm names.
      *
      * @return the new {@code KeyManagerFactory} object
      *
@@ -165,9 +166,10 @@
 
      * @param algorithm the standard name of the requested algorithm.
      *          See the <a href=
-     *          "{@docRoot}/../specs/security/standard-names.html">
-     *          Java Security Standard Algorithm Names</a> document
-     *          for information about standard algorithm names.
+     *          "{@docRoot}/../specs/security/standard-names.html#keymanagerfactory-algorithms">
+     *          KeyManagerFactory section</a> in the Java Security Standard
+     *          Algorithm Names Specification for information about standard
+     *          algorithm names.
      *
      * @param provider the name of the provider.
      *
@@ -209,9 +211,10 @@
      *
      * @param algorithm the standard name of the requested algorithm.
      *          See the <a href=
-     *          "{@docRoot}/../specs/security/standard-names.html">
-     *          Java Security Standard Algorithm Names</a> document
-     *          for information about standard algorithm names.
+     *          "{@docRoot}/../specs/security/standard-names.html#keymanagerfactory-algorithms">
+     *          KeyManagerFactory section</a> in the Java Security Standard
+     *          Algorithm Names Specification for information about standard
+     *          algorithm names.
      *
      * @param provider an instance of the provider.
      *
--- a/src/java.base/share/classes/javax/net/ssl/TrustManagerFactory.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.base/share/classes/javax/net/ssl/TrustManagerFactory.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -141,9 +141,10 @@
      *
      * @param algorithm the standard name of the requested trust management
      *          algorithm.  See the <a href=
-     *          "{@docRoot}/../specs/security/standard-names.html">
-     *          Java Security Standard Algorithm Names</a> document
-     *          for information about standard algorithm names.
+     *          "{@docRoot}/../specs/security/standard-names.html#trustmanagerfactory-algorithms">
+     *          TrustManagerFactory section</a> in the Java Security Standard
+     *          Algorithm Names Specification for information about standard
+     *          algorithm names.
      *
      * @return the new {@code TrustManagerFactory} object
      *
@@ -179,9 +180,10 @@
      *
      * @param algorithm the standard name of the requested trust management
      *          algorithm.  See the <a href=
-     *          "{@docRoot}/../specs/security/standard-names.html">
-     *          Java Security Standard Algorithm Names</a> document
-     *          for information about standard algorithm names.
+     *          "{@docRoot}/../specs/security/standard-names.html#trustmanagerfactory-algorithms">
+     *          TrustManagerFactory section</a> in the Java Security Standard
+     *          Algorithm Names Specification for information about standard
+     *          algorithm names.
      *
      * @param provider the name of the provider.
      *
@@ -223,9 +225,10 @@
      *
      * @param algorithm the standard name of the requested trust management
      *          algorithm.  See the <a href=
-     *          "{@docRoot}/../specs/security/standard-names.html">
-     *          Java Security Standard Algorithm Names</a> document
-     *          for information about standard algorithm names.
+     *          "{@docRoot}/../specs/security/standard-names.html#trustmanagerfactory-algorithms">
+     *          TrustManagerFactory section</a> in the Java Security Standard
+     *          Algorithm Names Specification for information about standard
+     *          algorithm names.
      *
      * @param provider an instance of the provider.
      *
--- a/src/java.base/share/classes/sun/util/locale/provider/CalendarDataUtility.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.base/share/classes/sun/util/locale/provider/CalendarDataUtility.java	Mon Jul 01 14:57:02 2019 -0700
@@ -249,9 +249,15 @@
             switch (requestID) {
             case FIRST_DAY_OF_WEEK:
                 value = calendarDataProvider.getFirstDayOfWeek(locale);
+                if (value == 0) {
+                    value = MONDAY; // default for the world ("001")
+                }
                 break;
             case MINIMAL_DAYS_IN_FIRST_WEEK:
                 value = calendarDataProvider.getMinimalDaysInFirstWeek(locale);
+                if (value == 0) {
+                    value = 1; // default for the world ("001")
+                }
                 break;
             default:
                 throw new InternalError("invalid requestID: " + requestID);
--- a/src/java.desktop/aix/native/libawt/porting_aix.c	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.desktop/aix/native/libawt/porting_aix.c	Mon Jul 01 14:57:02 2019 -0700
@@ -30,7 +30,7 @@
 
 #include "porting_aix.h"
 
-static unsigned char dladdr_buffer[0x4000];
+static unsigned char dladdr_buffer[0x8000];
 
 static void fill_dll_info(void) {
   int rc = loadquery(L_GETINFO,dladdr_buffer, sizeof(dladdr_buffer));
--- a/src/java.desktop/share/classes/javax/swing/plaf/nimbus/doc-files/properties.html	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.desktop/share/classes/javax/swing/plaf/nimbus/doc-files/properties.html	Mon Jul 01 14:57:02 2019 -0700
@@ -2,10 +2,10 @@
 <html lang="en">
 <head>
   <meta charset="utf-8"/>
-  <title>Nimbus colors</title>
+  <title>Colors Used in Nimbus Look and Feel</title>
 </head>
 <!--
- Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 
  This code is free software; you can redistribute it and/or modify it
@@ -31,212 +31,208 @@
 
 <body>
 <main role="main">
-<h1 id="primaryColors">Primary Colors</h1>
+<h1>Colors Used in Nimbus Look and Feel</h1>
+<h2 id="primaryColors">Primary Colors</h2>
 <table>
-<caption>Primary colors used in Nimbus Look And Feel</caption>
+<caption style="display:none">Primary colors used in Nimbus Look And Feel
+</caption>
 <thead>
-<tr><th>Key</th><th>Value</th><th>Preview</th></tr>
-</thead>
-<tbody>
 <tr>
-<td width="250"><code>control</code></td>
-<td><pre>#d6d9df (214,217,223)</pre></td>
-
-<td width="100" bgcolor="#d6d9df">&nbsp;</td>
+  <th scope="col">Key</th>
+  <th scope="col">Value</th>
+  <th scope="col">Preview</th>
 </tr>
+</thead>
+<tbody style="text-align:left">
 <tr>
-<td width="250"><code>info</code></td>
-<td><pre>#f2f2bd (242,242,189)</pre></td>
-<td width="100" bgcolor="#f2f2bd">&nbsp;</td>
+<th scope="row" width="250"><code>control</code></th>
+<td><pre>#d6d9df (214,217,223)</pre></td>
+<td width="100" bgcolor="#d6d9df" aria-label="Color preview">&nbsp;</td>
 </tr>
 <tr>
-<td width="250"><code>nimbusAlertYellow</code></td>
-<td><pre>#ffdc23 (255,220,35)</pre></td>
-<td width="100" bgcolor="#ffdc23">&nbsp;</td>
+<th scope="row" width="250"><code>info</code></th>
+<td><pre>#f2f2bd (242,242,189)</pre></td>
+<td width="100" bgcolor="#f2f2bd" aria-label="Color preview">&nbsp;</td>
 </tr>
 <tr>
-
-<td width="250"><code>nimbusBase</code></td>
-<td><pre>#33628c (51,98,140)</pre></td>
-<td width="100" bgcolor="#33628c">&nbsp;</td>
+<th scope="row" width="250"><code>nimbusAlertYellow</code></th>
+<td><pre>#ffdc23 (255,220,35)</pre></td>
+<td width="100" bgcolor="#ffdc23" aria-label="Color preview">&nbsp;</td>
 </tr>
 <tr>
-<td width="250"><code>nimbusDisabledText</code></td>
-<td><pre>#8e8f91 (142,143,145)</pre></td>
-<td width="100" bgcolor="#8e8f91">&nbsp;</td>
+<th scope="row" width="250"><code>nimbusBase</code></th>
+<td><pre>#33628c (51,98,140)</pre></td>
+<td width="100" bgcolor="#33628c" aria-label="Color preview">&nbsp;</td>
 </tr>
 <tr>
-<td width="250"><code>nimbusFocus</code></td>
-<td><pre>#73a4d1 (115,164,209)</pre></td>
-
-<td width="100" bgcolor="#73a4d1">&nbsp;</td>
+<th scope="row" width="250"><code>nimbusDisabledText</code></th>
+<td><pre>#8e8f91 (142,143,145)</pre></td>
+<td width="100" bgcolor="#8e8f91" aria-label="Color preview">&nbsp;</td>
 </tr>
 <tr>
-<td width="250"><code>nimbusGreen</code></td>
-<td><pre>#b0b332 (176,179,50)</pre></td>
-<td width="100" bgcolor="#b0b332">&nbsp;</td>
-</tr>
-<tr>
-<td width="250"><code>nimbusInfoBlue</code></td>
-<td><pre>#2f5cb4 (47,92,180)</pre></td>
-<td width="100" bgcolor="#2f5cb4">&nbsp;</td>
+<th scope="row" width="250"><code>nimbusFocus</code></th>
+<td><pre>#73a4d1 (115,164,209)</pre></td>
+<td width="100" bgcolor="#73a4d1" aria-label="Color preview">&nbsp;</td>
 </tr>
 <tr>
-
-<td width="250"><code>nimbusLightBackground</code></td>
-<td><pre>#ffffff (255,255,255)</pre></td>
-<td width="100" bgcolor="#ffffff">&nbsp;</td>
+<th scope="row" width="250"><code>nimbusGreen</code></th>
+<td><pre>#b0b332 (176,179,50)</pre></td>
+<td width="100" bgcolor="#b0b332" aria-label="Color preview">&nbsp;</td>
 </tr>
 <tr>
-<td width="250"><code>nimbusOrange</code></td>
-<td><pre>#bf6204 (191,98,4)</pre></td>
-<td width="100" bgcolor="#bf6204">&nbsp;</td>
+<th scope="row" width="250"><code>nimbusInfoBlue</code></th>
+<td><pre>#2f5cb4 (47,92,180)</pre></td>
+<td width="100" bgcolor="#2f5cb4" aria-label="Color preview">&nbsp;</td>
+</tr>
+<tr>
+<th scope="row" width="250"><code>nimbusLightBackground</code></th>
+<td><pre>#ffffff (255,255,255)</pre></td>
+<td width="100" bgcolor="#ffffff" aria-label="Color preview">&nbsp;</td>
 </tr>
 <tr>
-<td width="250"><code>nimbusRed</code></td>
+<th scope="row" width="250"><code>nimbusOrange</code></th>
+<td><pre>#bf6204 (191,98,4)</pre></td>
+<td width="100" bgcolor="#bf6204" aria-label="Color preview">&nbsp;</td>
+</tr>
+<tr>
+<th scope="row" width="250"><code>nimbusRed</code></th>
 <td><pre>#a92e22 (169,46,34)</pre></td>
-
-<td width="100" bgcolor="#a92e22">&nbsp;</td>
+<td width="100" bgcolor="#a92e22" aria-label="Color preview">&nbsp;</td>
 </tr>
 <tr>
-<td width="250"><code>nimbusSelectedText</code></td>
+<th scope="row" width="250"><code>nimbusSelectedText</code></th>
 <td><pre>#ffffff (255,255,255)</pre></td>
-<td width="100" bgcolor="#ffffff">&nbsp;</td>
+<td width="100" bgcolor="#ffffff" aria-label="Color preview">&nbsp;</td>
 </tr>
 <tr>
-<td width="250"><code>nimbusSelectionBackground</code></td>
+<th scope="row" width="250"><code>nimbusSelectionBackground</code></th>
 <td><pre>#39698a (57,105,138)</pre></td>
-<td width="100" bgcolor="#39698a">&nbsp;</td>
+<td width="100" bgcolor="#39698a" aria-label="Color preview">&nbsp;</td>
 </tr>
 <tr>
-
-<td width="250"><code>text</code></td>
+<th scope="row" width="250"><code>text</code></th>
 <td><pre>#000000 (0,0,0)</pre></td>
-<td width="100" bgcolor="#000000">&nbsp;</td>
+<td width="100" bgcolor="#000000" aria-label="Color preview">&nbsp;</td>
 </tr>
 </tbody>
 </table>
 
-<h1 id="secondaryColors">Secondary Colors</h1>
+<h2 id="secondaryColors">Secondary Colors</h2>
 <table>
-<caption>Secondary colors used in Nimbus Look And Feel </caption>
+<caption style="display:none">Secondary colors used in Nimbus Look And Feel
+</caption>
 <thead>
-<tr><th>Key</th><th>Value</th><th>Preview</th></tr>
+<tr>
+  <th scope="col">Key</th>
+  <th scope="col">Value</th>
+  <th scope="col">Preview</th>
+</tr>
 </thead>
-<tbody>
+<tbody style="text-align:left">
 <tr>
-<td width="250"><code>activeCaption</code></td>
-
+<th scope="row" width="250"><code>activeCaption</code></th>
 <td><pre>#babec6 (186,190,198)</pre></td>
-<td width="100" bgcolor="#babec6">&nbsp;</td>
+<td width="100" bgcolor="#babec6" aria-label="Color preview">&nbsp;</td>
 </tr>
 <tr>
-<td width="250"><code>background</code></td>
+<th scope="row" width="250"><code>background</code></th>
 <td><pre>#d6d9df (214,217,223)</pre></td>
-<td width="100" bgcolor="#d6d9df">&nbsp;</td>
+<td width="100" bgcolor="#d6d9df" aria-label="Color preview">&nbsp;</td>
 </tr>
 <tr>
-<td width="250"><code>controlDkShadow</code></td>
+<th scope="row" width="250"><code>controlDkShadow</code></th>
 <td><pre>#a4abb8 (164,171,184)</pre></td>
-<td width="100" bgcolor="#a4abb8">&nbsp;</td>
-
+<td width="100" bgcolor="#a4abb8" aria-label="Color preview">&nbsp;</td>
 </tr>
 <tr>
-<td width="250"><code>controlHighlight</code></td>
+<th scope="row" width="250"><code>controlHighlight</code></th>
 <td><pre>#e9ecf2 (233,236,242)</pre></td>
-<td width="100" bgcolor="#e9ecf2">&nbsp;</td>
+<td width="100" bgcolor="#e9ecf2" aria-label="Color preview">&nbsp;</td>
 </tr>
 <tr>
-<td width="250"><code>controlLHighlight</code></td>
+<th scope="row" width="250"><code>controlLHighlight</code></th>
 <td><pre>#f7f8fa (247,248,250)</pre></td>
-<td width="100" bgcolor="#f7f8fa">&nbsp;</td>
+<td width="100" bgcolor="#f7f8fa" aria-label="Color preview">&nbsp;</td>
 </tr>
 <tr>
-<td width="250"><code>controlShadow</code></td>
-
+<th scope="row" width="250"><code>controlShadow</code></th>
 <td><pre>#ccd3e0 (204,211,224)</pre></td>
-<td width="100" bgcolor="#ccd3e0">&nbsp;</td>
+<td width="100" bgcolor="#ccd3e0" aria-label="Color preview">&nbsp;</td>
 </tr>
 <tr>
-<td width="250"><code>controlText</code></td>
+<th scope="row" width="250"><code>controlText</code></th>
 <td><pre>#000000 (0,0,0)</pre></td>
-<td width="100" bgcolor="#000000">&nbsp;</td>
+<td width="100" bgcolor="#000000" aria-label="Color preview">&nbsp;</td>
 </tr>
 <tr>
-<td width="250"><code>desktop</code></td>
+<th scope="row" width="250"><code>desktop</code></th>
 <td><pre>#3d6079 (61,96,121)</pre></td>
-<td width="100" bgcolor="#3d6079">&nbsp;</td>
-
+<td width="100" bgcolor="#3d6079" aria-label="Color preview">&nbsp;</td>
 </tr>
 <tr>
-<td width="250"><code>inactiveCaption</code></td>
+<th scope="row" width="250"><code>inactiveCaption</code></th>
 <td><pre>#bdc1c8 (189,193,200)</pre></td>
-<td width="100" bgcolor="#bdc1c8">&nbsp;</td>
+<td width="100" bgcolor="#bdc1c8" aria-label="Color preview">&nbsp;</td>
 </tr>
 <tr>
-<td width="250"><code>infoText</code></td>
+<th scope="row" width="250"><code>infoText</code></th>
 <td><pre>#000000 (0,0,0)</pre></td>
-<td width="100" bgcolor="#000000">&nbsp;</td>
+<td width="100" bgcolor="#000000" aria-label="Color preview">&nbsp;</td>
 </tr>
 <tr>
-<td width="250"><code>menu</code></td>
-
+<th scope="row" width="250"><code>menu</code></th>
 <td><pre>#edeff2 (237,239,242)</pre></td>
-<td width="100" bgcolor="#edeff2">&nbsp;</td>
+<td width="100" bgcolor="#edeff2" aria-label="Color preview">&nbsp;</td>
 </tr>
 <tr>
-<td width="250"><code>menuText</code></td>
+<th scope="row" width="250"><code>menuText</code></th>
 <td><pre>#000000 (0,0,0)</pre></td>
-<td width="100" bgcolor="#000000">&nbsp;</td>
+<td width="100" bgcolor="#000000" aria-label="Color preview">&nbsp;</td>
 </tr>
 <tr>
-<td width="250"><code>nimbusBlueGrey</code></td>
+<th scope="row" width="250"><code>nimbusBlueGrey</code></th>
 <td><pre>#a9b0be (169,176,190)</pre></td>
-<td width="100" bgcolor="#a9b0be">&nbsp;</td>
-
+<td width="100" bgcolor="#a9b0be" aria-label="Color preview">&nbsp;</td>
 </tr>
 <tr>
-<td width="250"><code>nimbusBorder</code></td>
+<th scope="row" width="250"><code>nimbusBorder</code></th>
 <td><pre>#9297a1 (146,151,161)</pre></td>
-<td width="100" bgcolor="#9297a1">&nbsp;</td>
-</tr>
-<tr>
-<td width="250"><code>nimbusSelection</code></td>
-<td><pre>#39698a (57,105,138)</pre></td>
-<td width="100" bgcolor="#39698a">&nbsp;</td>
+<td width="100" bgcolor="#9297a1" aria-label="Color preview">&nbsp;</td>
 </tr>
 <tr>
-<td width="250"><code>scrollbar</code></td>
-
-<td><pre>#cdd0d5 (205,208,213)</pre></td>
-<td width="100" bgcolor="#cdd0d5">&nbsp;</td>
+<th scope="row" width="250"><code>nimbusSelection</code></th>
+<td><pre>#39698a (57,105,138)</pre></td>
+<td width="100" bgcolor="#39698a" aria-label="Color preview">&nbsp;</td>
 </tr>
 <tr>
-<td width="250"><code>textBackground</code></td>
+<th scope="row" width="250"><code>scrollbar</code></th>
+<td><pre>#cdd0d5 (205,208,213)</pre></td>
+<td width="100" bgcolor="#cdd0d5" aria-label="Color preview">&nbsp;</td>
+</tr>
+<tr>
+<th scope="row" width="250"><code>textBackground</code></th>
 <td><pre>#39698a (57,105,138)</pre></td>
-<td width="100" bgcolor="#39698a">&nbsp;</td>
+<td width="100" bgcolor="#39698a" aria-label="Color preview">&nbsp;</td>
 </tr>
 <tr>
-<td width="250"><code>textForeground</code></td>
+<th scope="row" width="250"><code>textForeground</code></th>
 <td><pre>#000000 (0,0,0)</pre></td>
-<td width="100" bgcolor="#000000">&nbsp;</td>
-
+<td width="100" bgcolor="#000000" aria-label="Color preview">&nbsp;</td>
 </tr>
 <tr>
-<td width="250"><code>textHighlight</code></td>
+<th scope="row" width="250"><code>textHighlight</code></th>
 <td><pre>#39698a (57,105,138)</pre></td>
-<td width="100" bgcolor="#39698a">&nbsp;</td>
+<td width="100" bgcolor="#39698a" aria-label="Color preview">&nbsp;</td>
 </tr>
 <tr>
-<td width="250"><code>textHighlightText</code></td>
+<th scope="row" width="250"><code>textHighlightText</code></th>
 <td><pre>#ffffff (255,255,255)</pre></td>
-<td width="100" bgcolor="#ffffff">&nbsp;</td>
+<td width="100" bgcolor="#ffffff" aria-label="Color preview">&nbsp;</td>
 </tr>
 <tr>
-<td width="250"><code>textInactiveText</code></td>
-
+<th scope="row" width="250"><code>textInactiveText</code></th>
 <td><pre>#8e8f91 (142,143,145)</pre></td>
-<td width="100" bgcolor="#8e8f91">&nbsp;</td>
+<td width="100" bgcolor="#8e8f91" aria-label="Color preview">&nbsp;</td>
 </tr>
 </tbody>
 </table>
--- a/src/java.desktop/unix/classes/sun/awt/UNIXToolkit.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.desktop/unix/classes/sun/awt/UNIXToolkit.java	Mon Jul 01 14:57:02 2019 -0700
@@ -97,7 +97,7 @@
     public String getDesktop() {
         String gsi = AccessController.doPrivileged(
                         (PrivilegedAction<String>) ()
-                                -> System.getenv("GNOME_SESSION_ID"));
+                                -> System.getenv("GNOME_DESKTOP_SESSION_ID"));
         return (gsi != null) ? "gnome" : null;
     }
 
--- a/src/java.net.http/share/classes/jdk/internal/net/http/RequestPublishers.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/RequestPublishers.java	Mon Jul 01 14:57:02 2019 -0700
@@ -59,7 +59,6 @@
     private RequestPublishers() { }
 
     public static class ByteArrayPublisher implements BodyPublisher {
-        private volatile Flow.Publisher<ByteBuffer> delegate;
         private final int length;
         private final byte[] content;
         private final int offset;
@@ -99,7 +98,7 @@
         @Override
         public void subscribe(Flow.Subscriber<? super ByteBuffer> subscriber) {
             List<ByteBuffer> copy = copy(content, offset, length);
-            this.delegate = new PullPublisher<>(copy);
+            var delegate = new PullPublisher<>(copy);
             delegate.subscribe(subscriber);
         }
 
@@ -111,7 +110,6 @@
 
     // This implementation has lots of room for improvement.
     public static class IterablePublisher implements BodyPublisher {
-        private volatile Flow.Publisher<ByteBuffer> delegate;
         private final Iterable<byte[]> content;
         private volatile long contentLength;
 
@@ -174,7 +172,7 @@
         @Override
         public void subscribe(Flow.Subscriber<? super ByteBuffer> subscriber) {
             Iterable<ByteBuffer> iterable = this::iterator;
-            this.delegate = new PullPublisher<>(iterable);
+            var delegate = new PullPublisher<>(iterable);
             delegate.subscribe(subscriber);
         }
 
--- a/src/java.smartcardio/unix/legal/pcsclite.md	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.smartcardio/unix/legal/pcsclite.md	Mon Jul 01 14:57:02 2019 -0700
@@ -1,10 +1,10 @@
-## PC/SC Lite for Suse Linux v1.1.1
+## PC/SC Lite v1.8.24
 
 ### PC/SC Lite License
 <pre>
 
-Copyright (c) 1999-2004 David Corcoran <corcoran@linuxnet.com>
-Copyright (c) 1999-2004 Ludovic Rousseau <ludovic.rousseau (at) free.fr>
+Copyright (c) 1999-2003 David Corcoran <corcoran@linuxnet.com>
+Copyright (c) 2001-2011 Ludovic Rousseau <ludovic.rousseau@free.fr>
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -16,12 +16,7 @@
 2. Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in the
    documentation and/or other materials provided with the distribution.
-3. All advertising materials mentioning features or use of this software
-   must display the following acknowledgement:
-     This product includes software developed by:
-      David Corcoran <corcoran@linuxnet.com>
-      http://www.linuxnet.com (MUSCLE)
-4. The name of the author may not be used to endorse or promote products
+3. The name of the author may not be used to endorse or promote products
    derived from this software without specific prior written permission.
 
 Changes to this license can be made only by the copyright author with
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.smartcardio/unix/native/libj2pcsc/MUSCLE/COPYING	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,95 @@
+Copyright (c) 1999-2003 David Corcoran <corcoran@musclecard.com>
+Copyright (c) 2001-2011 Ludovic Rousseau <ludovic.rousseau@free.fr>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+   derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+Some files are under GNU GPL v3 or any later version
+- doc/example/pcsc_demo.c
+- the files in src/spy/
+- the files in UnitaryTests/
+
+    Copyright (C) 2003-2014  Ludovic Rousseau
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+Files src/auth.c and src/auth.h are:
+ * Copyright (C) 2013 Red Hat
+ *
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * Author: Nikos Mavrogiannopoulos <nmav@redhat.com>
+
+
+Files src/simclist.c and src/simclist.h are:
+ * Copyright (c) 2007,2008,2009,2010,2011 Mij <mij@bitchx.it>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/Const.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/Const.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,3503 +25,2362 @@
 /**
  * Constants for the project, mostly defined in the JVM specification.
  *
- * @version $Id: Const.java 1748987 2016-06-18 12:36:47Z sebb $
+ * @version $Id$
  * @since 6.0 (intended to replace the Constants interface)
  */
 public final class Const {
 
-    /**
-     * Java class file format Magic number (0xCAFEBABE)
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.1-200-A">
-     * The ClassFile Structure in The Java Virtual Machine Specification</a>
-     */
-    public static final int JVM_CLASSFILE_MAGIC = 0xCAFEBABE;
-
-    /**
-     * Major version number of class files for Java 1.1.
-     *
-     * @see #MINOR_1_1
-   *
-     */
-    public static final short MAJOR_1_1 = 45;
-
-    /**
-     * Minor version number of class files for Java 1.1.
-     *
-     * @see #MAJOR_1_1
+  /**
+   * Java class file format Magic number (0xCAFEBABE)
    *
-     */
-    public static final short MINOR_1_1 = 3;
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.1-200-A">
+   * The ClassFile Structure in The Java Virtual Machine Specification</a>
+   */
+  public static final int JVM_CLASSFILE_MAGIC = 0xCAFEBABE;
 
-    /**
-     * Major version number of class files for Java 1.2.
-     *
-     * @see #MINOR_1_2
-   *
-     */
-    public static final short MAJOR_1_2 = 46;
+  /** Major version number of class files for Java 1.1.
+   *  @see #MINOR_1_1
+   *  */
+  public static final short MAJOR_1_1 = 45;
+
+  /** Minor version number of class files for Java 1.1.
+   *  @see #MAJOR_1_1
+   *  */
+  public static final short MINOR_1_1 = 3;
 
-    /**
-     * Minor version number of class files for Java 1.2.
-     *
-     * @see #MAJOR_1_2
-   *
-     */
-    public static final short MINOR_1_2 = 0;
+  /** Major version number of class files for Java 1.2.
+   *  @see #MINOR_1_2
+   *  */
+  public static final short MAJOR_1_2 = 46;
 
-    /**
-     * Major version number of class files for Java 1.2.
-     *
-     * @see #MINOR_1_2
-   *
-     */
-    public static final short MAJOR_1_3 = 47;
+  /** Minor version number of class files for Java 1.2.
+   *  @see #MAJOR_1_2
+   *  */
+  public static final short MINOR_1_2 = 0;
+
+  /** Major version number of class files for Java 1.2.
+   *  @see #MINOR_1_2
+   *  */
+  public static final short MAJOR_1_3 = 47;
 
-    /**
-     * Minor version number of class files for Java 1.3.
-     *
-     * @see #MAJOR_1_3
-   *
-     */
-    public static final short MINOR_1_3 = 0;
+  /** Minor version number of class files for Java 1.3.
+   *  @see #MAJOR_1_3
+   *  */
+  public static final short MINOR_1_3 = 0;
 
-    /**
-     * Major version number of class files for Java 1.3.
-     *
-     * @see #MINOR_1_3
-   *
-     */
-    public static final short MAJOR_1_4 = 48;
+  /** Major version number of class files for Java 1.3.
+   *  @see #MINOR_1_3
+   *  */
+  public static final short MAJOR_1_4 = 48;
 
-    /**
-     * Minor version number of class files for Java 1.4.
-     *
-     * @see #MAJOR_1_4
-   *
-     */
-    public static final short MINOR_1_4 = 0;
+  /** Minor version number of class files for Java 1.4.
+   *  @see #MAJOR_1_4
+   *  */
+  public static final short MINOR_1_4 = 0;
 
-    /**
-     * Major version number of class files for Java 1.4.
-     *
-     * @see #MINOR_1_4
-   *
-     */
-    public static final short MAJOR_1_5 = 49;
+  /** Major version number of class files for Java 1.4.
+   *  @see #MINOR_1_4
+   *  */
+  public static final short MAJOR_1_5 = 49;
 
-    /**
-     * Minor version number of class files for Java 1.5.
-     *
-     * @see #MAJOR_1_5
-   *
-     */
-    public static final short MINOR_1_5 = 0;
+  /** Minor version number of class files for Java 1.5.
+   *  @see #MAJOR_1_5
+   *  */
+  public static final short MINOR_1_5 = 0;
 
-    /**
-     * Major version number of class files for Java 1.6.
-     *
-     * @see #MINOR_1_6
-   *
-     */
-    public static final short MAJOR_1_6 = 50;
+  /** Major version number of class files for Java 1.6.
+   *  @see #MINOR_1_6
+   *  */
+  public static final short MAJOR_1_6 = 50;
 
-    /**
-     * Minor version number of class files for Java 1.6.
-     *
-     * @see #MAJOR_1_6
-   *
-     */
-    public static final short MINOR_1_6 = 0;
+  /** Minor version number of class files for Java 1.6.
+   *  @see #MAJOR_1_6
+   *  */
+  public static final short MINOR_1_6 = 0;
 
-    /**
-     * Major version number of class files for Java 1.7.
-     *
-     * @see #MINOR_1_7
-   *
-     */
-    public static final short MAJOR_1_7 = 51;
+  /** Major version number of class files for Java 1.7.
+   *  @see #MINOR_1_7
+   *  */
+  public static final short MAJOR_1_7 = 51;
 
-    /**
-     * Minor version number of class files for Java 1.7.
-     *
-     * @see #MAJOR_1_7
-   *
-     */
-    public static final short MINOR_1_7 = 0;
+  /** Minor version number of class files for Java 1.7.
+   *  @see #MAJOR_1_7
+   *  */
+  public static final short MINOR_1_7 = 0;
 
-    /**
-     * Major version number of class files for Java 1.8.
-     *
-     * @see #MINOR_1_8
-   *
-     */
-    public static final short MAJOR_1_8 = 52;
+  /** Major version number of class files for Java 1.8.
+   *  @see #MINOR_1_8
+   *  */
+  public static final short MAJOR_1_8 = 52;
 
-    /**
-     * Major version number of class files for Java 9.
-     *
-     * @see #MINOR_1_9
-   *
-     */
-    public static final short MAJOR_1_9 = 53;
+  /** Minor version number of class files for Java 1.8.
+   *  @see #MAJOR_1_8
+   *  */
+  public static final short MINOR_1_8 = 0;
+
+  /** Major version number of class files for Java 9.
+   *  @see #MINOR_9
+   *  */
+  public static final short MAJOR_9 = 53;
 
-    /**
-     * Minor version number of class files for Java 1.8.
-     *
-     * @see #MAJOR_1_8
-   *
-     */
-    public static final short MINOR_1_8 = 0;
+  /** Minor version number of class files for Java 9.
+   *  @see #MAJOR_9
+   *  */
+  public static final short MINOR_9 = 0;
 
-    /**
-     * Minor version number of class files for Java 9.
-     *
-     * @see #MAJOR_1_9
-   *
-     */
-    public static final short MINOR_1_9 = 0;
+  /**
+   * @deprecated Use {@link #MAJOR_9} instead
+   */
+  @Deprecated
+  public static final short MAJOR_1_9 = MAJOR_9;
 
-    /**
-     * Default major version number. Class file is for Java 1.1.
-     *
-     * @see #MAJOR_1_1
-   *
-     */
-    public static final short MAJOR = MAJOR_1_1;
+  /**
+   * @deprecated Use {@link #MINOR_9} instead
+   */
+  @Deprecated
+  public static final short MINOR_1_9 = MINOR_9;
 
-    /**
-     * Default major version number. Class file is for Java 1.1.
-     *
-     * @see #MAJOR_1_1
-   *
-     */
-    public static final short MINOR = MINOR_1_1;
+  /** Major version number of class files for Java 10.
+   *  @see #MINOR_10
+   *  */
+  public static final short MAJOR_10 = 54;
 
-    /**
-     * Maximum value for an unsigned short.
-     */
-    public static final int MAX_SHORT = 65535; // 2^16 - 1
-
-    /**
-     * Maximum value for an unsigned byte.
-     */
-    public static final int MAX_BYTE = 255; // 2^8 - 1
+  /** Minor version number of class files for Java 10.
+   *  @see #MAJOR_10
+   *  */
+  public static final short MINOR_10 = 0;
 
-    /**
-     * One of the access flags for fields, methods, or classes.
-     *
-     * @see <a
-     * href='http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.5'>
-     * Flag definitions for Fields in the Java Virtual Machine Specification
-     * (Java SE 8 Edition).</a>
-     * @see <a
-     * href='http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.6'>
-     * Flag definitions for Methods in the Java Virtual Machine Specification
-     * (Java SE 8 Edition).</a>
-     * @see <a
-     * href='http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.6-300-D.1-D.1'>
-     * Flag definitions for Classes in the Java Virtual Machine Specification
-     * (Java SE 8 Edition).</a>
-     */
-    public static final short ACC_PUBLIC = 0x0001;
+  /** Major version number of class files for Java 11.
+   *  @see #MINOR_11
+   *  */
+  public static final short MAJOR_11 = 55;
+
+  /** Minor version number of class files for Java 11.
+   *  @see #MAJOR_11
+   *  */
+  public static final short MINOR_11 = 0;
 
-    /**
-     * One of the access flags for fields, methods, or classes.
-     *
-     * @see #ACC_PUBLIC
-     */
-    public static final short ACC_PRIVATE = 0x0002;
+  /** Major version number of class files for Java 12.
+   *  @see #MINOR_12
+   *  */
+  public static final short MAJOR_12 = 56;
 
-    /**
-     * One of the access flags for fields, methods, or classes.
-     *
-     * @see #ACC_PUBLIC
-     */
-    public static final short ACC_PROTECTED = 0x0004;
+  /** Minor version number of class files for Java 12.
+   *  @see #MAJOR_12
+   *  */
+  public static final short MINOR_12 = 0;
 
-    /**
-     * One of the access flags for fields, methods, or classes.
-     *
-     * @see #ACC_PUBLIC
-     */
-    public static final short ACC_STATIC = 0x0008;
+  /** Major version number of class files for Java 13.
+   *  @see #MINOR_13
+   *  */
+  public static final short MAJOR_13 = 57;
 
-    /**
-     * One of the access flags for fields, methods, or classes.
-     *
-     * @see #ACC_PUBLIC
-     */
-    public static final short ACC_FINAL = 0x0010;
-
-    /**
-     * One of the access flags for fields, methods, or classes.
-     *
-     * @see #ACC_PUBLIC
-     */
-    public static final short ACC_SYNCHRONIZED = 0x0020;
+  /** Minor version number of class files for Java 13.
+   *  @see #MAJOR_13
+   *  */
+  public static final short MINOR_13 = 0;
 
-    /**
-     * One of the access flags for fields, methods, or classes.
-     *
-     * @see #ACC_PUBLIC
-     */
-    public static final short ACC_VOLATILE = 0x0040;
-
-    /**
-     * One of the access flags for fields, methods, or classes.
-     *
-     * @see #ACC_PUBLIC
-     */
-    public static final short ACC_BRIDGE = 0x0040;
+  /** Default major version number.  Class file is for Java 1.1.
+   *  @see #MAJOR_1_1
+   *  */
+  public static final short MAJOR = MAJOR_1_1;
 
-    /**
-     * One of the access flags for fields, methods, or classes.
-     *
-     * @see #ACC_PUBLIC
-     */
-    public static final short ACC_TRANSIENT = 0x0080;
+  /** Default major version number.  Class file is for Java 1.1.
+   *  @see #MAJOR_1_1
+   *  */
+  public static final short MINOR     = MINOR_1_1;
 
-    /**
-     * One of the access flags for fields, methods, or classes.
-     *
-     * @see #ACC_PUBLIC
-     */
-    public static final short ACC_VARARGS = 0x0080;
+  /** Maximum value for an unsigned short.
+   */
+  public static final int MAX_SHORT = 65535; // 2^16 - 1
+
+  /** Maximum value for an unsigned byte.
+   */
+  public static final int MAX_BYTE  = 255; // 2^8 - 1
 
-    /**
-     * One of the access flags for fields, methods, or classes.
-     *
-     * @see #ACC_PUBLIC
-     */
-    public static final short ACC_NATIVE = 0x0100;
-
-    /**
-     * One of the access flags for fields, methods, or classes.
-     *
-     * @see #ACC_PUBLIC
-     */
-    public static final short ACC_INTERFACE = 0x0200;
+  /** One of the access flags for fields, methods, or classes.
+   *  @see <a href='http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.5'>
+   *  Flag definitions for Fields in the Java Virtual Machine Specification (Java SE 8 Edition).</a>
+   *  @see <a href='http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.6'>
+   *  Flag definitions for Methods in the Java Virtual Machine Specification (Java SE 8 Edition).</a>
+   *  @see <a href='http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.6-300-D.1-D.1'>
+   *  Flag definitions for Classes in the Java Virtual Machine Specification (Java SE 8 Edition).</a>
+   */
+  public static final short ACC_PUBLIC       = 0x0001;
 
-    /**
-     * One of the access flags for fields, methods, or classes.
-     *
-     * @see #ACC_PUBLIC
-     */
-    public static final short ACC_ABSTRACT = 0x0400;
+  /** One of the access flags for fields, methods, or classes.
+   *  @see #ACC_PUBLIC
+   */
+  public static final short ACC_PRIVATE      = 0x0002;
 
-    /**
-     * One of the access flags for fields, methods, or classes.
-     *
-     * @see #ACC_PUBLIC
-     */
-    public static final short ACC_STRICT = 0x0800;
+  /** One of the access flags for fields, methods, or classes.
+   *  @see #ACC_PUBLIC
+   */
+  public static final short ACC_PROTECTED    = 0x0004;
 
-    /**
-     * One of the access flags for fields, methods, or classes.
-     *
-     * @see #ACC_PUBLIC
-     */
-    public static final short ACC_SYNTHETIC = 0x1000;
+  /** One of the access flags for fields, methods, or classes.
+   *  @see #ACC_PUBLIC
+   */
+  public static final short ACC_STATIC       = 0x0008;
 
-    /**
-     * One of the access flags for fields, methods, or classes.
-     *
-     * @see #ACC_PUBLIC
-     */
-    public static final short ACC_ANNOTATION = 0x2000;
+  /** One of the access flags for fields, methods, or classes.
+   *  @see #ACC_PUBLIC
+   */
+  public static final short ACC_FINAL        = 0x0010;
 
-    /**
-     * One of the access flags for fields, methods, or classes.
-     *
-     * @see #ACC_PUBLIC
-     */
-    public static final short ACC_ENUM = 0x4000;
+  /** One of the access flags for fields, methods, or classes.
+   *  @see #ACC_PUBLIC
+   */
+  public static final short ACC_SYNCHRONIZED = 0x0020;
 
-    /**
-     * One of the access flags for fields, methods, or classes.
-     *
-     * @see #ACC_PUBLIC
-     */
-    public static final short ACC_MANDATED = (short) 0x8000;
+  /** One of the access flags for fields, methods, or classes.
+   *  @see #ACC_PUBLIC
+   */
+  public static final short ACC_VOLATILE     = 0x0040;
+
+  /** One of the access flags for fields, methods, or classes.
+   *  @see #ACC_PUBLIC
+   */
+  public static final short ACC_BRIDGE       = 0x0040;
 
-    // Applies to classes compiled by new compilers only
-    /**
-     * One of the access flags for fields, methods, or classes.
-     *
-     * @see #ACC_PUBLIC
-     */
-    public static final short ACC_SUPER = 0x0020;
+  /** One of the access flags for fields, methods, or classes.
+   *  @see #ACC_PUBLIC
+   */
+  public static final short ACC_TRANSIENT    = 0x0080;
 
-    /**
-     * One of the access flags for fields, methods, or classes.
-     *
-     * @see #ACC_PUBLIC
-     */
-    public static final short MAX_ACC_FLAG = ACC_ENUM;
+  /** One of the access flags for fields, methods, or classes.
+   *  @see #ACC_PUBLIC
+   */
+  public static final short ACC_VARARGS      = 0x0080;
 
-    /**
-     * The names of the access flags.
-     */
-    private static final String[] ACCESS_NAMES = {
-        "public", "private", "protected", "static", "final", "synchronized",
-        "volatile", "transient", "native", "interface", "abstract", "strictfp",
-        "synthetic", "annotation", "enum"
-    };
+  /** One of the access flags for fields, methods, or classes.
+   *  @see #ACC_PUBLIC
+   */
+  public static final short ACC_NATIVE       = 0x0100;
 
-    /**
-     * @since 6.0
-     */
-    public static final int ACCESS_NAMES_LENGTH = ACCESS_NAMES.length;
+  /** One of the access flags for fields, methods, or classes.
+   *  @see #ACC_PUBLIC
+   */
+  public static final short ACC_INTERFACE    = 0x0200;
 
-    /**
-     * @param index
-     * @return the ACCESS_NAMES entry at the given index
-     * @since 6.0
-     */
-    public static String getAccessName(final int index) {
-        return ACCESS_NAMES[index];
-    }
+  /** One of the access flags for fields, methods, or classes.
+   *  @see #ACC_PUBLIC
+   */
+  public static final short ACC_ABSTRACT     = 0x0400;
 
-    /*
-     * The description of the constant pool is at:
-     * http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4
-     * References below are to the individual sections
-     */
-    /**
-     * Marks a constant pool entry as type UTF-8.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.7">
-     * The Constant Pool in The Java Virtual Machine Specification</a>
-     */
-    public static final byte CONSTANT_Utf8 = 1;
+  /** One of the access flags for fields, methods, or classes.
+   *  @see #ACC_PUBLIC
+   */
+  public static final short ACC_STRICT       = 0x0800;
+
+  /** One of the access flags for fields, methods, or classes.
+   *  @see #ACC_PUBLIC
+   */
+  public static final short ACC_SYNTHETIC    = 0x1000;
 
-    /**
-     * Marks a constant pool entry as type Integer.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.4">
-     * The Constant Pool in The Java Virtual Machine Specification</a>
-     */
-    public static final byte CONSTANT_Integer = 3;
+  /** One of the access flags for fields, methods, or classes.
+   *  @see #ACC_PUBLIC
+   */
+  public static final short ACC_ANNOTATION   = 0x2000;
 
-    /**
-     * Marks a constant pool entry as type Float.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.4">
-     * The Constant Pool in The Java Virtual Machine Specification</a>
-     */
-    public static final byte CONSTANT_Float = 4;
+  /** One of the access flags for fields, methods, or classes.
+   *  @see #ACC_PUBLIC
+   */
+  public static final short ACC_ENUM         = 0x4000;
 
-    /**
-     * Marks a constant pool entry as type Long.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.5">
-     * The Constant Pool in The Java Virtual Machine Specification</a>
-     */
-    public static final byte CONSTANT_Long = 5;
+  /** One of the access flags for fields, methods, or classes.
+   *  @see #ACC_PUBLIC
+   */
+  public static final short ACC_MANDATED     = (short) 0x8000;
 
-    /**
-     * Marks a constant pool entry as type Double.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.5">
-     * The Constant Pool in The Java Virtual Machine Specification</a>
-     */
-    public static final byte CONSTANT_Double = 6;
+  // Applies to classes compiled by new compilers only
+  /** One of the access flags for fields, methods, or classes.
+   *  @see #ACC_PUBLIC
+   */
+  public static final short ACC_SUPER        = 0x0020;
 
-    /**
-     * Marks a constant pool entry as a Class
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.1">
-     * The Constant Pool in The Java Virtual Machine Specification</a>
-     */
-    public static final byte CONSTANT_Class = 7;
+  /** One of the access flags for fields, methods, or classes.
+   *  @see #ACC_PUBLIC
+   */
+  public static final short MAX_ACC_FLAG     = ACC_ENUM;
 
-    /**
-     * Marks a constant pool entry as a Field Reference.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.2">
-     * The Constant Pool in The Java Virtual Machine Specification</a>
-     */
-    public static final byte CONSTANT_Fieldref = 9;
+  /**
+   * The names of the access flags.
+   */
+  private static final String[] ACCESS_NAMES = {
+    "public", "private", "protected", "static", "final", "synchronized",
+    "volatile", "transient", "native", "interface", "abstract", "strictfp",
+    "synthetic", "annotation", "enum"
+  };
 
-    /**
-     * Marks a constant pool entry as type String
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.3">
-     * The Constant Pool in The Java Virtual Machine Specification</a>
-     */
-    public static final byte CONSTANT_String = 8;
+  /** @since 6.0 */
+  public static final int ACCESS_NAMES_LENGTH = ACCESS_NAMES.length;
 
-    /**
-     * Marks a constant pool entry as a Method Reference.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.2">
-     * The Constant Pool in The Java Virtual Machine Specification</a>
-     */
-    public static final byte CONSTANT_Methodref = 10;
-
-    /**
-     * Marks a constant pool entry as an Interface Method Reference.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.2">
-     * The Constant Pool in The Java Virtual Machine Specification</a>
-     */
-    public static final byte CONSTANT_InterfaceMethodref = 11;
+  /**
+   * @param index
+   * @return the ACCESS_NAMES entry at the given index
+   * @since 6.0
+   */
+  public static String getAccessName(final int index) {
+      return ACCESS_NAMES[index];
+  }
 
-    /**
-     * Marks a constant pool entry as a name and type.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.6">
-     * The Constant Pool in The Java Virtual Machine Specification</a>
-     */
-    public static final byte CONSTANT_NameAndType = 12;
+  /*
+   * The description of the constant pool is at:
+   * http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4
+   * References below are to the individual sections
+   */
 
-    /**
-     * Marks a constant pool entry as a Method Handle.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.8">
-     * The Constant Pool in The Java Virtual Machine Specification</a>
-     */
-    public static final byte CONSTANT_MethodHandle = 15;
+  /**
+   * Marks a constant pool entry as type UTF-8.
+   * @see  <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.7">
+   * The Constant Pool in The Java Virtual Machine Specification</a>
+   */
+  public static final byte CONSTANT_Utf8               = 1;
 
-    /**
-     * Marks a constant pool entry as a Method Type.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.9">
-     * The Constant Pool in The Java Virtual Machine Specification</a>
-     */
-    public static final byte CONSTANT_MethodType = 16;
+  /**
+   * Marks a constant pool entry as type Integer.
+   * @see  <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.4">
+   * The Constant Pool in The Java Virtual Machine Specification</a>
+   */
+  public static final byte CONSTANT_Integer            = 3;
 
-    /**
-     * Marks a constant pool entry as an Invoke Dynamic
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.10">
-     * The Constant Pool in The Java Virtual Machine Specification</a>
-     */
-    public static final byte CONSTANT_InvokeDynamic = 18;
+  /**
+   * Marks a constant pool entry as type Float.
+   * @see  <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.4">
+   * The Constant Pool in The Java Virtual Machine Specification</a>
+   */
+  public static final byte CONSTANT_Float              = 4;
 
-    /**
-     * The names of the types of entries in a constant pool. Use getConstantName
-     * instead
-     */
-    private static final String[] CONSTANT_NAMES = {
-        "", "CONSTANT_Utf8", "", "CONSTANT_Integer",
-        "CONSTANT_Float", "CONSTANT_Long", "CONSTANT_Double",
-        "CONSTANT_Class", "CONSTANT_String", "CONSTANT_Fieldref",
-        "CONSTANT_Methodref", "CONSTANT_InterfaceMethodref",
-        "CONSTANT_NameAndType", "", "", "CONSTANT_MethodHandle",
-        "CONSTANT_MethodType", "", "CONSTANT_InvokeDynamic"};
+  /**
+   * Marks a constant pool entry as type Long.
+   * @see  <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.5">
+   * The Constant Pool in The Java Virtual Machine Specification</a>
+   */
+  public static final byte CONSTANT_Long               = 5;
+
+  /**
+   * Marks a constant pool entry as type Double.
+   * @see  <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.5">
+   * The Constant Pool in The Java Virtual Machine Specification</a>
+   */
+  public static final byte CONSTANT_Double             = 6;
 
-    /**
-     *
-     * @param index
-     * @return the CONSTANT_NAMES entry at the given index
-     * @since 6.0
-     */
-    public static String getConstantName(final int index) {
-        return CONSTANT_NAMES[index];
-    }
-
-    /**
-     * The name of the static initializer, also called &quot;class
-     * initialization method&quot; or &quot;interface initialization
-     * method&quot;. This is &quot;&lt;clinit&gt;&quot;.
-     */
-    public static final String STATIC_INITIALIZER_NAME = "<clinit>";
+  /**
+   * Marks a constant pool entry as a Class
+   * @see  <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.1">
+   * The Constant Pool in The Java Virtual Machine Specification</a>
+   */
+  public static final byte CONSTANT_Class              = 7;
 
-    /**
-     * The name of every constructor method in a class, also called
-     * &quot;instance initialization method&quot;. This is
-     * &quot;&lt;init&gt;&quot;.
-     */
-    public static final String CONSTRUCTOR_NAME = "<init>";
+  /**
+   * Marks a constant pool entry as a Field Reference.
+   * @see  <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.2">
+   * The Constant Pool in The Java Virtual Machine Specification</a>
+   */
+  public static final byte CONSTANT_Fieldref           = 9;
 
-    /**
-     * The names of the interfaces implemented by arrays
-     */
-    private static final String[] INTERFACES_IMPLEMENTED_BY_ARRAYS = {"java.lang.Cloneable", "java.io.Serializable"};
-
-    /**
-     * @since 6.0
-     */
-    public static Iterable<String> getInterfacesImplementedByArrays() {
-        return Collections.unmodifiableList(Arrays.asList(INTERFACES_IMPLEMENTED_BY_ARRAYS));
-    }
+  /**
+   * Marks a constant pool entry as type String
+   * @see  <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.3">
+   * The Constant Pool in The Java Virtual Machine Specification</a>
+   */
+  public static final byte CONSTANT_String             = 8;
 
-    /**
-     * Maximum Constant Pool entries. One of the limitations of the Java Virtual
-     * Machine.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.11-100-A">
-     * The Java Virtual Machine Specification, Java SE 8 Edition, page 330,
-     * chapter 4.11.</a>
-     */
-    public static final int MAX_CP_ENTRIES = 65535;
+  /** Marks a constant pool entry as a Method Reference.
+   * @see  <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.2">
+   * The Constant Pool in The Java Virtual Machine Specification</a> */
+  public static final byte CONSTANT_Methodref          = 10;
+
+  /**
+   * Marks a constant pool entry as an Interface Method Reference.
+   * @see  <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.2">
+   * The Constant Pool in The Java Virtual Machine Specification</a>
+   */
+  public static final byte CONSTANT_InterfaceMethodref = 11;
 
-    /**
-     * Maximum code size (plus one; the code size must be LESS than this) One of
-     * the limitations of the Java Virtual Machine. Note vmspec2 page 152
-     * ("Limitations") says: "The amount of code per non-native, non-abstract
-     * method is limited to 65536 bytes by the sizes of the indices in the
-     * exception_table of the Code attribute (4.7.3), in the LineNumberTable
-     * attribute (4.7.8), and in the LocalVariableTable attribute (4.7.9)."
-     * However this should be taken as an upper limit rather than the defined
-     * maximum. On page 134 (4.8.1 Static Constants) of the same spec, it says:
-     * "The value of the code_length item must be less than 65536." The entry in
-     * the Limitations section has been removed from later versions of the spec;
-     * it is not present in the Java SE 8 edition.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.3-300-E">
-     * The Java Virtual Machine Specification, Java SE 8 Edition, page 104,
-     * chapter 4.7.</a>
-     */
-    public static final int MAX_CODE_SIZE = 65536; //bytes
+  /** Marks a constant pool entry as a name and type.
+   * @see  <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.6">
+   * The Constant Pool in The Java Virtual Machine Specification</a> */
+  public static final byte CONSTANT_NameAndType        = 12;
 
-    /**
-     * The maximum number of dimensions in an array ({@value}). One of the
-     * limitations of the Java Virtual Machine.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.3.2-150">
-     * Field Descriptors in The Java Virtual Machine Specification</a>
-     */
-    public static final int MAX_ARRAY_DIMENSIONS = 255;
+  /**
+   * Marks a constant pool entry as a Method Handle.
+   * @see  <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.8">
+   * The Constant Pool in The Java Virtual Machine Specification</a>
+   */
+  public static final byte CONSTANT_MethodHandle       = 15;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.nop">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short NOP = 0;
+  /**
+   * Marks a constant pool entry as a Method Type.
+   * @see  <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.9">
+   * The Constant Pool in The Java Virtual Machine Specification</a>
+   */
+  public static final byte CONSTANT_MethodType         = 16;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.aconst_null">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short ACONST_NULL = 1;
+  /**
+   * Marks a constant pool entry as dynamically computed.
+   * @see  <a href="https://bugs.openjdk.java.net/secure/attachment/74618/constant-dynamic.html">
+   * Change request for JEP 309</a>
+   * @since 6.3
+   */
+  public static final byte CONSTANT_Dynamic            = 17;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iconst_i">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short ICONST_M1 = 2;
-
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iconst_i">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short ICONST_0 = 3;
+  /**
+   * Marks a constant pool entry as an Invoke Dynamic
+   * @see  <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.10">
+   * The Constant Pool in The Java Virtual Machine Specification</a>
+   */
+  public static final byte CONSTANT_InvokeDynamic      = 18;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iconst_i">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short ICONST_1 = 4;
-
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iconst_i">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short ICONST_2 = 5;
+  /**
+   * Marks a constant pool entry as a Module Reference.
+   * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.4.11">
+   * The Constant Pool in The Java Virtual Machine Specification</a>
+   * @since 6.1
+   */
+  public static final byte CONSTANT_Module             = 19;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iconst_i">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short ICONST_3 = 6;
+  /**
+   * Marks a constant pool entry as a Package Reference.
+   * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.4.12">
+   * The Constant Pool in The Java Virtual Machine Specification</a>
+   * @since 6.1
+   */
+  public static final byte CONSTANT_Package            = 20;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iconst_i">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short ICONST_4 = 7;
+  /**
+   * The names of the types of entries in a constant pool.
+   * Use getConstantName instead
+   */
+  private static final String[] CONSTANT_NAMES = {
+    "", "CONSTANT_Utf8", "", "CONSTANT_Integer",
+    "CONSTANT_Float", "CONSTANT_Long", "CONSTANT_Double",
+    "CONSTANT_Class", "CONSTANT_String", "CONSTANT_Fieldref",
+    "CONSTANT_Methodref", "CONSTANT_InterfaceMethodref",
+    "CONSTANT_NameAndType", "", "", "CONSTANT_MethodHandle",
+    "CONSTANT_MethodType", "CONSTANT_Dynamic", "CONSTANT_InvokeDynamic",
+    "CONSTANT_Module", "CONSTANT_Package"};
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iconst_i">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short ICONST_5 = 8;
+  /**
+   *
+   * @param index
+   * @return the CONSTANT_NAMES entry at the given index
+   * @since 6.0
+   */
+  public static String getConstantName(final int index) {
+      return CONSTANT_NAMES[index];
+  }
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lconst_l">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short LCONST_0 = 9;
-
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lconst_l">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short LCONST_1 = 10;
+  /** The name of the static initializer, also called &quot;class
+   *  initialization method&quot; or &quot;interface initialization
+   *   method&quot;. This is &quot;&lt;clinit&gt;&quot;.
+   */
+  public static final String STATIC_INITIALIZER_NAME = "<clinit>";
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fconst_f">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short FCONST_0 = 11;
+  /** The name of every constructor method in a class, also called
+   * &quot;instance initialization method&quot;. This is &quot;&lt;init&gt;&quot;.
+   */
+  public static final String CONSTRUCTOR_NAME = "<init>";
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fconst_f">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short FCONST_1 = 12;
+  /**
+   * The names of the interfaces implemented by arrays
+   */
+  private static final String[] INTERFACES_IMPLEMENTED_BY_ARRAYS = {"java.lang.Cloneable", "java.io.Serializable"};
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fconst_f">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short FCONST_2 = 13;
+  /**
+   * @since 6.0
+   */
+  public static Iterable<String> getInterfacesImplementedByArrays() {
+      return Collections.unmodifiableList(Arrays.asList(INTERFACES_IMPLEMENTED_BY_ARRAYS));
+  }
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dconst_d">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short DCONST_0 = 14;
-
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dconst_d">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short DCONST_1 = 15;
-
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.bipush">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short BIPUSH = 16;
+  /**
+   * Maximum Constant Pool entries.
+   * One of the limitations of the Java Virtual Machine.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.11-100-A">
+   * The Java Virtual Machine Specification, Java SE 8 Edition, page 330, chapter 4.11.</a>
+   */
+  public static final int MAX_CP_ENTRIES     = 65535;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.sipush">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short SIPUSH = 17;
+  /**
+   * Maximum code size (plus one; the code size must be LESS than this)
+   * One of the limitations of the Java Virtual Machine.
+   * Note vmspec2 page 152 ("Limitations") says:
+   * "The amount of code per non-native, non-abstract method is limited to 65536 bytes by
+   * the sizes of the indices in the exception_table of the Code attribute (4.7.3),
+   * in the LineNumberTable attribute (4.7.8), and in the LocalVariableTable attribute (4.7.9)."
+   * However this should be taken as an upper limit rather than the defined maximum.
+   * On page 134 (4.8.1 Static Constants) of the same spec, it says:
+   * "The value of the code_length item must be less than 65536."
+   * The entry in the Limitations section has been removed from later versions of the spec;
+   * it is not present in the Java SE 8 edition.
+   *
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.3-300-E">
+   * The Java Virtual Machine Specification, Java SE 8 Edition, page 104, chapter 4.7.3</a>
+   */
+  public static final int MAX_CODE_SIZE      = 65536; //bytes
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ldc">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short LDC = 18;
+  /**
+   * The maximum number of dimensions in an array ({@value}).
+   * One of the limitations of the Java Virtual Machine.
+   *
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.3.2-150">
+   * Field Descriptors in The Java Virtual Machine Specification</a>
+   */
+  public static final int MAX_ARRAY_DIMENSIONS = 255;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ldc_w">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short LDC_W = 19;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.nop">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short NOP              = 0;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ldc2_w">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short LDC2_W = 20;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.aconst_null">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ACONST_NULL      = 1;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iload">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short ILOAD = 21;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iconst_i">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ICONST_M1        = 2;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lload">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short LLOAD = 22;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iconst_i">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ICONST_0         = 3;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fload">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short FLOAD = 23;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iconst_i">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ICONST_1         = 4;
+
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iconst_i">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ICONST_2         = 5;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dload">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short DLOAD = 24;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iconst_i">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ICONST_3         = 6;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.aload">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short ALOAD = 25;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iconst_i">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ICONST_4         = 7;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iload_n">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short ILOAD_0 = 26;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iconst_i">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ICONST_5         = 8;
+
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lconst_l">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LCONST_0         = 9;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iload_n">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short ILOAD_1 = 27;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lconst_l">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LCONST_1         = 10;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iload_n">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short ILOAD_2 = 28;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fconst_f">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FCONST_0         = 11;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iload_n">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short ILOAD_3 = 29;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fconst_f">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FCONST_1         = 12;
+
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fconst_f">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FCONST_2         = 13;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lload_n">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short LLOAD_0 = 30;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dconst_d">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DCONST_0         = 14;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lload_n">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short LLOAD_1 = 31;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dconst_d">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DCONST_1         = 15;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lload_n">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short LLOAD_2 = 32;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.bipush">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short BIPUSH           = 16;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lload_n">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short LLOAD_3 = 33;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.sipush">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short SIPUSH           = 17;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fload_n">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short FLOAD_0 = 34;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ldc">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LDC              = 18;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fload_n">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short FLOAD_1 = 35;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ldc_w">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LDC_W            = 19;
+
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ldc2_w">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LDC2_W           = 20;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fload_n">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short FLOAD_2 = 36;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iload">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ILOAD            = 21;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fload_n">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short FLOAD_3 = 37;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lload">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LLOAD            = 22;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dload_n">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short DLOAD_0 = 38;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fload">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FLOAD            = 23;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dload_n">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short DLOAD_1 = 39;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dload">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DLOAD            = 24;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dload_n">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short DLOAD_2 = 40;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.aload">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ALOAD            = 25;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dload_n">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short DLOAD_3 = 41;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iload_n">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ILOAD_0          = 26;
+
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iload_n">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ILOAD_1          = 27;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.aload_n">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short ALOAD_0 = 42;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iload_n">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ILOAD_2          = 28;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.aload_n">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short ALOAD_1 = 43;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iload_n">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ILOAD_3          = 29;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.aload_n">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short ALOAD_2 = 44;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lload_n">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LLOAD_0          = 30;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.aload_n">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short ALOAD_3 = 45;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lload_n">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LLOAD_1          = 31;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iaload">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short IALOAD = 46;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lload_n">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LLOAD_2          = 32;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.laload">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short LALOAD = 47;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lload_n">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LLOAD_3          = 33;
+
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fload_n">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FLOAD_0          = 34;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.faload">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short FALOAD = 48;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fload_n">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FLOAD_1          = 35;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.daload">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short DALOAD = 49;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fload_n">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FLOAD_2          = 36;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.aaload">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short AALOAD = 50;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fload_n">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FLOAD_3          = 37;
+
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dload_n">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DLOAD_0          = 38;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.baload">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short BALOAD = 51;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dload_n">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DLOAD_1          = 39;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.caload">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short CALOAD = 52;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dload_n">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DLOAD_2          = 40;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.saload">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short SALOAD = 53;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dload_n">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DLOAD_3          = 41;
+
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.aload_n">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ALOAD_0          = 42;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.istore">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short ISTORE = 54;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.aload_n">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ALOAD_1          = 43;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lstore">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short LSTORE = 55;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.aload_n">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ALOAD_2          = 44;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fstore">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short FSTORE = 56;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.aload_n">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ALOAD_3          = 45;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dstore">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short DSTORE = 57;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iaload">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IALOAD           = 46;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.astore">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short ASTORE = 58;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.laload">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LALOAD           = 47;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.istore_n">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short ISTORE_0 = 59;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.faload">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FALOAD           = 48;
+
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.daload">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DALOAD           = 49;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.istore_n">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short ISTORE_1 = 60;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.aaload">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short AALOAD           = 50;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.istore_n">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short ISTORE_2 = 61;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.baload">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short BALOAD           = 51;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.istore_n">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short ISTORE_3 = 62;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.caload">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short CALOAD           = 52;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lstore_n">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short LSTORE_0 = 63;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.saload">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short SALOAD           = 53;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lstore_n">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short LSTORE_1 = 64;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.istore">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ISTORE           = 54;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lstore_n">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short LSTORE_2 = 65;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lstore">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LSTORE           = 55;
+
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fstore">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FSTORE           = 56;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lstore_n">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short LSTORE_3 = 66;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dstore">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DSTORE           = 57;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fstore_n">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short FSTORE_0 = 67;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.astore">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ASTORE           = 58;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fstore_n">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short FSTORE_1 = 68;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.istore_n">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ISTORE_0         = 59;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fstore_n">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short FSTORE_2 = 69;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.istore_n">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ISTORE_1         = 60;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fstore_n">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short FSTORE_3 = 70;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.istore_n">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ISTORE_2         = 61;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dstore_n">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short DSTORE_0 = 71;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.istore_n">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ISTORE_3         = 62;
+
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lstore_n">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LSTORE_0         = 63;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dstore_n">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short DSTORE_1 = 72;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lstore_n">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LSTORE_1         = 64;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dstore_n">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short DSTORE_2 = 73;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lstore_n">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LSTORE_2         = 65;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dstore_n">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short DSTORE_3 = 74;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lstore_n">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LSTORE_3         = 66;
+
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fstore_n">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FSTORE_0         = 67;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.astore_n">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short ASTORE_0 = 75;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fstore_n">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FSTORE_1         = 68;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.astore_n">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short ASTORE_1 = 76;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fstore_n">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FSTORE_2         = 69;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.astore_n">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short ASTORE_2 = 77;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fstore_n">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FSTORE_3         = 70;
+
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dstore_n">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DSTORE_0         = 71;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.astore_n">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short ASTORE_3 = 78;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dstore_n">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DSTORE_1         = 72;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iastore">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short IASTORE = 79;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dstore_n">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DSTORE_2         = 73;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lastore">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short LASTORE = 80;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dstore_n">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DSTORE_3         = 74;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fastore">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short FASTORE = 81;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.astore_n">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ASTORE_0         = 75;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dastore">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short DASTORE = 82;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.astore_n">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ASTORE_1         = 76;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.aastore">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short AASTORE = 83;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.astore_n">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ASTORE_2         = 77;
+
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.astore_n">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ASTORE_3         = 78;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.bastore">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short BASTORE = 84;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iastore">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IASTORE          = 79;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.castore">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short CASTORE = 85;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lastore">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LASTORE          = 80;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.sastore">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short SASTORE = 86;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fastore">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FASTORE          = 81;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.pop">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short POP = 87;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dastore">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DASTORE          = 82;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.pop2">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short POP2 = 88;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.aastore">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short AASTORE          = 83;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dup">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short DUP = 89;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.bastore">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short BASTORE          = 84;
+
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.castore">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short CASTORE          = 85;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dup_x1">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short DUP_X1 = 90;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.sastore">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short SASTORE          = 86;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dup_x2">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short DUP_X2 = 91;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.pop">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short POP              = 87;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dup2">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short DUP2 = 92;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.pop2">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short POP2             = 88;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dup2_x1">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short DUP2_X1 = 93;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dup">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DUP              = 89;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dup2_x2">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short DUP2_X2 = 94;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dup_x1">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DUP_X1           = 90;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.swap">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short SWAP = 95;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dup_x2">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DUP_X2           = 91;
+
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dup2">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DUP2             = 92;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iadd">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short IADD = 96;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dup2_x1">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DUP2_X1          = 93;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ladd">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short LADD = 97;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dup2_x2">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DUP2_X2          = 94;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fadd">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short FADD = 98;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.swap">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short SWAP             = 95;
+
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iadd">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IADD             = 96;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dadd">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short DADD = 99;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ladd">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LADD             = 97;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.isub">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short ISUB = 100;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fadd">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FADD             = 98;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lsub">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short LSUB = 101;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dadd">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DADD             = 99;
+
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.isub">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ISUB             = 100;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fsub">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short FSUB = 102;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lsub">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LSUB             = 101;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dsub">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short DSUB = 103;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fsub">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FSUB             = 102;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.imul">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short IMUL = 104;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dsub">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DSUB             = 103;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lmul">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short LMUL = 105;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.imul">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IMUL             = 104;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fmul">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short FMUL = 106;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lmul">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LMUL             = 105;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dmul">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short DMUL = 107;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fmul">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FMUL             = 106;
+
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dmul">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DMUL             = 107;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.idiv">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short IDIV = 108;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.idiv">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IDIV             = 108;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ldiv">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short LDIV = 109;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ldiv">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LDIV             = 109;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fdiv">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short FDIV = 110;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fdiv">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FDIV             = 110;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ddiv">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short DDIV = 111;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ddiv">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DDIV             = 111;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.irem">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short IREM = 112;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.irem">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IREM             = 112;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lrem">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short LREM = 113;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lrem">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LREM             = 113;
+
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.frem">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FREM             = 114;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.frem">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short FREM = 114;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.drem">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DREM             = 115;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.drem">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short DREM = 115;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ineg">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short INEG             = 116;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ineg">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short INEG = 116;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lneg">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LNEG             = 117;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lneg">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short LNEG = 117;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fneg">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FNEG             = 118;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fneg">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short FNEG = 118;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dneg">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DNEG             = 119;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dneg">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short DNEG = 119;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ishl">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ISHL             = 120;
+
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lshl">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LSHL             = 121;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ishl">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short ISHL = 120;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ishr">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ISHR             = 122;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lshl">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short LSHL = 121;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lshr">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LSHR             = 123;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ishr">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short ISHR = 122;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iushr">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IUSHR            = 124;
+
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lushr">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LUSHR            = 125;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lshr">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short LSHR = 123;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iand">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IAND             = 126;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iushr">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short IUSHR = 124;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.land">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LAND             = 127;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lushr">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short LUSHR = 125;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ior">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IOR              = 128;
+
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lor">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LOR              = 129;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iand">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short IAND = 126;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ixor">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IXOR             = 130;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.land">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short LAND = 127;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lxor">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LXOR             = 131;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ior">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short IOR = 128;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iinc">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IINC             = 132;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lor">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short LOR = 129;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.i2l">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short I2L              = 133;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ixor">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short IXOR = 130;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.i2f">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short I2F              = 134;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lxor">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short LXOR = 131;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.i2d">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short I2D              = 135;
+
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.l2i">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short L2I              = 136;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iinc">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short IINC = 132;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.l2f">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short L2F              = 137;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.i2l">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short I2L = 133;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.l2d">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short L2D              = 138;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.i2f">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short I2F = 134;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.f2i">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short F2I              = 139;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.i2d">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short I2D = 135;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.f2l">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short F2L              = 140;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.l2i">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short L2I = 136;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.f2d">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short F2D              = 141;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.l2f">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short L2F = 137;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.d2i">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short D2I              = 142;
+
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.d2l">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short D2L              = 143;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.l2d">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short L2D = 138;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.d2f">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short D2F              = 144;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.f2i">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short F2I = 139;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.i2b">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short I2B              = 145;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.f2l">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short F2L = 140;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short INT2BYTE         = 145; // Old notation
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.f2d">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short F2D = 141;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.i2c">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short I2C              = 146;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.d2i">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short D2I = 142;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short INT2CHAR         = 146; // Old notation
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.d2l">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short D2L = 143;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.i2s">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short I2S              = 147;
+
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short INT2SHORT        = 147; // Old notation
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.d2f">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short D2F = 144;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lcmp">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LCMP             = 148;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.i2b">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short I2B = 145;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fcmpl">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FCMPL            = 149;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short INT2BYTE = 145; // Old notation
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fcmpg">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FCMPG            = 150;
+
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dcmpl">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DCMPL            = 151;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.i2c">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short I2C = 146;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dcmpg">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DCMPG            = 152;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short INT2CHAR = 146; // Old notation
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ifeq">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IFEQ             = 153;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.i2s">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short I2S = 147;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ifne">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IFNE             = 154;
+
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iflt">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IFLT             = 155;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short INT2SHORT = 147; // Old notation
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ifge">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IFGE             = 156;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lcmp">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short LCMP = 148;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ifgt">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IFGT             = 157;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fcmpl">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short FCMPL = 149;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ifle">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IFLE             = 158;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.fcmpg">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short FCMPG = 150;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.if_icmp_cond">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IF_ICMPEQ        = 159;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dcmpl">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short DCMPL = 151;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.if_icmp_cond">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IF_ICMPNE        = 160;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dcmpg">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short DCMPG = 152;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.if_icmp_cond">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IF_ICMPLT        = 161;
+
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.if_icmp_cond">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IF_ICMPGE        = 162;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ifeq">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short IFEQ = 153;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.if_icmp_cond">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IF_ICMPGT        = 163;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ifne">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short IFNE = 154;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.if_icmp_cond">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IF_ICMPLE        = 164;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iflt">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short IFLT = 155;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.if_acmp_cond">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IF_ACMPEQ        = 165;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ifge">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short IFGE = 156;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.if_acmp_cond">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IF_ACMPNE        = 166;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ifgt">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short IFGT = 157;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.goto">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short GOTO             = 167;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ifle">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short IFLE = 158;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.jsr">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short JSR              = 168;
+
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ret">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short RET              = 169;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.if_icmp_cond">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short IF_ICMPEQ = 159;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.tableswitch">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short TABLESWITCH      = 170;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.if_icmp_cond">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short IF_ICMPNE = 160;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lookupswitch">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LOOKUPSWITCH     = 171;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.if_icmp_cond">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short IF_ICMPLT = 161;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ireturn">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IRETURN          = 172;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.if_icmp_cond">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short IF_ICMPGE = 162;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lreturn">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short LRETURN          = 173;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.if_icmp_cond">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short IF_ICMPGT = 163;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.freturn">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short FRETURN          = 174;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.if_icmp_cond">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short IF_ICMPLE = 164;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dreturn">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short DRETURN          = 175;
+
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.areturn">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ARETURN          = 176;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.if_acmp_cond">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short IF_ACMPEQ = 165;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.return">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short RETURN           = 177;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.if_acmp_cond">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short IF_ACMPNE = 166;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.getstatic">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short GETSTATIC        = 178;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.goto">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short GOTO = 167;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.putstatic">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short PUTSTATIC        = 179;
+
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.getfield">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short GETFIELD         = 180;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.jsr">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short JSR = 168;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.putfield">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short PUTFIELD         = 181;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ret">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short RET = 169;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokevirtual">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short INVOKEVIRTUAL    = 182;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.tableswitch">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short TABLESWITCH = 170;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokespecial">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short INVOKESPECIAL    = 183;
+
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short INVOKENONVIRTUAL = 183; // Old name in JDK 1.0
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lookupswitch">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short LOOKUPSWITCH = 171;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokestatic">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short INVOKESTATIC     = 184;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ireturn">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short IRETURN = 172;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokeinterface">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short INVOKEINTERFACE  = 185;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.lreturn">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short LRETURN = 173;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokedynamic">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short INVOKEDYNAMIC    = 186;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.freturn">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short FRETURN = 174;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.new">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short NEW              = 187;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.dreturn">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short DRETURN = 175;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.newarray">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short NEWARRAY         = 188;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.areturn">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short ARETURN = 176;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.anewarray">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ANEWARRAY        = 189;
+
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.arraylength">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ARRAYLENGTH      = 190;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.return">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short RETURN = 177;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.athrow">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short ATHROW           = 191;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.getstatic">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short GETSTATIC = 178;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.checkcast">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short CHECKCAST        = 192;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.putstatic">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short PUTSTATIC = 179;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.instanceof">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short INSTANCEOF       = 193;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.getfield">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short GETFIELD = 180;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.monitorenter">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short MONITORENTER     = 194;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.putfield">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short PUTFIELD = 181;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.monitorexit">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short MONITOREXIT      = 195;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokevirtual">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short INVOKEVIRTUAL = 182;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.wide">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short WIDE             = 196;
+
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.multianewarray">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short MULTIANEWARRAY   = 197;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokespecial">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short INVOKESPECIAL = 183;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ifnull">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IFNULL           = 198;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short INVOKENONVIRTUAL = 183; // Old name in JDK 1.0
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ifnonnull">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short IFNONNULL        = 199;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokestatic">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short INVOKESTATIC = 184;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.goto_w">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short GOTO_W           = 200;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokeinterface">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short INVOKEINTERFACE = 185;
-
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokedynamic">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short INVOKEDYNAMIC = 186;
+  /** Java VM opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.jsr_w">
+   * Opcode definitions in The Java Virtual Machine Specification</a> */
+  public static final short JSR_W            = 201;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.new">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short NEW = 187;
+  /** JVM internal opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.2">
+   * Reserved opcodes in the Java Virtual Machine Specification</a> */
+  public static final short BREAKPOINT                = 202;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.newarray">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short NEWARRAY = 188;
+  /** JVM internal opcode.
+   * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
+   * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
+   * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short LDC_QUICK                 = 203;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.anewarray">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short ANEWARRAY = 189;
+  /** JVM internal opcode.
+   * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
+   * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
+   * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short LDC_W_QUICK               = 204;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.arraylength">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short ARRAYLENGTH = 190;
+  /** JVM internal opcode.
+   * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
+   * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
+   * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short LDC2_W_QUICK              = 205;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.athrow">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short ATHROW = 191;
+  /** JVM internal opcode.
+   * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
+   * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
+   * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short GETFIELD_QUICK            = 206;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.checkcast">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short CHECKCAST = 192;
+  /** JVM internal opcode.
+   * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
+   * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
+   * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short PUTFIELD_QUICK            = 207;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.instanceof">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short INSTANCEOF = 193;
+  /** JVM internal opcode.
+   * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
+   * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
+   * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short GETFIELD2_QUICK           = 208;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.monitorenter">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short MONITORENTER = 194;
+  /** JVM internal opcode.
+   * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
+   * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
+   * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short PUTFIELD2_QUICK           = 209;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.monitorexit">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short MONITOREXIT = 195;
+  /** JVM internal opcode.
+   * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
+   * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
+   * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short GETSTATIC_QUICK           = 210;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.wide">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short WIDE = 196;
+  /** JVM internal opcode.
+   * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
+   * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
+   * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short PUTSTATIC_QUICK           = 211;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.multianewarray">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short MULTIANEWARRAY = 197;
+  /** JVM internal opcode.
+   * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
+   * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
+   * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short GETSTATIC2_QUICK          = 212;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ifnull">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short IFNULL = 198;
+  /** JVM internal opcode.
+   * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
+   * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
+   * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short PUTSTATIC2_QUICK          = 213;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ifnonnull">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short IFNONNULL = 199;
+  /** JVM internal opcode.
+   * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
+   * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
+   * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short INVOKEVIRTUAL_QUICK       = 214;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.goto_w">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short GOTO_W = 200;
+  /** JVM internal opcode.
+   * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
+   * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
+   * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short INVOKENONVIRTUAL_QUICK    = 215;
 
-    /**
-     * Java VM opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.jsr_w">
-     * Opcode definitions in The Java Virtual Machine Specification</a>
-     */
-    public static final short JSR_W = 201;
+  /** JVM internal opcode.
+   * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
+   * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
+   * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short INVOKESUPER_QUICK         = 216;
 
-    /**
-     * JVM internal opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.2">
-     * Reserved opcodes in the Java Virtual Machine Specification</a>
-     */
-    public static final short BREAKPOINT = 202;
+  /** JVM internal opcode.
+   * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
+   * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
+   * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short INVOKESTATIC_QUICK        = 217;
 
-    /**
-     * JVM internal opcode.
-     *
-     * @see <a
-     * href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
-     * Specification of _quick opcodes in the Java Virtual Machine Specification
-     * (version 1)</a>
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
-     * Why the _quick opcodes were removed from the second version of the Java
-     * Virtual Machine Specification.</a>
-     */
-    public static final short LDC_QUICK = 203;
+  /** JVM internal opcode.
+   * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
+   * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
+   * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short INVOKEINTERFACE_QUICK     = 218;
 
-    /**
-     * JVM internal opcode.
-     *
-     * @see <a
-     * href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
-     * Specification of _quick opcodes in the Java Virtual Machine Specification
-     * (version 1)</a>
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
-     * Why the _quick opcodes were removed from the second version of the Java
-     * Virtual Machine Specification.</a>
-     */
-    public static final short LDC_W_QUICK = 204;
+  /** JVM internal opcode.
+   * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
+   * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
+   * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short INVOKEVIRTUALOBJECT_QUICK = 219;
 
-    /**
-     * JVM internal opcode.
-     *
-     * @see <a
-     * href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
-     * Specification of _quick opcodes in the Java Virtual Machine Specification
-     * (version 1)</a>
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
-     * Why the _quick opcodes were removed from the second version of the Java
-     * Virtual Machine Specification.</a>
-     */
-    public static final short LDC2_W_QUICK = 205;
+  /** JVM internal opcode.
+   * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
+   * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
+   * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short NEW_QUICK                 = 221;
 
-    /**
-     * JVM internal opcode.
-     *
-     * @see <a
-     * href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
-     * Specification of _quick opcodes in the Java Virtual Machine Specification
-     * (version 1)</a>
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
-     * Why the _quick opcodes were removed from the second version of the Java
-     * Virtual Machine Specification.</a>
-     */
-    public static final short GETFIELD_QUICK = 206;
+  /** JVM internal opcode.
+   * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
+   * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
+   * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short ANEWARRAY_QUICK           = 222;
 
-    /**
-     * JVM internal opcode.
-     *
-     * @see <a
-     * href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
-     * Specification of _quick opcodes in the Java Virtual Machine Specification
-     * (version 1)</a>
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
-     * Why the _quick opcodes were removed from the second version of the Java
-     * Virtual Machine Specification.</a>
-     */
-    public static final short PUTFIELD_QUICK = 207;
+  /** JVM internal opcode.
+   * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
+   * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
+   * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short MULTIANEWARRAY_QUICK      = 223;
 
-    /**
-     * JVM internal opcode.
-     *
-     * @see <a
-     * href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
-     * Specification of _quick opcodes in the Java Virtual Machine Specification
-     * (version 1)</a>
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
-     * Why the _quick opcodes were removed from the second version of the Java
-     * Virtual Machine Specification.</a>
-     */
-    public static final short GETFIELD2_QUICK = 208;
+  /** JVM internal opcode.
+   * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
+   * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
+   * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short CHECKCAST_QUICK           = 224;
 
-    /**
-     * JVM internal opcode.
-     *
-     * @see <a
-     * href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
-     * Specification of _quick opcodes in the Java Virtual Machine Specification
-     * (version 1)</a>
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
-     * Why the _quick opcodes were removed from the second version of the Java
-     * Virtual Machine Specification.</a>
-     */
-    public static final short PUTFIELD2_QUICK = 209;
+  /** JVM internal opcode.
+   * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
+   * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
+   * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short INSTANCEOF_QUICK          = 225;
+
+  /** JVM internal opcode.
+   * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
+   * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
+   * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short INVOKEVIRTUAL_QUICK_W     = 226;
 
-    /**
-     * JVM internal opcode.
-     *
-     * @see <a
-     * href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
-     * Specification of _quick opcodes in the Java Virtual Machine Specification
-     * (version 1)</a>
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
-     * Why the _quick opcodes were removed from the second version of the Java
-     * Virtual Machine Specification.</a>
-     */
-    public static final short GETSTATIC_QUICK = 210;
+  /** JVM internal opcode.
+   * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
+   * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
+   * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short GETFIELD_QUICK_W          = 227;
 
-    /**
-     * JVM internal opcode.
-     *
-     * @see <a
-     * href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
-     * Specification of _quick opcodes in the Java Virtual Machine Specification
-     * (version 1)</a>
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
-     * Why the _quick opcodes were removed from the second version of the Java
-     * Virtual Machine Specification.</a>
-     */
-    public static final short PUTSTATIC_QUICK = 211;
+  /** JVM internal opcode.
+   * @see <a href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
+   * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1)</a>
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
+   * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification.</a> */
+  public static final short PUTFIELD_QUICK_W          = 228;
+
+  /** JVM internal opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.2">
+   * Reserved opcodes in the Java Virtual Machine Specification</a> */
+  public static final short IMPDEP1                   = 254;
 
-    /**
-     * JVM internal opcode.
-     *
-     * @see <a
-     * href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
-     * Specification of _quick opcodes in the Java Virtual Machine Specification
-     * (version 1)</a>
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
-     * Why the _quick opcodes were removed from the second version of the Java
-     * Virtual Machine Specification.</a>
-     */
-    public static final short GETSTATIC2_QUICK = 212;
+  /** JVM internal opcode.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.2">
+   * Reserved opcodes in the Java Virtual Machine Specification</a> */
+  public static final short IMPDEP2                   = 255;
+
+  /**
+   * BCEL virtual instruction for pushing an arbitrary data type onto the stack.  Will be converted to the appropriate JVM
+   * opcode when the class is dumped.
+   */
+  public static final short PUSH             = 4711;
 
-    /**
-     * JVM internal opcode.
-     *
-     * @see <a
-     * href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
-     * Specification of _quick opcodes in the Java Virtual Machine Specification
-     * (version 1)</a>
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
-     * Why the _quick opcodes were removed from the second version of the Java
-     * Virtual Machine Specification.</a>
-     */
-    public static final short PUTSTATIC2_QUICK = 213;
+  /**
+   * BCEL virtual instruction for either LOOKUPSWITCH or TABLESWITCH.  Will be converted to the appropriate JVM
+   * opcode when the class is dumped.
+   */
+  public static final short SWITCH           = 4712;
+
+  /** Illegal opcode. */
+  public static final short  UNDEFINED      = -1;
+
+  /** Illegal opcode. */
+  public static final short  UNPREDICTABLE  = -2;
+
+  /** Illegal opcode. */
+  public static final short  RESERVED       = -3;
 
-    /**
-     * JVM internal opcode.
-     *
-     * @see <a
-     * href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
-     * Specification of _quick opcodes in the Java Virtual Machine Specification
-     * (version 1)</a>
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
-     * Why the _quick opcodes were removed from the second version of the Java
-     * Virtual Machine Specification.</a>
-     */
-    public static final short INVOKEVIRTUAL_QUICK = 214;
+  /** Mnemonic for an illegal opcode. */
+  public static final String ILLEGAL_OPCODE = "<illegal opcode>";
+
+  /** Mnemonic for an illegal type. */
+  public static final String ILLEGAL_TYPE   = "<illegal type>";
+
+  /** Boolean data type.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.9.1-120-P">
+   * Static Constraints in the Java Virtual Machine Specification</a> */
+  public static final byte T_BOOLEAN = 4;
 
-    /**
-     * JVM internal opcode.
-     *
-     * @see <a
-     * href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
-     * Specification of _quick opcodes in the Java Virtual Machine Specification
-     * (version 1)</a>
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
-     * Why the _quick opcodes were removed from the second version of the Java
-     * Virtual Machine Specification.</a>
-     */
-    public static final short INVOKENONVIRTUAL_QUICK = 215;
+  /** Char data type.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.9.1-120-P">
+   * Static Constraints in the Java Virtual Machine Specification</a> */
+  public static final byte T_CHAR    = 5;
 
-    /**
-     * JVM internal opcode.
-     *
-     * @see <a
-     * href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
-     * Specification of _quick opcodes in the Java Virtual Machine Specification
-     * (version 1)</a>
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
-     * Why the _quick opcodes were removed from the second version of the Java
-     * Virtual Machine Specification.</a>
-     */
-    public static final short INVOKESUPER_QUICK = 216;
+  /** Float data type.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.9.1-120-P">
+   * Static Constraints in the Java Virtual Machine Specification</a> */
+  public static final byte T_FLOAT   = 6;
+
+  /** Double data type.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.9.1-120-P">
+   * Static Constraints in the Java Virtual Machine Specification</a> */
+  public static final byte T_DOUBLE  = 7;
 
-    /**
-     * JVM internal opcode.
-     *
-     * @see <a
-     * href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
-     * Specification of _quick opcodes in the Java Virtual Machine Specification
-     * (version 1)</a>
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
-     * Why the _quick opcodes were removed from the second version of the Java
-     * Virtual Machine Specification.</a>
-     */
-    public static final short INVOKESTATIC_QUICK = 217;
+  /** Byte data type.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.9.1-120-P">
+   * Static Constraints in the Java Virtual Machine Specification</a> */
+  public static final byte T_BYTE    = 8;
 
-    /**
-     * JVM internal opcode.
-     *
-     * @see <a
-     * href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
-     * Specification of _quick opcodes in the Java Virtual Machine Specification
-     * (version 1)</a>
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
-     * Why the _quick opcodes were removed from the second version of the Java
-     * Virtual Machine Specification.</a>
-     */
-    public static final short INVOKEINTERFACE_QUICK = 218;
+  /** Short data type.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.9.1-120-P">
+   * Static Constraints in the Java Virtual Machine Specification</a> */
+  public static final byte T_SHORT   = 9;
+
+  /** Int data type.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.9.1-120-P">
+   * Static Constraints in the Java Virtual Machine Specification</a> */
+  public static final byte T_INT     = 10;
 
-    /**
-     * JVM internal opcode.
-     *
-     * @see <a
-     * href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
-     * Specification of _quick opcodes in the Java Virtual Machine Specification
-     * (version 1)</a>
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
-     * Why the _quick opcodes were removed from the second version of the Java
-     * Virtual Machine Specification.</a>
-     */
-    public static final short INVOKEVIRTUALOBJECT_QUICK = 219;
+  /** Long data type.
+   * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.9.1-120-P">
+   * Static Constraints in the Java Virtual Machine Specification</a> */
+  public static final byte T_LONG    = 11;
+
+  /** Void data type (non-standard). */
+  public static final byte T_VOID      = 12; // Non-standard
 
-    /**
-     * JVM internal opcode.
-     *
-     * @see <a
-     * href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
-     * Specification of _quick opcodes in the Java Virtual Machine Specification
-     * (version 1)</a>
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
-     * Why the _quick opcodes were removed from the second version of the Java
-     * Virtual Machine Specification.</a>
-     */
-    public static final short NEW_QUICK = 221;
+  /** Array data type. */
+  public static final byte T_ARRAY     = 13;
+
+  /** Object data type. */
+  public static final byte T_OBJECT    = 14;
+
+  /** Reference data type (deprecated). */
+  public static final byte T_REFERENCE = 14; // Deprecated
+
+  /** Unknown data type. */
+  public static final byte T_UNKNOWN   = 15;
 
-    /**
-     * JVM internal opcode.
-     *
-     * @see <a
-     * href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
-     * Specification of _quick opcodes in the Java Virtual Machine Specification
-     * (version 1)</a>
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
-     * Why the _quick opcodes were removed from the second version of the Java
-     * Virtual Machine Specification.</a>
-     */
-    public static final short ANEWARRAY_QUICK = 222;
+  /** Address data type. */
+  public static final byte T_ADDRESS   = 16;
 
-    /**
-     * JVM internal opcode.
-     *
-     * @see <a
-     * href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
-     * Specification of _quick opcodes in the Java Virtual Machine Specification
-     * (version 1)</a>
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
-     * Why the _quick opcodes were removed from the second version of the Java
-     * Virtual Machine Specification.</a>
-     */
-    public static final short MULTIANEWARRAY_QUICK = 223;
+  /** The primitive type names corresponding to the T_XX constants,
+   * e.g., TYPE_NAMES[T_INT] = "int"
+   */
+  private static final String[] TYPE_NAMES = {
+    ILLEGAL_TYPE, ILLEGAL_TYPE,  ILLEGAL_TYPE, ILLEGAL_TYPE,
+    "boolean", "char", "float", "double", "byte", "short", "int", "long",
+    "void", "array", "object", "unknown", "address"
+  };
 
-    /**
-     * JVM internal opcode.
-     *
-     * @see <a
-     * href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
-     * Specification of _quick opcodes in the Java Virtual Machine Specification
-     * (version 1)</a>
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
-     * Why the _quick opcodes were removed from the second version of the Java
-     * Virtual Machine Specification.</a>
-     */
-    public static final short CHECKCAST_QUICK = 224;
+  /**
+   * The primitive type names corresponding to the T_XX constants,
+   * e.g., TYPE_NAMES[T_INT] = "int"
+   * @param index
+   * @return the type name
+   * @since 6.0
+   */
+  public static String getTypeName(final int index) {
+      return TYPE_NAMES[index];
+  }
 
-    /**
-     * JVM internal opcode.
-     *
-     * @see <a
-     * href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
-     * Specification of _quick opcodes in the Java Virtual Machine Specification
-     * (version 1)</a>
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
-     * Why the _quick opcodes were removed from the second version of the Java
-     * Virtual Machine Specification.</a>
-     */
-    public static final short INSTANCEOF_QUICK = 225;
-
-    /**
-     * JVM internal opcode.
-     *
-     * @see <a
-     * href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
-     * Specification of _quick opcodes in the Java Virtual Machine Specification
-     * (version 1)</a>
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
-     * Why the _quick opcodes were removed from the second version of the Java
-     * Virtual Machine Specification.</a>
-     */
-    public static final short INVOKEVIRTUAL_QUICK_W = 226;
+  /** The primitive class names corresponding to the T_XX constants,
+   * e.g., CLASS_TYPE_NAMES[T_INT] = "java.lang.Integer"
+   */
+  private static final String[] CLASS_TYPE_NAMES = {
+    ILLEGAL_TYPE, ILLEGAL_TYPE,  ILLEGAL_TYPE, ILLEGAL_TYPE,
+    "java.lang.Boolean", "java.lang.Character", "java.lang.Float",
+    "java.lang.Double", "java.lang.Byte", "java.lang.Short",
+    "java.lang.Integer", "java.lang.Long", "java.lang.Void",
+    ILLEGAL_TYPE, ILLEGAL_TYPE,  ILLEGAL_TYPE,  ILLEGAL_TYPE
+  };
 
-    /**
-     * JVM internal opcode.
-     *
-     * @see <a
-     * href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
-     * Specification of _quick opcodes in the Java Virtual Machine Specification
-     * (version 1)</a>
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
-     * Why the _quick opcodes were removed from the second version of the Java
-     * Virtual Machine Specification.</a>
-     */
-    public static final short GETFIELD_QUICK_W = 227;
+  /**
+   * The primitive class names corresponding to the T_XX constants,
+   * e.g., CLASS_TYPE_NAMES[T_INT] = "java.lang.Integer"
+   * @param index
+   * @return the class name
+   * @since 6.0
+   */
+  public static String getClassTypeName(final int index) {
+      return CLASS_TYPE_NAMES[index];
+  }
 
-    /**
-     * JVM internal opcode.
-     *
-     * @see <a
-     * href="https://web.archive.org/web/20120108031230/http://java.sun.com/docs/books/jvms/first_edition/html/Quick.doc.html">
-     * Specification of _quick opcodes in the Java Virtual Machine Specification
-     * (version 1)</a>
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se5.0/html/ChangesAppendix.doc.html#448885">
-     * Why the _quick opcodes were removed from the second version of the Java
-     * Virtual Machine Specification.</a>
-     */
-    public static final short PUTFIELD_QUICK_W = 228;
+  /** The signature characters corresponding to primitive types,
+   * e.g., SHORT_TYPE_NAMES[T_INT] = "I"
+   */
+  private static final String[] SHORT_TYPE_NAMES = {
+    ILLEGAL_TYPE, ILLEGAL_TYPE,  ILLEGAL_TYPE, ILLEGAL_TYPE,
+    "Z", "C", "F", "D", "B", "S", "I", "J",
+    "V", ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE
+  };
 
-    /**
-     * JVM internal opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.2">
-     * Reserved opcodes in the Java Virtual Machine Specification</a>
-     */
-    public static final short IMPDEP1 = 254;
+  /**
+   *
+   * @param index
+   * @return the short type name
+   * @since 6.0
+   */
+  public static String getShortTypeName(final int index) {
+      return SHORT_TYPE_NAMES[index];
+  }
+
 
-    /**
-     * JVM internal opcode.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.2">
-     * Reserved opcodes in the Java Virtual Machine Specification</a>
-     */
-    public static final short IMPDEP2 = 255;
-
-    /**
-     * BCEL virtual instruction for pushing an arbitrary data type onto the
-     * stack. Will be converted to the appropriate JVM opcode when the class is
-     * dumped.
-     */
-    public static final short PUSH = 4711;
-
-    /**
-     * BCEL virtual instruction for either LOOKUPSWITCH or TABLESWITCH. Will be
-     * converted to the appropriate JVM opcode when the class is dumped.
-     */
-    public static final short SWITCH = 4712;
-
-    /**
-     * Illegal opcode.
-     */
-    public static final short UNDEFINED = -1;
-
-    /**
-     * Illegal opcode.
-     */
-    public static final short UNPREDICTABLE = -2;
-
-    /**
-     * Illegal opcode.
-     */
-    public static final short RESERVED = -3;
-
-    /**
-     * Mnemonic for an illegal opcode.
-     */
-    public static final String ILLEGAL_OPCODE = "<illegal opcode>";
-
-    /**
-     * Mnemonic for an illegal type.
-     */
-    public static final String ILLEGAL_TYPE = "<illegal type>";
+  /**
+   * Number of byte code operands for each opcode, i.e., number of bytes after the tag byte
+   * itself.  Indexed by opcode, so NO_OF_OPERANDS[BIPUSH] = the number of operands for a bipush
+   * instruction.
+   */
+  private static final short[] NO_OF_OPERANDS = {
+    0/*nop*/, 0/*aconst_null*/, 0/*iconst_m1*/, 0/*iconst_0*/,
+    0/*iconst_1*/, 0/*iconst_2*/, 0/*iconst_3*/, 0/*iconst_4*/,
+    0/*iconst_5*/, 0/*lconst_0*/, 0/*lconst_1*/, 0/*fconst_0*/,
+    0/*fconst_1*/, 0/*fconst_2*/, 0/*dconst_0*/, 0/*dconst_1*/,
+    1/*bipush*/, 2/*sipush*/, 1/*ldc*/, 2/*ldc_w*/, 2/*ldc2_w*/,
+    1/*iload*/, 1/*lload*/, 1/*fload*/, 1/*dload*/, 1/*aload*/,
+    0/*iload_0*/, 0/*iload_1*/, 0/*iload_2*/, 0/*iload_3*/,
+    0/*lload_0*/, 0/*lload_1*/, 0/*lload_2*/, 0/*lload_3*/,
+    0/*fload_0*/, 0/*fload_1*/, 0/*fload_2*/, 0/*fload_3*/,
+    0/*dload_0*/, 0/*dload_1*/, 0/*dload_2*/, 0/*dload_3*/,
+    0/*aload_0*/, 0/*aload_1*/, 0/*aload_2*/, 0/*aload_3*/,
+    0/*iaload*/, 0/*laload*/, 0/*faload*/, 0/*daload*/,
+    0/*aaload*/, 0/*baload*/, 0/*caload*/, 0/*saload*/,
+    1/*istore*/, 1/*lstore*/, 1/*fstore*/, 1/*dstore*/,
+    1/*astore*/, 0/*istore_0*/, 0/*istore_1*/, 0/*istore_2*/,
+    0/*istore_3*/, 0/*lstore_0*/, 0/*lstore_1*/, 0/*lstore_2*/,
+    0/*lstore_3*/, 0/*fstore_0*/, 0/*fstore_1*/, 0/*fstore_2*/,
+    0/*fstore_3*/, 0/*dstore_0*/, 0/*dstore_1*/, 0/*dstore_2*/,
+    0/*dstore_3*/, 0/*astore_0*/, 0/*astore_1*/, 0/*astore_2*/,
+    0/*astore_3*/, 0/*iastore*/, 0/*lastore*/, 0/*fastore*/,
+    0/*dastore*/, 0/*aastore*/, 0/*bastore*/, 0/*castore*/,
+    0/*sastore*/, 0/*pop*/, 0/*pop2*/, 0/*dup*/, 0/*dup_x1*/,
+    0/*dup_x2*/, 0/*dup2*/, 0/*dup2_x1*/, 0/*dup2_x2*/, 0/*swap*/,
+    0/*iadd*/, 0/*ladd*/, 0/*fadd*/, 0/*dadd*/, 0/*isub*/,
+    0/*lsub*/, 0/*fsub*/, 0/*dsub*/, 0/*imul*/, 0/*lmul*/,
+    0/*fmul*/, 0/*dmul*/, 0/*idiv*/, 0/*ldiv*/, 0/*fdiv*/,
+    0/*ddiv*/, 0/*irem*/, 0/*lrem*/, 0/*frem*/, 0/*drem*/,
+    0/*ineg*/, 0/*lneg*/, 0/*fneg*/, 0/*dneg*/, 0/*ishl*/,
+    0/*lshl*/, 0/*ishr*/, 0/*lshr*/, 0/*iushr*/, 0/*lushr*/,
+    0/*iand*/, 0/*land*/, 0/*ior*/, 0/*lor*/, 0/*ixor*/, 0/*lxor*/,
+    2/*iinc*/, 0/*i2l*/, 0/*i2f*/, 0/*i2d*/, 0/*l2i*/, 0/*l2f*/,
+    0/*l2d*/, 0/*f2i*/, 0/*f2l*/, 0/*f2d*/, 0/*d2i*/, 0/*d2l*/,
+    0/*d2f*/, 0/*i2b*/, 0/*i2c*/, 0/*i2s*/, 0/*lcmp*/, 0/*fcmpl*/,
+    0/*fcmpg*/, 0/*dcmpl*/, 0/*dcmpg*/, 2/*ifeq*/, 2/*ifne*/,
+    2/*iflt*/, 2/*ifge*/, 2/*ifgt*/, 2/*ifle*/, 2/*if_icmpeq*/,
+    2/*if_icmpne*/, 2/*if_icmplt*/, 2/*if_icmpge*/, 2/*if_icmpgt*/,
+    2/*if_icmple*/, 2/*if_acmpeq*/, 2/*if_acmpne*/, 2/*goto*/,
+    2/*jsr*/, 1/*ret*/, UNPREDICTABLE/*tableswitch*/, UNPREDICTABLE/*lookupswitch*/,
+    0/*ireturn*/, 0/*lreturn*/, 0/*freturn*/,
+    0/*dreturn*/, 0/*areturn*/, 0/*return*/,
+    2/*getstatic*/, 2/*putstatic*/, 2/*getfield*/,
+    2/*putfield*/, 2/*invokevirtual*/, 2/*invokespecial*/, 2/*invokestatic*/,
+    4/*invokeinterface*/, 4/*invokedynamic*/, 2/*new*/,
+    1/*newarray*/, 2/*anewarray*/,
+    0/*arraylength*/, 0/*athrow*/, 2/*checkcast*/,
+    2/*instanceof*/, 0/*monitorenter*/,
+    0/*monitorexit*/, UNPREDICTABLE/*wide*/, 3/*multianewarray*/,
+    2/*ifnull*/, 2/*ifnonnull*/, 4/*goto_w*/,
+    4/*jsr_w*/, 0/*breakpoint*/, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, RESERVED/*impdep1*/, RESERVED/*impdep2*/
+  };
 
-    /**
-     * Boolean data type.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.9.1-120-P">
-     * Static Constraints in the Java Virtual Machine Specification</a>
-     */
-    public static final byte T_BOOLEAN = 4;
-
-    /**
-     * Char data type.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.9.1-120-P">
-     * Static Constraints in the Java Virtual Machine Specification</a>
-     */
-    public static final byte T_CHAR = 5;
-
-    /**
-     * Float data type.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.9.1-120-P">
-     * Static Constraints in the Java Virtual Machine Specification</a>
-     */
-    public static final byte T_FLOAT = 6;
-
-    /**
-     * Double data type.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.9.1-120-P">
-     * Static Constraints in the Java Virtual Machine Specification</a>
-     */
-    public static final byte T_DOUBLE = 7;
-
-    /**
-     * Byte data type.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.9.1-120-P">
-     * Static Constraints in the Java Virtual Machine Specification</a>
-     */
-    public static final byte T_BYTE = 8;
-
-    /**
-     * Short data type.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.9.1-120-P">
-     * Static Constraints in the Java Virtual Machine Specification</a>
-     */
-    public static final byte T_SHORT = 9;
+  /**
+   *
+   * @param index
+   * @return Number of byte code operands
+   * @since 6.0
+   */
+  public static short getNoOfOperands(final int index) {
+      return NO_OF_OPERANDS[index];
+  }
 
-    /**
-     * Int data type.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.9.1-120-P">
-     * Static Constraints in the Java Virtual Machine Specification</a>
-     */
-    public static final byte T_INT = 10;
-
-    /**
-     * Long data type.
-     *
-     * @see <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.9.1-120-P">
-     * Static Constraints in the Java Virtual Machine Specification</a>
-     */
-    public static final byte T_LONG = 11;
-
-    /**
-     * Void data type (non-standard).
-     */
-    public static final byte T_VOID = 12; // Non-standard
-
-    /**
-     * Array data type.
-     */
-    public static final byte T_ARRAY = 13;
-
-    /**
-     * Object data type.
-     */
-    public static final byte T_OBJECT = 14;
-
-    /**
-     * Reference data type (deprecated).
-     */
-    public static final byte T_REFERENCE = 14; // Deprecated
-
-    /**
-     * Unknown data type.
-     */
-    public static final byte T_UNKNOWN = 15;
-
-    /**
-     * Address data type.
-     */
-    public static final byte T_ADDRESS = 16;
+  /**
+   * How the byte code operands are to be interpreted for each opcode.
+   * Indexed by opcode.  TYPE_OF_OPERANDS[ILOAD] = an array of shorts
+   * describing the data types for the instruction.
+   */
+  private static final short[][] TYPE_OF_OPERANDS = {
+    {}/*nop*/, {}/*aconst_null*/, {}/*iconst_m1*/, {}/*iconst_0*/,
+    {}/*iconst_1*/, {}/*iconst_2*/, {}/*iconst_3*/, {}/*iconst_4*/,
+    {}/*iconst_5*/, {}/*lconst_0*/, {}/*lconst_1*/, {}/*fconst_0*/,
+    {}/*fconst_1*/, {}/*fconst_2*/, {}/*dconst_0*/, {}/*dconst_1*/,
+    {T_BYTE}/*bipush*/, {T_SHORT}/*sipush*/, {T_BYTE}/*ldc*/,
+    {T_SHORT}/*ldc_w*/, {T_SHORT}/*ldc2_w*/,
+    {T_BYTE}/*iload*/, {T_BYTE}/*lload*/, {T_BYTE}/*fload*/,
+    {T_BYTE}/*dload*/, {T_BYTE}/*aload*/, {}/*iload_0*/,
+    {}/*iload_1*/, {}/*iload_2*/, {}/*iload_3*/, {}/*lload_0*/,
+    {}/*lload_1*/, {}/*lload_2*/, {}/*lload_3*/, {}/*fload_0*/,
+    {}/*fload_1*/, {}/*fload_2*/, {}/*fload_3*/, {}/*dload_0*/,
+    {}/*dload_1*/, {}/*dload_2*/, {}/*dload_3*/, {}/*aload_0*/,
+    {}/*aload_1*/, {}/*aload_2*/, {}/*aload_3*/, {}/*iaload*/,
+    {}/*laload*/, {}/*faload*/, {}/*daload*/, {}/*aaload*/,
+    {}/*baload*/, {}/*caload*/, {}/*saload*/, {T_BYTE}/*istore*/,
+    {T_BYTE}/*lstore*/, {T_BYTE}/*fstore*/, {T_BYTE}/*dstore*/,
+    {T_BYTE}/*astore*/, {}/*istore_0*/, {}/*istore_1*/,
+    {}/*istore_2*/, {}/*istore_3*/, {}/*lstore_0*/, {}/*lstore_1*/,
+    {}/*lstore_2*/, {}/*lstore_3*/, {}/*fstore_0*/, {}/*fstore_1*/,
+    {}/*fstore_2*/, {}/*fstore_3*/, {}/*dstore_0*/, {}/*dstore_1*/,
+    {}/*dstore_2*/, {}/*dstore_3*/, {}/*astore_0*/, {}/*astore_1*/,
+    {}/*astore_2*/, {}/*astore_3*/, {}/*iastore*/, {}/*lastore*/,
+    {}/*fastore*/, {}/*dastore*/, {}/*aastore*/, {}/*bastore*/,
+    {}/*castore*/, {}/*sastore*/, {}/*pop*/, {}/*pop2*/, {}/*dup*/,
+    {}/*dup_x1*/, {}/*dup_x2*/, {}/*dup2*/, {}/*dup2_x1*/,
+    {}/*dup2_x2*/, {}/*swap*/, {}/*iadd*/, {}/*ladd*/, {}/*fadd*/,
+    {}/*dadd*/, {}/*isub*/, {}/*lsub*/, {}/*fsub*/, {}/*dsub*/,
+    {}/*imul*/, {}/*lmul*/, {}/*fmul*/, {}/*dmul*/, {}/*idiv*/,
+    {}/*ldiv*/, {}/*fdiv*/, {}/*ddiv*/, {}/*irem*/, {}/*lrem*/,
+    {}/*frem*/, {}/*drem*/, {}/*ineg*/, {}/*lneg*/, {}/*fneg*/,
+    {}/*dneg*/, {}/*ishl*/, {}/*lshl*/, {}/*ishr*/, {}/*lshr*/,
+    {}/*iushr*/, {}/*lushr*/, {}/*iand*/, {}/*land*/, {}/*ior*/,
+    {}/*lor*/, {}/*ixor*/, {}/*lxor*/, {T_BYTE, T_BYTE}/*iinc*/,
+    {}/*i2l*/, {}/*i2f*/, {}/*i2d*/, {}/*l2i*/, {}/*l2f*/, {}/*l2d*/,
+    {}/*f2i*/, {}/*f2l*/, {}/*f2d*/, {}/*d2i*/, {}/*d2l*/, {}/*d2f*/,
+    {}/*i2b*/, {}/*i2c*/, {}/*i2s*/, {}/*lcmp*/, {}/*fcmpl*/,
+    {}/*fcmpg*/, {}/*dcmpl*/, {}/*dcmpg*/, {T_SHORT}/*ifeq*/,
+    {T_SHORT}/*ifne*/, {T_SHORT}/*iflt*/, {T_SHORT}/*ifge*/,
+    {T_SHORT}/*ifgt*/, {T_SHORT}/*ifle*/, {T_SHORT}/*if_icmpeq*/,
+    {T_SHORT}/*if_icmpne*/, {T_SHORT}/*if_icmplt*/,
+    {T_SHORT}/*if_icmpge*/, {T_SHORT}/*if_icmpgt*/,
+    {T_SHORT}/*if_icmple*/, {T_SHORT}/*if_acmpeq*/,
+    {T_SHORT}/*if_acmpne*/, {T_SHORT}/*goto*/, {T_SHORT}/*jsr*/,
+    {T_BYTE}/*ret*/, {}/*tableswitch*/, {}/*lookupswitch*/,
+    {}/*ireturn*/, {}/*lreturn*/, {}/*freturn*/, {}/*dreturn*/,
+    {}/*areturn*/, {}/*return*/, {T_SHORT}/*getstatic*/,
+    {T_SHORT}/*putstatic*/, {T_SHORT}/*getfield*/,
+    {T_SHORT}/*putfield*/, {T_SHORT}/*invokevirtual*/,
+    {T_SHORT}/*invokespecial*/, {T_SHORT}/*invokestatic*/,
+    {T_SHORT, T_BYTE, T_BYTE}/*invokeinterface*/, {T_SHORT, T_BYTE, T_BYTE}/*invokedynamic*/,
+    {T_SHORT}/*new*/, {T_BYTE}/*newarray*/,
+    {T_SHORT}/*anewarray*/, {}/*arraylength*/, {}/*athrow*/,
+    {T_SHORT}/*checkcast*/, {T_SHORT}/*instanceof*/,
+    {}/*monitorenter*/, {}/*monitorexit*/, {T_BYTE}/*wide*/,
+    {T_SHORT, T_BYTE}/*multianewarray*/, {T_SHORT}/*ifnull*/,
+    {T_SHORT}/*ifnonnull*/, {T_INT}/*goto_w*/, {T_INT}/*jsr_w*/,
+    {}/*breakpoint*/, {}, {}, {}, {}, {}, {}, {},
+    {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {},
+    {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {},
+    {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {},
+    {}/*impdep1*/, {}/*impdep2*/
+  };
 
-    /**
-     * The primitive type names corresponding to the T_XX constants, e.g.,
-     * TYPE_NAMES[T_INT] = "int"
-     */
-    private static final String[] TYPE_NAMES = {
-        ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE,
-        "boolean", "char", "float", "double", "byte", "short", "int", "long",
-        "void", "array", "object", "unknown", "address"
-    };
-
-    /**
-     * The primitive type names corresponding to the T_XX constants, e.g.,
-     * TYPE_NAMES[T_INT] = "int"
-     *
-     * @param index
-     * @return the type name
-     * @since 6.0
-     */
-    public static String getTypeName(final int index) {
-        return TYPE_NAMES[index];
-    }
+  /**
+   * @since 6.0
+   */
+  public static short getOperandType(final int opcode, final int index) {
+      return TYPE_OF_OPERANDS[opcode][index];
+  }
 
-    /**
-     * The primitive class names corresponding to the T_XX constants, e.g.,
-     * CLASS_TYPE_NAMES[T_INT] = "java.lang.Integer"
-     */
-    private static final String[] CLASS_TYPE_NAMES = {
-        ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE,
-        "java.lang.Boolean", "java.lang.Character", "java.lang.Float",
-        "java.lang.Double", "java.lang.Byte", "java.lang.Short",
-        "java.lang.Integer", "java.lang.Long", "java.lang.Void",
-        ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE
-    };
-
-    /**
-     * The primitive class names corresponding to the T_XX constants, e.g.,
-     * CLASS_TYPE_NAMES[T_INT] = "java.lang.Integer"
-     *
-     * @param index
-     * @return the class name
-     * @since 6.0
-     */
-    public static String getClassTypeName(final int index) {
-        return CLASS_TYPE_NAMES[index];
-    }
-
-    /**
-     * The signature characters corresponding to primitive types, e.g.,
-     * SHORT_TYPE_NAMES[T_INT] = "I"
-     */
-    private static final String[] SHORT_TYPE_NAMES = {
-        ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE,
-        "Z", "C", "F", "D", "B", "S", "I", "J",
-        "V", ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE
-    };
-
-    /**
-     *
-     * @param index
-     * @return the short type name
-     * @since 6.0
-     */
-    public static String getShortTypeName(final int index) {
-        return SHORT_TYPE_NAMES[index];
-    }
+  /**
+   * @since 6.0
+   */
+  public static long getOperandTypeCount(final int opcode) {
+      return TYPE_OF_OPERANDS[opcode].length;
+  }
 
-    /**
-     * Number of byte code operands for each opcode, i.e., number of bytes after
-     * the tag byte itself. Indexed by opcode, so NO_OF_OPERANDS[BIPUSH] = the
-     * number of operands for a bipush instruction.
-     */
-    private static final short[] NO_OF_OPERANDS = {
-        0/*nop*/, 0/*aconst_null*/, 0/*iconst_m1*/, 0/*iconst_0*/,
-        0/*iconst_1*/, 0/*iconst_2*/, 0/*iconst_3*/, 0/*iconst_4*/,
-        0/*iconst_5*/, 0/*lconst_0*/, 0/*lconst_1*/, 0/*fconst_0*/,
-        0/*fconst_1*/, 0/*fconst_2*/, 0/*dconst_0*/, 0/*dconst_1*/,
-        1/*bipush*/, 2/*sipush*/, 1/*ldc*/, 2/*ldc_w*/, 2/*ldc2_w*/,
-        1/*iload*/, 1/*lload*/, 1/*fload*/, 1/*dload*/, 1/*aload*/,
-        0/*iload_0*/, 0/*iload_1*/, 0/*iload_2*/, 0/*iload_3*/,
-        0/*lload_0*/, 0/*lload_1*/, 0/*lload_2*/, 0/*lload_3*/,
-        0/*fload_0*/, 0/*fload_1*/, 0/*fload_2*/, 0/*fload_3*/,
-        0/*dload_0*/, 0/*dload_1*/, 0/*dload_2*/, 0/*dload_3*/,
-        0/*aload_0*/, 0/*aload_1*/, 0/*aload_2*/, 0/*aload_3*/,
-        0/*iaload*/, 0/*laload*/, 0/*faload*/, 0/*daload*/,
-        0/*aaload*/, 0/*baload*/, 0/*caload*/, 0/*saload*/,
-        1/*istore*/, 1/*lstore*/, 1/*fstore*/, 1/*dstore*/,
-        1/*astore*/, 0/*istore_0*/, 0/*istore_1*/, 0/*istore_2*/,
-        0/*istore_3*/, 0/*lstore_0*/, 0/*lstore_1*/, 0/*lstore_2*/,
-        0/*lstore_3*/, 0/*fstore_0*/, 0/*fstore_1*/, 0/*fstore_2*/,
-        0/*fstore_3*/, 0/*dstore_0*/, 0/*dstore_1*/, 0/*dstore_2*/,
-        0/*dstore_3*/, 0/*astore_0*/, 0/*astore_1*/, 0/*astore_2*/,
-        0/*astore_3*/, 0/*iastore*/, 0/*lastore*/, 0/*fastore*/,
-        0/*dastore*/, 0/*aastore*/, 0/*bastore*/, 0/*castore*/,
-        0/*sastore*/, 0/*pop*/, 0/*pop2*/, 0/*dup*/, 0/*dup_x1*/,
-        0/*dup_x2*/, 0/*dup2*/, 0/*dup2_x1*/, 0/*dup2_x2*/, 0/*swap*/,
-        0/*iadd*/, 0/*ladd*/, 0/*fadd*/, 0/*dadd*/, 0/*isub*/,
-        0/*lsub*/, 0/*fsub*/, 0/*dsub*/, 0/*imul*/, 0/*lmul*/,
-        0/*fmul*/, 0/*dmul*/, 0/*idiv*/, 0/*ldiv*/, 0/*fdiv*/,
-        0/*ddiv*/, 0/*irem*/, 0/*lrem*/, 0/*frem*/, 0/*drem*/,
-        0/*ineg*/, 0/*lneg*/, 0/*fneg*/, 0/*dneg*/, 0/*ishl*/,
-        0/*lshl*/, 0/*ishr*/, 0/*lshr*/, 0/*iushr*/, 0/*lushr*/,
-        0/*iand*/, 0/*land*/, 0/*ior*/, 0/*lor*/, 0/*ixor*/, 0/*lxor*/,
-        2/*iinc*/, 0/*i2l*/, 0/*i2f*/, 0/*i2d*/, 0/*l2i*/, 0/*l2f*/,
-        0/*l2d*/, 0/*f2i*/, 0/*f2l*/, 0/*f2d*/, 0/*d2i*/, 0/*d2l*/,
-        0/*d2f*/, 0/*i2b*/, 0/*i2c*/, 0/*i2s*/, 0/*lcmp*/, 0/*fcmpl*/,
-        0/*fcmpg*/, 0/*dcmpl*/, 0/*dcmpg*/, 2/*ifeq*/, 2/*ifne*/,
-        2/*iflt*/, 2/*ifge*/, 2/*ifgt*/, 2/*ifle*/, 2/*if_icmpeq*/,
-        2/*if_icmpne*/, 2/*if_icmplt*/, 2/*if_icmpge*/, 2/*if_icmpgt*/,
-        2/*if_icmple*/, 2/*if_acmpeq*/, 2/*if_acmpne*/, 2/*goto*/,
-        2/*jsr*/, 1/*ret*/, UNPREDICTABLE/*tableswitch*/, UNPREDICTABLE/*lookupswitch*/,
-        0/*ireturn*/, 0/*lreturn*/, 0/*freturn*/,
-        0/*dreturn*/, 0/*areturn*/, 0/*return*/,
-        2/*getstatic*/, 2/*putstatic*/, 2/*getfield*/,
-        2/*putfield*/, 2/*invokevirtual*/, 2/*invokespecial*/, 2/*invokestatic*/,
-        4/*invokeinterface*/, 4/*invokedynamic*/, 2/*new*/,
-        1/*newarray*/, 2/*anewarray*/,
-        0/*arraylength*/, 0/*athrow*/, 2/*checkcast*/,
-        2/*instanceof*/, 0/*monitorenter*/,
-        0/*monitorexit*/, UNPREDICTABLE/*wide*/, 3/*multianewarray*/,
-        2/*ifnull*/, 2/*ifnonnull*/, 4/*goto_w*/,
-        4/*jsr_w*/, 0/*breakpoint*/, UNDEFINED,
-        UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
-        UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
-        UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
-        UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
-        UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
-        UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
-        UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
-        UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
-        UNDEFINED, UNDEFINED, RESERVED/*impdep1*/, RESERVED/*impdep2*/};
+  /**
+   * Names of opcodes.  Indexed by opcode.  OPCODE_NAMES[ALOAD] = "aload".
+   */
+  private static final String[] OPCODE_NAMES = {
+    "nop", "aconst_null", "iconst_m1", "iconst_0", "iconst_1",
+    "iconst_2", "iconst_3", "iconst_4", "iconst_5", "lconst_0",
+    "lconst_1", "fconst_0", "fconst_1", "fconst_2", "dconst_0",
+    "dconst_1", "bipush", "sipush", "ldc", "ldc_w", "ldc2_w", "iload",
+    "lload", "fload", "dload", "aload", "iload_0", "iload_1", "iload_2",
+    "iload_3", "lload_0", "lload_1", "lload_2", "lload_3", "fload_0",
+    "fload_1", "fload_2", "fload_3", "dload_0", "dload_1", "dload_2",
+    "dload_3", "aload_0", "aload_1", "aload_2", "aload_3", "iaload",
+    "laload", "faload", "daload", "aaload", "baload", "caload", "saload",
+    "istore", "lstore", "fstore", "dstore", "astore", "istore_0",
+    "istore_1", "istore_2", "istore_3", "lstore_0", "lstore_1",
+    "lstore_2", "lstore_3", "fstore_0", "fstore_1", "fstore_2",
+    "fstore_3", "dstore_0", "dstore_1", "dstore_2", "dstore_3",
+    "astore_0", "astore_1", "astore_2", "astore_3", "iastore", "lastore",
+    "fastore", "dastore", "aastore", "bastore", "castore", "sastore",
+    "pop", "pop2", "dup", "dup_x1", "dup_x2", "dup2", "dup2_x1",
+    "dup2_x2", "swap", "iadd", "ladd", "fadd", "dadd", "isub", "lsub",
+    "fsub", "dsub", "imul", "lmul", "fmul", "dmul", "idiv", "ldiv",
+    "fdiv", "ddiv", "irem", "lrem", "frem", "drem", "ineg", "lneg",
+    "fneg", "dneg", "ishl", "lshl", "ishr", "lshr", "iushr", "lushr",
+    "iand", "land", "ior", "lor", "ixor", "lxor", "iinc", "i2l", "i2f",
+    "i2d", "l2i", "l2f", "l2d", "f2i", "f2l", "f2d", "d2i", "d2l", "d2f",
+    "i2b", "i2c", "i2s", "lcmp", "fcmpl", "fcmpg",
+    "dcmpl", "dcmpg", "ifeq", "ifne", "iflt", "ifge", "ifgt", "ifle",
+    "if_icmpeq", "if_icmpne", "if_icmplt", "if_icmpge", "if_icmpgt",
+    "if_icmple", "if_acmpeq", "if_acmpne", "goto", "jsr", "ret",
+    "tableswitch", "lookupswitch", "ireturn", "lreturn", "freturn",
+    "dreturn", "areturn", "return", "getstatic", "putstatic", "getfield",
+    "putfield", "invokevirtual", "invokespecial", "invokestatic",
+    "invokeinterface", "invokedynamic", "new", "newarray", "anewarray",
+    "arraylength", "athrow", "checkcast", "instanceof", "monitorenter",
+    "monitorexit", "wide", "multianewarray", "ifnull", "ifnonnull",
+    "goto_w", "jsr_w", "breakpoint", ILLEGAL_OPCODE, ILLEGAL_OPCODE,
+    ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
+    ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
+    ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
+    ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
+    ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
+    ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
+    ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
+    ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
+    ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
+    ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
+    ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
+    ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
+    ILLEGAL_OPCODE, "impdep1", "impdep2"
+  };
 
-    /**
-     *
-     * @param index
-     * @return Number of byte code operands
-     * @since 6.0
-     */
-    public static short getNoOfOperands(final int index) {
-        return NO_OF_OPERANDS[index];
-    }
+  /**
+   * @since 6.0
+   */
+  public static final int OPCODE_NAMES_LENGTH = OPCODE_NAMES.length;
+
+
+  /**
+   * @since 6.0
+   */
+  public static String getOpcodeName(final int index) {
+      return OPCODE_NAMES[index];
+  }
 
-    /**
-     * How the byte code operands are to be interpreted for each opcode. Indexed
-     * by opcode. TYPE_OF_OPERANDS[ILOAD] = an array of shorts describing the
-     * data types for the instruction.
-     */
-    private static final short[][] TYPE_OF_OPERANDS = {
-        {}/*nop*/, {}/*aconst_null*/, {}/*iconst_m1*/, {}/*iconst_0*/,
-        {}/*iconst_1*/, {}/*iconst_2*/, {}/*iconst_3*/, {}/*iconst_4*/,
-        {}/*iconst_5*/, {}/*lconst_0*/, {}/*lconst_1*/, {}/*fconst_0*/,
-        {}/*fconst_1*/, {}/*fconst_2*/, {}/*dconst_0*/, {}/*dconst_1*/,
-        {T_BYTE}/*bipush*/, {T_SHORT}/*sipush*/, {T_BYTE}/*ldc*/,
-        {T_SHORT}/*ldc_w*/, {T_SHORT}/*ldc2_w*/,
-        {T_BYTE}/*iload*/, {T_BYTE}/*lload*/, {T_BYTE}/*fload*/,
-        {T_BYTE}/*dload*/, {T_BYTE}/*aload*/, {}/*iload_0*/,
-        {}/*iload_1*/, {}/*iload_2*/, {}/*iload_3*/, {}/*lload_0*/,
-        {}/*lload_1*/, {}/*lload_2*/, {}/*lload_3*/, {}/*fload_0*/,
-        {}/*fload_1*/, {}/*fload_2*/, {}/*fload_3*/, {}/*dload_0*/,
-        {}/*dload_1*/, {}/*dload_2*/, {}/*dload_3*/, {}/*aload_0*/,
-        {}/*aload_1*/, {}/*aload_2*/, {}/*aload_3*/, {}/*iaload*/,
-        {}/*laload*/, {}/*faload*/, {}/*daload*/, {}/*aaload*/,
-        {}/*baload*/, {}/*caload*/, {}/*saload*/, {T_BYTE}/*istore*/,
-        {T_BYTE}/*lstore*/, {T_BYTE}/*fstore*/, {T_BYTE}/*dstore*/,
-        {T_BYTE}/*astore*/, {}/*istore_0*/, {}/*istore_1*/,
-        {}/*istore_2*/, {}/*istore_3*/, {}/*lstore_0*/, {}/*lstore_1*/,
-        {}/*lstore_2*/, {}/*lstore_3*/, {}/*fstore_0*/, {}/*fstore_1*/,
-        {}/*fstore_2*/, {}/*fstore_3*/, {}/*dstore_0*/, {}/*dstore_1*/,
-        {}/*dstore_2*/, {}/*dstore_3*/, {}/*astore_0*/, {}/*astore_1*/,
-        {}/*astore_2*/, {}/*astore_3*/, {}/*iastore*/, {}/*lastore*/,
-        {}/*fastore*/, {}/*dastore*/, {}/*aastore*/, {}/*bastore*/,
-        {}/*castore*/, {}/*sastore*/, {}/*pop*/, {}/*pop2*/, {}/*dup*/,
-        {}/*dup_x1*/, {}/*dup_x2*/, {}/*dup2*/, {}/*dup2_x1*/,
-        {}/*dup2_x2*/, {}/*swap*/, {}/*iadd*/, {}/*ladd*/, {}/*fadd*/,
-        {}/*dadd*/, {}/*isub*/, {}/*lsub*/, {}/*fsub*/, {}/*dsub*/,
-        {}/*imul*/, {}/*lmul*/, {}/*fmul*/, {}/*dmul*/, {}/*idiv*/,
-        {}/*ldiv*/, {}/*fdiv*/, {}/*ddiv*/, {}/*irem*/, {}/*lrem*/,
-        {}/*frem*/, {}/*drem*/, {}/*ineg*/, {}/*lneg*/, {}/*fneg*/,
-        {}/*dneg*/, {}/*ishl*/, {}/*lshl*/, {}/*ishr*/, {}/*lshr*/,
-        {}/*iushr*/, {}/*lushr*/, {}/*iand*/, {}/*land*/, {}/*ior*/,
-        {}/*lor*/, {}/*ixor*/, {}/*lxor*/, {T_BYTE, T_BYTE}/*iinc*/,
-        {}/*i2l*/, {}/*i2f*/, {}/*i2d*/, {}/*l2i*/, {}/*l2f*/, {}/*l2d*/,
-        {}/*f2i*/, {}/*f2l*/, {}/*f2d*/, {}/*d2i*/, {}/*d2l*/, {}/*d2f*/,
-        {}/*i2b*/, {}/*i2c*/, {}/*i2s*/, {}/*lcmp*/, {}/*fcmpl*/,
-        {}/*fcmpg*/, {}/*dcmpl*/, {}/*dcmpg*/, {T_SHORT}/*ifeq*/,
-        {T_SHORT}/*ifne*/, {T_SHORT}/*iflt*/, {T_SHORT}/*ifge*/,
-        {T_SHORT}/*ifgt*/, {T_SHORT}/*ifle*/, {T_SHORT}/*if_icmpeq*/,
-        {T_SHORT}/*if_icmpne*/, {T_SHORT}/*if_icmplt*/,
-        {T_SHORT}/*if_icmpge*/, {T_SHORT}/*if_icmpgt*/,
-        {T_SHORT}/*if_icmple*/, {T_SHORT}/*if_acmpeq*/,
-        {T_SHORT}/*if_acmpne*/, {T_SHORT}/*goto*/, {T_SHORT}/*jsr*/,
-        {T_BYTE}/*ret*/, {}/*tableswitch*/, {}/*lookupswitch*/,
-        {}/*ireturn*/, {}/*lreturn*/, {}/*freturn*/, {}/*dreturn*/,
-        {}/*areturn*/, {}/*return*/, {T_SHORT}/*getstatic*/,
-        {T_SHORT}/*putstatic*/, {T_SHORT}/*getfield*/,
-        {T_SHORT}/*putfield*/, {T_SHORT}/*invokevirtual*/,
-        {T_SHORT}/*invokespecial*/, {T_SHORT}/*invokestatic*/,
-        {T_SHORT, T_BYTE, T_BYTE}/*invokeinterface*/, {T_SHORT, T_BYTE, T_BYTE}/*invokedynamic*/,
-        {T_SHORT}/*new*/, {T_BYTE}/*newarray*/,
-        {T_SHORT}/*anewarray*/, {}/*arraylength*/, {}/*athrow*/,
-        {T_SHORT}/*checkcast*/, {T_SHORT}/*instanceof*/,
-        {}/*monitorenter*/, {}/*monitorexit*/, {T_BYTE}/*wide*/,
-        {T_SHORT, T_BYTE}/*multianewarray*/, {T_SHORT}/*ifnull*/,
-        {T_SHORT}/*ifnonnull*/, {T_INT}/*goto_w*/, {T_INT}/*jsr_w*/,
-        {}/*breakpoint*/, {}, {}, {}, {}, {}, {}, {},
-        {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {},
-        {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {},
-        {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {},
-        {}/*impdep1*/, {}/*impdep2*/};
+  /**
+   * Number of words consumed on operand stack by instructions.
+   * Indexed by opcode.  CONSUME_STACK[FALOAD] = number of words
+   * consumed from the stack by a faload instruction.
+   */
+  private static final int[] CONSUME_STACK = {
+    0/*nop*/, 0/*aconst_null*/, 0/*iconst_m1*/, 0/*iconst_0*/, 0/*iconst_1*/,
+    0/*iconst_2*/, 0/*iconst_3*/, 0/*iconst_4*/, 0/*iconst_5*/, 0/*lconst_0*/,
+    0/*lconst_1*/, 0/*fconst_0*/, 0/*fconst_1*/, 0/*fconst_2*/, 0/*dconst_0*/,
+    0/*dconst_1*/, 0/*bipush*/, 0/*sipush*/, 0/*ldc*/, 0/*ldc_w*/, 0/*ldc2_w*/, 0/*iload*/,
+    0/*lload*/, 0/*fload*/, 0/*dload*/, 0/*aload*/, 0/*iload_0*/, 0/*iload_1*/, 0/*iload_2*/,
+    0/*iload_3*/, 0/*lload_0*/, 0/*lload_1*/, 0/*lload_2*/, 0/*lload_3*/, 0/*fload_0*/,
+    0/*fload_1*/, 0/*fload_2*/, 0/*fload_3*/, 0/*dload_0*/, 0/*dload_1*/, 0/*dload_2*/,
+    0/*dload_3*/, 0/*aload_0*/, 0/*aload_1*/, 0/*aload_2*/, 0/*aload_3*/, 2/*iaload*/,
+    2/*laload*/, 2/*faload*/, 2/*daload*/, 2/*aaload*/, 2/*baload*/, 2/*caload*/, 2/*saload*/,
+    1/*istore*/, 2/*lstore*/, 1/*fstore*/, 2/*dstore*/, 1/*astore*/, 1/*istore_0*/,
+    1/*istore_1*/, 1/*istore_2*/, 1/*istore_3*/, 2/*lstore_0*/, 2/*lstore_1*/,
+    2/*lstore_2*/, 2/*lstore_3*/, 1/*fstore_0*/, 1/*fstore_1*/, 1/*fstore_2*/,
+    1/*fstore_3*/, 2/*dstore_0*/, 2/*dstore_1*/, 2/*dstore_2*/, 2/*dstore_3*/,
+    1/*astore_0*/, 1/*astore_1*/, 1/*astore_2*/, 1/*astore_3*/, 3/*iastore*/, 4/*lastore*/,
+    3/*fastore*/, 4/*dastore*/, 3/*aastore*/, 3/*bastore*/, 3/*castore*/, 3/*sastore*/,
+    1/*pop*/, 2/*pop2*/, 1/*dup*/, 2/*dup_x1*/, 3/*dup_x2*/, 2/*dup2*/, 3/*dup2_x1*/,
+    4/*dup2_x2*/, 2/*swap*/, 2/*iadd*/, 4/*ladd*/, 2/*fadd*/, 4/*dadd*/, 2/*isub*/, 4/*lsub*/,
+    2/*fsub*/, 4/*dsub*/, 2/*imul*/, 4/*lmul*/, 2/*fmul*/, 4/*dmul*/, 2/*idiv*/, 4/*ldiv*/,
+    2/*fdiv*/, 4/*ddiv*/, 2/*irem*/, 4/*lrem*/, 2/*frem*/, 4/*drem*/, 1/*ineg*/, 2/*lneg*/,
+    1/*fneg*/, 2/*dneg*/, 2/*ishl*/, 3/*lshl*/, 2/*ishr*/, 3/*lshr*/, 2/*iushr*/, 3/*lushr*/,
+    2/*iand*/, 4/*land*/, 2/*ior*/, 4/*lor*/, 2/*ixor*/, 4/*lxor*/, 0/*iinc*/,
+    1/*i2l*/, 1/*i2f*/, 1/*i2d*/, 2/*l2i*/, 2/*l2f*/, 2/*l2d*/, 1/*f2i*/, 1/*f2l*/,
+    1/*f2d*/, 2/*d2i*/, 2/*d2l*/, 2/*d2f*/, 1/*i2b*/, 1/*i2c*/, 1/*i2s*/,
+    4/*lcmp*/, 2/*fcmpl*/, 2/*fcmpg*/, 4/*dcmpl*/, 4/*dcmpg*/, 1/*ifeq*/, 1/*ifne*/,
+    1/*iflt*/, 1/*ifge*/, 1/*ifgt*/, 1/*ifle*/, 2/*if_icmpeq*/, 2/*if_icmpne*/, 2/*if_icmplt*/,
+    2 /*if_icmpge*/, 2/*if_icmpgt*/, 2/*if_icmple*/, 2/*if_acmpeq*/, 2/*if_acmpne*/,
+    0/*goto*/, 0/*jsr*/, 0/*ret*/, 1/*tableswitch*/, 1/*lookupswitch*/, 1/*ireturn*/,
+    2/*lreturn*/, 1/*freturn*/, 2/*dreturn*/, 1/*areturn*/, 0/*return*/, 0/*getstatic*/,
+    UNPREDICTABLE/*putstatic*/, 1/*getfield*/, UNPREDICTABLE/*putfield*/,
+    UNPREDICTABLE/*invokevirtual*/, UNPREDICTABLE/*invokespecial*/,
+    UNPREDICTABLE/*invokestatic*/,
+    UNPREDICTABLE/*invokeinterface*/, UNPREDICTABLE/*invokedynamic*/, 0/*new*/, 1/*newarray*/, 1/*anewarray*/,
+    1/*arraylength*/, 1/*athrow*/, 1/*checkcast*/, 1/*instanceof*/, 1/*monitorenter*/,
+    1/*monitorexit*/, 0/*wide*/, UNPREDICTABLE/*multianewarray*/, 1/*ifnull*/, 1/*ifnonnull*/,
+    0/*goto_w*/, 0/*jsr_w*/, 0/*breakpoint*/, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNPREDICTABLE/*impdep1*/, UNPREDICTABLE/*impdep2*/
+  };
 
-    /**
-     * @since 6.0
-     */
-    public static short getOperandType(final int opcode, final int index) {
-        return TYPE_OF_OPERANDS[opcode][index];
-    }
-
-    /**
-     * @since 6.0
-     */
-    public static long getOperandTypeCount(final int opcode) {
-        return TYPE_OF_OPERANDS[opcode].length;
-    }
+  /**
+   *
+   * @param index
+   * @return Number of words consumed on operand stack
+   * @since 6.0
+   */
+  public static int getConsumeStack(final int index) {
+      return CONSUME_STACK[index];
+  }
 
-    /**
-     * Names of opcodes. Indexed by opcode. OPCODE_NAMES[ALOAD] = "aload".
-     */
-    private static final String[] OPCODE_NAMES = {
-        "nop", "aconst_null", "iconst_m1", "iconst_0", "iconst_1",
-        "iconst_2", "iconst_3", "iconst_4", "iconst_5", "lconst_0",
-        "lconst_1", "fconst_0", "fconst_1", "fconst_2", "dconst_0",
-        "dconst_1", "bipush", "sipush", "ldc", "ldc_w", "ldc2_w", "iload",
-        "lload", "fload", "dload", "aload", "iload_0", "iload_1", "iload_2",
-        "iload_3", "lload_0", "lload_1", "lload_2", "lload_3", "fload_0",
-        "fload_1", "fload_2", "fload_3", "dload_0", "dload_1", "dload_2",
-        "dload_3", "aload_0", "aload_1", "aload_2", "aload_3", "iaload",
-        "laload", "faload", "daload", "aaload", "baload", "caload", "saload",
-        "istore", "lstore", "fstore", "dstore", "astore", "istore_0",
-        "istore_1", "istore_2", "istore_3", "lstore_0", "lstore_1",
-        "lstore_2", "lstore_3", "fstore_0", "fstore_1", "fstore_2",
-        "fstore_3", "dstore_0", "dstore_1", "dstore_2", "dstore_3",
-        "astore_0", "astore_1", "astore_2", "astore_3", "iastore", "lastore",
-        "fastore", "dastore", "aastore", "bastore", "castore", "sastore",
-        "pop", "pop2", "dup", "dup_x1", "dup_x2", "dup2", "dup2_x1",
-        "dup2_x2", "swap", "iadd", "ladd", "fadd", "dadd", "isub", "lsub",
-        "fsub", "dsub", "imul", "lmul", "fmul", "dmul", "idiv", "ldiv",
-        "fdiv", "ddiv", "irem", "lrem", "frem", "drem", "ineg", "lneg",
-        "fneg", "dneg", "ishl", "lshl", "ishr", "lshr", "iushr", "lushr",
-        "iand", "land", "ior", "lor", "ixor", "lxor", "iinc", "i2l", "i2f",
-        "i2d", "l2i", "l2f", "l2d", "f2i", "f2l", "f2d", "d2i", "d2l", "d2f",
-        "i2b", "i2c", "i2s", "lcmp", "fcmpl", "fcmpg",
-        "dcmpl", "dcmpg", "ifeq", "ifne", "iflt", "ifge", "ifgt", "ifle",
-        "if_icmpeq", "if_icmpne", "if_icmplt", "if_icmpge", "if_icmpgt",
-        "if_icmple", "if_acmpeq", "if_acmpne", "goto", "jsr", "ret",
-        "tableswitch", "lookupswitch", "ireturn", "lreturn", "freturn",
-        "dreturn", "areturn", "return", "getstatic", "putstatic", "getfield",
-        "putfield", "invokevirtual", "invokespecial", "invokestatic",
-        "invokeinterface", "invokedynamic", "new", "newarray", "anewarray",
-        "arraylength", "athrow", "checkcast", "instanceof", "monitorenter",
-        "monitorexit", "wide", "multianewarray", "ifnull", "ifnonnull",
-        "goto_w", "jsr_w", "breakpoint", ILLEGAL_OPCODE, ILLEGAL_OPCODE,
-        ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
-        ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
-        ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
-        ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
-        ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
-        ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
-        ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
-        ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
-        ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
-        ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
-        ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
-        ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE,
-        ILLEGAL_OPCODE, "impdep1", "impdep2"
-    };
-
-    /**
-     * @since 6.0
-     */
-    public static final int OPCODE_NAMES_LENGTH = OPCODE_NAMES.length;
-
-    /**
-     * @since 6.0
-     */
-    public static String getOpcodeName(final int index) {
-        return OPCODE_NAMES[index];
-    }
 
-    /**
-     * Number of words consumed on operand stack by instructions. Indexed by
-     * opcode. CONSUME_STACK[FALOAD] = number of words consumed from the stack
-     * by a faload instruction.
-     */
-    private static final int[] CONSUME_STACK = {
-        0/*nop*/, 0/*aconst_null*/, 0/*iconst_m1*/, 0/*iconst_0*/, 0/*iconst_1*/,
-        0/*iconst_2*/, 0/*iconst_3*/, 0/*iconst_4*/, 0/*iconst_5*/, 0/*lconst_0*/,
-        0/*lconst_1*/, 0/*fconst_0*/, 0/*fconst_1*/, 0/*fconst_2*/, 0/*dconst_0*/,
-        0/*dconst_1*/, 0/*bipush*/, 0/*sipush*/, 0/*ldc*/, 0/*ldc_w*/, 0/*ldc2_w*/, 0/*iload*/,
-        0/*lload*/, 0/*fload*/, 0/*dload*/, 0/*aload*/, 0/*iload_0*/, 0/*iload_1*/, 0/*iload_2*/,
-        0/*iload_3*/, 0/*lload_0*/, 0/*lload_1*/, 0/*lload_2*/, 0/*lload_3*/, 0/*fload_0*/,
-        0/*fload_1*/, 0/*fload_2*/, 0/*fload_3*/, 0/*dload_0*/, 0/*dload_1*/, 0/*dload_2*/,
-        0/*dload_3*/, 0/*aload_0*/, 0/*aload_1*/, 0/*aload_2*/, 0/*aload_3*/, 2/*iaload*/,
-        2/*laload*/, 2/*faload*/, 2/*daload*/, 2/*aaload*/, 2/*baload*/, 2/*caload*/, 2/*saload*/,
-        1/*istore*/, 2/*lstore*/, 1/*fstore*/, 2/*dstore*/, 1/*astore*/, 1/*istore_0*/,
-        1/*istore_1*/, 1/*istore_2*/, 1/*istore_3*/, 2/*lstore_0*/, 2/*lstore_1*/,
-        2/*lstore_2*/, 2/*lstore_3*/, 1/*fstore_0*/, 1/*fstore_1*/, 1/*fstore_2*/,
-        1/*fstore_3*/, 2/*dstore_0*/, 2/*dstore_1*/, 2/*dstore_2*/, 2/*dstore_3*/,
-        1/*astore_0*/, 1/*astore_1*/, 1/*astore_2*/, 1/*astore_3*/, 3/*iastore*/, 4/*lastore*/,
-        3/*fastore*/, 4/*dastore*/, 3/*aastore*/, 3/*bastore*/, 3/*castore*/, 3/*sastore*/,
-        1/*pop*/, 2/*pop2*/, 1/*dup*/, 2/*dup_x1*/, 3/*dup_x2*/, 2/*dup2*/, 3/*dup2_x1*/,
-        4/*dup2_x2*/, 2/*swap*/, 2/*iadd*/, 4/*ladd*/, 2/*fadd*/, 4/*dadd*/, 2/*isub*/, 4/*lsub*/,
-        2/*fsub*/, 4/*dsub*/, 2/*imul*/, 4/*lmul*/, 2/*fmul*/, 4/*dmul*/, 2/*idiv*/, 4/*ldiv*/,
-        2/*fdiv*/, 4/*ddiv*/, 2/*irem*/, 4/*lrem*/, 2/*frem*/, 4/*drem*/, 1/*ineg*/, 2/*lneg*/,
-        1/*fneg*/, 2/*dneg*/, 2/*ishl*/, 3/*lshl*/, 2/*ishr*/, 3/*lshr*/, 2/*iushr*/, 3/*lushr*/,
-        2/*iand*/, 4/*land*/, 2/*ior*/, 4/*lor*/, 2/*ixor*/, 4/*lxor*/, 0/*iinc*/,
-        1/*i2l*/, 1/*i2f*/, 1/*i2d*/, 2/*l2i*/, 2/*l2f*/, 2/*l2d*/, 1/*f2i*/, 1/*f2l*/,
-        1/*f2d*/, 2/*d2i*/, 2/*d2l*/, 2/*d2f*/, 1/*i2b*/, 1/*i2c*/, 1/*i2s*/,
-        4/*lcmp*/, 2/*fcmpl*/, 2/*fcmpg*/, 4/*dcmpl*/, 4/*dcmpg*/, 1/*ifeq*/, 1/*ifne*/,
-        1/*iflt*/, 1/*ifge*/, 1/*ifgt*/, 1/*ifle*/, 2/*if_icmpeq*/, 2/*if_icmpne*/, 2/*if_icmplt*/,
-        2 /*if_icmpge*/, 2/*if_icmpgt*/, 2/*if_icmple*/, 2/*if_acmpeq*/, 2/*if_acmpne*/,
-        0/*goto*/, 0/*jsr*/, 0/*ret*/, 1/*tableswitch*/, 1/*lookupswitch*/, 1/*ireturn*/,
-        2/*lreturn*/, 1/*freturn*/, 2/*dreturn*/, 1/*areturn*/, 0/*return*/, 0/*getstatic*/,
-        UNPREDICTABLE/*putstatic*/, 1/*getfield*/, UNPREDICTABLE/*putfield*/,
-        UNPREDICTABLE/*invokevirtual*/, UNPREDICTABLE/*invokespecial*/,
-        UNPREDICTABLE/*invokestatic*/,
-        UNPREDICTABLE/*invokeinterface*/, UNPREDICTABLE/*invokedynamic*/, 0/*new*/, 1/*newarray*/, 1/*anewarray*/,
-        1/*arraylength*/, 1/*athrow*/, 1/*checkcast*/, 1/*instanceof*/, 1/*monitorenter*/,
-        1/*monitorexit*/, 0/*wide*/, UNPREDICTABLE/*multianewarray*/, 1/*ifnull*/, 1/*ifnonnull*/,
-        0/*goto_w*/, 0/*jsr_w*/, 0/*breakpoint*/, UNDEFINED, UNDEFINED,
-        UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
-        UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
-        UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
-        UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
-        UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
-        UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
-        UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
-        UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
-        UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
-        UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
-        UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
-        UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
-        UNDEFINED, UNPREDICTABLE/*impdep1*/, UNPREDICTABLE/*impdep2*/};
+  /**
+   * Number of words produced onto operand stack by instructions.
+   * Indexed by opcode.  CONSUME_STACK[DALOAD] = number of words
+   * consumed from the stack by a daload instruction.
+   */
+  private static final int[] PRODUCE_STACK = {
+    0/*nop*/, 1/*aconst_null*/, 1/*iconst_m1*/, 1/*iconst_0*/, 1/*iconst_1*/,
+    1/*iconst_2*/, 1/*iconst_3*/, 1/*iconst_4*/, 1/*iconst_5*/, 2/*lconst_0*/,
+    2/*lconst_1*/, 1/*fconst_0*/, 1/*fconst_1*/, 1/*fconst_2*/, 2/*dconst_0*/,
+    2/*dconst_1*/, 1/*bipush*/, 1/*sipush*/, 1/*ldc*/, 1/*ldc_w*/, 2/*ldc2_w*/, 1/*iload*/,
+    2/*lload*/, 1/*fload*/, 2/*dload*/, 1/*aload*/, 1/*iload_0*/, 1/*iload_1*/, 1/*iload_2*/,
+    1/*iload_3*/, 2/*lload_0*/, 2/*lload_1*/, 2/*lload_2*/, 2/*lload_3*/, 1/*fload_0*/,
+    1/*fload_1*/, 1/*fload_2*/, 1/*fload_3*/, 2/*dload_0*/, 2/*dload_1*/, 2/*dload_2*/,
+    2/*dload_3*/, 1/*aload_0*/, 1/*aload_1*/, 1/*aload_2*/, 1/*aload_3*/, 1/*iaload*/,
+    2/*laload*/, 1/*faload*/, 2/*daload*/, 1/*aaload*/, 1/*baload*/, 1/*caload*/, 1/*saload*/,
+    0/*istore*/, 0/*lstore*/, 0/*fstore*/, 0/*dstore*/, 0/*astore*/, 0/*istore_0*/,
+    0/*istore_1*/, 0/*istore_2*/, 0/*istore_3*/, 0/*lstore_0*/, 0/*lstore_1*/,
+    0/*lstore_2*/, 0/*lstore_3*/, 0/*fstore_0*/, 0/*fstore_1*/, 0/*fstore_2*/,
+    0/*fstore_3*/, 0/*dstore_0*/, 0/*dstore_1*/, 0/*dstore_2*/, 0/*dstore_3*/,
+    0/*astore_0*/, 0/*astore_1*/, 0/*astore_2*/, 0/*astore_3*/, 0/*iastore*/, 0/*lastore*/,
+    0/*fastore*/, 0/*dastore*/, 0/*aastore*/, 0/*bastore*/, 0/*castore*/, 0/*sastore*/,
+    0/*pop*/, 0/*pop2*/, 2/*dup*/, 3/*dup_x1*/, 4/*dup_x2*/, 4/*dup2*/, 5/*dup2_x1*/,
+    6/*dup2_x2*/, 2/*swap*/, 1/*iadd*/, 2/*ladd*/, 1/*fadd*/, 2/*dadd*/, 1/*isub*/, 2/*lsub*/,
+    1/*fsub*/, 2/*dsub*/, 1/*imul*/, 2/*lmul*/, 1/*fmul*/, 2/*dmul*/, 1/*idiv*/, 2/*ldiv*/,
+    1/*fdiv*/, 2/*ddiv*/, 1/*irem*/, 2/*lrem*/, 1/*frem*/, 2/*drem*/, 1/*ineg*/, 2/*lneg*/,
+    1/*fneg*/, 2/*dneg*/, 1/*ishl*/, 2/*lshl*/, 1/*ishr*/, 2/*lshr*/, 1/*iushr*/, 2/*lushr*/,
+    1/*iand*/, 2/*land*/, 1/*ior*/, 2/*lor*/, 1/*ixor*/, 2/*lxor*/,
+    0/*iinc*/, 2/*i2l*/, 1/*i2f*/, 2/*i2d*/, 1/*l2i*/, 1/*l2f*/, 2/*l2d*/, 1/*f2i*/,
+    2/*f2l*/, 2/*f2d*/, 1/*d2i*/, 2/*d2l*/, 1/*d2f*/,
+    1/*i2b*/, 1/*i2c*/, 1/*i2s*/, 1/*lcmp*/, 1/*fcmpl*/, 1/*fcmpg*/,
+    1/*dcmpl*/, 1/*dcmpg*/, 0/*ifeq*/, 0/*ifne*/, 0/*iflt*/, 0/*ifge*/, 0/*ifgt*/, 0/*ifle*/,
+    0/*if_icmpeq*/, 0/*if_icmpne*/, 0/*if_icmplt*/, 0/*if_icmpge*/, 0/*if_icmpgt*/,
+    0/*if_icmple*/, 0/*if_acmpeq*/, 0/*if_acmpne*/, 0/*goto*/, 1/*jsr*/, 0/*ret*/,
+    0/*tableswitch*/, 0/*lookupswitch*/, 0/*ireturn*/, 0/*lreturn*/, 0/*freturn*/,
+    0/*dreturn*/, 0/*areturn*/, 0/*return*/, UNPREDICTABLE/*getstatic*/, 0/*putstatic*/,
+    UNPREDICTABLE/*getfield*/, 0/*putfield*/, UNPREDICTABLE/*invokevirtual*/,
+    UNPREDICTABLE/*invokespecial*/, UNPREDICTABLE/*invokestatic*/,
+    UNPREDICTABLE/*invokeinterface*/, UNPREDICTABLE/*invokedynamic*/, 1/*new*/, 1/*newarray*/, 1/*anewarray*/,
+    1/*arraylength*/, 1/*athrow*/, 1/*checkcast*/, 1/*instanceof*/, 0/*monitorenter*/,
+    0/*monitorexit*/, 0/*wide*/, 1/*multianewarray*/, 0/*ifnull*/, 0/*ifnonnull*/,
+    0/*goto_w*/, 1/*jsr_w*/, 0/*breakpoint*/, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
+    UNDEFINED, UNPREDICTABLE/*impdep1*/, UNPREDICTABLE/*impdep2*/
+  };
 
-    /**
-     *
-     * @param index
-     * @return Number of words consumed on operand stack
-     * @since 6.0
-     */
-    public static int getConsumeStack(final int index) {
-        return CONSUME_STACK[index];
-    }
+  /**
+   *
+   * @param index
+   * @return Number of words produced onto operand stack
+   * @since 6.0
+   */
+  public static int getProduceStack(final int index) {
+      return PRODUCE_STACK[index];
+  }
 
-    /**
-     * Number of words produced onto operand stack by instructions. Indexed by
-     * opcode. CONSUME_STACK[DALOAD] = number of words consumed from the stack
-     * by a daload instruction.
-     */
-    private static final int[] PRODUCE_STACK = {
-        0/*nop*/, 1/*aconst_null*/, 1/*iconst_m1*/, 1/*iconst_0*/, 1/*iconst_1*/,
-        1/*iconst_2*/, 1/*iconst_3*/, 1/*iconst_4*/, 1/*iconst_5*/, 2/*lconst_0*/,
-        2/*lconst_1*/, 1/*fconst_0*/, 1/*fconst_1*/, 1/*fconst_2*/, 2/*dconst_0*/,
-        2/*dconst_1*/, 1/*bipush*/, 1/*sipush*/, 1/*ldc*/, 1/*ldc_w*/, 2/*ldc2_w*/, 1/*iload*/,
-        2/*lload*/, 1/*fload*/, 2/*dload*/, 1/*aload*/, 1/*iload_0*/, 1/*iload_1*/, 1/*iload_2*/,
-        1/*iload_3*/, 2/*lload_0*/, 2/*lload_1*/, 2/*lload_2*/, 2/*lload_3*/, 1/*fload_0*/,
-        1/*fload_1*/, 1/*fload_2*/, 1/*fload_3*/, 2/*dload_0*/, 2/*dload_1*/, 2/*dload_2*/,
-        2/*dload_3*/, 1/*aload_0*/, 1/*aload_1*/, 1/*aload_2*/, 1/*aload_3*/, 1/*iaload*/,
-        2/*laload*/, 1/*faload*/, 2/*daload*/, 1/*aaload*/, 1/*baload*/, 1/*caload*/, 1/*saload*/,
-        0/*istore*/, 0/*lstore*/, 0/*fstore*/, 0/*dstore*/, 0/*astore*/, 0/*istore_0*/,
-        0/*istore_1*/, 0/*istore_2*/, 0/*istore_3*/, 0/*lstore_0*/, 0/*lstore_1*/,
-        0/*lstore_2*/, 0/*lstore_3*/, 0/*fstore_0*/, 0/*fstore_1*/, 0/*fstore_2*/,
-        0/*fstore_3*/, 0/*dstore_0*/, 0/*dstore_1*/, 0/*dstore_2*/, 0/*dstore_3*/,
-        0/*astore_0*/, 0/*astore_1*/, 0/*astore_2*/, 0/*astore_3*/, 0/*iastore*/, 0/*lastore*/,
-        0/*fastore*/, 0/*dastore*/, 0/*aastore*/, 0/*bastore*/, 0/*castore*/, 0/*sastore*/,
-        0/*pop*/, 0/*pop2*/, 2/*dup*/, 3/*dup_x1*/, 4/*dup_x2*/, 4/*dup2*/, 5/*dup2_x1*/,
-        6/*dup2_x2*/, 2/*swap*/, 1/*iadd*/, 2/*ladd*/, 1/*fadd*/, 2/*dadd*/, 1/*isub*/, 2/*lsub*/,
-        1/*fsub*/, 2/*dsub*/, 1/*imul*/, 2/*lmul*/, 1/*fmul*/, 2/*dmul*/, 1/*idiv*/, 2/*ldiv*/,
-        1/*fdiv*/, 2/*ddiv*/, 1/*irem*/, 2/*lrem*/, 1/*frem*/, 2/*drem*/, 1/*ineg*/, 2/*lneg*/,
-        1/*fneg*/, 2/*dneg*/, 1/*ishl*/, 2/*lshl*/, 1/*ishr*/, 2/*lshr*/, 1/*iushr*/, 2/*lushr*/,
-        1/*iand*/, 2/*land*/, 1/*ior*/, 2/*lor*/, 1/*ixor*/, 2/*lxor*/,
-        0/*iinc*/, 2/*i2l*/, 1/*i2f*/, 2/*i2d*/, 1/*l2i*/, 1/*l2f*/, 2/*l2d*/, 1/*f2i*/,
-        2/*f2l*/, 2/*f2d*/, 1/*d2i*/, 2/*d2l*/, 1/*d2f*/,
-        1/*i2b*/, 1/*i2c*/, 1/*i2s*/, 1/*lcmp*/, 1/*fcmpl*/, 1/*fcmpg*/,
-        1/*dcmpl*/, 1/*dcmpg*/, 0/*ifeq*/, 0/*ifne*/, 0/*iflt*/, 0/*ifge*/, 0/*ifgt*/, 0/*ifle*/,
-        0/*if_icmpeq*/, 0/*if_icmpne*/, 0/*if_icmplt*/, 0/*if_icmpge*/, 0/*if_icmpgt*/,
-        0/*if_icmple*/, 0/*if_acmpeq*/, 0/*if_acmpne*/, 0/*goto*/, 1/*jsr*/, 0/*ret*/,
-        0/*tableswitch*/, 0/*lookupswitch*/, 0/*ireturn*/, 0/*lreturn*/, 0/*freturn*/,
-        0/*dreturn*/, 0/*areturn*/, 0/*return*/, UNPREDICTABLE/*getstatic*/, 0/*putstatic*/,
-        UNPREDICTABLE/*getfield*/, 0/*putfield*/, UNPREDICTABLE/*invokevirtual*/,
-        UNPREDICTABLE/*invokespecial*/, UNPREDICTABLE/*invokestatic*/,
-        UNPREDICTABLE/*invokeinterface*/, UNPREDICTABLE/*invokedynamic*/, 1/*new*/, 1/*newarray*/, 1/*anewarray*/,
-        1/*arraylength*/, 1/*athrow*/, 1/*checkcast*/, 1/*instanceof*/, 0/*monitorenter*/,
-        0/*monitorexit*/, 0/*wide*/, 1/*multianewarray*/, 0/*ifnull*/, 0/*ifnonnull*/,
-        0/*goto_w*/, 1/*jsr_w*/, 0/*breakpoint*/, UNDEFINED, UNDEFINED,
-        UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
-        UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
-        UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
-        UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
-        UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
-        UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
-        UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
-        UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
-        UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
-        UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
-        UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
-        UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED,
-        UNDEFINED, UNPREDICTABLE/*impdep1*/, UNPREDICTABLE/*impdep2*/};
+  /** Attributes and their corresponding names.
+   */
+  public static final byte ATTR_UNKNOWN                                 = -1;
+  public static final byte ATTR_SOURCE_FILE                             = 0;
+  public static final byte ATTR_CONSTANT_VALUE                          = 1;
+  public static final byte ATTR_CODE                                    = 2;
+  public static final byte ATTR_EXCEPTIONS                              = 3;
+  public static final byte ATTR_LINE_NUMBER_TABLE                       = 4;
+  public static final byte ATTR_LOCAL_VARIABLE_TABLE                    = 5;
+  public static final byte ATTR_INNER_CLASSES                           = 6;
+  public static final byte ATTR_SYNTHETIC                               = 7;
+  public static final byte ATTR_DEPRECATED                              = 8;
+  public static final byte ATTR_PMG                                     = 9;
+  public static final byte ATTR_SIGNATURE                               = 10;
+  public static final byte ATTR_STACK_MAP                               = 11;
+  public static final byte ATTR_RUNTIME_VISIBLE_ANNOTATIONS             = 12;
+  public static final byte ATTR_RUNTIME_INVISIBLE_ANNOTATIONS           = 13;
+  public static final byte ATTR_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS   = 14;
+  public static final byte ATTR_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS = 15;
+  public static final byte ATTR_ANNOTATION_DEFAULT                      = 16;
+  public static final byte ATTR_LOCAL_VARIABLE_TYPE_TABLE               = 17;
+  public static final byte ATTR_ENCLOSING_METHOD                        = 18;
+  public static final byte ATTR_STACK_MAP_TABLE                         = 19;
+  public static final byte ATTR_BOOTSTRAP_METHODS                       = 20;
+  public static final byte ATTR_METHOD_PARAMETERS                       = 21;
 
-    /**
-     *
-     * @param index
-     * @return Number of words produced onto operand stack
-     * @since 6.0
-     */
-    public static int getProduceStack(final int index) {
-        return PRODUCE_STACK[index];
-    }
+  public static final short KNOWN_ATTRIBUTES = 22; // count of attributes
+
+  private static final String[] ATTRIBUTE_NAMES = {
+    "SourceFile", "ConstantValue", "Code", "Exceptions",
+    "LineNumberTable", "LocalVariableTable",
+    "InnerClasses", "Synthetic", "Deprecated",
+    "PMGClass", "Signature", "StackMap",
+    "RuntimeVisibleAnnotations", "RuntimeInvisibleAnnotations",
+    "RuntimeVisibleParameterAnnotations", "RuntimeInvisibleParameterAnnotations",
+    "AnnotationDefault", "LocalVariableTypeTable", "EnclosingMethod", "StackMapTable",
+    "BootstrapMethods", "MethodParameters"
+  };
+
+  /**
+   *
+   * @param index
+   * @return the attribute name
+   * @since 6.0
+   */
+  public static String getAttributeName(final int index) {
+      return ATTRIBUTE_NAMES[index];
+  }
 
-    /**
-     * Attributes and their corresponding names.
-     */
-    public static final byte ATTR_UNKNOWN = -1;
-    public static final byte ATTR_SOURCE_FILE = 0;
-    public static final byte ATTR_CONSTANT_VALUE = 1;
-    public static final byte ATTR_CODE = 2;
-    public static final byte ATTR_EXCEPTIONS = 3;
-    public static final byte ATTR_LINE_NUMBER_TABLE = 4;
-    public static final byte ATTR_LOCAL_VARIABLE_TABLE = 5;
-    public static final byte ATTR_INNER_CLASSES = 6;
-    public static final byte ATTR_SYNTHETIC = 7;
-    public static final byte ATTR_DEPRECATED = 8;
-    public static final byte ATTR_PMG = 9;
-    public static final byte ATTR_SIGNATURE = 10;
-    public static final byte ATTR_STACK_MAP = 11;
-    public static final byte ATTR_RUNTIME_VISIBLE_ANNOTATIONS = 12;
-    public static final byte ATTR_RUNTIME_INVISIBLE_ANNOTATIONS = 13;
-    public static final byte ATTR_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS = 14;
-    public static final byte ATTR_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS = 15;
-    public static final byte ATTR_ANNOTATION_DEFAULT = 16;
-    public static final byte ATTR_LOCAL_VARIABLE_TYPE_TABLE = 17;
-    public static final byte ATTR_ENCLOSING_METHOD = 18;
-    public static final byte ATTR_STACK_MAP_TABLE = 19;
-    public static final byte ATTR_BOOTSTRAP_METHODS = 20;
-    public static final byte ATTR_METHOD_PARAMETERS = 21;
+  /** Constants used in the StackMap attribute.
+   */
+  public static final byte ITEM_Bogus      = 0;
+  public static final byte ITEM_Integer    = 1;
+  public static final byte ITEM_Float      = 2;
+  public static final byte ITEM_Double     = 3;
+  public static final byte ITEM_Long       = 4;
+  public static final byte ITEM_Null       = 5;
+  public static final byte ITEM_InitObject = 6;
+  public static final byte ITEM_Object     = 7;
+  public static final byte ITEM_NewObject  = 8;
 
-    public static final short KNOWN_ATTRIBUTES = 22; // count of attributes
-
-    private static final String[] ATTRIBUTE_NAMES = {
-        "SourceFile", "ConstantValue", "Code", "Exceptions",
-        "LineNumberTable", "LocalVariableTable",
-        "InnerClasses", "Synthetic", "Deprecated",
-        "PMGClass", "Signature", "StackMap",
-        "RuntimeVisibleAnnotations", "RuntimeInvisibleAnnotations",
-        "RuntimeVisibleParameterAnnotations", "RuntimeInvisibleParameterAnnotations",
-        "AnnotationDefault", "LocalVariableTypeTable", "EnclosingMethod", "StackMapTable",
-        "BootstrapMethods", "MethodParameters"
-    };
-
-    /**
-     *
-     * @param index
-     * @return the attribute name
-     * @since 6.0
-     */
-    public static String getAttributeName(final int index) {
-        return ATTRIBUTE_NAMES[index];
-    }
+  private static final String[] ITEM_NAMES = {
+    "Bogus", "Integer", "Float", "Double", "Long",
+    "Null", "InitObject", "Object", "NewObject"
+  };
 
-    /**
-     * Constants used in the StackMap attribute.
-     */
-    public static final byte ITEM_Bogus = 0;
-    public static final byte ITEM_Integer = 1;
-    public static final byte ITEM_Float = 2;
-    public static final byte ITEM_Double = 3;
-    public static final byte ITEM_Long = 4;
-    public static final byte ITEM_Null = 5;
-    public static final byte ITEM_InitObject = 6;
-    public static final byte ITEM_Object = 7;
-    public static final byte ITEM_NewObject = 8;
-
-    private static final String[] ITEM_NAMES = {
-        "Bogus", "Integer", "Float", "Double", "Long",
-        "Null", "InitObject", "Object", "NewObject"
-    };
+  /**
+   *
+   * @param index
+   * @return the item name
+   * @since 6.0
+   */
+  public static String getItemName(final int index) {
+      return ITEM_NAMES[index];
+  }
 
-    /**
-     *
-     * @param index
-     * @return the item name
-     * @since 6.0
-     */
-    public static String getItemName(final int index) {
-        return ITEM_NAMES[index];
-    }
+  /** Constants used to identify StackMapEntry types.
+   *
+   * For those types which can specify a range, the
+   * constant names the lowest value.
+   */
+  public static final int SAME_FRAME = 0;
+  public static final int SAME_LOCALS_1_STACK_ITEM_FRAME = 64;
+  public static final int SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED = 247;
+  public static final int CHOP_FRAME = 248;
+  public static final int SAME_FRAME_EXTENDED = 251;
+  public static final int APPEND_FRAME = 252;
+  public static final int FULL_FRAME = 255;
 
-    /**
-     * Constants used to identify StackMapEntry types.
-     *
-     * For those types which can specify a range, the constant names the lowest
-     * value.
-     */
-    public static final int SAME_FRAME = 0;
-    public static final int SAME_LOCALS_1_STACK_ITEM_FRAME = 64;
-    public static final int SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED = 247;
-    public static final int CHOP_FRAME = 248;
-    public static final int SAME_FRAME_EXTENDED = 251;
-    public static final int APPEND_FRAME = 252;
-    public static final int FULL_FRAME = 255;
+  /** Constants that define the maximum value of
+   * those constants which store ranges. */
 
-    /**
-     * Constants that define the maximum value of those constants which store
-     * ranges.
-     */
-    public static final int SAME_FRAME_MAX = 63;
-    public static final int SAME_LOCALS_1_STACK_ITEM_FRAME_MAX = 127;
-    public static final int CHOP_FRAME_MAX = 250;
-    public static final int APPEND_FRAME_MAX = 254;
+  public static final int SAME_FRAME_MAX = 63;
+  public static final int SAME_LOCALS_1_STACK_ITEM_FRAME_MAX = 127;
+  public static final int CHOP_FRAME_MAX = 250;
+  public static final int APPEND_FRAME_MAX = 254;
+
 
   // Constants defining the behavior of the Method Handles (JVMS 5.4.3.5)
-    public static final byte REF_getField = 1;
-    public static final byte REF_getStatic = 2;
-    public static final byte REF_putField = 3;
-    public static final byte REF_putStatic = 4;
-    public static final byte REF_invokeVirtual = 5;
-    public static final byte REF_invokeStatic = 6;
-    public static final byte REF_invokeSpecial = 7;
-    public static final byte REF_newInvokeSpecial = 8;
-    public static final byte REF_invokeInterface = 9;
+
+  public static final byte REF_getField         = 1;
+  public static final byte REF_getStatic        = 2;
+  public static final byte REF_putField         = 3;
+  public static final byte REF_putStatic        = 4;
+  public static final byte REF_invokeVirtual    = 5;
+  public static final byte REF_invokeStatic     = 6;
+  public static final byte REF_invokeSpecial    = 7;
+  public static final byte REF_newInvokeSpecial = 8;
+  public static final byte REF_invokeInterface  = 9;
 
-    /**
-     * The names of the reference_kinds of a CONSTANT_MethodHandle_info.
-     */
-    private static final String[] METHODHANDLE_NAMES = {
-        "", "getField", "getStatic", "putField", "putStatic", "invokeVirtual",
-        "invokeStatic", "invokeSpecial", "newInvokeSpecial", "invokeInterface"};
+  /**
+   * The names of the reference_kinds of a CONSTANT_MethodHandle_info.
+   */
+  private static final String[] METHODHANDLE_NAMES = {
+      "", "getField", "getStatic", "putField", "putStatic", "invokeVirtual",
+      "invokeStatic", "invokeSpecial", "newInvokeSpecial", "invokeInterface" };
 
-    /**
-     *
-     * @param index
-     * @return the method handle name
-     * @since 6.0
-     */
-    public static String getMethodHandleName(final int index) {
-        return METHODHANDLE_NAMES[index];
-    }
+  /**
+   *
+   * @param index
+   * @return the method handle name
+   * @since 6.0
+   */
+  public static String getMethodHandleName(final int index) {
+      return METHODHANDLE_NAMES[index];
+  }
 
-    private Const() {
-    } // not instantiable
+  private Const() { } // not instantiable
 
 }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/Repository.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/Repository.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -25,59 +25,59 @@
 
 /**
  * The repository maintains informations about class interdependencies, e.g.,
- * whether a class is a sub-class of another. Delegates actual class loading to
- * SyntheticRepository with current class path by default.
+ * whether a class is a sub-class of another. Delegates actual class loading
+ * to SyntheticRepository with current class path by default.
  *
  * @see com.sun.org.apache.bcel.internal.util.Repository
  * @see SyntheticRepository
  *
- * @version $Id: Repository.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
+ * @LastModified: Jun 2019
  */
 public abstract class Repository {
 
     private static com.sun.org.apache.bcel.internal.util.Repository repository
             = SyntheticRepository.getInstance();
 
-    /**
-     * @return currently used repository instance
+
+    /** @return currently used repository instance
      */
     public static com.sun.org.apache.bcel.internal.util.Repository getRepository() {
         return repository;
     }
 
-    /**
-     * Set repository instance to be used for class loading
+
+    /** Set repository instance to be used for class loading
      */
-    public static void setRepository(final com.sun.org.apache.bcel.internal.util.Repository rep) {
+    public static void setRepository( final com.sun.org.apache.bcel.internal.util.Repository rep ) {
         repository = rep;
     }
 
-    /**
-     * Lookup class somewhere found on your CLASSPATH, or whereever the
+
+    /** Lookup class somewhere found on your CLASSPATH, or whereever the
      * repository instance looks for it.
      *
      * @return class object for given fully qualified class name
-     * @throws ClassNotFoundException if the class could not be found or parsed
-     * correctly
+     * @throws ClassNotFoundException if the class could not be found or
+     * parsed correctly
      */
-    public static JavaClass lookupClass(final String class_name)
-            throws ClassNotFoundException {
+    public static JavaClass lookupClass( final String class_name ) throws ClassNotFoundException {
         return repository.loadClass(class_name);
     }
 
+
     /**
      * Try to find class source using the internal repository instance.
-     *
      * @see Class
      * @return JavaClass object for given runtime class
-     * @throws ClassNotFoundException if the class could not be found or parsed
-     * correctly
+     * @throws ClassNotFoundException if the class could not be found or
+     * parsed correctly
      */
-    public static JavaClass lookupClass(final Class<?> clazz)
-            throws ClassNotFoundException {
+    public static JavaClass lookupClass( final Class<?> clazz ) throws ClassNotFoundException {
         return repository.loadClass(clazz);
     }
 
+
     /**
      * Clear the repository.
      */
@@ -85,149 +85,162 @@
         repository.clear();
     }
 
+
     /**
-     * Add clazz to repository if there isn't an equally named class already in
-     * there.
+     * Add clazz to repository if there isn't an equally named class already in there.
      *
      * @return old entry in repository
      */
-    public static JavaClass addClass(final JavaClass clazz) {
+    public static JavaClass addClass( final JavaClass clazz ) {
         final JavaClass old = repository.findClass(clazz.getClassName());
         repository.storeClass(clazz);
         return old;
     }
 
+
     /**
      * Remove class with given (fully qualified) name from repository.
      */
-    public static void removeClass(final String clazz) {
+    public static void removeClass( final String clazz ) {
         repository.removeClass(repository.findClass(clazz));
     }
 
+
     /**
      * Remove given class from repository.
      */
-    public static void removeClass(final JavaClass clazz) {
+    public static void removeClass( final JavaClass clazz ) {
         repository.removeClass(clazz);
     }
 
+
     /**
-     * @return list of super classes of clazz in ascending order, i.e., Object
-     * is always the last element
+     * @return list of super classes of clazz in ascending order, i.e.,
+     * Object is always the last element
      * @throws ClassNotFoundException if any of the superclasses can't be found
      */
-    public static JavaClass[] getSuperClasses(final JavaClass clazz) throws ClassNotFoundException {
+    public static JavaClass[] getSuperClasses( final JavaClass clazz ) throws ClassNotFoundException {
         return clazz.getSuperClasses();
     }
 
+
     /**
-     * @return list of super classes of clazz in ascending order, i.e., Object
-     * is always the last element.
+     * @return list of super classes of clazz in ascending order, i.e.,
+     * Object is always the last element.
      * @throws ClassNotFoundException if the named class or any of its
-     * superclasses can't be found
+     *  superclasses can't be found
      */
-    public static JavaClass[] getSuperClasses(final String class_name) throws ClassNotFoundException {
+    public static JavaClass[] getSuperClasses( final String class_name ) throws ClassNotFoundException {
         final JavaClass jc = lookupClass(class_name);
         return getSuperClasses(jc);
     }
 
+
     /**
-     * @return all interfaces implemented by class and its super classes and the
-     * interfaces that those interfaces extend, and so on. (Some people call
-     * this a transitive hull).
-     * @throws ClassNotFoundException if any of the class's superclasses or
-     * superinterfaces can't be found
+     * @return all interfaces implemented by class and its super
+     * classes and the interfaces that those interfaces extend, and so on.
+     * (Some people call this a transitive hull).
+     * @throws ClassNotFoundException if any of the class's
+     *  superclasses or superinterfaces can't be found
      */
-    public static JavaClass[] getInterfaces(final JavaClass clazz) throws ClassNotFoundException {
+    public static JavaClass[] getInterfaces( final JavaClass clazz ) throws ClassNotFoundException {
         return clazz.getAllInterfaces();
     }
 
+
     /**
-     * @return all interfaces implemented by class and its super classes and the
-     * interfaces that extend those interfaces, and so on
-     * @throws ClassNotFoundException if the named class can't be found, or if
-     * any of its superclasses or superinterfaces can't be found
+     * @return all interfaces implemented by class and its super
+     * classes and the interfaces that extend those interfaces, and so on
+     * @throws ClassNotFoundException if the named class can't be found,
+     *   or if any of its superclasses or superinterfaces can't be found
      */
-    public static JavaClass[] getInterfaces(final String class_name) throws ClassNotFoundException {
+    public static JavaClass[] getInterfaces( final String class_name ) throws ClassNotFoundException {
         return getInterfaces(lookupClass(class_name));
     }
 
+
     /**
      * Equivalent to runtime "instanceof" operator.
-     *
      * @return true, if clazz is an instance of super_class
-     * @throws ClassNotFoundException if any superclasses or superinterfaces of
-     * clazz can't be found
+     * @throws ClassNotFoundException if any superclasses or superinterfaces
+     *   of clazz can't be found
      */
-    public static boolean instanceOf(final JavaClass clazz, final JavaClass super_class)
+    public static boolean instanceOf( final JavaClass clazz, final JavaClass super_class )
             throws ClassNotFoundException {
         return clazz.instanceOf(super_class);
     }
 
+
     /**
      * @return true, if clazz is an instance of super_class
-     * @throws ClassNotFoundException if either clazz or super_class can't be
-     * found
+     * @throws ClassNotFoundException if either clazz or super_class
+     *   can't be found
      */
-    public static boolean instanceOf(final String clazz, final String super_class)
+    public static boolean instanceOf( final String clazz, final String super_class )
             throws ClassNotFoundException {
         return instanceOf(lookupClass(clazz), lookupClass(super_class));
     }
 
+
     /**
      * @return true, if clazz is an instance of super_class
      * @throws ClassNotFoundException if super_class can't be found
      */
-    public static boolean instanceOf(final JavaClass clazz, final String super_class)
+    public static boolean instanceOf( final JavaClass clazz, final String super_class )
             throws ClassNotFoundException {
         return instanceOf(clazz, lookupClass(super_class));
     }
 
+
     /**
      * @return true, if clazz is an instance of super_class
      * @throws ClassNotFoundException if clazz can't be found
      */
-    public static boolean instanceOf(final String clazz, final JavaClass super_class)
+    public static boolean instanceOf( final String clazz, final JavaClass super_class )
             throws ClassNotFoundException {
         return instanceOf(lookupClass(clazz), super_class);
     }
 
+
     /**
      * @return true, if clazz is an implementation of interface inter
-     * @throws ClassNotFoundException if any superclasses or superinterfaces of
-     * clazz can't be found
+     * @throws ClassNotFoundException if any superclasses or superinterfaces
+     *   of clazz can't be found
      */
-    public static boolean implementationOf(final JavaClass clazz, final JavaClass inter)
+    public static boolean implementationOf( final JavaClass clazz, final JavaClass inter )
             throws ClassNotFoundException {
         return clazz.implementationOf(inter);
     }
 
+
     /**
      * @return true, if clazz is an implementation of interface inter
-     * @throws ClassNotFoundException if clazz, inter, or any superclasses or
-     * superinterfaces of clazz can't be found
+     * @throws ClassNotFoundException if clazz, inter, or any superclasses
+     *   or superinterfaces of clazz can't be found
      */
-    public static boolean implementationOf(final String clazz, final String inter)
+    public static boolean implementationOf( final String clazz, final String inter )
             throws ClassNotFoundException {
         return implementationOf(lookupClass(clazz), lookupClass(inter));
     }
 
+
     /**
      * @return true, if clazz is an implementation of interface inter
-     * @throws ClassNotFoundException if inter or any superclasses or
-     * superinterfaces of clazz can't be found
+     * @throws ClassNotFoundException if inter or any superclasses
+     *   or superinterfaces of clazz can't be found
      */
-    public static boolean implementationOf(final JavaClass clazz, final String inter)
+    public static boolean implementationOf( final JavaClass clazz, final String inter )
             throws ClassNotFoundException {
         return implementationOf(clazz, lookupClass(inter));
     }
 
+
     /**
      * @return true, if clazz is an implementation of interface inter
      * @throws ClassNotFoundException if clazz or any superclasses or
-     * superinterfaces of clazz can't be found
+     *   superinterfaces of clazz can't be found
      */
-    public static boolean implementationOf(final String clazz, final JavaClass inter)
+    public static boolean implementationOf( final String clazz, final JavaClass inter )
             throws ClassNotFoundException {
         return implementationOf(lookupClass(clazz), inter);
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AccessFlags.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AccessFlags.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -25,7 +25,8 @@
  * Super class for all objects that have modifiers like private, final, ... I.e.
  * classes, fields, and methods.
  *
- * @version $Id: AccessFlags.java 1748636 2016-06-15 20:45:17Z dbrosius $
+ * @version $Id$
+ * @LastModified: Jun 2019
  */
 public abstract class AccessFlags {
 
@@ -35,7 +36,8 @@
     }
 
     /**
-     * @param a inital access flags
+     * @param a
+     *            inital access flags
      */
     public AccessFlags(final int a) {
         access_flags = a;
@@ -58,7 +60,8 @@
     /**
      * Set access flags aka "modifiers".
      *
-     * @param access_flags Access flags of the object.
+     * @param access_flags
+     *            Access flags of the object.
      */
     public final void setAccessFlags(final int access_flags) {
         this.access_flags = access_flags;
@@ -67,7 +70,8 @@
     /**
      * Set access flags aka "modifiers".
      *
-     * @param access_flags Access flags of the object.
+     * @param access_flags
+     *            Access flags of the object.
      */
     public final void setModifiers(final int access_flags) {
         setAccessFlags(access_flags);
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Attribute.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Attribute.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -36,7 +36,7 @@
  * <em>Synthetic</em> attributes are supported. The <em>Unknown</em>
  * attribute stands for non-standard-attributes.
  *
- * @version $Id: Attribute.java 1750029 2016-06-23 22:14:38Z sebb $
+ * @version $Id$
  * @see ConstantValue
  * @see SourceFile
  * @see Code
@@ -48,6 +48,7 @@
  * @see Synthetic
  * @see Deprecated
  * @see Signature
+ * @LastModified: Jun 2019
  */
 public abstract class Attribute implements Cloneable, Node {
 
@@ -79,7 +80,8 @@
      * @param file Output file stream
      * @throws IOException
      */
-    public void dump(final DataOutputStream file) throws IOException {
+    public void dump(final DataOutputStream file) throws IOException
+    {
         file.writeShort(name_index);
         file.writeInt(length);
     }
@@ -92,9 +94,10 @@
      * as "LineNumberTable", because those are handled internally.
      *
      * @param name the name of the attribute as stored in the class file
-     * @param r the reader object
+     * @param r    the reader object
      */
-    public static void addAttributeReader(final String name, final UnknownAttributeReader r) {
+    public static void addAttributeReader(final String name, final UnknownAttributeReader r)
+    {
         readers.put(name, r);
     }
 
@@ -103,7 +106,8 @@
      *
      * @param name the name of the attribute as stored in the class file
      */
-    public static void removeAttributeReader(final String name) {
+    public static void removeAttributeReader(final String name)
+    {
         readers.remove(name);
     }
 
@@ -122,7 +126,8 @@
      * @throws ClassFormatException
      */
     public static Attribute readAttribute(final DataInputStream file, final ConstantPool constant_pool)
-            throws IOException, ClassFormatException {
+            throws IOException, ClassFormatException
+    {
         return readAttribute((DataInput) file, constant_pool);
     }
 
@@ -142,7 +147,8 @@
      * @since 6.0
      */
     public static Attribute readAttribute(final DataInput file, final ConstantPool constant_pool)
-            throws IOException, ClassFormatException {
+            throws IOException, ClassFormatException
+    {
         byte tag = Const.ATTR_UNKNOWN; // Unknown attribute
         // Get class name from constant pool via `name_index' indirection
         final int name_index = file.readUnsignedShort();
@@ -153,18 +159,22 @@
         final int length = file.readInt();
 
         // Compare strings to find known attribute
-        for (byte i = 0; i < Const.KNOWN_ATTRIBUTES; i++) {
-            if (name.equals(Const.getAttributeName(i))) {
+        for (byte i = 0; i < Const.KNOWN_ATTRIBUTES; i++)
+        {
+            if (name.equals(Const.getAttributeName(i)))
+            {
                 tag = i; // found!
                 break;
             }
         }
 
         // Call proper constructor, depending on `tag'
-        switch (tag) {
+        switch (tag)
+        {
             case Const.ATTR_UNKNOWN:
                 final Object r = readers.get(name);
-                if (r instanceof UnknownAttributeReader) {
+                if (r instanceof UnknownAttributeReader)
+                {
                     return ((UnknownAttributeReader) r).createAttribute(name_index, length, file, constant_pool);
                 }
                 return new Unknown(name_index, length, file, constant_pool);
@@ -191,7 +201,10 @@
             case Const.ATTR_SIGNATURE:
                 return new Signature(name_index, length, file, constant_pool);
             case Const.ATTR_STACK_MAP:
-                return new StackMap(name_index, length, file, constant_pool);
+                // old style stack map: unneeded for JDK5 and below;
+                // illegal(?) for JDK6 and above.  So just delete with a warning.
+                System.err.println("Warning: Obsolete StackMap attribute ignored.");
+                return new Unknown(name_index, length, file, constant_pool);
             case Const.ATTR_RUNTIME_VISIBLE_ANNOTATIONS:
                 return new RuntimeVisibleAnnotations(name_index, length, file, constant_pool);
             case Const.ATTR_RUNTIME_INVISIBLE_ANNOTATIONS:
@@ -207,6 +220,8 @@
             case Const.ATTR_ENCLOSING_METHOD:
                 return new EnclosingMethod(name_index, length, file, constant_pool);
             case Const.ATTR_STACK_MAP_TABLE:
+                // read new style stack map: StackMapTable.  The rest of the code
+                // calls this a StackMap for historical reasons.
                 return new StackMap(name_index, length, file, constant_pool);
             case Const.ATTR_BOOTSTRAP_METHODS:
                 return new BootstrapMethods(name_index, length, file, constant_pool);
@@ -222,7 +237,8 @@
      * @return Name of attribute
      * @since 6.0
      */
-    public String getName() {
+    public String getName()
+    {
         final ConstantUtf8 c = (ConstantUtf8) constant_pool.getConstant(name_index, Const.CONSTANT_Utf8);
         return c.getBytes();
     }
@@ -230,36 +246,40 @@
     /**
      * @return Length of attribute field in bytes.
      */
-    public final int getLength() {
+    public final int getLength()
+    {
         return length;
     }
 
     /**
      * @param length length in bytes.
      */
-    public final void setLength(final int length) {
+    public final void setLength(final int length)
+    {
         this.length = length;
     }
 
     /**
      * @param name_index of attribute.
      */
-    public final void setNameIndex(final int name_index) {
+    public final void setNameIndex(final int name_index)
+    {
         this.name_index = name_index;
     }
 
     /**
      * @return Name index in constant pool of attribute name.
      */
-    public final int getNameIndex() {
+    public final int getNameIndex()
+    {
         return name_index;
     }
 
     /**
-     * @return Tag of attribute, i.e., its type. Value may not be altered, thus
-     * there is no setTag() method.
+     * @return Tag of attribute, i.e., its type. Value may not be altered, thus there is no setTag() method.
      */
-    public final byte getTag() {
+    public final byte getTag()
+    {
         return tag;
     }
 
@@ -267,7 +287,8 @@
      * @return Constant pool used by this object.
      * @see ConstantPool
      */
-    public final ConstantPool getConstantPool() {
+    public final ConstantPool getConstantPool()
+    {
         return constant_pool;
     }
 
@@ -275,7 +296,8 @@
      * @param constant_pool Constant pool to be used for this object.
      * @see ConstantPool
      */
-    public final void setConstantPool(final ConstantPool constant_pool) {
+    public final void setConstantPool(final ConstantPool constant_pool)
+    {
         this.constant_pool = constant_pool;
     }
 
@@ -286,11 +308,15 @@
      * @return shallow copy of this attribute
      */
     @Override
-    public Object clone() {
+    public Object clone()
+    {
         Attribute attr = null;
-        try {
+        try
+        {
             attr = (Attribute) super.clone();
-        } catch (final CloneNotSupportedException e) {
+        }
+        catch (final CloneNotSupportedException e)
+        {
             throw new Error("Clone Not Supported"); // never happens
         }
         return attr;
@@ -305,7 +331,8 @@
      * @return attribute name.
      */
     @Override
-    public String toString() {
+    public String toString()
+    {
         return Const.getAttributeName(tag);
     }
 }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AttributeReader.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AttributeReader.java	Mon Jul 01 14:57:02 2019 -0700
@@ -27,7 +27,7 @@
  * method. These factory objects should implement this interface.
 
  * @see Attribute
- * @version $Id: AttributeReader.java 1748467 2016-06-14 21:05:14Z ggregory $
+ * @version $Id$
  *
  * @deprecated Use UnknownAttributeReader instead
  */
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ClassFormatException.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ClassFormatException.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,7 +26,7 @@
  * that the file is malformed or otherwise cannot be interpreted as a
  * class file.
  *
- * @version $Id: ClassFormatException.java 1748973 2016-06-18 12:14:42Z sebb $
+ * @version $Id$
  */
 public class ClassFormatException extends RuntimeException {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ClassParser.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ClassParser.java	Mon Jul 01 14:57:02 2019 -0700
@@ -43,7 +43,7 @@
  * JVM specification 1.0</a>. See this paper for
  * further details about the structure of a bytecode file.
  *
- * @version $Id: ClassParser.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
  */
 public final class ClassParser {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Code.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Code.java	Mon Jul 01 14:57:02 2019 -0700
@@ -39,7 +39,7 @@
  * is used for debugging purposes and <em>LocalVariableTable</em> which
  * contains information about the local variables.
  *
- * @version $Id: Code.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
  * @see     Attribute
  * @see     CodeException
  * @see     LineNumberTable
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/CodeException.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/CodeException.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -31,8 +31,9 @@
  * attribute and is used only there. It contains a range in which a
  * particular exception handler is active.
  *
- * @version $Id: CodeException.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
  * @see     Code
+ * @LastModified: Jun 2019
  */
 public final class CodeException implements Cloneable, Node {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Constant.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Constant.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -22,30 +22,33 @@
 import java.io.DataInput;
 import java.io.DataOutputStream;
 import java.io.IOException;
+import java.util.Objects;
 
 import com.sun.org.apache.bcel.internal.Const;
 import com.sun.org.apache.bcel.internal.util.BCELComparator;
 
 /**
- * Abstract superclass for classes to represent the different constant types in
- * the constant pool of a class file. The classes keep closely to the JVM
- * specification.
+ * Abstract superclass for classes to represent the different constant types
+ * in the constant pool of a class file. The classes keep closely to
+ * the JVM specification.
  *
- * @version $Id: Constant.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
+ * @LastModified: Jun 2019
  */
 public abstract class Constant implements Cloneable, Node {
 
     private static BCELComparator bcelComparator = new BCELComparator() {
 
         @Override
-        public boolean equals(final Object o1, final Object o2) {
+        public boolean equals( final Object o1, final Object o2 ) {
             final Constant THIS = (Constant) o1;
             final Constant THAT = (Constant) o2;
-            return THIS.toString().equals(THAT.toString());
+            return Objects.equals(THIS.toString(), THAT.toString());
         }
 
+
         @Override
-        public int hashCode(final Object o) {
+        public int hashCode( final Object o ) {
             final Constant THIS = (Constant) o;
             return THIS.toString().hashCode();
         }
@@ -61,10 +64,12 @@
      */
     private byte tag;
 
+
     Constant(final byte tag) {
         this.tag = tag;
     }
 
+
     /**
      * Called by objects that are traversing the nodes of the tree implicitely
      * defined by the contents of a Java class. I.e., the hierarchy of methods,
@@ -73,9 +78,11 @@
      * @param v Visitor object
      */
     @Override
-    public abstract void accept(Visitor v);
+    public abstract void accept( Visitor v );
+
 
-    public abstract void dump(DataOutputStream file) throws IOException;
+    public abstract void dump( DataOutputStream file ) throws IOException;
+
 
     /**
      * @return Tag of constant, i.e., its type. No setTag() method to avoid
@@ -85,6 +92,7 @@
         return tag;
     }
 
+
     /**
      * @return String representation.
      */
@@ -93,6 +101,7 @@
         return Const.getConstantName(tag) + "[" + tag + "]";
     }
 
+
     /**
      * @return deep copy of this constant
      */
@@ -105,6 +114,7 @@
         return null;
     }
 
+
     @Override
     public Object clone() {
         try {
@@ -114,47 +124,55 @@
         }
     }
 
+
     /**
      * Read one constant from the given input, the type depends on a tag byte.
      *
-     * @param input Input stream
+     * @param dataInput Input stream
      * @return Constant object
+     * @throws IOException if an I/O error occurs reading from the given {@code dataInput}.
+     * @throws ClassFormatException if the next byte is not recognized
      * @since 6.0 made public
      */
-    public static Constant readConstant(final DataInput input) throws IOException,
-            ClassFormatException {
-        final byte b = input.readByte(); // Read tag byte
+    public static Constant readConstant(final DataInput dataInput) throws IOException, ClassFormatException {
+        final byte b = dataInput.readByte(); // Read tag byte
         switch (b) {
-            case Const.CONSTANT_Class:
-                return new ConstantClass(input);
-            case Const.CONSTANT_Fieldref:
-                return new ConstantFieldref(input);
-            case Const.CONSTANT_Methodref:
-                return new ConstantMethodref(input);
-            case Const.CONSTANT_InterfaceMethodref:
-                return new ConstantInterfaceMethodref(input);
-            case Const.CONSTANT_String:
-                return new ConstantString(input);
-            case Const.CONSTANT_Integer:
-                return new ConstantInteger(input);
-            case Const.CONSTANT_Float:
-                return new ConstantFloat(input);
-            case Const.CONSTANT_Long:
-                return new ConstantLong(input);
-            case Const.CONSTANT_Double:
-                return new ConstantDouble(input);
-            case Const.CONSTANT_NameAndType:
-                return new ConstantNameAndType(input);
-            case Const.CONSTANT_Utf8:
-                return ConstantUtf8.getInstance(input);
-            case Const.CONSTANT_MethodHandle:
-                return new ConstantMethodHandle(input);
-            case Const.CONSTANT_MethodType:
-                return new ConstantMethodType(input);
-            case Const.CONSTANT_InvokeDynamic:
-                return new ConstantInvokeDynamic(input);
-            default:
-                throw new ClassFormatException("Invalid byte tag in constant pool: " + b);
+        case Const.CONSTANT_Class:
+            return new ConstantClass(dataInput);
+        case Const.CONSTANT_Fieldref:
+            return new ConstantFieldref(dataInput);
+        case Const.CONSTANT_Methodref:
+            return new ConstantMethodref(dataInput);
+        case Const.CONSTANT_InterfaceMethodref:
+            return new ConstantInterfaceMethodref(dataInput);
+        case Const.CONSTANT_String:
+            return new ConstantString(dataInput);
+        case Const.CONSTANT_Integer:
+            return new ConstantInteger(dataInput);
+        case Const.CONSTANT_Float:
+            return new ConstantFloat(dataInput);
+        case Const.CONSTANT_Long:
+            return new ConstantLong(dataInput);
+        case Const.CONSTANT_Double:
+            return new ConstantDouble(dataInput);
+        case Const.CONSTANT_NameAndType:
+            return new ConstantNameAndType(dataInput);
+        case Const.CONSTANT_Utf8:
+            return ConstantUtf8.getInstance(dataInput);
+        case Const.CONSTANT_MethodHandle:
+            return new ConstantMethodHandle(dataInput);
+        case Const.CONSTANT_MethodType:
+            return new ConstantMethodType(dataInput);
+        case Const.CONSTANT_Dynamic:
+            return new ConstantDynamic(dataInput);
+        case Const.CONSTANT_InvokeDynamic:
+            return new ConstantInvokeDynamic(dataInput);
+        case Const.CONSTANT_Module:
+            return new ConstantModule(dataInput);
+        case Const.CONSTANT_Package:
+            return new ConstantPackage(dataInput);
+        default:
+            throw new ClassFormatException("Invalid byte tag in constant pool: " + b);
         }
     }
 
@@ -165,28 +183,31 @@
         return bcelComparator;
     }
 
+
     /**
      * @param comparator Comparison strategy object
      */
-    public static void setComparator(final BCELComparator comparator) {
+    public static void setComparator( final BCELComparator comparator ) {
         bcelComparator = comparator;
     }
 
+
     /**
-     * Return value as defined by given BCELComparator strategy. By default two
-     * Constant objects are said to be equal when the result of toString() is
-     * equal.
+     * Return value as defined by given BCELComparator strategy.
+     * By default two Constant objects are said to be equal when
+     * the result of toString() is equal.
      *
      * @see java.lang.Object#equals(java.lang.Object)
      */
     @Override
-    public boolean equals(final Object obj) {
+    public boolean equals( final Object obj ) {
         return bcelComparator.equals(this, obj);
     }
 
+
     /**
-     * Return value as defined by given BCELComparator strategy. By default
-     * return the hashcode of the result of toString().
+     * Return value as defined by given BCELComparator strategy.
+     * By default return the hashcode of the result of toString().
      *
      * @see java.lang.Object#hashCode()
      */
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantCP.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantCP.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -27,13 +27,14 @@
 
 /**
  * Abstract super class for Fieldref, Methodref, InterfaceMethodref and
- * InvokeDynamic constants.
+ *                          InvokeDynamic constants.
  *
- * @version $Id: ConstantCP.java 1747278 2016-06-07 17:28:43Z britter $
- * @see ConstantFieldref
- * @see ConstantMethodref
- * @see ConstantInterfaceMethodref
- * @see ConstantInvokeDynamic
+ * @version $Id$
+ * @see     ConstantFieldref
+ * @see     ConstantMethodref
+ * @see     ConstantInterfaceMethodref
+ * @see     ConstantInvokeDynamic
+ * @LastModified: Jun 2019
  */
 public abstract class ConstantCP extends Constant {
 
@@ -53,10 +54,11 @@
         this(c.getTag(), c.getClassIndex(), c.getNameAndTypeIndex());
     }
 
+
     /**
      * Initialize instance from file data.
      *
-     * @param tag Constant type tag
+     * @param tag  Constant type tag
      * @param file Input stream
      * @throws IOException
      */
@@ -64,6 +66,7 @@
         this(tag, file.readUnsignedShort(), file.readUnsignedShort());
     }
 
+
     /**
      * @param class_index Reference to the class containing the field
      * @param name_and_type_index and the field signature
@@ -74,6 +77,7 @@
         this.name_and_type_index = name_and_type_index;
     }
 
+
     /**
      * Dump constant field reference to file stream in binary format.
      *
@@ -81,12 +85,13 @@
      * @throws IOException
      */
     @Override
-    public final void dump(final DataOutputStream file) throws IOException {
+    public final void dump( final DataOutputStream file ) throws IOException {
         file.writeByte(super.getTag());
         file.writeShort(class_index);
         file.writeShort(name_and_type_index);
     }
 
+
     /**
      * @return Reference (index) to class this constant refers to.
      */
@@ -94,13 +99,15 @@
         return class_index;
     }
 
+
     /**
      * @param class_index points to Constant_class
      */
-    public final void setClassIndex(final int class_index) {
+    public final void setClassIndex( final int class_index ) {
         this.class_index = class_index;
     }
 
+
     /**
      * @return Reference (index) to signature of the field.
      */
@@ -108,20 +115,23 @@
         return name_and_type_index;
     }
 
+
     /**
      * @param name_and_type_index points to Constant_NameAndType
      */
-    public final void setNameAndTypeIndex(final int name_and_type_index) {
+    public final void setNameAndTypeIndex( final int name_and_type_index ) {
         this.name_and_type_index = name_and_type_index;
     }
 
+
     /**
      * @return Class this field belongs to.
      */
-    public String getClass(final ConstantPool cp) {
+    public String getClass( final ConstantPool cp ) {
         return cp.constantToString(class_index, Const.CONSTANT_Class);
     }
 
+
     /**
      * @return String representation.
      *
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantClass.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantClass.java	Mon Jul 01 14:57:02 2019 -0700
@@ -31,7 +31,6 @@
  * This class is derived from the abstract {@link Constant}
  * and represents a reference to a (external) class.
  *
- * @version $Id: ConstantClass.java 1749603 2016-06-21 20:50:19Z ggregory $
  * @see     Constant
  */
 public final class ConstantClass extends Constant implements ConstantObject {
@@ -48,13 +47,13 @@
 
 
     /**
-     * Initialize instance from file data.
+     * Constructs an instance from file data.
      *
-     * @param file Input stream
-     * @throws IOException
+     * @param dataInput Input stream
+     * @throws IOException if an I/O error occurs reading from the given {@code dataInput}.
      */
-    ConstantClass(final DataInput file) throws IOException {
-        this(file.readUnsignedShort());
+    ConstantClass(final DataInput dataInput) throws IOException {
+        this(dataInput.readUnsignedShort());
     }
 
 
@@ -82,10 +81,10 @@
 
 
     /**
-     * Dump constant class to file stream in binary format.
+     * Dumps constant class to file stream in binary format.
      *
      * @param file Output file stream
-     * @throws IOException
+     * @throws IOException if an I/O error occurs writing to the DataOutputStream.
      */
     @Override
     public final void dump( final DataOutputStream file ) throws IOException {
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantDouble.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantDouble.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -30,9 +30,9 @@
  * This class is derived from the abstract  {@link Constant}
  * and represents a reference to a Double object.
  *
- * @version $Id: ConstantDouble.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  * @see     Constant
- * @LastModified: Nov 2017
+ * @LastModified: Jun 2019
  */
 public final class ConstantDouble extends Constant implements ConstantObject {
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantDynamic.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,94 @@
+/*
+ * reserved comment block
+ * DO NOT REMOVE OR ALTER!
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+package com.sun.org.apache.bcel.internal.classfile;
+
+import java.io.DataInput;
+import java.io.IOException;
+
+import com.sun.org.apache.bcel.internal.Const;
+
+/**
+ * This class is derived from the abstract {@link Constant}
+ * and represents a reference to a dynamically computed constant.
+ *
+ * @see     Constant
+ * @see  <a href="https://bugs.openjdk.java.net/secure/attachment/74618/constant-dynamic.html">
+ * Change request for JEP 309</a>
+ * @since 6.3
+ */
+public final class ConstantDynamic extends ConstantCP {
+
+    /**
+     * Initialize from another object.
+     */
+    public ConstantDynamic(final ConstantDynamic c) {
+        this(c.getBootstrapMethodAttrIndex(), c.getNameAndTypeIndex());
+    }
+
+
+    /**
+     * Initialize instance from file data.
+     *
+     * @param file Input stream
+     * @throws IOException
+     */
+    ConstantDynamic(final DataInput file) throws IOException {
+        this(file.readShort(), file.readShort());
+    }
+
+
+    public ConstantDynamic(final int bootstrap_method_attr_index, final int name_and_type_index) {
+        super(Const.CONSTANT_Dynamic, bootstrap_method_attr_index, name_and_type_index);
+    }
+
+
+    /**
+     * Called by objects that are traversing the nodes of the tree implicitly
+     * defined by the contents of a Java class. I.e., the hierarchy of methods,
+     * fields, attributes, etc. spawns a tree of objects.
+     *
+     * @param v Visitor object
+     */
+    @Override
+    public void accept( final Visitor v ) {
+        v.visitConstantDynamic(this);
+    }
+
+    /**
+     * @return Reference (index) to bootstrap method this constant refers to.
+     *
+     * Note that this method is a functional duplicate of getClassIndex
+     * for use by ConstantInvokeDynamic.
+     * @since 6.0
+     */
+    public final int getBootstrapMethodAttrIndex() {
+        return super.getClassIndex();  // AKA bootstrap_method_attr_index
+    }
+
+    /**
+     * @return String representation
+     */
+    @Override
+    public final String toString() {
+        return super.toString().replace("class_index", "bootstrap_method_attr_index");
+    }
+}
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantFieldref.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantFieldref.java	Mon Jul 01 14:57:02 2019 -0700
@@ -29,7 +29,7 @@
 /**
  * This class represents a constant pool reference to a field.
  *
- * @version $Id: ConstantFieldref.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public final class ConstantFieldref extends ConstantCP {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantFloat.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantFloat.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -30,9 +30,9 @@
  * This class is derived from the abstract {@link Constant}
  * and represents a reference to a float object.
  *
- * @version $Id: ConstantFloat.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  * @see     Constant
- * @LastModified: Nov 2017
+ * @LastModified: Jun 2019
  */
 public final class ConstantFloat extends Constant implements ConstantObject {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantInteger.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantInteger.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -30,8 +30,9 @@
  * This class is derived from the abstract {@link Constant}
  * and represents a reference to an int object.
  *
- * @version $Id: ConstantInteger.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  * @see     Constant
+ * @LastModified: Jun 2019
  */
 public final class ConstantInteger extends Constant implements ConstantObject {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantInterfaceMethodref.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantInterfaceMethodref.java	Mon Jul 01 14:57:02 2019 -0700
@@ -29,7 +29,7 @@
 /**
  * This class represents a constant pool reference to an interface method.
  *
- * @version $Id: ConstantInterfaceMethodref.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public final class ConstantInterfaceMethodref extends ConstantCP {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantLong.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantLong.java	Mon Jul 01 14:57:02 2019 -0700
@@ -30,7 +30,7 @@
  * This class is derived from the abstract {@link Constant}
  * and represents a reference to a long object.
  *
- * @version $Id: ConstantLong.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  * @see     Constant
  */
 public final class ConstantLong extends Constant implements ConstantObject {
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantMethodref.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantMethodref.java	Mon Jul 01 14:57:02 2019 -0700
@@ -29,7 +29,7 @@
 /**
  * This class represents a constant pool reference to a method.
  *
- * @version $Id: ConstantMethodref.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public final class ConstantMethodref extends ConstantCP {
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantModule.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,138 @@
+/*
+ * reserved comment block
+ * DO NOT REMOVE OR ALTER!
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+package com.sun.org.apache.bcel.internal.classfile;
+
+import java.io.DataInput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import com.sun.org.apache.bcel.internal.Const;
+
+/**
+ * This class is derived from the abstract {@link Constant}
+ * and represents a reference to a module.
+ *
+ * <p>Note: Early access Java 9 support- currently subject to change</p>
+ *
+ * @see     Constant
+ * @since 6.1
+ */
+public final class ConstantModule extends Constant implements ConstantObject {
+
+    private int name_index;
+
+
+    /**
+     * Initialize from another object.
+     */
+    public ConstantModule(final ConstantModule c) {
+        this(c.getNameIndex());
+    }
+
+
+    /**
+     * Initialize instance from file data.
+     *
+     * @param file Input stream
+     * @throws IOException
+     */
+    ConstantModule(final DataInput file) throws IOException {
+        this(file.readUnsignedShort());
+    }
+
+
+    /**
+     * @param name_index Name index in constant pool.  Should refer to a
+     * ConstantUtf8.
+     */
+    public ConstantModule(final int name_index) {
+        super(Const.CONSTANT_Module);
+        this.name_index = name_index;
+    }
+
+
+    /**
+     * Called by objects that are traversing the nodes of the tree implicitly
+     * defined by the contents of a Java class. I.e., the hierarchy of methods,
+     * fields, attributes, etc. spawns a tree of objects.
+     *
+     * @param v Visitor object
+     */
+    @Override
+    public void accept( final Visitor v ) {
+        v.visitConstantModule(this);
+    }
+
+
+    /**
+     * Dump constant module to file stream in binary format.
+     *
+     * @param file Output file stream
+     * @throws IOException
+     */
+    @Override
+    public final void dump( final DataOutputStream file ) throws IOException {
+        file.writeByte(super.getTag());
+        file.writeShort(name_index);
+    }
+
+
+    /**
+     * @return Name index in constant pool of module name.
+     */
+    public final int getNameIndex() {
+        return name_index;
+    }
+
+
+    /**
+     * @param name_index the name index in the constant pool of this Constant Module
+     */
+    public final void setNameIndex( final int name_index ) {
+        this.name_index = name_index;
+    }
+
+
+    /** @return String object
+     */
+    @Override
+    public Object getConstantValue( final ConstantPool cp ) {
+        final Constant c = cp.getConstant(name_index, Const.CONSTANT_Utf8);
+        return ((ConstantUtf8) c).getBytes();
+    }
+
+
+    /** @return dereferenced string
+     */
+    public String getBytes( final ConstantPool cp ) {
+        return (String) getConstantValue(cp);
+    }
+
+
+    /**
+     * @return String representation.
+     */
+    @Override
+    public final String toString() {
+        return super.toString() + "(name_index = " + name_index + ")";
+    }
+}
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantNameAndType.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantNameAndType.java	Mon Jul 01 14:57:02 2019 -0700
@@ -32,7 +32,7 @@
  * and represents a reference to the name and signature
  * of a field or method.
  *
- * @version $Id: ConstantNameAndType.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  * @see     Constant
  */
 public final class ConstantNameAndType extends Constant {
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantObject.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantObject.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * This interface denotes those constants that have a "natural" value,
  * such as ConstantLong, ConstantString, etc..
  *
- * @version $Id: ConstantObject.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  * @see     Constant
  */
 public interface ConstantObject {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantPackage.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,138 @@
+/*
+ * reserved comment block
+ * DO NOT REMOVE OR ALTER!
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+package com.sun.org.apache.bcel.internal.classfile;
+
+import java.io.DataInput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import com.sun.org.apache.bcel.internal.Const;
+
+/**
+ * This class is derived from the abstract {@link Constant}
+ * and represents a reference to a package.
+ *
+ * <p>Note: Early access Java 9 support- currently subject to change</p>
+ *
+ * @see     Constant
+ * @since 6.1
+ */
+public final class ConstantPackage extends Constant implements ConstantObject {
+
+    private int name_index;
+
+
+    /**
+     * Initialize from another object.
+     */
+    public ConstantPackage(final ConstantPackage c) {
+        this(c.getNameIndex());
+    }
+
+
+    /**
+     * Initialize instance from file data.
+     *
+     * @param file Input stream
+     * @throws IOException
+     */
+    ConstantPackage(final DataInput file) throws IOException {
+        this(file.readUnsignedShort());
+    }
+
+
+    /**
+     * @param name_index Name index in constant pool.  Should refer to a
+     * ConstantUtf8.
+     */
+    public ConstantPackage(final int name_index) {
+        super(Const.CONSTANT_Package);
+        this.name_index = name_index;
+    }
+
+
+    /**
+     * Called by objects that are traversing the nodes of the tree implicitely
+     * defined by the contents of a Java class. I.e., the hierarchy of methods,
+     * fields, attributes, etc. spawns a tree of objects.
+     *
+     * @param v Visitor object
+     */
+    @Override
+    public void accept( final Visitor v ) {
+        v.visitConstantPackage(this);
+    }
+
+
+    /**
+     * Dump constant package to file stream in binary format.
+     *
+     * @param file Output file stream
+     * @throws IOException
+     */
+    @Override
+    public final void dump( final DataOutputStream file ) throws IOException {
+        file.writeByte(super.getTag());
+        file.writeShort(name_index);
+    }
+
+
+    /**
+     * @return Name index in constant pool of package name.
+     */
+    public final int getNameIndex() {
+        return name_index;
+    }
+
+
+    /**
+     * @param name_index the name index in the constant pool of this Constant Package
+     */
+    public final void setNameIndex( final int name_index ) {
+        this.name_index = name_index;
+    }
+
+
+    /** @return String object
+     */
+    @Override
+    public Object getConstantValue( final ConstantPool cp ) {
+        final Constant c = cp.getConstant(name_index, Const.CONSTANT_Utf8);
+        return ((ConstantUtf8) c).getBytes();
+    }
+
+
+    /** @return dereferenced string
+     */
+    public String getBytes( final ConstantPool cp ) {
+        return (String) getConstantValue(cp);
+    }
+
+
+    /**
+     * @return String representation.
+     */
+    @Override
+    public final String toString() {
+        return super.toString() + "(name_index = " + name_index + ")";
+    }
+}
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantPool.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantPool.java	Mon Jul 01 14:57:02 2019 -0700
@@ -35,7 +35,7 @@
  * programatically should see <a href="../generic/ConstantPoolGen.html">
  * ConstantPoolGen</a>.
 
- * @version $Id: ConstantPool.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
  * @see     Constant
  * @see     com.sun.org.apache.bcel.internal.generic.ConstantPoolGen
  */
@@ -135,7 +135,7 @@
             case Const.CONSTANT_NameAndType:
                 str = constantToString(((ConstantNameAndType) c).getNameIndex(),
                         Const.CONSTANT_Utf8)
-                        + ":" + constantToString(((ConstantNameAndType) c).getSignatureIndex(),
+                        + " " + constantToString(((ConstantNameAndType) c).getSignatureIndex(),
                         Const.CONSTANT_Utf8);
                 break;
             case Const.CONSTANT_InterfaceMethodref:
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantString.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantString.java	Mon Jul 01 14:57:02 2019 -0700
@@ -31,7 +31,7 @@
  * This class is derived from the abstract {@link Constant}
  * and represents a reference to a String object.
  *
- * @version $Id: ConstantString.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
  * @see     Constant
  */
 public final class ConstantString extends Constant implements ConstantObject {
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantUtf8.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantUtf8.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -32,8 +32,9 @@
  * This class is derived from the abstract {@link Constant}
  * and represents a reference to a Utf8 encoded string.
  *
- * @version $Id: ConstantUtf8.java 1750029 2016-06-23 22:14:38Z sebb $
+ * @version $Id$
  * @see     Constant
+ * @LastModified: Jun 2019
  */
 public final class ConstantUtf8 extends Constant {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantValue.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantValue.java	Mon Jul 01 14:57:02 2019 -0700
@@ -32,7 +32,7 @@
  * value, i.e., a default value for initializing a class field.
  * This class is instantiated by the <em>Attribute.readAttribute()</em> method.
  *
- * @version $Id: ConstantValue.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
  * @see     Attribute
  */
 public final class ConstantValue extends Attribute {
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Deprecated.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Deprecated.java	Mon Jul 01 14:57:02 2019 -0700
@@ -28,16 +28,17 @@
 
 /**
  * This class is derived from <em>Attribute</em> and denotes that this is a
- * deprecated method. It is instantiated from the
- * <em>Attribute.readAttribute()</em> method.
+ * deprecated method.
+ * It is instantiated from the <em>Attribute.readAttribute()</em> method.
  *
- * @version $Id: Deprecated.java 1749603 2016-06-21 20:50:19Z ggregory $
- * @see Attribute
+ * @version $Id$
+ * @see     Attribute
  */
 public final class Deprecated extends Attribute {
 
     private byte[] bytes;
 
+
     /**
      * Initialize from another object. Note that both objects use the same
      * references (shallow copy). Use clone() for a physical copy.
@@ -46,6 +47,7 @@
         this(c.getNameIndex(), c.getLength(), c.getBytes(), c.getConstantPool());
     }
 
+
     /**
      * @param name_index Index in constant pool to CONSTANT_Utf8
      * @param length Content length in bytes
@@ -57,6 +59,7 @@
         this.bytes = bytes;
     }
 
+
     /**
      * Construct object from input stream.
      *
@@ -76,6 +79,7 @@
         }
     }
 
+
     /**
      * Called by objects that are traversing the nodes of the tree implicitely
      * defined by the contents of a Java class. I.e., the hierarchy of methods,
@@ -84,10 +88,11 @@
      * @param v Visitor object
      */
     @Override
-    public void accept(final Visitor v) {
+    public void accept( final Visitor v ) {
         v.visitDeprecated(this);
     }
 
+
     /**
      * Dump source file attribute to file stream in binary format.
      *
@@ -95,13 +100,14 @@
      * @throws IOException
      */
     @Override
-    public final void dump(final DataOutputStream file) throws IOException {
+    public final void dump( final DataOutputStream file ) throws IOException {
         super.dump(file);
         if (super.getLength() > 0) {
             file.write(bytes, 0, super.getLength());
         }
     }
 
+
     /**
      * @return data bytes.
      */
@@ -109,13 +115,15 @@
         return bytes;
     }
 
+
     /**
      * @param bytes the raw bytes that represents this byte array
      */
-    public final void setBytes(final byte[] bytes) {
+    public final void setBytes( final byte[] bytes ) {
         this.bytes = bytes;
     }
 
+
     /**
      * @return attribute name
      */
@@ -124,11 +132,12 @@
         return Const.getAttributeName(Const.ATTR_DEPRECATED);
     }
 
+
     /**
      * @return deep copy of this attribute
      */
     @Override
-    public Attribute copy(final ConstantPool _constant_pool) {
+    public Attribute copy( final ConstantPool _constant_pool ) {
         final Deprecated c = (Deprecated) clone();
         if (bytes != null) {
             c.bytes = new byte[bytes.length];
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/DescendingVisitor.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/DescendingVisitor.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,10 +26,10 @@
  * applied to all components of a JavaClass object. I.e. this class supplies the
  * traversal strategy, other classes can make use of it.
  *
- * @version $Id: DescendingVisitor.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
  */
-public class DescendingVisitor implements Visitor {
-
+public class DescendingVisitor implements Visitor
+{
     private final JavaClass clazz;
 
     private final Visitor visitor;
@@ -39,17 +39,21 @@
     /**
      * @return container of current entitity, i.e., predecessor during traversal
      */
-    public Object predecessor() {
+    public Object predecessor()
+    {
         return predecessor(0);
     }
 
     /**
-     * @param level nesting level, i.e., 0 returns the direct predecessor
+     * @param level
+     *            nesting level, i.e., 0 returns the direct predecessor
      * @return container of current entitity, i.e., predecessor during traversal
      */
-    public Object predecessor(final int level) {
+    public Object predecessor(final int level)
+    {
         final int size = stack.size();
-        if ((size < 2) || (level < 0)) {
+        if ((size < 2) || (level < 0))
+        {
             return null;
         }
         return stack.elementAt(size - (level + 2)); // size - 1 == current
@@ -58,15 +62,19 @@
     /**
      * @return current object
      */
-    public Object current() {
+    public Object current()
+    {
         return stack.peek();
     }
 
     /**
-     * @param clazz Class to traverse
-     * @param visitor visitor object to apply to all components
+     * @param clazz
+     *            Class to traverse
+     * @param visitor
+     *            visitor object to apply to all components
      */
-    public DescendingVisitor(final JavaClass clazz, final Visitor visitor) {
+    public DescendingVisitor(final JavaClass clazz, final Visitor visitor)
+    {
         this.clazz = clazz;
         this.visitor = visitor;
     }
@@ -74,12 +82,14 @@
     /**
      * Start traversal.
      */
-    public void visit() {
+    public void visit()
+    {
         clazz.accept(this);
     }
 
     @Override
-    public void visitJavaClass(final JavaClass _clazz) {
+    public void visitJavaClass(final JavaClass _clazz)
+    {
         stack.push(_clazz);
         _clazz.accept(visitor);
         final Field[] fields = _clazz.getFields();
@@ -102,7 +112,8 @@
      * @since 6.0
      */
     @Override
-    public void visitAnnotation(final Annotations annotation) {
+    public void visitAnnotation(final Annotations annotation)
+    {
         stack.push(annotation);
         annotation.accept(visitor);
         final AnnotationEntry[] entries = annotation.getAnnotationEntries();
@@ -116,14 +127,16 @@
      * @since 6.0
      */
     @Override
-    public void visitAnnotationEntry(final AnnotationEntry annotationEntry) {
+    public void visitAnnotationEntry(final AnnotationEntry annotationEntry)
+    {
         stack.push(annotationEntry);
         annotationEntry.accept(visitor);
         stack.pop();
     }
 
     @Override
-    public void visitField(final Field field) {
+    public void visitField(final Field field)
+    {
         stack.push(field);
         field.accept(visitor);
         final Attribute[] attributes = field.getAttributes();
@@ -134,14 +147,16 @@
     }
 
     @Override
-    public void visitConstantValue(final ConstantValue cv) {
+    public void visitConstantValue(final ConstantValue cv)
+    {
         stack.push(cv);
         cv.accept(visitor);
         stack.pop();
     }
 
     @Override
-    public void visitMethod(final Method method) {
+    public void visitMethod(final Method method)
+    {
         stack.push(method);
         method.accept(visitor);
         final Attribute[] attributes = method.getAttributes();
@@ -152,14 +167,16 @@
     }
 
     @Override
-    public void visitExceptionTable(final ExceptionTable table) {
+    public void visitExceptionTable(final ExceptionTable table)
+    {
         stack.push(table);
         table.accept(visitor);
         stack.pop();
     }
 
     @Override
-    public void visitCode(final Code code) {
+    public void visitCode(final Code code)
+    {
         stack.push(code);
         code.accept(visitor);
         final CodeException[] table = code.getExceptionTable();
@@ -174,14 +191,16 @@
     }
 
     @Override
-    public void visitCodeException(final CodeException ce) {
+    public void visitCodeException(final CodeException ce)
+    {
         stack.push(ce);
         ce.accept(visitor);
         stack.pop();
     }
 
     @Override
-    public void visitLineNumberTable(final LineNumberTable table) {
+    public void visitLineNumberTable(final LineNumberTable table)
+    {
         stack.push(table);
         table.accept(visitor);
         final LineNumber[] numbers = table.getLineNumberTable();
@@ -192,14 +211,16 @@
     }
 
     @Override
-    public void visitLineNumber(final LineNumber number) {
+    public void visitLineNumber(final LineNumber number)
+    {
         stack.push(number);
         number.accept(visitor);
         stack.pop();
     }
 
     @Override
-    public void visitLocalVariableTable(final LocalVariableTable table) {
+    public void visitLocalVariableTable(final LocalVariableTable table)
+    {
         stack.push(table);
         table.accept(visitor);
         final LocalVariable[] vars = table.getLocalVariableTable();
@@ -210,7 +231,8 @@
     }
 
     @Override
-    public void visitStackMap(final StackMap table) {
+    public void visitStackMap(final StackMap table)
+    {
         stack.push(table);
         table.accept(visitor);
         final StackMapEntry[] vars = table.getStackMap();
@@ -221,26 +243,31 @@
     }
 
     @Override
-    public void visitStackMapEntry(final StackMapEntry var) {
+    public void visitStackMapEntry(final StackMapEntry var)
+    {
         stack.push(var);
         var.accept(visitor);
         stack.pop();
     }
 
     @Override
-    public void visitLocalVariable(final LocalVariable var) {
+    public void visitLocalVariable(final LocalVariable var)
+    {
         stack.push(var);
         var.accept(visitor);
         stack.pop();
     }
 
     @Override
-    public void visitConstantPool(final ConstantPool cp) {
+    public void visitConstantPool(final ConstantPool cp)
+    {
         stack.push(cp);
         cp.accept(visitor);
         final Constant[] constants = cp.getConstantPool();
-        for (int i = 1; i < constants.length; i++) {
-            if (constants[i] != null) {
+        for (int i = 1; i < constants.length; i++)
+        {
+            if (constants[i] != null)
+            {
                 constants[i].accept(this);
             }
         }
@@ -248,35 +275,40 @@
     }
 
     @Override
-    public void visitConstantClass(final ConstantClass constant) {
+    public void visitConstantClass(final ConstantClass constant)
+    {
         stack.push(constant);
         constant.accept(visitor);
         stack.pop();
     }
 
     @Override
-    public void visitConstantDouble(final ConstantDouble constant) {
+    public void visitConstantDouble(final ConstantDouble constant)
+    {
         stack.push(constant);
         constant.accept(visitor);
         stack.pop();
     }
 
     @Override
-    public void visitConstantFieldref(final ConstantFieldref constant) {
+    public void visitConstantFieldref(final ConstantFieldref constant)
+    {
         stack.push(constant);
         constant.accept(visitor);
         stack.pop();
     }
 
     @Override
-    public void visitConstantFloat(final ConstantFloat constant) {
+    public void visitConstantFloat(final ConstantFloat constant)
+    {
         stack.push(constant);
         constant.accept(visitor);
         stack.pop();
     }
 
     @Override
-    public void visitConstantInteger(final ConstantInteger constant) {
+    public void visitConstantInteger(final ConstantInteger constant)
+    {
         stack.push(constant);
         constant.accept(visitor);
         stack.pop();
@@ -284,7 +316,8 @@
 
     @Override
     public void visitConstantInterfaceMethodref(
-            final ConstantInterfaceMethodref constant) {
+            final ConstantInterfaceMethodref constant)
+    {
         stack.push(constant);
         constant.accept(visitor);
         stack.pop();
@@ -295,49 +328,56 @@
      */
     @Override
     public void visitConstantInvokeDynamic(
-            final ConstantInvokeDynamic constant) {
+            final ConstantInvokeDynamic constant)
+    {
         stack.push(constant);
         constant.accept(visitor);
         stack.pop();
     }
 
     @Override
-    public void visitConstantLong(final ConstantLong constant) {
+    public void visitConstantLong(final ConstantLong constant)
+    {
         stack.push(constant);
         constant.accept(visitor);
         stack.pop();
     }
 
     @Override
-    public void visitConstantMethodref(final ConstantMethodref constant) {
+    public void visitConstantMethodref(final ConstantMethodref constant)
+    {
         stack.push(constant);
         constant.accept(visitor);
         stack.pop();
     }
 
     @Override
-    public void visitConstantNameAndType(final ConstantNameAndType constant) {
+    public void visitConstantNameAndType(final ConstantNameAndType constant)
+    {
         stack.push(constant);
         constant.accept(visitor);
         stack.pop();
     }
 
     @Override
-    public void visitConstantString(final ConstantString constant) {
+    public void visitConstantString(final ConstantString constant)
+    {
         stack.push(constant);
         constant.accept(visitor);
         stack.pop();
     }
 
     @Override
-    public void visitConstantUtf8(final ConstantUtf8 constant) {
+    public void visitConstantUtf8(final ConstantUtf8 constant)
+    {
         stack.push(constant);
         constant.accept(visitor);
         stack.pop();
     }
 
     @Override
-    public void visitInnerClasses(final InnerClasses ic) {
+    public void visitInnerClasses(final InnerClasses ic)
+    {
         stack.push(ic);
         ic.accept(visitor);
         final InnerClass[] ics = ic.getInnerClasses();
@@ -348,7 +388,8 @@
     }
 
     @Override
-    public void visitInnerClass(final InnerClass inner) {
+    public void visitInnerClass(final InnerClass inner)
+    {
         stack.push(inner);
         inner.accept(visitor);
         stack.pop();
@@ -358,7 +399,8 @@
      * @since 6.0
      */
     @Override
-    public void visitBootstrapMethods(final BootstrapMethods bm) {
+    public void visitBootstrapMethods(final BootstrapMethods bm)
+    {
         stack.push(bm);
         bm.accept(visitor);
         // BootstrapMethod[] bms = bm.getBootstrapMethods();
@@ -370,35 +412,40 @@
     }
 
     @Override
-    public void visitDeprecated(final Deprecated attribute) {
+    public void visitDeprecated(final Deprecated attribute)
+    {
         stack.push(attribute);
         attribute.accept(visitor);
         stack.pop();
     }
 
     @Override
-    public void visitSignature(final Signature attribute) {
+    public void visitSignature(final Signature attribute)
+    {
         stack.push(attribute);
         attribute.accept(visitor);
         stack.pop();
     }
 
     @Override
-    public void visitSourceFile(final SourceFile attribute) {
+    public void visitSourceFile(final SourceFile attribute)
+    {
         stack.push(attribute);
         attribute.accept(visitor);
         stack.pop();
     }
 
     @Override
-    public void visitSynthetic(final Synthetic attribute) {
+    public void visitSynthetic(final Synthetic attribute)
+    {
         stack.push(attribute);
         attribute.accept(visitor);
         stack.pop();
     }
 
     @Override
-    public void visitUnknown(final Unknown attribute) {
+    public void visitUnknown(final Unknown attribute)
+    {
         stack.push(attribute);
         attribute.accept(visitor);
         stack.pop();
@@ -408,7 +455,8 @@
      * @since 6.0
      */
     @Override
-    public void visitAnnotationDefault(final AnnotationDefault obj) {
+    public void visitAnnotationDefault(final AnnotationDefault obj)
+    {
         stack.push(obj);
         obj.accept(visitor);
         stack.pop();
@@ -418,7 +466,8 @@
      * @since 6.0
      */
     @Override
-    public void visitEnclosingMethod(final EnclosingMethod obj) {
+    public void visitEnclosingMethod(final EnclosingMethod obj)
+    {
         stack.push(obj);
         obj.accept(visitor);
         stack.pop();
@@ -428,13 +477,10 @@
      * @since 6.0
      */
     @Override
-    public void visitLocalVariableTypeTable(final LocalVariableTypeTable obj) {
+    public void visitLocalVariableTypeTable(final LocalVariableTypeTable obj)
+    {
         stack.push(obj);
         obj.accept(visitor);
-        LocalVariable[] vars = obj.getLocalVariableTypeTable();
-        for (LocalVariable var : vars) {
-            var.accept(this);
-        }
         stack.pop();
     }
 
@@ -442,7 +488,8 @@
      * @since 6.0
      */
     @Override
-    public void visitParameterAnnotation(final ParameterAnnotations obj) {
+    public void visitParameterAnnotation(final ParameterAnnotations obj)
+    {
         stack.push(obj);
         obj.accept(visitor);
         stack.pop();
@@ -452,15 +499,14 @@
      * @since 6.0
      */
     @Override
-    public void visitMethodParameters(final MethodParameters obj) {
+    public void visitMethodParameters(final MethodParameters obj)
+    {
         stack.push(obj);
         obj.accept(visitor);
         stack.pop();
     }
 
-    /**
-     * @since 6.0
-     */
+    /** @since 6.0 */
     @Override
     public void visitConstantMethodType(final ConstantMethodType obj) {
         stack.push(obj);
@@ -468,9 +514,7 @@
         stack.pop();
     }
 
-    /**
-     * @since 6.0
-     */
+    /** @since 6.0 */
     @Override
     public void visitConstantMethodHandle(final ConstantMethodHandle obj) {
         stack.push(obj);
@@ -478,9 +522,7 @@
         stack.pop();
     }
 
-    /**
-     * @since 6.0
-     */
+    /** @since 6.0 */
     @Override
     public void visitParameterAnnotationEntry(final ParameterAnnotationEntry obj) {
         stack.push(obj);
@@ -488,4 +530,27 @@
         stack.pop();
     }
 
+    /** @since 6.1 */
+    @Override
+    public void visitConstantPackage(final ConstantPackage obj) {
+        stack.push(obj);
+        obj.accept(visitor);
+        stack.pop();
+    }
+
+    /** @since 6.1 */
+    @Override
+    public void visitConstantModule(final ConstantModule obj) {
+        stack.push(obj);
+        obj.accept(visitor);
+        stack.pop();
+    }
+
+    /** @since 6.3 */
+    @Override
+    public void visitConstantDynamic(final ConstantDynamic obj) {
+        stack.push(obj);
+        obj.accept(visitor);
+        stack.pop();
+    }
 }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ElementValue.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ElementValue.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,6 +1,5 @@
 /*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -28,6 +27,7 @@
 /**
  * @version $Id: ElementValue
  * @since 6.0
+ * @LastModified: Jun 2019
  */
 public abstract class ElementValue
 {
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/EmptyVisitor.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/EmptyVisitor.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,7 +26,7 @@
  * with the DescendingVisitor class, e.g. By courtesy of David Spencer.
  *
  * @see DescendingVisitor
- * @version $Id: EmptyVisitor.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class EmptyVisitor implements Visitor
 {
@@ -300,4 +300,26 @@
     @Override
     public void visitParameterAnnotationEntry(final ParameterAnnotationEntry parameterAnnotationEntry) {
     }
+
+    /**
+     * @since 6.1
+     */
+    @Override
+    public void visitConstantPackage(final ConstantPackage constantPackage) {
+    }
+
+    /**
+     * @since 6.1
+     */
+    @Override
+    public void visitConstantModule(final ConstantModule constantModule) {
+    }
+
+
+    /**
+     * @since 6.3
+     */
+    @Override
+    public void visitConstantDynamic(final ConstantDynamic obj) {
+    }
 }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ExceptionTable.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ExceptionTable.java	Mon Jul 01 14:57:02 2019 -0700
@@ -35,7 +35,7 @@
  * attribute using the name <em>Exceptions</em> (which is inconsistent
  * with the other classes).
  *
- * @version $Id: ExceptionTable.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
  * @see     Code
  */
 public final class ExceptionTable extends Attribute {
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Field.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Field.java	Mon Jul 01 14:57:02 2019 -0700
@@ -23,6 +23,7 @@
 
 import java.io.DataInput;
 import java.io.IOException;
+import java.util.Objects;
 
 import com.sun.org.apache.bcel.internal.Const;
 import com.sun.org.apache.bcel.internal.generic.Type;
@@ -32,7 +33,7 @@
  * This class represents the field info structure, i.e., the representation
  * for a variable in the class. See JVM specification for details.
  *
- * @version $Id: Field.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
  */
 public final class Field extends FieldOrMethod {
 
@@ -42,8 +43,8 @@
         public boolean equals( final Object o1, final Object o2 ) {
             final Field THIS = (Field) o1;
             final Field THAT = (Field) o2;
-            return THIS.getName().equals(THAT.getName())
-                    && THIS.getSignature().equals(THAT.getSignature());
+            return Objects.equals(THIS.getName(), THAT.getName())
+                    && Objects.equals(THIS.getSignature(), THAT.getSignature());
         }
 
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/FieldOrMethod.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/FieldOrMethod.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -29,7 +29,8 @@
 /**
  * Abstract super class for fields and methods.
  *
- * @version $Id: FieldOrMethod.java 1750029 2016-06-23 22:14:38Z sebb $
+ * @version $Id$
+ * @LastModified: Jun 2019
  */
 public abstract class FieldOrMethod extends AccessFlags implements Cloneable, Node {
     private int name_index; // Points to field name in constant pool
@@ -48,6 +49,7 @@
     FieldOrMethod() {
     }
 
+
     /**
      * Initialize from another object. Note that both objects use the same
      * references (shallow copy). Use clone() for a physical copy.
@@ -57,25 +59,23 @@
                 c.getAttributes(), c.getConstantPool());
     }
 
+
     /**
      * Construct object from file stream.
      *
      * @param file Input stream
      * @throws IOException
      * @throws ClassFormatException
-     * @deprecated (6.0) Use
-     * {@link #FieldOrMethod(java.io.DataInput, ConstantPool)} instead.
+     * @deprecated (6.0) Use {@link #FieldOrMethod(java.io.DataInput, ConstantPool)} instead.
      */
     @java.lang.Deprecated
-    protected FieldOrMethod(final DataInputStream file,
-            final ConstantPool constant_pool) throws IOException,
+    protected FieldOrMethod(final DataInputStream file, final ConstantPool constant_pool) throws IOException,
             ClassFormatException {
         this((DataInput) file, constant_pool);
     }
 
     /**
      * Construct object from file stream.
-     *
      * @param file Input stream
      * @throws IOException
      * @throws ClassFormatException
@@ -84,13 +84,15 @@
             final ConstantPool constant_pool) throws IOException, ClassFormatException {
         this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), null,
                 constant_pool);
-        attributes_count = file.readUnsignedShort();
+        final int attributes_count = file.readUnsignedShort();
         attributes = new Attribute[attributes_count];
         for (int i = 0; i < attributes_count; i++) {
             attributes[i] = Attribute.readAttribute(file, constant_pool);
         }
+        this.attributes_count = attributes_count; // init deprecated field
     }
 
+
     /**
      * @param access_flags Access rights of method
      * @param name_index Points to field name in constant pool
@@ -107,6 +109,7 @@
         setAttributes(attributes);
     }
 
+
     /**
      * Dump object to file stream on binary format.
      *
@@ -118,12 +121,14 @@
         file.writeShort(name_index);
         file.writeShort(signature_index);
         file.writeShort(attributes_count);
-
-        for(int i=0; i < attributes_count; i++) {
-            attributes[i].dump(file);
+        if (attributes != null) {
+            for (final Attribute attribute : attributes) {
+                attribute.dump(file);
+            }
         }
     }
 
+
     /**
      * @return Collection of object attributes.
      */
@@ -131,14 +136,16 @@
         return attributes;
     }
 
+
     /**
      * @param attributes Collection of object attributes.
      */
-    public final void setAttributes(final Attribute[] attributes) {
+    public final void setAttributes( final Attribute[] attributes ) {
         this.attributes = attributes;
-        this.attributes_count = attributes != null ? attributes.length : 0;
+        this.attributes_count = attributes != null ? attributes.length : 0; // init deprecated field
     }
 
+
     /**
      * @return Constant pool used by this object.
      */
@@ -146,13 +153,15 @@
         return constant_pool;
     }
 
+
     /**
      * @param constant_pool Constant pool to be used for this object.
      */
-    public final void setConstantPool(final ConstantPool constant_pool) {
+    public final void setConstantPool( final ConstantPool constant_pool ) {
         this.constant_pool = constant_pool;
     }
 
+
     /**
      * @return Index in constant pool of object's name.
      */
@@ -160,13 +169,15 @@
         return name_index;
     }
 
+
     /**
      * @param name_index Index in constant pool of object's name.
      */
-    public final void setNameIndex(final int name_index) {
+    public final void setNameIndex( final int name_index ) {
         this.name_index = name_index;
     }
 
+
     /**
      * @return Index in constant pool of field signature.
      */
@@ -174,13 +185,15 @@
         return signature_index;
     }
 
+
     /**
      * @param signature_index Index in constant pool of field signature.
      */
-    public final void setSignatureIndex(final int signature_index) {
+    public final void setSignatureIndex( final int signature_index ) {
         this.signature_index = signature_index;
     }
 
+
     /**
      * @return Name of object, i.e., method name or field name
      */
@@ -190,6 +203,7 @@
         return c.getBytes();
     }
 
+
     /**
      * @return String representation of object's type signature (java style)
      */
@@ -199,23 +213,24 @@
         return c.getBytes();
     }
 
+
     /**
      * @return deep copy of this field
      */
-    protected FieldOrMethod copy_(final ConstantPool _constant_pool) {
+    protected FieldOrMethod copy_( final ConstantPool _constant_pool ) {
         FieldOrMethod c = null;
 
         try {
-            c = (FieldOrMethod) clone();
-        } catch (final CloneNotSupportedException e) {
+          c = (FieldOrMethod)clone();
+        } catch(final CloneNotSupportedException e) {
             // ignored, but will cause NPE ...
         }
 
-        c.constant_pool = constant_pool;
-        c.attributes = new Attribute[attributes_count];
-        c.attributes_count = attributes_count;
+        c.constant_pool    = constant_pool;
+        c.attributes       = new Attribute[attributes.length];
+        c.attributes_count = attributes_count; // init deprecated field
 
-        for (int i = 0; i < attributes_count; i++) {
+        for (int i = 0; i < attributes.length; i++) {
             c.attributes[i] = attributes[i].copy(constant_pool);
         }
 
@@ -244,11 +259,15 @@
      *
      * @since 6.0
      */
-    public final String getGenericSignature() {
-        if (!searchedForSignatureAttribute) {
+    public final String getGenericSignature()
+    {
+        if (!searchedForSignatureAttribute)
+        {
             boolean found = false;
-            for (int i = 0; !found && i < attributes.length; i++) {
-                if (attributes[i] instanceof Signature) {
+            for (int i = 0; !found && i < attributes.length; i++)
+            {
+                if (attributes[i] instanceof Signature)
+                {
                     signatureAttributeString = ((Signature) attributes[i])
                             .getSignature();
                     found = true;
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/InnerClass.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/InnerClass.java	Mon Jul 01 14:57:02 2019 -0700
@@ -32,7 +32,7 @@
  * indices of the inner and outer classes, the name and the attributes
  * of the inner class.
  *
- * @version $Id: InnerClass.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
  * @see InnerClasses
  */
 public final class InnerClass implements Cloneable, Node {
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/InnerClasses.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/InnerClasses.java	Mon Jul 01 14:57:02 2019 -0700
@@ -33,7 +33,7 @@
  * to the source file of this class.
  * It is instantiated from the <em>Attribute.readAttribute()</em> method.
  *
- * @version $Id: InnerClasses.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
  * @see     Attribute
  */
 public final class InnerClasses extends Attribute {
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/JavaClass.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/JavaClass.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -26,9 +26,10 @@
 import java.io.IOException;
 import java.io.OutputStream;
 import java.util.ArrayList;
+import java.util.Objects;
+import java.util.StringTokenizer;
 import java.util.List;
 import java.util.Set;
-import java.util.StringTokenizer;
 import java.util.TreeSet;
 
 import com.sun.org.apache.bcel.internal.Const;
@@ -36,7 +37,6 @@
 import com.sun.org.apache.bcel.internal.util.BCELComparator;
 import com.sun.org.apache.bcel.internal.util.ClassQueue;
 import com.sun.org.apache.bcel.internal.util.SyntheticRepository;
-import jdk.xml.internal.SecuritySupport;
 
 /**
  * Represents a Java class, i.e., the data structures, constant pool, fields,
@@ -45,9 +45,10 @@
  * details. The intent of this class is to represent a parsed or otherwise
  * existing class file. Those interested in programatically generating classes
  * should see the <a href="../generic/ClassGen.html">ClassGen</a> class.
- *
- * @version $Id: JavaClass.java 1750227 2016-06-25 21:47:10Z ggregory $
+
+ * @version $Id$
  * @see com.sun.org.apache.bcel.internal.generic.ClassGen
+ * @LastModified: Jun 2019
  */
 public class JavaClass extends AccessFlags implements Cloneable, Node, Comparable<JavaClass> {
 
@@ -78,25 +79,28 @@
     private static BCELComparator bcelComparator = new BCELComparator() {
 
         @Override
-        public boolean equals(final Object o1, final Object o2) {
+        public boolean equals( final Object o1, final Object o2 ) {
             final JavaClass THIS = (JavaClass) o1;
             final JavaClass THAT = (JavaClass) o2;
-            return THIS.getClassName().equals(THAT.getClassName());
+            return Objects.equals(THIS.getClassName(), THAT.getClassName());
         }
 
+
         @Override
-        public int hashCode(final Object o) {
+        public int hashCode( final Object o ) {
             final JavaClass THIS = (JavaClass) o;
             return THIS.getClassName().hashCode();
         }
     };
     /**
-     * In cases where we go ahead and create something, use the default
-     * SyntheticRepository, because we don't know any better.
+     * In cases where we go ahead and create something,
+     * use the default SyntheticRepository, because we
+     * don't know any better.
      */
     private transient com.sun.org.apache.bcel.internal.util.Repository repository
             = SyntheticRepository.getInstance();
 
+
     /**
      * Constructor gets all contents as arguments.
      *
@@ -177,6 +181,7 @@
         }
     }
 
+
     /**
      * Constructor gets all contents as arguments.
      *
@@ -200,15 +205,16 @@
                 constant_pool, interfaces, fields, methods, attributes, HEAP);
     }
 
+
     /**
-     * Called by objects that are traversing the nodes of the tree implicitly
+     * Called by objects that are traversing the nodes of the tree implicitely
      * defined by the contents of a Java class. I.e., the hierarchy of methods,
      * fields, attributes, etc. spawns a tree of objects.
      *
      * @param v Visitor object
      */
     @Override
-    public void accept(final Visitor v) {
+    public void accept( final Visitor v ) {
         v.visitJavaClass(this);
     }
 
@@ -223,7 +229,7 @@
         if (parent != null) {
             final File dir = new File(parent);
             if (!dir.mkdirs()) { // either was not created or already existed
-                if (!SecuritySupport.isDirectory(dir)) {
+                if (!dir.isDirectory()) {
                     throw new IOException("Could not create the directory " + dir);
                 }
             }
@@ -233,16 +239,18 @@
         }
     }
 
+
     /**
      * Dump class to a file named file_name.
      *
      * @param _file_name Output file name
      * @throws IOException
      */
-    public void dump(final String _file_name) throws IOException {
+    public void dump( final String _file_name ) throws IOException {
         dump(new File(_file_name));
     }
 
+
     /**
      * @return class in binary format
      */
@@ -263,15 +271,6 @@
         return s.toByteArray();
     }
 
-    /**
-     * Dump Java class to output stream in binary format.
-     *
-     * @param file Output stream
-     * @throws IOException
-     */
-    public void dump(final OutputStream file) throws IOException {
-        dump(new DataOutputStream(file));
-    }
 
     /**
      * Dump Java class to output stream in binary format.
@@ -279,7 +278,18 @@
      * @param file Output stream
      * @throws IOException
      */
-    private void dump(final DataOutputStream file) throws IOException {
+    public void dump( final OutputStream file ) throws IOException {
+        dump(new DataOutputStream(file));
+    }
+
+
+    /**
+     * Dump Java class to output stream in binary format.
+     *
+     * @param file Output stream
+     * @throws IOException
+     */
+    public void dump( final DataOutputStream file ) throws IOException {
         file.writeInt(Const.JVM_CLASSFILE_MAGIC);
         file.writeShort(minor);
         file.writeShort(major);
@@ -310,6 +320,7 @@
         file.flush();
     }
 
+
     /**
      * @return Attributes of the class.
      */
@@ -336,6 +347,7 @@
         return class_name;
     }
 
+
     /**
      * @return Package name.
      */
@@ -343,6 +355,7 @@
         return package_name;
     }
 
+
     /**
      * @return Class name index.
      */
@@ -350,6 +363,7 @@
         return class_name_index;
     }
 
+
     /**
      * @return Constant pool.
      */
@@ -357,15 +371,17 @@
         return constant_pool;
     }
 
+
     /**
-     * @return Fields, i.e., variables of the class. Like the JVM spec mandates
-     * for the classfile format, these fields are those specific to this class,
-     * and not those of the superclass or superinterfaces.
+     * @return Fields, i.e., variables of the class. Like the JVM spec
+     * mandates for the classfile format, these fields are those specific to
+     * this class, and not those of the superclass or superinterfaces.
      */
     public Field[] getFields() {
         return fields;
     }
 
+
     /**
      * @return File name of class, aka SourceFile attribute value
      */
@@ -373,6 +389,7 @@
         return file_name;
     }
 
+
     /**
      * @return Names of implemented interfaces.
      */
@@ -380,6 +397,7 @@
         return interface_names;
     }
 
+
     /**
      * @return Indices in constant pool of implemented interfaces.
      */
@@ -387,6 +405,7 @@
         return interfaces;
     }
 
+
     /**
      * @return Major number of class file version.
      */
@@ -394,6 +413,7 @@
         return major;
     }
 
+
     /**
      * @return Methods of the class.
      */
@@ -401,10 +421,12 @@
         return methods;
     }
 
+
     /**
-     * @return A {@link Method} corresponding to java.lang.reflect.Method if any
+     * @return A {@link Method} corresponding to
+     * java.lang.reflect.Method if any
      */
-    public Method getMethod(final java.lang.reflect.Method m) {
+    public Method getMethod( final java.lang.reflect.Method m ) {
         for (final Method method : methods) {
             if (m.getName().equals(method.getName()) && (m.getModifiers() == method.getModifiers())
                     && Type.getSignature(m).equals(method.getSignature())) {
@@ -414,6 +436,7 @@
         return null;
     }
 
+
     /**
      * @return Minor number of class file version.
      */
@@ -421,6 +444,7 @@
         return minor;
     }
 
+
     /**
      * @return sbsolute path to file where this class was read from
      */
@@ -428,11 +452,11 @@
         return source_file_name;
     }
 
+
     /**
-     * returns the super class name of this class. In the case that this class
-     * is java.lang.Object, it will return itself (java.lang.Object). This is
-     * probably incorrect but isn't fixed at this time to not break existing
-     * clients.
+     * returns the super class name of this class. In the case that this class is
+     * java.lang.Object, it will return itself (java.lang.Object). This is probably incorrect
+     * but isn't fixed at this time to not break existing clients.
      *
      * @return Superclass name.
      */
@@ -440,6 +464,7 @@
         return superclass_name;
     }
 
+
     /**
      * @return Class name index.
      */
@@ -450,101 +475,115 @@
     /**
      * @param attributes .
      */
-    public void setAttributes(final Attribute[] attributes) {
+    public void setAttributes( final Attribute[] attributes ) {
         this.attributes = attributes;
     }
 
+
     /**
      * @param class_name .
      */
-    public void setClassName(final String class_name) {
+    public void setClassName( final String class_name ) {
         this.class_name = class_name;
     }
 
+
     /**
      * @param class_name_index .
      */
-    public void setClassNameIndex(final int class_name_index) {
+    public void setClassNameIndex( final int class_name_index ) {
         this.class_name_index = class_name_index;
     }
 
+
     /**
      * @param constant_pool .
      */
-    public void setConstantPool(final ConstantPool constant_pool) {
+    public void setConstantPool( final ConstantPool constant_pool ) {
         this.constant_pool = constant_pool;
     }
 
+
     /**
      * @param fields .
      */
-    public void setFields(final Field[] fields) {
+    public void setFields( final Field[] fields ) {
         this.fields = fields;
     }
 
+
     /**
      * Set File name of class, aka SourceFile attribute value
      */
-    public void setFileName(final String file_name) {
+    public void setFileName( final String file_name ) {
         this.file_name = file_name;
     }
 
+
     /**
      * @param interface_names .
      */
-    public void setInterfaceNames(final String[] interface_names) {
+    public void setInterfaceNames( final String[] interface_names ) {
         this.interface_names = interface_names;
     }
 
+
     /**
      * @param interfaces .
      */
-    public void setInterfaces(final int[] interfaces) {
+    public void setInterfaces( final int[] interfaces ) {
         this.interfaces = interfaces;
     }
 
+
     /**
      * @param major .
      */
-    public void setMajor(final int major) {
+    public void setMajor( final int major ) {
         this.major = major;
     }
 
+
     /**
      * @param methods .
      */
-    public void setMethods(final Method[] methods) {
+    public void setMethods( final Method[] methods ) {
         this.methods = methods;
     }
 
+
     /**
      * @param minor .
      */
-    public void setMinor(final int minor) {
+    public void setMinor( final int minor ) {
         this.minor = minor;
     }
 
+
     /**
      * Set absolute path to file this class was read from.
      */
-    public void setSourceFileName(final String source_file_name) {
+    public void setSourceFileName( final String source_file_name ) {
         this.source_file_name = source_file_name;
     }
 
+
     /**
      * @param superclass_name .
      */
-    public void setSuperclassName(final String superclass_name) {
+    public void setSuperclassName( final String superclass_name ) {
         this.superclass_name = superclass_name;
     }
 
+
     /**
      * @param superclass_name_index .
      */
-    public void setSuperclassNameIndex(final int superclass_name_index) {
+    public void setSuperclassNameIndex( final int superclass_name_index ) {
         this.superclass_name_index = superclass_name_index;
     }
 
+
     /**
      * @return String representing class contents.
      */
@@ -555,7 +594,7 @@
         final StringBuilder buf = new StringBuilder(128);
         buf.append(access).append(Utility.classOrInterface(super.getAccessFlags())).append(" ").append(
                 class_name).append(" extends ").append(
-                        Utility.compactClassName(superclass_name, false)).append('\n');
+                Utility.compactClassName(superclass_name, false)).append('\n');
         final int size = interfaces.length;
         if (size > 0) {
             buf.append("implements\t\t");
@@ -580,7 +619,7 @@
             }
         }
         final AnnotationEntry[] annotations = getAnnotationEntries();
-        if (annotations != null && annotations.length > 0) {
+        if (annotations!=null && annotations.length>0) {
             buf.append("\nAnnotation(s):\n");
             for (final AnnotationEntry annotation : annotations) {
                 buf.append(indent(annotation));
@@ -601,7 +640,8 @@
         return buf.toString();
     }
 
-    private static String indent(final Object obj) {
+
+    private static String indent( final Object obj ) {
         final StringTokenizer tok = new StringTokenizer(obj.toString(), "\n");
         final StringBuilder buf = new StringBuilder();
         while (tok.hasMoreTokens()) {
@@ -610,6 +650,7 @@
         return buf.toString();
     }
 
+
     /**
      * @return deep copy of this class
      */
@@ -638,10 +679,12 @@
         return c;
     }
 
+
     public final boolean isSuper() {
         return (super.getAccessFlags() & Const.ACC_SUPER) != 0;
     }
 
+
     public final boolean isClass() {
         return (super.getAccessFlags() & Const.ACC_INTERFACE) == 0;
     }
@@ -667,62 +710,62 @@
             return;
         }
         for (final Attribute attribute : this.attributes) {
-            if (attribute instanceof InnerClasses) {
-                final InnerClass[] innerClasses = ((InnerClasses) attribute).getInnerClasses();
-                for (final InnerClass innerClasse : innerClasses) {
-                    boolean innerClassAttributeRefersToMe = false;
-                    String inner_class_name = constant_pool.getConstantString(innerClasse.getInnerClassIndex(),
-                            Const.CONSTANT_Class);
-                    inner_class_name = Utility.compactClassName(inner_class_name);
-                    if (inner_class_name.equals(getClassName())) {
-                        innerClassAttributeRefersToMe = true;
-                    }
-                    if (innerClassAttributeRefersToMe) {
-                        this.isNested = true;
-                        if (innerClasse.getInnerNameIndex() == 0) {
-                            this.isAnonymous = true;
-                        }
-                    }
-                }
-            }
+              if (attribute instanceof InnerClasses) {
+                  final InnerClass[] innerClasses = ((InnerClasses) attribute).getInnerClasses();
+                  for (final InnerClass innerClasse : innerClasses) {
+                      boolean innerClassAttributeRefersToMe = false;
+                      String inner_class_name = constant_pool.getConstantString(innerClasse.getInnerClassIndex(),
+                                 Const.CONSTANT_Class);
+                      inner_class_name = Utility.compactClassName(inner_class_name);
+                      if (inner_class_name.equals(getClassName())) {
+                          innerClassAttributeRefersToMe = true;
+                      }
+                      if (innerClassAttributeRefersToMe) {
+                          this.isNested = true;
+                          if (innerClasse.getInnerNameIndex() == 0) {
+                              this.isAnonymous = true;
+                          }
+                      }
+                  }
+              }
         }
         this.computedNestedTypeStatus = true;
     }
 
-    /**
-     * @return returns either HEAP (generated), FILE, or ZIP
+
+    /** @return returns either HEAP (generated), FILE, or ZIP
      */
     public final byte getSource() {
         return source;
     }
 
+
+    /********************* New repository functionality *********************/
     /**
-     * ******************* New repository functionality ********************
-     */
-    /**
-     * Gets the ClassRepository which holds its definition. By default this is
-     * the same as SyntheticRepository.getInstance();
+     * Gets the ClassRepository which holds its definition. By default
+     * this is the same as SyntheticRepository.getInstance();
      */
     public com.sun.org.apache.bcel.internal.util.Repository getRepository() {
         return repository;
     }
 
+
     /**
-     * Sets the ClassRepository which loaded the JavaClass. Should be called
-     * immediately after parsing is done.
+     * Sets the ClassRepository which loaded the JavaClass.
+     * Should be called immediately after parsing is done.
      */
     public void setRepository(final com.sun.org.apache.bcel.internal.util.Repository repository) {
         this.repository = repository;
     }
 
-    /**
-     * Equivalent to runtime "instanceof" operator.
+
+    /** Equivalent to runtime "instanceof" operator.
      *
      * @return true if this JavaClass is derived from the super class
-     * @throws ClassNotFoundException if superclasses or superinterfaces of this
-     * object can't be found
+     * @throws ClassNotFoundException if superclasses or superinterfaces
+     *   of this object can't be found
      */
-    public final boolean instanceOf(final JavaClass super_class) throws ClassNotFoundException {
+    public final boolean instanceOf( final JavaClass super_class ) throws ClassNotFoundException {
         if (this.equals(super_class)) {
             return true;
         }
@@ -738,12 +781,13 @@
         return false;
     }
 
+
     /**
      * @return true, if this class is an implementation of interface inter
-     * @throws ClassNotFoundException if superclasses or superinterfaces of this
-     * class can't be found
+     * @throws ClassNotFoundException if superclasses or superinterfaces
+     *   of this class can't be found
      */
-    public boolean implementationOf(final JavaClass inter) throws ClassNotFoundException {
+    public boolean implementationOf( final JavaClass inter ) throws ClassNotFoundException {
         if (!inter.isInterface()) {
             throw new IllegalArgumentException(inter.getClassName() + " is no interface");
         }
@@ -759,9 +803,10 @@
         return false;
     }
 
+
     /**
-     * @return the superclass for this JavaClass object, or null if this is
-     * java.lang.Object
+     * @return the superclass for this JavaClass object, or null if this
+     * is java.lang.Object
      * @throws ClassNotFoundException if the superclass can't be found
      */
     public JavaClass getSuperClass() throws ClassNotFoundException {
@@ -771,6 +816,7 @@
         return repository.loadClass(getSuperclassName());
     }
 
+
     /**
      * @return list of super classes of this class in ascending order, i.e.,
      * java.lang.Object is always the last element
@@ -785,6 +831,7 @@
         return allSuperClasses.toArray(new JavaClass[allSuperClasses.size()]);
     }
 
+
     /**
      * Get interfaces directly implemented by this JavaClass.
      */
@@ -797,6 +844,7 @@
         return classes;
     }
 
+
     /**
      * Get all interfaces implemented by this JavaClass (transitively).
      */
@@ -822,6 +870,7 @@
         return allInterfaces.toArray(new JavaClass[allInterfaces.size()]);
     }
 
+
     /**
      * @return Comparison strategy object
      */
@@ -829,38 +878,42 @@
         return bcelComparator;
     }
 
+
     /**
      * @param comparator Comparison strategy object
      */
-    public static void setComparator(final BCELComparator comparator) {
+    public static void setComparator( final BCELComparator comparator ) {
         bcelComparator = comparator;
     }
 
+
     /**
-     * Return value as defined by given BCELComparator strategy. By default two
-     * JavaClass objects are said to be equal when their class names are equal.
+     * Return value as defined by given BCELComparator strategy.
+     * By default two JavaClass objects are said to be equal when
+     * their class names are equal.
      *
      * @see java.lang.Object#equals(java.lang.Object)
      */
     @Override
-    public boolean equals(final Object obj) {
+    public boolean equals( final Object obj ) {
         return bcelComparator.equals(this, obj);
     }
 
+
     /**
-     * Return the natural ordering of two JavaClasses. This ordering is based on
-     * the class name
-     *
+     * Return the natural ordering of two JavaClasses.
+     * This ordering is based on the class name
      * @since 6.0
      */
     @Override
-    public int compareTo(final JavaClass obj) {
+    public int compareTo( final JavaClass obj ) {
         return getClassName().compareTo(obj.getClassName());
     }
 
+
     /**
-     * Return value as defined by given BCELComparator strategy. By default
-     * return the hashcode of the class name.
+     * Return value as defined by given BCELComparator strategy.
+     * By default return the hashcode of the class name.
      *
      * @see java.lang.Object#hashCode()
      */
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LineNumber.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LineNumber.java	Mon Jul 01 14:57:02 2019 -0700
@@ -30,7 +30,7 @@
  * the source that corresponds to a relative address in the byte code. This
  * is used for debugging purposes.
  *
- * @version $Id: LineNumber.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
  * @see     LineNumberTable
  */
 public final class LineNumber implements Cloneable, Node {
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LineNumberTable.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LineNumberTable.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -26,13 +26,14 @@
 import jdk.xml.internal.SecuritySupport;
 
 /**
- * This class represents a table of line numbers for debugging purposes. This
- * attribute is used by the <em>Code</em> attribute. It contains pairs of PCs
- * and line numbers.
+ * This class represents a table of line numbers for debugging
+ * purposes. This attribute is used by the <em>Code</em> attribute. It
+ * contains pairs of PCs and line numbers.
  *
- * @version $Id: LineNumberTable.java 1749603 2016-06-21 20:50:19Z ggregory $
- * @see Code
+ * @version $Id$
+ * @see     Code
  * @see LineNumber
+ * @LastModified: Jun 2019
  */
 public final class LineNumberTable extends Attribute {
 
@@ -63,7 +64,6 @@
 
     /**
      * Construct object from input stream.
-     *
      * @param name_index Index of name
      * @param length Content length in bytes
      * @param input Input stream
@@ -88,7 +88,7 @@
      * @param v Visitor object
      */
     @Override
-    public void accept(final Visitor v) {
+    public void accept( final Visitor v ) {
         v.visitLineNumberTable(this);
     }
 
@@ -99,7 +99,7 @@
      * @throws IOEXception if an I/O Exception occurs in writeShort
      */
     @Override
-    public final void dump(final DataOutputStream file) throws IOException {
+    public final void dump( final DataOutputStream file ) throws IOException {
         super.dump(file);
         file.writeShort(line_number_table.length);
         for (final LineNumber lineNumber : line_number_table) {
@@ -117,7 +117,7 @@
     /**
      * @param line_number_table the line number entries for this table
      */
-    public final void setLineNumberTable(final LineNumber[] line_number_table) {
+    public final void setLineNumberTable( final LineNumber[] line_number_table ) {
         this.line_number_table = line_number_table;
     }
 
@@ -150,7 +150,7 @@
      * @param pos byte code offset
      * @return corresponding line in source code
      */
-    public int getSourceLine(final int pos) {
+    public int getSourceLine( final int pos ) {
         int l = 0;
         int r = line_number_table.length - 1;
         if (r < 0) {
@@ -192,7 +192,7 @@
      * @return deep copy of this attribute
      */
     @Override
-    public Attribute copy(final ConstantPool _constant_pool) {
+    public Attribute copy( final ConstantPool _constant_pool ) {
         // TODO could use the lower level constructor and thereby allow
         // line_number_table to be made final
         final LineNumberTable c = (LineNumberTable) clone();
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariable.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariable.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -30,8 +30,9 @@
  * This class represents a local variable within a method. It contains its
  * scope, name, signature and index on the method's frame.
  *
- * @version $Id: LocalVariable.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
  * @see     LocalVariableTable
+ * @LastModified: Jun 2019
  */
 public final class LocalVariable implements Cloneable, Node {
 
@@ -43,6 +44,7 @@
      * this method's frame.
      */
     private ConstantPool constant_pool;
+    private int orig_index; // never changes; used to match up with LocalVariableTypeTable entries
 
 
     /**
@@ -52,6 +54,7 @@
     public LocalVariable(final LocalVariable c) {
         this(c.getStartPC(), c.getLength(), c.getNameIndex(), c.getSignatureIndex(), c.getIndex(),
                 c.getConstantPool());
+        this.orig_index = c.getOrigIndex();
     }
 
 
@@ -82,6 +85,28 @@
         this.signature_index = signature_index;
         this.index = index;
         this.constant_pool = constant_pool;
+        this.orig_index = index;
+    }
+
+
+    /**
+     * @param start_pc Range in which the variable
+     * @param length ... is valid
+     * @param name_index Index in constant pool of variable name
+     * @param signature_index Index of variable's signature
+     * @param index Variable is `index'th local variable on the method's frame
+     * @param constant_pool Array of constants
+     * @param orig_index Variable is `index'th local variable on the method's frame prior to any changes
+     */
+    public LocalVariable(final int start_pc, final int length, final int name_index, final int signature_index, final int index,
+            final ConstantPool constant_pool, final int orig_index) {
+        this.start_pc = start_pc;
+        this.length = length;
+        this.name_index = name_index;
+        this.signature_index = signature_index;
+        this.index = index;
+        this.constant_pool = constant_pool;
+        this.orig_index = orig_index;
     }
 
 
@@ -174,6 +199,14 @@
 
 
     /**
+     * @return index of register where variable was originally stored
+     */
+    public final int getOrigIndex() {
+        return orig_index;
+    }
+
+
+    /**
      * @return Start of range where he variable is valid
      */
     public final int getStartPC() {
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariableTable.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariableTable.java	Mon Jul 01 14:57:02 2019 -0700
@@ -31,7 +31,7 @@
  * This class represents colection of local variables in a
  * method. This attribute is contained in the <em>Code</em> attribute.
  *
- * @version $Id: LocalVariableTable.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
  * @see     Code
  * @see LocalVariable
  */
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariableTypeTable.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariableTypeTable.java	Mon Jul 01 14:57:02 2019 -0700
@@ -23,9 +23,11 @@
 import java.io.DataInput;
 import java.io.DataOutputStream;
 import java.io.IOException;
+
 import com.sun.org.apache.bcel.internal.Const;
 
 // The new table is used when generic types are about...
+
 //LocalVariableTable_attribute {
 //       u2 attribute_name_index;
 //       u4 attribute_length;
@@ -37,6 +39,7 @@
 //          u2 index;
 //       } local_variable_table[local_variable_table_length];
 //     }
+
 //LocalVariableTypeTable_attribute {
 //    u2 attribute_name_index;
 //    u4 attribute_length;
@@ -50,6 +53,7 @@
 //    } local_variable_type_table[local_variable_type_table_length];
 //  }
 // J5TODO: Needs some testing !
+
 /**
  * @since 6.0
  */
@@ -61,14 +65,12 @@
         this(c.getNameIndex(), c.getLength(), c.getLocalVariableTypeTable(), c.getConstantPool());
     }
 
-    public LocalVariableTypeTable(final int name_index, final int length,
-            final LocalVariable[] local_variable_table, final ConstantPool constant_pool) {
+    public LocalVariableTypeTable(final int name_index, final int length, final LocalVariable[] local_variable_table, final ConstantPool constant_pool) {
         super(Const.ATTR_LOCAL_VARIABLE_TYPE_TABLE, name_index, length, constant_pool);
         this.local_variable_type_table = local_variable_table;
     }
 
-    LocalVariableTypeTable(final int nameIdx, final int len, final DataInput input,
-            final ConstantPool cpool) throws IOException {
+    LocalVariableTypeTable(final int nameIdx, final int len, final DataInput input, final ConstantPool cpool) throws IOException {
         this(nameIdx, len, (LocalVariable[]) null, cpool);
 
         final int local_variable_type_table_length = input.readUnsignedShort();
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Method.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Method.java	Mon Jul 01 14:57:02 2019 -0700
@@ -22,32 +22,34 @@
 
 import java.io.DataInput;
 import java.io.IOException;
+import java.util.Objects;
 
 import com.sun.org.apache.bcel.internal.Const;
 import com.sun.org.apache.bcel.internal.generic.Type;
 import com.sun.org.apache.bcel.internal.util.BCELComparator;
 
 /**
- * This class represents the method info structure, i.e., the representation for
- * a method in the class. See JVM specification for details. A method has access
- * flags, a name, a signature and a number of attributes.
+ * This class represents the method info structure, i.e., the representation
+ * for a method in the class. See JVM specification for details.
+ * A method has access flags, a name, a signature and a number of attributes.
  *
- * @version $Id: Method.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
  */
 public final class Method extends FieldOrMethod {
 
     private static BCELComparator bcelComparator = new BCELComparator() {
 
         @Override
-        public boolean equals(final Object o1, final Object o2) {
+        public boolean equals( final Object o1, final Object o2 ) {
             final Method THIS = (Method) o1;
             final Method THAT = (Method) o2;
-            return THIS.getName().equals(THAT.getName())
-                    && THIS.getSignature().equals(THAT.getSignature());
+            return Objects.equals(THIS.getName(), THAT.getName())
+                    && Objects.equals(THIS.getSignature(), THAT.getSignature());
         }
 
+
         @Override
-        public int hashCode(final Object o) {
+        public int hashCode( final Object o ) {
             final Method THIS = (Method) o;
             return THIS.getSignature().hashCode() ^ THIS.getName().hashCode();
         }
@@ -63,6 +65,7 @@
     public Method() {
     }
 
+
     /**
      * Initialize from another object. Note that both objects use the same
      * references (shallow copy). Use clone() for a physical copy.
@@ -71,9 +74,9 @@
         super(c);
     }
 
+
     /**
      * Construct object from file stream.
-     *
      * @param file Input stream
      * @throws IOException
      * @throws ClassFormatException
@@ -83,6 +86,7 @@
         super(file, constant_pool);
     }
 
+
     /**
      * @param access_flags Access rights of method
      * @param name_index Points to field name in constant pool
@@ -95,6 +99,7 @@
         super(access_flags, name_index, signature_index, attributes, constant_pool);
     }
 
+
     /**
      * Called by objects that are traversing the nodes of the tree implicitely
      * defined by the contents of a Java class. I.e., the hierarchy of methods,
@@ -103,10 +108,11 @@
      * @param v Visitor object
      */
     @Override
-    public void accept(final Visitor v) {
+    public void accept( final Visitor v ) {
         v.visitMethod(this);
     }
 
+
     /**
      * @return Code attribute of method, if any
      */
@@ -119,6 +125,7 @@
         return null;
     }
 
+
     /**
      * @return ExceptionTable attribute of method, if any, i.e., list all
      * exceptions the method may throw not exception handlers!
@@ -132,9 +139,9 @@
         return null;
     }
 
-    /**
-     * @return LocalVariableTable of code attribute if any, i.e. the call is
-     * forwarded to the Code atribute.
+
+    /** @return LocalVariableTable of code attribute if any, i.e. the call is forwarded
+     * to the Code atribute.
      */
     public final LocalVariableTable getLocalVariableTable() {
         final Code code = getCode();
@@ -144,9 +151,9 @@
         return code.getLocalVariableTable();
     }
 
-    /**
-     * @return LineNumberTable of code attribute if any, i.e. the call is
-     * forwarded to the Code atribute.
+
+    /** @return LineNumberTable of code attribute if any, i.e. the call is forwarded
+     * to the Code atribute.
      */
     public final LineNumberTable getLineNumberTable() {
         final Code code = getCode();
@@ -156,9 +163,10 @@
         return code.getLineNumberTable();
     }
 
+
     /**
-     * Return string representation close to declaration format, e.g.
-     * 'public static void main(String[] args) throws IOException'
+     * Return string representation close to declaration format,
+     * `public static void main(String[] args) throws IOException', e.g.
      *
      * @return String representation of the method.
      */
@@ -188,13 +196,15 @@
         return buf.toString();
     }
 
+
     /**
      * @return deep copy of this method
      */
-    public final Method copy(final ConstantPool _constant_pool) {
+    public final Method copy( final ConstantPool _constant_pool ) {
         return (Method) copy_(_constant_pool);
     }
 
+
     /**
      * @return return type of method
      */
@@ -202,6 +212,7 @@
         return Type.getReturnType(getSignature());
     }
 
+
     /**
      * @return array of method argument types
      */
@@ -209,6 +220,7 @@
         return Type.getArgumentTypes(getSignature());
     }
 
+
     /**
      * @return Comparison strategy object
      */
@@ -216,28 +228,31 @@
         return bcelComparator;
     }
 
+
     /**
      * @param comparator Comparison strategy object
      */
-    public static void setComparator(final BCELComparator comparator) {
+    public static void setComparator( final BCELComparator comparator ) {
         bcelComparator = comparator;
     }
 
+
     /**
-     * Return value as defined by given BCELComparator strategy. By default two
-     * method objects are said to be equal when their names and signatures are
-     * equal.
+     * Return value as defined by given BCELComparator strategy.
+     * By default two method objects are said to be equal when
+     * their names and signatures are equal.
      *
      * @see java.lang.Object#equals(java.lang.Object)
      */
     @Override
-    public boolean equals(final Object obj) {
+    public boolean equals( final Object obj ) {
         return bcelComparator.equals(this, obj);
     }
 
+
     /**
-     * Return value as defined by given BCELComparator strategy. By default
-     * return the hashcode of the method's name XOR signature.
+     * Return value as defined by given BCELComparator strategy.
+     * By default return the hashcode of the method's name XOR signature.
      *
      * @see java.lang.Object#hashCode()
      */
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Node.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Node.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,7 +24,7 @@
 /**
  * Denote class to have an accept method();
  *
- * @version $Id: Node.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public interface Node {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/PMGClass.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/PMGClass.java	Mon Jul 01 14:57:02 2019 -0700
@@ -31,7 +31,7 @@
  * This class is derived from <em>Attribute</em> and represents a reference
  * to a PMG attribute.
  *
- * @version $Id: PMGClass.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
  * @see     Attribute
  */
 public final class PMGClass extends Attribute {
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Signature.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Signature.java	Mon Jul 01 14:57:02 2019 -0700
@@ -32,7 +32,7 @@
  * This class is derived from <em>Attribute</em> and represents a reference
  * to a GJ attribute.
  *
- * @version $Id: Signature.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
  * @see     Attribute
  */
 public final class Signature extends Attribute {
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/SourceFile.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/SourceFile.java	Mon Jul 01 14:57:02 2019 -0700
@@ -33,7 +33,7 @@
  * should appear per classfile.  The intention of this class is that it is
  * instantiated from the <em>Attribute.readAttribute()</em> method.
  *
- * @version $Id: SourceFile.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
  * @see     Attribute
  */
 public final class SourceFile extends Attribute {
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMap.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMap.java	Mon Jul 01 14:57:02 2019 -0700
@@ -36,7 +36,7 @@
  * within the Code attribute of a method. See CLDC specification
  * 5.3.1.2
  *
- * @version $Id: StackMap.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
  * @see     Code
  * @see     StackMapEntry
  * @see     StackMapType
@@ -78,7 +78,7 @@
 
 
     /**
-     * Dump line number table attribute to file stream in binary format.
+     * Dump stack map table attribute to file stream in binary format.
      *
      * @param file Output file stream
      * @throws IOException
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMapEntry.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMapEntry.java	Mon Jul 01 14:57:02 2019 -0700
@@ -31,7 +31,7 @@
  * local variables and the the of stack items at a given byte code offset.
  * See CLDC specification 5.3.1.2
  *
- * @version $Id: StackMapEntry.java 1750029 2016-06-23 22:14:38Z sebb $
+ * @version $Id$
  * @see     StackMap
  * @see     StackMapType
  */
@@ -51,8 +51,8 @@
      * @param input Input stream
      * @throws IOException
      */
-    StackMapEntry(final DataInput input, final ConstantPool constant_pool) throws IOException {
-        this(input.readByte() & 0xFF, -1, null, null, constant_pool);
+    StackMapEntry(final DataInput input, final ConstantPool constantPool) throws IOException {
+        this(input.readByte() & 0xFF, -1, null, null, constantPool);
 
         if (frame_type >= Const.SAME_FRAME && frame_type <= Const.SAME_FRAME_MAX) {
             byte_code_offset = frame_type - Const.SAME_FRAME;
@@ -60,11 +60,11 @@
                    frame_type <= Const.SAME_LOCALS_1_STACK_ITEM_FRAME_MAX) {
             byte_code_offset = frame_type - Const.SAME_LOCALS_1_STACK_ITEM_FRAME;
             types_of_stack_items = new StackMapType[1];
-            types_of_stack_items[0] = new StackMapType(input, constant_pool);
+            types_of_stack_items[0] = new StackMapType(input, constantPool);
         } else if (frame_type == Const.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) {
             byte_code_offset = input.readShort();
             types_of_stack_items = new StackMapType[1];
-            types_of_stack_items[0] = new StackMapType(input, constant_pool);
+            types_of_stack_items[0] = new StackMapType(input, constantPool);
         } else if (frame_type >= Const.CHOP_FRAME && frame_type <= Const.CHOP_FRAME_MAX) {
             byte_code_offset = input.readShort();
         } else if (frame_type == Const.SAME_FRAME_EXTENDED) {
@@ -74,19 +74,19 @@
             final int number_of_locals = frame_type - 251;
             types_of_locals = new StackMapType[number_of_locals];
             for (int i = 0; i < number_of_locals; i++) {
-                types_of_locals[i] = new StackMapType(input, constant_pool);
+                types_of_locals[i] = new StackMapType(input, constantPool);
             }
         } else if (frame_type == Const.FULL_FRAME) {
             byte_code_offset = input.readShort();
             final int number_of_locals = input.readShort();
             types_of_locals = new StackMapType[number_of_locals];
             for (int i = 0; i < number_of_locals; i++) {
-                types_of_locals[i] = new StackMapType(input, constant_pool);
+                types_of_locals[i] = new StackMapType(input, constantPool);
             }
             final int number_of_stack_items = input.readShort();
             types_of_stack_items = new StackMapType[number_of_stack_items];
             for (int i = 0; i < number_of_stack_items; i++) {
-                types_of_stack_items[i] = new StackMapType(input, constant_pool);
+                types_of_stack_items[i] = new StackMapType(input, constantPool);
             }
         } else {
             /* Can't happen */
@@ -97,42 +97,42 @@
     /**
      * DO NOT USE
      *
-     * @param byte_code_offset
-     * @param number_of_locals NOT USED
-     * @param types_of_locals array of {@link StackMapType}s of locals
-     * @param number_of_stack_items NOT USED
-     * @param types_of_stack_items array ot {@link StackMapType}s of stack items
-     * @param constant_pool the constant pool
+     * @param byteCodeOffset
+     * @param numberOfLocals NOT USED
+     * @param typesOfLocals array of {@link StackMapType}s of locals
+     * @param numberOfStackItems NOT USED
+     * @param typesOfStackItems array ot {@link StackMapType}s of stack items
+     * @param constantPool the constant pool
      * @deprecated Since 6.0, use {@link #StackMapEntry(int, int, StackMapType[], StackMapType[], ConstantPool)}
      * instead
      */
     @java.lang.Deprecated
-    public StackMapEntry(final int byte_code_offset, final int number_of_locals,
-            final StackMapType[] types_of_locals, final int number_of_stack_items,
-            final StackMapType[] types_of_stack_items, final ConstantPool constant_pool) {
-        this.byte_code_offset = byte_code_offset;
-        this.types_of_locals = types_of_locals != null ? types_of_locals : new StackMapType[0];
-        this.types_of_stack_items = types_of_stack_items != null ? types_of_stack_items : new StackMapType[0];
-        this.constant_pool = constant_pool;
+    public StackMapEntry(final int byteCodeOffset, final int numberOfLocals,
+            final StackMapType[] typesOfLocals, final int numberOfStackItems,
+            final StackMapType[] typesOfStackItems, final ConstantPool constantPool) {
+        this.byte_code_offset = byteCodeOffset;
+        this.types_of_locals = typesOfLocals != null ? typesOfLocals : new StackMapType[0];
+        this.types_of_stack_items = typesOfStackItems != null ? typesOfStackItems : new StackMapType[0];
+        this.constant_pool = constantPool;
     }
 
     /**
      * Create an instance
      *
      * @param tag the frame_type to use
-     * @param byte_code_offset
-     * @param types_of_locals array of {@link StackMapType}s of locals
-     * @param types_of_stack_items array ot {@link StackMapType}s of stack items
-     * @param constant_pool the constant pool
+     * @param byteCodeOffset
+     * @param typesOfLocals array of {@link StackMapType}s of locals
+     * @param typesOfStackItems array ot {@link StackMapType}s of stack items
+     * @param constantPool the constant pool
      */
-    public StackMapEntry(final int tag, final int byte_code_offset,
-            final StackMapType[] types_of_locals,
-            final StackMapType[] types_of_stack_items, final ConstantPool constant_pool) {
+    public StackMapEntry(final int tag, final int byteCodeOffset,
+            final StackMapType[] typesOfLocals,
+            final StackMapType[] typesOfStackItems, final ConstantPool constantPool) {
         this.frame_type = tag;
-        this.byte_code_offset = byte_code_offset;
-        this.types_of_locals = types_of_locals != null ? types_of_locals : new StackMapType[0];
-        this.types_of_stack_items = types_of_stack_items != null ? types_of_stack_items : new StackMapType[0];
-        this.constant_pool = constant_pool;
+        this.byte_code_offset = byteCodeOffset;
+        this.types_of_locals = typesOfLocals != null ? typesOfLocals : new StackMapType[0];
+        this.types_of_stack_items = typesOfStackItems != null ? typesOfStackItems : new StackMapType[0];
+        this.constant_pool = constantPool;
     }
 
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMapType.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMapType.java	Mon Jul 01 14:57:02 2019 -0700
@@ -31,7 +31,7 @@
  * This class represents the type of a local variable or item on stack
  * used in the StackMap entries.
  *
- * @version $Id: StackMapType.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
  * @see     StackMapEntry
  * @see     StackMap
  * @see     Const
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Synthetic.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Synthetic.java	Mon Jul 01 14:57:02 2019 -0700
@@ -36,7 +36,7 @@
  * is intended to be instantiated from the
  * <em>Attribute.readAttribute()</em> method.
  *
- * @version $Id: Synthetic.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
  * @see     Attribute
  */
 public final class Synthetic extends Attribute {
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Unknown.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Unknown.java	Mon Jul 01 14:57:02 2019 -0700
@@ -38,7 +38,7 @@
  * {@link Attribute#addAttributeReader(String, UnknownAttributeReader)}.
 
  *
- * @version $Id: Unknown.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
  * @see Attribute
  * @see UnknownAttributeReader
  */
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/UnknownAttributeReader.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/UnknownAttributeReader.java	Mon Jul 01 14:57:02 2019 -0700
@@ -27,7 +27,7 @@
  * method. These factory objects should implement this interface.
  *
  * @see Attribute
- * @version $Id: UnknownAttributeReader.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  * @since 6.0
  */
 public interface UnknownAttributeReader {
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Utility.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Utility.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -42,32 +42,32 @@
 /**
  * Utility functions that do not really belong to any class in particular.
  *
- * @version $Id: Utility.java 1751107 2016-07-03 02:41:18Z dbrosius $
- * @LastModified: Oct 2017
+ * @version $Id$
+ * @LastModified: Jun 2019
  */
 // @since 6.0 methods are no longer final
 public abstract class Utility {
 
-    private static int unwrap(final ThreadLocal<Integer> tl) {
-        return tl.get().intValue();
+    private static int unwrap( final ThreadLocal<Integer> tl ) {
+        return tl.get();
     }
 
-    private static void wrap(final ThreadLocal<Integer> tl, final int value) {
-        tl.set(Integer.valueOf(value));
+
+    private static void wrap( final ThreadLocal<Integer> tl, final int value ) {
+        tl.set(value);
     }
 
     private static ThreadLocal<Integer> consumed_chars = new ThreadLocal<Integer>() {
 
         @Override
         protected Integer initialValue() {
-            return Integer.valueOf(0);
+            return 0;
         }
     };/* How many chars have been consumed
      * during parsing in signatureToString().
      * Read by methodSignatureToString().
      * Set by side effect,but only internally.
      */
-
     private static boolean wide = false; /* The `WIDE' instruction is used in the
      * byte code to allow 16-bit wide indices
      * for local variables. This opcode
@@ -82,25 +82,27 @@
     /**
      * Convert bit field of flags into string such as `static final'.
      *
-     * @param access_flags Access flags
+     * @param  access_flags Access flags
      * @return String representation of flags
      */
-    public static String accessToString(final int access_flags) {
+    public static String accessToString( final int access_flags ) {
         return accessToString(access_flags, false);
     }
 
+
     /**
      * Convert bit field of flags into string such as `static final'.
      *
      * Special case: Classes compiled with new compilers and with the
-     * `ACC_SUPER' flag would be said to be "synchronized". This is because SUN
-     * used the same value for the flags `ACC_SUPER' and `ACC_SYNCHRONIZED'.
+     * `ACC_SUPER' flag would be said to be "synchronized". This is
+     * because SUN used the same value for the flags `ACC_SUPER' and
+     * `ACC_SYNCHRONIZED'.
      *
-     * @param access_flags Access flags
-     * @param for_class access flags are for class qualifiers ?
+     * @param  access_flags Access flags
+     * @param  for_class access flags are for class qualifiers ?
      * @return String representation of flags
      */
-    public static String accessToString(final int access_flags, final boolean for_class) {
+    public static String accessToString( final int access_flags, final boolean for_class ) {
         final StringBuilder buf = new StringBuilder();
         int p = 0;
         for (int i = 0; p < Const.MAX_ACC_FLAG; i++) { // Loop through known flags
@@ -120,33 +122,34 @@
         return buf.toString().trim();
     }
 
+
     /**
      * @param access_flags the class flags
      *
      * @return "class" or "interface", depending on the ACC_INTERFACE flag
      */
-    public static String classOrInterface(final int access_flags) {
+    public static String classOrInterface( final int access_flags ) {
         return ((access_flags & Const.ACC_INTERFACE) != 0) ? "interface" : "class";
     }
 
+
     /**
      * Disassemble a byte array of JVM byte codes starting from code line
      * `index' and return the disassembled string representation. Decode only
-     * `num' opcodes (including their operands), use -1 if you want to decompile
-     * everything.
+     * `num' opcodes (including their operands), use -1 if you want to
+     * decompile everything.
      *
-     * @param code byte code array
-     * @param constant_pool Array of constants
-     * @param index offset in `code' array
+     * @param  code byte code array
+     * @param  constant_pool Array of constants
+     * @param  index offset in `code' array
      * <EM>(number of opcodes, not bytes!)</EM>
-     * @param length number of opcodes to decompile, -1 for all
-     * @param verbose be verbose, e.g. print constant pool index
+     * @param  length number of opcodes to decompile, -1 for all
+     * @param  verbose be verbose, e.g. print constant pool index
      * @return String representation of byte codes
      */
-    public static String codeToString(final byte[] code, final ConstantPool constant_pool,
-            final int index, final int length, final boolean verbose) {
-        // Should be sufficient // CHECKSTYLE IGNORE MagicNumber
-        final StringBuilder buf = new StringBuilder(code.length * 20);
+    public static String codeToString( final byte[] code, final ConstantPool constant_pool, final int index,
+            final int length, final boolean verbose ) {
+        final StringBuilder buf = new StringBuilder(code.length * 20); // Should be sufficient // CHECKSTYLE IGNORE MagicNumber
         try (ByteSequence stream = new ByteSequence(code)) {
             for (int i = 0; i < index; i++) {
                 codeToString(stream, constant_pool, verbose);
@@ -154,9 +157,7 @@
             for (int i = 0; stream.available() > 0; i++) {
                 if ((length < 0) || (i < length)) {
                     final String indices = fillup(stream.getIndex() + ":", 6, true, ' ');
-                    buf.append(indices)
-                            .append(codeToString(stream, constant_pool, verbose))
-                            .append('\n');
+                    buf.append(indices).append(codeToString(stream, constant_pool, verbose)).append('\n');
                 }
             }
         } catch (final IOException e) {
@@ -165,21 +166,22 @@
         return buf.toString();
     }
 
-    public static String codeToString(final byte[] code, final ConstantPool constant_pool,
-            final int index, final int length) {
+
+    public static String codeToString( final byte[] code, final ConstantPool constant_pool, final int index, final int length ) {
         return codeToString(code, constant_pool, index, length, true);
     }
 
+
     /**
-     * Disassemble a stream of byte codes and return the string representation.
+     * Disassemble a stream of byte codes and return the
+     * string representation.
      *
-     * @param bytes stream of bytes
-     * @param constant_pool Array of constants
-     * @param verbose be verbose, e.g. print constant pool index
+     * @param  bytes stream of bytes
+     * @param  constant_pool Array of constants
+     * @param  verbose be verbose, e.g. print constant pool index
      * @return String representation of byte code
      *
-     * @throws IOException if a failure from reading from the bytes argument
-     * occurs
+     * @throws IOException if a failure from reading from the bytes argument occurs
      */
     @SuppressWarnings("fallthrough") // by design for case Const.INSTANCEOF
     public static String codeToString(final ByteSequence bytes, final ConstantPool constant_pool,
@@ -253,7 +255,7 @@
                 }
                 buf.append(")");
             }
-            break;
+                break;
             /* Two address bytes + offset from start of byte stream form the
              * jump target
              */
@@ -327,14 +329,14 @@
                 index = bytes.readUnsignedShort();
                 buf.append("\t\t").append(
                         constant_pool.constantToString(index, Const.CONSTANT_Fieldref)).append(
-                                verbose ? " (" + index + ")" : "");
+                        verbose ? " (" + index + ")" : "");
                 break;
             /* Operands are references to classes in constant pool
              */
             case Const.NEW:
             case Const.CHECKCAST:
                 buf.append("\t");
-            //$FALL-THROUGH$
+                //$FALL-THROUGH$
             case Const.INSTANCEOF:
                 index = bytes.readUnsignedShort();
                 buf.append("\t<").append(
@@ -364,7 +366,7 @@
                 final int nargs = bytes.readUnsignedByte(); // historical, redundant
                 buf.append("\t").append(
                         constant_pool
-                        .constantToString(index, Const.CONSTANT_InterfaceMethodref))
+                                .constantToString(index, Const.CONSTANT_InterfaceMethodref))
                         .append(verbose ? " (" + index + ")\t" : "").append(nargs).append("\t")
                         .append(bytes.readUnsignedByte()); // Last byte is a reserved space
                 break;
@@ -372,9 +374,9 @@
                 index = bytes.readUnsignedShort();
                 buf.append("\t").append(
                         constant_pool
-                        .constantToString(index, Const.CONSTANT_InvokeDynamic))
+                                .constantToString(index, Const.CONSTANT_InvokeDynamic))
                         .append(verbose ? " (" + index + ")\t" : "")
-                        .append(bytes.readUnsignedByte()) // Thrid byte is a reserved space
+                        .append(bytes.readUnsignedByte())  // Thrid byte is a reserved space
                         .append(bytes.readUnsignedByte()); // Last byte is a reserved space
                 break;
             /* Operands are references to items in constant pool
@@ -398,8 +400,8 @@
                 index = bytes.readUnsignedShort();
                 buf.append("\t\t<").append(
                         compactClassName(constant_pool.getConstantString(index,
-                                        Const.CONSTANT_Class), false)).append(">").append(
-                                verbose ? " (" + index + ")" : "");
+                                Const.CONSTANT_Class), false)).append(">").append(
+                        verbose ? " (" + index + ")" : "");
                 break;
             /* Multidimensional array of references.
              */
@@ -408,10 +410,10 @@
                 final int dimensions = bytes.readUnsignedByte();
                 buf.append("\t<").append(
                         compactClassName(constant_pool.getConstantString(index,
-                                        Const.CONSTANT_Class), false)).append(">\t").append(dimensions)
+                                Const.CONSTANT_Class), false)).append(">\t").append(dimensions)
                         .append(verbose ? " (" + index + ")" : "");
             }
-            break;
+                break;
             /* Increment local variable.
              */
             case Const.IINC:
@@ -448,11 +450,13 @@
         return buf.toString();
     }
 
-    public static String codeToString(final ByteSequence bytes, final ConstantPool constant_pool)
+
+    public static String codeToString( final ByteSequence bytes, final ConstantPool constant_pool )
             throws IOException {
         return codeToString(bytes, constant_pool, true);
     }
 
+
     /**
      * Shorten long class names, <em>java/lang/String</em> becomes
      * <em>String</em>.
@@ -460,21 +464,23 @@
      * @param str The long class name
      * @return Compacted class name
      */
-    public static String compactClassName(final String str) {
+    public static String compactClassName( final String str ) {
         return compactClassName(str, true);
     }
 
+
     /**
      * Shorten long class name <em>str</em>, i.e., chop off the <em>prefix</em>,
-     * if the class name starts with this string and the flag <em>chopit</em> is
-     * true. Slashes <em>/</em> are converted to dots <em>.</em>.
+     * if the
+     * class name starts with this string and the flag <em>chopit</em> is true.
+     * Slashes <em>/</em> are converted to dots <em>.</em>.
      *
      * @param str The long class name
      * @param prefix The prefix the get rid off
      * @param chopit Flag that determines whether chopping is executed or not
      * @return Compacted class name
      */
-    public static String compactClassName(String str, final String prefix, final boolean chopit) {
+    public static String compactClassName( String str, final String prefix, final boolean chopit ) {
         final int len = prefix.length();
         str = str.replace('/', '.'); // Is `/' on all systems, even DOS
         if (chopit) {
@@ -486,53 +492,58 @@
         return str;
     }
 
+
     /**
      * Shorten long class names, <em>java/lang/String</em> becomes
-     * <em>java.lang.String</em>, e.g.. If <em>chopit</em> is <em>true</em> the
-     * prefix <em>java.lang</em>
+     * <em>java.lang.String</em>,
+     * e.g.. If <em>chopit</em> is <em>true</em> the prefix <em>java.lang</em>
      * is also removed.
      *
      * @param str The long class name
      * @param chopit Flag that determines whether chopping is executed or not
      * @return Compacted class name
      */
-    public static String compactClassName(final String str, final boolean chopit) {
+    public static String compactClassName( final String str, final boolean chopit ) {
         return compactClassName(str, "java.lang.", chopit);
     }
 
+
     /**
      * @return `flag' with bit `i' set to 1
      */
-    public static int setBit(final int flag, final int i) {
+    public static int setBit( final int flag, final int i ) {
         return flag | pow2(i);
     }
 
+
     /**
      * @return `flag' with bit `i' set to 0
      */
-    public static int clearBit(final int flag, final int i) {
+    public static int clearBit( final int flag, final int i ) {
         final int bit = pow2(i);
         return (flag & bit) == 0 ? flag : flag ^ bit;
     }
 
+
     /**
      * @return true, if bit `i' in `flag' is set
      */
-    public static boolean isSet(final int flag, final int i) {
+    public static boolean isSet( final int flag, final int i ) {
         return (flag & pow2(i)) != 0;
     }
 
+
     /**
-     * Converts string containing the method return and argument types to a byte
-     * code method signature.
+     * Converts string containing the method return and argument types
+     * to a byte code method signature.
      *
-     * @param ret Return type of method
-     * @param argv Types of method arguments
+     * @param  ret Return type of method
+     * @param  argv Types of method arguments
      * @return Byte code representation of method signature
      *
      * @throws ClassFormatException if the signature is for Void
      */
-    public static String methodTypeToSignature(final String ret, final String[] argv)
+    public static String methodTypeToSignature( final String ret, final String[] argv )
             throws ClassFormatException {
         final StringBuilder buf = new StringBuilder("(");
         String str;
@@ -550,23 +561,25 @@
         return buf.toString();
     }
 
+
     /**
-     * @param signature Method signature
+     * @param  signature    Method signature
      * @return Array of argument types
-     * @throws ClassFormatException
+     * @throws  ClassFormatException
      */
-    public static String[] methodSignatureArgumentTypes(final String signature)
+    public static String[] methodSignatureArgumentTypes( final String signature )
             throws ClassFormatException {
         return methodSignatureArgumentTypes(signature, true);
     }
 
+
     /**
-     * @param signature Method signature
+     * @param  signature    Method signature
      * @param chopit Shorten class names ?
      * @return Array of argument types
-     * @throws ClassFormatException
+     * @throws  ClassFormatException
      */
-    public static String[] methodSignatureArgumentTypes(final String signature, final boolean chopit)
+    public static String[] methodSignatureArgumentTypes( final String signature, final boolean chopit )
             throws ClassFormatException {
         final List<String> vec = new ArrayList<>();
         int index;
@@ -586,24 +599,24 @@
         return vec.toArray(new String[vec.size()]);
     }
 
+
     /**
-     * @param signature Method signature
+     * @param  signature    Method signature
      * @return return type of method
-     * @throws ClassFormatException
+     * @throws  ClassFormatException
      */
-    public static String methodSignatureReturnType(final String signature)
-            throws ClassFormatException {
+    public static String methodSignatureReturnType( final String signature ) throws ClassFormatException {
         return methodSignatureReturnType(signature, true);
     }
 
+
     /**
-     * @param signature Method signature
+     * @param  signature    Method signature
      * @param chopit Shorten class names ?
      * @return return type of method
-     * @throws ClassFormatException
+     * @throws  ClassFormatException
      */
-    public static String methodSignatureReturnType(final String signature,
-            final boolean chopit) throws ClassFormatException {
+    public static String methodSignatureReturnType( final String signature, final boolean chopit ) throws ClassFormatException {
         int index;
         String type;
         try {
@@ -616,6 +629,7 @@
         return type;
     }
 
+
     /**
      * Converts method signature to string with all class names compacted.
      *
@@ -624,27 +638,27 @@
      * @param access flags of method
      * @return Human readable signature
      */
-    public static String methodSignatureToString(final String signature,
-            final String name, final String access) {
+    public static String methodSignatureToString( final String signature, final String name, final String access ) {
         return methodSignatureToString(signature, name, access, true);
     }
 
-    public static String methodSignatureToString(final String signature,
-            final String name, final String access, final boolean chopit) {
+
+    public static String methodSignatureToString( final String signature, final String name, final String access, final boolean chopit ) {
         return methodSignatureToString(signature, name, access, chopit, null);
     }
 
+
     /**
-     * A returntype signature represents the return value from a method. It is a
-     * series of bytes in the following grammar:
+     * A returntype signature represents the return value from a method.
+     * It is a series of bytes in the following grammar:
      *
      * <pre>
      * &lt;return_signature&gt; ::= &lt;field_type&gt; | V
      * </pre>
      *
-     * The character V indicates that the method returns no value. Otherwise,
-     * the signature indicates the type of the return value. An argument
-     * signature represents an argument passed to a method:
+     * The character V indicates that the method returns no value. Otherwise, the
+     * signature indicates the type of the return value.
+     * An argument signature represents an argument passed to a method:
      *
      * <pre>
      * &lt;argument_signature&gt; ::= &lt;field_type&gt;
@@ -661,17 +675,16 @@
      * `void main(String[])' and throws a `ClassFormatException' when the parsed
      * type is invalid.
      *
-     * @param signature Method signature
-     * @param name Method name
-     * @param access Method access rights
+     * @param  signature    Method signature
+     * @param  name         Method name
+     * @param  access       Method access rights
      * @param chopit
      * @param vars
      * @return Java type declaration
-     * @throws ClassFormatException
+     * @throws  ClassFormatException
      */
-    public static String methodSignatureToString(final String signature, final String name,
-            final String access, final boolean chopit, final LocalVariableTable vars)
-            throws ClassFormatException {
+    public static String methodSignatureToString( final String signature, final String name,
+            final String access, final boolean chopit, final LocalVariableTable vars ) throws ClassFormatException {
         final StringBuilder buf = new StringBuilder("(");
         String type;
         int index;
@@ -715,21 +728,22 @@
                 type + " " + name + buf.toString();
     }
 
+
     // Guess what this does
-    private static int pow2(final int n) {
+    private static int pow2( final int n ) {
         return 1 << n;
     }
 
+
     /**
-     * Replace all occurrences of <em>old</em> in <em>str</em> with
-     * <em>new</em>.
+     * Replace all occurrences of <em>old</em> in <em>str</em> with <em>new</em>.
      *
      * @param str String to permute
      * @param old String to be replaced
      * @param new_ Replacement string
      * @return new String object
      */
-    public static String replace(String str, final String old, final String new_) {
+    public static String replace( String str, final String old, final String new_ ) {
         int index;
         int old_index;
         try {
@@ -751,16 +765,18 @@
         return str;
     }
 
+
     /**
      * Converts signature to string with all class names compacted.
      *
      * @param signature to convert
      * @return Human readable signature
      */
-    public static String signatureToString(final String signature) {
+    public static String signatureToString( final String signature ) {
         return signatureToString(signature, true);
     }
 
+
     /**
      * The field signature represents the value of an argument to a function or
      * the value of a variable. It is a series of bytes generated by the
@@ -790,12 +806,12 @@
      * `String[]' and throws a `ClassFormatException' when the parsed type is
      * invalid.
      *
-     * @param signature Class signature
+     * @param  signature  Class signature
      * @param chopit Flag that determines whether chopping is executed or not
      * @return Java type declaration
      * @throws ClassFormatException
      */
-    public static String signatureToString(final String signature, final boolean chopit) {
+    public static String signatureToString( final String signature, final boolean chopit ) {
         //corrected concurrent private static field acess
         wrap(consumed_chars, 1); // This is the default, read just one char like `B'
         try {
@@ -837,6 +853,7 @@
                     if (index < 0) {
                         throw new ClassFormatException("Invalid signature: " + signature);
                     }
+
                     // check to see if there are any TypeArguments
                     final int bracketIndex = signature.substring(0, index).indexOf('<');
                     if (bracketIndex < 0) {
@@ -844,12 +861,20 @@
                         wrap(consumed_chars, index + 1); // "Lblabla;" `L' and `;' are removed
                         return compactClassName(signature.substring(1, index), chopit);
                     }
+                    // but make sure we are not looking past the end of the current item
+                    fromIndex = signature.indexOf(';');
+                    if (fromIndex < 0) {
+                        throw new ClassFormatException("Invalid signature: " + signature);
+                    }
+                    if (fromIndex < bracketIndex) {
+                        // just a class identifier
+                        wrap(consumed_chars, fromIndex + 1); // "Lblabla;" `L' and `;' are removed
+                        return compactClassName(signature.substring(1, fromIndex), chopit);
+                    }
 
                     // we have TypeArguments; build up partial result
                     // as we recurse for each TypeArgument
-                    final StringBuilder type = new StringBuilder(
-                            compactClassName(signature.substring(1, bracketIndex), chopit))
-                            .append("<");
+                    final StringBuilder type = new StringBuilder(compactClassName(signature.substring(1, bracketIndex), chopit)).append("<");
                     int consumed_chars = bracketIndex + 1; // Shadows global var
 
                     // check for wildcards
@@ -859,37 +884,63 @@
                     } else if (signature.charAt(consumed_chars) == '-') {
                         type.append("? super ");
                         consumed_chars++;
-                    } else if (signature.charAt(consumed_chars) == '*') {
-                        // must be at end of signature
-                        if (signature.charAt(consumed_chars + 1) != '>') {
-                            throw new ClassFormatException("Invalid signature: " + signature);
-                        }
-                        if (signature.charAt(consumed_chars + 2) != ';') {
-                            throw new ClassFormatException("Invalid signature: " + signature);
-                        }
-                        wrap(Utility.consumed_chars, consumed_chars + 3); // remove final "*>;"
-                        return type + "?>...";
                     }
 
                     // get the first TypeArgument
-                    type.append(signatureToString(signature.substring(consumed_chars), chopit));
-                    // update our consumed count by the number of characters the for type argument
-                    consumed_chars = unwrap(Utility.consumed_chars) + consumed_chars;
-                    wrap(Utility.consumed_chars, consumed_chars);
-
-                    // are there more TypeArguments?
-                    while (signature.charAt(consumed_chars) != '>') {
-                        type.append(", ").append(signatureToString(signature.substring(consumed_chars), chopit));
+                    if (signature.charAt(consumed_chars) == '*') {
+                        type.append("?");
+                        consumed_chars++;
+                    } else {
+                        type.append(signatureToString(signature.substring(consumed_chars), chopit));
                         // update our consumed count by the number of characters the for type argument
                         consumed_chars = unwrap(Utility.consumed_chars) + consumed_chars;
                         wrap(Utility.consumed_chars, consumed_chars);
                     }
 
-                    if (signature.charAt(consumed_chars + 1) != ';') {
+                    // are there more TypeArguments?
+                    while (signature.charAt(consumed_chars) != '>') {
+                        type.append(", ");
+                        // check for wildcards
+                        if (signature.charAt(consumed_chars) == '+') {
+                            type.append("? extends ");
+                            consumed_chars++;
+                        } else if (signature.charAt(consumed_chars) == '-') {
+                            type.append("? super ");
+                            consumed_chars++;
+                        }
+                        if (signature.charAt(consumed_chars) == '*') {
+                            type.append("?");
+                            consumed_chars++;
+                        } else {
+                            type.append(signatureToString(signature.substring(consumed_chars), chopit));
+                            // update our consumed count by the number of characters the for type argument
+                            consumed_chars = unwrap(Utility.consumed_chars) + consumed_chars;
+                            wrap(Utility.consumed_chars, consumed_chars);
+                        }
+                    }
+
+                    // process the closing ">"
+                    consumed_chars++;
+                    type.append(">");
+
+                    if (signature.charAt(consumed_chars) == '.') {
+                        // we have a ClassTypeSignatureSuffix
+                        type.append(".");
+                        // convert SimpleClassTypeSignature to fake ClassTypeSignature
+                        // and then recurse to parse it
+                        type.append(signatureToString("L" + signature.substring(consumed_chars+1), chopit));
+                        // update our consumed count by the number of characters the for type argument
+                        // note that this count includes the "L" we added, but that is ok
+                        // as it accounts for the "." we didn't consume
+                        consumed_chars = unwrap(Utility.consumed_chars) + consumed_chars;
+                        wrap(Utility.consumed_chars, consumed_chars);
+                        return type.toString();
+                    }
+                    if (signature.charAt(consumed_chars) != ';') {
                         throw new ClassFormatException("Invalid signature: " + signature);
                     }
-                    wrap(Utility.consumed_chars, consumed_chars + 2); // remove final ">;"
-                    return type.append(">").toString();
+                    wrap(Utility.consumed_chars, consumed_chars + 1); // remove final ";"
+                    return type.toString();
                 }
                 case 'S':
                     return "short";
@@ -924,22 +975,20 @@
         }
     }
 
-    /**
-     * Parse Java type such as "char", or "java.lang.String[]" and return the
-     * signature in byte code format, e.g. "C" or "[Ljava/lang/String;"
-     * respectively.
+
+    /** Parse Java type such as "char", or "java.lang.String[]" and return the
+     * signature in byte code format, e.g. "C" or "[Ljava/lang/String;" respectively.
      *
-     * @param type Java type
+     * @param  type Java type
      * @return byte code signature
      */
-    public static String getSignature(String type) {
+    public static String getSignature( String type ) {
         final StringBuilder buf = new StringBuilder();
         final char[] chars = type.toCharArray();
         boolean char_found = false;
         boolean delim = false;
         int index = -1;
-        loop:
-        for (int i = 0; i < chars.length; i++) {
+        loop: for (int i = 0; i < chars.length; i++) {
             switch (chars[i]) {
                 case ' ':
                 case '\t':
@@ -985,7 +1034,8 @@
         return buf.toString();
     }
 
-    private static int countBrackets(final String brackets) {
+
+    private static int countBrackets( final String brackets ) {
         final char[] chars = brackets.toCharArray();
         int count = 0;
         boolean open = false;
@@ -1015,17 +1065,17 @@
         return count;
     }
 
+
     /**
-     * Return type of method signature as a byte value as defined in
-     * <em>Constants</em>
+     * Return type of method signature as a byte value as defined in <em>Constants</em>
      *
-     * @param signature in format described above
+     * @param  signature in format described above
      * @return type of method signature
-     * @see Const
+     * @see    Const
      *
      * @throws ClassFormatException if signature is not a method signature
      */
-    public static byte typeOfMethodSignature(final String signature) throws ClassFormatException {
+    public static byte typeOfMethodSignature( final String signature ) throws ClassFormatException {
         int index;
         try {
             if (signature.charAt(0) != '(') {
@@ -1038,16 +1088,17 @@
         }
     }
 
+
     /**
      * Return type of signature as a byte value as defined in <em>Constants</em>
      *
-     * @param signature in format described above
+     * @param  signature in format described above
      * @return type of signature
-     * @see Const
+     * @see    Const
      *
      * @throws ClassFormatException if signature isn't a known type
      */
-    public static byte typeOfSignature(final String signature) throws ClassFormatException {
+    public static byte typeOfSignature( final String signature ) throws ClassFormatException {
         try {
             switch (signature.charAt(0)) {
                 case 'B':
@@ -1085,11 +1136,10 @@
         }
     }
 
-    /**
-     * Map opcode names to opcode numbers. E.g., return Constants.ALOAD for
-     * "aload"
+
+    /** Map opcode names to opcode numbers. E.g., return Constants.ALOAD for "aload"
      */
-    public static short searchOpcode(String name) {
+    public static short searchOpcode( String name ) {
         name = name.toLowerCase(Locale.ENGLISH);
         for (short i = 0; i < Const.OPCODE_NAMES_LENGTH; i++) {
             if (Const.getOpcodeName(i).equals(name)) {
@@ -1099,22 +1149,23 @@
         return -1;
     }
 
+
     /**
      * Convert (signed) byte to (unsigned) short value, i.e., all negative
      * values become positive.
      */
-    private static short byteToShort(final byte b) {
+    private static short byteToShort( final byte b ) {
         return (b < 0) ? (short) (256 + b) : (short) b;
     }
 
-    /**
-     * Convert bytes into hexadecimal string
+
+    /** Convert bytes into hexadecimal string
      *
      * @param bytes an array of bytes to convert to hexadecimal
      *
      * @return bytes as hexadecimal string, e.g. 00 fa 12 ...
      */
-    public static String toHexString(final byte[] bytes) {
+    public static String toHexString( final byte[] bytes ) {
         final StringBuilder buf = new StringBuilder();
         for (int i = 0; i < bytes.length; i++) {
             final short b = byteToShort(bytes[i]);
@@ -1130,6 +1181,7 @@
         return buf.toString();
     }
 
+
     /**
      * Return a string for an integer justified left or right and filled up with
      * `fill' characters if necessary.
@@ -1140,14 +1192,13 @@
      * @param fill fill character
      * @return formatted int
      */
-    public static String format(final int i, final int length,
-            final boolean left_justify, final char fill) {
+    public static String format( final int i, final int length, final boolean left_justify, final char fill ) {
         return fillup(Integer.toString(i), length, left_justify, fill);
     }
 
+
     /**
-     * Fillup char with up to length characters with char `fill' and justify it
-     * left or right.
+     * Fillup char with up to length characters with char `fill' and justify it left or right.
      *
      * @param str string to format
      * @param length length of desired string
@@ -1155,8 +1206,7 @@
      * @param fill fill character
      * @return formatted string
      */
-    public static String fillup(final String str, final int length,
-            final boolean left_justify, final char fill) {
+    public static String fillup( final String str, final int length, final boolean left_justify, final char fill ) {
         final int len = length - str.length();
         final char[] buf = new char[(len < 0) ? 0 : len];
         for (int j = 0; j < buf.length; j++) {
@@ -1168,7 +1218,8 @@
         return new String(buf) + str;
     }
 
-    static boolean equals(final byte[] a, final byte[] b) {
+
+    static boolean equals( final byte[] a, final byte[] b ) {
         int size;
         if ((size = a.length) != b.length) {
             return false;
@@ -1181,23 +1232,28 @@
         return true;
     }
 
-    public static void printArray(final PrintStream out, final Object[] obj) {
+
+    public static void printArray( final PrintStream out, final Object[] obj ) {
         out.println(printArray(obj, true));
     }
 
-    public static void printArray(final PrintWriter out, final Object[] obj) {
+
+    public static void printArray( final PrintWriter out, final Object[] obj ) {
         out.println(printArray(obj, true));
     }
 
-    public static String printArray(final Object[] obj) {
+
+    public static String printArray( final Object[] obj ) {
         return printArray(obj, true);
     }
 
-    public static String printArray(final Object[] obj, final boolean braces) {
+
+    public static String printArray( final Object[] obj, final boolean braces ) {
         return printArray(obj, braces, false);
     }
 
-    public static String printArray(final Object[] obj, final boolean braces, final boolean quote) {
+
+    public static String printArray( final Object[] obj, final boolean braces, final boolean quote ) {
         if (obj == null) {
             return null;
         }
@@ -1221,32 +1277,32 @@
         return buf.toString();
     }
 
+
     /**
      * @param ch the character to test if it's part of an identifier
      *
      * @return true, if character is one of (a, ... z, A, ... Z, 0, ... 9, _)
      */
-    public static boolean isJavaIdentifierPart(final char ch) {
+    public static boolean isJavaIdentifierPart( final char ch ) {
         return ((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z'))
                 || ((ch >= '0') && (ch <= '9')) || (ch == '_');
     }
 
+
     /**
-     * Encode byte array it into Java identifier string, i.e., a string that
-     * only contains the following characters: (a, ... z, A, ... Z, 0, ... 9, _,
-     * $). The encoding algorithm itself is not too clever: if the current
-     * byte's ASCII value already is a valid Java identifier part, leave it as
-     * it is. Otherwise it writes the escape character($) followed by:
+     * Encode byte array it into Java identifier string, i.e., a string
+     * that only contains the following characters: (a, ... z, A, ... Z,
+     * 0, ... 9, _, $).  The encoding algorithm itself is not too
+     * clever: if the current byte's ASCII value already is a valid Java
+     * identifier part, leave it as it is. Otherwise it writes the
+     * escape character($) followed by:
      *
      * <ul>
-     * <li> the ASCII value as a hexadecimal string, if the value is not in the
-     * range 200..247</li>
-     * <li>a Java identifier char not used in a lowercase hexadecimal string, if
-     * the value is in the range 200..247</li>
+     *   <li> the ASCII value as a hexadecimal string, if the value is not in the range 200..247</li>
+     *   <li>a Java identifier char not used in a lowercase hexadecimal string, if the value is in the range 200..247</li>
      * </ul>
      *
-     * <p>
-     * This operation inflates the original byte array by roughly 40-50%</p>
+     * <p>This operation inflates the original byte array by roughly 40-50%</p>
      *
      * @param bytes the byte array to convert
      * @param compress use gzip to minimize string
@@ -1271,6 +1327,7 @@
         return caw.toString();
     }
 
+
     /**
      * Decode a string back to a byte array.
      *
@@ -1308,7 +1365,6 @@
     private static int[] CHAR_MAP = new int[FREE_CHARS];
     private static int[] MAP_CHAR = new int[256]; // Reverse map
     private static final char ESCAPE_CHAR = '$';
-
     static {
         int j = 0;
         for (int i = 'A'; i <= 'Z'; i++) {
@@ -1329,8 +1385,8 @@
     }
 
     /**
-     * Decode characters into bytes. Used by <a
-     * href="Utility.html#decode(java.lang.String, boolean)">decode()</a>
+     * Decode characters into bytes.
+     * Used by <a href="Utility.html#decode(java.lang.String, boolean)">decode()</a>
      */
     private static class JavaReader extends FilterReader {
 
@@ -1338,6 +1394,7 @@
             super(in);
         }
 
+
         @Override
         public int read() throws IOException {
             final int b = in.read();
@@ -1354,7 +1411,7 @@
                     return -1;
                 }
                 final char[] tmp = {
-                    (char) i, (char) j
+                        (char) i, (char) j
                 };
                 final int s = Integer.parseInt(new String(tmp), 16);
                 return s;
@@ -1362,8 +1419,9 @@
             return MAP_CHAR[i];
         }
 
+
         @Override
-        public int read(final char[] cbuf, final int off, final int len) throws IOException {
+        public int read( final char[] cbuf, final int off, final int len ) throws IOException {
             for (int i = 0; i < len; i++) {
                 cbuf[off + i] = (char) read();
             }
@@ -1372,8 +1430,8 @@
     }
 
     /**
-     * Encode bytes into valid java identifier characters. Used by <a
-     * href="Utility.html#encode(byte[], boolean)">encode()</a>
+     * Encode bytes into valid java identifier characters.
+     * Used by <a href="Utility.html#encode(byte[], boolean)">encode()</a>
      */
     private static class JavaWriter extends FilterWriter {
 
@@ -1381,8 +1439,9 @@
             super(out);
         }
 
+
         @Override
-        public void write(final int b) throws IOException {
+        public void write( final int b ) throws IOException {
             if (isJavaIdentifierPart((char) b) && (b != ESCAPE_CHAR)) {
                 out.write(b);
             } else {
@@ -1403,23 +1462,26 @@
             }
         }
 
+
         @Override
-        public void write(final char[] cbuf, final int off, final int len) throws IOException {
+        public void write( final char[] cbuf, final int off, final int len ) throws IOException {
             for (int i = 0; i < len; i++) {
                 write(cbuf[off + i]);
             }
         }
 
+
         @Override
-        public void write(final String str, final int off, final int len) throws IOException {
+        public void write( final String str, final int off, final int len ) throws IOException {
             write(str.toCharArray(), off, len);
         }
     }
 
+
     /**
      * Escape all occurences of newline chars '\n', quotes \", etc.
      */
-    public static String convertString(final String label) {
+    public static String convertString( final String label ) {
         final char[] ch = label.toCharArray();
         final StringBuilder buf = new StringBuilder();
         for (final char element : ch) {
@@ -1446,4 +1508,5 @@
         }
         return buf.toString();
     }
+
 }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Visitor.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Visitor.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,7 +26,7 @@
  * that implements this interface can traverse the contents of a Java class just
  * by calling the `accept' method which all classes have.
  *
- * @version $Id: Visitor.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public interface Visitor
 {
@@ -150,4 +150,21 @@
      * @since 6.0
      */
     void visitParameterAnnotationEntry(ParameterAnnotationEntry obj);
+
+    /**
+     * @since 6.1
+     */
+    void visitConstantPackage(ConstantPackage constantPackage);
+
+    /**
+     * @since 6.1
+     */
+    void visitConstantModule(ConstantModule constantModule);
+
+    /**
+     * @since 6.3
+     */
+    default void visitConstantDynamic(ConstantDynamic constantDynamic) {
+        // empty
+    }
 }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AALOAD.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AALOAD.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * AALOAD - Load reference from array
  * <PRE>Stack: ..., arrayref, index -&gt; value</PRE>
  *
- * @version $Id: AALOAD.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class AALOAD extends ArrayInstruction implements StackProducer {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AASTORE.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AASTORE.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * AASTORE -  Store into reference array
  * <PRE>Stack: ..., arrayref, index, value -&gt; ...</PRE>
  *
- * @version $Id: AASTORE.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class AASTORE extends ArrayInstruction implements StackConsumer {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ACONST_NULL.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ACONST_NULL.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * ACONST_NULL - Push null reference
  * <PRE>Stack: ... -&gt; ..., null</PRE>
  *
- * @version $Id: ACONST_NULL.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class ACONST_NULL extends Instruction implements PushInstruction, TypedInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ALOAD.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ALOAD.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,6 +1,5 @@
 /*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -27,18 +26,20 @@
  * ALOAD - Load reference from local variable
  * <PRE>Stack: ... -&gt; ..., objectref</PRE>
  *
- * @version $Id: ALOAD.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
+ * @LastModified: Jun 2019
  */
 public class ALOAD extends LoadInstruction {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     ALOAD() {
         super(Const.ALOAD, Const.ALOAD_0);
     }
 
+
     /** Load reference from local variable
      * @param n index of local variable
      */
@@ -46,6 +47,7 @@
         super(Const.ALOAD, Const.ALOAD_0, n);
     }
 
+
     /**
      * Call corresponding visitor method(s). The order is:
      * Call visitor methods of implemented interfaces first, then
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ANEWARRAY.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ANEWARRAY.java	Mon Jul 01 14:57:02 2019 -0700
@@ -27,14 +27,14 @@
  * ANEWARRAY -  Create new array of references
  * <PRE>Stack: ..., count -&gt; ..., arrayref</PRE>
  *
- * @version $Id: ANEWARRAY.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class ANEWARRAY extends CPInstruction implements LoadClass, AllocationInstruction,
         ExceptionThrower, StackConsumer, StackProducer {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     ANEWARRAY() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ARETURN.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ARETURN.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * ARETURN -  Return reference from method
  * <PRE>Stack: ..., objectref -&gt; &lt;empty&gt;</PRE>
  *
- * @version $Id: ARETURN.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class ARETURN extends ReturnInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ARRAYLENGTH.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ARRAYLENGTH.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -26,8 +26,8 @@
  * ARRAYLENGTH -  Get length of array
  * <PRE>Stack: ..., arrayref -&gt; ..., length</PRE>
  *
- * @version $Id: ARRAYLENGTH.java 1747278 2016-06-07 17:28:43Z britter $
- * @LastModified: Oct 2017
+ * @version $Id$
+ * @LastModified: Jun 2019
  */
 public class ARRAYLENGTH extends Instruction
     implements ExceptionThrower, StackProducer, StackConsumer /* since 6.0 */ {
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ASTORE.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ASTORE.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,6 +1,5 @@
 /*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -26,37 +25,38 @@
  * ASTORE - Store reference into local variable
  * <PRE>Stack ..., objectref -&gt; ... </PRE>
  *
- * @version $Id: ASTORE.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
+ * @LastModified: Jun 2019
  */
 public class ASTORE extends StoreInstruction {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     ASTORE() {
         super(Const.ASTORE, Const.ASTORE_0);
     }
 
-    /**
-     * Store reference into local variable
-     *
+
+    /** Store reference into local variable
      * @param n index of local variable
      */
     public ASTORE(final int n) {
         super(Const.ASTORE, Const.ASTORE_0, n);
     }
 
+
     /**
-     * Call corresponding visitor method(s). The order is: Call visitor methods
-     * of implemented interfaces first, then call methods according to the class
-     * hierarchy in descending order, i.e., the most specific visitXXX() call
-     * comes last.
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
      *
      * @param v Visitor object
      */
     @Override
-    public void accept(final Visitor v) {
+    public void accept( final Visitor v ) {
         super.accept(v);
         v.visitASTORE(this);
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ATHROW.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ATHROW.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -26,8 +26,8 @@
  * ATHROW -  Throw exception
  * <PRE>Stack: ..., objectref -&gt; objectref</PRE>
  *
- * @version $Id: ATHROW.java 1747278 2016-06-07 17:28:43Z britter $
- * @LastModified: Oct 2017
+ * @version $Id$
+ * @LastModified: Jun 2019
  */
 public class ATHROW extends Instruction implements UnconditionalBranch, ExceptionThrower {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AllocationInstruction.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AllocationInstruction.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,7 +24,7 @@
 /**
  * Denote family of instructions that allocates space in the heap.
  *
- * @version $Id: AllocationInstruction.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public interface AllocationInstruction {
 }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AnnotationEntryGen.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AnnotationEntryGen.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,6 +1,5 @@
 /*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -41,6 +40,7 @@
 
 /**
  * @since 6.0
+ * @LastModified: Jun 2019
  */
 public class AnnotationEntryGen {
     private int typeIndex;
@@ -263,8 +263,8 @@
 
             return newAttributes.toArray(new Attribute[newAttributes.size()]);
         } catch (final IOException e) {
-            System.err.println("IOException whilst processing annotations. " +
-                    e.getMessage());
+            System.err.println("IOException whilst processing annotations");
+            e.printStackTrace();
         }
         return null;
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArithmeticInstruction.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArithmeticInstruction.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,14 +26,14 @@
 /**
  * Super class for the family of arithmetic instructions.
  *
- * @version $Id: ArithmeticInstruction.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public abstract class ArithmeticInstruction extends Instruction implements TypedInstruction,
         StackProducer, StackConsumer {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     ArithmeticInstruction() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayInstruction.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayInstruction.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,14 +26,14 @@
 /**
  * Super class for instructions dealing with array access such as IALOAD.
  *
- * @version $Id: ArrayInstruction.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public abstract class ArrayInstruction extends Instruction implements ExceptionThrower,
         TypedInstruction {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     ArrayInstruction() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayType.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayType.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,13 +25,14 @@
 /**
  * Denotes array type, such as int[][]
  *
- * @version $Id: ArrayType.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
  */
 public final class ArrayType extends ReferenceType {
 
     private int dimensions;
     private Type basic_type;
 
+
     /**
      * Convenience constructor for array type, e.g. int[]
      *
@@ -41,6 +42,7 @@
         this(BasicType.getType(type), dimensions);
     }
 
+
     /**
      * Convenience constructor for reference array type, e.g. Object[]
      *
@@ -50,6 +52,7 @@
         this(ObjectType.getInstance(class_name), dimensions);
     }
 
+
     /**
      * Constructor for array of given type
      *
@@ -81,6 +84,7 @@
         super.setSignature(buf.toString());
     }
 
+
     /**
      * @return basic type of array, i.e., for int[][][] the basic type is int
      */
@@ -88,9 +92,9 @@
         return basic_type;
     }
 
+
     /**
-     * @return element type of array, i.e., for int[][][] the element type is
-     * int[][]
+     * @return element type of array, i.e., for int[][][] the element type is int[][]
      */
     public Type getElementType() {
         if (dimensions == 1) {
@@ -99,26 +103,26 @@
         return new ArrayType(basic_type, dimensions - 1);
     }
 
-    /**
-     * @return number of dimensions of array
+
+    /** @return number of dimensions of array
      */
     public int getDimensions() {
         return dimensions;
     }
 
-    /**
-     * @return a hash code value for the object.
+
+    /** @return a hash code value for the object.
      */
     @Override
     public int hashCode() {
         return basic_type.hashCode() ^ dimensions;
     }
 
-    /**
-     * @return true if both type objects refer to the same array type.
+
+    /** @return true if both type objects refer to the same array type.
      */
     @Override
-    public boolean equals(final Object _type) {
+    public boolean equals( final Object _type ) {
         if (_type instanceof ArrayType) {
             final ArrayType array = (ArrayType) _type;
             return (array.dimensions == dimensions) && array.basic_type.equals(basic_type);
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BALOAD.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BALOAD.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,27 +24,27 @@
  * BALOAD - Load byte or boolean from array
  * <PRE>Stack: ..., arrayref, index -&gt; ..., value</PRE>
  *
- * @version $Id: BALOAD.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class BALOAD extends ArrayInstruction implements StackProducer {
 
-    /**
-     * Load byte or boolean from array
+    /** Load byte or boolean from array
      */
     public BALOAD() {
         super(com.sun.org.apache.bcel.internal.Const.BALOAD);
     }
 
+
     /**
-     * Call corresponding visitor method(s). The order is: Call visitor methods
-     * of implemented interfaces first, then call methods according to the class
-     * hierarchy in descending order, i.e., the most specific visitXXX() call
-     * comes last.
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
      *
      * @param v Visitor object
      */
     @Override
-    public void accept(final Visitor v) {
+    public void accept( final Visitor v ) {
         v.visitStackProducer(this);
         v.visitExceptionThrower(this);
         v.visitTypedInstruction(this);
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BASTORE.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BASTORE.java	Mon Jul 01 14:57:02 2019 -0700
@@ -21,30 +21,30 @@
 package com.sun.org.apache.bcel.internal.generic;
 
 /**
- * BASTORE - Store into byte or boolean array
+ * BASTORE -  Store into byte or boolean array
  * <PRE>Stack: ..., arrayref, index, value -&gt; ...</PRE>
  *
- * @version $Id: BASTORE.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class BASTORE extends ArrayInstruction implements StackConsumer {
 
-    /**
-     * Store byte or boolean into array
+    /** Store byte or boolean into array
      */
     public BASTORE() {
         super(com.sun.org.apache.bcel.internal.Const.BASTORE);
     }
 
+
     /**
-     * Call corresponding visitor method(s). The order is: Call visitor methods
-     * of implemented interfaces first, then call methods according to the class
-     * hierarchy in descending order, i.e., the most specific visitXXX() call
-     * comes last.
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
      *
      * @param v Visitor object
      */
     @Override
-    public void accept(final Visitor v) {
+    public void accept( final Visitor v ) {
         v.visitStackConsumer(this);
         v.visitExceptionThrower(this);
         v.visitTypedInstruction(this);
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BIPUSH.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BIPUSH.java	Mon Jul 01 14:57:02 2019 -0700
@@ -29,76 +29,82 @@
  *
  * <PRE>Stack: ... -&gt; ..., value</PRE>
  *
- * @version $Id: BIPUSH.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class BIPUSH extends Instruction implements ConstantPushInstruction {
 
     private byte b;
 
+
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     BIPUSH() {
     }
 
-    /**
-     * Push byte on stack
+
+    /** Push byte on stack
      */
     public BIPUSH(final byte b) {
         super(com.sun.org.apache.bcel.internal.Const.BIPUSH, (short) 2);
         this.b = b;
     }
 
+
     /**
      * Dump instruction as byte code to stream out.
      */
     @Override
-    public void dump(final DataOutputStream out) throws IOException {
+    public void dump( final DataOutputStream out ) throws IOException {
         super.dump(out);
         out.writeByte(b);
     }
 
+
     /**
      * @return mnemonic for instruction
      */
     @Override
-    public String toString(final boolean verbose) {
+    public String toString( final boolean verbose ) {
         return super.toString(verbose) + " " + b;
     }
 
+
     /**
      * Read needed data (e.g. index) from file.
      */
     @Override
-    protected void initFromFile(final ByteSequence bytes, final boolean wide) throws IOException {
+    protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException {
         super.setLength(2);
         b = bytes.readByte();
     }
 
+
     @Override
     public Number getValue() {
         return Integer.valueOf(b);
     }
 
-    /**
-     * @return Type.BYTE
+
+    /** @return Type.BYTE
      */
     @Override
-    public Type getType(final ConstantPoolGen cp) {
+    public Type getType( final ConstantPoolGen cp ) {
         return Type.BYTE;
     }
 
+
     /**
-     * Call corresponding visitor method(s). The order is: Call visitor methods
-     * of implemented interfaces first, then call methods according to the class
-     * hierarchy in descending order, i.e., the most specific visitXXX() call
-     * comes last.
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
      *
      * @param v Visitor object
      */
     @Override
-    public void accept(final Visitor v) {
+    public void accept( final Visitor v ) {
         v.visitPushInstruction(this);
         v.visitStackProducer(this);
         v.visitTypedInstruction(this);
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BREAKPOINT.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BREAKPOINT.java	Mon Jul 01 14:57:02 2019 -0700
@@ -23,7 +23,7 @@
 /**
  * BREAKPOINT, JVM dependent, ignored by default
  *
- * @version $Id: BREAKPOINT.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class BREAKPOINT extends Instruction {
 
@@ -31,16 +31,17 @@
         super(com.sun.org.apache.bcel.internal.Const.BREAKPOINT, (short) 1);
     }
 
+
     /**
-     * Call corresponding visitor method(s). The order is: Call visitor methods
-     * of implemented interfaces first, then call methods according to the class
-     * hierarchy in descending order, i.e., the most specific visitXXX() call
-     * comes last.
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
      *
      * @param v Visitor object
      */
     @Override
-    public void accept(final Visitor v) {
+    public void accept( final Visitor v ) {
         v.visitBREAKPOINT(this);
     }
 }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BasicType.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BasicType.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
 /**
  * Denotes basic type such as int.
  *
- * @version $Id: BasicType.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public final class BasicType extends Type {
 
@@ -42,8 +42,9 @@
         }
     }
 
+
     // @since 6.0 no longer final
-    public static BasicType getType(final byte type) {
+    public static BasicType getType( final byte type ) {
         switch (type) {
             case Const.T_VOID:
                 return VOID;
@@ -68,19 +69,19 @@
         }
     }
 
-    /**
-     * @return a hash code value for the object.
+
+    /** @return a hash code value for the object.
      */
     @Override
     public int hashCode() {
         return super.getType();
     }
 
-    /**
-     * @return true if both type objects refer to the same type
+
+    /** @return true if both type objects refer to the same type
      */
     @Override
-    public boolean equals(final Object _type) {
+    public boolean equals( final Object _type ) {
         return (_type instanceof BasicType) ? ((BasicType) _type).getType() == this.getType() : false;
     }
 }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BranchHandle.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BranchHandle.java	Mon Jul 01 14:57:02 2019 -0700
@@ -23,13 +23,13 @@
 /**
  * BranchHandle is returned by specialized InstructionList.append() whenever a
  * BranchInstruction is appended. This is useful when the target of this
- * instruction is not known at time of creation and must be set later via
- * setTarget().
+ * instruction is not known at time of creation and must be set later
+ * via setTarget().
  *
  * @see InstructionHandle
  * @see Instruction
  * @see InstructionList
- * @version $Id: BranchHandle.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
  */
 public final class BranchHandle extends InstructionHandle {
 
@@ -37,33 +37,16 @@
     // See BCEL-273
     private BranchInstruction bi; // An alias in fact, but saves lots of casts
 
+
     private BranchHandle(final BranchInstruction i) {
         super(i);
         bi = i;
     }
 
-    /**
-     * Factory methods.
+    /** Factory method.
      */
-    private static BranchHandle bh_list = null; // List of reusable handles
-
-    static BranchHandle getBranchHandle(final BranchInstruction i) {
-        if (bh_list == null) {
-            return new BranchHandle(i);
-        }
-        final BranchHandle bh = bh_list;
-        bh_list = (BranchHandle) bh.getNext();
-        bh.setInstruction(i);
-        return bh;
-    }
-
-    /**
-     * Handle adds itself to the list of resuable handles.
-     */
-    @Override
-    protected void addHandle() {
-        super.setNext(bh_list);
-        bh_list = this;
+    static BranchHandle getBranchHandle( final BranchInstruction i ) {
+        return new BranchHandle(i);
     }
 
 
@@ -76,34 +59,39 @@
         return bi.getPosition();
     }
 
+
     @Override
-    void setPosition(final int pos) {
+    void setPosition( final int pos ) {
         // Original code: i_position = bi.position = pos;
         bi.setPosition(pos);
         super.setPosition(pos);
     }
 
+
     @Override
-    protected int updatePosition(final int offset, final int max_offset) {
+    protected int updatePosition( final int offset, final int max_offset ) {
         final int x = bi.updatePosition(offset, max_offset);
         super.setPosition(bi.getPosition());
         return x;
     }
 
+
     /**
      * Pass new target to instruction.
      */
-    public void setTarget(final InstructionHandle ih) {
+    public void setTarget( final InstructionHandle ih ) {
         bi.setTarget(ih);
     }
 
+
     /**
      * Update target of instruction.
      */
-    public void updateTarget(final InstructionHandle old_ih, final InstructionHandle new_ih) {
+    public void updateTarget( final InstructionHandle old_ih, final InstructionHandle new_ih ) {
         bi.updateTarget(old_ih, new_ih);
     }
 
+
     /**
      * @return target of instruction.
      */
@@ -111,12 +99,12 @@
         return bi.getTarget();
     }
 
+
     /**
-     * Set new contents. Old instruction is disposed and may not be used
-     * anymore.
+     * Set new contents. Old instruction is disposed and may not be used anymore.
      */
     @Override // This is only done in order to apply the additional type check; could be merged with super impl.
-    public void setInstruction(final Instruction i) { // TODO could be package-protected?
+    public void setInstruction( final Instruction i ) { // TODO could be package-protected?
         super.setInstruction(i);
         if (!(i instanceof BranchInstruction)) {
             throw new ClassGenException("Assigning " + i
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BranchInstruction.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BranchInstruction.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,6 +1,5 @@
 /*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -26,12 +25,13 @@
 import com.sun.org.apache.bcel.internal.util.ByteSequence;
 
 /**
- * Abstract super class for branching instructions like GOTO, IFEQ, etc.. Branch
- * instructions may have a variable length, namely GOTO, JSR, LOOKUPSWITCH and
- * TABLESWITCH.
+ * Abstract super class for branching instructions like GOTO, IFEQ, etc..
+ * Branch instructions may have a variable length, namely GOTO, JSR,
+ * LOOKUPSWITCH and TABLESWITCH.
  *
  * @see InstructionList
- * @version $Id: BranchInstruction.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
+ * @LastModified: Jun 2019
  */
 public abstract class BranchInstruction extends Instruction implements InstructionTargeter {
 
@@ -46,9 +46,8 @@
     BranchInstruction() {
     }
 
-    /**
-     * Common super constructor
-     *
+
+    /** Common super constructor
      * @param opcode Instruction opcode
      * @param target instruction to branch to
      */
@@ -57,13 +56,13 @@
         setTarget(target);
     }
 
+
     /**
      * Dump instruction as byte code to stream out.
-     *
      * @param out Output stream
      */
     @Override
-    public void dump(final DataOutputStream out) throws IOException {
+    public void dump( final DataOutputStream out ) throws IOException {
         out.writeByte(super.getOpcode());
         index = getTargetOffset();
         if (!isValidShort(index)) {
@@ -72,11 +71,12 @@
         out.writeShort(index); // May be negative, i.e., point backwards
     }
 
+
     /**
      * @param _target branch target
-     * @return the offset to `target' relative to this instruction
+     * @return the offset to  `target' relative to this instruction
      */
-    protected int getTargetOffset(final InstructionHandle _target) {
+    protected int getTargetOffset( final InstructionHandle _target ) {
         if (_target == null) {
             throw new ClassGenException("Target of " + super.toString(true)
                     + " is invalid null handle");
@@ -89,6 +89,7 @@
         return t - position;
     }
 
+
     /**
      * @return the offset to this instruction's target
      */
@@ -96,37 +97,36 @@
         return getTargetOffset(target);
     }
 
+
     /**
-     * Called by InstructionList.setPositions when setting the position for
-     * every instruction. In the presence of variable length instructions
-     * `setPositions' performs multiple passes over the instruction list to
-     * calculate the correct (byte) positions and offsets by calling this
-     * function.
+     * Called by InstructionList.setPositions when setting the position for every
+     * instruction. In the presence of variable length instructions `setPositions'
+     * performs multiple passes over the instruction list to calculate the
+     * correct (byte) positions and offsets by calling this function.
      *
-     * @param offset additional offset caused by preceding (variable length)
-     * instructions
-     * @param max_offset the maximum offset that may be caused by these
-     * instructions
-     * @return additional offset caused by possible change of this instruction's
-     * length
+     * @param offset additional offset caused by preceding (variable length) instructions
+     * @param max_offset the maximum offset that may be caused by these instructions
+     * @return additional offset caused by possible change of this instruction's length
      */
-    protected int updatePosition(final int offset, final int max_offset) {
+    protected int updatePosition( final int offset, final int max_offset ) {
         position += offset;
         return 0;
     }
 
+
     /**
      * Long output format:
      *
-     * &lt;position in byte code&gt; &lt;name of opcode&gt; "["&lt;opcode
-     * number&gt;"]" "("&lt;length of instruction&gt;")" "&lt;"&lt;target
-     * instruction&gt;"&gt;" "@"&lt;branch target offset&gt;
+     * &lt;position in byte code&gt;
+     * &lt;name of opcode&gt; "["&lt;opcode number&gt;"]"
+     * "("&lt;length of instruction&gt;")"
+     * "&lt;"&lt;target instruction&gt;"&gt;" "@"&lt;branch target offset&gt;
      *
      * @param verbose long/short format switch
      * @return mnemonic for instruction
      */
     @Override
-    public String toString(final boolean verbose) {
+    public String toString( final boolean verbose ) {
         final String s = super.toString(verbose);
         String t = "null";
         if (verbose) {
@@ -153,20 +153,22 @@
         return s + " -> " + t;
     }
 
+
     /**
-     * Read needed data (e.g. index) from file. Conversion to a
-     * InstructionHandle is done in InstructionList(byte[]).
+     * Read needed data (e.g. index) from file. Conversion to a InstructionHandle
+     * is done in InstructionList(byte[]).
      *
      * @param bytes input stream
      * @param wide wide prefix?
      * @see InstructionList
      */
     @Override
-    protected void initFromFile(final ByteSequence bytes, final boolean wide) throws IOException {
+    protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException {
         super.setLength(3);
         index = bytes.readShort();
     }
 
+
     /**
      * @return target offset in byte code
      */
@@ -174,6 +176,7 @@
         return index;
     }
 
+
     /**
      * @return target of branch instruction
      */
@@ -181,22 +184,22 @@
         return target;
     }
 
+
     /**
      * Set branch target
-     *
      * @param target branch target
      */
-    public void setTarget(final InstructionHandle target) {
+    public void setTarget( final InstructionHandle target ) {
         notifyTarget(this.target, target, this);
         this.target = target;
     }
 
+
     /**
-     * Used by BranchInstruction, LocalVariableGen, CodeExceptionGen,
-     * LineNumberGen
+     * Used by BranchInstruction, LocalVariableGen, CodeExceptionGen, LineNumberGen
      */
-    static void notifyTarget(final InstructionHandle old_ih, final InstructionHandle new_ih,
-            final InstructionTargeter t) {
+    static void notifyTarget( final InstructionHandle old_ih, final InstructionHandle new_ih,
+            final InstructionTargeter t ) {
         if (old_ih != null) {
             old_ih.removeTargeter(t);
         }
@@ -205,12 +208,13 @@
         }
     }
 
+
     /**
      * @param old_ih old target
      * @param new_ih new target
      */
     @Override
-    public void updateTarget(final InstructionHandle old_ih, final InstructionHandle new_ih) {
+    public void updateTarget( final InstructionHandle old_ih, final InstructionHandle new_ih ) {
         if (target == old_ih) {
             setTarget(new_ih);
         } else {
@@ -218,14 +222,16 @@
         }
     }
 
+
     /**
      * @return true, if ih is target of this instruction
      */
     @Override
-    public boolean containsTarget(final InstructionHandle ih) {
+    public boolean containsTarget( final InstructionHandle ih ) {
         return target == ih;
     }
 
+
     /**
      * Inform target that it's not targeted anymore.
      */
@@ -236,6 +242,7 @@
         position = -1;
     }
 
+
     /**
      * @return the position
      * @since 6.0
@@ -244,6 +251,7 @@
         return position;
     }
 
+
     /**
      * @param position the position to set
      * @since 6.0
@@ -252,6 +260,7 @@
         this.position = position;
     }
 
+
     /**
      * @param index the index to set
      * @since 6.0
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CALOAD.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CALOAD.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * CALOAD - Load char from array
  * <PRE>Stack: ..., arrayref, index -&gt; ..., value</PRE>
  *
- * @version $Id: CALOAD.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class CALOAD extends ArrayInstruction implements StackProducer {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CASTORE.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CASTORE.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * CASTORE -  Store into char array
  * <PRE>Stack: ..., arrayref, index, value -&gt; ...</PRE>
  *
- * @version $Id: CASTORE.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class CASTORE extends ArrayInstruction implements StackConsumer {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CHECKCAST.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CHECKCAST.java	Mon Jul 01 14:57:02 2019 -0700
@@ -27,14 +27,14 @@
  * CHECKCAST - Check whether object is of given type
  * <PRE>Stack: ..., objectref -&gt; ..., objectref</PRE>
  *
- * @version $Id: CHECKCAST.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class CHECKCAST extends CPInstruction implements LoadClass, ExceptionThrower, StackProducer,
         StackConsumer {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     CHECKCAST() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CPInstruction.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CPInstruction.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,6 +1,5 @@
 /*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -29,27 +28,30 @@
 import com.sun.org.apache.bcel.internal.util.ByteSequence;
 
 /**
- * Abstract super class for instructions that use an index into the constant
- * pool such as LDC, INVOKEVIRTUAL, etc.
+ * Abstract super class for instructions that use an index into the
+ * constant pool such as LDC, INVOKEVIRTUAL, etc.
  *
  * @see ConstantPoolGen
  * @see LDC
  * @see INVOKEVIRTUAL
  *
- * @version $Id: CPInstruction.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
+ * @LastModified: Jun 2019
  */
 public abstract class CPInstruction extends Instruction implements TypedInstruction,
         IndexedInstruction {
 
     private int index; // index to constant pool
 
+
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     CPInstruction() {
     }
 
+
     /**
      * @param index to constant pool
      */
@@ -58,36 +60,38 @@
         setIndex(index);
     }
 
+
     /**
      * Dump instruction as byte code to stream out.
-     *
      * @param out Output stream
      */
     @Override
-    public void dump(final DataOutputStream out) throws IOException {
+    public void dump( final DataOutputStream out ) throws IOException {
         out.writeByte(super.getOpcode());
         out.writeShort(index);
     }
 
+
     /**
      * Long output format:
      *
-     * &lt;name of opcode&gt; "["&lt;opcode number&gt;"]" "("&lt;length of
-     * instruction&gt;")" "&lt;"&lt; constant pool index&gt;"&gt;"
+     * &lt;name of opcode&gt; "["&lt;opcode number&gt;"]"
+     * "("&lt;length of instruction&gt;")" "&lt;"&lt; constant pool index&gt;"&gt;"
      *
      * @param verbose long/short format switch
      * @return mnemonic for instruction
      */
     @Override
-    public String toString(final boolean verbose) {
+    public String toString( final boolean verbose ) {
         return super.toString(verbose) + " " + index;
     }
 
+
     /**
      * @return mnemonic for instruction with symbolic references resolved
      */
     @Override
-    public String toString(final ConstantPool cp) {
+    public String toString( final ConstantPool cp ) {
         final Constant c = cp.getConstant(index);
         String str = cp.constantToString(c);
         if (c instanceof ConstantClass) {
@@ -96,18 +100,19 @@
         return com.sun.org.apache.bcel.internal.Const.getOpcodeName(super.getOpcode()) + " " + str;
     }
 
+
     /**
      * Read needed data (i.e., index) from file.
-     *
      * @param bytes input stream
      * @param wide wide prefix?
      */
     @Override
-    protected void initFromFile(final ByteSequence bytes, final boolean wide) throws IOException {
+    protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException {
         setIndex(bytes.readUnsignedShort());
         super.setLength(3);
     }
 
+
     /**
      * @return index in constant pool referred by this instruction.
      */
@@ -116,24 +121,24 @@
         return index;
     }
 
+
     /**
      * Set the index to constant pool.
-     *
-     * @param index in constant pool.
+     * @param index in  constant pool.
      */
     @Override
-    public void setIndex(final int index) { // TODO could be package-protected?
+    public void setIndex( final int index ) { // TODO could be package-protected?
         if (index < 0) {
             throw new ClassGenException("Negative index value: " + index);
         }
         this.index = index;
     }
 
-    /**
-     * @return type related with this instruction.
+
+    /** @return type related with this instruction.
      */
     @Override
-    public Type getType(final ConstantPoolGen cpg) {
+    public Type getType( final ConstantPoolGen cpg ) {
         final ConstantPool cp = cpg.getConstantPool();
         String name = cp.getConstantString(index, com.sun.org.apache.bcel.internal.Const.CONSTANT_Class);
         if (!name.startsWith("[")) {
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassGen.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassGen.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,6 +1,5 @@
 /*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -22,6 +21,7 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
 
 import com.sun.org.apache.bcel.internal.Const;
 import com.sun.org.apache.bcel.internal.classfile.AccessFlags;
@@ -42,7 +42,8 @@
  * existing java class (file).
  *
  * @see JavaClass
- * @version $Id: ClassGen.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
+ * @LastModified: Jun 2019
  */
 public class ClassGen extends AccessFlags implements Cloneable {
 
@@ -66,21 +67,22 @@
     private static BCELComparator _cmp = new BCELComparator() {
 
         @Override
-        public boolean equals(final Object o1, final Object o2) {
+        public boolean equals( final Object o1, final Object o2 ) {
             final ClassGen THIS = (ClassGen) o1;
             final ClassGen THAT = (ClassGen) o2;
-            return THIS.getClassName().equals(THAT.getClassName());
+            return Objects.equals(THIS.getClassName(), THAT.getClassName());
         }
 
+
         @Override
-        public int hashCode(final Object o) {
+        public int hashCode( final Object o ) {
             final ClassGen THIS = (ClassGen) o;
             return THIS.getClassName().hashCode();
         }
     };
 
-    /**
-     * Convenience constructor to set up some important values initially.
+
+    /** Convenience constructor to set up some important values initially.
      *
      * @param class_name fully qualified class name
      * @param super_class_name fully qualified superclass name
@@ -110,8 +112,8 @@
         }
     }
 
-    /**
-     * Convenience constructor to set up some important values initially.
+
+    /** Convenience constructor to set up some important values initially.
      *
      * @param class_name fully qualified class name
      * @param super_class_name fully qualified superclass name
@@ -125,9 +127,9 @@
                 new ConstantPoolGen());
     }
 
+
     /**
      * Initialize with existing class.
-     *
      * @param clazz JavaClass object (e.g. read from file)
      */
     public ClassGen(final JavaClass clazz) {
@@ -168,28 +170,34 @@
     /**
      * Look for attributes representing annotations and unpack them.
      */
-    private AnnotationEntryGen[] unpackAnnotations(final Attribute[] attrs) {
+    private AnnotationEntryGen[] unpackAnnotations(final Attribute[] attrs)
+    {
         final List<AnnotationEntryGen> annotationGenObjs = new ArrayList<>();
         for (final Attribute attr : attrs) {
-            if (attr instanceof RuntimeVisibleAnnotations) {
+            if (attr instanceof RuntimeVisibleAnnotations)
+            {
                 final RuntimeVisibleAnnotations rva = (RuntimeVisibleAnnotations) attr;
                 final AnnotationEntry[] annos = rva.getAnnotationEntries();
                 for (final AnnotationEntry a : annos) {
                     annotationGenObjs.add(new AnnotationEntryGen(a,
                             getConstantPool(), false));
                 }
-            } else if (attr instanceof RuntimeInvisibleAnnotations) {
-                final RuntimeInvisibleAnnotations ria = (RuntimeInvisibleAnnotations) attr;
-                final AnnotationEntry[] annos = ria.getAnnotationEntries();
-                for (final AnnotationEntry a : annos) {
-                    annotationGenObjs.add(new AnnotationEntryGen(a,
-                            getConstantPool(), false));
+            }
+            else
+                if (attr instanceof RuntimeInvisibleAnnotations)
+                {
+                    final RuntimeInvisibleAnnotations ria = (RuntimeInvisibleAnnotations) attr;
+                    final AnnotationEntry[] annos = ria.getAnnotationEntries();
+                    for (final AnnotationEntry a : annos) {
+                        annotationGenObjs.add(new AnnotationEntryGen(a,
+                                getConstantPool(), false));
+                    }
                 }
-            }
         }
         return annotationGenObjs.toArray(new AnnotationEntryGen[annotationGenObjs.size()]);
     }
 
+
     /**
      * @return the (finally) built up Java class object.
      */
@@ -197,15 +205,15 @@
         final int[] interfaces = getInterfaces();
         final Field[] fields = getFields();
         final Method[] methods = getMethods();
-        Attribute[] attributes;
+        Attribute[] attributes = null;
         if (annotation_vec.isEmpty()) {
             attributes = getAttributes();
         } else {
             // TODO: Sometime later, trash any attributes called 'RuntimeVisibleAnnotations' or 'RuntimeInvisibleAnnotations'
-            final Attribute[] annAttributes = AnnotationEntryGen.getAnnotationAttributes(cp, getAnnotationEntries());
-            attributes = new Attribute[attribute_vec.size() + annAttributes.length];
+            final Attribute[] annAttributes  = AnnotationEntryGen.getAnnotationAttributes(cp, getAnnotationEntries());
+            attributes = new Attribute[attribute_vec.size()+annAttributes.length];
             attribute_vec.toArray(attributes);
-            System.arraycopy(annAttributes, 0, attributes, attribute_vec.size(), annAttributes.length);
+            System.arraycopy(annAttributes,0,attributes,attribute_vec.size(),annAttributes.length);
         }
         // Must be last since the above calls may still add something to it
         final ConstantPool _cp = this.cp.getFinalConstantPool();
@@ -213,24 +221,25 @@
                 super.getAccessFlags(), _cp, interfaces, fields, methods, attributes);
     }
 
+
     /**
      * Add an interface to this class, i.e., this class has to implement it.
-     *
      * @param name interface to implement (fully qualified class name)
      */
-    public final void addInterface(final String name) {
+    public void addInterface( final String name ) {
         interface_vec.add(name);
     }
 
+
     /**
      * Remove an interface from this class.
-     *
      * @param name interface to remove (fully qualified name)
      */
-    public void removeInterface(final String name) {
+    public void removeInterface( final String name ) {
         interface_vec.remove(name);
     }
 
+
     /**
      * @return major version number of class file
      */
@@ -238,21 +247,19 @@
         return major;
     }
 
-    /**
-     * Set major version number of class file, default value is 45 (JDK 1.1)
-     *
+
+    /** Set major version number of class file, default value is 45 (JDK 1.1)
      * @param major major version number
      */
-    public void setMajor(final int major) { // TODO could be package-protected - only called by test code
+    public void setMajor( final int major ) { // TODO could be package-protected - only called by test code
         this.major = major;
     }
 
-    /**
-     * Set minor version number of class file, default value is 3 (JDK 1.1)
-     *
+
+    /** Set minor version number of class file, default value is 3 (JDK 1.1)
      * @param minor minor version number
      */
-    public void setMinor(final int minor) {  // TODO could be package-protected - only called by test code
+    public void setMinor( final int minor ) {  // TODO could be package-protected - only called by test code
         this.minor = minor;
     }
 
@@ -263,37 +270,36 @@
         return minor;
     }
 
+
     /**
      * Add an attribute to this class.
-     *
      * @param a attribute to add
      */
-    public final void addAttribute(final Attribute a) {
+    public void addAttribute( final Attribute a ) {
         attribute_vec.add(a);
     }
 
-    public final void addAnnotationEntry(final AnnotationEntryGen a) {
+    public void addAnnotationEntry(final AnnotationEntryGen a) {
         annotation_vec.add(a);
     }
 
+
     /**
      * Add a method to this class.
-     *
      * @param m method to add
      */
-    public final void addMethod(final Method m) {
+    public void addMethod( final Method m ) {
         method_vec.add(m);
     }
 
+
     /**
      * Convenience method.
      *
-     * Add an empty constructor to this class that does nothing but calling
-     * super().
-     *
+     * Add an empty constructor to this class that does nothing but calling super().
      * @param access_flags rights for constructor
      */
-    public void addEmptyConstructor(final int access_flags) {
+    public void addEmptyConstructor( final int access_flags ) {
         final InstructionList il = new InstructionList();
         il.append(InstructionConst.THIS); // Push `this'
         il.append(new INVOKESPECIAL(cp.addMethodref(super_class_name, "<init>", "()V")));
@@ -304,23 +310,24 @@
         addMethod(mg.getMethod());
     }
 
+
     /**
      * Add a field to this class.
-     *
      * @param f field to add
      */
-    public final void addField(final Field f) {
+    public void addField( final Field f ) {
         field_vec.add(f);
     }
 
-    public boolean containsField(final Field f) {
+
+    public boolean containsField( final Field f ) {
         return field_vec.contains(f);
     }
 
-    /**
-     * @return field object with given name, or null
+
+    /** @return field object with given name, or null
      */
-    public Field containsField(final String name) {
+    public Field containsField( final String name ) {
         for (final Field f : field_vec) {
             if (f.getName().equals(name)) {
                 return f;
@@ -329,10 +336,10 @@
         return null;
     }
 
-    /**
-     * @return method object with given name and signature, or null
+
+    /** @return method object with given name and signature, or null
      */
-    public Method containsMethod(final String name, final String signature) {
+    public Method containsMethod( final String name, final String signature ) {
         for (final Method m : method_vec) {
             if (m.getName().equals(name) && m.getSignature().equals(signature)) {
                 return m;
@@ -341,29 +348,29 @@
         return null;
     }
 
+
     /**
      * Remove an attribute from this class.
-     *
      * @param a attribute to remove
      */
-    public void removeAttribute(final Attribute a) {
+    public void removeAttribute( final Attribute a ) {
         attribute_vec.remove(a);
     }
 
+
     /**
      * Remove a method from this class.
-     *
      * @param m method to remove
      */
-    public void removeMethod(final Method m) {
+    public void removeMethod( final Method m ) {
         method_vec.remove(m);
     }
 
-    /**
-     * Replace given method with new one. If the old one does not exist add the
-     * new_ method to the class anyway.
+
+    /** Replace given method with new one. If the old one does not exist
+     * add the new_ method to the class anyway.
      */
-    public void replaceMethod(final Method old, final Method new_) {
+    public void replaceMethod( final Method old, final Method new_ ) {
         if (new_ == null) {
             throw new ClassGenException("Replacement method must not be null");
         }
@@ -375,11 +382,11 @@
         }
     }
 
-    /**
-     * Replace given field with new one. If the old one does not exist add the
-     * new_ field to the class anyway.
+
+    /** Replace given field with new one. If the old one does not exist
+     * add the new_ field to the class anyway.
      */
-    public void replaceField(final Field old, final Field new_) {
+    public void replaceField( final Field old, final Field new_ ) {
         if (new_ == null) {
             throw new ClassGenException("Replacement method must not be null");
         }
@@ -391,56 +398,66 @@
         }
     }
 
+
     /**
      * Remove a field to this class.
-     *
      * @param f field to remove
      */
-    public void removeField(final Field f) {
+    public void removeField( final Field f ) {
         field_vec.remove(f);
     }
 
+
     public String getClassName() {
         return class_name;
     }
 
+
     public String getSuperclassName() {
         return super_class_name;
     }
 
+
     public String getFileName() {
         return file_name;
     }
 
-    public void setClassName(final String name) {
+
+    public void setClassName( final String name ) {
         class_name = name.replace('/', '.');
         class_name_index = cp.addClass(name);
     }
 
-    public void setSuperclassName(final String name) {
+
+    public void setSuperclassName( final String name ) {
         super_class_name = name.replace('/', '.');
         superclass_name_index = cp.addClass(name);
     }
 
+
     public Method[] getMethods() {
         return method_vec.toArray(new Method[method_vec.size()]);
     }
 
-    public void setMethods(final Method[] methods) {
+
+    public void setMethods( final Method[] methods ) {
         method_vec.clear();
         for (final Method method : methods) {
             addMethod(method);
         }
     }
 
-    public void setMethodAt(final Method method, final int pos) {
+
+    public void setMethodAt( final Method method, final int pos ) {
         method_vec.set(pos, method);
     }
 
-    public Method getMethodAt(final int pos) {
+
+    public Method getMethodAt( final int pos ) {
         return method_vec.get(pos);
     }
 
+
     public String[] getInterfaceNames() {
         final int size = interface_vec.size();
         final String[] interfaces = new String[size];
@@ -448,6 +465,7 @@
         return interfaces;
     }
 
+
     public int[] getInterfaces() {
         final int size = interface_vec.size();
         final int[] interfaces = new int[size];
@@ -457,10 +475,12 @@
         return interfaces;
     }
 
+
     public Field[] getFields() {
         return field_vec.toArray(new Field[field_vec.size()]);
     }
 
+
     public Attribute[] getAttributes() {
         return attribute_vec.toArray(new Attribute[attribute_vec.size()]);
     }
@@ -470,59 +490,65 @@
         return annotation_vec.toArray(new AnnotationEntryGen[annotation_vec.size()]);
     }
 
+
     public ConstantPoolGen getConstantPool() {
         return cp;
     }
 
-    public void setConstantPool(final ConstantPoolGen constant_pool) {
+
+    public void setConstantPool( final ConstantPoolGen constant_pool ) {
         cp = constant_pool;
     }
 
-    public void setClassNameIndex(final int class_name_index) {
+
+    public void setClassNameIndex( final int class_name_index ) {
         this.class_name_index = class_name_index;
         class_name = cp.getConstantPool().getConstantString(class_name_index,
                 Const.CONSTANT_Class).replace('/', '.');
     }
 
-    public void setSuperclassNameIndex(final int superclass_name_index) {
+
+    public void setSuperclassNameIndex( final int superclass_name_index ) {
         this.superclass_name_index = superclass_name_index;
         super_class_name = cp.getConstantPool().getConstantString(superclass_name_index,
                 Const.CONSTANT_Class).replace('/', '.');
     }
 
+
     public int getSuperclassNameIndex() {
         return superclass_name_index;
     }
 
+
     public int getClassNameIndex() {
         return class_name_index;
     }
 
     private List<ClassObserver> observers;
 
-    /**
-     * Add observer for this object.
+
+    /** Add observer for this object.
      */
-    public void addObserver(final ClassObserver o) {
+    public void addObserver( final ClassObserver o ) {
         if (observers == null) {
             observers = new ArrayList<>();
         }
         observers.add(o);
     }
 
-    /**
-     * Remove observer for this object.
+
+    /** Remove observer for this object.
      */
-    public void removeObserver(final ClassObserver o) {
+    public void removeObserver( final ClassObserver o ) {
         if (observers != null) {
             observers.remove(o);
         }
     }
 
-    /**
-     * Call notify() method on all observers. This method is not called
-     * automatically whenever the state has changed, but has to be called by the
-     * user after he has finished editing the object.
+
+    /** Call notify() method on all observers. This method is not called
+     * automatically whenever the state has changed, but has to be
+     * called by the user after he has finished editing the object.
      */
     public void update() {
         if (observers != null) {
@@ -532,6 +558,7 @@
         }
     }
 
+
     @Override
     public Object clone() {
         try {
@@ -541,6 +568,7 @@
         }
     }
 
+
     /**
      * @return Comparison strategy object
      */
@@ -548,27 +576,31 @@
         return _cmp;
     }
 
+
     /**
      * @param comparator Comparison strategy object
      */
-    public static void setComparator(final BCELComparator comparator) {
+    public static void setComparator( final BCELComparator comparator ) {
         _cmp = comparator;
     }
 
+
     /**
-     * Return value as defined by given BCELComparator strategy. By default two
-     * ClassGen objects are said to be equal when their class names are equal.
+     * Return value as defined by given BCELComparator strategy.
+     * By default two ClassGen objects are said to be equal when
+     * their class names are equal.
      *
      * @see java.lang.Object#equals(java.lang.Object)
      */
     @Override
-    public boolean equals(final Object obj) {
+    public boolean equals( final Object obj ) {
         return _cmp.equals(this, obj);
     }
 
+
     /**
-     * Return value as defined by given BCELComparator strategy. By default
-     * return the hashcode of the class name.
+     * Return value as defined by given BCELComparator strategy.
+     * By default return the hashcode of the class name.
      *
      * @see java.lang.Object#hashCode()
      */
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassGenException.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassGenException.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * Thrown on internal errors. Extends RuntimeException so it hasn't to be declared
  * in the throws clause every time.
  *
- * @version $Id: ClassGenException.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class ClassGenException extends RuntimeException {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassObserver.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassObserver.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * Implement this interface if you're interested in changes to a ClassGen object
  * and register yourself with addObserver().
  *
- * @version $Id: ClassObserver.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public interface ClassObserver {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CodeExceptionGen.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CodeExceptionGen.java	Mon Jul 01 14:57:02 2019 -0700
@@ -23,7 +23,7 @@
 import com.sun.org.apache.bcel.internal.classfile.CodeException;
 
 /**
- * This class represents an exception handler, i.e., specifies the region where
+ * This class represents an exception handler, i.e., specifies the  region where
  * a handler is active and an instruction where the actual handling is done.
  * pool as parameters. Opposed to the JVM specification the end of the handled
  * region is set to be inclusive, i.e. all instructions between start and end
@@ -31,10 +31,10 @@
  * The end of the region is automatically mapped to be exclusive when calling
  * getCodeException(), i.e., there is no difference semantically.
  *
- * @version $Id: CodeExceptionGen.java 1749603 2016-06-21 20:50:19Z ggregory $
- * @see MethodGen
- * @see CodeException
- * @see InstructionHandle
+ * @version $Id$
+ * @see     MethodGen
+ * @see     CodeException
+ * @see     InstructionHandle
  */
 public final class CodeExceptionGen implements InstructionTargeter, Cloneable {
 
@@ -43,9 +43,10 @@
     private InstructionHandle handler_pc;
     private ObjectType catch_type;
 
+
     /**
-     * Add an exception handler, i.e., specify region where a handler is active
-     * and an instruction where the actual handling is done.
+     * Add an exception handler, i.e., specify region where a handler is active and an
+     * instruction where the actual handling is done.
      *
      * @param start_pc Start of handled region (inclusive)
      * @param end_pc End of handled region (inclusive)
@@ -60,16 +61,17 @@
         this.catch_type = catch_type;
     }
 
+
     /**
      * Get CodeException object.<BR>
      *
-     * This relies on that the instruction list has already been dumped to byte
-     * code or or that the `setPositions' methods has been called for the
-     * instruction list.
+     * This relies on that the instruction list has already been dumped
+     * to byte code or or that the `setPositions' methods has been
+     * called for the instruction list.
      *
      * @param cp constant pool
      */
-    public CodeException getCodeException(final ConstantPoolGen cp) {
+    public CodeException getCodeException( final ConstantPoolGen cp ) {
         return new CodeException(start_pc.getPosition(), end_pc.getPosition()
                 + end_pc.getInstruction().getLength(), handler_pc.getPosition(),
                 (catch_type == null) ? 0 : cp.addClass(catch_type));
@@ -79,7 +81,7 @@
     /* Set start of handler
      * @param start_pc Start of handled region (inclusive)
      */
-    public void setStartPC(final InstructionHandle start_pc) { // TODO could be package-protected?
+    public void setStartPC( final InstructionHandle start_pc ) { // TODO could be package-protected?
         BranchInstruction.notifyTarget(this.start_pc, start_pc, this);
         this.start_pc = start_pc;
     }
@@ -88,7 +90,7 @@
     /* Set end of handler
      * @param end_pc End of handled region (inclusive)
      */
-    public void setEndPC(final InstructionHandle end_pc) { // TODO could be package-protected?
+    public void setEndPC( final InstructionHandle end_pc ) { // TODO could be package-protected?
         BranchInstruction.notifyTarget(this.end_pc, end_pc, this);
         this.end_pc = end_pc;
     }
@@ -97,17 +99,18 @@
     /* Set handler code
      * @param handler_pc Start of handler
      */
-    public void setHandlerPC(final InstructionHandle handler_pc) { // TODO could be package-protected?
+    public void setHandlerPC( final InstructionHandle handler_pc ) { // TODO could be package-protected?
         BranchInstruction.notifyTarget(this.handler_pc, handler_pc, this);
         this.handler_pc = handler_pc;
     }
 
+
     /**
      * @param old_ih old target, either start or end
      * @param new_ih new target
      */
     @Override
-    public void updateTarget(final InstructionHandle old_ih, final InstructionHandle new_ih) {
+    public void updateTarget( final InstructionHandle old_ih, final InstructionHandle new_ih ) {
         boolean targeted = false;
         if (start_pc == old_ih) {
             targeted = true;
@@ -127,54 +130,55 @@
         }
     }
 
+
     /**
      * @return true, if ih is target of this handler
      */
     @Override
-    public boolean containsTarget(final InstructionHandle ih) {
+    public boolean containsTarget( final InstructionHandle ih ) {
         return (start_pc == ih) || (end_pc == ih) || (handler_pc == ih);
     }
 
-    /**
-     * Sets the type of the Exception to catch. Set 'null' for ANY.
-     */
-    public void setCatchType(final ObjectType catch_type) {
+
+    /** Sets the type of the Exception to catch. Set 'null' for ANY. */
+    public void setCatchType( final ObjectType catch_type ) {
         this.catch_type = catch_type;
     }
 
-    /**
-     * Gets the type of the Exception to catch, 'null' for ANY.
-     */
+
+    /** Gets the type of the Exception to catch, 'null' for ANY. */
     public ObjectType getCatchType() {
         return catch_type;
     }
 
-    /**
-     * @return start of handled region (inclusive)
+
+    /** @return start of handled region (inclusive)
      */
     public InstructionHandle getStartPC() {
         return start_pc;
     }
 
-    /**
-     * @return end of handled region (inclusive)
+
+    /** @return end of handled region (inclusive)
      */
     public InstructionHandle getEndPC() {
         return end_pc;
     }
 
-    /**
-     * @return start of handler
+
+    /** @return start of handler
      */
     public InstructionHandle getHandlerPC() {
         return handler_pc;
     }
 
+
     @Override
     public String toString() {
         return "CodeExceptionGen(" + start_pc + ", " + end_pc + ", " + handler_pc + ")";
     }
 
+
     @Override
     public Object clone() {
         try {
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CompoundInstruction.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CompoundInstruction.java	Mon Jul 01 14:57:02 2019 -0700
@@ -32,7 +32,7 @@
  * The interface provides the possibilty for the user to write
  * `templates' or `macros' for such reuseable code patterns.
  *
- * @version $Id: CompoundInstruction.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  * @see PUSH
  * @see SWITCH
  */
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConstantPoolGen.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConstantPoolGen.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -40,16 +40,18 @@
 import com.sun.org.apache.bcel.internal.classfile.ConstantUtf8;
 
 /**
- * This class is used to build up a constant pool. The user adds constants via
- * `addXXX' methods, `addString', `addClass', etc.. These methods return an
- * index into the constant pool. Finally, `getFinalConstantPool()' returns the
- * constant pool built up. Intermediate versions of the constant pool can be
+ * This class is used to build up a constant pool. The user adds
+ * constants via `addXXX' methods, `addString', `addClass',
+ * etc.. These methods return an index into the constant
+ * pool. Finally, `getFinalConstantPool()' returns the constant pool
+ * built up. Intermediate versions of the constant pool can be
  * obtained with `getConstantPool()'. A constant pool has capacity for
- * Constants.MAX_SHORT entries. Note that the first (0) is used by the JVM and
- * that Double and Long constants need two slots.
+ * Constants.MAX_SHORT entries. Note that the first (0) is used by the
+ * JVM and that Double and Long constants need two slots.
  *
- * @version $Id: ConstantPoolGen.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
  * @see Constant
+ * @LastModified: Jun 2019
  */
 public class ConstantPoolGen {
 
@@ -67,11 +69,13 @@
 
         final int index;
 
+
         Index(final int i) {
             index = i;
         }
     }
 
+
     /**
      * Initialize with given array of constants.
      *
@@ -88,6 +92,7 @@
             index = cs.length;
         }
 
+
         for (int i = 1; i < index; i++) {
             final Constant c = constants[i];
             if (c instanceof ConstantString) {
@@ -134,7 +139,7 @@
                     // since name can't begin with digit, can  use
                     // METHODREF_DELIM with out fear of duplicates.
                 } else {
-                    final ConstantClass clazz = (ConstantClass) constants[m.getClassIndex()];
+                final ConstantClass clazz = (ConstantClass) constants[m.getClassIndex()];
                     u8 = (ConstantUtf8) constants[clazz.getNameIndex()];
                     class_name = u8.getBytes().replace('/', '.');
                 }
@@ -183,6 +188,7 @@
         }
     }
 
+
     /**
      * Initialize with given constant pool.
      */
@@ -190,6 +196,7 @@
         this(cp.getConstantPool());
     }
 
+
     /**
      * Create empty constant pool.
      */
@@ -198,8 +205,8 @@
         constants = new Constant[size];
     }
 
-    /**
-     * Resize internal array of constants.
+
+    /** Resize internal array of constants.
      */
     protected void adjustSize() {
         if (index + 3 >= size) {
@@ -212,25 +219,26 @@
 
     private final Map<String, Index> string_table = new HashMap<>();
 
+
     /**
      * Look for ConstantString in ConstantPool containing String `str'.
      *
      * @param str String to search for
      * @return index on success, -1 otherwise
      */
-    public int lookupString(final String str) {
+    public int lookupString( final String str ) {
         final Index index = string_table.get(str);
         return (index != null) ? index.index : -1;
     }
 
+
     /**
-     * Add a new String constant to the ConstantPool, if it is not already in
-     * there.
+     * Add a new String constant to the ConstantPool, if it is not already in there.
      *
      * @param str String to add
      * @return index of entry
      */
-    public int addString(final String str) {
+    public int addString( final String str ) {
         int ret;
         if ((ret = lookupString(str)) != -1) {
             return ret; // Already in CP
@@ -248,18 +256,20 @@
 
     private final Map<String, Index> class_table = new HashMap<>();
 
+
     /**
      * Look for ConstantClass in ConstantPool named `str'.
      *
      * @param str String to search for
      * @return index on success, -1 otherwise
      */
-    public int lookupClass(final String str) {
+    public int lookupClass( final String str ) {
         final Index index = class_table.get(str.replace('.', '/'));
         return (index != null) ? index.index : -1;
     }
 
-    private int addClass_(final String clazz) {
+
+    private int addClass_( final String clazz ) {
         int ret;
         if ((ret = lookupClass(clazz)) != -1) {
             return ret; // Already in CP
@@ -274,45 +284,48 @@
         return ret;
     }
 
+
     /**
-     * Add a new Class reference to the ConstantPool, if it is not already in
-     * there.
+     * Add a new Class reference to the ConstantPool, if it is not already in there.
      *
      * @param str Class to add
      * @return index of entry
      */
-    public int addClass(final String str) {
+    public int addClass( final String str ) {
         return addClass_(str.replace('.', '/'));
     }
 
+
     /**
      * Add a new Class reference to the ConstantPool for a given type.
      *
      * @param type Class to add
      * @return index of entry
      */
-    public int addClass(final ObjectType type) {
+    public int addClass( final ObjectType type ) {
         return addClass(type.getClassName());
     }
 
+
     /**
-     * Add a reference to an array class (e.g. String[][]) as needed by
-     * MULTIANEWARRAY instruction, e.g. to the ConstantPool.
+     * Add a reference to an array class (e.g. String[][]) as needed by MULTIANEWARRAY
+     * instruction, e.g. to the ConstantPool.
      *
      * @param type type of array class
      * @return index of entry
      */
-    public int addArrayClass(final ArrayType type) {
+    public int addArrayClass( final ArrayType type ) {
         return addClass_(type.getSignature());
     }
 
+
     /**
      * Look for ConstantInteger in ConstantPool.
      *
      * @param n integer number to look for
      * @return index on success, -1 otherwise
      */
-    public int lookupInteger(final int n) {
+    public int lookupInteger( final int n ) {
         for (int i = 1; i < index; i++) {
             if (constants[i] instanceof ConstantInteger) {
                 final ConstantInteger c = (ConstantInteger) constants[i];
@@ -324,14 +337,14 @@
         return -1;
     }
 
+
     /**
-     * Add a new Integer constant to the ConstantPool, if it is not already in
-     * there.
+     * Add a new Integer constant to the ConstantPool, if it is not already in there.
      *
      * @param n integer number to add
      * @return index of entry
      */
-    public int addInteger(final int n) {
+    public int addInteger( final int n ) {
         int ret;
         if ((ret = lookupInteger(n)) != -1) {
             return ret; // Already in CP
@@ -342,13 +355,14 @@
         return ret;
     }
 
+
     /**
      * Look for ConstantFloat in ConstantPool.
      *
      * @param n Float number to look for
      * @return index on success, -1 otherwise
      */
-    public int lookupFloat(final float n) {
+    public int lookupFloat( final float n ) {
         final int bits = Float.floatToIntBits(n);
         for (int i = 1; i < index; i++) {
             if (constants[i] instanceof ConstantFloat) {
@@ -361,14 +375,14 @@
         return -1;
     }
 
+
     /**
-     * Add a new Float constant to the ConstantPool, if it is not already in
-     * there.
+     * Add a new Float constant to the ConstantPool, if it is not already in there.
      *
      * @param n Float number to add
      * @return index of entry
      */
-    public int addFloat(final float n) {
+    public int addFloat( final float n ) {
         int ret;
         if ((ret = lookupFloat(n)) != -1) {
             return ret; // Already in CP
@@ -381,25 +395,26 @@
 
     private final Map<String, Index> utf8_table = new HashMap<>();
 
+
     /**
      * Look for ConstantUtf8 in ConstantPool.
      *
      * @param n Utf8 string to look for
      * @return index on success, -1 otherwise
      */
-    public int lookupUtf8(final String n) {
+    public int lookupUtf8( final String n ) {
         final Index index = utf8_table.get(n);
         return (index != null) ? index.index : -1;
     }
 
+
     /**
-     * Add a new Utf8 constant to the ConstantPool, if it is not already in
-     * there.
+     * Add a new Utf8 constant to the ConstantPool, if it is not already in there.
      *
      * @param n Utf8 string to add
      * @return index of entry
      */
-    public int addUtf8(final String n) {
+    public int addUtf8( final String n ) {
         int ret;
         if ((ret = lookupUtf8(n)) != -1) {
             return ret; // Already in CP
@@ -413,13 +428,14 @@
         return ret;
     }
 
+
     /**
      * Look for ConstantLong in ConstantPool.
      *
      * @param n Long number to look for
      * @return index on success, -1 otherwise
      */
-    public int lookupLong(final long n) {
+    public int lookupLong( final long n ) {
         for (int i = 1; i < index; i++) {
             if (constants[i] instanceof ConstantLong) {
                 final ConstantLong c = (ConstantLong) constants[i];
@@ -431,14 +447,14 @@
         return -1;
     }
 
+
     /**
-     * Add a new long constant to the ConstantPool, if it is not already in
-     * there.
+     * Add a new long constant to the ConstantPool, if it is not already in there.
      *
      * @param n Long number to add
      * @return index of entry
      */
-    public int addLong(final long n) {
+    public int addLong( final long n ) {
         int ret;
         if ((ret = lookupLong(n)) != -1) {
             return ret; // Already in CP
@@ -450,13 +466,14 @@
         return ret;
     }
 
+
     /**
      * Look for ConstantDouble in ConstantPool.
      *
      * @param n Double number to look for
      * @return index on success, -1 otherwise
      */
-    public int lookupDouble(final double n) {
+    public int lookupDouble( final double n ) {
         final long bits = Double.doubleToLongBits(n);
         for (int i = 1; i < index; i++) {
             if (constants[i] instanceof ConstantDouble) {
@@ -469,14 +486,14 @@
         return -1;
     }
 
+
     /**
-     * Add a new double constant to the ConstantPool, if it is not already in
-     * there.
+     * Add a new double constant to the ConstantPool, if it is not already in there.
      *
      * @param n Double number to add
      * @return index of entry
      */
-    public int addDouble(final double n) {
+    public int addDouble( final double n ) {
         int ret;
         if ((ret = lookupDouble(n)) != -1) {
             return ret; // Already in CP
@@ -490,6 +507,7 @@
 
     private final Map<String, Index> n_a_t_table = new HashMap<>();
 
+
     /**
      * Look for ConstantNameAndType in ConstantPool.
      *
@@ -497,11 +515,12 @@
      * @param signature of variable/method
      * @return index on success, -1 otherwise
      */
-    public int lookupNameAndType(final String name, final String signature) {
+    public int lookupNameAndType( final String name, final String signature ) {
         final Index _index = n_a_t_table.get(name + NAT_DELIM + signature);
         return (_index != null) ? _index.index : -1;
     }
 
+
     /**
      * Add a new NameAndType constant to the ConstantPool if it is not already
      * in there.
@@ -510,7 +529,7 @@
      * @param signature signature string to add
      * @return index of entry
      */
-    public int addNameAndType(final String name, final String signature) {
+    public int addNameAndType( final String name, final String signature ) {
         int ret;
         int name_index;
         int signature_index;
@@ -531,6 +550,7 @@
 
     private final Map<String, Index> cp_table = new HashMap<>();
 
+
     /**
      * Look for ConstantMethodref in ConstantPool.
      *
@@ -539,26 +559,28 @@
      * @param signature return and argument types
      * @return index on success, -1 otherwise
      */
-    public int lookupMethodref(final String class_name, final String method_name, final String signature) {
+    public int lookupMethodref( final String class_name, final String method_name, final String signature ) {
         final Index index = cp_table.get(class_name + METHODREF_DELIM + method_name
                 + METHODREF_DELIM + signature);
         return (index != null) ? index.index : -1;
     }
 
-    public int lookupMethodref(final MethodGen method) {
+
+    public int lookupMethodref( final MethodGen method ) {
         return lookupMethodref(method.getClassName(), method.getName(), method.getSignature());
     }
 
+
     /**
-     * Add a new Methodref constant to the ConstantPool, if it is not already in
-     * there.
+     * Add a new Methodref constant to the ConstantPool, if it is not already
+     * in there.
      *
      * @param class_name class name string to add
      * @param method_name method name string to add
      * @param signature method signature string to add
      * @return index of entry
      */
-    public int addMethodref(final String class_name, final String method_name, final String signature) {
+    public int addMethodref( final String class_name, final String method_name, final String signature ) {
         int ret;
         int class_index;
         int name_and_type_index;
@@ -577,10 +599,12 @@
         return ret;
     }
 
-    public int addMethodref(final MethodGen method) {
+
+    public int addMethodref( final MethodGen method ) {
         return addMethodref(method.getClassName(), method.getName(), method.getSignature());
     }
 
+
     /**
      * Look for ConstantInterfaceMethodref in ConstantPool.
      *
@@ -589,27 +613,29 @@
      * @param signature return and argument types
      * @return index on success, -1 otherwise
      */
-    public int lookupInterfaceMethodref(final String class_name, final String method_name, final String signature) {
+    public int lookupInterfaceMethodref( final String class_name, final String method_name, final String signature ) {
         final Index index = cp_table.get(class_name + IMETHODREF_DELIM + method_name
                 + IMETHODREF_DELIM + signature);
         return (index != null) ? index.index : -1;
     }
 
-    public int lookupInterfaceMethodref(final MethodGen method) {
+
+    public int lookupInterfaceMethodref( final MethodGen method ) {
         return lookupInterfaceMethodref(method.getClassName(), method.getName(), method
                 .getSignature());
     }
 
+
     /**
-     * Add a new InterfaceMethodref constant to the ConstantPool, if it is not
-     * already in there.
+     * Add a new InterfaceMethodref constant to the ConstantPool, if it is not already
+     * in there.
      *
      * @param class_name class name string to add
      * @param method_name method name string to add
      * @param signature signature string to add
      * @return index of entry
      */
-    public int addInterfaceMethodref(final String class_name, final String method_name, final String signature) {
+    public int addInterfaceMethodref( final String class_name, final String method_name, final String signature ) {
         int ret;
         int class_index;
         int name_and_type_index;
@@ -628,10 +654,12 @@
         return ret;
     }
 
-    public int addInterfaceMethodref(final MethodGen method) {
+
+    public int addInterfaceMethodref( final MethodGen method ) {
         return addInterfaceMethodref(method.getClassName(), method.getName(), method.getSignature());
     }
 
+
     /**
      * Look for ConstantFieldref in ConstantPool.
      *
@@ -640,22 +668,23 @@
      * @param signature return and argument types
      * @return index on success, -1 otherwise
      */
-    public int lookupFieldref(final String class_name, final String field_name, final String signature) {
+    public int lookupFieldref( final String class_name, final String field_name, final String signature ) {
         final Index index = cp_table.get(class_name + FIELDREF_DELIM + field_name
                 + FIELDREF_DELIM + signature);
         return (index != null) ? index.index : -1;
     }
 
+
     /**
-     * Add a new Fieldref constant to the ConstantPool, if it is not already in
-     * there.
+     * Add a new Fieldref constant to the ConstantPool, if it is not already
+     * in there.
      *
      * @param class_name class name string to add
      * @param field_name field name string to add
      * @param signature signature string to add
      * @return index of entry
      */
-    public int addFieldref(final String class_name, final String field_name, final String signature) {
+    public int addFieldref( final String class_name, final String field_name, final String signature ) {
         int ret;
         int class_index;
         int name_and_type_index;
@@ -674,24 +703,27 @@
         return ret;
     }
 
+
     /**
      * @param i index in constant pool
      * @return constant pool entry at index i
      */
-    public Constant getConstant(final int i) {
+    public Constant getConstant( final int i ) {
         return constants[i];
     }
 
+
     /**
      * Use with care!
      *
      * @param i index in constant pool
      * @param c new constant pool entry at index i
      */
-    public void setConstant(final int i, final Constant c) {
+    public void setConstant( final int i, final Constant c ) {
         constants[i] = c;
     }
 
+
     /**
      * @return intermediate constant pool
      */
@@ -699,6 +731,7 @@
         return new ConstantPool(constants);
     }
 
+
     /**
      * @return current size of constant pool
      */
@@ -706,6 +739,7 @@
         return index;
     }
 
+
     /**
      * @return constant pool with proper length
      */
@@ -715,6 +749,7 @@
         return new ConstantPool(cs);
     }
 
+
     /**
      * @return String representation.
      */
@@ -727,10 +762,10 @@
         return buf.toString();
     }
 
-    /**
-     * Import constant from another ConstantPool and return new index.
+
+    /** Import constant from another ConstantPool and return new index.
      */
-    public int addConstant(final Constant c, final ConstantPoolGen cp) {
+    public int addConstant( final Constant c, final ConstantPoolGen cp ) {
         final Constant[] constants = cp.getConstantPool().getConstantPool();
         switch (c.getTag()) {
             case Const.CONSTANT_String: {
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConstantPushInstruction.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConstantPushInstruction.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * Denotes a push instruction that produces a literal on the stack
  * such as  SIPUSH, BIPUSH, ICONST, etc.
  *
- * @version $Id: ConstantPushInstruction.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
 
  * @see ICONST
  * @see SIPUSH
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConversionInstruction.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConversionInstruction.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,14 +26,14 @@
 /**
  * Super class for the x2y family of instructions.
  *
- * @version $Id: ConversionInstruction.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public abstract class ConversionInstruction extends Instruction implements TypedInstruction,
         StackProducer, StackConsumer {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     ConversionInstruction() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/D2F.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/D2F.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * D2F - Convert double to float
  * <PRE>Stack: ..., value.word1, value.word2 -&gt; ..., result</PRE>
  *
- * @version $Id: D2F.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class D2F extends ConversionInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/D2I.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/D2I.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * D2I - Convert double to int
  * <PRE>Stack: ..., value.word1, value.word2 -&gt; ..., result</PRE>
  *
- * @version $Id: D2I.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class D2I extends ConversionInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/D2L.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/D2L.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * D2L - Convert double to long
  * <PRE>Stack: ..., value.word1, value.word2 -&gt; ..., result.word1, result.word2</PRE>
  *
- * @version $Id: D2L.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class D2L extends ConversionInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DADD.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DADD.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,7 +26,7 @@
  * <PRE>Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -&gt;</PRE>
  *        ..., result.word1, result1.word2
  *
- * @version $Id: DADD.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class DADD extends ArithmeticInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DALOAD.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DALOAD.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * DALOAD - Load double from array
  * <PRE>Stack: ..., arrayref, index -&gt; ..., result.word1, result.word2</PRE>
  *
- * @version $Id: DALOAD.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class DALOAD extends ArrayInstruction implements StackProducer {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DASTORE.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DASTORE.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * DASTORE -  Store into double array
  * <PRE>Stack: ..., arrayref, index, value.word1, value.word2 -&gt; ...</PRE>
  *
- * @version $Id: DASTORE.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class DASTORE extends ArrayInstruction implements StackConsumer {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DCMPG.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DCMPG.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * DCMPG - Compare doubles: value1 &gt; value2
  * <PRE>Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -&gt; ..., result</PRE>
  *
- * @version $Id: DCMPG.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class DCMPG extends Instruction implements TypedInstruction, StackProducer, StackConsumer {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DCMPL.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DCMPL.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * DCMPL - Compare doubles: value1 &lt; value2
  * <PRE>Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -&gt; ..., result</PRE>
  *
- * @version $Id: DCMPL.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class DCMPL extends Instruction implements TypedInstruction, StackProducer, StackConsumer {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DCONST.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DCONST.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -25,8 +25,8 @@
  *
  * <PRE>Stack: ... -&gt; ..., </PRE>
  *
- * @version $Id: DCONST.java 1747278 2016-06-07 17:28:43Z britter $
- * @LastModified: Nov 2017
+ * @version $Id$
+ * @LastModified: Jun 2019
  */
 public class DCONST extends Instruction implements ConstantPushInstruction {
 
@@ -34,8 +34,8 @@
 
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     DCONST() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DDIV.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DDIV.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,7 +26,7 @@
  * <PRE>Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -&gt;</PRE>
  *        ..., result.word1, result.word2
  *
- * @version $Id: DDIV.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class DDIV extends ArithmeticInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DLOAD.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DLOAD.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,13 +25,13 @@
  * DLOAD - Load double from local variable
  * <PRE>Stack ... -&gt; ..., result.word1, result.word2</PRE>
  *
- * @version $Id: DLOAD.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class DLOAD extends LoadInstruction {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     DLOAD() {
         super(com.sun.org.apache.bcel.internal.Const.DLOAD, com.sun.org.apache.bcel.internal.Const.DLOAD_0);
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DMUL.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DMUL.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,7 +26,7 @@
  * <PRE>Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -&gt;</PRE>
  *        ..., result.word1, result.word2
  *
- * @version $Id: DMUL.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class DMUL extends ArithmeticInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DNEG.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DNEG.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * DNEG - Negate double
  * <PRE>Stack: ..., value.word1, value.word2 -&gt; ..., result.word1, result.word2</PRE>
  *
- * @version $Id: DNEG.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class DNEG extends ArithmeticInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DREM.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DREM.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,7 +26,7 @@
  * <PRE>Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -&gt;</PRE>
  *        ..., result.word1, result.word2
  *
- * @version $Id: DREM.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class DREM extends ArithmeticInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DRETURN.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DRETURN.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * DRETURN -  Return double from method
  * <PRE>Stack: ..., value.word1, value.word2 -&gt; &lt;empty&gt;</PRE>
  *
- * @version $Id: DRETURN.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class DRETURN extends ReturnInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DSTORE.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DSTORE.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,13 +25,13 @@
  * DSTORE - Store double into local variable
  * <pre>Stack: ..., value.word1, value.word2 -&gt; ... </PRE>
  *
- * @version $Id: DSTORE.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class DSTORE extends StoreInstruction {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     DSTORE() {
         super(com.sun.org.apache.bcel.internal.Const.DSTORE, com.sun.org.apache.bcel.internal.Const.DSTORE_0);
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DSUB.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DSUB.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,7 +26,7 @@
  * <PRE>Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -&gt;</PRE>
  *        ..., result.word1, result.word2
  *
- * @version $Id: DSUB.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class DSUB extends ArithmeticInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * DUP - Duplicate top operand stack word
  * <PRE>Stack: ..., word -&gt; ..., word, word</PRE>
  *
- * @version $Id: DUP.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class DUP extends StackInstruction implements PushInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP2.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP2.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * DUP2 - Duplicate two top operand stack words
  * <PRE>Stack: ..., word2, word1 -&gt; ..., word2, word1, word2, word1</PRE>
  *
- * @version $Id: DUP2.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class DUP2 extends StackInstruction implements PushInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP2_X1.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP2_X1.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * DUP2_X1 - Duplicate two top operand stack words and put three down
  * <PRE>Stack: ..., word3, word2, word1 -&gt; ..., word2, word1, word3, word2, word1</PRE>
  *
- * @version $Id: DUP2_X1.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class DUP2_X1 extends StackInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP2_X2.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP2_X2.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * DUP2_X2 - Duplicate two top operand stack words and put four down
  * <PRE>Stack: ..., word4, word3, word2, word1 -&gt; ..., word2, word1, word4, word3, word2, word1</PRE>
  *
- * @version $Id: DUP2_X2.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class DUP2_X2 extends StackInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP_X1.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP_X1.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * DUP_X1 - Duplicate top operand stack word and put two down
  * <PRE>Stack: ..., word2, word1 -&gt; ..., word1, word2, word1</PRE>
  *
- * @version $Id: DUP_X1.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class DUP_X1 extends StackInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP_X2.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP_X2.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * DUP_X2 - Duplicate top operand stack word and put three down
  * <PRE>Stack: ..., word3, word2, word1 -&gt; ..., word1, word3, word2, word1</PRE>
  *
- * @version $Id: DUP_X2.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class DUP_X2 extends StackInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ElementValueGen.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ElementValueGen.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -34,6 +34,7 @@
 
 /**
  * @since 6.0
+ * @LastModified: Jun 2019
  */
 public abstract class ElementValueGen
 {
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/EmptyVisitor.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/EmptyVisitor.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,7 +24,7 @@
 /**
  * Supplies empty method bodies to be overridden by subclasses.
  *
- * @version $Id: EmptyVisitor.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public abstract class EmptyVisitor implements Visitor {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ExceptionThrower.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ExceptionThrower.java	Mon Jul 01 14:57:02 2019 -0700
@@ -38,7 +38,7 @@
  * "Throwable" object; so this term is equally used for "Exception"
  * and "Error" objects.
  *
- * @version $Id: ExceptionThrower.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public interface ExceptionThrower {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/F2D.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/F2D.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * F2D - Convert float to double
  * <PRE>Stack: ..., value -&gt; ..., result.word1, result.word2</PRE>
  *
- * @version $Id: F2D.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class F2D extends ConversionInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/F2I.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/F2I.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * F2I - Convert float to int
  * <PRE>Stack: ..., value -&gt; ..., result</PRE>
  *
- * @version $Id: F2I.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class F2I extends ConversionInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/F2L.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/F2L.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * F2L - Convert float to long
  * <PRE>Stack: ..., value -&gt; ..., result.word1, result.word2</PRE>
  *
- * @version $Id: F2L.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class F2L extends ConversionInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FADD.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FADD.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * FADD - Add floats
  * <PRE>Stack: ..., value1, value2 -&gt; result</PRE>
  *
- * @version $Id: FADD.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class FADD extends ArithmeticInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FALOAD.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FALOAD.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * FALOAD - Load float from array
  * <PRE>Stack: ..., arrayref, index -&gt; ..., value</PRE>
  *
- * @version $Id: FALOAD.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class FALOAD extends ArrayInstruction implements StackProducer {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FASTORE.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FASTORE.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * FASTORE -  Store into float array
  * <PRE>Stack: ..., arrayref, index, value -&gt; ...</PRE>
  *
- * @version $Id: FASTORE.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class FASTORE extends ArrayInstruction implements StackConsumer {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FCMPG.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FCMPG.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * FCMPG - Compare floats: value1 &gt; value2
  * <PRE>Stack: ..., value1, value2 -&gt; ..., result</PRE>
  *
- * @version $Id: FCMPG.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class FCMPG extends Instruction implements TypedInstruction, StackProducer, StackConsumer {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FCMPL.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FCMPL.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * FCMPL - Compare floats: value1 &lt; value2
  * <PRE>Stack: ..., value1, value2 -&gt; ..., result</PRE>
  *
- * @version $Id: FCMPL.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class FCMPL extends Instruction implements TypedInstruction, StackProducer, StackConsumer {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FCONST.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FCONST.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -25,8 +25,8 @@
  *
  * <PRE>Stack: ... -&gt; ..., </PRE>
  *
- * @version $Id: FCONST.java 1747278 2016-06-07 17:28:43Z britter $
- * @LastModified: Nov 2017
+ * @version $Id$
+ * @LastModified: Jun 2019
  */
 public class FCONST extends Instruction implements ConstantPushInstruction {
 
@@ -34,8 +34,8 @@
 
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     FCONST() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FDIV.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FDIV.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * FDIV - Divide floats
  * <PRE>Stack: ..., value1, value2 -&gt; result</PRE>
  *
- * @version $Id: FDIV.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class FDIV extends ArithmeticInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FLOAD.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FLOAD.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,13 +25,13 @@
  * FLOAD - Load float from local variable
  * <PRE>Stack ... -&gt; ..., result</PRE>
  *
- * @version $Id: FLOAD.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class FLOAD extends LoadInstruction {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     FLOAD() {
         super(com.sun.org.apache.bcel.internal.Const.FLOAD, com.sun.org.apache.bcel.internal.Const.FLOAD_0);
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FMUL.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FMUL.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * FMUL - Multiply floats
  * <PRE>Stack: ..., value1, value2 -&gt; result</PRE>
  *
- * @version $Id: FMUL.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class FMUL extends ArithmeticInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FNEG.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FNEG.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * FNEG - Negate float
  * <PRE>Stack: ..., value -&gt; ..., result</PRE>
  *
- * @version $Id: FNEG.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class FNEG extends ArithmeticInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FREM.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FREM.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * FREM - Remainder of floats
  * <PRE>Stack: ..., value1, value2 -&gt; result</PRE>
  *
- * @version $Id: FREM.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class FREM extends ArithmeticInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FRETURN.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FRETURN.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * FRETURN -  Return float from method
  * <PRE>Stack: ..., value -&gt; &lt;empty&gt;</PRE>
  *
- * @version $Id: FRETURN.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class FRETURN extends ReturnInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FSTORE.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FSTORE.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,13 +25,13 @@
  * FSTORE - Store float into local variable
  * <PRE>Stack: ..., value -&gt; ... </PRE>
  *
- * @version $Id: FSTORE.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class FSTORE extends StoreInstruction {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     FSTORE() {
         super(com.sun.org.apache.bcel.internal.Const.FSTORE, com.sun.org.apache.bcel.internal.Const.FSTORE_0);
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FSUB.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FSUB.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * FSUB - Substract floats
  * <PRE>Stack: ..., value1, value2 -&gt; result</PRE>
  *
- * @version $Id: FSUB.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class FSUB extends ArithmeticInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldGen.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldGen.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -21,6 +21,7 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
 
 import com.sun.org.apache.bcel.internal.Const;
 import com.sun.org.apache.bcel.internal.classfile.AnnotationEntry;
@@ -35,12 +36,13 @@
 import com.sun.org.apache.bcel.internal.util.BCELComparator;
 
 /**
- * Template class for building up a field. The only extraordinary thing one can
- * do is to add a constant value attribute to a field (which must of course be
- * compatible with to the declared type).
+ * Template class for building up a field.  The only extraordinary thing
+ * one can do is to add a constant value attribute to a field (which must of
+ * course be compatible with to the declared type).
  *
- * @version $Id: FieldGen.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
  * @see Field
+ * @LastModified: Jun 2019
  */
 public class FieldGen extends FieldGenOrMethodGen {
 
@@ -48,27 +50,29 @@
     private static BCELComparator bcelComparator = new BCELComparator() {
 
         @Override
-        public boolean equals(final Object o1, final Object o2) {
+        public boolean equals( final Object o1, final Object o2 ) {
             final FieldGen THIS = (FieldGen) o1;
             final FieldGen THAT = (FieldGen) o2;
-            return THIS.getName().equals(THAT.getName())
-                    && THIS.getSignature().equals(THAT.getSignature());
+            return Objects.equals(THIS.getName(), THAT.getName())
+                    && Objects.equals(THIS.getSignature(), THAT.getSignature());
         }
 
+
         @Override
-        public int hashCode(final Object o) {
+        public int hashCode( final Object o ) {
             final FieldGen THIS = (FieldGen) o;
             return THIS.getSignature().hashCode() ^ THIS.getName().hashCode();
         }
     };
 
+
     /**
-     * Declare a field. If it is static (isStatic() == true) and has a basic
-     * type like int or String it may have an initial value associated with it
-     * as defined by setInitValue().
+     * Declare a field. If it is static (isStatic() == true) and has a
+     * basic type like int or String it may have an initial value
+     * associated with it as defined by setInitValue().
      *
      * @param access_flags access qualifiers
-     * @param type field type
+     * @param type  field type
      * @param name field name
      * @param cp constant pool
      */
@@ -79,12 +83,12 @@
         setConstantPool(cp);
     }
 
+
     /**
      * Instantiate from existing field.
      *
      * @param field Field object
-     * @param cp constant pool (must contain the same entries as the field's
-     * constant pool)
+     * @param cp constant pool (must contain the same entries as the field's constant pool)
      */
     public FieldGen(final Field field, final ConstantPoolGen cp) {
         this(field.getAccessFlags(), Type.getType(field.getSignature()), field.getName(), cp);
@@ -93,10 +97,10 @@
             if (attr instanceof ConstantValue) {
                 setValue(((ConstantValue) attr).getConstantValueIndex());
             } else if (attr instanceof Annotations) {
-                final Annotations runtimeAnnotations = (Annotations) attr;
+                final Annotations runtimeAnnotations = (Annotations)attr;
                 final AnnotationEntry[] annotationEntries = runtimeAnnotations.getAnnotationEntries();
                 for (final AnnotationEntry element : annotationEntries) {
-                    addAnnotationEntry(new AnnotationEntryGen(element, cp, false));
+                    addAnnotationEntry(new AnnotationEntryGen(element,cp,false));
                 }
             } else {
                 addAttribute(attr);
@@ -104,87 +108,98 @@
         }
     }
 
-    private void setValue(final int index) {
+
+    private void setValue( final int index ) {
         final ConstantPool cp = super.getConstantPool().getConstantPool();
         final Constant c = cp.getConstant(index);
         value = ((ConstantObject) c).getConstantValue(cp);
     }
 
+
     /**
-     * Set (optional) initial value of field, otherwise it will be set to
-     * null/0/false by the JVM automatically.
+     * Set (optional) initial value of field, otherwise it will be set to null/0/false
+     * by the JVM automatically.
      */
-    public void setInitValue(final String str) {
-        checkType(ObjectType.getInstance("java.lang.String"));
+    public void setInitValue( final String str ) {
+        checkType(  ObjectType.getInstance("java.lang.String"));
         if (str != null) {
             value = str;
         }
     }
 
-    public void setInitValue(final long l) {
+
+    public void setInitValue( final long l ) {
         checkType(Type.LONG);
         if (l != 0L) {
-            value = l;
+            value = Long.valueOf(l);
         }
     }
 
-    public void setInitValue(final int i) {
+
+    public void setInitValue( final int i ) {
         checkType(Type.INT);
         if (i != 0) {
-            value = i;
+            value = Integer.valueOf(i);
         }
     }
 
-    public void setInitValue(final short s) {
+
+    public void setInitValue( final short s ) {
         checkType(Type.SHORT);
         if (s != 0) {
-            value = (int) s;
+            value = Integer.valueOf(s);
         }
     }
 
-    public void setInitValue(final char c) {
+
+    public void setInitValue( final char c ) {
         checkType(Type.CHAR);
         if (c != 0) {
-            value = (int) c;
+            value = Integer.valueOf(c);
         }
     }
 
-    public void setInitValue(final byte b) {
+
+    public void setInitValue( final byte b ) {
         checkType(Type.BYTE);
         if (b != 0) {
-            value = (int) b;
+            value = Integer.valueOf(b);
         }
     }
 
-    public void setInitValue(final boolean b) {
+
+    public void setInitValue( final boolean b ) {
         checkType(Type.BOOLEAN);
         if (b) {
-            value = 1;
+            value = Integer.valueOf(1);
         }
     }
 
-    public void setInitValue(final float f) {
+
+    public void setInitValue( final float f ) {
         checkType(Type.FLOAT);
         if (f != 0.0) {
             value = f;
         }
     }
 
-    public void setInitValue(final double d) {
+
+    public void setInitValue( final double d ) {
         checkType(Type.DOUBLE);
         if (d != 0.0) {
             value = d;
         }
     }
 
-    /**
-     * Remove any initial value.
+
+    /** Remove any initial value.
      */
     public void cancelInitValue() {
         value = null;
     }
 
-    private void checkType(final Type atype) {
+
+    private void checkType( final Type atype ) {
         final Type superType = super.getType();
         if (superType == null) {
             throw new ClassGenException("You haven't defined the type of the field yet");
@@ -197,6 +212,7 @@
         }
     }
 
+
     /**
      * Get field object after having set up all necessary values.
      */
@@ -216,11 +232,12 @@
     }
 
     private void addAnnotationsAsAttribute(final ConstantPoolGen cp) {
-        final Attribute[] attrs = AnnotationEntryGen.getAnnotationAttributes(cp, super.getAnnotationEntries());
+          final Attribute[] attrs = AnnotationEntryGen.getAnnotationAttributes(cp, super.getAnnotationEntries());
         for (final Attribute attr : attrs) {
             addAttribute(attr);
         }
-    }
+      }
+
 
     private int addConstant() {
         switch (super.getType().getType()) { // sic
@@ -243,6 +260,7 @@
         }
     }
 
+
     @Override
     public String getSignature() {
         return super.getType().getSignature();
@@ -250,38 +268,39 @@
 
     private List<FieldObserver> observers;
 
-    /**
-     * Add observer for this object.
+
+    /** Add observer for this object.
      */
-    public void addObserver(final FieldObserver o) {
+    public void addObserver( final FieldObserver o ) {
         if (observers == null) {
             observers = new ArrayList<>();
         }
         observers.add(o);
     }
 
-    /**
-     * Remove observer for this object.
+
+    /** Remove observer for this object.
      */
-    public void removeObserver(final FieldObserver o) {
+    public void removeObserver( final FieldObserver o ) {
         if (observers != null) {
             observers.remove(o);
         }
     }
 
-    /**
-     * Call notify() method on all observers. This method is not called
-     * automatically whenever the state has changed, but has to be called by the
-     * user after he has finished editing the object.
+
+    /** Call notify() method on all observers. This method is not called
+     * automatically whenever the state has changed, but has to be
+     * called by the user after he has finished editing the object.
      */
     public void update() {
         if (observers != null) {
-            for (final FieldObserver observer : observers) {
+            for (final FieldObserver observer : observers ) {
                 observer.notify(this);
             }
         }
     }
 
+
     public String getInitValue() {
         if (value != null) {
             return value.toString();
@@ -289,9 +308,10 @@
         return null;
     }
 
+
     /**
-     * Return string representation close to declaration format, `public static
-     * final short MAX = 100', e.g..
+     * Return string representation close to declaration format,
+     * `public static final short MAX = 100', e.g..
      *
      * @return String representation of field
      */
@@ -313,15 +333,16 @@
         return buf.toString();
     }
 
-    /**
-     * @return deep copy of this field
+
+    /** @return deep copy of this field
      */
-    public FieldGen copy(final ConstantPoolGen cp) {
+    public FieldGen copy( final ConstantPoolGen cp ) {
         final FieldGen fg = (FieldGen) clone();
         fg.setConstantPool(cp);
         return fg;
     }
 
+
     /**
      * @return Comparison strategy object
      */
@@ -329,28 +350,31 @@
         return bcelComparator;
     }
 
+
     /**
      * @param comparator Comparison strategy object
      */
-    public static void setComparator(final BCELComparator comparator) {
+    public static void setComparator( final BCELComparator comparator ) {
         bcelComparator = comparator;
     }
 
+
     /**
-     * Return value as defined by given BCELComparator strategy. By default two
-     * FieldGen objects are said to be equal when their names and signatures are
-     * equal.
+     * Return value as defined by given BCELComparator strategy.
+     * By default two FieldGen objects are said to be equal when
+     * their names and signatures are equal.
      *
      * @see java.lang.Object#equals(java.lang.Object)
      */
     @Override
-    public boolean equals(final Object obj) {
+    public boolean equals( final Object obj ) {
         return bcelComparator.equals(this, obj);
     }
 
+
     /**
-     * Return value as defined by given BCELComparator strategy. By default
-     * return the hashcode of the field's name XOR signature.
+     * Return value as defined by given BCELComparator strategy.
+     * By default return the hashcode of the field's name XOR signature.
      *
      * @see java.lang.Object#hashCode()
      */
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldGenOrMethodGen.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldGenOrMethodGen.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -27,11 +27,11 @@
 import com.sun.org.apache.bcel.internal.classfile.Attribute;
 
 /**
- * Super class for FieldGen and MethodGen objects, since they have some methods
- * in common!
+ * Super class for FieldGen and MethodGen objects, since they have
+ * some methods in common!
  *
- * @version $Id: FieldGenOrMethodGen.java 1749603 2016-06-21 20:50:19Z ggregory
- * $
+ * @version $Id$
+ * @LastModified: Jun 2019
  */
 public abstract class FieldGenOrMethodGen extends AccessFlags implements NamedAndTyped, Cloneable {
 
@@ -42,11 +42,13 @@
     private final List<Attribute> attribute_vec = new ArrayList<>();
 
     // @since 6.0
-    private final List<AnnotationEntryGen> annotation_vec = new ArrayList<>();
+    private final List<AnnotationEntryGen>       annotation_vec= new ArrayList<>();
+
 
     protected FieldGenOrMethodGen() {
     }
 
+
     /**
      * @since 6.0
      */
@@ -55,47 +57,53 @@
     }
 
     @Override
-    public void setType(final Type type) { // TODO could be package-protected?
+    public void setType( final Type type ) { // TODO could be package-protected?
         if (type.getType() == Const.T_ADDRESS) {
             throw new IllegalArgumentException("Type can not be " + type);
         }
         this.type = type;
     }
 
+
     @Override
     public Type getType() {
         return type;
     }
 
-    /**
-     * @return name of method/field.
+
+    /** @return name of method/field.
      */
     @Override
     public String getName() {
         return name;
     }
 
+
     @Override
-    public void setName(final String name) { // TODO could be package-protected?
+    public void setName( final String name ) { // TODO could be package-protected?
         this.name = name;
     }
 
+
     public ConstantPoolGen getConstantPool() {
         return cp;
     }
 
-    public void setConstantPool(final ConstantPoolGen cp) { // TODO could be package-protected?
+
+    public void setConstantPool( final ConstantPoolGen cp ) { // TODO could be package-protected?
         this.cp = cp;
     }
 
+
     /**
-     * Add an attribute to this method. Currently, the JVM knows about the
-     * `Code', `ConstantValue', `Synthetic' and `Exceptions' attributes. Other
-     * attributes will be ignored by the JVM but do no harm.
+     * Add an attribute to this method. Currently, the JVM knows about
+     * the `Code', `ConstantValue', `Synthetic' and `Exceptions'
+     * attributes. Other attributes will be ignored by the JVM but do no
+     * harm.
      *
      * @param a attribute to be added
      */
-    public void addAttribute(final Attribute a) {
+    public void addAttribute( final Attribute a ) {
         attribute_vec.add(a);
     }
 
@@ -107,10 +115,11 @@
         annotation_vec.add(ag);
     }
 
+
     /**
      * Remove an attribute.
      */
-    public void removeAttribute(final Attribute a) {
+    public void removeAttribute( final Attribute a ) {
         attribute_vec.remove(a);
     }
 
@@ -122,6 +131,7 @@
         annotation_vec.remove(ag);
     }
 
+
     /**
      * Remove all attributes.
      */
@@ -137,6 +147,7 @@
         annotation_vec.clear();
     }
 
+
     /**
      * @return all attributes of this method.
      */
@@ -148,15 +159,16 @@
 
     public AnnotationEntryGen[] getAnnotationEntries() {
         final AnnotationEntryGen[] annotations = new AnnotationEntryGen[annotation_vec.size()];
-        annotation_vec.toArray(annotations);
-        return annotations;
-    }
+          annotation_vec.toArray(annotations);
+          return annotations;
+      }
 
-    /**
-     * @return signature of method/field.
+
+    /** @return signature of method/field.
      */
     public abstract String getSignature();
 
+
     @Override
     public Object clone() {
         try {
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldInstruction.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldInstruction.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,13 +26,13 @@
 /**
  * Super class for the GET/PUTxxx family of instructions.
  *
- * @version $Id: FieldInstruction.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public abstract class FieldInstruction extends FieldOrMethod {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     FieldInstruction() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldObserver.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldObserver.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * Imnplement this interface if you're interested in changes to a FieldGen object
  * and register yourself with addObserver().
  *
- * @version $Id: FieldObserver.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public interface FieldObserver {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldOrMethod.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldOrMethod.java	Mon Jul 01 14:57:02 2019 -0700
@@ -31,13 +31,13 @@
  * Super class for InvokeInstruction and FieldInstruction, since they have
  * some methods in common!
  *
- * @version $Id: FieldOrMethod.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
  */
 public abstract class FieldOrMethod extends CPInstruction implements LoadClass {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     FieldOrMethod() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GETFIELD.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GETFIELD.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,47 +25,52 @@
 
 /**
  * GETFIELD - Fetch field from object
- * <PRE>Stack: ..., objectref -&gt; ..., value</PRE> OR
+ * <PRE>Stack: ..., objectref -&gt; ..., value</PRE>
+ * OR
  * <PRE>Stack: ..., objectref -&gt; ..., value.word1, value.word2</PRE>
  *
- * @version $Id: GETFIELD.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class GETFIELD extends FieldInstruction implements ExceptionThrower, StackConsumer,
         StackProducer {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     GETFIELD() {
     }
 
+
     public GETFIELD(final int index) {
         super(Const.GETFIELD, index);
     }
 
+
     @Override
-    public int produceStack(final ConstantPoolGen cpg) {
+    public int produceStack( final ConstantPoolGen cpg ) {
         return getFieldSize(cpg);
     }
 
+
     @Override
     public Class<?>[] getExceptions() {
         return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_FIELD_AND_METHOD_RESOLUTION,
-                ExceptionConst.NULL_POINTER_EXCEPTION,
-                ExceptionConst.INCOMPATIBLE_CLASS_CHANGE_ERROR);
+            ExceptionConst.NULL_POINTER_EXCEPTION,
+            ExceptionConst.INCOMPATIBLE_CLASS_CHANGE_ERROR);
     }
 
+
     /**
-     * Call corresponding visitor method(s). The order is: Call visitor methods
-     * of implemented interfaces first, then call methods according to the class
-     * hierarchy in descending order, i.e., the most specific visitXXX() call
-     * comes last.
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
      *
      * @param v Visitor object
      */
     @Override
-    public void accept(final Visitor v) {
+    public void accept( final Visitor v ) {
         v.visitExceptionThrower(this);
         v.visitStackConsumer(this);
         v.visitStackProducer(this);
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GETSTATIC.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GETSTATIC.java	Mon Jul 01 14:57:02 2019 -0700
@@ -30,13 +30,13 @@
  * OR
  * <PRE>Stack: ..., -&gt; ..., value.word1, value.word2</PRE>
  *
- * @version $Id: GETSTATIC.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class GETSTATIC extends FieldInstruction implements PushInstruction, ExceptionThrower {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     GETSTATIC() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GOTO.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GOTO.java	Mon Jul 01 14:57:02 2019 -0700
@@ -27,13 +27,13 @@
 /**
  * GOTO - Branch always (to relative offset, not absolute address)
  *
- * @version $Id: GOTO.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
  */
 public class GOTO extends GotoInstruction implements VariableLengthInstruction {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     GOTO() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GOTO_W.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GOTO_W.java	Mon Jul 01 14:57:02 2019 -0700
@@ -29,13 +29,13 @@
 /**
  * GOTO_W - Branch always (to relative offset, not absolute address)
  *
- * @version $Id: GOTO_W.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class GOTO_W extends GotoInstruction {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     GOTO_W() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GotoInstruction.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GotoInstruction.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,7 +24,7 @@
 /**
  * Super class for GOTO
  *
- * @version $Id: GotoInstruction.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public abstract class GotoInstruction extends BranchInstruction implements UnconditionalBranch {
 
@@ -34,8 +34,8 @@
 
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     GotoInstruction() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2B.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2B.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * I2B - Convert int to byte
  * <PRE>Stack: ..., value -&gt; ..., result</PRE>
  *
- * @version $Id: I2B.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class I2B extends ConversionInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2C.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2C.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * I2C - Convert int to char
  * <PRE>Stack: ..., value -&gt; ..., result</PRE>
  *
- * @version $Id: I2C.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class I2C extends ConversionInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2D.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2D.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * I2D - Convert int to double
  * <PRE>Stack: ..., value -&gt; ..., result.word1, result.word2</PRE>
  *
- * @version $Id: I2D.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class I2D extends ConversionInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2F.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2F.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * I2F - Convert int to float
  * <PRE>Stack: ..., value -&gt; ..., result</PRE>
  *
- * @version $Id: I2F.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class I2F extends ConversionInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2L.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2L.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * I2L - Convert int to long
  * <PRE>Stack: ..., value -&gt; ..., result.word1, result.word2</PRE>
  *
- * @version $Id: I2L.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class I2L extends ConversionInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2S.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2S.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * I2S - Convert int to short
  * <PRE>Stack: ..., value -&gt; ..., result</PRE>
  *
- * @version $Id: I2S.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class I2S extends ConversionInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IADD.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IADD.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * IADD - Add ints
  * <PRE>Stack: ..., value1, value2 -&gt; result</PRE>
  *
- * @version $Id: IADD.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class IADD extends ArithmeticInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IALOAD.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IALOAD.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * IALOAD - Load int from array
  * <PRE>Stack: ..., arrayref, index -&gt; ..., value</PRE>
  *
- * @version $Id: IALOAD.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class IALOAD extends ArrayInstruction implements StackProducer {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IAND.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IAND.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * IAND - Bitwise AND int
  * <PRE>Stack: ..., value1, value2 -&gt; ..., result</PRE>
  *
- * @version $Id: IAND.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class IAND extends ArithmeticInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IASTORE.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IASTORE.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * IASTORE -  Store into int array
  * <PRE>Stack: ..., arrayref, index, value -&gt; ...</PRE>
  *
- * @version $Id: IASTORE.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class IASTORE extends ArrayInstruction implements StackConsumer {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ICONST.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ICONST.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,19 +24,21 @@
  *
  * <PRE>Stack: ... -&gt; ..., </PRE>
  *
- * @version $Id: ICONST.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class ICONST extends Instruction implements ConstantPushInstruction {
 
     private int value;
 
+
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     ICONST() {
     }
 
+
     public ICONST(final int i) {
         super(com.sun.org.apache.bcel.internal.Const.ICONST_0, (short) 1);
         if ((i >= -1) && (i <= 5)) {
@@ -47,29 +49,31 @@
         value = i;
     }
 
+
     @Override
     public Number getValue() {
         return Integer.valueOf(value);
     }
 
-    /**
-     * @return Type.INT
+
+    /** @return Type.INT
      */
     @Override
-    public Type getType(final ConstantPoolGen cp) {
+    public Type getType( final ConstantPoolGen cp ) {
         return Type.INT;
     }
 
+
     /**
-     * Call corresponding visitor method(s). The order is: Call visitor methods
-     * of implemented interfaces first, then call methods according to the class
-     * hierarchy in descending order, i.e., the most specific visitXXX() call
-     * comes last.
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
      *
      * @param v Visitor object
      */
     @Override
-    public void accept(final Visitor v) {
+    public void accept( final Visitor v ) {
         v.visitPushInstruction(this);
         v.visitStackProducer(this);
         v.visitTypedInstruction(this);
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IDIV.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IDIV.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -26,8 +26,8 @@
  * IDIV - Divide ints
  * <PRE>Stack: ..., value1, value2 -&gt; result</PRE>
  *
- * @version $Id: IDIV.java 1747278 2016-06-07 17:28:43Z britter $
- * @LastModified: Oct 2017
+ * @version $Id$
+ * @LastModified: Jun 2019
  */
 public class IDIV extends ArithmeticInstruction implements ExceptionThrower {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFEQ.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFEQ.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,13 +26,13 @@
  *
  * <PRE>Stack: ..., value -&gt; ...</PRE>
  *
- * @version $Id: IFEQ.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class IFEQ extends IfInstruction {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     IFEQ() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFGE.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFGE.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,13 +26,13 @@
  *
  * <PRE>Stack: ..., value -&gt; ...</PRE>
  *
- * @version $Id: IFGE.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class IFGE extends IfInstruction {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     IFGE() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFGT.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFGT.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,13 +26,13 @@
  *
  * <PRE>Stack: ..., value -&gt; ...</PRE>
  *
- * @version $Id: IFGT.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class IFGT extends IfInstruction {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     IFGT() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFLE.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFLE.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,13 +26,13 @@
  *
  * <PRE>Stack: ..., value -&gt; ...</PRE>
  *
- * @version $Id: IFLE.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class IFLE extends IfInstruction {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     IFLE() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFLT.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFLT.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,13 +26,13 @@
  *
  * <PRE>Stack: ..., value -&gt; ...</PRE>
  *
- * @version $Id: IFLT.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class IFLT extends IfInstruction {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     IFLT() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFNE.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFNE.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,13 +26,13 @@
  *
  * <PRE>Stack: ..., value -&gt; ...</PRE>
  *
- * @version $Id: IFNE.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class IFNE extends IfInstruction {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     IFNE() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFNONNULL.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFNONNULL.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,13 +26,13 @@
  *
  * <PRE>Stack: ..., reference -&gt; ...</PRE>
  *
- * @version $Id: IFNONNULL.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class IFNONNULL extends IfInstruction {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     IFNONNULL() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFNULL.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFNULL.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,13 +26,13 @@
  *
  * <PRE>Stack: ..., reference -&gt; ...</PRE>
  *
- * @version $Id: IFNULL.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class IFNULL extends IfInstruction {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     IFNULL() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ACMPEQ.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ACMPEQ.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,13 +26,13 @@
  *
  * <PRE>Stack: ..., value1, value2 -&gt; ...</PRE>
  *
- * @version $Id: IF_ACMPEQ.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class IF_ACMPEQ extends IfInstruction {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     IF_ACMPEQ() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ACMPNE.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ACMPNE.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,13 +26,13 @@
  *
  * <PRE>Stack: ..., value1, value2 -&gt; ...</PRE>
  *
- * @version $Id: IF_ACMPNE.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class IF_ACMPNE extends IfInstruction {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     IF_ACMPNE() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPEQ.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPEQ.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,13 +26,13 @@
  *
  * <PRE>Stack: ..., value1, value2 -&gt; ...</PRE>
  *
- * @version $Id: IF_ICMPEQ.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class IF_ICMPEQ extends IfInstruction {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     IF_ICMPEQ() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPGE.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPGE.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,13 +26,13 @@
  *
  * <PRE>Stack: ..., value1, value2 -&gt; ...</PRE>
  *
- * @version $Id: IF_ICMPGE.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class IF_ICMPGE extends IfInstruction {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     IF_ICMPGE() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPGT.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPGT.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,13 +26,13 @@
  *
  * <PRE>Stack: ..., value1, value2 -&gt; ...</PRE>
  *
- * @version $Id: IF_ICMPGT.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class IF_ICMPGT extends IfInstruction {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     IF_ICMPGT() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPLE.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPLE.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,13 +26,13 @@
  *
  * <PRE>Stack: ..., value1, value2 -&gt; ...</PRE>
  *
- * @version $Id: IF_ICMPLE.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class IF_ICMPLE extends IfInstruction {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     IF_ICMPLE() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPLT.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPLT.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,13 +26,13 @@
  *
  * <PRE>Stack: ..., value1, value2 -&gt; ...</PRE>
  *
- * @version $Id: IF_ICMPLT.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class IF_ICMPLT extends IfInstruction {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     IF_ICMPLT() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPNE.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPNE.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,13 +26,13 @@
  *
  * <PRE>Stack: ..., value1, value2 -&gt; ...</PRE>
  *
- * @version $Id: IF_ICMPNE.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class IF_ICMPNE extends IfInstruction {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     IF_ICMPNE() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IINC.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IINC.java	Mon Jul 01 14:57:02 2019 -0700
@@ -29,7 +29,7 @@
 /**
  * IINC - Increment local variable by constant
  *
- * @version $Id: IINC.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class IINC extends LocalVariableInstruction {
 
@@ -38,8 +38,8 @@
 
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     IINC() {
     }
@@ -79,7 +79,12 @@
 
 
     private void setWide() {
-        wide = (super.getIndex() > com.sun.org.apache.bcel.internal.Const.MAX_BYTE) || (Math.abs(c) > Byte.MAX_VALUE);
+        wide = super.getIndex() > com.sun.org.apache.bcel.internal.Const.MAX_BYTE;
+        if (c > 0) {
+            wide = wide || (c > Byte.MAX_VALUE);
+        } else {
+            wide = wide || (c < Byte.MIN_VALUE);
+        }
         if (wide) {
             super.setLength(6); // wide byte included
         } else {
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ILOAD.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ILOAD.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,13 +25,13 @@
  * ILOAD - Load int from local variable onto stack
  * <PRE>Stack: ... -&gt; ..., result</PRE>
  *
- * @version $Id: ILOAD.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class ILOAD extends LoadInstruction {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     ILOAD() {
         super(com.sun.org.apache.bcel.internal.Const.ILOAD, com.sun.org.apache.bcel.internal.Const.ILOAD_0);
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IMPDEP1.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IMPDEP1.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,7 +24,7 @@
 /**
  * IMPDEP1 - Implementation dependent
  *
- * @version $Id: IMPDEP1.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class IMPDEP1 extends Instruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IMPDEP2.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IMPDEP2.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,7 +24,7 @@
 /**
  * IMPDEP2 - Implementation dependent
  *
- * @version $Id: IMPDEP2.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class IMPDEP2 extends Instruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IMUL.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IMUL.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * IMUL - Multiply ints
  * <PRE>Stack: ..., value1, value2 -&gt; result</PRE>
  *
- * @version $Id: IMUL.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class IMUL extends ArithmeticInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INEG.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INEG.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * INEG - Negate int
  * <PRE>Stack: ..., value -&gt; ..., result</PRE>
  *
- * @version $Id: INEG.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class INEG extends ArithmeticInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INSTANCEOF.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INSTANCEOF.java	Mon Jul 01 14:57:02 2019 -0700
@@ -27,14 +27,14 @@
  * INSTANCEOF - Determine if object is of given type
  * <PRE>Stack: ..., objectref -&gt; ..., result</PRE>
  *
- * @version $Id: INSTANCEOF.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class INSTANCEOF extends CPInstruction implements LoadClass, ExceptionThrower,
         StackProducer, StackConsumer {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     INSTANCEOF() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEDYNAMIC.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEDYNAMIC.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -40,13 +40,13 @@
  * <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokedynamic">
  * The invokedynamic instruction in The Java Virtual Machine Specification</a>
  * @since 6.0
- * @LastModified: Nov 2017
+ * @LastModified: Jun 2019
  */
 public class INVOKEDYNAMIC extends InvokeInstruction {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     INVOKEDYNAMIC() {
     }
@@ -137,4 +137,19 @@
         final ConstantInvokeDynamic cid = (ConstantInvokeDynamic) cp.getConstant(super.getIndex(), Const.CONSTANT_InvokeDynamic);
         return ((ConstantNameAndType) cp.getConstant(cid.getNameAndTypeIndex())).getName(cp);
     }
+
+
+    /**
+     * Since InvokeDynamic doesn't refer to a reference type, just return java.lang.Object,
+     * as that is the only type we can say for sure the reference will be.
+     *
+     * @param cpg
+     *            the ConstantPoolGen used to create the instruction
+     * @return an ObjectType for java.lang.Object
+     * @since 6.1
+     */
+    @Override
+    public ReferenceType getReferenceType(final ConstantPoolGen cpg) {
+        return new ObjectType(Object.class.getName());
+    }
 }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEINTERFACE.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEINTERFACE.java	Mon Jul 01 14:57:02 2019 -0700
@@ -33,7 +33,7 @@
  * INVOKEINTERFACE - Invoke interface method
  * <PRE>Stack: ..., objectref, [arg1, [arg2 ...]] -&gt; ...</PRE>
  *
- * @version $Id: INVOKEINTERFACE.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  * @see
  * <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokeinterface">
  * The invokeinterface instruction in The Java Virtual Machine Specification</a>
@@ -44,8 +44,8 @@
 
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     INVOKEINTERFACE() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKESPECIAL.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKESPECIAL.java	Mon Jul 01 14:57:02 2019 -0700
@@ -33,7 +33,7 @@
  *
  * <PRE>Stack: ..., objectref, [arg1, [arg2 ...]] -&gt; ...</PRE>
  *
- * @version $Id: INVOKESPECIAL.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  * @see
  * <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokespecial">
  * The invokespecial instruction in The Java Virtual Machine Specification</a>
@@ -41,8 +41,8 @@
 public class INVOKESPECIAL extends InvokeInstruction {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     INVOKESPECIAL() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKESTATIC.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKESTATIC.java	Mon Jul 01 14:57:02 2019 -0700
@@ -32,7 +32,7 @@
  *
  * <PRE>Stack: ..., [arg1, [arg2 ...]] -&gt; ...</PRE>
  *
- * @version $Id: INVOKESTATIC.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  * @see
  * <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokestatic">
  * The invokestatic instruction in The Java Virtual Machine Specification</a>
@@ -40,8 +40,8 @@
 public class INVOKESTATIC extends InvokeInstruction {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     INVOKESTATIC() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEVIRTUAL.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEVIRTUAL.java	Mon Jul 01 14:57:02 2019 -0700
@@ -32,7 +32,7 @@
  *
  * <PRE>Stack: ..., objectref, [arg1, [arg2 ...]] -&gt; ...</PRE>
  *
- * @version $Id: INVOKEVIRTUAL.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  * @see
  * <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokevirtual">
  * The invokevirtual instruction in The Java Virtual Machine Specification</a>
@@ -40,8 +40,8 @@
 public class INVOKEVIRTUAL extends InvokeInstruction {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     INVOKEVIRTUAL() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IOR.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IOR.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * IOR - Bitwise OR int
  * <PRE>Stack: ..., value1, value2 -&gt; ..., result</PRE>
  *
- * @version $Id: IOR.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class IOR extends ArithmeticInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IREM.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IREM.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -26,8 +26,8 @@
  * IREM - Remainder of int
  * <PRE>Stack: ..., value1, value2 -&gt; result</PRE>
  *
- * @version $Id: IREM.java 1747278 2016-06-07 17:28:43Z britter $
- * @LastModified: Oct 2017
+ * @version $Id$
+ * @LastModified: Jun 2019
  */
 public class IREM extends ArithmeticInstruction implements ExceptionThrower {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IRETURN.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IRETURN.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * IRETURN -  Return int from method
  * <PRE>Stack: ..., value -&gt; &lt;empty&gt;</PRE>
  *
- * @version $Id: IRETURN.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class IRETURN extends ReturnInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISHL.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISHL.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * ISHL - Arithmetic shift left int
  * <PRE>Stack: ..., value1, value2 -&gt; ..., result</PRE>
  *
- * @version $Id: ISHL.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class ISHL extends ArithmeticInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISHR.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISHR.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * ISHR - Arithmetic shift right int
  * <PRE>Stack: ..., value1, value2 -&gt; ..., result</PRE>
  *
- * @version $Id: ISHR.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class ISHR extends ArithmeticInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISTORE.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISTORE.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,13 +25,13 @@
  * ISTORE - Store int from stack into local variable
  * <PRE>Stack: ..., value -&gt; ... </PRE>
  *
- * @version $Id: ISTORE.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class ISTORE extends StoreInstruction {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     ISTORE() {
         super(com.sun.org.apache.bcel.internal.Const.ISTORE, com.sun.org.apache.bcel.internal.Const.ISTORE_0);
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISUB.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISUB.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * ISUB - Substract ints
  * <PRE>Stack: ..., value1, value2 -&gt; result</PRE>
  *
- * @version $Id: ISUB.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class ISUB extends ArithmeticInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IUSHR.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IUSHR.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * IUSHR - Logical shift right int
  * <PRE>Stack: ..., value1, value2 -&gt; ..., result</PRE>
  *
- * @version $Id: IUSHR.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class IUSHR extends ArithmeticInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IXOR.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IXOR.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * IXOR - Bitwise XOR int
  * <PRE>Stack: ..., value1, value2 -&gt; ..., result</PRE>
  *
- * @version $Id: IXOR.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class IXOR extends ArithmeticInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IfInstruction.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IfInstruction.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,13 +24,13 @@
 /**
  * Super class for the IFxxx family of instructions.
  *
- * @version $Id: IfInstruction.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public abstract class IfInstruction extends BranchInstruction implements StackConsumer {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     IfInstruction() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IndexedInstruction.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IndexedInstruction.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * Denote entity that refers to an index, e.g. local variable instructions,
  * RET, CPInstruction, etc.
  *
- * @version $Id: IndexedInstruction.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public interface IndexedInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Instruction.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Instruction.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -29,7 +29,8 @@
 /**
  * Abstract super class for all Java byte codes.
  *
- * @version $Id: Instruction.java 1750029 2016-06-23 22:14:38Z sebb $
+ * @version $Id$
+ * @LastModified: Jun 2019
  */
 public abstract class Instruction implements Cloneable {
 
@@ -38,50 +39,54 @@
 
     private static InstructionComparator cmp = InstructionComparator.DEFAULT;
 
+
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     Instruction() {
     }
 
+
     public Instruction(final short opcode, final short length) {
         this.length = length;
         this.opcode = opcode;
     }
 
+
     /**
      * Dump instruction as byte code to stream out.
-     *
      * @param out Output stream
      */
-    public void dump(final DataOutputStream out) throws IOException {
+    public void dump( final DataOutputStream out ) throws IOException {
         out.writeByte(opcode); // Common for all instructions
     }
 
-    /**
-     * @return name of instruction, i.e., opcode name
+
+    /** @return name of instruction, i.e., opcode name
      */
     public String getName() {
         return Const.getOpcodeName(opcode);
     }
 
+
     /**
      * Long output format:
      *
-     * &lt;name of opcode&gt; "["&lt;opcode number&gt;"]" "("&lt;length of
-     * instruction&gt;")"
+     * &lt;name of opcode&gt; "["&lt;opcode number&gt;"]"
+     * "("&lt;length of instruction&gt;")"
      *
      * @param verbose long/short format switch
      * @return mnemonic for instruction
      */
-    public String toString(final boolean verbose) {
+    public String toString( final boolean verbose ) {
         if (verbose) {
             return getName() + "[" + opcode + "](" + length + ")";
         }
         return getName();
     }
 
+
     /**
      * @return mnemonic for instruction in verbose format
      */
@@ -90,17 +95,19 @@
         return toString(true);
     }
 
+
     /**
      * @return mnemonic for instruction with sumbolic references resolved
      */
-    public String toString(final ConstantPool cp) {
+    public String toString( final ConstantPool cp ) {
         return toString(false);
     }
 
+
     /**
-     * Use with caution, since `BranchInstruction's have a `target' reference
-     * which is not copied correctly (only basic types are). This also applies
-     * for `Select' instructions with their multiple branch targets.
+     * Use with caution, since `BranchInstruction's have a `target' reference which
+     * is not copied correctly (only basic types are). This also applies for
+     * `Select' instructions with their multiple branch targets.
      *
      * @see BranchInstruction
      * @return (shallow) copy of an instruction
@@ -120,30 +127,30 @@
         return i;
     }
 
+
     /**
      * Read needed data (e.g. index) from file.
      *
      * @param bytes byte sequence to read from
      * @param wide "wide" instruction flag
-     * @throws IOException may be thrown if the implementation needs to read
-     * data from the file
+     * @throws IOException may be thrown if the implementation needs to read data from the file
      */
-    protected void initFromFile(final ByteSequence bytes, final boolean wide) throws IOException {
+    protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException {
     }
 
+
     /**
      * Read an instruction from (byte code) input stream and return the
      * appropiate object.
      * <p>
      * If the Instruction is defined in {@link InstructionConst}, then the
      * singleton instance is returned.
-     *
      * @param bytes input stream bytes
      * @return instruction object being read
      * @see InstructionConst#getInstruction(int)
      */
     // @since 6.0 no longer final
-    public static Instruction readInstruction(final ByteSequence bytes) throws IOException {
+    public static Instruction readInstruction( final ByteSequence bytes ) throws IOException {
         boolean wide = false;
         short opcode = (short) bytes.readUnsignedByte();
         Instruction obj = null;
@@ -463,27 +470,29 @@
     }
 
     /**
-     * This method also gives right results for instructions whose effect on the
-     * stack depends on the constant pool entry they reference.
-     *
-     * @return Number of words consumed from stack by this instruction, or
-     * Constants.UNPREDICTABLE, if this can not be computed statically
+     * This method also gives right results for instructions whose
+     * effect on the stack depends on the constant pool entry they
+     * reference.
+     *  @return Number of words consumed from stack by this instruction,
+     * or Constants.UNPREDICTABLE, if this can not be computed statically
      */
-    public int consumeStack(final ConstantPoolGen cpg) {
+    public int consumeStack( final ConstantPoolGen cpg ) {
         return Const.getConsumeStack(opcode);
     }
 
+
     /**
-     * This method also gives right results for instructions whose effect on the
-     * stack depends on the constant pool entry they reference.
-     *
-     * @return Number of words produced onto stack by this instruction, or
-     * Constants.UNPREDICTABLE, if this can not be computed statically
+     * This method also gives right results for instructions whose
+     * effect on the stack depends on the constant pool entry they
+     * reference.
+     * @return Number of words produced onto stack by this instruction,
+     * or Constants.UNPREDICTABLE, if this can not be computed statically
      */
-    public int produceStack(final ConstantPoolGen cpg) {
+    public int produceStack( final ConstantPoolGen cpg ) {
         return Const.getProduceStack(opcode);
     }
 
+
     /**
      * @return this instructions opcode
      */
@@ -491,6 +500,7 @@
         return opcode;
     }
 
+
     /**
      * @return length (in bytes) of instruction
      */
@@ -498,75 +508,71 @@
         return length;
     }
 
-    /**
-     * Needed in readInstruction and subclasses in this package
-     */
-    final void setOpcode(final short opcode) {
-        this.opcode = opcode;
-    }
 
     /**
      * Needed in readInstruction and subclasses in this package
-     *
+     */
+    final void setOpcode( final short opcode ) {
+        this.opcode = opcode;
+    }
+
+
+    /**
+     * Needed in readInstruction and subclasses in this package
      * @since 6.0
      */
-    final void setLength(final int length) {
+    final void setLength( final int length ) {
         this.length = (short) length; // TODO check range?
     }
 
-    /**
-     * Some instructions may be reused, so don't do anything by default.
+
+    /** Some instructions may be reused, so don't do anything by default.
      */
     void dispose() {
     }
 
+
     /**
-     * Call corresponding visitor method(s). The order is: Call visitor methods
-     * of implemented interfaces first, then call methods according to the class
-     * hierarchy in descending order, i.e., the most specific visitXXX() call
-     * comes last.
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
      *
      * @param v Visitor object
      */
-    public abstract void accept(Visitor v);
+    public abstract void accept( Visitor v );
+
 
-    /**
-     * Get Comparator object used in the equals() method to determine equality
-     * of instructions.
+    /** Get Comparator object used in the equals() method to determine
+     * equality of instructions.
      *
      * @return currently used comparator for equals()
-     * @deprecated (6.0) use the built in comparator, or wrap this class in
-     * another object that implements these methods
+     * @deprecated (6.0) use the built in comparator, or wrap this class in another object that implements these methods
      */
     @Deprecated
     public static InstructionComparator getComparator() {
         return cmp;
     }
 
-    /**
-     * Set comparator to be used for equals().
-     *
-     * @deprecated (6.0) use the built in comparator, or wrap this class in
-     * another object that implements these methods
+
+    /** Set comparator to be used for equals().
+      * @deprecated (6.0) use the built in comparator, or wrap this class in another object that implements these methods
      */
     @Deprecated
-    public static void setComparator(final InstructionComparator c) {
+    public static void setComparator( final InstructionComparator c ) {
         cmp = c;
     }
 
-    /**
-     * Check for equality, delegated to comparator
-     *
+
+    /** Check for equality, delegated to comparator
      * @return true if that is an Instruction and has the same opcode
      */
     @Override
-    public boolean equals(final Object that) {
+    public boolean equals( final Object that ) {
         return (that instanceof Instruction) ? cmp.equals(this, (Instruction) that) : false;
     }
 
-    /**
-     * calculate the hashCode of this object
-     *
+    /** calculate the hashCode of this object
      * @return the hashCode
      * @since 6.0
      */
@@ -577,7 +583,6 @@
 
     /**
      * Check if the value can fit in a byte (signed)
-     *
      * @param value the value to check
      * @return true if the value is in range
      * @since 6.0
@@ -588,7 +593,6 @@
 
     /**
      * Check if the value can fit in a short (signed)
-     *
      * @param value the value to check
      * @return true if the value is in range
      * @since 6.0
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionComparator.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionComparator.java	Mon Jul 01 14:57:02 2019 -0700
@@ -31,7 +31,7 @@
  * instructions must have the same target.
  *
  * @see Instruction
- * @version $Id: InstructionComparator.java 1749597 2016-06-21 20:28:51Z ggregory $
+ * @version $Id$
  */
 public interface InstructionComparator {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionConst.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionConst.java	Mon Jul 01 14:57:02 2019 -0700
@@ -37,7 +37,7 @@
  * The Instructions can also accessed directly under their names, so
  * it's possible to write il.append(Instruction.ICONST_0);
  *
- * @version $Id: InstructionConst.java 1695415 2015-08-12 01:02:39Z chas $
+ * @version $Id: InstructionConstants.java 1695415 2015-08-12 01:02:39Z chas $
  */
 public final class InstructionConst {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionFactory.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionFactory.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -22,23 +22,24 @@
 import com.sun.org.apache.bcel.internal.Const;
 
 /**
- * Instances of this class may be used, e.g., to generate typed versions of
- * instructions. Its main purpose is to be used as the byte code generating
- * backend of a compiler. You can subclass it to add your own create methods.
+ * Instances of this class may be used, e.g., to generate typed
+ * versions of instructions. Its main purpose is to be used as the
+ * byte code generating backend of a compiler. You can subclass it to
+ * add your own create methods.
  * <p>
- * Note: The static createXXX methods return singleton instances from the
- * {@link InstructionConst} class.
+ * Note: The static createXXX methods return singleton instances
+ * from the {@link InstructionConst} class.
  *
- * @version $Id: InstructionFactory.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
  * @see Const
  * @see InstructionConst
- * @LastModified: Nov 2017
+ * @LastModified: Jun 2019
  */
 public class InstructionFactory {
 
     // N.N. These must agree with the order of Constants.T_CHAR through T_LONG
     private static final String[] short_names = {
-        "C", "F", "D", "B", "S", "I", "L"
+            "C", "F", "D", "B", "S", "I", "L"
     };
 
     private ClassGen cg;
@@ -49,33 +50,33 @@
         this.cp = cp;
     }
 
-    /**
-     * Initialize with ClassGen object
+
+    /** Initialize with ClassGen object
      */
     public InstructionFactory(final ClassGen cg) {
         this(cg, cg.getConstantPool());
     }
 
-    /**
-     * Initialize just with ConstantPoolGen object
+
+    /** Initialize just with ConstantPoolGen object
      */
     public InstructionFactory(final ConstantPoolGen cp) {
         this(null, cp);
     }
 
-    /**
-     * Create an invoke instruction. (Except for invokedynamic.)
+
+    /** Create an invoke instruction. (Except for invokedynamic.)
      *
      * @param class_name name of the called class
      * @param name name of the called method
      * @param ret_type return type of method
      * @param arg_types argument types of method
-     * @param kind how to invoke, i.e., INVOKEINTERFACE, INVOKESTATIC,
-     * INVOKEVIRTUAL, or INVOKESPECIAL
+     * @param kind how to invoke, i.e., INVOKEINTERFACE, INVOKESTATIC, INVOKEVIRTUAL,
+     * or INVOKESPECIAL
      * @see Const
      */
-    public InvokeInstruction createInvoke(final String class_name, final String name, final Type ret_type,
-            final Type[] arg_types, final short kind) {
+    public InvokeInstruction createInvoke( final String class_name, final String name,
+            final Type ret_type, final Type[] arg_types, final short kind ) {
         int index;
         int nargs = 0;
         final String signature = Type.getMethodSignature(ret_type, arg_types);
@@ -103,8 +104,7 @@
         }
     }
 
-    /**
-     * Create an invokedynamic instruction.
+    /** Create an invokedynamic instruction.
      *
      * @param bootstrap_index index into the bootstrap_methods array
      * @param name name of the called method
@@ -112,30 +112,30 @@
      * @param arg_types argument types of method
      * @see Constants
      */
-    /*
-     * createInvokeDynamic only needed if instrumention code wants to generate
-     * a new invokedynamic instruction.  I don't think we need.  (markro)
-     *
-     public InvokeInstruction createInvokeDynamic( int bootstrap_index, String name, Type ret_type,
-     Type[] arg_types) {
-     int index;
-     int nargs = 0;
-     String signature = Type.getMethodSignature(ret_type, arg_types);
-     for (int i = 0; i < arg_types.length; i++) {
-     nargs += arg_types[i].getSize();
-     }
-     // UNDONE - needs to be added to ConstantPoolGen
-     //index = cp.addInvokeDynamic(bootstrap_index, name, signature);
-     index = 0;
-     return new INVOKEDYNAMIC(index);
-     }
-     */
-    /**
-     * Create a call to the most popular System.out.println() method.
+/*
+ * createInvokeDynamic only needed if instrumention code wants to generate
+ * a new invokedynamic instruction.  I don't think we need.  (markro)
+ *
+    public InvokeInstruction createInvokeDynamic( int bootstrap_index, String name, Type ret_type,
+            Type[] arg_types) {
+        int index;
+        int nargs = 0;
+        String signature = Type.getMethodSignature(ret_type, arg_types);
+        for (int i = 0; i < arg_types.length; i++) {
+            nargs += arg_types[i].getSize();
+        }
+        // UNDONE - needs to be added to ConstantPoolGen
+        //index = cp.addInvokeDynamic(bootstrap_index, name, signature);
+        index = 0;
+        return new INVOKEDYNAMIC(index);
+    }
+ */
+
+    /** Create a call to the most popular System.out.println() method.
      *
      * @param s the string to print
      */
-    public InstructionList createPrintln(final String s) {
+    public InstructionList createPrintln( final String s ) {
         final InstructionList il = new InstructionList();
         final int out = cp.addFieldref("java.lang.System", "out", "Ljava/io/PrintStream;");
         final int println = cp.addMethodref("java.io.PrintStream", "println", "(Ljava/lang/String;)V");
@@ -145,12 +145,11 @@
         return il;
     }
 
-    /**
-     * Uses PUSH to push a constant value onto the stack.
-     *
+
+    /** Uses PUSH to push a constant value onto the stack.
      * @param value must be of type Number, Boolean, Character or String
      */
-    public Instruction createConstant(final Object value) {
+    public Instruction createConstant( final Object value ) {
         PUSH push;
         if (value instanceof Number) {
             push = new PUSH(cp, (Number) value);
@@ -173,6 +172,7 @@
         final String class_name;
         final String name;
 
+
         MethodObject(final String c, final String n, final Type r, final Type[] a) {
             class_name = c;
             name = n;
@@ -181,53 +181,56 @@
         }
     }
 
-    private InvokeInstruction createInvoke(final MethodObject m, final short kind) {
+
+    private InvokeInstruction createInvoke( final MethodObject m, final short kind ) {
         return createInvoke(m.class_name, m.name, m.result_type, m.arg_types, kind);
     }
 
     private static final MethodObject[] append_mos = {
-        new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[]{
-            Type.STRING
-        }),
-        new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[]{
-            Type.OBJECT
-        }),
-        null,
-        null, // indices 2, 3
-        new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[]{
-            Type.BOOLEAN
-        }),
-        new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[]{
-            Type.CHAR
-        }),
-        new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[]{
-            Type.FLOAT
-        }),
-        new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[]{
-            Type.DOUBLE
-        }),
-        new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[]{
-            Type.INT
-        }),
-        new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, // No append(byte)
-        new Type[]{
-            Type.INT
-        }),
-        new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, // No append(short)
-        new Type[]{
-            Type.INT
-        }),
-        new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[]{
-            Type.LONG
-        })
+            new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[] {
+                Type.STRING
+            }),
+            new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[] {
+                Type.OBJECT
+            }),
+            null,
+            null, // indices 2, 3
+            new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[] {
+                Type.BOOLEAN
+            }),
+            new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[] {
+                Type.CHAR
+            }),
+            new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[] {
+                Type.FLOAT
+            }),
+            new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[] {
+                Type.DOUBLE
+            }),
+            new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[] {
+                Type.INT
+            }),
+            new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, // No append(byte)
+                    new Type[] {
+                        Type.INT
+                    }),
+            new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, // No append(short)
+                    new Type[] {
+                        Type.INT
+                    }),
+            new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[] {
+                Type.LONG
+            })
     };
 
-    private static boolean isString(final Type type) {
-        return (type instanceof ObjectType)
-                && ((ObjectType) type).getClassName().equals("java.lang.String");
+
+    private static boolean isString( final Type type ) {
+        return (type instanceof ObjectType) &&
+              ((ObjectType) type).getClassName().equals("java.lang.String");
     }
 
-    public Instruction createAppend(final Type type) {
+
+    public Instruction createAppend( final Type type ) {
         final byte t = type.getType();
         if (isString(type)) {
             return createInvoke(append_mos[0], Const.INVOKEVIRTUAL);
@@ -250,16 +253,17 @@
         }
     }
 
-    /**
-     * Create a field instruction.
+
+    /** Create a field instruction.
      *
      * @param class_name name of the accessed class
      * @param name name of the referenced field
-     * @param type type of field
+     * @param type  type of field
      * @param kind how to access, i.e., GETFIELD, PUTFIELD, GETSTATIC, PUTSTATIC
      * @see Const
      */
-    public FieldInstruction createFieldAccess(final String class_name, final String name, final Type type, final short kind) {
+    public FieldInstruction createFieldAccess( final String class_name,
+            final String name, final Type type, final short kind ) {
         int index;
         final String signature = type.getSignature();
         index = cp.addFieldref(class_name, name, signature);
@@ -277,17 +281,17 @@
         }
     }
 
-    /**
-     * Create reference to `this'
+
+    /** Create reference to `this'
      */
     public static Instruction createThis() {
         return new ALOAD(0);
     }
 
-    /**
-     * Create typed return
+
+    /** Create typed return
      */
-    public static ReturnInstruction createReturn(final Type type) {
+    public static ReturnInstruction createReturn( final Type type ) {
         switch (type.getType()) {
             case Const.T_ARRAY:
             case Const.T_OBJECT:
@@ -311,7 +315,8 @@
         }
     }
 
-    private static ArithmeticInstruction createBinaryIntOp(final char first, final String op) {
+
+    private static ArithmeticInstruction createBinaryIntOp( final char first, final String op ) {
         switch (first) {
             case '-':
                 return InstructionConst.ISUB;
@@ -338,7 +343,8 @@
         }
     }
 
-    private static ArithmeticInstruction createBinaryLongOp(final char first, final String op) {
+
+    private static ArithmeticInstruction createBinaryLongOp( final char first, final String op ) {
         switch (first) {
             case '-':
                 return InstructionConst.LSUB;
@@ -365,7 +371,8 @@
         }
     }
 
-    private static ArithmeticInstruction createBinaryFloatOp(final char op) {
+
+    private static ArithmeticInstruction createBinaryFloatOp( final char op ) {
         switch (op) {
             case '-':
                 return InstructionConst.FSUB;
@@ -382,7 +389,8 @@
         }
     }
 
-    private static ArithmeticInstruction createBinaryDoubleOp(final char op) {
+
+    private static ArithmeticInstruction createBinaryDoubleOp( final char op ) {
         switch (op) {
             case '-':
                 return InstructionConst.DSUB;
@@ -399,12 +407,13 @@
         }
     }
 
+
     /**
      * Create binary operation for simple basic types, such as int and float.
      *
      * @param op operation, such as "+", "*", "&lt;&lt;", etc.
      */
-    public static ArithmeticInstruction createBinaryOperation(final String op, final Type type) {
+    public static ArithmeticInstruction createBinaryOperation( final String op, final Type type ) {
         final char first = op.charAt(0);
         switch (type.getType()) {
             case Const.T_BYTE:
@@ -423,38 +432,43 @@
         }
     }
 
+
     /**
      * @param size size of operand, either 1 (int, e.g.) or 2 (double)
      */
-    public static StackInstruction createPop(final int size) {
+    public static StackInstruction createPop( final int size ) {
         return (size == 2) ? InstructionConst.POP2 : InstructionConst.POP;
     }
 
+
     /**
      * @param size size of operand, either 1 (int, e.g.) or 2 (double)
      */
-    public static StackInstruction createDup(final int size) {
+    public static StackInstruction createDup( final int size ) {
         return (size == 2) ? InstructionConst.DUP2 : InstructionConst.DUP;
     }
 
+
     /**
      * @param size size of operand, either 1 (int, e.g.) or 2 (double)
      */
-    public static StackInstruction createDup_2(final int size) {
+    public static StackInstruction createDup_2( final int size ) {
         return (size == 2) ? InstructionConst.DUP2_X2 : InstructionConst.DUP_X2;
     }
 
+
     /**
      * @param size size of operand, either 1 (int, e.g.) or 2 (double)
      */
-    public static StackInstruction createDup_1(final int size) {
+    public static StackInstruction createDup_1( final int size ) {
         return (size == 2) ? InstructionConst.DUP2_X1 : InstructionConst.DUP_X1;
     }
 
+
     /**
      * @param index index of local variable
      */
-    public static LocalVariableInstruction createStore(final Type type, final int index) {
+    public static LocalVariableInstruction createStore( final Type type, final int index ) {
         switch (type.getType()) {
             case Const.T_BOOLEAN:
             case Const.T_CHAR:
@@ -476,10 +490,11 @@
         }
     }
 
+
     /**
      * @param index index of local variable
      */
-    public static LocalVariableInstruction createLoad(final Type type, final int index) {
+    public static LocalVariableInstruction createLoad( final Type type, final int index ) {
         switch (type.getType()) {
             case Const.T_BOOLEAN:
             case Const.T_CHAR:
@@ -501,10 +516,11 @@
         }
     }
 
+
     /**
      * @param type type of elements of array, i.e., array.getElementType()
      */
-    public static ArrayInstruction createArrayLoad(final Type type) {
+    public static ArrayInstruction createArrayLoad( final Type type ) {
         switch (type.getType()) {
             case Const.T_BOOLEAN:
             case Const.T_BYTE:
@@ -529,10 +545,11 @@
         }
     }
 
+
     /**
      * @param type type of elements of array, i.e., array.getElementType()
      */
-    public static ArrayInstruction createArrayStore(final Type type) {
+    public static ArrayInstruction createArrayStore( final Type type ) {
         switch (type.getType()) {
             case Const.T_BOOLEAN:
             case Const.T_BYTE:
@@ -562,7 +579,7 @@
      * instruction, e.g., if the operands are basic types and CHECKCAST if they
      * are reference types.
      */
-    public Instruction createCast(final Type src_type, final Type dest_type) {
+    public Instruction createCast( final Type src_type, final Type dest_type ) {
         if ((src_type instanceof BasicType) && (dest_type instanceof BasicType)) {
             final byte dest = dest_type.getType();
             byte src = src_type.getType();
@@ -589,41 +606,49 @@
         }
     }
 
-    public GETFIELD createGetField(final String class_name, final String name, final Type t) {
+
+    public GETFIELD createGetField( final String class_name, final String name, final Type t ) {
         return new GETFIELD(cp.addFieldref(class_name, name, t.getSignature()));
     }
 
-    public GETSTATIC createGetStatic(final String class_name, final String name, final Type t) {
+
+    public GETSTATIC createGetStatic( final String class_name, final String name, final Type t ) {
         return new GETSTATIC(cp.addFieldref(class_name, name, t.getSignature()));
     }
 
-    public PUTFIELD createPutField(final String class_name, final String name, final Type t) {
+
+    public PUTFIELD createPutField( final String class_name, final String name, final Type t ) {
         return new PUTFIELD(cp.addFieldref(class_name, name, t.getSignature()));
     }
 
-    public PUTSTATIC createPutStatic(final String class_name, final String name, final Type t) {
+
+    public PUTSTATIC createPutStatic( final String class_name, final String name, final Type t ) {
         return new PUTSTATIC(cp.addFieldref(class_name, name, t.getSignature()));
     }
 
-    public CHECKCAST createCheckCast(final ReferenceType t) {
+
+    public CHECKCAST createCheckCast( final ReferenceType t ) {
         if (t instanceof ArrayType) {
             return new CHECKCAST(cp.addArrayClass((ArrayType) t));
         }
         return new CHECKCAST(cp.addClass((ObjectType) t));
     }
 
-    public INSTANCEOF createInstanceOf(final ReferenceType t) {
+
+    public INSTANCEOF createInstanceOf( final ReferenceType t ) {
         if (t instanceof ArrayType) {
             return new INSTANCEOF(cp.addArrayClass((ArrayType) t));
         }
         return new INSTANCEOF(cp.addClass((ObjectType) t));
     }
 
-    public NEW createNew(final ObjectType t) {
+
+    public NEW createNew( final ObjectType t ) {
         return new NEW(cp.addClass(t));
     }
 
-    public NEW createNew(final String s) {
+
+    public NEW createNew( final String s ) {
         return createNew(ObjectType.getInstance(s));
     }
 
@@ -633,7 +658,7 @@
      * @return an instruction that creates the corresponding array at runtime,
      * i.e. is an AllocationInstruction
      */
-    public Instruction createNewArray(final Type t, final short dim) {
+    public Instruction createNewArray( final Type t, final short dim ) {
         if (dim == 1) {
             if (t instanceof ObjectType) {
                 return new ANEWARRAY(cp.addClass((ObjectType) t));
@@ -655,7 +680,7 @@
     /**
      * Create "null" value for reference types, 0 for basic types like int
      */
-    public static Instruction createNull(final Type type) {
+    public static Instruction createNull( final Type type ) {
         switch (type.getType()) {
             case Const.T_ARRAY:
             case Const.T_OBJECT:
@@ -683,7 +708,8 @@
      * Create branch instruction by given opcode, except LOOKUPSWITCH and
      * TABLESWITCH. For those you should use the SWITCH compound instruction.
      */
-    public static BranchInstruction createBranchInstruction(final short opcode, final InstructionHandle target) {
+    public static BranchInstruction createBranchInstruction( final short opcode,
+            final InstructionHandle target ) {
         switch (opcode) {
             case Const.IFEQ:
                 return new IFEQ(target);
@@ -730,18 +756,22 @@
         }
     }
 
-    public void setClassGen(final ClassGen c) {
+
+    public void setClassGen( final ClassGen c ) {
         cg = c;
     }
 
+
     public ClassGen getClassGen() {
         return cg;
     }
 
-    public void setConstantPool(final ConstantPoolGen c) {
+
+    public void setConstantPool( final ConstantPoolGen c ) {
         cp = c;
     }
 
+
     public ConstantPoolGen getConstantPool() {
         return cp;
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionHandle.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionHandle.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -32,13 +32,14 @@
  * an InstructionList. Instruction objects may be used more than once within a
  * list, this is useful because it saves memory and may be much faster.
  *
- * Within an InstructionList an InstructionHandle object is wrapped around all
- * instructions, i.e., it implements a cell in a doubly-linked list. From the
- * outside only the next and the previous instruction (handle) are accessible.
- * One can traverse the list via an Enumeration returned by
+ * Within an InstructionList an InstructionHandle object is wrapped
+ * around all instructions, i.e., it implements a cell in a
+ * doubly-linked list. From the outside only the next and the
+ * previous instruction (handle) are accessible. One
+ * can traverse the list via an Enumeration returned by
  * InstructionList.elements().
  *
- * @version $Id: InstructionHandle.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
  * @see Instruction
  * @see BranchHandle
  * @see InstructionList
@@ -54,23 +55,37 @@
     private Set<InstructionTargeter> targeters;
     private Map<Object, Object> attributes;
 
+
+    /**
+     * Does nothing.
+     *
+     * @deprecated Does nothing as of 6.3.1.
+     */
+    @Deprecated
+    protected void addHandle() {
+        // noop
+    }
+
     public final InstructionHandle getNext() {
         return next;
     }
 
+
     public final InstructionHandle getPrev() {
         return prev;
     }
 
+
     public final Instruction getInstruction() {
         return instruction;
     }
 
+
     /**
-     * Replace current instruction contained in this handle. Old instruction is
-     * disposed using Instruction.dispose().
+     * Replace current instruction contained in this handle.
+     * Old instruction is disposed using Instruction.dispose().
      */
-    public void setInstruction(final Instruction i) { // Overridden in BranchHandle TODO could be package-protected?
+    public void setInstruction( final Instruction i ) { // Overridden in BranchHandle TODO could be package-protected?
         if (i == null) {
             throw new ClassGenException("Assigning null to handle");
         }
@@ -83,91 +98,71 @@
         instruction = i;
     }
 
+
     /**
-     * Temporarily swap the current instruction, without disturbing anything.
-     * Meant to be used by a debugger, implementing breakpoints. Current
-     * instruction is returned.
+     * Temporarily swap the current instruction, without disturbing
+     * anything. Meant to be used by a debugger, implementing
+     * breakpoints. Current instruction is returned.
      * <p>
      * Warning: if this is used on a BranchHandle then some methods such as
-     * getPosition() will still refer to the original cached instruction,
-     * whereas other BH methods may affect the cache and the replacement
-     * instruction.
+     * getPosition() will still refer to the original cached instruction, whereas
+     * other BH methods may affect the cache and the replacement instruction.
      */
     // See BCEL-273
     // TODO remove this method in any redesign of BCEL
-    public Instruction swapInstruction(final Instruction i) {
+    public Instruction swapInstruction( final Instruction i ) {
         final Instruction oldInstruction = instruction;
         instruction = i;
         return oldInstruction;
     }
 
 
-    /*private*/
-    protected InstructionHandle(final Instruction i) {
+    /*private*/protected InstructionHandle(final Instruction i) {
         setInstruction(i);
     }
 
-    private static InstructionHandle ih_list = null; // List of reusable handles
-
-    /**
-     * Factory method.
+    /** Factory method.
      */
-    static InstructionHandle getInstructionHandle(final Instruction i) {
-        if (ih_list == null) {
-            return new InstructionHandle(i);
-        }
-        final InstructionHandle ih = ih_list;
-        ih_list = ih.next;
-        ih.setInstruction(i);
-        return ih;
+    static InstructionHandle getInstructionHandle( final Instruction i ) {
+        return new InstructionHandle(i);
     }
 
+
     /**
-     * Called by InstructionList.setPositions when setting the position for
-     * every instruction. In the presence of variable length instructions
-     * `setPositions()' performs multiple passes over the instruction list to
-     * calculate the correct (byte) positions and offsets by calling this
-     * function.
+     * Called by InstructionList.setPositions when setting the position for every
+     * instruction. In the presence of variable length instructions `setPositions()'
+     * performs multiple passes over the instruction list to calculate the
+     * correct (byte) positions and offsets by calling this function.
      *
-     * @param offset additional offset caused by preceding (variable length)
-     * instructions
-     * @param max_offset the maximum offset that may be caused by these
-     * instructions
-     * @return additional offset caused by possible change of this instruction's
-     * length
+     * @param offset additional offset caused by preceding (variable length) instructions
+     * @param max_offset the maximum offset that may be caused by these instructions
+     * @return additional offset caused by possible change of this instruction's length
      */
-    protected int updatePosition(final int offset, final int max_offset) {
+    protected int updatePosition( final int offset, final int max_offset ) {
         i_position += offset;
         return 0;
     }
 
-    /**
-     * @return the position, i.e., the byte code offset of the contained
-     * instruction. This is accurate only after InstructionList.setPositions()
-     * has been called.
+
+    /** @return the position, i.e., the byte code offset of the contained
+     * instruction. This is accurate only after
+     * InstructionList.setPositions() has been called.
      */
     public int getPosition() {
         return i_position;
     }
 
-    /**
-     * Set the position, i.e., the byte code offset of the contained
+
+    /** Set the position, i.e., the byte code offset of the contained
      * instruction.
      */
-    void setPosition(final int pos) {
+    void setPosition( final int pos ) {
         i_position = pos;
     }
 
-    /**
-     * Overridden in BranchHandle
-     */
-    protected void addHandle() {
-        next = ih_list;
-        ih_list = this;
-    }
 
     /**
-     * Delete contents, i.e., remove user access and make handle reusable.
+     * Delete contents, i.e., remove user access.
      */
     void dispose() {
         next = prev = null;
@@ -176,11 +171,10 @@
         i_position = -1;
         attributes = null;
         removeAllTargeters();
-        addHandle();
     }
 
-    /**
-     * Remove all targeters, if any.
+
+    /** Remove all targeters, if any.
      */
     public void removeAllTargeters() {
         if (targeters != null) {
@@ -188,19 +182,21 @@
         }
     }
 
+
     /**
      * Denote this handle isn't referenced anymore by t.
      */
-    public void removeTargeter(final InstructionTargeter t) {
+    public void removeTargeter( final InstructionTargeter t ) {
         if (targeters != null) {
             targeters.remove(t);
         }
     }
 
+
     /**
      * Denote this handle is being referenced by t.
      */
-    public void addTargeter(final InstructionTargeter t) {
+    public void addTargeter( final InstructionTargeter t ) {
         if (targeters == null) {
             targeters = new HashSet<>();
         }
@@ -208,10 +204,12 @@
         targeters.add(t);
     }
 
+
     public boolean hasTargeters() {
         return (targeters != null) && (targeters.size() > 0);
     }
 
+
     /**
      * @return null, if there are no targeters
      */
@@ -224,59 +222,59 @@
         return t;
     }
 
-    /**
-     * @return a (verbose) string representation of the contained instruction.
+
+    /** @return a (verbose) string representation of the contained instruction.
      */
-    public String toString(final boolean verbose) {
+    public String toString( final boolean verbose ) {
         return Utility.format(i_position, 4, false, ' ') + ": " + instruction.toString(verbose);
     }
 
-    /**
-     * @return a string representation of the contained instruction.
+
+    /** @return a string representation of the contained instruction.
      */
     @Override
     public String toString() {
         return toString(true);
     }
 
-    /**
-     * Add an attribute to an instruction handle.
+
+    /** Add an attribute to an instruction handle.
      *
      * @param key the key object to store/retrieve the attribute
      * @param attr the attribute to associate with this handle
      */
-    public void addAttribute(final Object key, final Object attr) {
+    public void addAttribute( final Object key, final Object attr ) {
         if (attributes == null) {
             attributes = new HashMap<>(3);
         }
         attributes.put(key, attr);
     }
 
-    /**
-     * Delete an attribute of an instruction handle.
+
+    /** Delete an attribute of an instruction handle.
      *
      * @param key the key object to retrieve the attribute
      */
-    public void removeAttribute(final Object key) {
+    public void removeAttribute( final Object key ) {
         if (attributes != null) {
             attributes.remove(key);
         }
     }
 
-    /**
-     * Get attribute of an instruction handle.
+
+    /** Get attribute of an instruction handle.
      *
      * @param key the key object to store/retrieve the attribute
      */
-    public Object getAttribute(final Object key) {
+    public Object getAttribute( final Object key ) {
         if (attributes != null) {
             return attributes.get(key);
         }
         return null;
     }
 
-    /**
-     * @return all attributes associated with this handle
+
+    /** @return all attributes associated with this handle
      */
     public Collection<Object> getAttributes() {
         if (attributes == null) {
@@ -285,15 +283,16 @@
         return attributes.values();
     }
 
-    /**
-     * Convenience method, simply calls accept() on the contained instruction.
+
+    /** Convenience method, simply calls accept() on the contained instruction.
      *
      * @param v Visitor object
      */
-    public void accept(final Visitor v) {
+    public void accept( final Visitor v ) {
         instruction.accept(v);
     }
 
+
     /**
      * @param next the next to set
      * @ since 6.0
@@ -303,6 +302,7 @@
         return next;
     }
 
+
     /**
      * @param prev the prev to set
      * @ since 6.0
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionList.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionList.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
-/*
+ /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
@@ -44,12 +44,14 @@
  * A list is finally dumped to a byte code array with <a
  * href="#getByteCode()">getByteCode</a>.
  *
- * @version $Id: InstructionList.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
  * @see Instruction
  * @see InstructionHandle
  * @see BranchHandle
+ * @LastModified: Jun 2019
  */
 public class InstructionList implements Iterable<InstructionHandle> {
+
     private InstructionHandle start = null;
     private InstructionHandle end = null;
     private int length = 0; // number of elements in list
@@ -191,12 +193,11 @@
         for (int i = 0; i < count; i++) {
             if (ihs[i] instanceof BranchHandle) {
                 final BranchInstruction bi = (BranchInstruction) ihs[i].getInstruction();
-                int target = bi.getPosition() + bi.getIndex(); /*
-                 * Byte code position: relative -> absolute.
+                int target = bi.getPosition() + bi.getIndex();
+                /*
+                                                                * Byte code position: relative -> absolute.
                  */
-
                 // Search for target position
-
                 InstructionHandle ih = findHandle(ihs, pos, count, target);
                 if (ih == null) {
                     throw new ClassGenException("Couldn't find target for branch: " + bi);
@@ -433,7 +434,6 @@
         } else {
             start = il.start; // Update start ...
         }
-
         length += il.length; // Update length
         il.clear();
         return ret;
@@ -468,7 +468,6 @@
             ih.setPrev(null);
             start = ih;
         }
-
         length++;
     }
 
@@ -843,26 +842,26 @@
                 if (i instanceof BranchInstruction) { // target instruction within list?
                     Instruction inst = ((BranchInstruction) i).getTarget().getInstruction();
                     if (!contains(inst)) {
-                        throw new ClassGenException("Branch target of " +
-                                Const.getOpcodeName(i.getOpcode()) + ":" +
-                                inst + " not in instruction list");
+                        throw new ClassGenException("Branch target of "
+                                + Const.getOpcodeName(i.getOpcode()) + ":"
+                                + inst + " not in instruction list");
                     }
                     if (i instanceof Select) {
                         final InstructionHandle[] targets = ((Select) i).getTargets();
                         for (final InstructionHandle target : targets) {
                             inst = target.getInstruction();
                             if (!contains(inst)) {
-                                throw new ClassGenException("Branch target of " +
-                                        Const.getOpcodeName(i.getOpcode()) + ":" +
-                                        inst + " not in instruction list");
+                                throw new ClassGenException("Branch target of "
+                                        + Const.getOpcodeName(i.getOpcode()) + ":"
+                                        + inst + " not in instruction list");
                             }
                         }
                     }
                     if (!(ih instanceof BranchHandle)) {
                         throw new ClassGenException(
-                                "Branch instruction " +
-                                        Const.getOpcodeName(i.getOpcode()) + ":" +
-                                        inst + " not contained in BranchHandle.");
+                                "Branch instruction "
+                                + Const.getOpcodeName(i.getOpcode()) + ":"
+                                + inst + " not contained in BranchHandle.");
                     }
                 }
             }
@@ -871,11 +870,9 @@
          * Pass 1: Set position numbers and sum up the maximum number of bytes an instruction may be shifted.
          */
         for (InstructionHandle ih = start; ih != null; ih = ih.getNext()) {
-
             final Instruction i = ih.getInstruction();
             ih.setPosition(index);
             pos[count++] = index;
-
             /*
              * Get an estimate about how many additional bytes may be added,
              * because BranchInstructions may have variable length depending on the target offset
@@ -908,7 +905,6 @@
         index = count = 0;
         for (InstructionHandle ih = start; ih != null; ih = ih.getNext()) {
             final Instruction i = ih.getInstruction();
-
             ih.setPosition(index);
             pos[count++] = index;
             index += i.getLength();
@@ -1040,7 +1036,8 @@
         final Map<InstructionHandle, InstructionHandle> map = new HashMap<>();
         final InstructionList il = new InstructionList();
         /*
-         * Pass 1: Make copies of all instructions, append them to the new list and associate old instruction references with the new ones, i.e., a 1:1 mapping.
+         * Pass 1: Make copies of all instructions, append them to the new list
+         * and associate old instruction references with the new ones, i.e., a 1:1 mapping.
          */
         for (InstructionHandle ih = start; ih != null; ih = ih.getNext()) {
             final Instruction i = ih.getInstruction();
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionListObserver.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionListObserver.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * Implement this interface if you're interested in changes to an InstructionList object
  * and register yourself with addObserver().
  *
- * @version $Id: InstructionListObserver.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public interface InstructionListObserver {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionTargeter.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionTargeter.java	Mon Jul 01 14:57:02 2019 -0700
@@ -28,7 +28,7 @@
  * @see BranchHandle
  * @see LocalVariableGen
  * @see CodeExceptionGen
- * @version $Id: InstructionTargeter.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public interface InstructionTargeter {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InvokeInstruction.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InvokeInstruction.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,6 +1,5 @@
 /*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -31,14 +30,15 @@
 /**
  * Super class for the INVOKExxx family of instructions.
  *
- * @version $Id: InvokeInstruction.java 1752106 2016-07-10 20:02:39Z britter $
+ * @version $Id$
+ * @LastModified: Jun 2019
  */
 public abstract class InvokeInstruction extends FieldOrMethod implements ExceptionThrower,
         StackConsumer, StackProducer {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     InvokeInstruction() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/JSR.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/JSR.java	Mon Jul 01 14:57:02 2019 -0700
@@ -27,13 +27,13 @@
 /**
  * JSR - Jump to subroutine
  *
- * @version $Id: JSR.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
  */
 public class JSR extends JsrInstruction implements VariableLengthInstruction {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     JSR() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/JSR_W.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/JSR_W.java	Mon Jul 01 14:57:02 2019 -0700
@@ -29,13 +29,13 @@
 /**
  * JSR_W - Jump to subroutine
  *
- * @version $Id: JSR_W.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class JSR_W extends JsrInstruction {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     JSR_W() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/JsrInstruction.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/JsrInstruction.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,7 +24,7 @@
 /**
  * Super class for JSR - Jump to subroutine
  *
- * @version $Id: JsrInstruction.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
  */
 public abstract class JsrInstruction extends BranchInstruction implements UnconditionalBranch,
         TypedInstruction, StackProducer {
@@ -35,8 +35,8 @@
 
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     JsrInstruction() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/L2D.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/L2D.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * L2D - Convert long to double
  * <PRE>Stack: ..., value.word1, value.word2 -&gt; ..., result.word1, result.word2</PRE>
  *
- * @version $Id: L2D.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class L2D extends ConversionInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/L2F.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/L2F.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * L2F - Convert long to float
  * <PRE>Stack: ..., value.word1, value.word2 -&gt; ..., result</PRE>
  *
- * @version $Id: L2F.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class L2F extends ConversionInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/L2I.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/L2I.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * L2I - Convert long to int
  * <PRE>Stack: ..., value.word1, value.word2 -&gt; ..., result</PRE>
  *
- * @version $Id: L2I.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class L2I extends ConversionInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LADD.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LADD.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,7 +26,7 @@
  * <PRE>Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -&gt;</PRE>
  *        ..., result.word1, result.word2
  *
- * @version $Id: LADD.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class LADD extends ArithmeticInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LALOAD.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LALOAD.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * LALOAD - Load long from array
  * <PRE>Stack: ..., arrayref, index -&gt; ..., value1, value2</PRE>
  *
- * @version $Id: LALOAD.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class LALOAD extends ArrayInstruction implements StackProducer {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LAND.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LAND.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,7 +26,7 @@
  * <PRE>Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -&gt;</PRE>
  *        ..., result.word1, result.word2
  *
- * @version $Id: LAND.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class LAND extends ArithmeticInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LASTORE.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LASTORE.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * LASTORE -  Store into long array
  * <PRE>Stack: ..., arrayref, index, value.word1, value.word2 -&gt; ...</PRE>
  *
- * @version $Id: LASTORE.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class LASTORE extends ArrayInstruction implements StackConsumer {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LCMP.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LCMP.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,7 +26,7 @@
  * <PRE>Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -&gt; ..., result &lt;= -1, 0, 1&gt;</PRE>
  *
  *
- * @version $Id: LCMP.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class LCMP extends Instruction implements TypedInstruction, StackProducer, StackConsumer {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LCONST.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LCONST.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  *
  * <PRE>Stack: ... -&gt; ..., </PRE>
  *
- * @version $Id: LCONST.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class LCONST extends Instruction implements ConstantPushInstruction {
 
@@ -33,8 +33,8 @@
 
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     LCONST() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -31,14 +31,14 @@
  *
  * <PRE>Stack: ... -&gt; ..., item</PRE>
  *
- * @version $Id: LDC.java 1749603 2016-06-21 20:50:19Z ggregory $
- * @LastModified: Nov 2017
+ * @version $Id$
+ * @LastModified: Jun 2019
  */
 public class LDC extends CPInstruction implements PushInstruction, ExceptionThrower {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     LDC() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC2_W.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC2_W.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -25,14 +25,14 @@
  *
  * <PRE>Stack: ... -&gt; ..., item.word1, item.word2</PRE>
  *
- * @version $Id: LDC2_W.java 1749603 2016-06-21 20:50:19Z ggregory $
- * @LastModified: Nov 2017
+ * @version $Id$
+ * @LastModified: Jun 2019
  */
 public class LDC2_W extends CPInstruction implements PushInstruction {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     LDC2_W() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC_W.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC_W.java	Mon Jul 01 14:57:02 2019 -0700
@@ -30,13 +30,13 @@
  *
  * <PRE>Stack: ... -&gt; ..., item.word1, item.word2</PRE>
  *
- * @version $Id: LDC_W.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class LDC_W extends LDC {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     LDC_W() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDIV.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDIV.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -27,8 +27,8 @@
  * <PRE>Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -&gt;</PRE>
  *        ..., result.word1, result.word2
  *
- * @version $Id: LDIV.java 1747278 2016-06-07 17:28:43Z britter $
- * @LastModified: Oct 2017
+ * @version $Id$
+ * @LastModified: Jun 2019
  */
 public class LDIV extends ArithmeticInstruction implements ExceptionThrower {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LLOAD.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LLOAD.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,13 +25,13 @@
  * LLOAD - Load long from local variable
  *<PRE>Stack ... -&gt; ..., result.word1, result.word2</PRE>
  *
- * @version $Id: LLOAD.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class LLOAD extends LoadInstruction {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     LLOAD() {
         super(com.sun.org.apache.bcel.internal.Const.LLOAD, com.sun.org.apache.bcel.internal.Const.LLOAD_0);
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LMUL.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LMUL.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,7 +26,7 @@
  * <PRE>Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -&gt;</PRE>
  *        ..., result.word1, result.word2
  *
- * @version $Id: LMUL.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class LMUL extends ArithmeticInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LNEG.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LNEG.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * LNEG - Negate long
  * <PRE>Stack: ..., value.word1, value.word2 -&gt; ..., result.word1, result.word2</PRE>
  *
- * @version $Id: LNEG.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class LNEG extends ArithmeticInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LOOKUPSWITCH.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LOOKUPSWITCH.java	Mon Jul 01 14:57:02 2019 -0700
@@ -29,14 +29,14 @@
 /**
  * LOOKUPSWITCH - Switch with unordered set of values
  *
- * @version $Id: LOOKUPSWITCH.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  * @see SWITCH
  */
 public class LOOKUPSWITCH extends Select {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     LOOKUPSWITCH() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LOR.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LOR.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * LOR - Bitwise OR long
  * <PRE>Stack: ..., value1, value2 -&gt; ..., result</PRE>
  *
- * @version $Id: LOR.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class LOR extends ArithmeticInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LREM.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LREM.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -26,8 +26,8 @@
  * LREM - Remainder of long
  * <PRE>Stack: ..., value1, value2 -&gt; result</PRE>
  *
- * @version $Id: LREM.java 1747278 2016-06-07 17:28:43Z britter $
- * @LastModified: Oct 2017
+ * @version $Id$
+ * @LastModified: Jun 2019
  */
 public class LREM extends ArithmeticInstruction implements ExceptionThrower {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LRETURN.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LRETURN.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * LRETURN -  Return long from method
  * <PRE>Stack: ..., value.word1, value.word2 -&gt; &lt;empty&gt;</PRE>
  *
- * @version $Id: LRETURN.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class LRETURN extends ReturnInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSHL.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSHL.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * LSHL - Arithmetic shift left long
  * <PRE>Stack: ..., value1.word1, value1.word2, value2 -&gt; ..., result.word1, result.word2</PRE>
  *
- * @version $Id: LSHL.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class LSHL extends ArithmeticInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSHR.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSHR.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * LSHR - Arithmetic shift right long
  * <PRE>Stack: ..., value1.word1, value1.word2, value2 -&gt; ..., result.word1, result.word2</PRE>
  *
- * @version $Id: LSHR.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class LSHR extends ArithmeticInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSTORE.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSTORE.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,13 +25,13 @@
  * LSTORE - Store long into local variable
  * <PRE>Stack: ..., value.word1, value.word2 -&gt; ... </PRE>
  *
- * @version $Id: LSTORE.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class LSTORE extends StoreInstruction {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     LSTORE() {
         super(com.sun.org.apache.bcel.internal.Const.LSTORE, com.sun.org.apache.bcel.internal.Const.LSTORE_0);
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSUB.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSUB.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,7 +26,7 @@
  * <PRE>Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -&gt;</PRE>
  *        ..., result.word1, result.word2
  *
- * @version $Id: LSUB.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class LSUB extends ArithmeticInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LUSHR.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LUSHR.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * LUSHR - Logical shift right long
  * <PRE>Stack: ..., value1, value2 -&gt; ..., result</PRE>
  *
- * @version $Id: LUSHR.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class LUSHR extends ArithmeticInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LXOR.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LXOR.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * LXOR - Bitwise XOR long
  * <PRE>Stack: ..., value1, value2 -&gt; ..., result</PRE>
  *
- * @version $Id: LXOR.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class LXOR extends ArithmeticInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LineNumberGen.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LineNumberGen.java	Mon Jul 01 14:57:02 2019 -0700
@@ -27,7 +27,7 @@
  * This class represents a line number within a method, i.e., give an instruction
  * a line number corresponding to the source code line.
  *
- * @version $Id: LineNumberGen.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
  * @see     LineNumber
  * @see     MethodGen
  */
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LoadClass.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LoadClass.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * Denotes that an instruction may start the process of loading and resolving
  * the referenced class in the Virtual Machine.
  *
- * @version $Id: LoadClass.java 1749597 2016-06-21 20:28:51Z ggregory $
+ * @version $Id$
  */
 public interface LoadClass {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LoadInstruction.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LoadInstruction.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,13 +25,13 @@
  * Denotes an unparameterized instruction to load a value from a local
  * variable, e.g. ILOAD.
  *
- * @version $Id: LoadInstruction.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public abstract class LoadInstruction extends LocalVariableInstruction implements PushInstruction {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      * tag and length are defined in readInstruction and initFromFile, respectively.
      */
     LoadInstruction(final short canon_tag, final short c_tag) {
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LocalVariableGen.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LocalVariableGen.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,13 +25,13 @@
 
 /**
  * This class represents a local variable within a method. It contains its
- * scope, name and type. The generated LocalVariable object can be obtained with
- * getLocalVariable which needs the instruction list and the constant pool as
- * parameters.
+ * scope, name and type. The generated LocalVariable object can be obtained
+ * with getLocalVariable which needs the instruction list and the constant
+ * pool as parameters.
  *
- * @version $Id: LocalVariableGen.java 1749603 2016-06-21 20:50:19Z ggregory $
- * @see LocalVariable
- * @see MethodGen
+ * @version $Id$
+ * @see     LocalVariable
+ * @see     MethodGen
  */
 public class LocalVariableGen implements InstructionTargeter, NamedAndTyped, Cloneable {
 
@@ -40,21 +40,22 @@
     private Type type;
     private InstructionHandle start;
     private InstructionHandle end;
+    private int orig_index; // never changes; used to match up with LocalVariableTypeTable entries
+    private boolean live_to_end;
+
 
     /**
-     * Generate a local variable that with index `index'. Note that double and
-     * long variables need two indexs. Index indices have to be provided by the
-     * user.
+     * Generate a local variable that with index `index'. Note that double and long
+     * variables need two indexs. Index indices have to be provided by the user.
      *
      * @param index index of local variable
      * @param name its name
      * @param type its type
-     * @param start from where the instruction is valid (null means from the
-     * start)
+     * @param start from where the instruction is valid (null means from the start)
      * @param end until where the instruction is valid (null means to the end)
      */
-    public LocalVariableGen(final int index, final String name, final Type type,
-            final InstructionHandle start, final InstructionHandle end) {
+    public LocalVariableGen(final int index, final String name, final Type type, final InstructionHandle start,
+            final InstructionHandle end) {
         if ((index < 0) || (index > Const.MAX_SHORT)) {
             throw new ClassGenException("Invalid index index: " + index);
         }
@@ -63,90 +64,137 @@
         this.index = index;
         setStart(start);
         setEnd(end);
+        this.orig_index = index;
+        this.live_to_end = end == null;
     }
 
+
+    /**
+     * Generate a local variable that with index `index'. Note that double and long
+     * variables need two indexs. Index indices have to be provided by the user.
+     *
+     * @param index index of local variable
+     * @param name its name
+     * @param type its type
+     * @param start from where the instruction is valid (null means from the start)
+     * @param end until where the instruction is valid (null means to the end)
+     * @param orig_index index of local variable prior to any changes to index
+     */
+    public LocalVariableGen(final int index, final String name, final Type type, final InstructionHandle start,
+            final InstructionHandle end, final int orig_index) {
+        this(index, name, type, start, end);
+        this.orig_index = orig_index;
+    }
+
+
     /**
      * Get LocalVariable object.
      *
-     * This relies on that the instruction list has already been dumped to byte
-     * code or or that the `setPositions' methods has been called for the
-     * instruction list.
+     * This relies on that the instruction list has already been dumped to byte code or
+     * or that the `setPositions' methods has been called for the instruction list.
      *
-     * Note that for local variables whose scope end at the last instruction of
-     * the method's code, the JVM specification is ambiguous: both a
-     * start_pc+length ending at the last instruction and start_pc+length ending
-     * at first index beyond the end of the code are valid.
+     * Note that due to the conversion from byte code offset to InstructionHandle,
+     * it is impossible to tell the difference between a live range that ends BEFORE
+     * the last insturction of the method or a live range that ends AFTER the last
+     * instruction of the method.  Hence the live_to_end flag to differentiate
+     * between these two cases.
      *
      * @param cp constant pool
      */
-    public LocalVariable getLocalVariable(final ConstantPoolGen cp) {
+    public LocalVariable getLocalVariable( final ConstantPoolGen cp ) {
         int start_pc = 0;
         int length = 0;
         if ((start != null) && (end != null)) {
             start_pc = start.getPosition();
             length = end.getPosition() - start_pc;
-            if (end.getNext() == null) {
+            if ((end.getNext() == null) && live_to_end) {
                 length += end.getInstruction().getLength();
             }
         }
         final int name_index = cp.addUtf8(name);
         final int signature_index = cp.addUtf8(type.getSignature());
         return new LocalVariable(start_pc, length, name_index, signature_index, index, cp
-                .getConstantPool());
+                .getConstantPool(), orig_index);
     }
 
-    public void setIndex(final int index) {
+
+    public void setIndex( final int index ) {
         this.index = index;
     }
 
+
     public int getIndex() {
         return index;
     }
 
+
+    public int getOrigIndex() {
+        return orig_index;
+    }
+
+
+    public void setLiveToEnd( final boolean live_to_end) {
+        this.live_to_end = live_to_end;
+    }
+
+
+    public boolean getLiveToEnd() {
+        return live_to_end;
+    }
+
+
     @Override
-    public void setName(final String name) {
+    public void setName( final String name ) {
         this.name = name;
     }
 
+
     @Override
     public String getName() {
         return name;
     }
 
+
     @Override
-    public void setType(final Type type) {
+    public void setType( final Type type ) {
         this.type = type;
     }
 
+
     @Override
     public Type getType() {
         return type;
     }
 
+
     public InstructionHandle getStart() {
         return start;
     }
 
+
     public InstructionHandle getEnd() {
         return end;
     }
 
-    public void setStart(final InstructionHandle start) { // TODO could be package-protected?
+
+    public void setStart( final InstructionHandle start ) { // TODO could be package-protected?
         BranchInstruction.notifyTarget(this.start, start, this);
         this.start = start;
     }
 
-    public void setEnd(final InstructionHandle end) { // TODO could be package-protected?
+
+    public void setEnd( final InstructionHandle end ) { // TODO could be package-protected?
         BranchInstruction.notifyTarget(this.end, end, this);
         this.end = end;
     }
 
+
     /**
      * @param old_ih old target, either start or end
      * @param new_ih new target
      */
     @Override
-    public void updateTarget(final InstructionHandle old_ih, final InstructionHandle new_ih) {
+    public void updateTarget( final InstructionHandle old_ih, final InstructionHandle new_ih ) {
         boolean targeted = false;
         if (start == old_ih) {
             targeted = true;
@@ -174,10 +222,11 @@
      * @return true, if ih is target of this variable
      */
     @Override
-    public boolean containsTarget(final InstructionHandle ih) {
+    public boolean containsTarget( final InstructionHandle ih ) {
         return (start == ih) || (end == ih);
     }
 
+
     @Override
     public int hashCode() {
         // If the user changes the name or type, problems with the targeter hashmap will occur.
@@ -185,12 +234,13 @@
         return name.hashCode() ^ type.hashCode();
     }
 
+
     /**
      * We consider to local variables to be equal, if the use the same index and
      * are valid in the same range.
      */
     @Override
-    public boolean equals(final Object o) {
+    public boolean equals( final Object o ) {
         if (!(o instanceof LocalVariableGen)) {
             return false;
         }
@@ -198,11 +248,13 @@
         return (l.index == index) && (l.start == start) && (l.end == end);
     }
 
+
     @Override
     public String toString() {
         return "LocalVariableGen(" + name + ", " + type + ", " + start + ", " + end + ")";
     }
 
+
     @Override
     public Object clone() {
         try {
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LocalVariableInstruction.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LocalVariableInstruction.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -28,8 +28,8 @@
 /**
  * Abstract super class for instructions dealing with local variables.
  *
- * @version $Id: LocalVariableInstruction.java 1747278 2016-06-07 17:28:43Z
- * britter $
+ * @version $Id$
+ * @LastModified: Jun 2019
  */
 public abstract class LocalVariableInstruction extends Instruction implements TypedInstruction,
         IndexedInstruction {
@@ -38,14 +38,16 @@
     private short c_tag = -1; // compact version, such as ILOAD_0
     private short canon_tag = -1; // canonical tag such as ILOAD
 
+
     private boolean wide() {
         return n > Const.MAX_BYTE;
     }
 
+
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise. tag and length
-     * are defined in readInstruction and initFromFile, respectively.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
+     * tag and length are defined in readInstruction and initFromFile, respectively.
      */
     LocalVariableInstruction(final short canon_tag, final short c_tag) {
         super();
@@ -53,13 +55,15 @@
         this.c_tag = c_tag;
     }
 
+
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Also used by IINC()!
+     * Empty constructor needed for Instruction.readInstruction.
+     * Also used by IINC()!
      */
     LocalVariableInstruction() {
     }
 
+
     /**
      * @param opcode Instruction opcode
      * @param c_tag Instruction number for compact version, ALOAD_0, e.g.
@@ -72,13 +76,13 @@
         setIndex(n);
     }
 
+
     /**
      * Dump instruction as byte code to stream out.
-     *
      * @param out Output stream
      */
     @Override
-    public void dump(final DataOutputStream out) throws IOException {
+    public void dump( final DataOutputStream out ) throws IOException {
         if (wide()) {
             out.writeByte(Const.WIDE);
         }
@@ -92,25 +96,27 @@
         }
     }
 
+
     /**
      * Long output format:
      *
-     * &lt;name of opcode&gt; "["&lt;opcode number&gt;"]" "("&lt;length of
-     * instruction&gt;")" "&lt;"&lt; local variable index&gt;"&gt;"
+     * &lt;name of opcode&gt; "["&lt;opcode number&gt;"]"
+     * "("&lt;length of instruction&gt;")" "&lt;"&lt; local variable index&gt;"&gt;"
      *
      * @param verbose long/short format switch
      * @return mnemonic for instruction
      */
     @Override
-    public String toString(final boolean verbose) {
+    public String toString( final boolean verbose ) {
         final short _opcode = super.getOpcode();
         if (((_opcode >= Const.ILOAD_0) && (_opcode <= Const.ALOAD_3))
-                || ((_opcode >= Const.ISTORE_0) && (_opcode <= Const.ASTORE_3))) {
+         || ((_opcode >= Const.ISTORE_0) && (_opcode <= Const.ASTORE_3))) {
             return super.toString(verbose);
         }
         return super.toString(verbose) + " " + n;
     }
 
+
     /**
      * Read needed data (e.g. index) from file.
      * <pre>
@@ -118,14 +124,14 @@
      * </pre>
      */
     @Override
-    protected void initFromFile(final ByteSequence bytes, final boolean wide) throws IOException {
+    protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException {
         if (wide) {
             n = bytes.readUnsignedShort();
             super.setLength(4);
         } else {
             final short _opcode = super.getOpcode();
             if (((_opcode >= Const.ILOAD) && (_opcode <= Const.ALOAD))
-                    || ((_opcode >= Const.ISTORE) && (_opcode <= Const.ASTORE))) {
+             || ((_opcode >= Const.ISTORE) && (_opcode <= Const.ASTORE))) {
                 n = bytes.readUnsignedByte();
                 super.setLength(2);
             } else if (_opcode <= Const.ALOAD_3) { // compact load instruction such as ILOAD_2
@@ -138,6 +144,7 @@
         }
     }
 
+
     /**
      * @return local variable index (n) referred by this instruction.
      */
@@ -146,13 +153,15 @@
         return n;
     }
 
+
     /**
-     * Set the local variable index. also updates opcode and length TODO Why?
-     *
+     * Set the local variable index.
+     * also updates opcode and length
+     * TODO Why?
      * @see #setIndexOnly(int)
      */
     @Override
-    public void setIndex(final int n) { // TODO could be package-protected?
+    public void setIndex( final int n ) { // TODO could be package-protected?
         if ((n < 0) || (n > Const.MAX_SHORT)) {
             throw new ClassGenException("Illegal value: " + n);
         }
@@ -171,23 +180,24 @@
         }
     }
 
-    /**
-     * @return canonical tag for instruction, e.g., ALOAD for ALOAD_0
+
+    /** @return canonical tag for instruction, e.g., ALOAD for ALOAD_0
      */
     public short getCanonicalTag() {
         return canon_tag;
     }
 
+
     /**
-     * Returns the type associated with the instruction - in case of ALOAD or
-     * ASTORE Type.OBJECT is returned. This is just a bit incorrect, because
-     * ALOAD and ASTORE may work on every ReferenceType (including Type.NULL)
-     * and ASTORE may even work on a ReturnaddressType .
-     *
+     * Returns the type associated with the instruction -
+     * in case of ALOAD or ASTORE Type.OBJECT is returned.
+     * This is just a bit incorrect, because ALOAD and ASTORE
+     * may work on every ReferenceType (including Type.NULL) and
+     * ASTORE may even work on a ReturnaddressType .
      * @return type associated with the instruction
      */
     @Override
-    public Type getType(final ConstantPoolGen cp) {
+    public Type getType( final ConstantPoolGen cp ) {
         switch (canon_tag) {
             case Const.ILOAD:
             case Const.ISTORE:
@@ -211,7 +221,6 @@
 
     /**
      * Sets the index of the referenced variable (n) only
-     *
      * @since 6.0
      * @see #setIndex(int)
      */
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MONITORENTER.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MONITORENTER.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -26,8 +26,8 @@
  * MONITORENTER - Enter monitor for object
  * <PRE>Stack: ..., objectref -&gt; ...</PRE>
  *
- * @version $Id: MONITORENTER.java 1747278 2016-06-07 17:28:43Z britter $
- * @LastModified: Oct 2017
+ * @version $Id$
+ * @LastModified: Jun 2019
  */
 public class MONITORENTER extends Instruction implements ExceptionThrower, StackConsumer {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MONITOREXIT.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MONITOREXIT.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -26,8 +26,8 @@
  * MONITOREXIT - Exit monitor for object
  * <PRE>Stack: ..., objectref -&gt; ...</PRE>
  *
- * @version $Id: MONITOREXIT.java 1747278 2016-06-07 17:28:43Z britter $
- * @LastModified: Oct 2017
+ * @version $Id$
+ * @LastModified: Jun 2019
  */
 public class MONITOREXIT extends Instruction implements ExceptionThrower, StackConsumer {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MULTIANEWARRAY.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MULTIANEWARRAY.java	Mon Jul 01 14:57:02 2019 -0700
@@ -32,7 +32,7 @@
  * MULTIANEWARRAY - Create new mutidimensional array of references
  * <PRE>Stack: ..., count1, [count2, ...] -&gt; ..., arrayref</PRE>
  *
- * @version $Id: MULTIANEWARRAY.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class MULTIANEWARRAY extends CPInstruction implements LoadClass, AllocationInstruction,
         ExceptionThrower {
@@ -41,8 +41,8 @@
 
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     MULTIANEWARRAY() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MethodGen.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MethodGen.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -52,13 +52,13 @@
  * automatically for the code. Use stripAttributes() if you don't like this.
  *
  * While generating code it may be necessary to insert NOP operations. You can
- * use the `removeNOPs' method to get rid off them. The resulting method object
- * can be obtained via the `getMethod()' method.
+ * use the `removeNOPs' method to get rid off them.
+ * The resulting method object can be obtained via the `getMethod()' method.
  *
- * @version $Id: MethodGen.java 1749603 2016-06-21 20:50:19Z ggregory $
- * @see InstructionList
- * @see Method
- * @LastModified: Oct 2017
+ * @version $Id$
+ * @see     InstructionList
+ * @see     Method
+ * @LastModified: Jun 2019
  */
 public class MethodGen extends FieldGenOrMethodGen {
 
@@ -69,8 +69,8 @@
     private int max_stack;
     private InstructionList il;
     private boolean strip_attributes;
+    private LocalVariableTypeTable local_variable_type_table = null;
     private final List<LocalVariableGen> variable_vec = new ArrayList<>();
-    private final List<LocalVariableGen> type_vec = new ArrayList<>();
     private final List<LineNumberGen> line_number_vec = new ArrayList<>();
     private final List<CodeExceptionGen> exception_vec = new ArrayList<>();
     private final List<String> throws_vec = new ArrayList<>();
@@ -83,41 +83,42 @@
     private static BCELComparator bcelComparator = new BCELComparator() {
 
         @Override
-        public boolean equals(final Object o1, final Object o2) {
+        public boolean equals( final Object o1, final Object o2 ) {
             final MethodGen THIS = (MethodGen) o1;
             final MethodGen THAT = (MethodGen) o2;
             return THIS.getName().equals(THAT.getName())
                     && THIS.getSignature().equals(THAT.getSignature());
         }
 
+
         @Override
-        public int hashCode(final Object o) {
+        public int hashCode( final Object o ) {
             final MethodGen THIS = (MethodGen) o;
             return THIS.getSignature().hashCode() ^ THIS.getName().hashCode();
         }
     };
 
+
     /**
-     * Declare method. If the method is non-static the constructor automatically
-     * declares a local variable `$this' in slot 0. The actual code is contained
-     * in the `il' parameter, which may further manipulated by the user. But he
-     * must take care not to remove any instruction (handles) that are still
-     * referenced from this object.
+     * Declare method. If the method is non-static the constructor
+     * automatically declares a local variable `$this' in slot 0. The
+     * actual code is contained in the `il' parameter, which may further
+     * manipulated by the user. But he must take care not to remove any
+     * instruction (handles) that are still referenced from this object.
      *
      * For example one may not add a local variable and later remove the
-     * instructions it refers to without causing havoc. It is safe however if
-     * you remove that local variable, too.
+     * instructions it refers to without causing havoc. It is safe
+     * however if you remove that local variable, too.
      *
      * @param access_flags access qualifiers
-     * @param return_type method type
+     * @param return_type  method type
      * @param arg_types argument types
-     * @param arg_names argument names (if this is null, default names will be
-     * provided for them)
+     * @param arg_names argument names (if this is null, default names will be provided
+     * for them)
      * @param method_name name of method
-     * @param class_name class name containing this method (may be null, if you
-     * don't care)
-     * @param il instruction list associated with this method, may be null only
-     * for abstract or native methods
+     * @param class_name class name containing this method (may be null, if you don't care)
+     * @param il instruction list associated with this method, may be null only for
+     * abstract or native methods
      * @param cp constant pool
      */
     public MethodGen(final int access_flags, final Type return_type, final Type[] arg_types, String[] arg_names,
@@ -132,14 +133,14 @@
         setConstantPool(cp);
         final boolean abstract_ = isAbstract() || isNative();
         InstructionHandle start = null;
-        InstructionHandle end = null;
+        final InstructionHandle end = null;
         if (!abstract_) {
             start = il.getStart();
-            end = il.getEnd();
+            // end == null => live to end of method
             /* Add local variables, namely the implicit `this' and the arguments
              */
             if (!isStatic() && (class_name != null)) { // Instance method -> `this' is local var 0
-                addLocalVariable("this", ObjectType.getInstance(class_name), start, end);
+                addLocalVariable("this",  ObjectType.getInstance(class_name), start, end);
             }
         }
         if (arg_types != null) {
@@ -169,6 +170,7 @@
         }
     }
 
+
     /**
      * Instantiate from existing method.
      *
@@ -178,10 +180,11 @@
      */
     public MethodGen(final Method m, final String class_name, final ConstantPoolGen cp) {
         this(m.getAccessFlags(), Type.getReturnType(m.getSignature()), Type.getArgumentTypes(m
-                .getSignature()), null /* may be overridden anyway */, m.getName(), class_name,
+                .getSignature()), null /* may be overridden anyway */
+        , m.getName(), class_name,
                 ((m.getAccessFlags() & (Const.ACC_ABSTRACT | Const.ACC_NATIVE)) == 0)
-                ? new InstructionList(m.getCode().getCode())
-                : null, cp);
+                        ? new InstructionList(m.getCode().getCode())
+                        : null, cp);
         final Attribute[] attributes = m.getAttributes();
         for (final Attribute attribute : attributes) {
             Attribute a = attribute;
@@ -197,7 +200,7 @@
                         if (type > 0) {
                             final String cen = m.getConstantPool().getConstantString(type,
                                     Const.CONSTANT_Class);
-                            c_type = ObjectType.getInstance(cen);
+                            c_type =  ObjectType.getInstance(cen);
                         }
                         final int end_pc = ce.getEndPC();
                         final int length = m.getCode().getCode().length;
@@ -224,13 +227,9 @@
                             }
                         }
                     } else if (a instanceof LocalVariableTable) {
-                        final LocalVariable[] lv = ((LocalVariableTable) a).getLocalVariableTable();
-                        removeLocalVariables();
-                        repairHandles(lv, false);
+                        updateLocalVariableTable((LocalVariableTable) a);
                     } else if (a instanceof LocalVariableTypeTable) {
-                        LocalVariable[] lv = ((LocalVariableTypeTable) a).getLocalVariableTypeTable();
-                        removeLocalVariableTypes();
-                        repairHandles(lv, true);
+                        this.local_variable_type_table = (LocalVariableTypeTable) a.copy(cp.getConstantPool());
                     } else {
                         addCodeAttribute(a);
                     }
@@ -252,50 +251,28 @@
         }
     }
 
-    private void repairHandles(final LocalVariable[] lv, boolean isLVT) {
-        for (int k = 0; k < lv.length; k++) {
-            LocalVariable l = lv[k];
-            InstructionHandle start = il.findHandle(l.getStartPC());
-            InstructionHandle end = il.findHandle(l.getStartPC() + l.getLength());
-            // Repair malformed handles
-            if (null == start) {
-                start = il.getStart();
-            }
-            if (null == end) {
-                end = il.getEnd();
-            }
-            if (isLVT) {
-                addLocalVariableType(l.getName(), Type.getType(l.getSignature()),
-                        l.getIndex(), start, end);
-            } else {
-                addLocalVariable(l.getName(), Type.getType(l.getSignature()),
-                        l.getIndex(), start, end);
-            }
-        }
-    }
-
     /**
      * Adds a local variable to this method.
      *
      * @param name variable name
      * @param type variable type
-     * @param slot the index of the local variable, if type is long or double,
-     * the next available index is slot+2
+     * @param slot the index of the local variable, if type is long or double, the next available
+     * index is slot+2
      * @param start from where the variable is valid
      * @param end until where the variable is valid
+     * @param orig_index the index of the local variable prior to any modifications
      * @return new local variable object
      * @see LocalVariable
      */
-    public LocalVariableGen addLocalVariable(final String name, final Type type, final int slot,
-            final InstructionHandle start, final InstructionHandle end) {
-
+    public LocalVariableGen addLocalVariable( final String name, final Type type, final int slot,
+            final InstructionHandle start, final InstructionHandle end, final int orig_index ) {
         final byte t = type.getType();
         if (t != Const.T_ADDRESS) {
             final int add = type.getSize();
             if (slot + add > max_locals) {
                 max_locals = slot + add;
             }
-            final LocalVariableGen l = new LocalVariableGen(slot, name, type, start, end);
+            final LocalVariableGen l = new LocalVariableGen(slot, name, type, start, end, orig_index);
             int i;
             if ((i = variable_vec.indexOf(l)) >= 0) {
                 variable_vec.set(i, l);
@@ -308,23 +285,42 @@
                 + " as type for local variable");
     }
 
+
+    /**
+     * Adds a local variable to this method.
+     *
+     * @param name variable name
+     * @param type variable type
+     * @param slot the index of the local variable, if type is long or double, the next available
+     * index is slot+2
+     * @param start from where the variable is valid
+     * @param end until where the variable is valid
+     * @return new local variable object
+     * @see LocalVariable
+     */
+    public LocalVariableGen addLocalVariable( final String name, final Type type, final int slot,
+            final InstructionHandle start, final InstructionHandle end ) {
+        return addLocalVariable(name, type, slot, start, end, slot);
+    }
+
     /**
      * Adds a local variable to this method and assigns an index automatically.
      *
      * @param name variable name
      * @param type variable type
-     * @param start from where the variable is valid, if this is null, it is
-     * valid from the start
-     * @param end until where the variable is valid, if this is null, it is
-     * valid to the end
+     * @param start from where the variable is valid, if this is null,
+     * it is valid from the start
+     * @param end until where the variable is valid, if this is null,
+     * it is valid to the end
      * @return new local variable object
      * @see LocalVariable
      */
-    public LocalVariableGen addLocalVariable(final String name, final Type type,
-            final InstructionHandle start, final InstructionHandle end) {
+    public LocalVariableGen addLocalVariable( final String name, final Type type, final InstructionHandle start,
+            final InstructionHandle end ) {
         return addLocalVariable(name, type, max_locals, start, end);
     }
 
+
     /**
      * Remove a local variable, its slot will not be reused, if you do not use
      * addLocalVariable with an explicit index argument.
@@ -333,6 +329,7 @@
         variable_vec.remove(l);
     }
 
+
     /**
      * Remove all local variables.
      */
@@ -340,6 +337,7 @@
         variable_vec.clear();
     }
 
+
     /*
      * If the range of the variable has not been set yet, it will be set to be valid from
      * the start to the end of the instruction list.
@@ -347,44 +345,17 @@
      * @return array of declared local variables sorted by index
      */
     public LocalVariableGen[] getLocalVariables() {
-        return getLocalVariableOrTypes(false);
-    }
-
-    /*
-     * If the range of the variable has not been set yet, it will be set to be
-     * valid from the start to the end of the instruction list.
-     *
-     * @return array of declared local variable types sorted by index
-     */
-    private LocalVariableGen[] getLocalVariableTypes() {
-        return getLocalVariableOrTypes(true);
-    }
-
-    /*
-     * If the range of the variable or type has not been set yet, it will be set
-     * to be valid from the start to the end of the instruction list.
-     *
-     * @return array of declared local variables or types sorted by index
-     */
-    private LocalVariableGen[] getLocalVariableOrTypes(boolean isLVT) {
-        int size = (isLVT) ? type_vec.size() : variable_vec.size();
-        LocalVariableGen[] lg = new LocalVariableGen[size];
-        if (isLVT) {
-            type_vec.toArray(lg);
-        } else {
-            variable_vec.toArray(lg);
-        }
-
+        final int size = variable_vec.size();
+        final LocalVariableGen[] lg = new LocalVariableGen[size];
+        variable_vec.toArray(lg);
         for (int i = 0; i < size; i++) {
-            if (lg[i].getStart() == null) {
+            if ((lg[i].getStart() == null) && (il != null)) {
                 lg[i].setStart(il.getStart());
             }
-
-            if (lg[i].getEnd() == null) {
+            if ((lg[i].getEnd() == null) && (il != null)) {
                 lg[i].setEnd(il.getEnd());
             }
         }
-
         if (size > 1) {
             Arrays.sort(lg, new Comparator<LocalVariableGen>() {
                 @Override
@@ -393,15 +364,14 @@
                 }
             });
         }
-
         return lg;
     }
 
+
     /**
-     * @return `LocalVariableTable' attribute of all the local variables of this
-     * method.
+     * @return `LocalVariableTable' attribute of all the local variables of this method.
      */
-    public LocalVariableTable getLocalVariableTable(final ConstantPoolGen cp) {
+    public LocalVariableTable getLocalVariableTable( final ConstantPoolGen cp ) {
         final LocalVariableGen[] lg = getLocalVariables();
         final int size = lg.length;
         final LocalVariable[] lv = new LocalVariable[size];
@@ -413,68 +383,10 @@
     }
 
     /**
-     * @return `LocalVariableTypeTable' attribute of all the local variable
-     * types of this method.
-     */
-    public LocalVariableTypeTable getLocalVariableTypeTable(ConstantPoolGen cp) {
-        LocalVariableGen[] lg = getLocalVariableTypes();
-        int size = lg.length;
-        LocalVariable[] lv = new LocalVariable[size];
-
-        for (int i = 0; i < size; i++) {
-            lv[i] = lg[i].getLocalVariable(cp);
-        }
-
-        return new LocalVariableTypeTable(cp.addUtf8("LocalVariableTypeTable"),
-                2 + lv.length * 10, lv, cp.getConstantPool());
-    }
-
-    /**
-     * Adds a local variable type to this method.
-     *
-     * @param name variable name
-     * @param type variable type
-     * @param slot the index of the local variable, if type is long or double,
-     * the next available index is slot+2
-     * @param start from where the variable is valid
-     * @param end until where the variable is valid
-     * @return new local variable object
-     * @see LocalVariable
+     * @return `LocalVariableTypeTable' attribute of this method.
      */
-    private LocalVariableGen addLocalVariableType(String name, Type type, int slot,
-            InstructionHandle start,
-            InstructionHandle end) {
-        byte t = type.getType();
-
-        if (t != Const.T_ADDRESS) {
-            int add = type.getSize();
-
-            if (slot + add > max_locals) {
-                max_locals = slot + add;
-            }
-
-            LocalVariableGen l = new LocalVariableGen(slot, name, type, start, end);
-            int i;
-
-            if ((i = type_vec.indexOf(l)) >= 0) // Overwrite if necessary
-            {
-                type_vec.set(i, l);
-            } else {
-                type_vec.add(l);
-            }
-
-            return l;
-        } else {
-            throw new IllegalArgumentException("Can not use " + type
-                    + " as type for local variable");
-        }
-    }
-
-    /**
-     * Remove all local variable types.
-     */
-    private void removeLocalVariableTypes() {
-        type_vec.clear();
+    public LocalVariableTypeTable getLocalVariableTypeTable() {
+        return local_variable_type_table;
     }
 
     /**
@@ -484,19 +396,21 @@
      * @return new line number object
      * @see LineNumber
      */
-    public LineNumberGen addLineNumber(final InstructionHandle ih, final int src_line) {
+    public LineNumberGen addLineNumber( final InstructionHandle ih, final int src_line ) {
         final LineNumberGen l = new LineNumberGen(ih, src_line);
         line_number_vec.add(l);
         return l;
     }
 
+
     /**
      * Remove a line number.
      */
-    public void removeLineNumber(final LineNumberGen l) {
+    public void removeLineNumber( final LineNumberGen l ) {
         line_number_vec.remove(l);
     }
 
+
     /**
      * Remove all line numbers.
      */
@@ -504,6 +418,7 @@
         line_number_vec.clear();
     }
 
+
     /*
      * @return array of line numbers
      */
@@ -513,11 +428,11 @@
         return lg;
     }
 
+
     /**
-     * @return `LineNumberTable' attribute of all the local variables of this
-     * method.
+     * @return `LineNumberTable' attribute of all the local variables of this method.
      */
-    public LineNumberTable getLineNumberTable(final ConstantPoolGen cp) {
+    public LineNumberTable getLineNumberTable( final ConstantPoolGen cp ) {
         final int size = line_number_vec.size();
         final LineNumber[] ln = new LineNumber[size];
         for (int i = 0; i < size; i++) {
@@ -527,9 +442,10 @@
                 .getConstantPool());
     }
 
+
     /**
-     * Add an exception handler, i.e., specify region where a handler is active
-     * and an instruction where the actual handling is done.
+     * Add an exception handler, i.e., specify region where a handler is active and an
+     * instruction where the actual handling is done.
      *
      * @param start_pc Start of region (inclusive)
      * @param end_pc End of region (inclusive)
@@ -538,8 +454,8 @@
      * exception is handled
      * @return new exception handler object
      */
-    public CodeExceptionGen addExceptionHandler(final InstructionHandle start_pc,
-            final InstructionHandle end_pc, final InstructionHandle handler_pc, final ObjectType catch_type) {
+    public CodeExceptionGen addExceptionHandler( final InstructionHandle start_pc,
+            final InstructionHandle end_pc, final InstructionHandle handler_pc, final ObjectType catch_type ) {
         if ((start_pc == null) || (end_pc == null) || (handler_pc == null)) {
             throw new ClassGenException("Exception handler target is null instruction");
         }
@@ -548,13 +464,15 @@
         return c;
     }
 
+
     /**
      * Remove an exception handler.
      */
-    public void removeExceptionHandler(final CodeExceptionGen c) {
+    public void removeExceptionHandler( final CodeExceptionGen c ) {
         exception_vec.remove(c);
     }
 
+
     /**
      * Remove all line numbers.
      */
@@ -562,6 +480,7 @@
         exception_vec.clear();
     }
 
+
     /*
      * @return array of declared exception handlers
      */
@@ -571,6 +490,7 @@
         return cg;
     }
 
+
     /**
      * @return code exceptions for `Code' attribute
      */
@@ -578,28 +498,31 @@
         final int size = exception_vec.size();
         final CodeException[] c_exc = new CodeException[size];
         for (int i = 0; i < size; i++) {
-            final CodeExceptionGen c = exception_vec.get(i);
+            final CodeExceptionGen c =  exception_vec.get(i);
             c_exc[i] = c.getCodeException(super.getConstantPool());
         }
         return c_exc;
     }
 
+
     /**
      * Add an exception possibly thrown by this method.
      *
      * @param class_name (fully qualified) name of exception
      */
-    public void addException(final String class_name) {
+    public void addException( final String class_name ) {
         throws_vec.add(class_name);
     }
 
+
     /**
      * Remove an exception.
      */
-    public void removeException(final String c) {
+    public void removeException( final String c ) {
         throws_vec.remove(c);
     }
 
+
     /**
      * Remove all exceptions.
      */
@@ -607,6 +530,7 @@
         throws_vec.clear();
     }
 
+
     /*
      * @return array of thrown exceptions
      */
@@ -616,11 +540,11 @@
         return e;
     }
 
+
     /**
-     * @return `Exceptions' attribute of all the exceptions thrown by this
-     * method.
+     * @return `Exceptions' attribute of all the exceptions thrown by this method.
      */
-    private ExceptionTable getExceptionTable(final ConstantPoolGen cp) {
+    private ExceptionTable getExceptionTable( final ConstantPoolGen cp ) {
         final int size = throws_vec.size();
         final int[] ex = new int[size];
         for (int i = 0; i < size; i++) {
@@ -629,32 +553,45 @@
         return new ExceptionTable(cp.addUtf8("Exceptions"), 2 + 2 * size, ex, cp.getConstantPool());
     }
 
+
     /**
      * Add an attribute to the code. Currently, the JVM knows about the
-     * LineNumberTable, LocalVariableTable and StackMap attributes, where the
-     * former two will be generated automatically and the latter is used for the
-     * MIDP only. Other attributes will be ignored by the JVM but do no harm.
+     * LineNumberTable, LocalVariableTable and StackMap attributes,
+     * where the former two will be generated automatically and the
+     * latter is used for the MIDP only. Other attributes will be
+     * ignored by the JVM but do no harm.
      *
      * @param a attribute to be added
      */
-    public void addCodeAttribute(final Attribute a) {
+    public void addCodeAttribute( final Attribute a ) {
         code_attrs_vec.add(a);
     }
 
+
+    /**
+     * Remove the LocalVariableTypeTable
+     */
+    public void removeLocalVariableTypeTable( ) {
+        local_variable_type_table = null;
+    }
+
     /**
      * Remove a code attribute.
      */
-    public void removeCodeAttribute(final Attribute a) {
+    public void removeCodeAttribute( final Attribute a ) {
         code_attrs_vec.remove(a);
     }
 
+
     /**
      * Remove all code attributes.
      */
     public void removeCodeAttributes() {
+        local_variable_type_table = null;
         code_attrs_vec.clear();
     }
 
+
     /**
      * @return all attributes of this method.
      */
@@ -668,31 +605,31 @@
      * @since 6.0
      */
     public void addAnnotationsAsAttribute(final ConstantPoolGen cp) {
-        final Attribute[] attrs = AnnotationEntryGen.getAnnotationAttributes(cp, super.getAnnotationEntries());
+          final Attribute[] attrs = AnnotationEntryGen.getAnnotationAttributes(cp, super.getAnnotationEntries());
         for (final Attribute attr : attrs) {
             addAttribute(attr);
         }
-    }
+      }
 
     /**
      * @since 6.0
      */
-    public void addParameterAnnotationsAsAttribute(final ConstantPoolGen cp) {
-        if (!hasParameterAnnotations) {
-            return;
-        }
-        final Attribute[] attrs = AnnotationEntryGen.getParameterAnnotationAttributes(cp, param_annotations);
-        if (attrs != null) {
-            for (final Attribute attr : attrs) {
-                addAttribute(attr);
-            }
-        }
-    }
+      public void addParameterAnnotationsAsAttribute(final ConstantPoolGen cp) {
+          if (!hasParameterAnnotations) {
+              return;
+          }
+          final Attribute[] attrs = AnnotationEntryGen.getParameterAnnotationAttributes(cp,param_annotations);
+          if (attrs != null) {
+              for (final Attribute attr : attrs) {
+                  addAttribute(attr);
+              }
+          }
+      }
+
 
     /**
-     * Get method object. Never forget to call setMaxStack() or
-     * setMaxStack(max), respectively, before calling this method (the same
-     * applies for max locals).
+     * Get method object. Never forget to call setMaxStack() or setMaxStack(max), respectively,
+     * before calling this method (the same applies for max locals).
      *
      * @return method object
      */
@@ -709,19 +646,19 @@
         }
         LineNumberTable lnt = null;
         LocalVariableTable lvt = null;
-        LocalVariableTypeTable lvtt = null;
-
-        /* Create LocalVariableTable, LocalvariableTypeTable, and LineNumberTable
-         * attributes (for debuggers, e.g.)
+        /* Create LocalVariableTable and LineNumberTable attributes (for debuggers, e.g.)
          */
         if ((variable_vec.size() > 0) && !strip_attributes) {
+            updateLocalVariableTable(getLocalVariableTable(_cp));
             addCodeAttribute(lvt = getLocalVariableTable(_cp));
         }
-
-        if ((type_vec.size() > 0) && !strip_attributes) {
-            addCodeAttribute(lvtt = getLocalVariableTypeTable(_cp));
+        if (local_variable_type_table != null) {
+            // LocalVariable length in LocalVariableTypeTable is not updated automatically. It's a difference with LocalVariableTable.
+            if (lvt != null) {
+                adjustLocalVariableTypeTable(lvt);
+            }
+            addCodeAttribute(local_variable_type_table);
         }
-
         if ((line_number_vec.size() > 0) && !strip_attributes) {
             addCodeAttribute(lnt = getLineNumberTable(_cp));
         }
@@ -762,8 +699,8 @@
         if (lvt != null) {
             removeCodeAttribute(lvt);
         }
-        if (lvtt != null) {
-            removeCodeAttribute(lvtt);
+        if (local_variable_type_table != null) {
+            removeCodeAttribute(local_variable_type_table);
         }
         if (lnt != null) {
             removeCodeAttribute(lnt);
@@ -777,6 +714,41 @@
         return m;
     }
 
+    private void updateLocalVariableTable(final LocalVariableTable a) {
+        final LocalVariable[] lv = a.getLocalVariableTable();
+        removeLocalVariables();
+        for (final LocalVariable l : lv) {
+            InstructionHandle start = il.findHandle(l.getStartPC());
+            final InstructionHandle end = il.findHandle(l.getStartPC() + l.getLength());
+            // Repair malformed handles
+            if (null == start) {
+                start = il.getStart();
+            }
+            // end == null => live to end of method
+            // Since we are recreating the LocalVaraible, we must
+            // propagate the orig_index to new copy.
+            addLocalVariable(l.getName(), Type.getType(l.getSignature()), l
+                    .getIndex(), start, end, l.getOrigIndex());
+        }
+    }
+
+    private void adjustLocalVariableTypeTable(final LocalVariableTable lvt) {
+        final LocalVariable[] lv = lvt.getLocalVariableTable();
+        final LocalVariable[] lvg = local_variable_type_table.getLocalVariableTypeTable();
+
+        for (final LocalVariable element : lvg) {
+            for (final LocalVariable l : lv) {
+                if (element.getName().equals(l.getName()) && element.getIndex() == l.getOrigIndex()) {
+                    element.setLength(l.getLength());
+                    element.setStartPC(l.getStartPC());
+                    element.setIndex(l.getIndex());
+                    break;
+                }
+            }
+        }
+    }
+
+
     /**
      * Remove all NOPs from the instruction list (if possible) and update every
      * object referring to them, i.e., branch instructions, local variables and
@@ -804,92 +776,111 @@
         }
     }
 
+
     /**
      * Set maximum number of local variables.
      */
-    public void setMaxLocals(final int m) {
+    public void setMaxLocals( final int m ) {
         max_locals = m;
     }
 
+
     public int getMaxLocals() {
         return max_locals;
     }
 
+
     /**
      * Set maximum stack size for this method.
      */
-    public void setMaxStack(final int m) { // TODO could be package-protected?
+    public void setMaxStack( final int m ) { // TODO could be package-protected?
         max_stack = m;
     }
 
+
     public int getMaxStack() {
         return max_stack;
     }
 
-    /**
-     * @return class that contains this method
+
+    /** @return class that contains this method
      */
     public String getClassName() {
         return class_name;
     }
 
-    public void setClassName(final String class_name) { // TODO could be package-protected?
+
+    public void setClassName( final String class_name ) { // TODO could be package-protected?
         this.class_name = class_name;
     }
 
-    public void setReturnType(final Type return_type) {
+
+    public void setReturnType( final Type return_type ) {
         setType(return_type);
     }
 
+
     public Type getReturnType() {
         return getType();
     }
 
-    public void setArgumentTypes(final Type[] arg_types) {
+
+    public void setArgumentTypes( final Type[] arg_types ) {
         this.arg_types = arg_types;
     }
 
+
     public Type[] getArgumentTypes() {
         return arg_types.clone();
     }
 
-    public void setArgumentType(final int i, final Type type) {
+
+    public void setArgumentType( final int i, final Type type ) {
         arg_types[i] = type;
     }
 
-    public Type getArgumentType(final int i) {
+
+    public Type getArgumentType( final int i ) {
         return arg_types[i];
     }
 
-    public void setArgumentNames(final String[] arg_names) {
+
+    public void setArgumentNames( final String[] arg_names ) {
         this.arg_names = arg_names;
     }
 
+
     public String[] getArgumentNames() {
         return arg_names.clone();
     }
 
-    public void setArgumentName(final int i, final String name) {
+
+    public void setArgumentName( final int i, final String name ) {
         arg_names[i] = name;
     }
 
-    public String getArgumentName(final int i) {
+
+    public String getArgumentName( final int i ) {
         return arg_names[i];
     }
 
+
     public InstructionList getInstructionList() {
         return il;
     }
 
-    public void setInstructionList(final InstructionList il) { // TODO could be package-protected?
+
+    public void setInstructionList( final InstructionList il ) { // TODO could be package-protected?
         this.il = il;
     }
 
+
     @Override
     public String getSignature() {
         return Type.getMethodSignature(super.getType(), arg_types);
     }
 
+
     /**
      * Computes max. stack size by performing control flow analysis.
      */
@@ -901,6 +892,7 @@
         }
     }
 
+
     /**
      * Compute maximum number of local variables.
      */
@@ -929,11 +921,11 @@
         }
     }
 
-    /**
-     * Do not/Do produce attributes code attributesLineNumberTable and
+
+    /** Do not/Do produce attributes code attributesLineNumberTable and
      * LocalVariableTable, like javac -O
      */
-    public void stripAttributes(final boolean flag) {
+    public void stripAttributes( final boolean flag ) {
         strip_attributes = flag;
     }
 
@@ -942,6 +934,7 @@
         final InstructionHandle target;
         final int stackDepth;
 
+
         BranchTarget(final InstructionHandle target, final int stackDepth) {
             this.target = target;
             this.stackDepth = stackDepth;
@@ -953,13 +946,15 @@
         private final Stack<BranchTarget> branchTargets = new Stack<>();
         private final Map<InstructionHandle, BranchTarget> visitedTargets = new HashMap<>();
 
-        public void push(final InstructionHandle target, final int stackDepth) {
+
+        public void push( final InstructionHandle target, final int stackDepth ) {
             if (visited(target)) {
                 return;
             }
             branchTargets.push(visit(target, stackDepth));
         }
 
+
         public BranchTarget pop() {
             if (!branchTargets.empty()) {
                 final BranchTarget bt = branchTargets.pop();
@@ -968,25 +963,26 @@
             return null;
         }
 
-        private BranchTarget visit(final InstructionHandle target, final int stackDepth) {
+
+        private BranchTarget visit( final InstructionHandle target, final int stackDepth ) {
             final BranchTarget bt = new BranchTarget(target, stackDepth);
             visitedTargets.put(target, bt);
             return bt;
         }
 
-        private boolean visited(final InstructionHandle target) {
+
+        private boolean visited( final InstructionHandle target ) {
             return visitedTargets.get(target) != null;
         }
     }
 
+
     /**
-     * Computes stack usage of an instruction list by performing control flow
-     * analysis.
+     * Computes stack usage of an instruction list by performing control flow analysis.
      *
      * @return maximum stack depth used by method
      */
-    public static int getMaxStack(final ConstantPoolGen cp, final InstructionList il,
-            final CodeExceptionGen[] et) {
+    public static int getMaxStack( final ConstantPoolGen cp, final InstructionList il, final CodeExceptionGen[] et ) {
         final BranchStack branchTargets = new BranchStack();
         /* Initially, populate the branch stack with the exception
          * handlers, because these aren't (necessarily) branched to
@@ -1059,29 +1055,29 @@
 
     private List<MethodObserver> observers;
 
-    /**
-     * Add observer for this object.
+
+    /** Add observer for this object.
      */
-    public void addObserver(final MethodObserver o) {
+    public void addObserver( final MethodObserver o ) {
         if (observers == null) {
             observers = new ArrayList<>();
         }
         observers.add(o);
     }
 
-    /**
-     * Remove observer for this object.
+
+    /** Remove observer for this object.
      */
-    public void removeObserver(final MethodObserver o) {
+    public void removeObserver( final MethodObserver o ) {
         if (observers != null) {
             observers.remove(o);
         }
     }
 
-    /**
-     * Call notify() method on all observers. This method is not called
-     * automatically whenever the state has changed, but has to be called by the
-     * user after he has finished editing the object.
+
+    /** Call notify() method on all observers. This method is not called
+     * automatically whenever the state has changed, but has to be
+     * called by the user after he has finished editing the object.
      */
     public void update() {
         if (observers != null) {
@@ -1091,9 +1087,10 @@
         }
     }
 
+
     /**
-     * Return string representation close to declaration format, e.g. public
-     * static void main(String[]) throws IOException'
+     * Return string representation close to declaration format,
+     * `public static void main(String[]) throws IOException', e.g.
      *
      * @return String representation of the method.
      */
@@ -1118,10 +1115,10 @@
         return buf.toString();
     }
 
-    /**
-     * @return deep copy of this method
+
+    /** @return deep copy of this method
      */
-    public MethodGen copy(final String class_name, final ConstantPoolGen cp) {
+    public MethodGen copy( final String class_name, final ConstantPoolGen cp ) {
         final Method m = ((MethodGen) clone()).getMethod();
         final MethodGen mg = new MethodGen(m, class_name, super.getConstantPool());
         if (super.getConstantPool() != cp) {
@@ -1135,7 +1132,6 @@
     // is more likely to suggest to the caller it is readonly (which a List does not).
     /**
      * Return a list of AnnotationGen objects representing parameter annotations
-     *
      * @since 6.0
      */
     public List<AnnotationEntryGen> getAnnotationsOnParameter(final int i) {
@@ -1154,7 +1150,8 @@
      * deleted. (The annotations will be rebuilt as attributes when someone
      * builds a Method object out of this MethodGen object).
      */
-    private void ensureExistingParameterAnnotationsUnpacked() {
+    private void ensureExistingParameterAnnotationsUnpacked()
+    {
         if (haveUnpackedParameterAnnotations) {
             return;
         }
@@ -1163,9 +1160,11 @@
         ParameterAnnotations paramAnnVisAttr = null;
         ParameterAnnotations paramAnnInvisAttr = null;
         for (final Attribute attribute : attrs) {
-            if (attribute instanceof ParameterAnnotations) {
+            if (attribute instanceof ParameterAnnotations)
+            {
                 // Initialize param_annotations
-                if (!hasParameterAnnotations) {
+                if (!hasParameterAnnotations)
+                {
                     @SuppressWarnings({"rawtypes", "unchecked"})
                     final List<AnnotationEntryGen>[] parmList = new List[arg_types.length];
                     param_annotations = parmList;
@@ -1180,13 +1179,13 @@
                 } else {
                     paramAnnInvisAttr = rpa;
                 }
-                for (int j = 0; j < arg_types.length; j++) {
+                final ParameterAnnotationEntry[] parameterAnnotationEntries = rpa.getParameterAnnotationEntries();
+                for (int j = 0; j < parameterAnnotationEntries.length; j++)
+                {
                     // This returns Annotation[] ...
-                    final ParameterAnnotationEntry immutableArray = rpa
-                            .getParameterAnnotationEntries()[j];
+                    final ParameterAnnotationEntry immutableArray = rpa.getParameterAnnotationEntries()[j];
                     // ... which needs transforming into an AnnotationGen[] ...
-                    final List<AnnotationEntryGen> mutable
-                            = makeMutableVersion(immutableArray.getAnnotationEntries());
+                    final List<AnnotationEntryGen> mutable = makeMutableVersion(immutableArray.getAnnotationEntries());
                     // ... then add these to any we already know about
                     param_annotations[j].addAll(mutable);
                 }
@@ -1201,7 +1200,8 @@
         haveUnpackedParameterAnnotations = true;
     }
 
-    private List<AnnotationEntryGen> makeMutableVersion(final AnnotationEntry[] mutableArray) {
+    private List<AnnotationEntryGen> makeMutableVersion(final AnnotationEntry[] mutableArray)
+    {
         final List<AnnotationEntryGen> result = new ArrayList<>();
         for (final AnnotationEntry element : mutableArray) {
             result.add(new AnnotationEntryGen(element, getConstantPool(),
@@ -1211,18 +1211,23 @@
     }
 
     public void addParameterAnnotation(final int parameterIndex,
-            final AnnotationEntryGen annotation) {
+            final AnnotationEntryGen annotation)
+    {
         ensureExistingParameterAnnotationsUnpacked();
-        if (!hasParameterAnnotations) {
+        if (!hasParameterAnnotations)
+        {
             @SuppressWarnings({"rawtypes", "unchecked"})
             final List<AnnotationEntryGen>[] parmList = new List[arg_types.length];
             param_annotations = parmList;
             hasParameterAnnotations = true;
         }
         final List<AnnotationEntryGen> existingAnnotations = param_annotations[parameterIndex];
-        if (existingAnnotations != null) {
+        if (existingAnnotations != null)
+        {
             existingAnnotations.add(annotation);
-        } else {
+        }
+        else
+        {
             final List<AnnotationEntryGen> l = new ArrayList<>();
             l.add(annotation);
             param_annotations[parameterIndex] = l;
@@ -1236,28 +1241,31 @@
         return bcelComparator;
     }
 
+
     /**
      * @param comparator Comparison strategy object
      */
-    public static void setComparator(final BCELComparator comparator) {
+    public static void setComparator( final BCELComparator comparator ) {
         bcelComparator = comparator;
     }
 
+
     /**
-     * Return value as defined by given BCELComparator strategy. By default two
-     * MethodGen objects are said to be equal when their names and signatures
-     * are equal.
+     * Return value as defined by given BCELComparator strategy.
+     * By default two MethodGen objects are said to be equal when
+     * their names and signatures are equal.
      *
      * @see java.lang.Object#equals(java.lang.Object)
      */
     @Override
-    public boolean equals(final Object obj) {
+    public boolean equals( final Object obj ) {
         return bcelComparator.equals(this, obj);
     }
 
+
     /**
-     * Return value as defined by given BCELComparator strategy. By default
-     * return the hashcode of the method's name XOR signature.
+     * Return value as defined by given BCELComparator strategy.
+     * By default return the hashcode of the method's name XOR signature.
      *
      * @see java.lang.Object#hashCode()
      */
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MethodObserver.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MethodObserver.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * Implement this interface if you're interested in changes to a MethodGen object
  * and register yourself with addObserver().
  *
- * @version $Id: MethodObserver.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public interface MethodObserver {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NEW.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NEW.java	Mon Jul 01 14:57:02 2019 -0700
@@ -27,14 +27,14 @@
  * NEW - Create new object
  * <PRE>Stack: ... -&gt; ..., objectref</PRE>
  *
- * @version $Id: NEW.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class NEW extends CPInstruction implements LoadClass, AllocationInstruction,
         ExceptionThrower, StackProducer {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     NEW() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NEWARRAY.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NEWARRAY.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -20,18 +20,19 @@
 
 package com.sun.org.apache.bcel.internal.generic;
 
+import java.io.DataOutputStream;
+import java.io.IOException;
+
 import com.sun.org.apache.bcel.internal.ExceptionConst;
 import com.sun.org.apache.bcel.internal.util.ByteSequence;
-import java.io.DataOutputStream;
-import java.io.IOException;
 
 /**
  * NEWARRAY -  Create new array of basic type (int, short, ...)
  * <PRE>Stack: ..., count -&gt; ..., arrayref</PRE>
  * type must be one of T_INT, T_SHORT, ...
  *
- * @version $Id: NEWARRAY.java 1747278 2016-06-07 17:28:43Z britter $
- * @LastModified: Oct 2017
+ * @version $Id$
+ * @LastModified: Jun 2019
  */
 public class NEWARRAY extends Instruction implements AllocationInstruction, ExceptionThrower,
         StackProducer {
@@ -40,8 +41,8 @@
 
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     NEWARRAY() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NOP.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NOP.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,7 +24,7 @@
 /**
  * NOP - Do nothing
  *
- * @version $Id: NOP.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class NOP extends Instruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NamedAndTyped.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NamedAndTyped.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * Denote entity that has both name and type. This is true for local variables,
  * methods and fields.
  *
- * @version $Id: NamedAndTyped.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public interface NamedAndTyped {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ObjectType.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ObjectType.java	Mon Jul 01 14:57:02 2019 -0700
@@ -28,7 +28,7 @@
 /**
  * Denotes reference such as java.lang.String.
  *
- * @version $Id: ObjectType.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
  */
 public class ObjectType extends ReferenceType {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/POP.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/POP.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,7 +26,7 @@
  *
  * <PRE>Stack: ..., word -&gt; ...</PRE>
  *
- * @version $Id: POP.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class POP extends StackInstruction implements PopInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/POP2.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/POP2.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,7 +26,7 @@
  *
  * <PRE>Stack: ..., word2, word1 -&gt; ...</PRE>
  *
- * @version $Id: POP2.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class POP2 extends StackInstruction implements PopInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PUSH.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PUSH.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -26,7 +26,8 @@
  * Wrapper class for push operations, which are implemented either as BIPUSH,
  * LDC or xCONST_n instructions.
  *
- * @version $Id: PUSH.java 1749598 2016-06-21 20:36:33Z ggregory $
+ * @version $Id$
+ * @LastModified: Jun 2019
  */
 public final class PUSH implements CompoundInstruction, VariableLengthInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PUTFIELD.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PUTFIELD.java	Mon Jul 01 14:57:02 2019 -0700
@@ -30,13 +30,13 @@
  * OR
  * <PRE>Stack: ..., objectref, value.word1, value.word2 -&gt; ...</PRE>
  *
- * @version $Id: PUTFIELD.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class PUTFIELD extends FieldInstruction implements PopInstruction, ExceptionThrower {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     PUTFIELD() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PUTSTATIC.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PUTSTATIC.java	Mon Jul 01 14:57:02 2019 -0700
@@ -30,13 +30,13 @@
  * OR
  * <PRE>Stack: ..., value.word1, value.word2 -&gt; ...</PRE>
  *
- * @version $Id: PUTSTATIC.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class PUTSTATIC extends FieldInstruction implements ExceptionThrower, PopInstruction {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     PUTSTATIC() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PopInstruction.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PopInstruction.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * Denotes an unparameterized instruction to pop a value on top from the stack,
  * such as ISTORE, POP, PUTSTATIC.
  *
- * @version $Id: PopInstruction.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  * @see ISTORE
  * @see POP
  */
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PushInstruction.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PushInstruction.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * Denotes an unparameterized instruction to produce a value on top of the stack,
  * such as ILOAD, LDC, SIPUSH, DUP, ICONST, etc.
  *
- * @version $Id: PushInstruction.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
 
  * @see ILOAD
  * @see ICONST
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/RET.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/RET.java	Mon Jul 01 14:57:02 2019 -0700
@@ -31,7 +31,7 @@
  *
  * <PRE>Stack: ... -&gt; ...</PRE>
  *
- * @version $Id: RET.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class RET extends Instruction implements IndexedInstruction, TypedInstruction {
 
@@ -40,8 +40,8 @@
 
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     RET() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/RETURN.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/RETURN.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * RETURN -  Return from void method
  * <PRE>Stack: ... -&gt; &lt;empty&gt;</PRE>
  *
- * @version $Id: RETURN.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class RETURN extends ReturnInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ReferenceType.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ReferenceType.java	Mon Jul 01 14:57:02 2019 -0700
@@ -27,7 +27,7 @@
 /**
  * Super class for object and array types.
  *
- * @version $Id: ReferenceType.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
  */
 public abstract class ReferenceType extends Type {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ReturnInstruction.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ReturnInstruction.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -26,15 +26,15 @@
 /**
  * Super class for the xRETURN family of instructions.
  *
- * @version $Id: ReturnInstruction.java 1747278 2016-06-07 17:28:43Z britter $
- * @LastModified: Oct 2017
+ * @version $Id$
+ * @LastModified: Jun 2019
  */
 public abstract class ReturnInstruction extends Instruction implements ExceptionThrower,
         TypedInstruction, StackConsumer {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     ReturnInstruction() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ReturnaddressType.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ReturnaddressType.java	Mon Jul 01 14:57:02 2019 -0700
@@ -27,7 +27,7 @@
  * Returnaddress, the type JSR or JSR_W instructions push upon the stack.
  *
  * see vmspec2 3.3.3
- * @version $Id: ReturnaddressType.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
  */
 public class ReturnaddressType extends Type {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SALOAD.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SALOAD.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * SALOAD - Load short from array
  * <PRE>Stack: ..., arrayref, index -&gt; ..., value</PRE>
  *
- * @version $Id: SALOAD.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class SALOAD extends ArrayInstruction implements StackProducer {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SASTORE.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SASTORE.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * SASTORE - Store into short array
  * <PRE>Stack: ..., arrayref, index, value -&gt; ...</PRE>
  *
- * @version $Id: SASTORE.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class SASTORE extends ArrayInstruction implements StackConsumer {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SIPUSH.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SIPUSH.java	Mon Jul 01 14:57:02 2019 -0700
@@ -30,7 +30,7 @@
  *
  * <PRE>Stack: ... -&gt; ..., value</PRE>
  *
- * @version $Id: SIPUSH.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class SIPUSH extends Instruction implements ConstantPushInstruction {
 
@@ -38,8 +38,8 @@
 
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     SIPUSH() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SWAP.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SWAP.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * SWAP - Swa top operand stack word
  * <PRE>Stack: ..., word2, word1 -&gt; ..., word1, word2</PRE>
  *
- * @version $Id: SWAP.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public class SWAP extends StackInstruction implements StackConsumer, StackProducer {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SWITCH.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SWITCH.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,7 +26,7 @@
  * TABLESWITCH instruction, depending on whether the match values (int[]) can be
  * sorted with no gaps between the numbers.
  *
- * @version $Id: SWITCH.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
  */
 public final class SWITCH implements CompoundInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Select.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Select.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -27,13 +27,13 @@
 /**
  * Select - Abstract super class for LOOKUPSWITCH and TABLESWITCH instructions.
  *
- * <p>
- * We use our super's <code>target</code> property as the default target.
+ * <p>We use our super's <code>target</code> property as the default target.
  *
- * @version $Id: Select.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
  * @see LOOKUPSWITCH
  * @see TABLESWITCH
  * @see InstructionList
+ * @LastModified: Jun 2019
  */
 public abstract class Select extends BranchInstruction implements VariableLengthInstruction,
         StackConsumer /* @since 6.0 */, StackProducer {
@@ -52,9 +52,10 @@
     Select() {
     }
 
+
     /**
-     * (Match, target) pairs for switch. `Match' and `targets' must have the
-     * same length of course.
+     * (Match, target) pairs for switch.
+     * `Match' and `targets' must have the same length of course.
      *
      * @param match array of matching values
      * @param targets instruction targets
@@ -71,31 +72,28 @@
             notifyTarget(null, target2, this);
         }
         if ((match_length = match.length) != targets.length) {
-            throw new ClassGenException("Match and target array have not the same length: Match length: "
-                    + match.length + " Target length: " + targets.length);
+            throw new ClassGenException("Match and target array have not the same length: Match length: " +
+                match.length + " Target length: " + targets.length);
         }
         indices = new int[match_length];
     }
 
+
     /**
      * Since this is a variable length instruction, it may shift the following
      * instructions which then need to update their position.
      *
-     * Called by InstructionList.setPositions when setting the position for
-     * every instruction. In the presence of variable length instructions
-     * `setPositions' performs multiple passes over the instruction list to
-     * calculate the correct (byte) positions and offsets by calling this
-     * function.
+     * Called by InstructionList.setPositions when setting the position for every
+     * instruction. In the presence of variable length instructions `setPositions'
+     * performs multiple passes over the instruction list to calculate the
+     * correct (byte) positions and offsets by calling this function.
      *
-     * @param offset additional offset caused by preceding (variable length)
-     * instructions
-     * @param max_offset the maximum offset that may be caused by these
-     * instructions
-     * @return additional offset caused by possible change of this instruction's
-     * length
+     * @param offset additional offset caused by preceding (variable length) instructions
+     * @param max_offset the maximum offset that may be caused by these instructions
+     * @return additional offset caused by possible change of this instruction's length
      */
     @Override
-    protected int updatePosition(final int offset, final int max_offset) {
+    protected int updatePosition( final int offset, final int max_offset ) {
         setPosition(getPosition() + offset); // Additional offset caused by preceding SWITCHs, GOTOs, etc.
         final short old_length = (short) super.getLength();
         /* Alignment on 4-byte-boundary, + 1, because of tag byte.
@@ -105,13 +103,13 @@
         return super.getLength() - old_length;
     }
 
+
     /**
      * Dump instruction as byte code to stream out.
-     *
      * @param out Output stream
      */
     @Override
-    public void dump(final DataOutputStream out) throws IOException {
+    public void dump( final DataOutputStream out ) throws IOException {
         out.writeByte(super.getOpcode());
         for (int i = 0; i < padding; i++) {
             out.writeByte(0);
@@ -120,11 +118,12 @@
         out.writeInt(super.getIndex());
     }
 
+
     /**
      * Read needed data (e.g. index) from file.
      */
     @Override
-    protected void initFromFile(final ByteSequence bytes, final boolean wide) throws IOException {
+    protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException {
         padding = (4 - (bytes.getIndex() % 4)) % 4; // Compute number of pad bytes
         for (int i = 0; i < padding; i++) {
             bytes.readByte();
@@ -133,11 +132,12 @@
         super.setIndex(bytes.readInt());
     }
 
+
     /**
      * @return mnemonic for instruction
      */
     @Override
-    public String toString(final boolean verbose) {
+    public String toString( final boolean verbose ) {
         final StringBuilder buf = new StringBuilder(super.toString(verbose));
         if (verbose) {
             for (int i = 0; i < match_length; i++) {
@@ -154,20 +154,22 @@
         return buf.toString();
     }
 
+
     /**
      * Set branch target for `i'th case
      */
-    public void setTarget(final int i, final InstructionHandle target) { // TODO could be package-protected?
+    public void setTarget( final int i, final InstructionHandle target ) { // TODO could be package-protected?
         notifyTarget(targets[i], target, this);
         targets[i] = target;
     }
 
+
     /**
      * @param old_ih old target
      * @param new_ih new target
      */
     @Override
-    public void updateTarget(final InstructionHandle old_ih, final InstructionHandle new_ih) {
+    public void updateTarget( final InstructionHandle old_ih, final InstructionHandle new_ih ) {
         boolean targeted = false;
         if (super.getTarget() == old_ih) {
             targeted = true;
@@ -184,11 +186,12 @@
         }
     }
 
+
     /**
      * @return true, if ih is target of this instruction
      */
     @Override
-    public boolean containsTarget(final InstructionHandle ih) {
+    public boolean containsTarget( final InstructionHandle ih ) {
         if (super.getTarget() == ih) {
             return true;
         }
@@ -200,6 +203,7 @@
         return false;
     }
 
+
     @Override
     protected Object clone() throws CloneNotSupportedException {
         final Select copy = (Select) super.clone();
@@ -209,6 +213,7 @@
         return copy;
     }
 
+
     /**
      * Inform targets that they're not targeted anymore.
      */
@@ -220,6 +225,7 @@
         }
     }
 
+
     /**
      * @return array of match indices
      */
@@ -227,6 +233,7 @@
         return match;
     }
 
+
     /**
      * @return array of match target offsets
      */
@@ -234,6 +241,7 @@
         return indices;
     }
 
+
     /**
      * @return array of match targets
      */
@@ -249,6 +257,7 @@
         return match[index];
     }
 
+
     /**
      * @return index entry from indices
      * @since 6.0
@@ -265,6 +274,7 @@
         return targets[index];
     }
 
+
     /**
      * @return the fixed_length
      * @since 6.0
@@ -273,6 +283,7 @@
         return fixed_length;
     }
 
+
     /**
      * @param fixed_length the fixed_length to set
      * @since 6.0
@@ -281,6 +292,7 @@
         this.fixed_length = fixed_length;
     }
 
+
     /**
      * @return the match_length
      * @since 6.0
@@ -289,6 +301,7 @@
         return match_length;
     }
 
+
     /**
      * @param match_length the match_length to set
      * @since 6.0
@@ -344,9 +357,8 @@
         return padding;
     }
 
-    /**
-     * @since 6.0
-     */
+
+    /** @since 6.0 */
     final int setIndices(final int i, final int value) {
         indices[i] = value;
         return value;  // Allow use in nested calls
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StackConsumer.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StackConsumer.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,7 +24,7 @@
 /**
  * Denote an instruction that may consume a value from the stack.
  *
- * @version $Id: StackConsumer.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public interface StackConsumer {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StackInstruction.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StackInstruction.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,13 +24,13 @@
 /**
  * Super class for stack operations like DUP and POP.
  *
- * @version $Id: StackInstruction.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public abstract class StackInstruction extends Instruction {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     StackInstruction() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StackProducer.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StackProducer.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * Denote an instruction that may produce a value on top of the stack
  * (this excludes DUP_X1, e.g.)
  *
- * @version $Id: StackProducer.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public interface StackProducer {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StoreInstruction.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StoreInstruction.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,13 +25,13 @@
  * Denotes an unparameterized instruction to store a value into a local variable,
  * e.g. ISTORE.
  *
- * @version $Id: StoreInstruction.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public abstract class StoreInstruction extends LocalVariableInstruction implements PopInstruction {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      * tag and length are defined in readInstruction and initFromFile, respectively.
      */
     StoreInstruction(final short canon_tag, final short c_tag) {
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/TABLESWITCH.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/TABLESWITCH.java	Mon Jul 01 14:57:02 2019 -0700
@@ -29,14 +29,14 @@
 /**
  * TABLESWITCH - Switch within given range of values, i.e., low..high
  *
- * @version $Id: TABLESWITCH.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
  * @see SWITCH
  */
 public class TABLESWITCH extends Select {
 
     /**
-     * Empty constructor needed for the Class.newInstance() statement in
-     * Instruction.readInstruction(). Not to be used otherwise.
+     * Empty constructor needed for Instruction.readInstruction.
+     * Not to be used otherwise.
      */
     TABLESWITCH() {
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/TargetLostException.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/TargetLostException.java	Mon Jul 01 14:57:02 2019 -0700
@@ -47,7 +47,7 @@
  * @see InstructionHandle
  * @see InstructionList
  * @see InstructionTargeter
- * @version $Id: TargetLostException.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public final class TargetLostException extends Exception {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Type.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Type.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -27,10 +27,11 @@
 import com.sun.org.apache.bcel.internal.classfile.Utility;
 
 /**
- * Abstract super class for all possible java types, namely basic types such as
- * int, object types like String and array types, e.g. int[]
+ * Abstract super class for all possible java types, namely basic types
+ * such as int, object types like String and array types, e.g. int[]
  *
- * @version $Id: Type.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
+ * @LastModified: Jun 2019
  */
 public abstract class Type {
 
@@ -59,11 +60,13 @@
     public static final Type UNKNOWN = new Type(Const.T_UNKNOWN, "<unknown object>") {
     };
 
+
     protected Type(final byte t, final String s) {
         type = t;
         signature = s;
     }
 
+
     /**
      * @return hashcode of Type
      */
@@ -72,18 +75,20 @@
         return type ^ signature.hashCode();
     }
 
+
     /**
      * @return whether the Types are equal
      */
     @Override
     public boolean equals(final Object o) {
-        if (o instanceof Type) {
-            final Type t = (Type) o;
-            return (type == t.type) && signature.equals(t.signature);
-        }
-        return false;
+          if (o instanceof Type) {
+              final Type t = (Type)o;
+              return (type == t.type) && signature.equals(t.signature);
+          }
+          return false;
     }
 
+
     /**
      * @return signature for given type.
      */
@@ -91,6 +96,7 @@
         return signature;
     }
 
+
     /**
      * @return type as defined in Constants
      */
@@ -99,11 +105,9 @@
     }
 
     /**
-     * boolean, short and char variable are considered as int in the stack or
-     * local variable area. Returns {@link Type#INT} for
-     * {@link Type#BOOLEAN}, {@link Type#SHORT} or {@link Type#CHAR}, otherwise
+     * boolean, short and char variable are considered as int in the stack or local variable area.
+     * Returns {@link Type#INT} for {@link Type#BOOLEAN}, {@link Type#SHORT} or {@link Type#CHAR}, otherwise
      * returns the given type.
-     *
      * @since 6.0
      */
     public Type normalizeForStackOrLocal() {
@@ -114,8 +118,7 @@
     }
 
     /**
-     * @return stack size of this type (2 for long and double, 0 for void, 1
-     * otherwise)
+     * @return stack size of this type (2 for long and double, 0 for void, 1 otherwise)
      */
     public int getSize() {
         switch (type) {
@@ -129,6 +132,7 @@
         }
     }
 
+
     /**
      * @return Type string, e.g. `int[]'
      */
@@ -138,6 +142,7 @@
                 .signatureToString(signature, false);
     }
 
+
     /**
      * Convert type to Java method signature, e.g. int[] f(java.lang.String x)
      * becomes (Ljava/lang/String;)[I
@@ -146,7 +151,7 @@
      * @param arg_types what are the argument types
      * @return method signature for given type(s).
      */
-    public static String getMethodSignature(final Type return_type, final Type[] arg_types) {
+    public static String getMethodSignature( final Type return_type, final Type[] arg_types ) {
         final StringBuilder buf = new StringBuilder("(");
         if (arg_types != null) {
             for (final Type arg_type : arg_types) {
@@ -166,22 +171,24 @@
         }
     };//int consumed_chars=0; // Remember position in string, see getArgumentTypes
 
-    private static int unwrap(final ThreadLocal<Integer> tl) {
+
+    private static int unwrap( final ThreadLocal<Integer> tl ) {
         return tl.get().intValue();
     }
 
-    private static void wrap(final ThreadLocal<Integer> tl, final int value) {
+
+    private static void wrap( final ThreadLocal<Integer> tl, final int value ) {
         tl.set(Integer.valueOf(value));
     }
 
+
     /**
      * Convert signature to a Type object.
-     *
      * @param signature signature string such as Ljava/lang/String;
      * @return type object
      */
     // @since 6.0 no longer final
-    public static Type getType(final String signature) throws StringIndexOutOfBoundsException {
+    public static Type getType( final String signature ) throws StringIndexOutOfBoundsException {
         final byte type = Utility.typeOfSignature(signature);
         if (type <= Const.T_VOID) {
             //corrected concurrent private static field acess
@@ -208,13 +215,14 @@
         }
     }
 
+
     /**
      * Convert return value of a method (signature) to a Type object.
      *
      * @param signature signature string such as (Ljava/lang/String;)V
      * @return return type
      */
-    public static Type getReturnType(final String signature) {
+    public static Type getReturnType( final String signature ) {
         try {
             // Read return type after `)'
             final int index = signature.lastIndexOf(')') + 1;
@@ -224,13 +232,13 @@
         }
     }
 
+
     /**
      * Convert arguments of a method (signature) to an array of Type objects.
-     *
      * @param signature signature string such as (Ljava/lang/String;)V
      * @return array of argument types
      */
-    public static Type[] getArgumentTypes(final String signature) {
+    public static Type[] getArgumentTypes( final String signature ) {
         final List<Type> vec = new ArrayList<>();
         int index;
         Type[] types;
@@ -252,13 +260,12 @@
         return types;
     }
 
-    /**
-     * Convert runtime java.lang.Class to BCEL Type object.
-     *
+
+    /** Convert runtime java.lang.Class to BCEL Type object.
      * @param cl Java class
      * @return corresponding Type object
      */
-    public static Type getType(final java.lang.Class<?> cl) {
+    public static Type getType( final java.lang.Class<?> cl ) {
         if (cl == null) {
             throw new IllegalArgumentException("Class must not be null");
         }
@@ -296,13 +303,13 @@
         }
     }
 
+
     /**
      * Convert runtime java.lang.Class[] to BCEL Type objects.
-     *
      * @param classes an array of runtime class objects
      * @return array of corresponding Type objects
      */
-    public static Type[] getTypes(final java.lang.Class<?>[] classes) {
+    public static Type[] getTypes( final java.lang.Class<?>[] classes ) {
         final Type[] ret = new Type[classes.length];
         for (int i = 0; i < ret.length; i++) {
             ret[i] = getType(classes[i]);
@@ -310,7 +317,8 @@
         return ret;
     }
 
-    public static String getSignature(final java.lang.reflect.Method meth) {
+
+    public static String getSignature( final java.lang.reflect.Method meth ) {
         final StringBuilder sb = new StringBuilder("(");
         final Class<?>[] params = meth.getParameterTypes(); // avoid clone
         for (final Class<?> param : params) {
@@ -333,7 +341,7 @@
         return consumed << 2 | size;
     }
 
-    static int getArgumentTypesSize(final String signature) {
+    static int getArgumentTypesSize( final String signature ) {
         int res = 0;
         int index;
         try { // Read all declarations between for `(' and `)'
@@ -352,7 +360,7 @@
         return res;
     }
 
-    static int getTypeSize(final String signature) throws StringIndexOutOfBoundsException {
+    static int getTypeSize( final String signature ) throws StringIndexOutOfBoundsException {
         final byte type = Utility.typeOfSignature(signature);
         if (type <= Const.T_VOID) {
             return encode(BasicType.getType(type).getSize(), 1);
@@ -373,6 +381,7 @@
         }
     }
 
+
     static int getReturnTypeSize(final String signature) {
         final int index = signature.lastIndexOf(')') + 1;
         return Type.size(getTypeSize(signature.substring(index)));
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/TypedInstruction.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/TypedInstruction.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * Get the type associated with an instruction, int for ILOAD, or the type
  * of the field of a PUTFIELD instruction, e.g..
  *
- * @version $Id: TypedInstruction.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public interface TypedInstruction {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/UnconditionalBranch.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/UnconditionalBranch.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,7 +24,7 @@
 /**
  * Denotes an instruction to perform an unconditional branch, i.e., GOTO, JSR.
  *
- * @version $Id: UnconditionalBranch.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
 
  * @see GOTO
  * @see JSR
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/VariableLengthInstruction.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/VariableLengthInstruction.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,7 @@
  * Denotes an instruction to be a variable length instruction, such as
  * GOTO, JSR, LOOKUPSWITCH and TABLESWITCH.
  *
- * @version $Id: VariableLengthInstruction.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
 
  * @see GOTO
  * @see JSR
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Visitor.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Visitor.java	Mon Jul 01 14:57:02 2019 -0700
@@ -27,7 +27,7 @@
  * instructions with the properly typed methods just by calling the accept()
  * method.
  *
- * @version $Id: Visitor.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public interface Visitor {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/AttributeHTML.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/AttributeHTML.java	Mon Jul 01 14:57:02 2019 -0700
@@ -45,7 +45,7 @@
 /**
  * Convert found attributes into HTML file.
  *
- * @version $Id: AttributeHTML.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
  *
  */
 final class AttributeHTML {
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELComparator.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELComparator.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,7 +24,7 @@
 /**
  * Used for BCEL comparison strategy
  *
- * @version $Id: BCELComparator.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  * @since 5.2
  */
 public interface BCELComparator {
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELFactory.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELFactory.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -64,8 +64,8 @@
  * A helper class for BCELifier.
  *
  * @see BCELifier
- * @version $Id: BCELFactory.java 1749603 2016-06-21 20:50:19Z ggregory $
- * @LastModified: Oct 2017
+ * @version $Id$
+ * @LastModified: Jun 2019
  */
 class BCELFactory extends EmptyVisitor {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELifier.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELifier.java	Mon Jul 01 14:57:02 2019 -0700
@@ -46,7 +46,7 @@
  * are done with BCEL. It does not cover all features of BCEL,
  * but tries to mimic hand-written code as close as possible.
  *
- * @version $Id: BCELifier.java 1750228 2016-06-25 21:47:44Z ggregory $
+ * @version $Id$
  */
 public class BCELifier extends com.sun.org.apache.bcel.internal.classfile.EmptyVisitor {
 
@@ -284,7 +284,7 @@
 
     /** Default main method
      */
-    public static void _main( final String[] argv ) throws Exception {
+    public static void main( final String[] argv ) throws Exception {
         if (argv.length != 1) {
             System.out.println("Usage: BCELifier classname");
             System.out.println("\tThe class must exist on the classpath");
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ByteSequence.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ByteSequence.java	Mon Jul 01 14:57:02 2019 -0700
@@ -29,7 +29,7 @@
  * via the `readByte()' method. This is used to implement a wrapper for the
  * Java byte code stream to gain some more readability.
  *
- * @version $Id: ByteSequence.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  */
 public final class ByteSequence extends DataInputStream {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/Class2HTML.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/Class2HTML.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -37,24 +37,24 @@
 /**
  * Read class file(s) and convert them into HTML files.
  *
- * Given a JavaClass object "class" that is in package "package" five files will
- * be created in the specified directory.
+ * Given a JavaClass object "class" that is in package "package" five files
+ * will be created in the specified directory.
  *
  * <OL>
- * <LI> "package"."class".html as the main file which defines the frames for the
- * following subfiles.
- * <LI> "package"."class"_attributes.html contains all (known) attributes found
- * in the file
- * <LI> "package"."class"_cp.html contains the constant pool
- * <LI> "package"."class"_code.html contains the byte code
- * <LI> "package"."class"_methods.html contains references to all methods and
- * fields of the class
+ * <LI> "package"."class".html as the main file which defines the frames for
+ * the following subfiles.
+ * <LI>  "package"."class"_attributes.html contains all (known) attributes found in the file
+ * <LI>  "package"."class"_cp.html contains the constant pool
+ * <LI>  "package"."class"_code.html contains the byte code
+ * <LI>  "package"."class"_methods.html contains references to all methods and fields of the class
  * </OL>
  *
- * All subfiles reference each other appropriately, e.g. clicking on a method in
- * the Method's frame will jump to the appropriate method in the Code frame.
+ * All subfiles reference each other appropriately, e.g. clicking on a
+ * method in the Method's frame will jump to the appropriate method in
+ * the Code frame.
  *
- * @version $Id: Class2HTML.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
+ * @LastModified: Jun 2019
  */
 public class Class2HTML {
 
@@ -111,7 +111,8 @@
         attribute_html.close();
     }
 
-    public static void _main(final String[] argv) throws IOException {
+
+    public static void main( final String[] argv ) throws IOException {
         final String[] file_name = new String[argv.length];
         int files = 0;
         ClassParser parser = null;
@@ -129,7 +130,6 @@
                         dir = dir + sep;
                     }
                     final File store = new File(dir);
-
                     if (!store.isDirectory()) {
                         final boolean created = store.mkdirs(); // Create target directory if necessary
                         if (!created) {
@@ -176,7 +176,8 @@
                 + "</A>";
     }
 
-    static String referenceType(final String type) {
+
+    static String referenceType( final String type ) {
         String short_type = Utility.compactClassName(type);
         short_type = Utility.compactClassName(short_type, class_package + ".", true);
         final int index = type.indexOf('['); // Type is an array?
@@ -191,7 +192,8 @@
         return "<A HREF=\"" + base_type + ".html\" TARGET=_top>" + short_type + "</A>";
     }
 
-    static String toHTML(final String str) {
+
+    static String toHTML( final String str ) {
         final StringBuilder buf = new StringBuilder();
         for (int i = 0; i < str.length(); i++) {
             char ch;
@@ -215,7 +217,8 @@
         return buf.toString();
     }
 
-    private void writeMainHTML(final AttributeHTML attribute_html) throws IOException {
+
+    private void writeMainHTML( final AttributeHTML attribute_html ) throws IOException {
         try (PrintWriter file = new PrintWriter(new FileOutputStream(dir + class_name + ".html"))) {
             file.println("<HTML>\n" + "<HEAD><TITLE>Documentation for " + class_name + "</TITLE>" + "</HEAD>\n"
                     + "<FRAMESET BORDER=1 cols=\"30%,*\">\n" + "<FRAMESET BORDER=1 rows=\"80%,*\">\n"
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassQueue.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassQueue.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -24,26 +24,32 @@
 import com.sun.org.apache.bcel.internal.classfile.JavaClass;
 
 /**
- * Utility class implementing a (typesafe) queue of JavaClass objects.
+ * Utility class implementing a (typesafe) queue of JavaClass
+ * objects.
  *
- * @version $Id: ClassQueue.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
+ * @LastModified: Jun 2019
  */
 public class ClassQueue {
 
     private final LinkedList<JavaClass> vec = new LinkedList<>();
 
-    public void enqueue(final JavaClass clazz) {
+
+    public void enqueue( final JavaClass clazz ) {
         vec.addLast(clazz);
     }
 
+
     public JavaClass dequeue() {
         return vec.removeFirst();
     }
 
+
     public boolean empty() {
         return vec.isEmpty();
     }
 
+
     @Override
     public String toString() {
         return vec.toString();
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassSet.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassSet.java	Mon Jul 01 14:57:02 2019 -0700
@@ -32,7 +32,7 @@
  * Since JavaClass has no equals() method, the name of the class is
  * used for comparison.
  *
- * @version $Id: ClassSet.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
  * @see ClassStack
  */
 public class ClassSet {
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassStack.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassStack.java	Mon Jul 01 14:57:02 2019 -0700
@@ -22,12 +22,13 @@
 package com.sun.org.apache.bcel.internal.util;
 
 import java.util.Stack;
+
 import com.sun.org.apache.bcel.internal.classfile.JavaClass;
 
 /**
  * Utility class implementing a (typesafe) stack of JavaClass objects.
  *
- * @version $Id: ClassStack.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
  * @see Stack
  */
 public class ClassStack {
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/CodeHTML.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/CodeHTML.java	Mon Jul 01 14:57:02 2019 -0700
@@ -44,7 +44,7 @@
 /**
  * Convert code into HTML file.
  *
- * @version $Id: CodeHTML.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
  *
  */
 final class CodeHTML {
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ConstantHTML.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ConstantHTML.java	Mon Jul 01 14:57:02 2019 -0700
@@ -40,7 +40,7 @@
 /**
  * Convert constant pool into HTML file.
  *
- * @version $Id: ConstantHTML.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
  *
  */
 final class ConstantHTML {
@@ -54,8 +54,8 @@
     private final Method[] methods;
 
 
-    ConstantHTML(final String dir, final String class_name, final String class_package,
-            final Method[] methods, final ConstantPool constant_pool) throws IOException {
+    ConstantHTML(final String dir, final String class_name, final String class_package, final Method[] methods,
+            final ConstantPool constant_pool) throws IOException {
         this.class_name = class_name;
         this.class_package = class_package;
         this.constant_pool = constant_pool;
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/InstructionFinder.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/InstructionFinder.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -62,10 +62,10 @@
  *
  * </pre>
  *
- * @version $Id: InstructionFinder.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
  * @see com.sun.org.apache.bcel.internal.generic.Instruction
  * @see InstructionList
- * @LastModified: Oct 2017
+ * @LastModified: Jun 2019
  */
 public class InstructionFinder {
 
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/MethodHTML.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/MethodHTML.java	Mon Jul 01 14:57:02 2019 -0700
@@ -37,7 +37,7 @@
 /**
  * Convert methods and fields into HTML file.
  *
- * @version $Id: MethodHTML.java 1749603 2016-06-21 20:50:19Z ggregory $
+ * @version $Id$
  *
  */
 final class MethodHTML {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ModularRuntimeImage.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,158 @@
+/*
+ * reserved comment block
+ * DO NOT REMOVE OR ALTER!
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+package com.sun.org.apache.bcel.internal.util;
+
+import java.io.Closeable;
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.nio.file.DirectoryStream;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Wraps a Java 9 JEP 220 modular runtime image. Requires the JRT NIO file system.
+ *
+ * @since 6.3
+ */
+public class ModularRuntimeImage implements Closeable {
+
+    static final String MODULES_PATH = File.separator + "modules";
+    static final String PACKAGES_PATH = File.separator + "packages";
+
+    private final URLClassLoader classLoader;
+    private final FileSystem fileSystem;
+
+    /**
+     * Constructs a default instance.
+     *
+     * @throws IOException
+     *             an I/O error occurs accessing the file system
+     */
+    public ModularRuntimeImage() throws IOException {
+        this(null, FileSystems.getFileSystem(URI.create("jrt:/")));
+    }
+
+    /**
+     * Constructs an instance using the JRT file system implementation from a specific Java Home.
+     *
+     * @param javaHome
+     *            Path to a Java 9 or greater home.
+     *
+     * @throws IOException
+     *             an I/O error occurs accessing the file system
+     */
+    public ModularRuntimeImage(final String javaHome) throws IOException {
+        final Map<String, ?> emptyMap = Collections.emptyMap();
+        final Path jrePath = Paths.get(javaHome);
+        final Path jrtFsPath = jrePath.resolve("lib").resolve("jrt-fs.jar");
+        this.classLoader = new URLClassLoader(new URL[] {jrtFsPath.toUri().toURL() });
+        this.fileSystem = FileSystems.newFileSystem(URI.create("jrt:/"), emptyMap, classLoader);
+    }
+
+    private ModularRuntimeImage(final URLClassLoader cl, final FileSystem fs) {
+        this.classLoader = cl;
+        this.fileSystem = fs;
+    }
+
+    @Override
+    public void close() throws IOException {
+        if (classLoader != null) {
+            if (classLoader != null) {
+                classLoader.close();
+            }
+            if (fileSystem != null) {
+                fileSystem.close();
+            }
+        }
+    }
+
+    /**
+     * Lists all entries in the given directory.
+     *
+     * @param dirPath
+     *            directory path.
+     * @return a list of dir entries if an I/O error occurs
+     * @throws IOException
+     *             an I/O error occurs accessing the file system
+     */
+    public List<Path> list(final Path dirPath) throws IOException {
+        final List<Path> list = new ArrayList<>();
+        try (DirectoryStream<Path> ds = Files.newDirectoryStream(dirPath)) {
+            final Iterator<Path> iterator = ds.iterator();
+            while (iterator.hasNext()) {
+                list.add(iterator.next());
+            }
+        }
+        return list;
+    }
+
+    /**
+     * Lists all entries in the given directory.
+     *
+     * @param dirName
+     *            directory path.
+     * @return a list of dir entries if an I/O error occurs
+     * @throws IOException
+     *             an I/O error occurs accessing the file system
+     */
+    public List<Path> list(final String dirName) throws IOException {
+        return list(fileSystem.getPath(dirName));
+    }
+
+    /**
+     * Lists all modules.
+     *
+     * @return a list of modules
+     * @throws IOException
+     *             an I/O error occurs accessing the file system
+     */
+    public List<Path> modules() throws IOException {
+        return list(MODULES_PATH);
+    }
+
+    /**
+     * Lists all packages.
+     *
+     * @return a list of modules
+     * @throws IOException
+     *             an I/O error occurs accessing the file system
+     */
+    public List<Path> packages() throws IOException {
+        return list(PACKAGES_PATH);
+    }
+
+    public FileSystem getFileSystem() {
+        return fileSystem;
+    }
+
+}
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/Repository.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/Repository.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -22,44 +22,50 @@
 import com.sun.org.apache.bcel.internal.classfile.JavaClass;
 
 /**
- * Abstract definition of a class repository. Instances may be used to load
- * classes from different sources and may be used in the
+ * Abstract definition of a class repository. Instances may be used
+ * to load classes from different sources and may be used in the
  * Repository.setRepository method.
  *
  * @see com.sun.org.apache.bcel.internal.Repository
- * @version $Id: Repository.java 1747278 2016-06-07 17:28:43Z britter $
+ * @version $Id$
+ * @LastModified: Jun 2019
  */
 public interface Repository {
 
     /**
-     * Store the provided class under "clazz.getClassName()"
+     * Stores the provided class under "clazz.getClassName()"
      */
-    void storeClass(JavaClass clazz);
+    void storeClass( JavaClass clazz );
+
 
     /**
-     * Remove class from repository
+     * Removes class from repository
      */
-    void removeClass(JavaClass clazz);
+    void removeClass( JavaClass clazz );
+
 
     /**
-     * Find the class with the name provided, if the class isn't there, return
-     * NULL.
+     * Finds the class with the name provided, if the class
+     * isn't there, return NULL.
      */
-    JavaClass findClass(String className);
+    JavaClass findClass( String className );
+
 
     /**
-     * Find the class with the name provided, if the class isn't there, make an
-     * attempt to load it.
+     * Finds the class with the name provided, if the class
+     * isn't there, make an attempt to load it.
      */
-    JavaClass loadClass(String className) throws java.lang.ClassNotFoundException;
+    JavaClass loadClass( String className ) throws java.lang.ClassNotFoundException;
+
 
     /**
-     * Find the JavaClass instance for the given run-time class object
+     * Finds the JavaClass instance for the given run-time class object
      */
-    JavaClass loadClass(Class<?> clazz) throws java.lang.ClassNotFoundException;
+    JavaClass loadClass( Class<?> clazz ) throws java.lang.ClassNotFoundException;
+
 
     /**
-     * Clear all entries from cache.
+     * Clears all entries from cache.
      */
     void clear();
 }
--- a/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/SyntheticRepository.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/SyntheticRepository.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -39,8 +39,8 @@
  *
  * @see com.sun.org.apache.bcel.internal.Repository
  *
- * @version $Id: SyntheticRepository.java 1748124 2016-06-13 08:02:16Z ggregory
- * $
+ * @version $Id$
+ * @LastModified: Jun 2019
  */
 public class SyntheticRepository implements Repository {
 
@@ -79,7 +79,7 @@
         final SoftReference<JavaClass> ref = loadedClasses.get(className);
         if (ref == null) {
             return null;
-        }
+}
         return ref.get();
     }
 
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Main.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Main.java	Mon Jul 01 14:57:02 2019 -0700
@@ -195,7 +195,8 @@
             AOTDynamicTypeStore dynoStore = new AOTDynamicTypeStore();
             AOTCompiledClass.setDynamicTypeStore(dynoStore);
 
-            // AOTBackend aotBackend = new AOTBackend(this, graalOptions, backend, new HotSpotInvokeDynamicPlugin(dynoStore));
+            // AOTBackend aotBackend = new AOTBackend(this, graalOptions, backend, new
+            // HotSpotInvokeDynamicPlugin(dynoStore));
             // Temporary workaround until JDK-8223533 is fixed.
             // Disable invokedynamic support.
             var indyPlugin = new HotSpotInvokeDynamicPlugin(dynoStore) {
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/MarkId.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/MarkId.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,6 +25,7 @@
 
 package jdk.tools.jaotc;
 
+import java.util.HashMap;
 import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
 
 /**
@@ -56,17 +57,22 @@
     INLINE_CONTIGUOUS_ALLOCATION_SUPPORTED("CodeInstaller::INLINE_CONTIGUOUS_ALLOCATION_SUPPORTED");
 
     private final int value;
+    private static HashMap<Integer, MarkId> lookup = new HashMap<Integer, MarkId>();
 
+    static {
+        for (MarkId e : values()) {
+            lookup.put(e.value, e);
+        }
+    }
     MarkId(String name) {
         this.value = (int) (long) HotSpotJVMCIRuntime.runtime().getConfigStore().getConstants().get(name);
     }
 
     static MarkId getEnum(int value) {
-        for (MarkId e : values()) {
-            if (e.value == value) {
-                return e;
-            }
+        MarkId e = lookup.get(value);
+        if (e == null) {
+            throw new InternalError("Unknown enum value: " + value);
         }
-        throw new InternalError("Unknown enum value: " + value);
+        return e;
     }
 }
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/MetadataBuilder.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/MetadataBuilder.java	Mon Jul 01 14:57:02 2019 -0700
@@ -28,12 +28,12 @@
 import static jdk.tools.jaotc.AOTCompiledClass.getType;
 import static jdk.tools.jaotc.AOTCompiledClass.metadataName;
 
-import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.List;
 
 import org.graalvm.compiler.code.CompilationResult;
 import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
+import org.graalvm.compiler.hotspot.HotSpotGraalServices;
 
 import jdk.tools.jaotc.binformat.BinaryContainer;
 import jdk.tools.jaotc.binformat.ByteContainer;
@@ -82,12 +82,6 @@
         HotSpotGraalRuntimeProvider runtime = dataBuilder.getBackend().getRuntime();
         ByteContainer methodMetadataContainer = binaryContainer.getMethodMetadataContainer();
 
-        Method implicitExceptionsMethod = null;
-        try {
-            implicitExceptionsMethod = HotSpotMetaData.class.getDeclaredMethod("implicitExceptionBytes");
-        } catch (NoSuchMethodException e) {
-        }
-
         // For each of the compiled java methods, create records holding information about them.
         for (CompiledMethodInfo methodInfo : compiledClass.getCompiledMethods()) {
             // Get the current offset in the methodmetadata container.
@@ -104,6 +98,7 @@
             byte[] scopeDesc = metaData.scopesDescBytes();
             byte[] relocationInfo = metaData.relocBytes();
             byte[] oopMapInfo = metaData.oopMaps();
+            byte[] implicitExceptionBytes = HotSpotGraalServices.getImplicitExceptionBytes(metaData);
 
             // create a global symbol at this position for this method
             NativeOrderOutputStream metadataStream = new NativeOrderOutputStream();
@@ -148,10 +143,9 @@
                 NativeOrderOutputStream.PatchableInt scopeOffset = metadataStream.patchableInt();
                 NativeOrderOutputStream.PatchableInt relocationOffset = metadataStream.patchableInt();
                 NativeOrderOutputStream.PatchableInt exceptionOffset = metadataStream.patchableInt();
-                NativeOrderOutputStream.PatchableInt implictTableOFfset = null;
-
-                if (implicitExceptionsMethod != null) {
-                    implictTableOFfset = metadataStream.patchableInt();
+                NativeOrderOutputStream.PatchableInt implictTableOffset = null;
+                if (implicitExceptionBytes != null) {
+                    implictTableOffset = metadataStream.patchableInt();
                 }
                 NativeOrderOutputStream.PatchableInt oopMapOffset = metadataStream.patchableInt();
                 metadataStream.align(8);
@@ -168,10 +162,9 @@
                 exceptionOffset.set(metadataStream.position());
                 metadataStream.put(metaData.exceptionBytes()).align(8);
 
-                if (implicitExceptionsMethod != null) {
-                    implictTableOFfset.set(metadataStream.position());
-                    byte[] data = (byte[]) implicitExceptionsMethod.invoke(metaData);
-                    metadataStream.put(data).align(8);
+                if (implicitExceptionBytes != null) {
+                    implictTableOffset.set(metadataStream.position());
+                    metadataStream.put(implicitExceptionBytes).align(8);
                 }
 
                 // oopmaps should be last
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1447,6 +1447,9 @@
         if (tree.cases.isEmpty()) {
             log.error(tree.pos(),
                       Errors.SwitchExpressionEmpty);
+        } else if (caseTypes.isEmpty()) {
+            log.error(tree.pos(),
+                      Errors.SwitchExpressionNoResultExpressions);
         }
 
         Type owntype = (tree.polyKind == PolyKind.STANDALONE) ? condType(caseTypePositions.toList(), caseTypes.toList()) : pt();
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Mon Jul 01 14:57:02 2019 -0700
@@ -223,6 +223,9 @@
 compiler.err.switch.expression.empty=\
     switch expression does not have any case clauses
 
+compiler.err.switch.expression.no.result.expressions=\
+    switch expression does not have any result expressions
+
 # 0: name
 compiler.err.call.must.be.first.stmt.in.ctor=\
     call to {0} must be first statement in constructor
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/MandatoryWarningHandler.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/MandatoryWarningHandler.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
 package com.sun.tools.javac.util;
 
 import java.util.HashSet;
+import java.util.Objects;
 import java.util.Set;
 import javax.tools.JavaFileObject;
 
@@ -147,7 +148,7 @@
                 deferredDiagnosticArg = currentSource;
             } else if ((deferredDiagnosticKind == DeferredDiagnosticKind.IN_FILE
                         || deferredDiagnosticKind == DeferredDiagnosticKind.ADDITIONAL_IN_FILE)
-                       && !equal(deferredDiagnosticSource, currentSource)) {
+                       && !Objects.equals(deferredDiagnosticSource, currentSource)) {
                 // additional errors in more than one source file
                 deferredDiagnosticKind = DeferredDiagnosticKind.ADDITIONAL_IN_FILES;
                 deferredDiagnosticArg = null;
@@ -159,7 +160,7 @@
                 deferredDiagnosticSource = currentSource;
                 deferredDiagnosticArg = currentSource;
             }  else if (deferredDiagnosticKind == DeferredDiagnosticKind.IN_FILE &&
-                        !equal(deferredDiagnosticSource, currentSource)) {
+                        !Objects.equals(deferredDiagnosticSource, currentSource)) {
                 // warnings in multiple source files
                 deferredDiagnosticKind = DeferredDiagnosticKind.IN_FILES;
                 deferredDiagnosticArg = null;
@@ -183,13 +184,6 @@
     }
 
     /**
-     * Check two objects, each possibly null, are either both null or are equal.
-     */
-    private static boolean equal(Object o1, Object o2) {
-        return ((o1 == null || o2 == null) ? (o1 == o2) : o1.equals(o2));
-    }
-
-    /**
      * The log to which to report warnings.
      */
     private Log log;
--- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11PSSSignature.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11PSSSignature.java	Mon Jul 01 14:57:02 2019 -0700
@@ -395,33 +395,49 @@
                 ("Unsupported digest algorithm in Signature parameters: " +
                  digestAlgorithm);
         }
+
         if (!(params.getMGFAlgorithm().equalsIgnoreCase("MGF1"))) {
             throw new InvalidAlgorithmParameterException("Only supports MGF1");
         }
+
+        // defaults to the digest algorithm unless overridden
+        String mgfDigestAlgo = digestAlgorithm;
+        AlgorithmParameterSpec mgfParams = params.getMGFParameters();
+        if (mgfParams != null) {
+            if (!(mgfParams instanceof MGF1ParameterSpec)) {
+                throw new InvalidAlgorithmParameterException
+                        ("Only MGF1ParameterSpec is supported");
+            }
+            mgfDigestAlgo = ((MGF1ParameterSpec)mgfParams).getDigestAlgorithm();
+        }
+
         if (params.getTrailerField() != PSSParameterSpec.TRAILER_FIELD_BC) {
             throw new InvalidAlgorithmParameterException
                 ("Only supports TrailerFieldBC(1)");
         }
+
         int saltLen = params.getSaltLength();
         if (this.p11Key != null) {
-            int maxSaltLen = ((this.p11Key.length() + 7) >> 3) - digestLen.intValue() - 2;
+            int maxSaltLen = ((this.p11Key.length() + 7) >> 3) -
+                    digestLen.intValue() - 2;
 
             if (DEBUG) {
                 System.out.println("Max saltLen = " + maxSaltLen);
                 System.out.println("Curr saltLen = " + saltLen);
             }
             if (maxSaltLen < 0 || saltLen > maxSaltLen) {
-                throw new InvalidAlgorithmParameterException("Invalid with current key size");
+                throw new InvalidAlgorithmParameterException
+                        ("Invalid with current key size");
             }
-        } else {
-            if (DEBUG) System.out.println("No key available for validating saltLen");
+        } else if (DEBUG) {
+            System.out.println("No key available for validating saltLen");
         }
 
         // validated, now try to store the parameter internally
         try {
             this.mechanism.setParameter(
                     new CK_RSA_PKCS_PSS_PARAMS(digestAlgorithm, "MGF1",
-                        digestAlgorithm, saltLen));
+                            mgfDigestAlgo, saltLen));
             this.sigParams = params;
         } catch (IllegalArgumentException iae) {
             throw new InvalidAlgorithmParameterException(iae);
--- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_RSA_PKCS_PSS_PARAMS.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_RSA_PKCS_PSS_PARAMS.java	Mon Jul 01 14:57:02 2019 -0700
@@ -57,7 +57,7 @@
             throw new ProviderException("Only MGF1 is supported");
         }
         // no dash in PKCS#11 mechanism names
-        this.mgf = Functions.getMGFId("CKG_MGF1_" + hashAlg.replaceFirst("-", ""));
+        this.mgf = Functions.getMGFId("CKG_MGF1_" + mgfHash.replaceFirst("-", ""));
         this.sLen = sLen;
     }
 
--- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java	Mon Jul 01 14:57:02 2019 -0700
@@ -211,20 +211,13 @@
     native HotSpotResolvedJavaType lookupClass(Class<?> javaClass);
 
     /**
-     * Resolves the entry at index {@code cpi} in {@code constantPool} to an object.
-     *
-     * The behavior of this method is undefined if {@code cpi} does not denote one of the following
-     * entry types: {@code JVM_CONSTANT_MethodHandle}, {@code JVM_CONSTANT_MethodHandleInError},
-     * {@code JVM_CONSTANT_MethodType} and {@code JVM_CONSTANT_MethodTypeInError}.
-     */
-    native HotSpotObjectConstantImpl resolveConstantInPool(HotSpotConstantPool constantPool, int cpi);
-
-    /**
      * Resolves the entry at index {@code cpi} in {@code constantPool} to an object, looking in the
      * constant pool cache first.
      *
-     * The behavior of this method is undefined if {@code cpi} does not denote a
-     * {@code JVM_CONSTANT_String} entry.
+     * The behavior of this method is undefined if {@code cpi} does not denote one of the following
+     * entry types: {@code JVM_CONSTANT_String}, {@code JVM_CONSTANT_MethodHandle},
+     * {@code JVM_CONSTANT_MethodHandleInError}, {@code JVM_CONSTANT_MethodType} and
+     * {@code JVM_CONSTANT_MethodTypeInError}.
      */
     native HotSpotObjectConstantImpl resolvePossiblyCachedConstantInPool(HotSpotConstantPool constantPool, int cpi);
 
@@ -771,6 +764,12 @@
     native HotSpotResolvedJavaType getComponentType(HotSpotResolvedObjectTypeImpl type);
 
     /**
+     * Get the array class for {@code type}. This can't be done symbolically since anonymous types
+     * can't be looked up by name.
+     */
+    native HotSpotResolvedObjectTypeImpl getArrayType(HotSpotResolvedJavaType type);
+
+    /**
      * Forces initialization of {@code type}.
      */
     native void ensureInitialized(HotSpotResolvedObjectTypeImpl type);
@@ -978,4 +977,9 @@
      * @see HotSpotJVMCIRuntime#detachCurrentThread()
      */
     native void detachCurrentThread();
+
+    /**
+     * @see HotSpotJVMCIRuntime#exitHotSpot(int)
+     */
+    native void callSystemExit(int status);
 }
--- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCompilationRequest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCompilationRequest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -87,4 +87,9 @@
     public int getId() {
         return id;
     }
+
+    @Override
+    public String toString() {
+        return id + ":" + super.toString();
+    }
 }
--- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPool.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPool.java	Mon Jul 01 14:57:02 2019 -0700
@@ -545,7 +545,7 @@
             case "MethodHandleInError":
             case "MethodType":
             case "MethodTypeInError":
-                return compilerToVM().resolveConstantInPool(this, cpi);
+                return compilerToVM().resolvePossiblyCachedConstantInPool(this, cpi);
             default:
                 throw new JVMCIError("Unknown constant pool tag %s", tag);
         }
--- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java	Mon Jul 01 14:57:02 2019 -0700
@@ -223,6 +223,8 @@
         // so that -XX:+JVMCIPrintProperties shows the option.
         InitTimer(Boolean.class, false, "Specifies if initialization timing is enabled."),
         PrintConfig(Boolean.class, false, "Prints VM configuration available via JVMCI."),
+        AuditHandles(Boolean.class, false, "Record stack trace along with scoped foreign object reference wrappers " +
+                "to debug issue with a wrapper being used after its scope has closed."),
         TraceMethodDataFilter(String.class, null,
                 "Enables tracing of profiling info when read by JVMCI.",
                 "Empty value: trace all methods",
@@ -687,9 +689,11 @@
         return Collections.unmodifiableMap(backends);
     }
 
+    @SuppressWarnings("try")
     @VMEntryPoint
     private HotSpotCompilationRequestResult compileMethod(HotSpotResolvedJavaMethod method, int entryBCI, long compileState, int id) {
-        CompilationRequestResult result = getCompiler().compileMethod(new HotSpotCompilationRequest(method, entryBCI, compileState, id));
+        HotSpotCompilationRequest request = new HotSpotCompilationRequest(method, entryBCI, compileState, id);
+        CompilationRequestResult result = getCompiler().compileMethod(request);
         assert result != null : "compileMethod must always return something";
         HotSpotCompilationRequestResult hsResult;
         if (result instanceof HotSpotCompilationRequestResult) {
@@ -704,7 +708,6 @@
                 hsResult = HotSpotCompilationRequestResult.success(inlinedBytecodes);
             }
         }
-
         return hsResult;
     }
 
@@ -1032,4 +1035,14 @@
     public void excludeFromJVMCICompilation(Module...modules) {
         this.excludeFromJVMCICompilation = modules.clone();
     }
+
+    /**
+     * Calls {@link System#exit(int)} in HotSpot's runtime.
+     */
+    public void exitHotSpot(int status) {
+        if (!IS_IN_NATIVE_IMAGE) {
+            System.exit(status);
+        }
+        compilerToVm.callSystemExit(status);
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotObjectConstantScope.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.hotspot;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+import jdk.vm.ci.services.Services;
+
+/**
+ * A mechanism for limiting the lifetime of a foreign object reference encapsulated in a
+ * {@link HotSpotObjectConstant}.
+ *
+ * A {@link HotSpotObjectConstant} allocated in a {@linkplain #openLocalScope local} scope will have
+ * its reference to any foreign object cleared when the scope {@linkplain #close() closes}. This
+ * allows the foreign memory manager to reclaim the foreign object (once there are no other strong
+ * references to it).
+ *
+ * {@link HotSpotObjectConstantScope}s have no impact on {@link HotSpotObjectConstant}s that do not
+ * encapsulate a foreign object reference.
+ *
+ * The object returned by {@link #enterGlobalScope()} or {@link #openLocalScope(Object)} should
+ * always be used in a try-with-resources statement. Failure to close a scope will almost certainly
+ * result in foreign objects being leaked.
+ */
+public final class HotSpotObjectConstantScope implements AutoCloseable {
+    static final ThreadLocal<HotSpotObjectConstantScope> CURRENT = new ThreadLocal<>();
+
+    private final HotSpotObjectConstantScope parent;
+    private List<IndirectHotSpotObjectConstantImpl> foreignObjects;
+
+    /**
+     * An object whose {@link Object#toString()} value describes a non-global scope. This is
+     * {@code null} iff this is a global scope.
+     */
+    final Object localScopeDescription;
+
+    /**
+     * Opens a local scope that upon closing, will release foreign object references encapsulated by
+     * {@link HotSpotObjectConstant}s created in the scope.
+     *
+     * @param description an non-null object whose {@link Object#toString()} value describes the
+     *            scope being opened
+     * @return {@code null} if the current runtime does not support remote object references
+     */
+    public static HotSpotObjectConstantScope openLocalScope(Object description) {
+        return Services.IS_IN_NATIVE_IMAGE ? new HotSpotObjectConstantScope(Objects.requireNonNull(description)) : null;
+    }
+
+    /**
+     * Enters the global scope. This is useful to escape a local scope for execution that will
+     * create foreign object references that need to outlive the local scope.
+     *
+     * Foreign object references encapsulated by {@link HotSpotObjectConstant}s created in the
+     * global scope are only subject to reclamation once the {@link HotSpotObjectConstant} wrapper
+     * dies.
+     *
+     * @return {@code null} if the current runtime does not support remote object references or if
+     *         this thread is currently in the global scope
+     */
+    public static HotSpotObjectConstantScope enterGlobalScope() {
+        return Services.IS_IN_NATIVE_IMAGE && CURRENT.get() != null ? new HotSpotObjectConstantScope(null) : null;
+    }
+
+    private HotSpotObjectConstantScope(Object localScopeDescription) {
+        this.parent = CURRENT.get();
+        CURRENT.set(this);
+        this.localScopeDescription = localScopeDescription;
+    }
+
+    /**
+     * Determines if this scope is global.
+     */
+    boolean isGlobal() {
+        return localScopeDescription == null;
+    }
+
+    void add(IndirectHotSpotObjectConstantImpl obj) {
+        assert !isGlobal();
+        if (foreignObjects == null) {
+            foreignObjects = new ArrayList<>();
+        }
+        foreignObjects.add(obj);
+    }
+
+    @VMEntryPoint
+    @Override
+    public void close() {
+        if (CURRENT.get() != this) {
+            throw new IllegalStateException("Cannot close non-active scope");
+        }
+        if (foreignObjects != null) {
+            for (IndirectHotSpotObjectConstantImpl obj : foreignObjects) {
+                obj.clear(localScopeDescription);
+            }
+            foreignObjects = null;
+        }
+        CURRENT.set(parent);
+    }
+}
--- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaType.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaType.java	Mon Jul 01 14:57:02 2019 -0700
@@ -22,11 +22,15 @@
  */
 package jdk.vm.ci.hotspot;
 
+import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
+
 import jdk.vm.ci.meta.JavaConstant;
 import jdk.vm.ci.meta.ResolvedJavaType;
 
 public abstract class HotSpotResolvedJavaType extends HotSpotJavaType implements ResolvedJavaType {
 
+    HotSpotResolvedObjectTypeImpl arrayOfType;
+
     HotSpotResolvedJavaType(String name) {
         super(name);
     }
@@ -40,4 +44,12 @@
     }
 
     abstract JavaConstant getJavaMirror();
+
+    @Override
+    public HotSpotResolvedObjectType getArrayClass() {
+        if (arrayOfType == null) {
+            arrayOfType = runtime().compilerToVm.getArrayType(this);
+        }
+        return arrayOfType;
+    }
 }
--- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java	Mon Jul 01 14:57:02 2019 -0700
@@ -72,7 +72,6 @@
     private volatile HotSpotResolvedJavaField[] instanceFields;
     private volatile HotSpotResolvedObjectTypeImpl[] interfaces;
     private HotSpotConstantPool constantPool;
-    private HotSpotResolvedObjectType arrayOfType;
     private final JavaConstant mirror;
     private HotSpotResolvedObjectTypeImpl superClass;
 
@@ -103,17 +102,24 @@
      * Creates the JVMCI mirror for a {@link Class} object.
      *
      * <b>NOTE</b>: Creating an instance of this class does not install the mirror for the
-     * {@link Class} type. {@link #fromMetaspace} instead.
+     * {@link Class} type.
      * </p>
      *
      * @param metadataPointer the Klass* to create the mirror for
      */
+    @SuppressWarnings("try")
     HotSpotResolvedObjectTypeImpl(long metadataPointer, String name) {
         super(name);
+        assert metadataPointer != 0;
         this.metadataPointer = metadataPointer;
-        this.mirror = runtime().compilerToVm.getJavaMirror(this);
-        assert metadataPointer != 0;
-        assert getName().charAt(0) != '[' || isArray() : getName();
+
+        // The mirror object must be in the global scope since
+        // this object will be cached in HotSpotJVMCIRuntime.resolvedJavaTypes
+        // and live across more than one compilation.
+        try (HotSpotObjectConstantScope global = HotSpotObjectConstantScope.enterGlobalScope()) {
+            this.mirror = runtime().compilerToVm.getJavaMirror(this);
+            assert getName().charAt(0) != '[' || isArray() : getName();
+        }
     }
 
     /**
@@ -147,18 +153,6 @@
     }
 
     @Override
-    public HotSpotResolvedObjectType getArrayClass() {
-        if (arrayOfType == null) {
-            try {
-                arrayOfType = (HotSpotResolvedObjectType) runtime().compilerToVm.lookupType("[" + getName(), this, true);
-            } catch (ClassNotFoundException e) {
-                throw new JVMCIError(e);
-            }
-        }
-        return arrayOfType;
-    }
-
-    @Override
     public ResolvedJavaType getComponentType() {
         return runtime().compilerToVm.getComponentType(this);
     }
@@ -579,6 +573,15 @@
             // The type isn't known to implement the method.
             return null;
         }
+        if (resolvedMethod.canBeStaticallyBound()) {
+            // No assumptions are required.
+            return new AssumptionResult<>(resolvedMethod);
+        }
+
+        if (resolvedMethod.canBeStaticallyBound()) {
+            // No assumptions are required.
+            return new AssumptionResult<>(resolvedMethod);
+        }
 
         ResolvedJavaMethod result = resolvedMethod.uniqueConcreteMethod(this);
         if (result != null) {
--- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedPrimitiveType.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedPrimitiveType.java	Mon Jul 01 14:57:02 2019 -0700
@@ -46,7 +46,6 @@
     @NativeImageReinitialize static HotSpotResolvedPrimitiveType[] primitives;
 
     private JavaKind kind;
-    private HotSpotResolvedObjectType arrayClass;
     HotSpotObjectConstantImpl mirror;
 
     /**
@@ -87,14 +86,7 @@
         if (kind == JavaKind.Void) {
             return null;
         }
-        if (arrayClass == null) {
-            try {
-                arrayClass = (HotSpotResolvedObjectType) runtime().compilerToVm.lookupType("[" + kind.getTypeChar(), null, true);
-            } catch (ClassNotFoundException e) {
-                throw new JVMCIError(e);
-            }
-        }
-        return arrayClass;
+        return super.getArrayClass();
     }
 
     @Override
--- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/IndirectHotSpotObjectConstantImpl.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/IndirectHotSpotObjectConstantImpl.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,17 +24,52 @@
 
 import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
 
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+
+import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.Option;
 import jdk.vm.ci.meta.JavaConstant;
 
+/**
+ * Encapsulates a JNI reference to an object in the HotSpot heap.
+ *
+ * {@link IndirectHotSpotObjectConstantImpl} objects are only allocated in the shared library heap.
+ *
+ * @see HotSpotObjectConstantScope
+ */
 final class IndirectHotSpotObjectConstantImpl extends HotSpotObjectConstantImpl {
     /**
-     * An object handle in {@code JVMCI::_jvmci_handles}.
+     * An object handle in {@code JVMCI::_object_handles}.
      */
-    final long objectHandle;
+    private long objectHandle;
+
+    /**
+     * Lazily computed hash code.
+     */
     private int hashCode;
 
     final IndirectHotSpotObjectConstantImpl base;
 
+    private static class Audit {
+        final Object scope;
+        final long handle;
+        final Throwable origin;
+
+        Audit(Object scope, long handle, Throwable origin) {
+            this.scope = scope;
+            this.handle = handle;
+            this.origin = origin;
+        }
+    }
+
+    /**
+     * Details useful to audit a scoped handle used after its creating scope closes. Set to an
+     * {@link Audit} object if {@link HotSpotJVMCIRuntime.Option#AuditHandles} is true otherwise to
+     * {@link HotSpotObjectConstantScope#localScopeDescription}.
+     */
+    private Object rawAudit;
+
+    @SuppressWarnings("serial")
     @VMEntryPoint
     private IndirectHotSpotObjectConstantImpl(long objectHandle, boolean compressed, boolean skipRegister) {
         super(compressed);
@@ -42,7 +77,20 @@
         this.objectHandle = objectHandle;
         this.base = null;
         if (!skipRegister) {
-            HandleCleaner.create(this, objectHandle);
+            HotSpotObjectConstantScope scope = HotSpotObjectConstantScope.CURRENT.get();
+            if (scope != null && !scope.isGlobal()) {
+                scope.add(this);
+                if (HotSpotJVMCIRuntime.Option.AuditHandles.getBoolean()) {
+                    rawAudit = new Audit(scope.localScopeDescription, objectHandle, new Throwable() {
+                        @Override
+                        public String toString() {
+                            return "Created " + objectHandle;
+                        }
+                    });
+                }
+            } else {
+                HandleCleaner.create(this, objectHandle);
+            }
         }
     }
 
@@ -50,12 +98,59 @@
         super(compressed);
         // This is a variant of an original object that only varies in compress vs uncompressed.
         // Instead of creating a new handle, reference that object and objectHandle.
-        this.objectHandle = base.objectHandle;
-        // There should only be on level of indirection to the base object.
+        this.objectHandle = base.getHandle();
+        // There should only be one level of indirection to the base object.
         assert base.base == null || base.base.base == null;
         this.base = base.base != null ? base.base : base;
     }
 
+    long getHandle() {
+        checkHandle();
+        return objectHandle;
+    }
+
+    private void checkHandle() {
+        if (objectHandle == 0L) {
+            String message;
+            if (rawAudit instanceof Audit) {
+                Audit audit = (Audit) rawAudit;
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                PrintStream ps = new PrintStream(baos);
+                ps.println("Foreign object reference " + audit.handle + " created in scope '" + audit.scope + "' is no longer valid. Origin: {");
+                audit.origin.printStackTrace(ps);
+                ps.print('}');
+                ps.flush();
+                message = baos.toString();
+            } else {
+                message = "Foreign object reference created in scope '" + rawAudit + "' is no longer valid. " +
+                                "Set property " + Option.AuditHandles.getPropertyName() + "=true to show origin of invalid foreign references.";
+            }
+            throw new NullPointerException(message);
+        }
+    }
+
+    boolean isValid() {
+        return objectHandle != 0L;
+    }
+
+    @Override
+    public HotSpotResolvedObjectType getType() {
+        checkHandle();
+        return super.getType();
+    }
+
+    /**
+     * Clears the foreign object reference.
+     */
+    void clear(Object scopeDescription) {
+        checkHandle();
+        CompilerToVM.compilerToVM().deleteGlobalHandle(objectHandle);
+        if (rawAudit == null) {
+            rawAudit = scopeDescription;
+        }
+        objectHandle = 0L;
+    }
+
     @Override
     public JavaConstant compress() {
         assert !compressed;
@@ -70,6 +165,7 @@
 
     @Override
     public int getIdentityHashCode() {
+        checkHandle();
         int hash = hashCode;
         if (hash == 0) {
             hash = runtime().compilerToVm.getIdentityHashCode(this);
--- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/SharedLibraryJVMCIReflection.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/SharedLibraryJVMCIReflection.java	Mon Jul 01 14:57:02 2019 -0700
@@ -114,7 +114,7 @@
         }
         IndirectHotSpotObjectConstantImpl indirectX = (IndirectHotSpotObjectConstantImpl) x;
         IndirectHotSpotObjectConstantImpl indirectY = (IndirectHotSpotObjectConstantImpl) y;
-        return runtime().compilerToVm.equals(x, indirectX.objectHandle, y, indirectY.objectHandle);
+        return runtime().compilerToVm.equals(x, indirectX.getHandle(), y, indirectY.getHandle());
     }
 
     @Override
@@ -288,6 +288,10 @@
             DirectHotSpotObjectConstantImpl direct = (DirectHotSpotObjectConstantImpl) object;
             return "CompilerObject<" + direct.object.getClass().getName() + ">";
         }
+        IndirectHotSpotObjectConstantImpl indirect = (IndirectHotSpotObjectConstantImpl) object;
+        if (!indirect.isValid()) {
+            return "Instance<null>";
+        }
         return "Instance<" + object.getType().toJavaName() + ">";
     }
 
--- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MetaUtil.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MetaUtil.java	Mon Jul 01 14:57:02 2019 -0700
@@ -87,6 +87,29 @@
     }
 
     /**
+     * Classes for lambdas can have {@code /} characters that are not package separators. These are
+     * distinguished by being followed by a character that is not a
+     * {@link Character#isJavaIdentifierStart(char)} (e.g.,
+     * "jdk.vm.ci.runtime.test.TypeUniverse$$Lambda$1/869601985").
+     */
+    private static String replacePackageSeparatorsWithDot(String name) {
+        int length = name.length();
+        int i = 0;
+        StringBuilder buf = new StringBuilder(length);
+        while (i < length - 1) {
+            char ch = name.charAt(i);
+            if (ch == '/' && Character.isJavaIdentifierStart(name.charAt(i + 1))) {
+                buf.append('.');
+            } else {
+                buf.append(ch);
+            }
+            i++;
+        }
+        buf.append(name.charAt(length - 1));
+        return buf.toString();
+    }
+
+    /**
      * Converts a type name in internal form to an external form.
      *
      * @param name the internal name to convert
@@ -99,7 +122,7 @@
     public static String internalNameToJava(String name, boolean qualified, boolean classForNameCompatible) {
         switch (name.charAt(0)) {
             case 'L': {
-                String result = name.substring(1, name.length() - 1).replace('/', '.');
+                String result = replacePackageSeparatorsWithDot(name.substring(1, name.length() - 1));
                 if (!qualified) {
                     final int lastDot = result.lastIndexOf('.');
                     if (lastDot != -1) {
@@ -109,7 +132,7 @@
                 return result;
             }
             case '[':
-                return classForNameCompatible ? name.replace('/', '.') : internalNameToJava(name.substring(1), qualified, classForNameCompatible) + "[]";
+                return classForNameCompatible ? replacePackageSeparatorsWithDot(name) : internalNameToJava(name.substring(1), qualified, classForNameCompatible) + "[]";
             default:
                 if (name.length() != 1) {
                     throw new IllegalArgumentException("Illegal internal name: " + name);
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/EconomicMap.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/EconomicMap.java	Mon Jul 01 14:57:02 2019 -0700
@@ -47,7 +47,7 @@
 /**
  * Memory efficient map data structure.
  *
- * @since 1.0
+ * @since 19.0
  */
 public interface EconomicMap<K, V> extends UnmodifiableEconomicMap<K, V> {
 
@@ -57,14 +57,14 @@
      *
      * @return the previous value associated with {@code key}, or {@code null} if there was no
      *         mapping for {@code key}.
-     * @since 1.0
+     * @since 19.0
      */
     V put(K key, V value);
 
     /**
      * Copies all of the mappings from {@code other} to this map.
      *
-     * @since 1.0
+     * @since 19.0
      */
     default void putAll(EconomicMap<K, V> other) {
         MapCursor<K, V> e = other.getEntries();
@@ -76,7 +76,7 @@
     /**
      * Copies all of the mappings from {@code other} to this map.
      *
-     * @since 1.0
+     * @since 19.0
      */
     default void putAll(UnmodifiableEconomicMap<? extends K, ? extends V> other) {
         UnmodifiableMapCursor<? extends K, ? extends V> entry = other.getEntries();
@@ -88,7 +88,7 @@
     /**
      * Removes all of the mappings from this map. The map will be empty after this call returns.
      *
-     * @since 1.0
+     * @since 19.0
      */
     void clear();
 
@@ -98,14 +98,14 @@
      *
      * @return the previous value associated with {@code key}, or {@code null} if there was no
      *         mapping for {@code key}.
-     * @since 1.0
+     * @since 19.0
      */
     V removeKey(K key);
 
     /**
      * Returns a {@link MapCursor} view of the mappings contained in this map.
      *
-     * @since 1.0
+     * @since 19.0
      */
     @Override
     MapCursor<K, V> getEntries();
@@ -115,7 +115,7 @@
      * all entries have been processed or the function throws an exception. Exceptions thrown by the
      * function are relayed to the caller.
      *
-     * @since 1.0
+     * @since 19.0
      */
     void replaceAll(BiFunction<? super K, ? super V, ? extends V> function);
 
@@ -123,7 +123,7 @@
      * Creates a new map that guarantees insertion order on the key set with the default
      * {@link Equivalence#DEFAULT} comparison strategy for keys.
      *
-     * @since 1.0
+     * @since 19.0
      */
     static <K, V> EconomicMap<K, V> create() {
         return EconomicMap.create(Equivalence.DEFAULT);
@@ -134,7 +134,7 @@
      * {@link Equivalence#DEFAULT} comparison strategy for keys and initializes with a specified
      * capacity.
      *
-     * @since 1.0
+     * @since 19.0
      */
     static <K, V> EconomicMap<K, V> create(int initialCapacity) {
         return EconomicMap.create(Equivalence.DEFAULT, initialCapacity);
@@ -144,7 +144,7 @@
      * Creates a new map that guarantees insertion order on the key set with the given comparison
      * strategy for keys.
      *
-     * @since 1.0
+     * @since 19.0
      */
     static <K, V> EconomicMap<K, V> create(Equivalence strategy) {
         return EconomicMapImpl.create(strategy, false);
@@ -155,7 +155,7 @@
      * {@link Equivalence#DEFAULT} comparison strategy for keys and copies all elements from the
      * specified existing map.
      *
-     * @since 1.0
+     * @since 19.0
      */
     static <K, V> EconomicMap<K, V> create(UnmodifiableEconomicMap<K, V> m) {
         return EconomicMap.create(Equivalence.DEFAULT, m);
@@ -165,7 +165,7 @@
      * Creates a new map that guarantees insertion order on the key set and copies all elements from
      * the specified existing map.
      *
-     * @since 1.0
+     * @since 19.0
      */
     static <K, V> EconomicMap<K, V> create(Equivalence strategy, UnmodifiableEconomicMap<K, V> m) {
         return EconomicMapImpl.create(strategy, m, false);
@@ -175,7 +175,7 @@
      * Creates a new map that guarantees insertion order on the key set and initializes with a
      * specified capacity.
      *
-     * @since 1.0
+     * @since 19.0
      */
     static <K, V> EconomicMap<K, V> create(Equivalence strategy, int initialCapacity) {
         return EconomicMapImpl.create(strategy, initialCapacity, false);
@@ -184,7 +184,7 @@
     /**
      * Wraps an existing {@link Map} as an {@link EconomicMap}.
      *
-     * @since 1.0
+     * @since 19.0
      */
     static <K, V> EconomicMap<K, V> wrapMap(Map<K, V> map) {
         return new EconomicMap<K, V>() {
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/EconomicSet.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/EconomicSet.java	Mon Jul 01 14:57:02 2019 -0700
@@ -45,7 +45,7 @@
 /**
  * Memory efficient set data structure.
  *
- * @since 1.0
+ * @since 19.0
  */
 public interface EconomicSet<E> extends UnmodifiableEconomicSet<E> {
 
@@ -53,7 +53,7 @@
      * Adds {@code element} to this set if it is not already present.
      *
      * @return {@code true} if this set did not already contain {@code element}.
-     * @since 1.0
+     * @since 19.0
      */
     boolean add(E element);
 
@@ -61,21 +61,21 @@
      * Removes {@code element} from this set if it is present. This set will not contain
      * {@code element} once the call returns.
      *
-     * @since 1.0
+     * @since 19.0
      */
     void remove(E element);
 
     /**
      * Removes all of the elements from this set. The set will be empty after this call returns.
      *
-     * @since 1.0
+     * @since 19.0
      */
     void clear();
 
     /**
      * Adds all of the elements in {@code other} to this set if they're not already present.
      *
-     * @since 1.0
+     * @since 19.0
      */
     default void addAll(EconomicSet<E> other) {
         addAll(other.iterator());
@@ -84,7 +84,7 @@
     /**
      * Adds all of the elements in {@code values} to this set if they're not already present.
      *
-     * @since 1.0
+     * @since 19.0
      */
     default void addAll(Iterable<E> values) {
         addAll(values.iterator());
@@ -94,7 +94,7 @@
      * Adds all of the elements enumerated by {@code iterator} to this set if they're not already
      * present.
      *
-     * @since 1.0
+     * @since 19.0
      */
     default void addAll(Iterator<E> iterator) {
         while (iterator.hasNext()) {
@@ -105,7 +105,7 @@
     /**
      * Removes from this set all of its elements that are contained in {@code other}.
      *
-     * @since 1.0
+     * @since 19.0
      */
     default void removeAll(EconomicSet<E> other) {
         removeAll(other.iterator());
@@ -114,7 +114,7 @@
     /**
      * Removes from this set all of its elements that are contained in {@code values}.
      *
-     * @since 1.0
+     * @since 19.0
      */
     default void removeAll(Iterable<E> values) {
         removeAll(values.iterator());
@@ -123,7 +123,7 @@
     /**
      * Removes from this set all of its elements that are enumerated by {@code iterator}.
      *
-     * @since 1.0
+     * @since 19.0
      */
     default void removeAll(Iterator<E> iterator) {
         while (iterator.hasNext()) {
@@ -134,7 +134,7 @@
     /**
      * Removes from this set all of its elements that are not contained in {@code other}.
      *
-     * @since 1.0
+     * @since 19.0
      */
     default void retainAll(EconomicSet<E> other) {
         Iterator<E> iterator = iterator();
@@ -150,7 +150,7 @@
      * Creates a new set guaranteeing insertion order when iterating over its elements with the
      * default {@link Equivalence#DEFAULT} comparison strategy.
      *
-     * @since 1.0
+     * @since 19.0
      */
     static <E> EconomicSet<E> create() {
         return EconomicSet.create(Equivalence.DEFAULT);
@@ -159,7 +159,7 @@
     /**
      * Creates a new set guaranteeing insertion order when iterating over its elements.
      *
-     * @since 1.0
+     * @since 19.0
      */
     static <E> EconomicSet<E> create(Equivalence strategy) {
         return EconomicMapImpl.create(strategy, true);
@@ -170,7 +170,7 @@
      * default {@link Equivalence#DEFAULT} comparison strategy and inserts all elements of the
      * specified collection.
      *
-     * @since 1.0
+     * @since 19.0
      */
     static <E> EconomicSet<E> create(int initialCapacity) {
         return EconomicSet.create(Equivalence.DEFAULT, initialCapacity);
@@ -181,7 +181,7 @@
      * default {@link Equivalence#DEFAULT} comparison strategy and inserts all elements of the
      * specified collection.
      *
-     * @since 1.0
+     * @since 19.0
      */
     static <E> EconomicSet<E> create(UnmodifiableEconomicSet<E> c) {
         return EconomicSet.create(Equivalence.DEFAULT, c);
@@ -191,7 +191,7 @@
      * Creates a new set guaranteeing insertion order when iterating over its elements and
      * initializes with the given capacity.
      *
-     * @since 1.0
+     * @since 19.0
      */
     static <E> EconomicSet<E> create(Equivalence strategy, int initialCapacity) {
         return EconomicMapImpl.create(strategy, initialCapacity, true);
@@ -201,7 +201,7 @@
      * Creates a new set guaranteeing insertion order when iterating over its elements and inserts
      * all elements of the specified collection.
      *
-     * @since 1.0
+     * @since 19.0
      */
     static <E> EconomicSet<E> create(Equivalence strategy, UnmodifiableEconomicSet<E> c) {
         return EconomicMapImpl.create(strategy, c, true);
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/Equivalence.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/Equivalence.java	Mon Jul 01 14:57:02 2019 -0700
@@ -44,7 +44,7 @@
  * Strategy for comparing two objects. Default predefined strategies are {@link #DEFAULT},
  * {@link #IDENTITY}, and {@link #IDENTITY_WITH_SYSTEM_HASHCODE}.
  *
- * @since 1.0
+ * @since 19.0
  */
 public abstract class Equivalence {
 
@@ -53,7 +53,7 @@
      * for obtaining hash values. Do not change the logic of this class as it may be inlined in
      * other places.
      *
-     * @since 1.0
+     * @since 19.0
      */
     public static final Equivalence DEFAULT = new Equivalence() {
 
@@ -72,7 +72,7 @@
      * Identity equivalence using {@code ==} to check equality and {@link #hashCode()} for obtaining
      * hash values. Do not change the logic of this class as it may be inlined in other places.
      *
-     * @since 1.0
+     * @since 19.0
      */
     public static final Equivalence IDENTITY = new Equivalence() {
 
@@ -92,7 +92,7 @@
      * {@link System#identityHashCode(Object)} for obtaining hash values. Do not change the logic of
      * this class as it may be inlined in other places.
      *
-     * @since 1.0
+     * @since 19.0
      */
     public static final Equivalence IDENTITY_WITH_SYSTEM_HASHCODE = new Equivalence() {
 
@@ -110,7 +110,7 @@
     /**
      * Subclass for creating custom equivalence definitions.
      *
-     * @since 1.0
+     * @since 19.0
      */
     protected Equivalence() {
     }
@@ -119,14 +119,14 @@
      * Returns {@code true} if the non-{@code null} arguments are equal to each other and
      * {@code false} otherwise.
      *
-     * @since 1.0
+     * @since 19.0
      */
     public abstract boolean equals(Object a, Object b);
 
     /**
      * Returns the hash code of a non-{@code null} argument {@code o}.
      *
-     * @since 1.0
+     * @since 19.0
      */
     public abstract int hashCode(Object o);
 }
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/MapCursor.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/MapCursor.java	Mon Jul 01 14:57:02 2019 -0700
@@ -43,7 +43,7 @@
 /**
  * Cursor to iterate over a mutable map.
  *
- * @since 1.0
+ * @since 19.0
  */
 public interface MapCursor<K, V> extends UnmodifiableMapCursor<K, V> {
     /**
@@ -51,7 +51,7 @@
      * {@link #remove()}, it is no longer valid to call {@link #getKey()} or {@link #getValue()} on
      * the current entry.
      *
-     * @since 1.0
+     * @since 19.0
      */
     void remove();
 }
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/Pair.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/Pair.java	Mon Jul 01 14:57:02 2019 -0700
@@ -45,7 +45,7 @@
 /**
  * Utility class representing a pair of values.
  *
- * @since 1.0
+ * @since 19.0
  */
 public final class Pair<L, R> {
 
@@ -57,7 +57,7 @@
     /**
      * Returns an empty pair.
      *
-     * @since 1.0
+     * @since 19.0
      */
     @SuppressWarnings("unchecked")
     public static <L, R> Pair<L, R> empty() {
@@ -69,7 +69,7 @@
      * {@code left} is null.
      *
      * @return the constructed pair or an empty pair if {@code left} is null.
-     * @since 1.0
+     * @since 19.0
      */
     public static <L, R> Pair<L, R> createLeft(L left) {
         if (left == null) {
@@ -84,7 +84,7 @@
      * {@code right} is null.
      *
      * @return the constructed pair or an empty pair if {@code right} is null.
-     * @since 1.0
+     * @since 19.0
      */
     public static <L, R> Pair<L, R> createRight(R right) {
         if (right == null) {
@@ -99,7 +99,7 @@
      * {@code right}, or returns an empty pair if both inputs are null.
      *
      * @return the constructed pair or an empty pair if both inputs are null.
-     * @since 1.0
+     * @since 19.0
      */
     public static <L, R> Pair<L, R> create(L left, R right) {
         if (right == null && left == null) {
@@ -117,7 +117,7 @@
     /**
      * Returns the left value of this pair.
      *
-     * @since 1.0
+     * @since 19.0
      */
     public L getLeft() {
         return left;
@@ -126,7 +126,7 @@
     /**
      * Returns the right value of this pair.
      *
-     * @since 1.0
+     * @since 19.0
      */
     public R getRight() {
         return right;
@@ -135,7 +135,7 @@
     /**
      * {@inheritDoc}
      *
-     * @since 1.0
+     * @since 19.0
      */
     @Override
     public int hashCode() {
@@ -145,7 +145,7 @@
     /**
      * {@inheritDoc}
      *
-     * @since 1.0
+     * @since 19.0
      */
     @SuppressWarnings("unchecked")
     @Override
@@ -165,7 +165,7 @@
     /**
      * {@inheritDoc}
      *
-     * @since 1.0
+     * @since 19.0
      */
     @Override
     public String toString() {
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/UnmodifiableEconomicMap.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/UnmodifiableEconomicMap.java	Mon Jul 01 14:57:02 2019 -0700
@@ -43,7 +43,7 @@
 /**
  * Unmodifiable memory efficient map data structure.
  *
- * @since 1.0
+ * @since 19.0
  */
 public interface UnmodifiableEconomicMap<K, V> {
 
@@ -51,7 +51,7 @@
      * Returns the value to which {@code key} is mapped, or {@code null} if this map contains no
      * mapping for {@code key}.
      *
-     * @since 1.0
+     * @since 19.0
      */
     V get(K key);
 
@@ -59,7 +59,7 @@
      * Returns the value to which {@code key} is mapped, or {@code defaultValue} if this map
      * contains no mapping for {@code key}.
      *
-     * @since 1.0
+     * @since 19.0
      */
     default V get(K key, V defaultValue) {
         V v = get(key);
@@ -72,42 +72,42 @@
     /**
      * Returns {@code true} if this map contains a mapping for {@code key}.
      *
-     * @since 1.0
+     * @since 19.0
      */
     boolean containsKey(K key);
 
     /**
      * Returns the number of key-value mappings in this map.
      *
-     * @since 1.0
+     * @since 19.0
      */
     int size();
 
     /**
      * Returns {@code true} if this map contains no key-value mappings.
      *
-     * @since 1.0
+     * @since 19.0
      */
     boolean isEmpty();
 
     /**
      * Returns a {@link Iterable} view of the values contained in this map.
      *
-     * @since 1.0
+     * @since 19.0
      */
     Iterable<V> getValues();
 
     /**
      * Returns a {@link Iterable} view of the keys contained in this map.
      *
-     * @since 1.0
+     * @since 19.0
      */
     Iterable<K> getKeys();
 
     /**
      * Returns a {@link UnmodifiableMapCursor} view of the mappings contained in this map.
      *
-     * @since 1.0
+     * @since 19.0
      */
     UnmodifiableMapCursor<K, V> getEntries();
 }
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/UnmodifiableEconomicSet.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/UnmodifiableEconomicSet.java	Mon Jul 01 14:57:02 2019 -0700
@@ -43,28 +43,28 @@
 /**
  * Unmodifiable memory efficient set data structure.
  *
- * @since 1.0
+ * @since 19.0
  */
 public interface UnmodifiableEconomicSet<E> extends Iterable<E> {
 
     /**
      * Returns {@code true} if this set contains a mapping for the {@code element}.
      *
-     * @since 1.0
+     * @since 19.0
      */
     boolean contains(E element);
 
     /**
      * Returns the number of elements in this set.
      *
-     * @since 1.0
+     * @since 19.0
      */
     int size();
 
     /**
      * Returns {@code true} if this set contains no elements.
      *
-     * @since 1.0
+     * @since 19.0
      */
     boolean isEmpty();
 
@@ -76,7 +76,7 @@
      * @return an array containing all the elements in this set.
      * @throws UnsupportedOperationException if the length of {@code target} does not equal the size
      *             of this set.
-     * @since 1.0
+     * @since 19.0
      */
     default E[] toArray(E[] target) {
         if (target.length != size()) {
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/UnmodifiableMapCursor.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/UnmodifiableMapCursor.java	Mon Jul 01 14:57:02 2019 -0700
@@ -43,28 +43,28 @@
 /**
  * Cursor to iterate over a map without changing its contents.
  *
- * @since 1.0
+ * @since 19.0
  */
 public interface UnmodifiableMapCursor<K, V> {
     /**
      * Advances to the next entry.
      *
      * @return {@code true} if a next entry exists, {@code false} if there is no next entry.
-     * @since 1.0
+     * @since 19.0
      */
     boolean advance();
 
     /**
      * The key of the current entry.
      *
-     * @since 1.0
+     * @since 19.0
      */
     K getKey();
 
     /**
      * The value of the current entry.
      *
-     * @since 1.0
+     * @since 19.0
      */
     V getValue();
 }
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/package-info.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.collections/src/jdk/internal/vm/compiler/collections/package-info.java	Mon Jul 01 14:57:02 2019 -0700
@@ -31,7 +31,7 @@
  * @see jdk.internal.vm.compiler.collections.EconomicMap
  * @see jdk.internal.vm.compiler.collections.EconomicSet
  *
- * @since 1.0
+ * @since 19.0
  */
 
 
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.libgraal/src/jdk/internal/vm/compiler/libgraal/LibGraal.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.libgraal/src/jdk/internal/vm/compiler/libgraal/LibGraal.java	Mon Jul 01 14:57:02 2019 -0700
@@ -33,67 +33,43 @@
 public class LibGraal {
 
     public static boolean isAvailable() {
-        return isCurrentRuntime() || libgraalIsolate != 0L;
+        return inLibGraal() || isolate != 0L;
     }
 
-    public static boolean isCurrentRuntime() {
+    public static boolean inLibGraal() {
         return Services.IS_IN_NATIVE_IMAGE;
     }
 
-    public static long getIsolate() {
-        if (isCurrentRuntime() || !isAvailable()) {
-            throw new IllegalStateException();
-        }
-        return libgraalIsolate;
-    }
-
-    public static long getIsolateThread() {
-        if (isCurrentRuntime()) {
-            throw new IllegalStateException();
-        }
-        return CURRENT_ISOLATE_THREAD.get();
-    }
-
-    @SuppressWarnings("unused")
-    public static long[] registerNativeMethods(HotSpotJVMCIRuntime runtime, Class<?> clazz) {
+    public static void registerNativeMethods(HotSpotJVMCIRuntime runtime, Class<?> clazz) {
         if (clazz.isPrimitive()) {
             throw new IllegalArgumentException();
         }
-        if (isCurrentRuntime() || !isAvailable()) {
+        if (inLibGraal() || !isAvailable()) {
             throw new IllegalStateException();
         }
-        // Waiting for https://bugs.openjdk.java.net/browse/JDK-8220623
-        // return runtime.registerNativeMethods(clazz);
-        throw new IllegalStateException("Requires JDK-8220623");
+        runtime.registerNativeMethods(clazz);
     }
 
-    @SuppressWarnings("unused")
     public static long translate(HotSpotJVMCIRuntime runtime, Object obj) {
         if (!isAvailable()) {
             throw new IllegalStateException();
         }
-        // return runtime.translate(obj);
-        throw new IllegalStateException("Requires JDK-8220623");
+        if (!inLibGraal() && LibGraalScope.currentScope.get() == null) {
+            throw new IllegalStateException("Not within a " + LibGraalScope.class.getName());
+        }
+        return runtime.translate(obj);
     }
 
-    @SuppressWarnings("unused")
     public static <T> T unhand(HotSpotJVMCIRuntime runtime, Class<T> type, long handle) {
         if (!isAvailable()) {
             throw new IllegalStateException();
         }
-        // return runtime.unhand(type, handle);
-        throw new IllegalStateException("Requires JDK-8220623");
+        if (!inLibGraal() && LibGraalScope.currentScope.get() == null) {
+            throw new IllegalStateException("Not within a " + LibGraalScope.class.getName());
+        }
+        return runtime.unhand(type, handle);
     }
 
-    private static final ThreadLocal<Long> CURRENT_ISOLATE_THREAD = new ThreadLocal<>() {
-        @Override
-        protected Long initialValue() {
-            return attachThread(libgraalIsolate);
-        }
-    };
-
-    private static final long libgraalIsolate = Services.IS_BUILDING_NATIVE_IMAGE ? 0L : initializeLibgraal();
-
     private static long initializeLibgraal() {
         try {
             // Initialize JVMCI to ensure JVMCI opens its packages to
@@ -101,20 +77,27 @@
             // below will fail on JDK13+.
             Services.initializeJVMCI();
 
-            // Waiting for https://bugs.openjdk.java.net/browse/JDK-8220623
-            // HotSpotJVMCIRuntime runtime = HotSpotJVMCIRuntime.runtime();
-            // long[] nativeInterface = runtime.registerNativeMethods(LibGraal.class);
-            // return nativeInterface[1];
-            return 0L;
+            HotSpotJVMCIRuntime runtime = HotSpotJVMCIRuntime.runtime();
+            long[] nativeInterface = runtime.registerNativeMethods(LibGraal.class);
+            return nativeInterface[1];
         } catch (UnsupportedOperationException e) {
             return 0L;
         }
     }
 
-    /**
-     * Attaches the current thread to a thread in {@code isolate}.
-     *
-     * @param isolate
-     */
-    private static native long attachThread(long isolate);
+    static final long isolate = Services.IS_BUILDING_NATIVE_IMAGE ? 0L : initializeLibgraal();
+
+    static boolean isCurrentThreadAttached(HotSpotJVMCIRuntime runtime) {
+        return runtime.isCurrentThreadAttached();
+    }
+
+    static boolean attachCurrentThread(HotSpotJVMCIRuntime runtime) {
+        return runtime.attachCurrentThread(false);
+    }
+
+    static void detachCurrentThread(HotSpotJVMCIRuntime runtime) {
+        runtime.detachCurrentThread();
+    }
+
+    static native long getCurrentIsolateThread(long iso);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.libgraal/src/jdk/internal/vm/compiler/libgraal/LibGraalScope.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package jdk.internal.vm.compiler.libgraal;
+
+import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
+
+/**
+ * Scope for calling CEntryPoints in libgraal. {@linkplain #LibGraalScope(HotSpotJVMCIRuntime)
+ * Opening} a scope attaches the current thread to libgraal and {@linkplain #close() closing} it
+ * detaches the current thread.
+ */
+public final class LibGraalScope implements AutoCloseable {
+
+    static final ThreadLocal<LibGraalScope> currentScope = new ThreadLocal<>();
+
+    private final LibGraalScope parent;
+    private final boolean topLevel;
+    private final HotSpotJVMCIRuntime runtime;
+    private final long isolateThread;
+
+    /**
+     * Gets the isolate thread associated with the current thread. The current thread must be in an
+     * {@linkplain #LibGraalScope(HotSpotJVMCIRuntime) opened} scope.
+     *
+     * @returns a value that can be used for the IsolateThreadContext argument of a {@code native}
+     *          method {@link LibGraal#registerNativeMethods linked} to a CEntryPoint function in
+     *          libgraal
+     * @throws IllegalStateException if not the current thread is not attached to libgraal
+     */
+    public static long getIsolateThread() {
+        LibGraalScope scope = currentScope.get();
+        if (scope == null) {
+            throw new IllegalStateException("Cannot get isolate thread outside of a " + LibGraalScope.class.getSimpleName());
+        }
+        return scope.isolateThread;
+    }
+
+    /**
+     * Enters a scope for making calls into libgraal. If there is no existing libgraal scope for the
+     * current thread, the current thread is attached to libgraal. When the outer most scope is
+     * closed, the current thread is detached from libgraal.
+     *
+     * This must be used in a try-with-resources statement.
+     *
+     * This cannot be called from {@linkplain LibGraal#inLibGraal() within} libgraal.
+     *
+     * @throws IllegalStateException if libgraal is {@linkplain LibGraal#isAvailable() unavailable}
+     *             or {@link LibGraal#inLibGraal()} returns true
+     */
+    public LibGraalScope(HotSpotJVMCIRuntime runtime) {
+        if (LibGraal.inLibGraal() || !LibGraal.isAvailable()) {
+            throw new IllegalStateException();
+        }
+        this.runtime = runtime;
+        parent = currentScope.get();
+        boolean top = false;
+        if (parent == null) {
+            top = LibGraal.attachCurrentThread(runtime);
+            isolateThread = LibGraal.getCurrentIsolateThread(LibGraal.isolate);
+        } else {
+            isolateThread = parent.isolateThread;
+        }
+        topLevel = top;
+        currentScope.set(this);
+    }
+
+    @Override
+    public void close() {
+        if (topLevel) {
+            LibGraal.detachCurrentThread(runtime);
+        }
+        currentScope.set(parent);
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.libgraal/src/jdk/internal/vm/compiler/libgraal/OptionsEncoder.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.libgraal/src/jdk/internal/vm/compiler/libgraal/OptionsEncoder.java	Mon Jul 01 14:57:02 2019 -0700
@@ -162,6 +162,9 @@
                 }
                 res.put(key, value);
             }
+            if (in.available() != 0) {
+                throw new IllegalArgumentException(in.available() + " undecoded bytes");
+            }
         } catch (IOException ioe) {
             throw new IllegalArgumentException(ioe);
         }
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/ComparableWord.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/ComparableWord.java	Mon Jul 01 14:57:02 2019 -0700
@@ -43,7 +43,7 @@
 /**
  * A machine-word-sized value that can be compared for equality.
  *
- * @since 1.0
+ * @since 19.0
  */
 public interface ComparableWord extends WordBase {
 
@@ -53,7 +53,7 @@
      * @param val value to which this word is to be compared.
      * @return {@code this == val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     boolean equal(ComparableWord val);
 
@@ -63,7 +63,7 @@
      * @param val value to which this word is to be compared.
      * @return {@code this != val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     boolean notEqual(ComparableWord val);
 }
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/LocationIdentity.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/LocationIdentity.java	Mon Jul 01 14:57:02 2019 -0700
@@ -50,7 +50,7 @@
  * comparing two {@link LocationIdentity} values for equality. Likewise, they must not use
  * {@link java.util.IdentityHashMap}s with {@link LocationIdentity} values as keys.
  *
- * @since 1.0
+ * @since 19.0
  */
 public abstract class LocationIdentity {
 
@@ -82,7 +82,7 @@
      * Creates a new location identity. Subclasses are responsible to provide proper implementations
      * of {@link #equals} and {@link #hashCode}.
      *
-     * @since 1.0
+     * @since 19.0
      */
     protected LocationIdentity() {
     }
@@ -92,7 +92,7 @@
      * such a location kill all reads from mutable locations and a read from this location is killed
      * by any write (except for initialization writes).
      *
-     * @since 1.0
+     * @since 19.0
      */
     public static final LocationIdentity ANY_LOCATION = new AnyLocationIdentity();
 
@@ -101,7 +101,7 @@
      * is written. Kills no read. The previous value at the given location must be either
      * uninitialized or null. Writes to this location do not need a GC pre-barrier.
      *
-     * @since 1.0
+     * @since 19.0
      */
     public static final LocationIdentity INIT_LOCATION = new InitLocationIdentity();
 
@@ -110,7 +110,7 @@
      * such a location kill all reads from mutable locations and a read from this location is killed
      * by any write (except for initialization writes).
      *
-     * @since 1.0
+     * @since 19.0
      */
     public static LocationIdentity any() {
         return ANY_LOCATION;
@@ -121,7 +121,7 @@
      * is written. Kills no read. The previous value at the given location must be either
      * uninitialized or null. Writes to this location do not need a GC pre-barrier.
      *
-     * @since 1.0
+     * @since 19.0
      */
     public static LocationIdentity init() {
         return INIT_LOCATION;
@@ -131,14 +131,14 @@
      * Denotes a location is unchanging in all cases. Not that this is different than the Java
      * notion of final which only requires definite assignment.
      *
-     * @since 1.0
+     * @since 19.0
      */
     public abstract boolean isImmutable();
 
     /**
      * The inversion of {@link #isImmutable}.
      *
-     * @since 1.0
+     * @since 19.0
      */
     public final boolean isMutable() {
         return !isImmutable();
@@ -147,7 +147,7 @@
     /**
      * Returns true if this location identity is {@link #any}.
      *
-     * @since 1.0
+     * @since 19.0
      */
     public final boolean isAny() {
         return this == ANY_LOCATION;
@@ -156,7 +156,7 @@
     /**
      * Returns true if this location identity is {@link #init}.
      *
-     * @since 1.0
+     * @since 19.0
      */
     public final boolean isInit() {
         return this == INIT_LOCATION;
@@ -165,7 +165,7 @@
     /**
      * Returns true if this location identity is not {@link #any}.
      *
-     * @since 1.0
+     * @since 19.0
      */
     public final boolean isSingle() {
         return this != ANY_LOCATION;
@@ -175,7 +175,7 @@
      * Returns true if the memory slice denoted by this location identity may overlap with the
      * provided other location identity.
      *
-     * @since 1.0
+     * @since 19.0
      */
     public final boolean overlaps(LocationIdentity other) {
         return isAny() || other.isAny() || this.equals(other);
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/Pointer.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/Pointer.java	Mon Jul 01 14:57:02 2019 -0700
@@ -47,7 +47,7 @@
  * null checks, read- or write barriers. Even when the VM uses compressed pointers, then readObject
  * and writeObject methods access uncompressed pointers.
  *
- * @since 1.0
+ * @since 19.0
  */
 public interface Pointer extends UnsignedWord, PointerBase {
 
@@ -58,7 +58,7 @@
      *
      * @return this Pointer cast to Object.
      *
-     * @since 1.0
+     * @since 19.0
      */
     Object toObject();
 
@@ -69,7 +69,7 @@
      *
      * @return this Pointer cast to non-null Object.
      *
-     * @since 1.0
+     * @since 19.0
      */
     Object toObjectNonNull();
 
@@ -85,7 +85,7 @@
      * @param locationIdentity the identity of the read
      * @return the result of the memory access
      *
-     * @since 1.0
+     * @since 19.0
      */
     byte readByte(WordBase offset, LocationIdentity locationIdentity);
 
@@ -101,7 +101,7 @@
      * @param locationIdentity the identity of the read
      * @return the result of the memory access
      *
-     * @since 1.0
+     * @since 19.0
      */
     char readChar(WordBase offset, LocationIdentity locationIdentity);
 
@@ -117,7 +117,7 @@
      * @param locationIdentity the identity of the read
      * @return the result of the memory access
      *
-     * @since 1.0
+     * @since 19.0
      */
     short readShort(WordBase offset, LocationIdentity locationIdentity);
 
@@ -133,7 +133,7 @@
      * @param locationIdentity the identity of the read
      * @return the result of the memory access
      *
-     * @since 1.0
+     * @since 19.0
      */
     int readInt(WordBase offset, LocationIdentity locationIdentity);
 
@@ -149,7 +149,7 @@
      * @param locationIdentity the identity of the read
      * @return the result of the memory access
      *
-     * @since 1.0
+     * @since 19.0
      */
     long readLong(WordBase offset, LocationIdentity locationIdentity);
 
@@ -165,7 +165,7 @@
      * @param locationIdentity the identity of the read
      * @return the result of the memory access
      *
-     * @since 1.0
+     * @since 19.0
      */
     float readFloat(WordBase offset, LocationIdentity locationIdentity);
 
@@ -181,7 +181,7 @@
      * @param locationIdentity the identity of the read
      * @return the result of the memory access
      *
-     * @since 1.0
+     * @since 19.0
      */
     double readDouble(WordBase offset, LocationIdentity locationIdentity);
 
@@ -197,7 +197,7 @@
      * @param locationIdentity the identity of the read
      * @return the result of the memory access
      *
-     * @since 1.0
+     * @since 19.0
      */
     <T extends WordBase> T readWord(WordBase offset, LocationIdentity locationIdentity);
 
@@ -213,7 +213,7 @@
      * @param locationIdentity the identity of the read
      * @return the result of the memory access
      *
-     * @since 1.0
+     * @since 19.0
      */
     Object readObject(WordBase offset, LocationIdentity locationIdentity);
 
@@ -225,7 +225,7 @@
      * @param locationIdentity the identity of the read
      * @return the result of the memory access
      *
-     * @since 1.0
+     * @since 19.0
      */
     byte readByte(int offset, LocationIdentity locationIdentity);
 
@@ -237,7 +237,7 @@
      * @param locationIdentity the identity of the read
      * @return the result of the memory access
      *
-     * @since 1.0
+     * @since 19.0
      */
     char readChar(int offset, LocationIdentity locationIdentity);
 
@@ -249,7 +249,7 @@
      * @param locationIdentity the identity of the read
      * @return the result of the memory access
      *
-     * @since 1.0
+     * @since 19.0
      */
     short readShort(int offset, LocationIdentity locationIdentity);
 
@@ -261,7 +261,7 @@
      * @param locationIdentity the identity of the read
      * @return the result of the memory access
      *
-     * @since 1.0
+     * @since 19.0
      */
     int readInt(int offset, LocationIdentity locationIdentity);
 
@@ -273,7 +273,7 @@
      * @param locationIdentity the identity of the read
      * @return the result of the memory access
      *
-     * @since 1.0
+     * @since 19.0
      */
     long readLong(int offset, LocationIdentity locationIdentity);
 
@@ -285,7 +285,7 @@
      * @param locationIdentity the identity of the read
      * @return the result of the memory access
      *
-     * @since 1.0
+     * @since 19.0
      */
     float readFloat(int offset, LocationIdentity locationIdentity);
 
@@ -297,7 +297,7 @@
      * @param locationIdentity the identity of the read
      * @return the result of the memory access
      *
-     * @since 1.0
+     * @since 19.0
      */
     double readDouble(int offset, LocationIdentity locationIdentity);
 
@@ -309,7 +309,7 @@
      * @param locationIdentity the identity of the read
      * @return the result of the memory access
      *
-     * @since 1.0
+     * @since 19.0
      */
     <T extends WordBase> T readWord(int offset, LocationIdentity locationIdentity);
 
@@ -321,7 +321,7 @@
      * @param locationIdentity the identity of the read
      * @return the result of the memory access
      *
-     * @since 1.0
+     * @since 19.0
      */
     Object readObject(int offset, LocationIdentity locationIdentity);
 
@@ -337,7 +337,7 @@
      * @param locationIdentity the identity of the write
      * @param val the value to be written to memory
      *
-     * @since 1.0
+     * @since 19.0
      */
     void writeByte(WordBase offset, byte val, LocationIdentity locationIdentity);
 
@@ -353,7 +353,7 @@
      * @param locationIdentity the identity of the write
      * @param val the value to be written to memory
      *
-     * @since 1.0
+     * @since 19.0
      */
     void writeChar(WordBase offset, char val, LocationIdentity locationIdentity);
 
@@ -369,7 +369,7 @@
      * @param locationIdentity the identity of the write
      * @param val the value to be written to memory
      *
-     * @since 1.0
+     * @since 19.0
      */
     void writeShort(WordBase offset, short val, LocationIdentity locationIdentity);
 
@@ -385,7 +385,7 @@
      * @param locationIdentity the identity of the write
      * @param val the value to be written to memory
      *
-     * @since 1.0
+     * @since 19.0
      */
     void writeInt(WordBase offset, int val, LocationIdentity locationIdentity);
 
@@ -401,7 +401,7 @@
      * @param locationIdentity the identity of the write
      * @param val the value to be written to memory
      *
-     * @since 1.0
+     * @since 19.0
      */
     void writeLong(WordBase offset, long val, LocationIdentity locationIdentity);
 
@@ -417,7 +417,7 @@
      * @param locationIdentity the identity of the write
      * @param val the value to be written to memory
      *
-     * @since 1.0
+     * @since 19.0
      */
     void writeFloat(WordBase offset, float val, LocationIdentity locationIdentity);
 
@@ -433,7 +433,7 @@
      * @param locationIdentity the identity of the write
      * @param val the value to be written to memory
      *
-     * @since 1.0
+     * @since 19.0
      */
     void writeDouble(WordBase offset, double val, LocationIdentity locationIdentity);
 
@@ -449,7 +449,7 @@
      * @param locationIdentity the identity of the write
      * @param val the value to be written to memory
      *
-     * @since 1.0
+     * @since 19.0
      */
     void writeWord(WordBase offset, WordBase val, LocationIdentity locationIdentity);
 
@@ -465,7 +465,7 @@
      * @param locationIdentity the identity of the write
      * @param val the value to be written to memory
      *
-     * @since 1.0
+     * @since 19.0
      */
     void initializeLong(WordBase offset, long val, LocationIdentity locationIdentity);
 
@@ -481,7 +481,7 @@
      * @param locationIdentity the identity of the write
      * @param val the value to be written to memory
      *
-     * @since 1.0
+     * @since 19.0
      */
     void writeObject(WordBase offset, Object val, LocationIdentity locationIdentity);
 
@@ -493,7 +493,7 @@
      * @param locationIdentity the identity of the write
      * @param val the value to be written to memory
      *
-     * @since 1.0
+     * @since 19.0
      */
     void writeByte(int offset, byte val, LocationIdentity locationIdentity);
 
@@ -505,7 +505,7 @@
      * @param locationIdentity the identity of the write
      * @param val the value to be written to memory
      *
-     * @since 1.0
+     * @since 19.0
      */
     void writeChar(int offset, char val, LocationIdentity locationIdentity);
 
@@ -517,7 +517,7 @@
      * @param locationIdentity the identity of the write
      * @param val the value to be written to memory
      *
-     * @since 1.0
+     * @since 19.0
      */
     void writeShort(int offset, short val, LocationIdentity locationIdentity);
 
@@ -529,7 +529,7 @@
      * @param locationIdentity the identity of the write
      * @param val the value to be written to memory
      *
-     * @since 1.0
+     * @since 19.0
      */
     void writeInt(int offset, int val, LocationIdentity locationIdentity);
 
@@ -541,7 +541,7 @@
      * @param locationIdentity the identity of the write
      * @param val the value to be written to memory
      *
-     * @since 1.0
+     * @since 19.0
      */
     void writeLong(int offset, long val, LocationIdentity locationIdentity);
 
@@ -553,7 +553,7 @@
      * @param locationIdentity the identity of the write
      * @param val the value to be written to memory
      *
-     * @since 1.0
+     * @since 19.0
      */
     void writeFloat(int offset, float val, LocationIdentity locationIdentity);
 
@@ -565,7 +565,7 @@
      * @param locationIdentity the identity of the write
      * @param val the value to be written to memory
      *
-     * @since 1.0
+     * @since 19.0
      */
     void writeDouble(int offset, double val, LocationIdentity locationIdentity);
 
@@ -577,7 +577,7 @@
      * @param locationIdentity the identity of the write
      * @param val the value to be written to memory
      *
-     * @since 1.0
+     * @since 19.0
      */
     void writeWord(int offset, WordBase val, LocationIdentity locationIdentity);
 
@@ -589,7 +589,7 @@
      * @param locationIdentity the identity of the write
      * @param val the value to be written to memory
      *
-     * @since 1.0
+     * @since 19.0
      */
     void initializeLong(int offset, long val, LocationIdentity locationIdentity);
 
@@ -601,7 +601,7 @@
      * @param locationIdentity the identity of the write
      * @param val the value to be written to memory
      *
-     * @since 1.0
+     * @since 19.0
      */
     void writeObject(int offset, Object val, LocationIdentity locationIdentity);
 
@@ -616,7 +616,7 @@
      * @param offset the signed offset for the memory access
      * @return the result of the memory access
      *
-     * @since 1.0
+     * @since 19.0
      */
     byte readByte(WordBase offset);
 
@@ -631,7 +631,7 @@
      * @param offset the signed offset for the memory access
      * @return the result of the memory access
      *
-     * @since 1.0
+     * @since 19.0
      */
     char readChar(WordBase offset);
 
@@ -646,7 +646,7 @@
      * @param offset the signed offset for the memory access
      * @return the result of the memory access
      *
-     * @since 1.0
+     * @since 19.0
      */
     short readShort(WordBase offset);
 
@@ -661,7 +661,7 @@
      * @param offset the signed offset for the memory access
      * @return the result of the memory access
      *
-     * @since 1.0
+     * @since 19.0
      */
     int readInt(WordBase offset);
 
@@ -676,7 +676,7 @@
      * @param offset the signed offset for the memory access
      * @return the result of the memory access
      *
-     * @since 1.0
+     * @since 19.0
      */
     long readLong(WordBase offset);
 
@@ -691,7 +691,7 @@
      * @param offset the signed offset for the memory access
      * @return the result of the memory access
      *
-     * @since 1.0
+     * @since 19.0
      */
     float readFloat(WordBase offset);
 
@@ -706,7 +706,7 @@
      * @param offset the signed offset for the memory access
      * @return the result of the memory access
      *
-     * @since 1.0
+     * @since 19.0
      */
     double readDouble(WordBase offset);
 
@@ -721,7 +721,7 @@
      * @param offset the signed offset for the memory access
      * @return the result of the memory access
      *
-     * @since 1.0
+     * @since 19.0
      */
     <T extends WordBase> T readWord(WordBase offset);
 
@@ -736,7 +736,7 @@
      * @param offset the signed offset for the memory access
      * @return the result of the memory access
      *
-     * @since 1.0
+     * @since 19.0
      */
     Object readObject(WordBase offset);
 
@@ -747,7 +747,7 @@
      * @param offset the signed offset for the memory access
      * @return the result of the memory access
      *
-     * @since 1.0
+     * @since 19.0
      */
     byte readByte(int offset);
 
@@ -758,7 +758,7 @@
      * @param offset the signed offset for the memory access
      * @return the result of the memory access
      *
-     * @since 1.0
+     * @since 19.0
      */
     char readChar(int offset);
 
@@ -769,7 +769,7 @@
      * @param offset the signed offset for the memory access
      * @return the result of the memory access
      *
-     * @since 1.0
+     * @since 19.0
      */
     short readShort(int offset);
 
@@ -780,7 +780,7 @@
      * @param offset the signed offset for the memory access
      * @return the result of the memory access
      *
-     * @since 1.0
+     * @since 19.0
      */
     int readInt(int offset);
 
@@ -791,7 +791,7 @@
      * @param offset the signed offset for the memory access
      * @return the result of the memory access
      *
-     * @since 1.0
+     * @since 19.0
      */
     long readLong(int offset);
 
@@ -802,7 +802,7 @@
      * @param offset the signed offset for the memory access
      * @return the result of the memory access
      *
-     * @since 1.0
+     * @since 19.0
      */
     float readFloat(int offset);
 
@@ -813,7 +813,7 @@
      * @param offset the signed offset for the memory access
      * @return the result of the memory access
      *
-     * @since 1.0
+     * @since 19.0
      */
     double readDouble(int offset);
 
@@ -824,7 +824,7 @@
      * @param offset the signed offset for the memory access
      * @return the result of the memory access
      *
-     * @since 1.0
+     * @since 19.0
      */
     <T extends WordBase> T readWord(int offset);
 
@@ -835,7 +835,7 @@
      * @param offset the signed offset for the memory access
      * @return the result of the memory access
      *
-     * @since 1.0
+     * @since 19.0
      */
     Object readObject(int offset);
 
@@ -850,7 +850,7 @@
      * @param offset the signed offset for the memory access
      * @param val the value to be written to memory
      *
-     * @since 1.0
+     * @since 19.0
      */
     void writeByte(WordBase offset, byte val);
 
@@ -865,7 +865,7 @@
      * @param offset the signed offset for the memory access
      * @param val the value to be written to memory
      *
-     * @since 1.0
+     * @since 19.0
      */
     void writeChar(WordBase offset, char val);
 
@@ -880,7 +880,7 @@
      * @param offset the signed offset for the memory access
      * @param val the value to be written to memory
      *
-     * @since 1.0
+     * @since 19.0
      */
     void writeShort(WordBase offset, short val);
 
@@ -895,7 +895,7 @@
      * @param offset the signed offset for the memory access
      * @param val the value to be written to memory
      *
-     * @since 1.0
+     * @since 19.0
      */
     void writeInt(WordBase offset, int val);
 
@@ -910,7 +910,7 @@
      * @param offset the signed offset for the memory access
      * @param val the value to be written to memory
      *
-     * @since 1.0
+     * @since 19.0
      */
     void writeLong(WordBase offset, long val);
 
@@ -925,7 +925,7 @@
      * @param offset the signed offset for the memory access
      * @param val the value to be written to memory
      *
-     * @since 1.0
+     * @since 19.0
      */
     void writeFloat(WordBase offset, float val);
 
@@ -940,7 +940,7 @@
      * @param offset the signed offset for the memory access
      * @param val the value to be written to memory
      *
-     * @since 1.0
+     * @since 19.0
      */
     void writeDouble(WordBase offset, double val);
 
@@ -955,7 +955,7 @@
      * @param offset the signed offset for the memory access
      * @param val the value to be written to memory
      *
-     * @since 1.0
+     * @since 19.0
      */
     void writeWord(WordBase offset, WordBase val);
 
@@ -970,7 +970,7 @@
      * @param offset the signed offset for the memory access
      * @param val the value to be written to memory
      *
-     * @since 1.0
+     * @since 19.0
      */
     void writeObject(WordBase offset, Object val);
 
@@ -990,7 +990,7 @@
      * @return The value that was read for comparison, which is {@code expectedValue} if the
      *         exchange was performed.
      *
-     * @since 1.0
+     * @since 19.0
      */
     int compareAndSwapInt(WordBase offset, int expectedValue, int newValue, LocationIdentity locationIdentity);
 
@@ -1010,7 +1010,7 @@
      * @return The value that was read for comparison, which is {@code expectedValue} if the
      *         exchange was performed.
      *
-     * @since 1.0
+     * @since 19.0
      */
     long compareAndSwapLong(WordBase offset, long expectedValue, long newValue, LocationIdentity locationIdentity);
 
@@ -1030,7 +1030,7 @@
      * @return The value that was read for comparison, which is {@code expectedValue} if the
      *         exchange was performed.
      *
-     * @since 1.0
+     * @since 19.0
      */
     <T extends WordBase> T compareAndSwapWord(WordBase offset, T expectedValue, T newValue, LocationIdentity locationIdentity);
 
@@ -1050,7 +1050,7 @@
      * @return The value that was read for comparison, which is {@code expectedValue} if the
      *         exchange was performed.
      *
-     * @since 1.0
+     * @since 19.0
      */
     Object compareAndSwapObject(WordBase offset, Object expectedValue, Object newValue, LocationIdentity locationIdentity);
 
@@ -1070,7 +1070,7 @@
      * @return {@code true} if successful. False return indicates that the actual value was not
      *         equal to the expected value.
      *
-     * @since 1.0
+     * @since 19.0
      */
     boolean logicCompareAndSwapInt(WordBase offset, int expectedValue, int newValue, LocationIdentity locationIdentity);
 
@@ -1090,7 +1090,7 @@
      * @return {@code true} if successful. False return indicates that the actual value was not
      *         equal to the expected value.
      *
-     * @since 1.0
+     * @since 19.0
      */
     boolean logicCompareAndSwapLong(WordBase offset, long expectedValue, long newValue, LocationIdentity locationIdentity);
 
@@ -1110,7 +1110,7 @@
      * @return {@code true} if successful. False return indicates that the actual value was not
      *         equal to the expected value.
      *
-     * @since 1.0
+     * @since 19.0
      */
     boolean logicCompareAndSwapWord(WordBase offset, WordBase expectedValue, WordBase newValue, LocationIdentity locationIdentity);
 
@@ -1130,7 +1130,7 @@
      * @return {@code true} if successful. False return indicates that the actual value was not
      *         equal to the expected value.
      *
-     * @since 1.0
+     * @since 19.0
      */
     boolean logicCompareAndSwapObject(WordBase offset, Object expectedValue, Object newValue, LocationIdentity locationIdentity);
 
@@ -1141,7 +1141,7 @@
      * @param offset the signed offset for the memory access
      * @param val the value to be written to memory
      *
-     * @since 1.0
+     * @since 19.0
      */
     void writeByte(int offset, byte val);
 
@@ -1152,7 +1152,7 @@
      * @param offset the signed offset for the memory access
      * @param val the value to be written to memory
      *
-     * @since 1.0
+     * @since 19.0
      */
     void writeChar(int offset, char val);
 
@@ -1163,7 +1163,7 @@
      * @param offset the signed offset for the memory access
      * @param val the value to be written to memory
      *
-     * @since 1.0
+     * @since 19.0
      */
     void writeShort(int offset, short val);
 
@@ -1174,7 +1174,7 @@
      * @param offset the signed offset for the memory access
      * @param val the value to be written to memory
      *
-     * @since 1.0
+     * @since 19.0
      */
     void writeInt(int offset, int val);
 
@@ -1185,7 +1185,7 @@
      * @param offset the signed offset for the memory access
      * @param val the value to be written to memory
      *
-     * @since 1.0
+     * @since 19.0
      */
     void writeLong(int offset, long val);
 
@@ -1196,7 +1196,7 @@
      * @param offset the signed offset for the memory access
      * @param val the value to be written to memory
      *
-     * @since 1.0
+     * @since 19.0
      */
     void writeFloat(int offset, float val);
 
@@ -1207,7 +1207,7 @@
      * @param offset the signed offset for the memory access
      * @param val the value to be written to memory
      *
-     * @since 1.0
+     * @since 19.0
      */
     void writeDouble(int offset, double val);
 
@@ -1218,7 +1218,7 @@
      * @param offset the signed offset for the memory access
      * @param val the value to be written to memory
      *
-     * @since 1.0
+     * @since 19.0
      */
     void writeWord(int offset, WordBase val);
 
@@ -1229,7 +1229,7 @@
      * @param offset the signed offset for the memory access
      * @param val the value to be written to memory
      *
-     * @since 1.0
+     * @since 19.0
      */
     void writeObject(int offset, Object val);
 
@@ -1245,7 +1245,7 @@
      * @return The value that was read for comparison, which is {@code expectedValue} if the
      *         exchange was performed.
      *
-     * @since 1.0
+     * @since 19.0
      */
     int compareAndSwapInt(int offset, int expectedValue, int newValue, LocationIdentity locationIdentity);
 
@@ -1261,7 +1261,7 @@
      * @return The value that was read for comparison, which is {@code expectedValue} if the
      *         exchange was performed.
      *
-     * @since 1.0
+     * @since 19.0
      */
     long compareAndSwapLong(int offset, long expectedValue, long newValue, LocationIdentity locationIdentity);
 
@@ -1277,7 +1277,7 @@
      * @return The value that was read for comparison, which is {@code expectedValue} if the
      *         exchange was performed.
      *
-     * @since 1.0
+     * @since 19.0
      */
     <T extends WordBase> T compareAndSwapWord(int offset, T expectedValue, T newValue, LocationIdentity locationIdentity);
 
@@ -1293,7 +1293,7 @@
      * @return The value that was read for comparison, which is {@code expectedValue} if the
      *         exchange was performed.
      *
-     * @since 1.0
+     * @since 19.0
      */
     Object compareAndSwapObject(int offset, Object expectedValue, Object newValue, LocationIdentity locationIdentity);
 
@@ -1309,7 +1309,7 @@
      * @return {@code true} if successful. False return indicates that the actual value was not
      *         equal to the expected value.
      *
-     * @since 1.0
+     * @since 19.0
      */
     boolean logicCompareAndSwapInt(int offset, int expectedValue, int newValue, LocationIdentity locationIdentity);
 
@@ -1325,7 +1325,7 @@
      * @return {@code true} if successful. False return indicates that the actual value was not
      *         equal to the expected value.
      *
-     * @since 1.0
+     * @since 19.0
      */
     boolean logicCompareAndSwapLong(int offset, long expectedValue, long newValue, LocationIdentity locationIdentity);
 
@@ -1341,7 +1341,7 @@
      * @return {@code true} if successful. False return indicates that the actual value was not
      *         equal to the expected value.
      *
-     * @since 1.0
+     * @since 19.0
      */
     boolean logicCompareAndSwapWord(int offset, WordBase expectedValue, WordBase newValue, LocationIdentity locationIdentity);
 
@@ -1357,7 +1357,7 @@
      * @return {@code true} if successful. False return indicates that the actual value was not
      *         equal to the expected value.
      *
-     * @since 1.0
+     * @since 19.0
      */
     boolean logicCompareAndSwapObject(int offset, Object expectedValue, Object newValue, LocationIdentity locationIdentity);
 
@@ -1371,7 +1371,7 @@
      * @param val value to be added to this Pointer.
      * @return {@code this + val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     @Override
     Pointer add(UnsignedWord val);
@@ -1382,7 +1382,7 @@
      * @param val value to be added to this Pointer.
      * @return {@code this + val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     @Override
     Pointer add(int val);
@@ -1393,7 +1393,7 @@
      * @param val value to be subtracted from this Pointer.
      * @return {@code this - val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     @Override
     Pointer subtract(UnsignedWord val);
@@ -1404,7 +1404,7 @@
      * @param val value to be subtracted from this Pointer.
      * @return {@code this - val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     @Override
     Pointer subtract(int val);
@@ -1415,7 +1415,7 @@
      * @param val value to be AND'ed with this Pointer.
      * @return {@code this & val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     @Override
     Pointer and(UnsignedWord val);
@@ -1426,7 +1426,7 @@
      * @param val value to be AND'ed with this Pointer.
      * @return {@code this & val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     @Override
     Pointer and(int val);
@@ -1437,7 +1437,7 @@
      * @param val value to be OR'ed with this Pointer.
      * @return {@code this | val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     @Override
     Pointer or(UnsignedWord val);
@@ -1448,7 +1448,7 @@
      * @param val value to be OR'ed with this Pointer.
      * @return {@code this | val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     @Override
     Pointer or(int val);
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/PointerBase.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/PointerBase.java	Mon Jul 01 14:57:02 2019 -0700
@@ -44,21 +44,21 @@
  * Marker interface for all {@link WordBase word types} that have the semantic of a pointer (but not
  * necessarily all the memory access methods defined in {@link Pointer}).
  *
- * @since 1.0
+ * @since 19.0
  */
 public interface PointerBase extends ComparableWord {
 
     /**
      * Returns true if this pointer is the {@link WordFactory#nullPointer null pointer}.
      *
-     * @since 1.0
+     * @since 19.0
      */
     boolean isNull();
 
     /**
      * Returns true if this pointer is not the {@link WordFactory#nullPointer null pointer}.
      *
-     * @since 1.0
+     * @since 19.0
      */
     boolean isNonNull();
 }
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/SignedWord.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/SignedWord.java	Mon Jul 01 14:57:02 2019 -0700
@@ -43,7 +43,7 @@
 /**
  * Represents a signed word-sized value.
  *
- * @since 1.0
+ * @since 19.0
  */
 public interface SignedWord extends ComparableWord {
 
@@ -53,7 +53,7 @@
      * @param val value to be added to this Signed.
      * @return {@code this + val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     SignedWord add(SignedWord val);
 
@@ -63,7 +63,7 @@
      * @param val value to be subtracted from this Signed.
      * @return {@code this - val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     SignedWord subtract(SignedWord val);
 
@@ -73,7 +73,7 @@
      * @param val value to be multiplied by this Signed.
      * @return {@code this * val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     SignedWord multiply(SignedWord val);
 
@@ -83,7 +83,7 @@
      * @param val value by which this Signed is to be divided.
      * @return {@code this / val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     SignedWord signedDivide(SignedWord val);
 
@@ -93,7 +93,7 @@
      * @param val value by which this Signed is to be divided, and the remainder computed.
      * @return {@code this % val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     SignedWord signedRemainder(SignedWord val);
 
@@ -103,7 +103,7 @@
      * @param n shift distance, in bits.
      * @return {@code this << n}
      *
-     * @since 1.0
+     * @since 19.0
      */
     SignedWord shiftLeft(UnsignedWord n);
 
@@ -113,7 +113,7 @@
      * @param n shift distance, in bits.
      * @return {@code this >> n}
      *
-     * @since 1.0
+     * @since 19.0
      */
     SignedWord signedShiftRight(UnsignedWord n);
 
@@ -124,7 +124,7 @@
      * @param val value to be AND'ed with this Signed.
      * @return {@code this & val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     SignedWord and(SignedWord val);
 
@@ -135,7 +135,7 @@
      * @param val value to be OR'ed with this Signed.
      * @return {@code this | val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     SignedWord or(SignedWord val);
 
@@ -146,7 +146,7 @@
      * @param val value to be XOR'ed with this Signed.
      * @return {@code this ^ val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     SignedWord xor(SignedWord val);
 
@@ -156,7 +156,7 @@
      *
      * @return {@code ~this}
      *
-     * @since 1.0
+     * @since 19.0
      */
     SignedWord not();
 
@@ -166,7 +166,7 @@
      * @param val value to which this Signed is to be compared.
      * @return {@code this == val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     boolean equal(SignedWord val);
 
@@ -176,7 +176,7 @@
      * @param val value to which this Signed is to be compared.
      * @return {@code this != val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     boolean notEqual(SignedWord val);
 
@@ -186,7 +186,7 @@
      * @param val value to which this Signed is to be compared.
      * @return {@code this < val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     boolean lessThan(SignedWord val);
 
@@ -196,7 +196,7 @@
      * @param val value to which this Signed is to be compared.
      * @return {@code this <= val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     boolean lessOrEqual(SignedWord val);
 
@@ -206,7 +206,7 @@
      * @param val value to which this Signed is to be compared.
      * @return {@code this > val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     boolean greaterThan(SignedWord val);
 
@@ -216,7 +216,7 @@
      * @param val value to which this Signed is to be compared.
      * @return {@code this >= val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     boolean greaterOrEqual(SignedWord val);
 
@@ -226,7 +226,7 @@
      * @param val value to be added to this Signed.
      * @return {@code this + val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     SignedWord add(int val);
 
@@ -236,7 +236,7 @@
      * @param val value to be subtracted from this Signed.
      * @return {@code this - val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     SignedWord subtract(int val);
 
@@ -246,7 +246,7 @@
      * @param val value to be multiplied by this Signed.
      * @return {@code this * val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     SignedWord multiply(int val);
 
@@ -256,7 +256,7 @@
      * @param val value by which this Signed is to be divided.
      * @return {@code this / val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     SignedWord signedDivide(int val);
 
@@ -266,7 +266,7 @@
      * @param val value by which this Signed is to be divided, and the remainder computed.
      * @return {@code this % val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     SignedWord signedRemainder(int val);
 
@@ -276,7 +276,7 @@
      * @param n shift distance, in bits.
      * @return {@code this << n}
      *
-     * @since 1.0
+     * @since 19.0
      */
     SignedWord shiftLeft(int n);
 
@@ -286,7 +286,7 @@
      * @param n shift distance, in bits.
      * @return {@code this >> n}
      *
-     * @since 1.0
+     * @since 19.0
      */
     SignedWord signedShiftRight(int n);
 
@@ -297,7 +297,7 @@
      * @param val value to be AND'ed with this Signed.
      * @return {@code this & val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     SignedWord and(int val);
 
@@ -308,7 +308,7 @@
      * @param val value to be OR'ed with this Signed.
      * @return {@code this | val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     SignedWord or(int val);
 
@@ -319,7 +319,7 @@
      * @param val value to be XOR'ed with this Signed.
      * @return {@code this ^ val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     SignedWord xor(int val);
 
@@ -329,7 +329,7 @@
      * @param val value to which this Signed is to be compared.
      * @return {@code this == val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     boolean equal(int val);
 
@@ -339,7 +339,7 @@
      * @param val value to which this Signed is to be compared.
      * @return {@code this != val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     boolean notEqual(int val);
 
@@ -349,7 +349,7 @@
      * @param val value to which this Signed is to be compared.
      * @return {@code this < val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     boolean lessThan(int val);
 
@@ -359,7 +359,7 @@
      * @param val value to which this Signed is to be compared.
      * @return {@code this <= val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     boolean lessOrEqual(int val);
 
@@ -369,7 +369,7 @@
      * @param val value to which this Signed is to be compared.
      * @return {@code this > val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     boolean greaterThan(int val);
 
@@ -379,7 +379,7 @@
      * @param val value to which this Signed is to be compared.
      * @return {@code this >= val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     boolean greaterOrEqual(int val);
 }
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/UnsignedWord.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/UnsignedWord.java	Mon Jul 01 14:57:02 2019 -0700
@@ -43,7 +43,7 @@
 /**
  * Represents an unsigned word-sized value.
  *
- * @since 1.0
+ * @since 19.0
  */
 public interface UnsignedWord extends ComparableWord {
 
@@ -53,7 +53,7 @@
      * @param val value to be added to this Unsigned.
      * @return {@code this + val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     UnsignedWord add(UnsignedWord val);
 
@@ -63,7 +63,7 @@
      * @param val value to be subtracted from this Unsigned.
      * @return {@code this - val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     UnsignedWord subtract(UnsignedWord val);
 
@@ -73,7 +73,7 @@
      * @param val value to be multiplied by this Unsigned.
      * @return {@code this * val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     UnsignedWord multiply(UnsignedWord val);
 
@@ -83,7 +83,7 @@
      * @param val value by which this Unsigned is to be divided.
      * @return {@code this / val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     UnsignedWord unsignedDivide(UnsignedWord val);
 
@@ -93,7 +93,7 @@
      * @param val value by which this Unsigned is to be divided, and the remainder computed.
      * @return {@code this % val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     UnsignedWord unsignedRemainder(UnsignedWord val);
 
@@ -103,7 +103,7 @@
      * @param n shift distance, in bits.
      * @return {@code this << n}
      *
-     * @since 1.0
+     * @since 19.0
      */
     UnsignedWord shiftLeft(UnsignedWord n);
 
@@ -113,7 +113,7 @@
      * @param n shift distance, in bits.
      * @return {@code this >> n}
      *
-     * @since 1.0
+     * @since 19.0
      */
     UnsignedWord unsignedShiftRight(UnsignedWord n);
 
@@ -123,7 +123,7 @@
      * @param val value to be AND'ed with this Unsigned.
      * @return {@code this & val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     UnsignedWord and(UnsignedWord val);
 
@@ -133,7 +133,7 @@
      * @param val value to be OR'ed with this Unsigned.
      * @return {@code this | val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     UnsignedWord or(UnsignedWord val);
 
@@ -143,7 +143,7 @@
      * @param val value to be XOR'ed with this Unsigned.
      * @return {@code this ^ val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     UnsignedWord xor(UnsignedWord val);
 
@@ -152,7 +152,7 @@
      *
      * @return {@code ~this}
      *
-     * @since 1.0
+     * @since 19.0
      */
     UnsignedWord not();
 
@@ -162,7 +162,7 @@
      * @param val value to which this Unsigned is to be compared.
      * @return {@code this == val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     boolean equal(UnsignedWord val);
 
@@ -172,7 +172,7 @@
      * @param val value to which this Unsigned is to be compared.
      * @return {@code this != val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     boolean notEqual(UnsignedWord val);
 
@@ -182,7 +182,7 @@
      * @param val value to which this Unsigned is to be compared.
      * @return {@code this < val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     boolean belowThan(UnsignedWord val);
 
@@ -192,7 +192,7 @@
      * @param val value to which this Unsigned is to be compared.
      * @return {@code this <= val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     boolean belowOrEqual(UnsignedWord val);
 
@@ -202,7 +202,7 @@
      * @param val value to which this Unsigned is to be compared.
      * @return {@code this > val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     boolean aboveThan(UnsignedWord val);
 
@@ -212,7 +212,7 @@
      * @param val value to which this Unsigned is to be compared.
      * @return {@code this >= val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     boolean aboveOrEqual(UnsignedWord val);
 
@@ -225,7 +225,7 @@
      * @param val value to be added to this Unsigned.
      * @return {@code this + val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     UnsignedWord add(int val);
 
@@ -238,7 +238,7 @@
      * @param val value to be subtracted from this Unsigned.
      * @return {@code this - val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     UnsignedWord subtract(int val);
 
@@ -251,7 +251,7 @@
      * @param val value to be multiplied by this Unsigned.
      * @return {@code this * val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     UnsignedWord multiply(int val);
 
@@ -264,7 +264,7 @@
      * @param val value by which this Unsigned is to be divided.
      * @return {@code this / val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     UnsignedWord unsignedDivide(int val);
 
@@ -277,7 +277,7 @@
      * @param val value by which this Unsigned is to be divided, and the remainder computed.
      * @return {@code this % val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     UnsignedWord unsignedRemainder(int val);
 
@@ -290,7 +290,7 @@
      * @param n shift distance, in bits.
      * @return {@code this << n}
      *
-     * @since 1.0
+     * @since 19.0
      */
     UnsignedWord shiftLeft(int n);
 
@@ -303,7 +303,7 @@
      * @param n shift distance, in bits.
      * @return {@code this >> n}
      *
-     * @since 1.0
+     * @since 19.0
      */
     UnsignedWord unsignedShiftRight(int n);
 
@@ -316,7 +316,7 @@
      * @param val value to be AND'ed with this Unsigned.
      * @return {@code this & val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     UnsignedWord and(int val);
 
@@ -329,7 +329,7 @@
      * @param val value to be OR'ed with this Unsigned.
      * @return {@code this | val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     UnsignedWord or(int val);
 
@@ -342,7 +342,7 @@
      * @param val value to be XOR'ed with this Unsigned.
      * @return {@code this ^ val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     UnsignedWord xor(int val);
 
@@ -355,7 +355,7 @@
      * @param val value to which this Unsigned is to be compared.
      * @return {@code this == val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     boolean equal(int val);
 
@@ -368,7 +368,7 @@
      * @param val value to which this Unsigned is to be compared.
      * @return {@code this != val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     boolean notEqual(int val);
 
@@ -381,7 +381,7 @@
      * @param val value to which this Unsigned is to be compared.
      * @return {@code this < val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     boolean belowThan(int val);
 
@@ -394,7 +394,7 @@
      * @param val value to which this Unsigned is to be compared.
      * @return {@code this <= val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     boolean belowOrEqual(int val);
 
@@ -407,7 +407,7 @@
      * @param val value to which this Unsigned is to be compared.
      * @return {@code this > val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     boolean aboveThan(int val);
 
@@ -420,7 +420,7 @@
      * @param val value to which this Unsigned is to be compared.
      * @return {@code this >= val}
      *
-     * @since 1.0
+     * @since 19.0
      */
     boolean aboveOrEqual(int val);
 }
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/WordBase.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/WordBase.java	Mon Jul 01 14:57:02 2019 -0700
@@ -43,14 +43,14 @@
 /**
  * The root of the interface hierarchy for machine-word-sized values.
  *
- * @since 1.0
+ * @since 19.0
  */
 public interface WordBase {
 
     /**
      * Conversion to a Java primitive value.
      *
-     * @since 1.0
+     * @since 19.0
      */
     long rawValue();
 
@@ -59,7 +59,7 @@
      * the other word based equality routines. In general you should never be statically calling
      * this method anyway.
      *
-     * @since 1.0
+     * @since 19.0
      */
     @Override
     @Deprecated
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/WordFactory.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/WordFactory.java	Mon Jul 01 14:57:02 2019 -0700
@@ -47,7 +47,7 @@
 /**
  * Provides factory method to create machine-word-sized values.
  *
- * @since 1.0
+ * @since 19.0
  */
 public final class WordFactory {
 
@@ -60,7 +60,7 @@
      *
      * @return the constant 0.
      *
-     * @since 1.0
+     * @since 19.0
      */
     @WordFactoryOperation(opcode = WordFactoryOpcode.ZERO)
     public static <T extends WordBase> T zero() {
@@ -73,7 +73,7 @@
      *
      * @return the null pointer.
      *
-     * @since 1.0
+     * @since 19.0
      */
     @WordFactoryOperation(opcode = WordFactoryOpcode.ZERO)
     public static <T extends PointerBase> T nullPointer() {
@@ -87,7 +87,7 @@
      * @param val a 64 bit unsigned value
      * @return the value cast to Word
      *
-     * @since 1.0
+     * @since 19.0
      */
     @WordFactoryOperation(opcode = WordFactoryOpcode.FROM_UNSIGNED)
     public static <T extends UnsignedWord> T unsigned(long val) {
@@ -101,7 +101,7 @@
      * @param val a 64 bit unsigned value
      * @return the value cast to PointerBase
      *
-     * @since 1.0
+     * @since 19.0
      */
     @WordFactoryOperation(opcode = WordFactoryOpcode.FROM_UNSIGNED)
     public static <T extends PointerBase> T pointer(long val) {
@@ -115,7 +115,7 @@
      * @param val a 32 bit unsigned value
      * @return the value cast to Word
      *
-     * @since 1.0
+     * @since 19.0
      */
     @WordFactoryOperation(opcode = WordFactoryOpcode.FROM_UNSIGNED)
     public static <T extends UnsignedWord> T unsigned(int val) {
@@ -129,7 +129,7 @@
      * @param val a 64 bit signed value
      * @return the value cast to Word
      *
-     * @since 1.0
+     * @since 19.0
      */
     @WordFactoryOperation(opcode = WordFactoryOpcode.FROM_SIGNED)
     public static <T extends SignedWord> T signed(long val) {
@@ -143,7 +143,7 @@
      * @param val a 32 bit signed value
      * @return the value cast to Word
      *
-     * @since 1.0
+     * @since 19.0
      */
     @WordFactoryOperation(opcode = WordFactoryOpcode.FROM_SIGNED)
     public static <T extends SignedWord> T signed(int val) {
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/package-info.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.word/src/jdk/internal/vm/compiler/word/package-info.java	Mon Jul 01 14:57:02 2019 -0700
@@ -29,7 +29,7 @@
  * This package provides a low-level mechanism to use machine-word-sized values in Java. The package
  * can only be used in the context of native images or Graal snippets.
  *
- * @since 1.0
+ * @since 19.0
  */
 
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.directives.test/src/org/graalvm/compiler/api/directives/test/BlackholeDirectiveTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.directives.test/src/org/graalvm/compiler/api/directives/test/BlackholeDirectiveTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -139,7 +139,7 @@
     }
 
     @Override
-    protected boolean checkLowTierGraph(StructuredGraph graph) {
+    protected void checkLowTierGraph(StructuredGraph graph) {
         BlackholeSnippet snippet = graph.method().getAnnotation(BlackholeSnippet.class);
         ParameterNode arg = graph.getParameter(0);
         if (snippet.expectParameterUsage()) {
@@ -148,6 +148,5 @@
         } else {
             Assert.assertTrue("expected no usages of ParameterNode", arg == null || arg.hasNoUsages());
         }
-        return true;
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.directives.test/src/org/graalvm/compiler/api/directives/test/ControlFlowAnchorDirectiveTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.directives.test/src/org/graalvm/compiler/api/directives/test/ControlFlowAnchorDirectiveTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -249,7 +249,7 @@
     }
 
     @Override
-    protected boolean checkLowTierGraph(StructuredGraph graph) {
+    protected void checkLowTierGraph(StructuredGraph graph) {
         List<ControlFlowAnchorNode> anchors = graph.getNodes().filter(ControlFlowAnchorNode.class).snapshot();
         for (int i = 0; i < anchors.size(); i++) {
             ControlFlowAnchorNode a = anchors.get(i);
@@ -265,6 +265,5 @@
             NodeIterable<? extends Node> nodes = graph.getNodes().filter(nodeCount.nodeClass());
             Assert.assertEquals(nodeCount.nodeClass().getSimpleName(), nodeCount.expectedCount(), nodes.count());
         }
-        return true;
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.directives.test/src/org/graalvm/compiler/api/directives/test/IterationDirectiveTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.directives.test/src/org/graalvm/compiler/api/directives/test/IterationDirectiveTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -54,13 +54,11 @@
     }
 
     @Override
-    protected boolean checkLowTierGraph(StructuredGraph graph) {
+    protected void checkLowTierGraph(StructuredGraph graph) {
         NodeIterable<LoopBeginNode> loopBeginNodes = graph.getNodes(LoopBeginNode.TYPE);
         Assert.assertEquals("LoopBeginNode count", 1, loopBeginNodes.count());
 
         LoopBeginNode loopBeginNode = loopBeginNodes.first();
         Assert.assertEquals("loop frequency of " + loopBeginNode, 128, loopBeginNode.loopFrequency(), 0);
-
-        return true;
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.directives.test/src/org/graalvm/compiler/api/directives/test/OpaqueDirectiveTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.directives.test/src/org/graalvm/compiler/api/directives/test/OpaqueDirectiveTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -138,11 +138,10 @@
     }
 
     @Override
-    protected boolean checkLowTierGraph(StructuredGraph graph) {
+    protected void checkLowTierGraph(StructuredGraph graph) {
         OpaqueSnippet snippet = graph.method().getAnnotation(OpaqueSnippet.class);
         for (ReturnNode returnNode : graph.getNodes(ReturnNode.TYPE)) {
             Assert.assertEquals(snippet.expectedReturnNode(), returnNode.result().getClass());
         }
-        return true;
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.directives.test/src/org/graalvm/compiler/api/directives/test/ProbabilityDirectiveTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.api.directives.test/src/org/graalvm/compiler/api/directives/test/ProbabilityDirectiveTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,6 +24,8 @@
 
 package org.graalvm.compiler.api.directives.test;
 
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+
 import org.graalvm.compiler.api.directives.GraalDirectives;
 import org.graalvm.compiler.core.test.GraalCompilerTest;
 import org.graalvm.compiler.graph.iterators.NodeIterable;
@@ -37,6 +39,15 @@
 
 public class ProbabilityDirectiveTest extends GraalCompilerTest {
 
+    /**
+     * Called before a test is compiled.
+     */
+    @Override
+    protected void before(ResolvedJavaMethod method) {
+        // don't let -Xcomp pollute profile
+        method.reprofile();
+    }
+
     public static int branchProbabilitySnippet(int arg) {
         if (GraalDirectives.injectBranchProbability(0.125, arg > 0)) {
             GraalDirectives.controlFlowAnchor(); // prevent removal of the if
@@ -68,7 +79,7 @@
     }
 
     @Override
-    protected boolean checkLowTierGraph(StructuredGraph graph) {
+    protected void checkLowTierGraph(StructuredGraph graph) {
         NodeIterable<IfNode> ifNodes = graph.getNodes(IfNode.TYPE);
         Assert.assertEquals("IfNode count", 1, ifNodes.count());
 
@@ -81,8 +92,6 @@
             oneSuccessor = ifNode.falseSuccessor();
         }
         Assert.assertEquals("branch probability of " + ifNode, 0.125, ifNode.probability(oneSuccessor), 0);
-
-        return true;
     }
 
     private static int returnValue(AbstractBeginNode b) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64/src/org/graalvm/compiler/asm/aarch64/AArch64Assembler.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64/src/org/graalvm/compiler/asm/aarch64/AArch64Assembler.java	Mon Jul 01 14:57:02 2019 -0700
@@ -2963,17 +2963,17 @@
 
     public void annotatePatchingImmediate(int pos, Instruction instruction, int operandSizeBits, int offsetBits, int shift) {
         if (codePatchingAnnotationConsumer != null) {
-            codePatchingAnnotationConsumer.accept(new OperandDataAnnotation(pos, instruction, operandSizeBits, offsetBits, shift));
+            codePatchingAnnotationConsumer.accept(new SingleInstructionAnnotation(pos, instruction, operandSizeBits, offsetBits, shift));
         }
     }
 
-    void annotatePatchingImmediateNativeAddress(int pos, int operandSizeBits, int numInstrs) {
+    void annotateImmediateMovSequence(int pos, int numInstrs) {
         if (codePatchingAnnotationConsumer != null) {
-            codePatchingAnnotationConsumer.accept(new MovSequenceAnnotation(pos, operandSizeBits, numInstrs));
+            codePatchingAnnotationConsumer.accept(new MovSequenceAnnotation(pos, numInstrs));
         }
     }
 
-    public static class OperandDataAnnotation extends CodeAnnotation {
+    public static class SingleInstructionAnnotation extends CodeAnnotation {
 
         /**
          * The size of the operand, in bytes.
@@ -2983,7 +2983,7 @@
         public final Instruction instruction;
         public final int shift;
 
-        OperandDataAnnotation(int instructionPosition, Instruction instruction, int operandSizeBits, int offsetBits, int shift) {
+        SingleInstructionAnnotation(int instructionPosition, Instruction instruction, int operandSizeBits, int offsetBits, int shift) {
             super(instructionPosition);
             this.operandSizeBits = operandSizeBits;
             this.offsetBits = offsetBits;
@@ -2997,12 +2997,10 @@
         /**
          * The size of the operand, in bytes.
          */
-        public final int operandSizeBits;
         public final int numInstrs;
 
-        MovSequenceAnnotation(int instructionPosition, int operandSizeBits, int numInstrs) {
+        MovSequenceAnnotation(int instructionPosition, int numInstrs) {
             super(instructionPosition);
-            this.operandSizeBits = operandSizeBits;
             this.numInstrs = numInstrs;
         }
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64/src/org/graalvm/compiler/asm/aarch64/AArch64MacroAssembler.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64/src/org/graalvm/compiler/asm/aarch64/AArch64MacroAssembler.java	Mon Jul 01 14:57:02 2019 -0700
@@ -339,10 +339,13 @@
      * Generates a 64-bit immediate move code sequence.
      *
      * @param dst general purpose register. May not be null, stackpointer or zero-register.
-     * @param imm
+     * @param imm the value to move into the register
+     * @param annotateImm Flag denoting if annotation should be added.
      */
-    private void mov64(Register dst, long imm) {
+    private void mov64(Register dst, long imm, boolean annotateImm) {
         // We have to move all non zero parts of the immediate in 16-bit chunks
+        int numMovs = 0;
+        int pos = position();
         boolean firstMove = true;
         for (int offset = 0; offset < 64; offset += 16) {
             int chunk = (int) (imm >> offset) & NumUtil.getNbitNumberInt(16);
@@ -355,8 +358,12 @@
             } else {
                 movk(64, dst, chunk, offset);
             }
+            ++numMovs;
         }
         assert !firstMove;
+        if (annotateImm) {
+            annotateImmediateMovSequence(pos, numMovs);
+        }
     }
 
     /**
@@ -378,7 +385,6 @@
      */
     public void mov(Register dst, long imm, boolean annotateImm) {
         assert dst.getRegisterCategory().equals(CPU);
-        int pos = position();
         if (imm == 0L) {
             movx(dst, zr);
         } else if (LogicalImmediateTable.isRepresentable(true, imm) != LogicalImmediateTable.Representable.NO) {
@@ -391,10 +397,7 @@
             mov(dst, (int) imm);
             sxt(64, 32, dst, dst);
         } else {
-            mov64(dst, imm);
-            if (annotateImm) {
-                annotatePatchingImmediateNativeAddress(pos, 64, 4);
-            }
+            mov64(dst, imm, annotateImm);
         }
     }
 
@@ -448,7 +451,7 @@
             }
         }
         if (annotateImm) {
-            annotatePatchingImmediateNativeAddress(pos, 48, 3);
+            annotateImmediateMovSequence(pos, 3);
         }
         assert !firstMove;
     }
@@ -1805,24 +1808,24 @@
     }
 
     /**
-     * Emits elf patchable adrp add sequence.
+     * Emits elf patchable adrp ldr sequence.
      */
-    public void adrAddRel(int srcSize, Register result, AArch64Address a) {
+    public void adrpLdr(int srcSize, Register result, AArch64Address a) {
         if (codePatchingAnnotationConsumer != null) {
-            codePatchingAnnotationConsumer.accept(new ADRADDPRELMacroInstruction(position()));
+            codePatchingAnnotationConsumer.accept(new AdrpLdrMacroInstruction(position()));
         }
         super.adrp(a.getBase());
         this.ldr(srcSize, result, a);
     }
 
-    public static class ADRADDPRELMacroInstruction extends CodeAnnotation implements MacroInstruction {
-        public ADRADDPRELMacroInstruction(int position) {
+    public static class AdrpLdrMacroInstruction extends CodeAnnotation implements MacroInstruction {
+        public AdrpLdrMacroInstruction(int position) {
             super(position);
         }
 
         @Override
         public String toString() {
-            return "ADR_PREL_PG";
+            return "ADRP_LDR";
         }
 
         @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64AsmOptions.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64AsmOptions.java	Mon Jul 01 14:57:02 2019 -0700
@@ -27,6 +27,7 @@
 public class AMD64AsmOptions {
     public static final boolean UseNormalNop = false;
     public static final boolean UseAddressNop = true;
+    public static final boolean UseIntelNops = true;
     public static final boolean UseIncDec = true;
     public static final boolean UseXmmLoadAndClearUpper = true;
     public static final boolean UseXmmRegToRegMoveAll = true;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64Assembler.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64Assembler.java	Mon Jul 01 14:57:02 2019 -0700
@@ -29,6 +29,7 @@
 import static jdk.vm.ci.amd64.AMD64.XMM;
 import static jdk.vm.ci.code.MemoryBarriers.STORE_LOAD;
 import static org.graalvm.compiler.asm.amd64.AMD64AsmOptions.UseAddressNop;
+import static org.graalvm.compiler.asm.amd64.AMD64AsmOptions.UseIntelNops;
 import static org.graalvm.compiler.asm.amd64.AMD64AsmOptions.UseNormalNop;
 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.ADD;
 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.AND;
@@ -2295,125 +2296,10 @@
         }
 
         if (UseAddressNop) {
-            //
-            // Using multi-bytes nops "0x0F 0x1F [Address]" for AMD.
-            // 1: 0x90
-            // 2: 0x66 0x90
-            // 3: 0x66 0x66 0x90 (don't use "0x0F 0x1F 0x00" - need patching safe padding)
-            // 4: 0x0F 0x1F 0x40 0x00
-            // 5: 0x0F 0x1F 0x44 0x00 0x00
-            // 6: 0x66 0x0F 0x1F 0x44 0x00 0x00
-            // 7: 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00
-            // 8: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
-            // 9: 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
-            // 10: 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
-            // 11: 0x66 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
-
-            // The rest coding is AMD specific - use consecutive Address nops
-
-            // 12: 0x66 0x0F 0x1F 0x44 0x00 0x00 0x66 0x0F 0x1F 0x44 0x00 0x00
-            // 13: 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00 0x66 0x0F 0x1F 0x44 0x00 0x00
-            // 14: 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00
-            // 15: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00
-            // 16: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
-            // Size prefixes (0x66) are added for larger sizes
-
-            while (i >= 22) {
-                i -= 11;
-                emitByte(0x66); // size prefix
-                emitByte(0x66); // size prefix
-                emitByte(0x66); // size prefix
-                addrNop8();
-            }
-            // Generate first nop for size between 21-12
-            switch (i) {
-                case 21:
-                    i -= 11;
-                    emitByte(0x66); // size prefix
-                    emitByte(0x66); // size prefix
-                    emitByte(0x66); // size prefix
-                    addrNop8();
-                    break;
-                case 20:
-                case 19:
-                    i -= 10;
-                    emitByte(0x66); // size prefix
-                    emitByte(0x66); // size prefix
-                    addrNop8();
-                    break;
-                case 18:
-                case 17:
-                    i -= 9;
-                    emitByte(0x66); // size prefix
-                    addrNop8();
-                    break;
-                case 16:
-                case 15:
-                    i -= 8;
-                    addrNop8();
-                    break;
-                case 14:
-                case 13:
-                    i -= 7;
-                    addrNop7();
-                    break;
-                case 12:
-                    i -= 6;
-                    emitByte(0x66); // size prefix
-                    addrNop5();
-                    break;
-                default:
-                    assert i < 12;
-            }
-
-            // Generate second nop for size between 11-1
-            switch (i) {
-                case 11:
-                    emitByte(0x66); // size prefix
-                    emitByte(0x66); // size prefix
-                    emitByte(0x66); // size prefix
-                    addrNop8();
-                    break;
-                case 10:
-                    emitByte(0x66); // size prefix
-                    emitByte(0x66); // size prefix
-                    addrNop8();
-                    break;
-                case 9:
-                    emitByte(0x66); // size prefix
-                    addrNop8();
-                    break;
-                case 8:
-                    addrNop8();
-                    break;
-                case 7:
-                    addrNop7();
-                    break;
-                case 6:
-                    emitByte(0x66); // size prefix
-                    addrNop5();
-                    break;
-                case 5:
-                    addrNop5();
-                    break;
-                case 4:
-                    addrNop4();
-                    break;
-                case 3:
-                    // Don't use "0x0F 0x1F 0x00" - need patching safe padding
-                    emitByte(0x66); // size prefix
-                    emitByte(0x66); // size prefix
-                    emitByte(0x90); // nop
-                    break;
-                case 2:
-                    emitByte(0x66); // size prefix
-                    emitByte(0x90); // nop
-                    break;
-                case 1:
-                    emitByte(0x90); // nop
-                    break;
-                default:
-                    assert i == 0;
+            if (UseIntelNops) {
+                intelNops(i);
+            } else {
+                amdNops(i);
             }
             return;
         }
@@ -2484,6 +2370,222 @@
         }
     }
 
+    private void amdNops(int count) {
+        int i = count;
+        //
+        // Using multi-bytes nops "0x0F 0x1F [Address]" for AMD.
+        // 1: 0x90
+        // 2: 0x66 0x90
+        // 3: 0x66 0x66 0x90 (don't use "0x0F 0x1F 0x00" - need patching safe padding)
+        // 4: 0x0F 0x1F 0x40 0x00
+        // 5: 0x0F 0x1F 0x44 0x00 0x00
+        // 6: 0x66 0x0F 0x1F 0x44 0x00 0x00
+        // 7: 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00
+        // 8: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
+        // 9: 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
+        // 10: 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
+        // 11: 0x66 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
+
+        // The rest coding is AMD specific - use consecutive Address nops
+
+        // 12: 0x66 0x0F 0x1F 0x44 0x00 0x00 0x66 0x0F 0x1F 0x44 0x00 0x00
+        // 13: 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00 0x66 0x0F 0x1F 0x44 0x00 0x00
+        // 14: 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00
+        // 15: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00
+        // 16: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
+        // Size prefixes (0x66) are added for larger sizes
+
+        while (i >= 22) {
+            i -= 11;
+            emitByte(0x66); // size prefix
+            emitByte(0x66); // size prefix
+            emitByte(0x66); // size prefix
+            addrNop8();
+        }
+        // Generate first nop for size between 21-12
+        switch (i) {
+            case 21:
+                i -= 11;
+                emitByte(0x66); // size prefix
+                emitByte(0x66); // size prefix
+                emitByte(0x66); // size prefix
+                addrNop8();
+                break;
+            case 20:
+            case 19:
+                i -= 10;
+                emitByte(0x66); // size prefix
+                emitByte(0x66); // size prefix
+                addrNop8();
+                break;
+            case 18:
+            case 17:
+                i -= 9;
+                emitByte(0x66); // size prefix
+                addrNop8();
+                break;
+            case 16:
+            case 15:
+                i -= 8;
+                addrNop8();
+                break;
+            case 14:
+            case 13:
+                i -= 7;
+                addrNop7();
+                break;
+            case 12:
+                i -= 6;
+                emitByte(0x66); // size prefix
+                addrNop5();
+                break;
+            default:
+                assert i < 12;
+        }
+
+        // Generate second nop for size between 11-1
+        switch (i) {
+            case 11:
+                emitByte(0x66); // size prefix
+                emitByte(0x66); // size prefix
+                emitByte(0x66); // size prefix
+                addrNop8();
+                break;
+            case 10:
+                emitByte(0x66); // size prefix
+                emitByte(0x66); // size prefix
+                addrNop8();
+                break;
+            case 9:
+                emitByte(0x66); // size prefix
+                addrNop8();
+                break;
+            case 8:
+                addrNop8();
+                break;
+            case 7:
+                addrNop7();
+                break;
+            case 6:
+                emitByte(0x66); // size prefix
+                addrNop5();
+                break;
+            case 5:
+                addrNop5();
+                break;
+            case 4:
+                addrNop4();
+                break;
+            case 3:
+                // Don't use "0x0F 0x1F 0x00" - need patching safe padding
+                emitByte(0x66); // size prefix
+                emitByte(0x66); // size prefix
+                emitByte(0x90); // nop
+                break;
+            case 2:
+                emitByte(0x66); // size prefix
+                emitByte(0x90); // nop
+                break;
+            case 1:
+                emitByte(0x90); // nop
+                break;
+            default:
+                assert i == 0;
+        }
+    }
+
+    @SuppressWarnings("fallthrough")
+    private void intelNops(int count) {
+        //
+        // Using multi-bytes nops "0x0F 0x1F [address]" for Intel
+        // 1: 0x90
+        // 2: 0x66 0x90
+        // 3: 0x66 0x66 0x90 (don't use "0x0F 0x1F 0x00" - need patching safe padding)
+        // 4: 0x0F 0x1F 0x40 0x00
+        // 5: 0x0F 0x1F 0x44 0x00 0x00
+        // 6: 0x66 0x0F 0x1F 0x44 0x00 0x00
+        // 7: 0x0F 0x1F 0x80 0x00 0x00 0x00 0x00
+        // 8: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
+        // 9: 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
+        // 10: 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
+        // 11: 0x66 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00
+
+        // The rest coding is Intel specific - don't use consecutive address nops
+
+        // 12: 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x66 0x66 0x66 0x90
+        // 13: 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x66 0x66 0x66 0x90
+        // 14: 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x66 0x66 0x66 0x90
+        // 15: 0x66 0x66 0x66 0x0F 0x1F 0x84 0x00 0x00 0x00 0x00 0x00 0x66 0x66 0x66 0x90
+
+        int i = count;
+        while (i >= 15) {
+            // For Intel don't generate consecutive addess nops (mix with regular nops)
+            i -= 15;
+            emitByte(0x66);   // size prefix
+            emitByte(0x66);   // size prefix
+            emitByte(0x66);   // size prefix
+            addrNop8();
+            emitByte(0x66);   // size prefix
+            emitByte(0x66);   // size prefix
+            emitByte(0x66);   // size prefix
+            emitByte(0x90);
+            // nop
+        }
+        switch (i) {
+            case 14:
+                emitByte(0x66); // size prefix
+                // fall through
+            case 13:
+                emitByte(0x66); // size prefix
+                // fall through
+            case 12:
+                addrNop8();
+                emitByte(0x66); // size prefix
+                emitByte(0x66); // size prefix
+                emitByte(0x66); // size prefix
+                emitByte(0x90);
+                // nop
+                break;
+            case 11:
+                emitByte(0x66); // size prefix
+                // fall through
+            case 10:
+                emitByte(0x66); // size prefix
+                // fall through
+            case 9:
+                emitByte(0x66); // size prefix
+                // fall through
+            case 8:
+                addrNop8();
+                break;
+            case 7:
+                addrNop7();
+                break;
+            case 6:
+                emitByte(0x66); // size prefix
+                // fall through
+            case 5:
+                addrNop5();
+                break;
+            case 4:
+                addrNop4();
+                break;
+            case 3:
+                // Don't use "0x0F 0x1F 0x00" - need patching safe padding
+                emitByte(0x66); // size prefix
+                // fall through
+            case 2:
+                emitByte(0x66); // size prefix
+                // fall through
+            case 1:
+                emitByte(0x90);
+                // nop
+                break;
+            default:
+                assert i == 0;
+        }
+    }
+
     public final void orl(Register dst, Register src) {
         OR.rmOp.emit(this, DWORD, dst, src);
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm/src/org/graalvm/compiler/asm/Assembler.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm/src/org/graalvm/compiler/asm/Assembler.java	Mon Jul 01 14:57:02 2019 -0700
@@ -30,6 +30,8 @@
 import java.util.Map;
 import java.util.function.Consumer;
 
+import org.graalvm.compiler.debug.GraalError;
+
 import jdk.vm.ci.code.Register;
 import jdk.vm.ci.code.StackSlot;
 import jdk.vm.ci.code.TargetDescription;
@@ -164,7 +166,7 @@
         Label label = labelsWithPatches;
         while (label != null) {
             if (label.patchPositions != null) {
-                throw new InternalError("Label used by instructions at following offsets has not been bound: " + label.patchPositions);
+                throw new GraalError("Label used by instructions at following offsets has not been bound: %s", label.patchPositions);
             }
             Label next = label.nextWithPatches;
             label.nextWithPatches = null;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm/src/org/graalvm/compiler/asm/Buffer.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm/src/org/graalvm/compiler/asm/Buffer.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,12 +24,13 @@
 
 package org.graalvm.compiler.asm;
 
-import org.graalvm.compiler.core.common.NumUtil;
-
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.util.Arrays;
 
+import org.graalvm.compiler.core.common.NumUtil;
+import org.graalvm.compiler.serviceprovider.BufferUtil;
+
 /**
  * Code buffer management for the assembler.
  */
@@ -48,7 +49,7 @@
 
     public void setPosition(int position) {
         assert position >= 0 && position <= data.limit();
-        data.position(position);
+        BufferUtil.asBaseBuffer(data).position(position);
     }
 
     /**
@@ -93,7 +94,7 @@
             byte[] newBuf = Arrays.copyOf(data.array(), length * 4);
             ByteBuffer newData = ByteBuffer.wrap(newBuf);
             newData.order(data.order());
-            newData.position(data.position());
+            BufferUtil.asBaseBuffer(newData).position(data.position());
             data = newData;
         }
     }
@@ -170,6 +171,6 @@
     }
 
     public void reset() {
-        data.clear();
+        BufferUtil.asBaseBuffer(data).clear();
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm/src/org/graalvm/compiler/asm/Label.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm/src/org/graalvm/compiler/asm/Label.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,6 +26,8 @@
 
 import java.util.ArrayList;
 
+import org.graalvm.compiler.debug.GraalError;
+
 /**
  * This class represents a label within assembly code.
  */
@@ -71,7 +73,9 @@
      * {@link #addPatchAt(int, Assembler)}.
      */
     protected void bind(int pos, Assembler asm) {
-        assert pos >= 0;
+        if (pos < 0) {
+            throw new GraalError("Cannot bind label to negative position %d", pos);
+        }
         this.position = pos;
         if (patchPositions != null) {
             for (int i = 0; i < patchPositions.size(); ++i) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.code/src/org/graalvm/compiler/code/DataSection.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.code/src/org/graalvm/compiler/code/DataSection.java	Mon Jul 01 14:57:02 2019 -0700
@@ -33,6 +33,7 @@
 import java.util.function.BiConsumer;
 
 import org.graalvm.compiler.code.DataSection.Data;
+import org.graalvm.compiler.serviceprovider.BufferUtil;
 
 import jdk.vm.ci.code.site.DataSectionReference;
 import jdk.vm.ci.meta.SerializableConstant;
@@ -376,11 +377,11 @@
         assert buffer.remaining() >= sectionSize;
         int start = buffer.position();
         for (Data d : dataItems) {
-            buffer.position(start + d.ref.getOffset());
+            BufferUtil.asBaseBuffer(buffer).position(start + d.ref.getOffset());
             onEmit.accept(d.ref, d.getSize());
             d.emit(buffer, patch);
         }
-        buffer.position(start + sectionSize);
+        BufferUtil.asBaseBuffer(buffer).position(start + sectionSize);
     }
 
     public Data findData(DataSectionReference ref) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64.test/src/org/graalvm/compiler/core/aarch64/test/AArch64BitFieldTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, Arm Limited and affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+
+package org.graalvm.compiler.core.aarch64.test;
+
+import org.graalvm.compiler.lir.LIRInstruction;
+import org.graalvm.compiler.lir.aarch64.AArch64BitFieldOp;
+import org.junit.Test;
+
+import java.util.function.Predicate;
+
+public class AArch64BitFieldTest extends AArch64MatchRuleTest {
+    private static final Predicate<LIRInstruction> predicate = op -> (op instanceof AArch64BitFieldOp);
+
+    private void testAndCheckLIR(String method, String negativeMethod, Object input) {
+        test(method, input);
+        checkLIR(method, predicate, 1);
+        test(negativeMethod, input);
+        checkLIR(negativeMethod, predicate, 0);
+    }
+
+    /**
+     * unsigned bit field extract int.
+     */
+    public static int extractInt(int input) {
+        return (input >>> 6) & 0xffff;
+    }
+
+    /**
+     * unsigned bit field extract int (negative cases).
+     */
+    public static int invalidExtractInt(int input) {
+        int result = 0;
+        result += ((input >>> 10) & 0xfff0);    // Invalid mask
+        result += ((input >>> 2) & 0x7fffffff); // Bit field width too large
+        result += ((input >>> 16) & 0x1ffff);   // Width + lsb exceeds limit
+        return result;
+    }
+
+    @Test
+    public void testExtractInt() {
+        testAndCheckLIR("extractInt", "invalidExtractInt", 0x12345678);
+    }
+
+    /**
+     * unsigned bit field extract long.
+     */
+    public static long extractLong(long input) {
+        return (input >>> 25) & 0xffffffffL;
+    }
+
+    /**
+     * unsigned bit field extract long (negative cases).
+     */
+    public static long invalidExtractLong(long input) {
+        long result = 0L;
+        result += ((input >>> 10) & 0x230L);                // Invalid mask
+        result += ((input >>> 2) & 0x7fffffffffffffffL);    // Bit field width too large
+        result += ((input >>> 62) & 0x7L);                  // Width + lsb exceeds limit
+        return result;
+    }
+
+    @Test
+    public void testExtractLong() {
+        testAndCheckLIR("extractLong", "invalidExtractLong", 0xfedcba9876543210L);
+    }
+
+    /**
+     * unsigned bit field insert int.
+     */
+    public static int insertInt(int input) {
+        return (input & 0xfff) << 10;
+    }
+
+    /**
+     * unsigned bit field insert int (negative cases).
+     */
+    public static int invalidInsertInt(int input) {
+        int result = 0;
+        result += ((input & 0xe) << 25);        // Invalid mask
+        result += ((input & 0x7fffffff) << 1);  // Bit field width too large
+        result += ((input & 0x1ffff) << 16);    // Width + lsb exceeds limit
+        return result;
+    }
+
+    @Test
+    public void testInsertInt() {
+        testAndCheckLIR("insertInt", "invalidInsertInt", 0xcafebabe);
+    }
+
+    /**
+     * unsigned bit field insert long.
+     */
+    public static long insertLong(long input) {
+        return (input & 0x3fffffffffffL) << 7;
+    }
+
+    /**
+     * unsigned bit field insert long (negative cases).
+     */
+    public static long invalidInsertLong(long input) {
+        long result = 0L;
+        result += ((input & 0x1a) << 39);                   // Invalid mask
+        result += ((input & 0x7fffffffffffffffL) << 1);     // Bit field width too large
+        result += ((input & 0x3fffffff) << 52);             // Width + lsb exceeds limit
+        return result;
+    }
+
+    @Test
+    public void testInsertLong() {
+        testAndCheckLIR("insertLong", "invalidInsertLong", 0xdeadbeefdeadbeefL);
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64NodeMatchRules.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64NodeMatchRules.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,6 +26,7 @@
 package org.graalvm.compiler.core.aarch64;
 
 import jdk.vm.ci.aarch64.AArch64Kind;
+import jdk.vm.ci.code.CodeUtil;
 import jdk.vm.ci.meta.AllocatableValue;
 import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.Value;
@@ -42,6 +43,7 @@
 import org.graalvm.compiler.lir.LabelRef;
 import org.graalvm.compiler.lir.Variable;
 import org.graalvm.compiler.lir.aarch64.AArch64ArithmeticOp;
+import org.graalvm.compiler.lir.aarch64.AArch64BitFieldOp;
 import org.graalvm.compiler.lir.aarch64.AArch64ControlFlow;
 import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
 import org.graalvm.compiler.nodes.ConstantNode;
@@ -65,7 +67,7 @@
 
 public class AArch64NodeMatchRules extends NodeMatchRules {
     private static final EconomicMap<Class<? extends Node>, AArch64ArithmeticOp> nodeOpMap;
-
+    private static final EconomicMap<Class<? extends BinaryNode>, AArch64BitFieldOp.BitFieldOpCode> bitFieldOpMap;
     private static final EconomicMap<Class<? extends BinaryNode>, AArch64MacroAssembler.ShiftType> shiftTypeMap;
 
     static {
@@ -76,6 +78,10 @@
         nodeOpMap.put(OrNode.class, AArch64ArithmeticOp.OR);
         nodeOpMap.put(XorNode.class, AArch64ArithmeticOp.XOR);
 
+        bitFieldOpMap = EconomicMap.create(Equivalence.IDENTITY, 2);
+        bitFieldOpMap.put(UnsignedRightShiftNode.class, AArch64BitFieldOp.BitFieldOpCode.UBFX);
+        bitFieldOpMap.put(LeftShiftNode.class, AArch64BitFieldOp.BitFieldOpCode.UBFIZ);
+
         shiftTypeMap = EconomicMap.create(Equivalence.IDENTITY, 3);
         shiftTypeMap.put(LeftShiftNode.class, AArch64MacroAssembler.ShiftType.LSL);
         shiftTypeMap.put(RightShiftNode.class, AArch64MacroAssembler.ShiftType.ASR);
@@ -101,6 +107,19 @@
         return getLIRGeneratorTool().moveSp(value);
     }
 
+    private ComplexMatchResult emitBitField(AArch64BitFieldOp.BitFieldOpCode op, ValueNode value, int lsb, int width) {
+        assert op != null;
+        assert value.getStackKind().isNumericInteger();
+
+        return builder -> {
+            Value a = operand(value);
+            Variable result = gen.newVariable(LIRKind.combine(a));
+            AllocatableValue src = moveSp(gen.asAllocatable(a));
+            gen.append(new AArch64BitFieldOp(op, result, src, lsb, width));
+            return result;
+        };
+    }
+
     private ComplexMatchResult emitBinaryShift(AArch64ArithmeticOp op, ValueNode value, BinaryNode shift,
                     boolean isShiftNot) {
         AArch64MacroAssembler.ShiftType shiftType = shiftTypeMap.get(shift.getClass());
@@ -133,6 +152,40 @@
         };
     }
 
+    @MatchRule("(And (UnsignedRightShift=shift a Constant=b) Constant=c)")
+    @MatchRule("(LeftShift=shift (And a Constant=c) Constant=b)")
+    public ComplexMatchResult unsignedBitField(BinaryNode shift, ValueNode a, ConstantNode b, ConstantNode c) {
+        JavaKind srcKind = a.getStackKind();
+        assert srcKind.isNumericInteger();
+        AArch64BitFieldOp.BitFieldOpCode op = bitFieldOpMap.get(shift.getClass());
+        assert op != null;
+        int distance = b.asJavaConstant().asInt();
+        long mask = c.asJavaConstant().asLong();
+
+        // The Java(R) Language Specification CHAPTER 15.19 Shift Operators says:
+        // "If the promoted type of the left-hand operand is int(long), then only the five(six)
+        // lowest-order bits of the right-hand operand are used as the shift distance."
+        distance = distance & (srcKind == JavaKind.Int ? 0x1f : 0x3f);
+
+        // Constraint 1: Mask plus one should be a power-of-2 integer.
+        if (!CodeUtil.isPowerOf2(mask + 1)) {
+            return null;
+        }
+        int width = CodeUtil.log2(mask + 1);
+        int srcBits = srcKind.getBitCount();
+        // Constraint 2: Bit field width is less than 31(63) for int(long) as any bit field move
+        // operations can be done by a single shift instruction if the width is 31(63).
+        if (width >= srcBits - 1) {
+            return null;
+        }
+        // Constraint 3: Sum of bit field width and the shift distance is less or equal to 32(64)
+        // for int(long) as the specification of AArch64 bit field instructions.
+        if (width + distance > srcBits) {
+            return null;
+        }
+        return emitBitField(op, a, distance, width);
+    }
+
     @MatchRule("(Add=binary a (LeftShift=shift b Constant))")
     @MatchRule("(Add=binary a (RightShift=shift b Constant))")
     @MatchRule("(Add=binary a (UnsignedRightShift=shift b Constant))")
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64ArithmeticLIRGenerator.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64ArithmeticLIRGenerator.java	Mon Jul 01 14:57:02 2019 -0700
@@ -450,6 +450,13 @@
         }
     }
 
+    public Value emitBinaryMemory(VexRVMOp op, OperandSize size, AllocatableValue a, AMD64AddressValue location, LIRFrameState state) {
+        assert (size.isXmmType() && supportAVX());
+        Variable result = getLIRGen().newVariable(LIRKind.combine(a));
+        getLIRGen().append(new AMD64VectorBinary.AVXBinaryMemoryOp(op, getRegisterSize(result), result, a, location, state));
+        return result;
+    }
+
     public Value emitBinaryMemory(AMD64RMOp op, OperandSize size, AllocatableValue a, AMD64AddressValue location, LIRFrameState state) {
         Variable result = getLIRGen().newVariable(LIRKind.combine(a));
         getLIRGen().append(new AMD64Binary.MemoryTwoOp(op, size, result, a, location, state));
@@ -1339,7 +1346,7 @@
         return result;
     }
 
-    private boolean supportAVX() {
+    public boolean supportAVX() {
         TargetDescription target = getLIRGen().target();
         return ((AMD64) target.arch).getFeatures().contains(CPUFeature.AVX);
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64LIRGenerator.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64LIRGenerator.java	Mon Jul 01 14:57:02 2019 -0700
@@ -576,13 +576,10 @@
     }
 
     @Override
-    public Variable emitArrayIndexOf(JavaKind kind, boolean findTwoConsecutive, Value arrayPointer, Value arrayLength, Value... searchValues) {
-        Variable result = newVariable(LIRKind.value(AMD64Kind.QWORD));
-        Value[] allocatableSearchValues = new Value[searchValues.length];
-        for (int i = 0; i < searchValues.length; i++) {
-            allocatableSearchValues[i] = asAllocatable(searchValues[i]);
-        }
-        append(new AMD64ArrayIndexOfOp(kind, findTwoConsecutive, getVMPageSize(), getMaxVectorSize(), this, result, asAllocatable(arrayPointer), asAllocatable(arrayLength), allocatableSearchValues));
+    public Variable emitArrayIndexOf(JavaKind arrayKind, JavaKind valueKind, boolean findTwoConsecutive, Value arrayPointer, Value arrayLength, Value fromIndex, Value... searchValues) {
+        Variable result = newVariable(LIRKind.value(AMD64Kind.DWORD));
+        append(new AMD64ArrayIndexOfOp(arrayKind, valueKind, findTwoConsecutive, getMaxVectorSize(), this, result,
+                        asAllocatable(arrayPointer), asAllocatable(arrayLength), asAllocatable(fromIndex), searchValues));
         return result;
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64NodeMatchRules.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64NodeMatchRules.java	Mon Jul 01 14:57:02 2019 -0700
@@ -33,11 +33,18 @@
 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSX;
 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSXB;
 import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp.MOVSXD;
+import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMOp.VADDSD;
+import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMOp.VADDSS;
+import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMOp.VMULSD;
+import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMOp.VMULSS;
+import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMOp.VSUBSD;
+import static org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMOp.VSUBSS;
 import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.DWORD;
 import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.QWORD;
 import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.SD;
 import static org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize.SS;
 
+import org.graalvm.compiler.asm.amd64.AMD64Assembler;
 import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64MIOp;
 import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp;
 import org.graalvm.compiler.asm.amd64.AMD64Assembler.SSEOp;
@@ -380,7 +387,7 @@
     @MatchRule("(If (IntegerEquals=compare value ValueCompareAndSwap=cas))")
     public ComplexMatchResult ifCompareValueCas(IfNode root, CompareNode compare, ValueNode value, ValueCompareAndSwapNode cas) {
         assert compare.condition() == CanonicalCondition.EQ;
-        if (value == cas.getExpectedValue() && cas.usages().count() == 1) {
+        if (value == cas.getExpectedValue() && cas.hasExactlyOneUsage()) {
             return builder -> {
                 LIRKind kind = getLirKind(cas);
                 LabelRef trueLabel = getLIRBlock(root.trueSuccessor());
@@ -403,7 +410,7 @@
     public ComplexMatchResult ifCompareLogicCas(IfNode root, CompareNode compare, ValueNode value, LogicCompareAndSwapNode cas) {
         JavaConstant constant = value.asJavaConstant();
         assert compare.condition() == CanonicalCondition.EQ;
-        if (constant != null && cas.usages().count() == 1) {
+        if (constant != null && cas.hasExactlyOneUsage()) {
             long constantValue = constant.asLong();
             boolean successIsTrue;
             if (constantValue == 0) {
@@ -463,12 +470,22 @@
                         getState(access));
     }
 
+    private ComplexMatchResult binaryRead(AMD64Assembler.VexRVMOp op, OperandSize size, ValueNode value, LIRLowerableAccess access) {
+        assert size == SS || size == SD;
+        return builder -> getArithmeticLIRGenerator().emitBinaryMemory(op, size, getLIRGeneratorTool().asAllocatable(operand(value)), (AMD64AddressValue) operand(access.getAddress()),
+                        getState(access));
+    }
+
     @MatchRule("(Add value Read=access)")
     @MatchRule("(Add value FloatingRead=access)")
     public ComplexMatchResult addMemory(ValueNode value, LIRLowerableAccess access) {
         OperandSize size = getMemorySize(access);
         if (size.isXmmType()) {
-            return binaryRead(SSEOp.ADD, size, value, access);
+            if (getArithmeticLIRGenerator().supportAVX()) {
+                return binaryRead(size == SS ? VADDSS : VADDSD, size, value, access);
+            } else {
+                return binaryRead(SSEOp.ADD, size, value, access);
+            }
         } else {
             return binaryRead(ADD.getRMOpcode(size), size, value, access);
         }
@@ -479,7 +496,11 @@
     public ComplexMatchResult subMemory(ValueNode value, LIRLowerableAccess access) {
         OperandSize size = getMemorySize(access);
         if (size.isXmmType()) {
-            return binaryRead(SSEOp.SUB, size, value, access);
+            if (getArithmeticLIRGenerator().supportAVX()) {
+                return binaryRead(size == SS ? VSUBSS : VSUBSD, size, value, access);
+            } else {
+                return binaryRead(SSEOp.SUB, size, value, access);
+            }
         } else {
             return binaryRead(SUB.getRMOpcode(size), size, value, access);
         }
@@ -490,7 +511,11 @@
     public ComplexMatchResult mulMemory(ValueNode value, LIRLowerableAccess access) {
         OperandSize size = getMemorySize(access);
         if (size.isXmmType()) {
-            return binaryRead(SSEOp.MUL, size, value, access);
+            if (getArithmeticLIRGenerator().supportAVX()) {
+                return binaryRead(size == SS ? VMULSS : VMULSD, size, value, access);
+            } else {
+                return binaryRead(SSEOp.MUL, size, value, access);
+            }
         } else {
             return binaryRead(AMD64RMOp.IMUL, size, value, access);
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/GraalOptions.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/GraalOptions.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,10 +26,11 @@
 
 import org.graalvm.compiler.options.Option;
 import org.graalvm.compiler.options.OptionKey;
+import org.graalvm.compiler.options.OptionStability;
 import org.graalvm.compiler.options.OptionType;
 
 /**
- * This class encapsulates options that control the behavior of the Graal compiler.
+ * This class encapsulates options that control the behavior of the GraalVM compiler.
  */
 // @formatter:off
 public final class GraalOptions {
@@ -167,6 +168,9 @@
     public static final OptionKey<Boolean> ConditionalElimination = new OptionKey<>(true);
 
     @Option(help = "", type = OptionType.Debug)
+    public static final OptionKey<Integer> ConditionalEliminationMaxIterations = new OptionKey<>(4);
+
+    @Option(help = "", type = OptionType.Debug)
     public static final OptionKey<Boolean> RawConditionalElimination = new OptionKey<>(true);
 
     @Option(help = "", type = OptionType.Debug)
@@ -238,9 +242,6 @@
     public static final OptionKey<Boolean> OptImplicitNullChecks = new OptionKey<>(true);
 
     @Option(help = "", type = OptionType.Debug)
-    public static final OptionKey<Boolean> OptClearNonLiveLocals = new OptionKey<>(true);
-
-    @Option(help = "", type = OptionType.Debug)
     public static final OptionKey<Boolean> OptLoopTransform = new OptionKey<>(true);
 
     @Option(help = "", type = OptionType.Debug)
@@ -273,7 +274,7 @@
     @Option(help = "Use a cache for snippet graphs.", type = OptionType.Debug)
     public static final OptionKey<Boolean> UseSnippetGraphCache = new OptionKey<>(true);
 
-    @Option(help = "file:doc-files/TraceInliningHelp.txt", type = OptionType.Debug)
+    @Option(help = "file:doc-files/TraceInliningHelp.txt", type = OptionType.Debug, stability = OptionStability.STABLE)
     public static final OptionKey<Boolean> TraceInlining = new OptionKey<>(false);
 
     @Option(help = "Enable inlining decision tracing in stubs and snippets.", type = OptionType.Debug)
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/LIRKind.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/LIRKind.java	Mon Jul 01 14:57:02 2019 -0700
@@ -88,7 +88,7 @@
         this.referenceCompressionMask = referenceCompressionMask;
         this.derivedReferenceBase = derivedReferenceBase;
 
-        assert this.referenceCompressionMask == 0 || this.referenceMask == this.referenceCompressionMask : "mixing compressed and uncompressed references is untested";
+        assert this.referenceCompressionMask == 0 || this.referenceMask == this.referenceCompressionMask : "mixing compressed and uncompressed references is unsupported";
         assert derivedReferenceBase == null || !derivedReferenceBase.getValueKind(LIRKind.class).isDerivedReference() : "derived reference can't have another derived reference as base";
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/SpeculativeExecutionAttacksMitigations.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/SpeculativeExecutionAttacksMitigations.java	Mon Jul 01 14:57:02 2019 -0700
@@ -27,6 +27,7 @@
 import org.graalvm.compiler.options.EnumOptionKey;
 import org.graalvm.compiler.options.Option;
 import org.graalvm.compiler.options.OptionKey;
+import org.graalvm.compiler.options.OptionStability;
 import org.graalvm.compiler.options.OptionType;
 
 public enum SpeculativeExecutionAttacksMitigations {
@@ -39,7 +40,7 @@
         // @formatter:off
         @Option(help = "file:doc-files/MitigateSpeculativeExecutionAttacksHelp.txt")
         public static final EnumOptionKey<SpeculativeExecutionAttacksMitigations> MitigateSpeculativeExecutionAttacks = new EnumOptionKey<>(None);
-        @Option(help = "Use index masking after bounds check to mitigate speculative execution attacks.", type = OptionType.User)
+        @Option(help = "Use index masking after bounds check to mitigate speculative execution attacks.", type = OptionType.User, stability = OptionStability.STABLE)
         public static final OptionKey<Boolean> UseIndexMasking = new OptionKey<>(false);
         // @formatter:on
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/FloatStamp.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/FloatStamp.java	Mon Jul 01 14:57:02 2019 -0700
@@ -150,6 +150,13 @@
     }
 
     /**
+     * Returns true if NaN is included in the value described by this stamp.
+     */
+    public boolean canBeNaN() {
+        return !nonNaN;
+    }
+
+    /**
      * Returns true if this stamp represents the NaN value.
      */
     public boolean isNaN() {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.sparc/src/org/graalvm/compiler/core/sparc/SPARCNodeMatchRules.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.sparc/src/org/graalvm/compiler/core/sparc/SPARCNodeMatchRules.java	Mon Jul 01 14:57:02 2019 -0700
@@ -151,7 +151,7 @@
     public ComplexMatchResult ifCompareLogicCas(IfNode root, CompareNode compare, ValueNode value, LogicCompareAndSwapNode cas) {
         JavaConstant constant = value.asJavaConstant();
         assert compare.condition() == CanonicalCondition.EQ;
-        if (constant != null && cas.usages().count() == 1) {
+        if (constant != null && cas.hasExactlyOneUsage()) {
             long constantValue = constant.asLong();
             boolean successIsTrue;
             if (constantValue == 0) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CanonicalizedConversionTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CanonicalizedConversionTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -41,7 +41,7 @@
 public class CanonicalizedConversionTest extends GraalCompilerTest {
 
     @Override
-    protected boolean checkLowTierGraph(StructuredGraph graph) {
+    protected void checkLowTierGraph(StructuredGraph graph) {
         int reinterpretCount = 0;
         int floatEqualsCount = 0;
         int addCount = 0;
@@ -59,7 +59,6 @@
         Assert.assertEquals(1, reinterpretCount);
         Assert.assertEquals(1, floatEqualsCount);
         Assert.assertEquals(2, addCount);
-        return true;
     }
 
     @Test
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CheckGraalInvariants.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CheckGraalInvariants.java	Mon Jul 01 14:57:02 2019 -0700
@@ -66,6 +66,7 @@
 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration;
 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.phases.OptimisticOptimizations;
 import org.graalvm.compiler.phases.PhaseSuite;
@@ -73,9 +74,9 @@
 import org.graalvm.compiler.phases.VerifyPhase.VerificationError;
 import org.graalvm.compiler.phases.contract.VerifyNodeCosts;
 import org.graalvm.compiler.phases.tiers.HighTierContext;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.graalvm.compiler.phases.util.Providers;
 import org.graalvm.compiler.runtime.RuntimeProvider;
+import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
 import jdk.internal.vm.compiler.word.LocationIdentity;
 import org.junit.Assert;
 import org.junit.Assume;
@@ -127,7 +128,7 @@
 
         protected String getClassPath() {
             String bootclasspath;
-            if (Java8OrEarlier) {
+            if (JavaVersionUtil.JAVA_SPEC <= 8) {
                 bootclasspath = System.getProperty("sun.boot.class.path");
             } else {
                 bootclasspath = System.getProperty("jdk.module.path") + File.pathSeparatorChar + System.getProperty("jdk.module.upgrade.path");
@@ -139,7 +140,7 @@
             if (className.equals("module-info") || className.startsWith("META-INF.versions.")) {
                 return false;
             }
-            if (!Java8OrEarlier) {
+            if (JavaVersionUtil.JAVA_SPEC > 8) {
                 // @formatter:off
                 /*
                  * Work around to prevent:
@@ -247,7 +248,7 @@
 
         List<String> errors = Collections.synchronizedList(new ArrayList<>());
 
-        List<VerifyPhase<PhaseContext>> verifiers = new ArrayList<>();
+        List<VerifyPhase<CoreProviders>> verifiers = new ArrayList<>();
 
         // If you add a new type to test here, be sure to add appropriate
         // methods to the BadUsageWithEquals class below
@@ -270,6 +271,7 @@
         verifiers.add(new VerifySystemPropertyUsage());
         verifiers.add(new VerifyInstanceOfUsage());
         verifiers.add(new VerifyGraphAddUsage());
+        verifiers.add(new VerifyBufferUsage());
         verifiers.add(new VerifyGetOptionsUsage());
         verifiers.add(new VerifyUnsafeAccess());
 
@@ -413,14 +415,14 @@
      * @param metaAccess
      * @param verifiers
      */
-    private static void checkClass(Class<?> c, MetaAccessProvider metaAccess, List<VerifyPhase<PhaseContext>> verifiers) {
+    private static void checkClass(Class<?> c, MetaAccessProvider metaAccess, List<VerifyPhase<CoreProviders>> verifiers) {
         if (Node.class.isAssignableFrom(c)) {
             if (c.getAnnotation(NodeInfo.class) == null) {
                 throw new AssertionError(String.format("Node subclass %s requires %s annotation", c.getName(), NodeClass.class.getSimpleName()));
             }
             VerifyNodeCosts.verifyNodeClass(c);
         }
-        for (VerifyPhase<PhaseContext> verifier : verifiers) {
+        for (VerifyPhase<CoreProviders> verifier : verifiers) {
             verifier.verifyClass(c, metaAccess);
         }
     }
@@ -445,8 +447,8 @@
     /**
      * Checks the invariants for a single graph.
      */
-    private static void checkGraph(List<VerifyPhase<PhaseContext>> verifiers, HighTierContext context, StructuredGraph graph) {
-        for (VerifyPhase<PhaseContext> verifier : verifiers) {
+    private static void checkGraph(List<VerifyPhase<CoreProviders>> verifiers, HighTierContext context, StructuredGraph graph) {
+        for (VerifyPhase<CoreProviders> verifier : verifiers) {
             if (!(verifier instanceof VerifyUsageWithEquals) || shouldVerifyEquals(graph.method())) {
                 verifier.apply(graph, context);
             } else {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CompareCanonicalizerTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CompareCanonicalizerTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,8 +24,6 @@
 
 package org.graalvm.compiler.core.test;
 
-import org.junit.Test;
-
 import org.graalvm.compiler.nodes.ParameterNode;
 import org.graalvm.compiler.nodes.ReturnNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
@@ -34,13 +32,13 @@
 import org.graalvm.compiler.nodes.calc.ConditionalNode;
 import org.graalvm.compiler.nodes.calc.IntegerTestNode;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
+import org.junit.Test;
 
 public class CompareCanonicalizerTest extends GraalCompilerTest {
 
     private StructuredGraph getCanonicalizedGraph(String name) {
         StructuredGraph graph = parseEager(name, AllowAssumptions.YES);
-        new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders()));
+        new CanonicalizerPhase().apply(graph, getProviders());
         return graph;
     }
 
@@ -57,7 +55,7 @@
             StructuredGraph graph = parseEager("canonicalCompare" + i, AllowAssumptions.NO);
             assertEquals(referenceGraph, graph);
         }
-        new CanonicalizerPhase().apply(referenceGraph, new PhaseContext(getProviders()));
+        new CanonicalizerPhase().apply(referenceGraph, getProviders());
         for (int i = 1; i < 4; i++) {
             StructuredGraph graph = getCanonicalizedGraph("canonicalCompare" + i);
             assertEquals(referenceGraph, graph);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CompareCanonicalizerTest2.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CompareCanonicalizerTest2.java	Mon Jul 01 14:57:02 2019 -0700
@@ -27,7 +27,6 @@
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.junit.Test;
 
 public class CompareCanonicalizerTest2 extends GraalCompilerTest {
@@ -36,7 +35,7 @@
 
     private StructuredGraph getCanonicalizedGraph(String name) {
         StructuredGraph graph = getRegularGraph(name);
-        new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders()));
+        new CanonicalizerPhase().apply(graph, getProviders());
         return graph;
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CompareCanonicalizerTest3.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CompareCanonicalizerTest3.java	Mon Jul 01 14:57:02 2019 -0700
@@ -29,12 +29,12 @@
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
 import org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.phases.OptimisticOptimizations;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
 import org.graalvm.compiler.phases.common.FrameStateAssignmentPhase;
 import org.graalvm.compiler.phases.common.GuardLoweringPhase;
 import org.graalvm.compiler.phases.tiers.MidTierContext;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.junit.Ignore;
 import org.junit.Test;
 
@@ -238,7 +238,7 @@
 
     protected void assertCanonicallyEqual(String snippet, String reference) {
         StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES);
-        PhaseContext context = new PhaseContext(getProviders());
+        CoreProviders context = getProviders();
         CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
 
         canonicalizer.apply(graph, context);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationTest10.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationTest10.java	Mon Jul 01 14:57:02 2019 -0700
@@ -28,11 +28,11 @@
 import org.graalvm.compiler.nodes.GuardNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
+import org.graalvm.compiler.phases.common.ConditionalEliminationPhase;
 import org.graalvm.compiler.phases.common.LoweringPhase;
-import org.graalvm.compiler.phases.common.ConditionalEliminationPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -94,7 +94,7 @@
 
     private void test(String snippet, int guardCount) {
         StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES);
-        PhaseContext context = new PhaseContext(getProviders());
+        CoreProviders context = getProviders();
         new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
         new ConditionalEliminationPhase(true).apply(graph, context);
         Assert.assertEquals(guardCount, graph.getNodes().filter(GuardNode.class).count());
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationTest13.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationTest13.java	Mon Jul 01 14:57:02 2019 -0700
@@ -29,8 +29,8 @@
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
 import org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.junit.Ignore;
 import org.junit.Test;
 
@@ -310,7 +310,7 @@
     }
 
     @Override
-    protected void prepareGraph(StructuredGraph graph, CanonicalizerPhase canonicalizer, PhaseContext context, boolean applyLowering) {
+    protected void prepareGraph(StructuredGraph graph, CanonicalizerPhase canonicalizer, CoreProviders context, boolean applyLowering) {
         super.prepareGraph(graph, canonicalizer, context, applyLowering);
         graph.clearAllStateAfter();
         graph.setGuardsStage(StructuredGraph.GuardsStage.AFTER_FSA);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationTest14.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationTest14.java	Mon Jul 01 14:57:02 2019 -0700
@@ -35,12 +35,12 @@
 import org.graalvm.compiler.nodes.java.LoadIndexedNode;
 import org.graalvm.compiler.nodes.memory.FloatingReadNode;
 import org.graalvm.compiler.nodes.memory.ReadNode;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
 import org.graalvm.compiler.phases.common.FloatingReadPhase;
 import org.graalvm.compiler.phases.common.IterativeConditionalEliminationPhase;
 import org.graalvm.compiler.phases.common.LoweringPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -71,7 +71,7 @@
     public void test1() {
         StructuredGraph graph = parseEager("test1Snippet", AllowAssumptions.YES);
         CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
-        PhaseContext context = new PhaseContext(getProviders());
+        CoreProviders context = getProviders();
 
         /* Convert the LoadIndexNode to ReadNode with floating guards. */
         new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationTest15.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationTest15.java	Mon Jul 01 14:57:02 2019 -0700
@@ -29,11 +29,11 @@
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
 import org.graalvm.compiler.nodes.calc.IntegerLessThanNode;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
 import org.graalvm.compiler.phases.common.IterativeConditionalEliminationPhase;
 import org.graalvm.compiler.phases.common.LoweringPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.graalvm.compiler.virtual.phases.ea.EarlyReadEliminationPhase;
 import org.junit.Assert;
 import org.junit.Test;
@@ -48,7 +48,7 @@
         StructuredGraph graph = parseEager(methodName, AllowAssumptions.YES);
 
         CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
-        PhaseContext context = new PhaseContext(getProviders());
+        CoreProviders context = getProviders();
 
         new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
         canonicalizer.apply(graph, context);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationTest16.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationTest16.java	Mon Jul 01 14:57:02 2019 -0700
@@ -32,6 +32,7 @@
 import org.graalvm.compiler.nodes.PiNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
+import org.junit.Before;
 import org.junit.Test;
 
 import jdk.vm.ci.meta.ResolvedJavaMethod;
@@ -41,6 +42,13 @@
  */
 public class ConditionalEliminationTest16 extends ConditionalEliminationTestBase {
 
+    @Before
+    public void resetType() {
+        parameterType = null;
+    }
+
+    Class<?> parameterType;
+
     public static int testCastExactInstance(Object object) {
         if (object.getClass() == Integer.class) {
             return ((Integer) object).intValue();
@@ -50,35 +58,91 @@
     }
 
     @Override
-    protected boolean checkHighTierGraph(StructuredGraph graph) {
-        for (ParameterNode param : graph.getNodes().filter(ParameterNode.class)) {
-            if (param.index() == 0) {
-                ParameterNode newParam = new ParameterNode(0, StampPair.createSingle(StampFactory.object(TypeReference.createExactTrusted(getMetaAccess().lookupJavaType(Integer.class)))));
-                graph.addWithoutUnique(newParam);
-                param.replaceAtUsages(newParam);
-                param.safeDelete();
-                break;
+    protected void checkHighTierGraph(StructuredGraph graph) {
+        if (parameterType != null) {
+            for (ParameterNode param : graph.getNodes().filter(ParameterNode.class)) {
+                if (param.index() == 0) {
+                    ParameterNode newParam = new ParameterNode(0, StampPair.createSingle(StampFactory.object(TypeReference.createExactTrusted(getMetaAccess().lookupJavaType(parameterType)))));
+                    graph.addWithoutUnique(newParam);
+                    param.replaceAtUsages(newParam);
+                    param.safeDelete();
+                    break;
+                }
             }
+            new CanonicalizerPhase().apply(graph, getDefaultHighTierContext());
         }
-        new CanonicalizerPhase().apply(graph, getDefaultHighTierContext());
-        return super.checkHighTierGraph(graph);
+        super.checkHighTierGraph(graph);
     }
 
     @Override
-    protected boolean checkMidTierGraph(StructuredGraph graph) {
+    protected void checkMidTierGraph(StructuredGraph graph) {
         int count = 0;
         for (PiNode node : graph.getNodes().filter(PiNode.class)) {
             assertTrue(node.getGuard() != null, "must have guarding node");
             count++;
         }
         assertTrue(count > 0, "expected at least one Pi");
-        return super.checkMidTierGraph(graph);
+        super.checkMidTierGraph(graph);
     }
 
     @Test
     public void test1() {
+        parameterType = Integer.class;
         ResolvedJavaMethod method = getResolvedJavaMethod("testCastExactInstance");
         StructuredGraph graph = parseForCompile(method);
         compile(method, graph);
     }
+
+    static class Base {
+        int getValue1() {
+            return 0;
+        }
+
+        Base getBase() {
+            return this;
+        }
+    }
+
+    static class Box extends Base {
+        int value1;
+
+        @Override
+        int getValue1() {
+            return value1;
+        }
+    }
+
+    static class BiggerBox extends Box {
+        int value2;
+
+        int getValue2() {
+            return value2;
+        }
+    }
+
+    public static int testCastExactTwiceInstance(Base base, boolean b) {
+        if (!(base instanceof Box)) {
+            GraalDirectives.deoptimizeAndInvalidate();
+            return -1;
+        }
+        int total = 0;
+        if (base instanceof Box) {
+            Box box = (Box) base;
+            total += box.value1;
+            if (b) {
+                total += System.identityHashCode(base);
+            }
+            total += ((BiggerBox) base).getValue2();
+        }
+        return total;
+    }
+
+    @Test
+    public void test2() {
+        BiggerBox box = new BiggerBox();
+        ResolvedJavaMethod method = getResolvedJavaMethod("testCastExactTwiceInstance");
+        StructuredGraph graph = parseForCompile(method);
+        compile(method, graph);
+        test("testCastExactTwiceInstance", box, false);
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationTest2.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationTest2.java	Mon Jul 01 14:57:02 2019 -0700
@@ -29,12 +29,12 @@
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
 import org.graalvm.compiler.nodes.java.InstanceOfNode;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
 import org.graalvm.compiler.phases.common.ConditionalEliminationPhase;
 import org.graalvm.compiler.phases.common.FloatingReadPhase;
 import org.graalvm.compiler.phases.common.LoweringPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -110,7 +110,7 @@
     public void testRedundantCompares() {
         StructuredGraph graph = parseEager("testRedundantComparesSnippet", AllowAssumptions.YES);
         CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
-        PhaseContext context = new PhaseContext(getProviders());
+        CoreProviders context = getProviders();
 
         new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
         canonicalizer.apply(graph, context);
@@ -133,7 +133,7 @@
         StructuredGraph graph = parseEager("testInstanceOfCheckCastSnippet", AllowAssumptions.YES);
 
         CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
-        PhaseContext context = new PhaseContext(getProviders());
+        CoreProviders context = getProviders();
 
         new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
         canonicalizer.apply(graph, context);
@@ -147,7 +147,7 @@
         StructuredGraph graph = parseEager(methodName, AllowAssumptions.YES);
 
         CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
-        PhaseContext context = new PhaseContext(getProviders());
+        CoreProviders context = getProviders();
 
         canonicalizer.apply(graph, context);
         new ConditionalEliminationPhase(true).apply(graph, context);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationTestBase.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationTestBase.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,20 +25,20 @@
 package org.graalvm.compiler.core.test;
 
 import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.loop.phases.ConvertDeoptimizeToGuardPhase;
 import org.graalvm.compiler.nodes.ProxyNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
 import org.graalvm.compiler.phases.OptimisticOptimizations;
 import org.graalvm.compiler.phases.OptimisticOptimizations.Optimization;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
 import org.graalvm.compiler.phases.common.ConditionalEliminationPhase;
-import org.graalvm.compiler.loop.phases.ConvertDeoptimizeToGuardPhase;
 import org.graalvm.compiler.phases.common.IterativeConditionalEliminationPhase;
 import org.graalvm.compiler.phases.common.LoweringPhase;
 import org.graalvm.compiler.phases.schedule.SchedulePhase;
 import org.graalvm.compiler.phases.tiers.HighTierContext;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.junit.Assert;
 
 /**
@@ -68,7 +68,7 @@
         StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES);
         DebugContext debug = graph.getDebug();
         debug.dump(DebugContext.BASIC_LEVEL, graph, "Graph");
-        PhaseContext context = new PhaseContext(getProviders());
+        CoreProviders context = getProviders();
         CanonicalizerPhase canonicalizer1 = new CanonicalizerPhase();
         CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
         try (DebugContext.Scope scope = debug.scope("ConditionalEliminationTest", graph)) {
@@ -93,7 +93,7 @@
         assertEquals(referenceGraph, graph);
     }
 
-    protected void prepareGraph(StructuredGraph graph, CanonicalizerPhase canonicalizer, PhaseContext context, boolean applyLowering) {
+    protected void prepareGraph(StructuredGraph graph, CanonicalizerPhase canonicalizer, CoreProviders context, boolean applyLowering) {
         if (applyLowering) {
             new ConvertDeoptimizeToGuardPhase().apply(graph, context);
             new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
@@ -105,7 +105,7 @@
 
     public void testProxies(String snippet, int expectedProxiesCreated) {
         StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES);
-        PhaseContext context = new PhaseContext(getProviders());
+        CoreProviders context = getProviders();
         CanonicalizerPhase canonicalizer1 = new CanonicalizerPhase();
         canonicalizer1.disableSimplification();
         canonicalizer1.apply(graph, context);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CopyOfVirtualizationTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CopyOfVirtualizationTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -35,9 +35,9 @@
 public class CopyOfVirtualizationTest extends GraalCompilerTest {
 
     @Override
-    protected boolean checkMidTierGraph(StructuredGraph graph) {
+    protected void checkMidTierGraph(StructuredGraph graph) {
         assertTrue(graph.getNodes().filter(node -> node instanceof NewArrayNode).count() == 0, "shouldn't require allocation in %s", graph);
-        return super.checkMidTierGraph(graph);
+        super.checkMidTierGraph(graph);
     }
 
     public byte byteCopyOfVirtualization(int index) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CountedLoopTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CountedLoopTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -483,14 +483,13 @@
     }
 
     @Override
-    protected boolean checkHighTierGraph(StructuredGraph graph) {
+    protected void checkHighTierGraph(StructuredGraph graph) {
         LoopsData loops = new LoopsData(graph);
         loops.detectedCountedLoops();
         for (IVPropertyNode node : graph.getNodes().filter(IVPropertyNode.class)) {
             node.rewrite(loops);
         }
         assert graph.getNodes().filter(IVPropertyNode.class).isEmpty();
-        return true;
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CustomizedBytecodePatternTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CustomizedBytecodePatternTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,14 +24,45 @@
 
 package org.graalvm.compiler.core.test;
 
+import java.lang.invoke.MethodHandles;
+import java.lang.reflect.Method;
+import java.security.ProtectionDomain;
+
+import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
 import org.objectweb.asm.Opcodes;
 
+import sun.misc.Unsafe;
+
 public abstract class CustomizedBytecodePatternTest extends GraalCompilerTest implements Opcodes {
 
     protected Class<?> getClass(String className) throws ClassNotFoundException {
         return new CachedLoader(CustomizedBytecodePatternTest.class.getClassLoader(), className).findClass(className);
     }
 
+    /**
+     * @param className
+     * @param lookUp lookup object with boot class load capability (required for jdk 9 and above)
+     * @return loaded class
+     * @throws ClassNotFoundException
+     */
+    protected Class<?> getClassBL(String className, MethodHandles.Lookup lookUp) throws ClassNotFoundException {
+        byte[] gen = generateClass(className.replace('.', '/'));
+        Method defineClass = null;
+        Class<?> loadedClass = null;
+        try {
+            if (JavaVersionUtil.JAVA_SPEC <= 8) {
+                defineClass = Unsafe.class.getDeclaredMethod("defineClass", String.class, byte[].class, int.class, int.class, ClassLoader.class, ProtectionDomain.class);
+                loadedClass = (Class<?>) defineClass.invoke(UNSAFE, className, gen, 0, gen.length, null, null);
+            } else {
+                defineClass = MethodHandles.lookup().getClass().getDeclaredMethod("defineClass", byte[].class);
+                loadedClass = (Class<?>) defineClass.invoke(lookUp, gen);
+            }
+        } catch (Exception e) {
+            throw new ClassNotFoundException();
+        }
+        return loadedClass;
+    }
+
     private class CachedLoader extends ClassLoader {
 
         final String className;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/FloatingReadTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/FloatingReadTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -32,11 +32,11 @@
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
 import org.graalvm.compiler.nodes.extended.MonitorExit;
 import org.graalvm.compiler.nodes.memory.FloatingReadNode;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
 import org.graalvm.compiler.phases.common.FloatingReadPhase;
 import org.graalvm.compiler.phases.common.LoweringPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -67,7 +67,7 @@
         try (DebugContext.Scope s = debug.scope("FloatingReadTest", new DebugDumpScope(snippet))) {
 
             StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES);
-            PhaseContext context = new PhaseContext(getProviders());
+            CoreProviders context = getProviders();
             new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
             new FloatingReadPhase().apply(graph);
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraalCompilerTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraalCompilerTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -124,6 +124,7 @@
 import org.graalvm.compiler.phases.util.Providers;
 import org.graalvm.compiler.printer.GraalDebugHandlersFactory;
 import org.graalvm.compiler.runtime.RuntimeProvider;
+import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
 import org.graalvm.compiler.test.AddExports;
 import org.graalvm.compiler.test.GraalTest;
 import org.graalvm.compiler.test.JLModule;
@@ -150,9 +151,9 @@
 import jdk.vm.ci.meta.SpeculationLog;
 
 /**
- * Base class for Graal compiler unit tests.
+ * Base class for compiler unit tests.
  * <p>
- * White box tests for Graal compiler transformations use this pattern:
+ * White box tests for compiler transformations use this pattern:
  * <ol>
  * <li>Create a graph by {@linkplain #parseEager parsing} a method.</li>
  * <li>Manually modify the graph (e.g. replace a parameter node with a constant).</li>
@@ -194,7 +195,7 @@
      * as of JDK 9.
      */
     protected final void exportPackage(Class<?> moduleMember, String packageName) {
-        if (!Java8OrEarlier) {
+        if (JavaVersionUtil.JAVA_SPEC > 8) {
             JLModule.exportPackageTo(moduleMember, packageName, getClass());
         }
     }
@@ -224,27 +225,27 @@
      * Can be overridden by unit tests to verify properties of the graph.
      *
      * @param graph the graph at the end of HighTier
+     * @throws AssertionError if the verification fails
      */
-    protected boolean checkHighTierGraph(StructuredGraph graph) {
-        return true;
+    protected void checkHighTierGraph(StructuredGraph graph) {
     }
 
     /**
      * Can be overridden by unit tests to verify properties of the graph.
      *
      * @param graph the graph at the end of MidTier
+     * @throws AssertionError if the verification fails
      */
-    protected boolean checkMidTierGraph(StructuredGraph graph) {
-        return true;
+    protected void checkMidTierGraph(StructuredGraph graph) {
     }
 
     /**
      * Can be overridden by unit tests to verify properties of the graph.
      *
      * @param graph the graph at the end of LowTier
+     * @throws AssertionError if the verification fails
      */
-    protected boolean checkLowTierGraph(StructuredGraph graph) {
-        return true;
+    protected void checkLowTierGraph(StructuredGraph graph) {
     }
 
     protected static void breakpoint() {
@@ -288,7 +289,7 @@
 
             @Override
             protected void run(StructuredGraph graph) {
-                assert checkHighTierGraph(graph) : "failed HighTier graph check";
+                checkHighTierGraph(graph);
             }
 
             @Override
@@ -305,7 +306,7 @@
 
             @Override
             protected void run(StructuredGraph graph) {
-                assert checkMidTierGraph(graph) : "failed MidTier graph check";
+                checkMidTierGraph(graph);
             }
 
             @Override
@@ -322,7 +323,7 @@
 
             @Override
             protected void run(StructuredGraph graph) {
-                assert checkLowTierGraph(graph) : "failed LowTier graph check";
+                checkLowTierGraph(graph);
             }
 
             @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraphEncoderTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraphEncoderTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -34,8 +34,8 @@
 import org.graalvm.compiler.nodes.GraphEncoder;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.junit.Test;
 
 import jdk.vm.ci.meta.ResolvedJavaMethod;
@@ -60,7 +60,7 @@
             if (javaMethod.hasBytecodes()) {
                 StructuredGraph originalGraph = parseEager(javaMethod, AllowAssumptions.YES);
                 if (canonicalize) {
-                    PhaseContext context = new PhaseContext(getProviders());
+                    CoreProviders context = getProviders();
                     new CanonicalizerPhase().apply(originalGraph, context);
                 }
                 originalGraphs.add(originalGraph);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GuardedIntrinsicTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,234 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package org.graalvm.compiler.core.test;
-
-import java.util.List;
-
-import org.graalvm.compiler.core.common.CompilationIdentifier;
-import org.graalvm.compiler.graph.Node;
-import org.graalvm.compiler.nodes.ConstantNode;
-import org.graalvm.compiler.nodes.Invoke;
-import org.graalvm.compiler.nodes.InvokeNode;
-import org.graalvm.compiler.nodes.StructuredGraph;
-import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
-import org.graalvm.compiler.nodes.ValueNode;
-import org.graalvm.compiler.nodes.extended.OpaqueNode;
-import org.graalvm.compiler.nodes.extended.LoadHubNode;
-import org.graalvm.compiler.nodes.extended.LoadMethodNode;
-import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
-import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin;
-import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.Receiver;
-import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins;
-import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration;
-import org.graalvm.compiler.options.OptionValues;
-import org.junit.Assert;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-import jdk.vm.ci.meta.JavaKind;
-import jdk.vm.ci.meta.ResolvedJavaMethod;
-
-/**
- * Tests use of an intrinsic for virtual methods where the call site is indirect. A prime example is
- * an intrinsic for {@link Object#hashCode()}. The intrinsic can only be used if the call site would
- * actually dispatch to {@link Object#hashCode()} and not a method that overrides it.
- */
-public class GuardedIntrinsicTest extends GraalCompilerTest {
-
-    static class Super {
-        int getAge() {
-            return 11;
-        }
-    }
-
-    public static class Person extends Super {
-        int age;
-
-        public Person(int age) {
-            this.age = age;
-        }
-
-        @Override
-        public int getAge() {
-            return age;
-        }
-    }
-
-    @BytecodeParserForceInline
-    public static final Super createSuper() {
-        return new Super();
-    }
-
-    @BytecodeParserNeverInline
-    public static final Super createPerson() {
-        return new Person(42);
-    }
-
-    public static int getSuperAge(Super s) {
-        return s.getAge();
-    }
-
-    public static int getPersonAge(Person p) {
-        return p.getAge();
-    }
-
-    public static int makeSuperAge() {
-        return createSuper().getAge();
-    }
-
-    public static int makePersonAge() {
-        return createPerson().getAge();
-    }
-
-    @BeforeClass
-    public static void init() {
-        // Ensure classes are initialized
-        new Person(0).toString();
-    }
-
-    private StructuredGraph graph;
-    private StructuredGraph parsedForCompile;
-
-    @Override
-    protected StructuredGraph parseForCompile(ResolvedJavaMethod method, CompilationIdentifier compilationId, OptionValues options) {
-        graph = super.parseForCompile(method, compilationId, options);
-        parsedForCompile = (StructuredGraph) graph.copy(graph.getDebug());
-        return graph;
-    }
-
-    @Override
-    protected void registerInvocationPlugins(InvocationPlugins invocationPlugins) {
-        Registration r = new Registration(invocationPlugins, Super.class);
-
-        r.register1("getAge", Receiver.class, new InvocationPlugin() {
-            @Override
-            public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
-                ConstantNode res = b.add(ConstantNode.forInt(new Super().getAge()));
-                b.add(new OpaqueNode(res));
-                b.push(JavaKind.Int, res);
-                return true;
-            }
-        });
-        super.registerInvocationPlugins(invocationPlugins);
-    }
-
-    public static int referenceMakeSuperAge() {
-        return 11;
-    }
-
-    public static int referenceMakePersonAge() {
-        return 42;
-    }
-
-    @Test
-    public void test01() {
-        Super inheritsHC = new Super();
-        Person overridesHC = new Person(0);
-
-        // Ensure the profile for getSuperAge includes both receiver types
-        getSuperAge(inheritsHC);
-        getSuperAge(overridesHC);
-
-        test("getSuperAge", inheritsHC);
-        test("getSuperAge", overridesHC);
-
-        // Check that the virtual dispatch test exists after bytecode parsing
-        Assert.assertEquals(1, parsedForCompile.getNodes().filter(LoadMethodNode.class).count());
-        Assert.assertEquals(1, parsedForCompile.getNodes().filter(LoadHubNode.class).count());
-
-        // Check for the marker node indicating the intrinsic was applied
-        Assert.assertEquals(1, parsedForCompile.getNodes().filter(OpaqueNode.class).count());
-
-        // Final graph should have a single invoke
-        List<Node> invokes = graph.getNodes().filter(n -> n instanceof Invoke).snapshot();
-        Assert.assertEquals(invokes.toString(), 1, invokes.size());
-    }
-
-    @Test
-    public void test02() {
-        test("getPersonAge", new Person(0));
-
-        // Check that the virtual dispatch test does not exist after bytecode parsing
-        Assert.assertEquals(0, parsedForCompile.getNodes().filter(LoadMethodNode.class).count());
-        Assert.assertEquals(0, parsedForCompile.getNodes().filter(LoadHubNode.class).count());
-
-        Assert.assertEquals(0, parsedForCompile.getNodes().filter(InvokeNode.class).count());
-    }
-
-    @Test
-    public void test03() {
-        test("makeSuperAge");
-
-        // Check that the virtual dispatch test does not exist after bytecode parsing
-        Assert.assertEquals(0, parsedForCompile.getNodes().filter(LoadMethodNode.class).count());
-        Assert.assertEquals(0, parsedForCompile.getNodes().filter(LoadHubNode.class).count());
-
-        StructuredGraph referenceGraph = parseEager("referenceMakeSuperAge", AllowAssumptions.NO);
-        assertEquals(referenceGraph, graph, true, true);
-    }
-
-    @Test
-    public void test04() {
-        test("makePersonAge");
-
-        // Check that the virtual dispatch test exists after bytecode parsing
-        Assert.assertEquals(1, parsedForCompile.getNodes().filter(LoadMethodNode.class).count());
-        Assert.assertEquals(1, parsedForCompile.getNodes().filter(LoadHubNode.class).count());
-
-        StructuredGraph referenceGraph = parseEager("referenceMakePersonAge", AllowAssumptions.NO);
-        assertEquals(referenceGraph, graph, true, true);
-    }
-
-    static final class ReadCacheEntry {
-
-        public final Object identity;
-        public final ValueNode object;
-
-        ReadCacheEntry(Object identity, ValueNode object) {
-            this.identity = identity;
-            this.object = object;
-        }
-
-        @Override
-        public int hashCode() {
-            int result = ((identity == null) ? 0 : identity.hashCode());
-            return result + System.identityHashCode(object);
-        }
-    }
-
-    public static int getHashCode(ReadCacheEntry obj) {
-        return obj.hashCode();
-    }
-
-    @Test
-    public void test05() {
-        ReadCacheEntry val1 = new ReadCacheEntry("identity", ConstantNode.forBoolean(false));
-        ReadCacheEntry val2 = new ReadCacheEntry(Integer.valueOf(34), ConstantNode.forInt(42));
-        for (int i = 0; i < 10000; i++) {
-            getHashCode(val2);
-        }
-        test("getHashCode", val1);
-    }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/HashCodeTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/HashCodeTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,22 +24,14 @@
 
 package org.graalvm.compiler.core.test;
 
-import java.util.HashMap;
-import java.util.List;
-
 import org.graalvm.compiler.core.phases.HighTier;
 import org.graalvm.compiler.core.phases.MidTier;
 import org.graalvm.compiler.nodes.InvokeNode;
-import org.graalvm.compiler.nodes.InvokeWithExceptionNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
-import org.graalvm.compiler.nodes.extended.LoadHubNode;
-import org.graalvm.compiler.nodes.extended.LoadMethodNode;
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.phases.OptimisticOptimizations;
 import org.graalvm.compiler.phases.tiers.MidTierContext;
-import org.graalvm.compiler.test.SubprocessUtil;
 import org.junit.Assert;
-import org.junit.Assume;
 import org.junit.Test;
 
 public class HashCodeTest extends GraalCompilerTest {
@@ -81,10 +73,6 @@
         return System.identityHashCode(NonOverridingConstant);
     }
 
-    public static final int hashCodeNoFoldOverridingSnippet01(Object o) {
-        return o.hashCode();
-    }
-
     public static final int identityHashCodeFoldOverridingSnippet01() {
         return System.identityHashCode(OverridingConstant);
     }
@@ -117,56 +105,17 @@
 
     @Test
     public void test05() {
-        checkForGuardedIntrinsicPattern("hashCodeNoFoldOverridingSnippet01");
-
-        Object nullObject = null;
-        test("hashCodeNoFoldOverridingSnippet01", nullObject);
-        test("hashCodeNoFoldOverridingSnippet01", new Object());
-        test("hashCodeNoFoldOverridingSnippet01", new DontOverrideHashCode());
-    }
-
-    @Test
-    public void test06() {
         StructuredGraph g = buildGraphAfterMidTier("identityHashCodeFoldOverridingSnippet01");
         Assert.assertEquals(0, g.getNodes().filter(InvokeNode.class).count());
     }
 
     @Test
-    public void test07() {
+    public void test06() {
         initialize(DontOverrideHashCode.class);
         StructuredGraph g = buildGraphAfterMidTier("dontOverrideHashCodeFinalClass");
         Assert.assertEquals(0, g.getNodes().filter(InvokeNode.class).count());
     }
 
-    public static final int hashCodeInterface(Appendable o) {
-        return o.hashCode();
-    }
-
-    @Test
-    public void test08() {
-        // This test requires profiling information which does not work reliable across platforms
-        // when running with -Xcomp
-        List<String> commandLine = SubprocessUtil.getVMCommandLine();
-        Assume.assumeTrue(commandLine != null);
-        Assume.assumeFalse(commandLine.contains("-Xcomp"));
-        initialize(Appendable.class);
-        checkForGuardedIntrinsicPattern("hashCodeInterface");
-
-        // Ensure the profile for the dispatch in hashCodeSnippet01
-        // has a receiver type that does not select Object.hashCode intrinsic
-        hashCodeSnippet01(new HashMap<>());
-        checkForGuardedIntrinsicPattern("hashCodeSnippet01");
-    }
-
-    private void checkForGuardedIntrinsicPattern(String name) {
-        StructuredGraph g = parseForCompile(getResolvedJavaMethod(name));
-        int invokeNodeCount = g.getNodes().filter(InvokeNode.class).count();
-        int invokeWithExceptionNodeCount = g.getNodes().filter(InvokeWithExceptionNode.class).count();
-        Assert.assertEquals(1, invokeNodeCount + invokeWithExceptionNodeCount);
-        Assert.assertEquals(1, g.getNodes().filter(LoadHubNode.class).count());
-        Assert.assertEquals(1, g.getNodes().filter(LoadMethodNode.class).count());
-    }
-
     @SuppressWarnings("try")
     private StructuredGraph buildGraphAfterMidTier(String name) {
         StructuredGraph g = parseForCompile(getResolvedJavaMethod(name));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/IfCanonicalizerTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/IfCanonicalizerTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -32,6 +32,7 @@
 import org.graalvm.compiler.nodes.ParameterNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
 import org.graalvm.compiler.phases.OptimisticOptimizations;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
@@ -39,7 +40,6 @@
 import org.graalvm.compiler.phases.common.GuardLoweringPhase;
 import org.graalvm.compiler.phases.common.LoweringPhase;
 import org.graalvm.compiler.phases.tiers.MidTierContext;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.junit.Test;
 
 /**
@@ -226,7 +226,7 @@
 
     private void testCombinedIf(String snippet, int count) {
         StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES);
-        PhaseContext context = new PhaseContext(getProviders());
+        CoreProviders context = getProviders();
         new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
         new FloatingReadPhase().apply(graph);
         MidTierContext midContext = new MidTierContext(getProviders(), getTargetProvider(), OptimisticOptimizations.ALL, graph.getProfilingInfo());
@@ -247,7 +247,7 @@
             }
         }
         debug.dump(DebugContext.BASIC_LEVEL, graph, "Graph");
-        new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders()));
+        new CanonicalizerPhase().apply(graph, getProviders());
         for (FrameState fs : param.usages().filter(FrameState.class).snapshot()) {
             fs.replaceFirstInput(param, null);
             param.safeDelete();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ImplicitNullCheckTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ImplicitNullCheckTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -31,6 +31,7 @@
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
 import org.graalvm.compiler.nodes.memory.ReadNode;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
 import org.graalvm.compiler.phases.OptimisticOptimizations;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
@@ -38,7 +39,6 @@
 import org.graalvm.compiler.phases.common.GuardLoweringPhase;
 import org.graalvm.compiler.phases.common.LoweringPhase;
 import org.graalvm.compiler.phases.tiers.MidTierContext;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.junit.Assert;
 import org.junit.Ignore;
 import org.junit.Test;
@@ -71,7 +71,7 @@
         DebugContext debug = getDebugContext();
         try (DebugContext.Scope s = debug.scope("FloatingReadTest", new DebugDumpScope(snippet))) {
             StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES, debug);
-            PhaseContext context = new PhaseContext(getProviders());
+            CoreProviders context = getProviders();
             new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
             new FloatingReadPhase().apply(graph);
             MidTierContext midTierContext = new MidTierContext(getProviders(), getTargetProvider(), OptimisticOptimizations.ALL, graph.getProfilingInfo());
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/IntegerDivPowerOf2Test.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.core.test;
+
+import org.graalvm.compiler.api.directives.GraalDirectives;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.calc.RightShiftNode;
+import org.graalvm.compiler.nodes.calc.UnsignedRightShiftNode;
+import org.junit.Test;
+
+public class IntegerDivPowerOf2Test extends GraalCompilerTest {
+
+    public static int positiveDivByPowerOf2(boolean flag) {
+        int val = flag ? 1 : 10;
+        GraalDirectives.blackhole(val);
+        return val / 8;
+    }
+
+    @Test
+    public void testPositiveDivByPowerOf2() {
+        StructuredGraph graph = parseForCompile(getResolvedJavaMethod("positiveDivByPowerOf2"));
+        // We expect no rounding is needed
+        assertTrue(countShiftNode(graph) == 1);
+    }
+
+    private static int countShiftNode(StructuredGraph graph) {
+        return graph.getNodes().filter(node -> node instanceof RightShiftNode || node instanceof UnsignedRightShiftNode).count();
+    }
+
+    public static int unknownDivByPowerOf2(boolean flag) {
+        int val = flag ? 0x800000F0 : 0x20;
+        GraalDirectives.blackhole(val);
+        return val / 8;
+    }
+
+    @Test
+    public void testUnknownDivByPowerOf2() {
+        StructuredGraph graph = parseForCompile(getResolvedJavaMethod("unknownDivByPowerOf2"));
+        // We expect no rounding is needed
+        assertTrue(graph.getNodes().filter(RightShiftNode.class).count() <= 1);
+    }
+
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/IntegerEqualsCanonicalizerTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/IntegerEqualsCanonicalizerTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,13 +24,11 @@
 
 package org.graalvm.compiler.core.test;
 
-import org.junit.Test;
-
 import org.graalvm.compiler.nodes.FrameState;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
+import org.junit.Test;
 
 public class IntegerEqualsCanonicalizerTest extends GraalCompilerTest {
 
@@ -168,7 +166,7 @@
 
     private StructuredGraph getCanonicalizedGraph(String snippet) {
         StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES);
-        new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders()));
+        new CanonicalizerPhase().apply(graph, getProviders());
         for (FrameState state : graph.getNodes(FrameState.TYPE).snapshot()) {
             state.replaceAtUsages(null);
             state.safeDelete();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/LockEliminationTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/LockEliminationTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -36,7 +36,6 @@
 import org.graalvm.compiler.phases.common.LockEliminationPhase;
 import org.graalvm.compiler.phases.common.LoweringPhase;
 import org.graalvm.compiler.phases.tiers.HighTierContext;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.graalvm.compiler.virtual.phases.ea.PartialEscapePhase;
 import org.junit.Test;
 
@@ -70,7 +69,7 @@
         test("testSynchronizedSnippet", new A(), new A());
 
         StructuredGraph graph = getGraph("testSynchronizedSnippet", false);
-        new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders()));
+        new CanonicalizerPhase().apply(graph, getProviders());
         new LockEliminationPhase().apply(graph);
         assertDeepEquals(1, graph.getNodes().filter(RawMonitorEnterNode.class).count());
         assertDeepEquals(1, graph.getNodes().filter(MonitorExitNode.class).count());
@@ -88,7 +87,7 @@
         test("testSynchronizedMethodSnippet", new A());
 
         StructuredGraph graph = getGraph("testSynchronizedMethodSnippet", false);
-        new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders()));
+        new CanonicalizerPhase().apply(graph, getProviders());
         new LockEliminationPhase().apply(graph);
         assertDeepEquals(1, graph.getNodes().filter(RawMonitorEnterNode.class).count());
         assertDeepEquals(1, graph.getNodes().filter(MonitorExitNode.class).count());
@@ -106,7 +105,7 @@
     public void testUnrolledSync() {
         StructuredGraph graph = getGraph("testUnrolledSyncSnippet", false);
         CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
-        canonicalizer.apply(graph, new PhaseContext(getProviders()));
+        canonicalizer.apply(graph, getProviders());
         HighTierContext context = getDefaultHighTierContext();
         new LoopFullUnrollPhase(canonicalizer, new DefaultLoopPolicies()).apply(graph, context);
         new LockEliminationPhase().apply(graph);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/LoopFullUnrollTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/LoopFullUnrollTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -31,8 +31,8 @@
 import org.graalvm.compiler.nodes.LoopBeginNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.junit.Test;
 
 public class LoopFullUnrollTest extends GraalCompilerTest {
@@ -88,7 +88,7 @@
         try (DebugContext.Scope s = debug.scope(getClass().getSimpleName(), new DebugDumpScope(snippet))) {
             final StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO, debug);
 
-            PhaseContext context = new PhaseContext(getProviders());
+            CoreProviders context = getProviders();
             new LoopFullUnrollPhase(new CanonicalizerPhase(), new DefaultLoopPolicies()).apply(graph, context);
 
             assertTrue(graph.getNodes().filter(LoopBeginNode.class).count() == loopCount);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/LoopUnswitchTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/LoopUnswitchTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -31,7 +31,6 @@
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.junit.Test;
 
 public class LoopUnswitchTest extends GraalCompilerTest {
@@ -134,8 +133,8 @@
         graph.clearAllStateAfter();
         referenceGraph.clearAllStateAfter();
 
-        new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders()));
-        new CanonicalizerPhase().apply(referenceGraph, new PhaseContext(getProviders()));
+        new CanonicalizerPhase().apply(graph, getProviders());
+        new CanonicalizerPhase().apply(referenceGraph, getProviders());
         try (DebugContext.Scope s = debug.scope("Test", new DebugDumpScope("Test:" + snippet))) {
             assertEquals(referenceGraph, graph);
         } catch (Throwable e) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/MergeCanonicalizerTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/MergeCanonicalizerTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -32,7 +32,6 @@
 import org.graalvm.compiler.phases.OptimisticOptimizations.Optimization;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
 import org.graalvm.compiler.phases.tiers.HighTierContext;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.junit.Test;
 
 public class MergeCanonicalizerTest extends GraalCompilerTest {
@@ -71,8 +70,8 @@
 
     private void testReturnCount(String snippet, int returnCount) {
         StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES);
-        new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders()));
-        new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders()));
+        new CanonicalizerPhase().apply(graph, getProviders());
+        new CanonicalizerPhase().apply(graph, getProviders());
         graph.getDebug().dump(DebugContext.BASIC_LEVEL, graph, "Graph");
         assertDeepEquals(returnCount, graph.getNodes(ReturnNode.TYPE).count());
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/NodePropertiesTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/NodePropertiesTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -33,12 +33,12 @@
 import org.graalvm.compiler.nodes.LoopBeginNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.phases.BasePhase;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase.CustomCanonicalizer;
 import org.graalvm.compiler.phases.contract.NodeCostUtil;
 import org.graalvm.compiler.phases.tiers.HighTierContext;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -318,12 +318,12 @@
         }
     }
 
-    private static class GraphCostPhase extends BasePhase<PhaseContext> {
+    private static class GraphCostPhase extends BasePhase<CoreProviders> {
         private double finalCycles;
         private double finalSize;
 
         @Override
-        protected void run(StructuredGraph graph, PhaseContext context) {
+        protected void run(StructuredGraph graph, CoreProviders context) {
             finalCycles = NodeCostUtil.computeGraphCycles(graph, true);
             finalSize = NodeCostUtil.computeGraphSize(graph);
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/OptionsVerifierTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/OptionsVerifierTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -49,7 +49,7 @@
 import org.graalvm.compiler.options.OptionDescriptors;
 import org.graalvm.compiler.options.OptionKey;
 import org.graalvm.compiler.options.OptionsParser;
-import org.graalvm.compiler.test.GraalTest;
+import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
 import org.junit.Test;
 import org.objectweb.asm.ClassReader;
 import org.objectweb.asm.ClassVisitor;
@@ -82,7 +82,7 @@
 
         Classpath() throws IOException {
             List<String> names = new ArrayList<>(Arrays.asList(System.getProperty("java.class.path").split(File.pathSeparator)));
-            if (GraalTest.Java8OrEarlier) {
+            if (JavaVersionUtil.JAVA_SPEC <= 8) {
                 names.addAll(Arrays.asList(System.getProperty("sun.boot.class.path").split(File.pathSeparator)));
             } else {
                 names.addAll(Arrays.asList(System.getProperty("jdk.module.path").split(File.pathSeparator)));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/PushNodesThroughPiTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/PushNodesThroughPiTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -33,11 +33,11 @@
 import org.graalvm.compiler.nodes.calc.IsNullNode;
 import org.graalvm.compiler.nodes.memory.ReadNode;
 import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
 import org.graalvm.compiler.nodes.type.StampTool;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
 import org.graalvm.compiler.phases.common.LoweringPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.junit.Assert;
 import org.junit.Ignore;
 import org.junit.Test;
@@ -103,7 +103,7 @@
 
     private StructuredGraph compileTestSnippet(final String snippet) {
         StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO);
-        PhaseContext context = new PhaseContext(getProviders());
+        CoreProviders context = getProviders();
         CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
         new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
         canonicalizer.apply(graph, context);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/PushThroughIfTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/PushThroughIfTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -30,7 +30,6 @@
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
 import org.graalvm.compiler.nodes.util.GraphUtil;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.junit.Test;
 
 public class PushThroughIfTest extends GraalCompilerTest {
@@ -66,15 +65,15 @@
             fs.replaceAtUsages(null);
             GraphUtil.killWithUnusedFloatingInputs(fs);
         }
-        new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders()));
-        new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders()));
+        new CanonicalizerPhase().apply(graph, getProviders());
+        new CanonicalizerPhase().apply(graph, getProviders());
 
         StructuredGraph referenceGraph = parseEager(reference, AllowAssumptions.YES);
         for (FrameState fs : referenceGraph.getNodes(FrameState.TYPE).snapshot()) {
             fs.replaceAtUsages(null);
             GraphUtil.killWithUnusedFloatingInputs(fs);
         }
-        new CanonicalizerPhase().apply(referenceGraph, new PhaseContext(getProviders()));
+        new CanonicalizerPhase().apply(referenceGraph, getProviders());
         assertEquals(referenceGraph, graph);
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ReadAfterCheckCastTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ReadAfterCheckCastTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -30,11 +30,11 @@
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
 import org.graalvm.compiler.nodes.memory.FloatingReadNode;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
 import org.graalvm.compiler.phases.common.FloatingReadPhase;
 import org.graalvm.compiler.phases.common.LoweringPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -89,7 +89,7 @@
             // check shape of graph, with lots of assumptions. will probably fail if graph
             // structure changes significantly
             StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES);
-            PhaseContext context = new PhaseContext(getProviders());
+            CoreProviders context = getProviders();
             CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
             new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
             new FloatingReadPhase().apply(graph);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ReassociateAndCanonicalTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ReassociateAndCanonicalTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,14 +24,12 @@
 
 package org.graalvm.compiler.core.test;
 
-import org.junit.Test;
-
 import org.graalvm.compiler.graph.IterableNodeType;
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
+import org.junit.Test;
 
 public class ReassociateAndCanonicalTest extends GraalCompilerTest {
 
@@ -247,9 +245,9 @@
 
     private <T extends Node & IterableNodeType> void test(String test, String ref) {
         StructuredGraph testGraph = parseEager(test, AllowAssumptions.NO);
-        new CanonicalizerPhase().apply(testGraph, new PhaseContext(getProviders()));
+        new CanonicalizerPhase().apply(testGraph, getProviders());
         StructuredGraph refGraph = parseEager(ref, AllowAssumptions.NO);
-        new CanonicalizerPhase().apply(refGraph, new PhaseContext(getProviders()));
+        new CanonicalizerPhase().apply(refGraph, getProviders());
         assertEquals(testGraph, refGraph);
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ReferenceGetLoopTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ReferenceGetLoopTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -42,7 +42,7 @@
 public class ReferenceGetLoopTest extends GraalCompilerTest {
 
     @Override
-    protected boolean checkMidTierGraph(StructuredGraph graph) {
+    protected void checkMidTierGraph(StructuredGraph graph) {
         final LoopsData loops = new LoopsData(graph);
         boolean found = false;
         for (LoopEx loop : loops.loops()) {
@@ -62,7 +62,6 @@
         if (!found) {
             assertTrue(false, "Reference.referent not found in loop: " + getCanonicalGraphString(graph, true, false));
         }
-        return true;
     }
 
     public volatile Object referent;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ScalarTypeSystemTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ScalarTypeSystemTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -27,8 +27,8 @@
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.junit.Test;
 
 /**
@@ -133,7 +133,7 @@
         // No debug scope to reduce console noise for @Test(expected = ...) tests
         StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO);
         graph.getDebug().dump(DebugContext.BASIC_LEVEL, graph, "Graph");
-        PhaseContext context = new PhaseContext(getProviders());
+        CoreProviders context = getProviders();
         new CanonicalizerPhase().apply(graph, context);
         StructuredGraph referenceGraph = parseEager(referenceSnippet, AllowAssumptions.NO);
         assertEquals(referenceGraph, graph);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/SchedulingTest2.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/SchedulingTest2.java	Mon Jul 01 14:57:02 2019 -0700
@@ -41,6 +41,7 @@
 import org.graalvm.compiler.nodes.calc.AddNode;
 import org.graalvm.compiler.nodes.calc.BinaryArithmeticNode;
 import org.graalvm.compiler.nodes.cfg.Block;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
 import org.graalvm.compiler.phases.OptimisticOptimizations;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
@@ -50,7 +51,6 @@
 import org.graalvm.compiler.phases.schedule.SchedulePhase;
 import org.graalvm.compiler.phases.schedule.SchedulePhase.SchedulingStrategy;
 import org.graalvm.compiler.phases.tiers.MidTierContext;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.junit.Test;
 
 public class SchedulingTest2 extends GraphScheduleTest {
@@ -98,7 +98,7 @@
             }
         }
 
-        PhaseContext context = new PhaseContext(getProviders());
+        CoreProviders context = getProviders();
         new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
         new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, context);
         MidTierContext midContext = new MidTierContext(getProviders(), getTargetProvider(), OptimisticOptimizations.ALL, graph.getProfilingInfo());
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/StampCanonicalizerTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/StampCanonicalizerTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,14 +24,12 @@
 
 package org.graalvm.compiler.core.test;
 
-import org.junit.Test;
-
 import org.graalvm.compiler.core.common.type.IntegerStamp;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
 import org.graalvm.compiler.phases.common.DeadCodeEliminationPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
+import org.junit.Test;
 
 /**
  * This class tests some specific patterns the stamp system should be able to canonicalize away
@@ -113,7 +111,7 @@
 
     private void testZeroReturn(String methodName) {
         StructuredGraph graph = parseEager(methodName, AllowAssumptions.YES);
-        new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders()));
+        new CanonicalizerPhase().apply(graph, getProviders());
         new DeadCodeEliminationPhase().apply(graph);
         assertConstantReturn(graph, 0);
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/StraighteningTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/StraighteningTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -28,7 +28,6 @@
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.junit.Test;
 
 public class StraighteningTest extends GraalCompilerTest {
@@ -91,7 +90,7 @@
         StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES);
         DebugContext debug = graph.getDebug();
         debug.dump(DebugContext.BASIC_LEVEL, graph, "Graph");
-        new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders()));
+        new CanonicalizerPhase().apply(graph, getProviders());
         StructuredGraph referenceGraph = parseEager(REFERENCE_SNIPPET, AllowAssumptions.YES);
         assertEquals(referenceGraph, graph);
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/TypeSystemTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/TypeSystemTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -44,7 +44,6 @@
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
 import org.graalvm.compiler.phases.common.ConditionalEliminationPhase;
 import org.graalvm.compiler.phases.schedule.SchedulePhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.junit.Assert;
 import org.junit.Ignore;
 import org.junit.Test;
@@ -188,14 +187,14 @@
          * tail-duplication gets activated thus resulting in a graph with more nodes than the
          * reference graph.
          */
-        new ConditionalEliminationPhase(false).apply(graph, new PhaseContext(getProviders()));
-        new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders()));
+        new ConditionalEliminationPhase(false).apply(graph, getProviders());
+        new CanonicalizerPhase().apply(graph, getProviders());
         // a second canonicalizer is needed to process nested MaterializeNodes
-        new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders()));
+        new CanonicalizerPhase().apply(graph, getProviders());
         StructuredGraph referenceGraph = parseEager(referenceSnippet, AllowAssumptions.NO);
-        new ConditionalEliminationPhase(false).apply(referenceGraph, new PhaseContext(getProviders()));
-        new CanonicalizerPhase().apply(referenceGraph, new PhaseContext(getProviders()));
-        new CanonicalizerPhase().apply(referenceGraph, new PhaseContext(getProviders()));
+        new ConditionalEliminationPhase(false).apply(referenceGraph, getProviders());
+        new CanonicalizerPhase().apply(referenceGraph, getProviders());
+        new CanonicalizerPhase().apply(referenceGraph, getProviders());
         assertEquals(referenceGraph, graph);
     }
 
@@ -245,8 +244,8 @@
 
     private <T extends Node> void testHelper(String snippet, Class<T> clazz) {
         StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO);
-        new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders()));
-        new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders()));
+        new CanonicalizerPhase().apply(graph, getProviders());
+        new CanonicalizerPhase().apply(graph, getProviders());
         DebugContext debug = graph.getDebug();
         debug.dump(DebugContext.BASIC_LEVEL, graph, "Graph " + snippet);
         Assert.assertFalse("shouldn't have nodes of type " + clazz, graph.getNodes().filter(clazz).iterator().hasNext());
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UnsafeReadEliminationTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UnsafeReadEliminationTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -30,11 +30,11 @@
 import org.graalvm.compiler.nodes.extended.UnsafeAccessNode;
 import org.graalvm.compiler.nodes.memory.ReadNode;
 import org.graalvm.compiler.nodes.memory.WriteNode;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
 import org.graalvm.compiler.phases.common.LoweringPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.graalvm.compiler.virtual.phases.ea.EarlyReadEliminationPhase;
 import org.graalvm.compiler.virtual.phases.ea.PartialEscapePhase;
 import org.junit.Assert;
@@ -118,7 +118,7 @@
     }
 
     public void testEarlyReadElimination(StructuredGraph graph, int reads, int writes) {
-        PhaseContext context = getDefaultHighTierContext();
+        CoreProviders context = getDefaultHighTierContext();
         CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
         canonicalizer.apply(graph, context);
         new EarlyReadEliminationPhase(canonicalizer).apply(graph, context);
@@ -133,7 +133,7 @@
 
     public void testPartialEscapeReadElimination(StructuredGraph graph, int reads, int writes) {
         OptionValues options = graph.getOptions();
-        PhaseContext context = getDefaultHighTierContext();
+        CoreProviders context = getDefaultHighTierContext();
         CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
         canonicalizer.apply(graph, context);
         new PartialEscapePhase(true, true, canonicalizer, null, options).apply(graph, context);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UnsafeVirtualizationTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UnsafeVirtualizationTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -28,9 +28,9 @@
 
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.graalvm.compiler.virtual.phases.ea.PartialEscapePhase;
 import org.junit.Test;
 
@@ -146,7 +146,7 @@
         ResolvedJavaMethod method = getResolvedJavaMethod(snippet);
         StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO);
         OptionValues options = graph.getOptions();
-        PhaseContext context = getDefaultHighTierContext();
+        CoreProviders context = getDefaultHighTierContext();
         CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
         if (canonicalizeBefore) {
             canonicalizer.apply(graph, context);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UnusedArray.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UnusedArray.java	Mon Jul 01 14:57:02 2019 -0700
@@ -31,7 +31,6 @@
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.java.NewArrayNode;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.junit.Test;
 
 public class UnusedArray extends GraalCompilerTest {
@@ -67,7 +66,7 @@
 
     public void test(String method) {
         StructuredGraph graph = parseEager(method, StructuredGraph.AllowAssumptions.YES);
-        new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders()));
+        new CanonicalizerPhase().apply(graph, getProviders());
         NodeIterable<NewArrayNode> newArrayNodes = graph.getNodes().filter(NewArrayNode.class);
         assertThat(newArrayNodes, isEmpty());
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyBailoutUsage.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyBailoutUsage.java	Mon Jul 01 14:57:02 2019 -0700
@@ -29,14 +29,14 @@
 import org.graalvm.compiler.debug.GraalError;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.phases.VerifyPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 
 import jdk.vm.ci.code.BailoutException;
 import jdk.vm.ci.meta.ResolvedJavaMethod;
 import jdk.vm.ci.meta.ResolvedJavaType;
 
-public class VerifyBailoutUsage extends VerifyPhase<PhaseContext> {
+public class VerifyBailoutUsage extends VerifyPhase<CoreProviders> {
 
     private static final String[] AllowedPackagePrefixes;
 
@@ -73,7 +73,7 @@
     }
 
     @Override
-    protected void verify(StructuredGraph graph, PhaseContext context) {
+    protected void verify(StructuredGraph graph, CoreProviders context) {
         final ResolvedJavaType bailoutType = context.getMetaAccess().lookupJavaType(BailoutException.class);
         ResolvedJavaMethod caller = graph.method();
         String holderQualified = caller.format("%H");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyBufferUsage.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.core.test;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.graalvm.compiler.core.common.type.ObjectStamp;
+import org.graalvm.compiler.nodes.NodeView;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
+import org.graalvm.compiler.phases.VerifyPhase;
+import org.graalvm.compiler.serviceprovider.BufferUtil;
+
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
+
+/**
+ * See {@link BufferUtil}.
+ */
+public class VerifyBufferUsage extends VerifyPhase<CoreProviders> {
+
+    private final Set<String> bufferTypes = new HashSet<>(Arrays.asList(
+                    "Ljava/nio/Buffer;",
+                    "Ljava/nio/ByteBuffer;",
+                    "Ljava/nio/ShortBuffer;",
+                    "Ljava/nio/CharBuffer;",
+                    "Ljava/nio/IntBuffer;",
+                    "Ljava/nio/LongBuffer;",
+                    "Ljava/nio/FloatBuffer;",
+                    "Ljava/nio/DoubleBuffer;",
+                    "Ljava/nio/MappedByteBuffer;"));
+
+    private final Set<String> bufferMethods = new HashSet<>(Arrays.asList(
+                    "position",
+                    "limit",
+                    "mark",
+                    "reset",
+                    "clear",
+                    "flip",
+                    "rewind"));
+
+    @Override
+    protected void verify(StructuredGraph graph, CoreProviders context) {
+        ResolvedJavaMethod caller = graph.method();
+        for (MethodCallTargetNode t : graph.getNodes(MethodCallTargetNode.TYPE)) {
+            ResolvedJavaMethod callee = t.targetMethod();
+            String calleeClassName = callee.getDeclaringClass().getName();
+            String calleeName = callee.getName();
+            if (bufferTypes.contains(calleeClassName) &&
+                            bufferMethods.contains(calleeName) &&
+                            !callee.getSignature().getReturnKind().isPrimitive()) {
+                StackTraceElement e = caller.asStackTraceElement(t.invoke().bci());
+                ResolvedJavaType receiverType = ((ObjectStamp) t.arguments().get(0).stamp(NodeView.DEFAULT)).type();
+                if (!receiverType.getName().equals("Ljava/nio/Buffer;")) {
+                    throw new VerificationError(
+                                    "%s: Cast receiver of type %s to java.nio.Buffer for call to %s to avoid problems with co-variant overloads added by https://bugs.openjdk.java.net/browse/JDK-4774077",
+                                    e, receiverType.toJavaName(),
+                                    callee.format("%H.%n(%p)"));
+                }
+            }
+        }
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyCallerSensitiveMethods.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyCallerSensitiveMethods.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,15 +24,14 @@
 
 package org.graalvm.compiler.core.test;
 
-import static org.graalvm.compiler.serviceprovider.JavaVersionUtil.Java8OrEarlier;
-
 import java.lang.annotation.Annotation;
 
 import org.graalvm.compiler.nodes.Invoke;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.phases.VerifyPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
+import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
 
 import jdk.vm.ci.meta.ResolvedJavaMethod;
 import jdk.vm.ci.meta.ResolvedJavaType;
@@ -40,7 +39,7 @@
 /**
  * Verifies a method is annotated with CallerSensitive iff it calls Reflection#getCallerClass().
  */
-public class VerifyCallerSensitiveMethods extends VerifyPhase<PhaseContext> {
+public class VerifyCallerSensitiveMethods extends VerifyPhase<CoreProviders> {
 
     Class<? extends Annotation> callerSensitiveClass;
     Class<?> reflectionClass;
@@ -54,7 +53,7 @@
     public VerifyCallerSensitiveMethods() {
         try {
             ClassLoader classLoader = ClassLoader.getSystemClassLoader();
-            if (Java8OrEarlier) {
+            if (JavaVersionUtil.JAVA_SPEC <= 8) {
                 reflectionClass = classLoader.loadClass("sun.reflect.Reflection");
                 callerSensitiveClass = (Class<? extends Annotation>) classLoader.loadClass("sun.reflect.ConstantPool");
             } else {
@@ -67,7 +66,7 @@
     }
 
     @Override
-    protected void verify(StructuredGraph graph, PhaseContext context) {
+    protected void verify(StructuredGraph graph, CoreProviders context) {
         Invoke invoke = callsReflectionGetCallerClass(graph, context);
         Annotation annotation = graph.method().getAnnotation(callerSensitiveClass);
         if (invoke != null) {
@@ -81,7 +80,7 @@
         }
     }
 
-    private Invoke callsReflectionGetCallerClass(StructuredGraph graph, PhaseContext context) {
+    private Invoke callsReflectionGetCallerClass(StructuredGraph graph, CoreProviders context) {
         ResolvedJavaType reflectionType = context.getMetaAccess().lookupJavaType(reflectionClass);
         for (MethodCallTargetNode t : graph.getNodes(MethodCallTargetNode.TYPE)) {
             ResolvedJavaMethod callee = t.targetMethod();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyDebugUsage.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyDebugUsage.java	Mon Jul 01 14:57:02 2019 -0700
@@ -46,8 +46,8 @@
 import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
 import org.graalvm.compiler.nodes.java.NewArrayNode;
 import org.graalvm.compiler.nodes.java.StoreIndexedNode;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.phases.VerifyPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 
 import jdk.vm.ci.meta.Constant;
 import jdk.vm.ci.meta.MetaAccessProvider;
@@ -68,7 +68,7 @@
  * {@link DebugContext#log(String)} , {@link DebugContext#dump(int, Object, String)},
  * {@link DebugContext#logAndIndent(String)} and {@link DebugContext#verify(Object, String)}.
  */
-public class VerifyDebugUsage extends VerifyPhase<PhaseContext> {
+public class VerifyDebugUsage extends VerifyPhase<CoreProviders> {
 
     @Override
     public boolean checkContract() {
@@ -78,7 +78,7 @@
     MetaAccessProvider metaAccess;
 
     @Override
-    protected void verify(StructuredGraph graph, PhaseContext context) {
+    protected void verify(StructuredGraph graph, CoreProviders context) {
         metaAccess = context.getMetaAccess();
         ResolvedJavaType debugType = metaAccess.lookupJavaType(DebugContext.class);
         ResolvedJavaType nodeType = metaAccess.lookupJavaType(Node.class);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyFoldableMethods.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyFoldableMethods.java	Mon Jul 01 14:57:02 2019 -0700
@@ -32,8 +32,8 @@
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.graphbuilderconf.GeneratedInvocationPlugin;
 import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.phases.VerifyPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 
 import jdk.vm.ci.meta.ResolvedJavaMethod;
 import jdk.vm.ci.meta.ResolvedJavaType;
@@ -41,7 +41,7 @@
 /**
  * Verifies that all {@link Fold} annotated methods have at least one caller.
  */
-public class VerifyFoldableMethods extends VerifyPhase<PhaseContext> {
+public class VerifyFoldableMethods extends VerifyPhase<CoreProviders> {
 
     @Override
     public boolean checkContract() {
@@ -52,7 +52,7 @@
     ResolvedJavaType generatedInvocationPluginType;
 
     @Override
-    protected void verify(StructuredGraph graph, PhaseContext context) {
+    protected void verify(StructuredGraph graph, CoreProviders context) {
         ResolvedJavaMethod method = graph.method();
         if (method.getAnnotation(Fold.class) != null) {
             foldables.putIfAbsent(method, false);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyGetOptionsUsage.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyGetOptionsUsage.java	Mon Jul 01 14:57:02 2019 -0700
@@ -31,8 +31,8 @@
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.phases.VerifyPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 
 import jdk.vm.ci.meta.MetaAccessProvider;
 import jdk.vm.ci.meta.ResolvedJavaMethod;
@@ -45,7 +45,7 @@
  * general but since there are several canonical methods with varying signatures this covers more
  * cases.
  */
-public class VerifyGetOptionsUsage extends VerifyPhase<PhaseContext> {
+public class VerifyGetOptionsUsage extends VerifyPhase<CoreProviders> {
     static Method lookupMethod(Class<?> klass, String name) {
         for (Method m : klass.getDeclaredMethods()) {
             if (m.getName().equals(name)) {
@@ -56,7 +56,7 @@
     }
 
     @Override
-    protected void verify(StructuredGraph graph, PhaseContext context) {
+    protected void verify(StructuredGraph graph, CoreProviders context) {
         MetaAccessProvider metaAccess = context.getMetaAccess();
         ResolvedJavaType canonicalizerToolClass = metaAccess.lookupJavaType(CanonicalizerTool.class);
         boolean hasTool = false;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyGraphAddUsage.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyGraphAddUsage.java	Mon Jul 01 14:57:02 2019 -0700
@@ -41,14 +41,14 @@
 import org.graalvm.compiler.nodes.ValueProxyNode;
 import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
 import org.graalvm.compiler.nodes.java.NewInstanceNode;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.nodes.spi.LoweringProvider;
 import org.graalvm.compiler.phases.VerifyPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 
 import jdk.vm.ci.meta.ResolvedJavaMethod;
 import jdk.vm.ci.meta.ResolvedJavaType;
 
-public class VerifyGraphAddUsage extends VerifyPhase<PhaseContext> {
+public class VerifyGraphAddUsage extends VerifyPhase<CoreProviders> {
     private static final Method ADD_OR_UNIQUE;
     private static final Method CONSTRUCTOR_NEW_INSTANCE;
     private static final EconomicSet<Class<?>> ALLOWED_CLASSES = EconomicSet.create();
@@ -66,7 +66,7 @@
     }
 
     @Override
-    protected void verify(StructuredGraph graph, PhaseContext context) {
+    protected void verify(StructuredGraph graph, CoreProviders context) {
         boolean allowed = false;
         for (Class<?> cls : ALLOWED_CLASSES) {
             ResolvedJavaType declaringClass = graph.method().getDeclaringClass();
@@ -87,7 +87,7 @@
         }
     }
 
-    private void checkNonFactory(StructuredGraph graph, EconomicSet<Node> seen, PhaseContext context, ValueNode node) {
+    private void checkNonFactory(StructuredGraph graph, EconomicSet<Node> seen, CoreProviders context, ValueNode node) {
         if (seen.contains(node)) {
             return;
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyInstanceOfUsage.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyInstanceOfUsage.java	Mon Jul 01 14:57:02 2019 -0700
@@ -29,8 +29,8 @@
 import org.graalvm.compiler.lir.StandardOp.ValueMoveOp;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.java.InstanceOfNode;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.phases.VerifyPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 
 import jdk.vm.ci.meta.MetaAccessProvider;
 import jdk.vm.ci.meta.ResolvedJavaMethod;
@@ -39,7 +39,7 @@
 /**
  * Checks that we do not use {@code instanceof} for types where faster alternatives are available.
  */
-public class VerifyInstanceOfUsage extends VerifyPhase<PhaseContext> {
+public class VerifyInstanceOfUsage extends VerifyPhase<CoreProviders> {
 
     private static final Class<?>[] FORBIDDEN_INSTANCE_OF_CHECKS = {
                     MoveOp.class,
@@ -53,7 +53,7 @@
     }
 
     @Override
-    protected void verify(StructuredGraph graph, PhaseContext context) {
+    protected void verify(StructuredGraph graph, CoreProviders context) {
         final ResolvedJavaType[] bailoutType = new ResolvedJavaType[FORBIDDEN_INSTANCE_OF_CHECKS.length];
         for (int i = 0; i < FORBIDDEN_INSTANCE_OF_CHECKS.length; i++) {
             bailoutType[i] = context.getMetaAccess().lookupJavaType(FORBIDDEN_INSTANCE_OF_CHECKS[i]);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifySystemPropertyUsage.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifySystemPropertyUsage.java	Mon Jul 01 14:57:02 2019 -0700
@@ -29,8 +29,8 @@
 
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.phases.VerifyPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 
 import jdk.vm.ci.meta.MetaAccessProvider;
 import jdk.vm.ci.meta.ResolvedJavaMethod;
@@ -43,7 +43,7 @@
  * can be modified by application code so {@link Services#getSavedProperties()} should be used
  * instead.
  */
-public class VerifySystemPropertyUsage extends VerifyPhase<PhaseContext> {
+public class VerifySystemPropertyUsage extends VerifyPhase<CoreProviders> {
 
     static final Class<?>[] BOXES = {Integer.class, Long.class, Boolean.class, Float.class, Double.class};
     static final int JVMCI_VERSION_MAJOR;
@@ -65,7 +65,7 @@
     }
 
     @Override
-    protected void verify(StructuredGraph graph, PhaseContext context) {
+    protected void verify(StructuredGraph graph, CoreProviders context) {
         MetaAccessProvider metaAccess = context.getMetaAccess();
         final ResolvedJavaType systemType = metaAccess.lookupJavaType(System.class);
         final ResolvedJavaType[] boxTypes = new ResolvedJavaType[BOXES.length];
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyUnsafeAccess.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyUnsafeAccess.java	Mon Jul 01 14:57:02 2019 -0700
@@ -33,8 +33,8 @@
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.java.InstanceOfNode;
 import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.phases.VerifyPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.graalvm.compiler.serviceprovider.GraalUnsafeAccess;
 
 import jdk.vm.ci.meta.MetaAccessProvider;
@@ -46,10 +46,10 @@
  * Checks that the {@link Unsafe} singleton instance is only accessed via well known classes such as
  * {@link GraalUnsafeAccess}.
  */
-public class VerifyUnsafeAccess extends VerifyPhase<PhaseContext> {
+public class VerifyUnsafeAccess extends VerifyPhase<CoreProviders> {
 
     @Override
-    protected void verify(StructuredGraph graph, PhaseContext context) {
+    protected void verify(StructuredGraph graph, CoreProviders context) {
         MetaAccessProvider metaAccess = context.getMetaAccess();
         final ResolvedJavaType unsafeType = metaAccess.lookupJavaType(Unsafe.class);
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyUpdateUsages.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyUpdateUsages.java	Mon Jul 01 14:57:02 2019 -0700
@@ -34,8 +34,8 @@
 import org.graalvm.compiler.nodes.java.LoadFieldNode;
 import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
 import org.graalvm.compiler.nodes.java.StoreFieldNode;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.phases.VerifyPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 
 import jdk.vm.ci.meta.ResolvedJavaField;
 import jdk.vm.ci.meta.ResolvedJavaMethod;
@@ -45,7 +45,7 @@
  * Try to ensure that methods which update {@link Input} or {@link OptionalInput} fields also
  * include a call to {@link Node#updateUsages} or {@link Node#updateUsagesInterface}.
  */
-public class VerifyUpdateUsages extends VerifyPhase<PhaseContext> {
+public class VerifyUpdateUsages extends VerifyPhase<CoreProviders> {
 
     @Override
     public boolean checkContract() {
@@ -56,7 +56,7 @@
     }
 
     @Override
-    protected void verify(StructuredGraph graph, PhaseContext context) {
+    protected void verify(StructuredGraph graph, CoreProviders context) {
         if (graph.method().isConstructor()) {
             return;
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyUsageWithEquals.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyUsageWithEquals.java	Mon Jul 01 14:57:02 2019 -0700
@@ -32,10 +32,10 @@
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.ObjectEqualsNode;
 import org.graalvm.compiler.nodes.java.LoadFieldNode;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.nodes.spi.UncheckedInterfaceProvider;
 import org.graalvm.compiler.nodes.type.StampTool;
 import org.graalvm.compiler.phases.VerifyPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 
 import jdk.vm.ci.meta.JavaField;
 import jdk.vm.ci.meta.JavaKind;
@@ -51,7 +51,7 @@
  * checks the correct usage of the given type. Equality checks with == or != (except null checks)
  * results in an {@link AssertionError}.
  */
-public class VerifyUsageWithEquals extends VerifyPhase<PhaseContext> {
+public class VerifyUsageWithEquals extends VerifyPhase<CoreProviders> {
 
     @Override
     public boolean checkContract() {
@@ -143,7 +143,7 @@
     }
 
     @Override
-    protected void verify(StructuredGraph graph, PhaseContext context) {
+    protected void verify(StructuredGraph graph, CoreProviders context) {
         for (ObjectEqualsNode cn : graph.getNodes().filter(ObjectEqualsNode.class)) {
             // bail out if we compare an object of type klass with == or != (except null checks)
             ResolvedJavaMethod method = graph.method();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyVirtualizableUsage.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifyVirtualizableUsage.java	Mon Jul 01 14:57:02 2019 -0700
@@ -34,9 +34,9 @@
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.nodes.spi.Virtualizable;
 import org.graalvm.compiler.phases.VerifyPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 
 import jdk.vm.ci.meta.ResolvedJavaMethod;
 import jdk.vm.ci.meta.ResolvedJavaType;
@@ -46,14 +46,14 @@
  * Implementors of {@link Virtualizable#virtualize(org.graalvm.compiler.nodes.spi.VirtualizerTool)}
  * must not apply effects on their {@link Graph graph} that cannot be easily undone.
  */
-public class VerifyVirtualizableUsage extends VerifyPhase<PhaseContext> {
+public class VerifyVirtualizableUsage extends VerifyPhase<CoreProviders> {
     @Override
     public boolean checkContract() {
         return false;
     }
 
     @Override
-    protected void verify(StructuredGraph graph, PhaseContext context) {
+    protected void verify(StructuredGraph graph, CoreProviders context) {
         final ResolvedJavaType graphType = context.getMetaAccess().lookupJavaType(Graph.class);
         final ResolvedJavaType virtualizableType = context.getMetaAccess().lookupJavaType(Virtualizable.class);
         final ResolvedJavaType constantNodeType = context.getMetaAccess().lookupJavaType(ConstantNode.class);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/deopt/CompiledMethodTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/deopt/CompiledMethodTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -31,7 +31,6 @@
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
 import org.graalvm.compiler.phases.common.DeadCodeEliminationPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -63,7 +62,7 @@
     public void test1() {
         final ResolvedJavaMethod javaMethod = getResolvedJavaMethod("testMethod");
         final StructuredGraph graph = parseEager(javaMethod, AllowAssumptions.NO);
-        new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders()));
+        new CanonicalizerPhase().apply(graph, getProviders());
         new DeadCodeEliminationPhase().apply(graph);
 
         for (ConstantNode node : ConstantNode.getConstantNodes(graph)) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/deopt/SynchronizedMethodDeoptimizationTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/deopt/SynchronizedMethodDeoptimizationTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,12 +24,12 @@
 
 package org.graalvm.compiler.core.test.deopt;
 
+import org.graalvm.compiler.core.test.GraalCompilerTest;
+import org.graalvm.compiler.core.test.ea.EATestBase.TestClassObject;
+import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
 import org.junit.Assume;
 import org.junit.Test;
 
-import org.graalvm.compiler.core.test.GraalCompilerTest;
-import org.graalvm.compiler.core.test.ea.EATestBase.TestClassObject;
-
 /**
  * In the following tests, we try to deoptimize out of synchronized methods.
  */
@@ -48,7 +48,7 @@
     @Test
     public void test1() {
         // https://bugs.openjdk.java.net/browse/JDK-8182755
-        Assume.assumeTrue(Java8OrEarlier);
+        Assume.assumeTrue(JavaVersionUtil.JAVA_SPEC <= 8);
 
         test("testMethodSynchronized", "test");
         test("testMethodSynchronized", (Object) null);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/PoorMansEATest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/PoorMansEATest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -33,11 +33,11 @@
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
 import org.graalvm.compiler.nodes.java.AbstractNewObjectNode;
 import org.graalvm.compiler.nodes.java.NewInstanceNode;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
 import org.graalvm.compiler.phases.common.LoweringPhase;
 import org.graalvm.compiler.phases.tiers.HighTierContext;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.junit.Test;
 
 /**
@@ -67,7 +67,7 @@
             StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO);
             HighTierContext highTierContext = getDefaultHighTierContext();
             createInliningPhase().apply(graph, highTierContext);
-            PhaseContext context = new PhaseContext(getProviders());
+            CoreProviders context = getProviders();
             new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
 
             // remove framestates in order to trigger the simplification.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/inlining/NestedLoopEffectsPhaseComplexityTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/inlining/NestedLoopEffectsPhaseComplexityTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -35,6 +35,7 @@
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
 import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.phases.BasePhase;
 import org.graalvm.compiler.phases.OptimisticOptimizations;
@@ -43,10 +44,8 @@
 import org.graalvm.compiler.phases.common.DeadCodeEliminationPhase;
 import org.graalvm.compiler.phases.common.inlining.InliningUtil;
 import org.graalvm.compiler.phases.tiers.HighTierContext;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.graalvm.compiler.virtual.phases.ea.EarlyReadEliminationPhase;
 import org.graalvm.compiler.virtual.phases.ea.PartialEscapePhase;
-
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TestRule;
@@ -124,7 +123,7 @@
         }
     }
 
-    private long runAndTimePhase(StructuredGraph g, BasePhase<? super PhaseContext> phase) {
+    private long runAndTimePhase(StructuredGraph g, BasePhase<? super CoreProviders> phase) {
         HighTierContext context = getDefaultHighTierContext();
         long start = System.currentTimeMillis();
         phase.apply(g, context);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/CompilationWrapper.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/CompilationWrapper.java	Mon Jul 01 14:57:02 2019 -0700
@@ -166,10 +166,11 @@
     /**
      * Creates the {@link DebugContext} to use when retrying a compilation.
      *
+     * @param initialDebug the debug context used in the failing compilation
      * @param options the options for configuring the debug context
      * @param logStream the log stream to use in the debug context
      */
-    protected abstract DebugContext createRetryDebugContext(OptionValues options, PrintStream logStream);
+    protected abstract DebugContext createRetryDebugContext(DebugContext initialDebug, OptionValues options, PrintStream logStream);
 
     @SuppressWarnings("try")
     public final T run(DebugContext initialDebug) {
@@ -277,7 +278,7 @@
 
                 ByteArrayOutputStream logBaos = new ByteArrayOutputStream();
                 PrintStream ps = new PrintStream(logBaos);
-                try (DebugContext retryDebug = createRetryDebugContext(retryOptions, ps)) {
+                try (DebugContext retryDebug = createRetryDebugContext(initialDebug, retryOptions, ps)) {
                     T res = performCompilation(retryDebug);
                     ps.println("There was no exception during retry.");
                     maybeExitVM(action);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalCompilerOptions.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalCompilerOptions.java	Mon Jul 01 14:57:02 2019 -0700
@@ -28,6 +28,7 @@
 import org.graalvm.compiler.options.EnumOptionKey;
 import org.graalvm.compiler.options.Option;
 import org.graalvm.compiler.options.OptionKey;
+import org.graalvm.compiler.options.OptionStability;
 import org.graalvm.compiler.options.OptionType;
 
 /**
@@ -36,7 +37,7 @@
 public class GraalCompilerOptions {
 
     // @formatter:off
-    @Option(help = "Print an informational line to the console for each completed compilation.", type = OptionType.Debug)
+    @Option(help = "Print an informational line to the console for each completed compilation.", type = OptionType.Debug, stability = OptionStability.STABLE)
     public static final OptionKey<Boolean> PrintCompilation = new OptionKey<>(false);
     @Option(help = "Pattern for method(s) that will trigger an exception when compiled. " +
                    "This option exists to test handling compilation crashes gracefully. " +
@@ -44,9 +45,9 @@
                    "suffix will raise a bailout exception and a ':PermanentBailout' " +
                    "suffix will raise a permanent bailout exception.", type = OptionType.Debug)
     public static final OptionKey<String> CrashAt = new OptionKey<>(null);
-    @Option(help = "Treat compilation bailouts like compilation failures.", type = OptionType.User)
+    @Option(help = "Treat compilation bailouts like compilation failures.", type = OptionType.User, stability = OptionStability.STABLE)
     public static final OptionKey<Boolean> CompilationBailoutAsFailure = new OptionKey<>(false);
-    @Option(help = "file:doc-files/CompilationFailureActionHelp.txt", type = OptionType.User)
+    @Option(help = "file:doc-files/CompilationFailureActionHelp.txt", type = OptionType.User, stability = OptionStability.STABLE)
     public static final EnumOptionKey<ExceptionAction> CompilationFailureAction = new EnumOptionKey<>(ExceptionAction.Silent);
     @Option(help = "The maximum number of compilation failures to handle with the action specified " +
                    "by CompilationFailureAction before changing to a less verbose action. " +
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalServiceThread.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.core;
+
+/**
+ * This is a utility class for Threads started by the compiler itself. In certain execution
+ * environments extra work must be done for these threads to execute correctly and this class
+ * provides hooks for this work.
+ */
+public class GraalServiceThread extends Thread {
+    private final Runnable runnable;
+
+    public GraalServiceThread(Runnable runnable) {
+        super();
+        this.runnable = runnable;
+    }
+
+    @Override
+    public final void run() {
+        beforeRun();
+        try {
+            runnable.run();
+        } finally {
+            afterRun();
+        }
+    }
+
+    /**
+     * Substituted by {@code com.oracle.svm.graal.hotspot.libgraal.
+     * Target_org_graalvm_compiler_truffle_common_TruffleCompilerRuntimeInstance} to attach to the
+     * peer runtime if required.
+     */
+    private void afterRun() {
+    }
+
+    /**
+     * Substituted by {@code com.oracle.svm.graal.hotspot.libgraal.
+     * Target_org_graalvm_compiler_truffle_common_TruffleCompilerRuntimeInstance} to attach to the
+     * peer runtime if required.
+     */
+    private void beforeRun() {
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/LIRCompilerBackend.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/LIRCompilerBackend.java	Mon Jul 01 14:57:02 2019 -0700
@@ -124,7 +124,11 @@
     }
 
     @SuppressWarnings("try")
-    private static LIRGenerationResult emitLIR0(Backend backend, StructuredGraph graph, Object stub, RegisterConfig registerConfig, LIRSuites lirSuites,
+    private static LIRGenerationResult emitLIR0(Backend backend,
+                    StructuredGraph graph,
+                    Object stub,
+                    RegisterConfig registerConfig,
+                    LIRSuites lirSuites,
                     String[] allocationRestrictedTo) {
         DebugContext debug = graph.getDebug();
         try (DebugContext.Scope ds = debug.scope("EmitLIR"); DebugCloseable a = EmitLIR.start(debug)) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/LIRGenerationProvider.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/LIRGenerationProvider.java	Mon Jul 01 14:57:02 2019 -0700
@@ -44,7 +44,10 @@
 public interface LIRGenerationProvider {
     LIRGeneratorTool newLIRGenerator(LIRGenerationResult lirGenRes);
 
-    LIRGenerationResult newLIRGenerationResult(CompilationIdentifier compilationId, LIR lir, RegisterConfig registerConfig, StructuredGraph graph,
+    LIRGenerationResult newLIRGenerationResult(CompilationIdentifier compilationId,
+                    LIR lir,
+                    RegisterConfig registerConfig,
+                    StructuredGraph graph,
                     Object stub);
 
     NodeLIRBuilderTool newNodeLIRBuilder(StructuredGraph graph, LIRGeneratorTool lirGen);
@@ -52,7 +55,9 @@
     /**
      * Creates the object used to fill in the details of a given compilation result.
      */
-    CompilationResultBuilder newCompilationResultBuilder(LIRGenerationResult lirGenResult, FrameMap frameMap, CompilationResult compilationResult,
+    CompilationResultBuilder newCompilationResultBuilder(LIRGenerationResult lirGenResult,
+                    FrameMap frameMap,
+                    CompilationResult compilationResult,
                     CompilationResultBuilderFactory factory);
 
     /**
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/EconomyLowTier.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/EconomyLowTier.java	Mon Jul 01 14:57:02 2019 -0700
@@ -47,6 +47,6 @@
 
         appendPhase(new ExpandLogicPhase());
 
-        appendPhase(new SchedulePhase(SchedulePhase.SchedulingStrategy.FINAL_SCHEDULE));
+        appendPhase(new SchedulePhase(SchedulePhase.SchedulingStrategy.LATEST_OUT_OF_LOOPS));
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/EconomyMidTier.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/EconomyMidTier.java	Mon Jul 01 14:57:02 2019 -0700
@@ -35,6 +35,7 @@
 import org.graalvm.compiler.phases.common.LoopSafepointInsertionPhase;
 import org.graalvm.compiler.phases.common.LoweringPhase;
 import org.graalvm.compiler.phases.common.RemoveValueProxyPhase;
+import org.graalvm.compiler.phases.common.WriteBarrierAdditionPhase;
 import org.graalvm.compiler.phases.tiers.MidTierContext;
 
 public class EconomyMidTier extends PhaseSuite<MidTierContext> {
@@ -53,5 +54,7 @@
         appendPhase(new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.MID_TIER));
 
         appendPhase(new FrameStateAssignmentPhase());
+
+        appendPhase(new WriteBarrierAdditionPhase());
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/GraphChangeMonitoringPhase.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/GraphChangeMonitoringPhase.java	Mon Jul 01 14:57:02 2019 -0700
@@ -32,10 +32,10 @@
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.nodes.LogicConstantNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.phases.BasePhase;
 import org.graalvm.compiler.phases.PhaseSuite;
 import org.graalvm.compiler.phases.common.util.EconomicSetNodeEventListener;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 
 /**
  * A utility phase for detecting when a phase would change the graph and reporting extra information
@@ -46,7 +46,7 @@
  *
  * @param <C>
  */
-public class GraphChangeMonitoringPhase<C extends PhaseContext> extends PhaseSuite<C> {
+public class GraphChangeMonitoringPhase<C extends CoreProviders> extends PhaseSuite<C> {
 
     private final String message;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/HighTier.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/HighTier.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,7 +25,6 @@
 package org.graalvm.compiler.core.phases;
 
 import static org.graalvm.compiler.core.common.GraalOptions.ConditionalElimination;
-import static org.graalvm.compiler.core.common.GraalOptions.FullUnroll;
 import static org.graalvm.compiler.core.common.GraalOptions.ImmutableCode;
 import static org.graalvm.compiler.core.common.GraalOptions.LoopPeeling;
 import static org.graalvm.compiler.core.common.GraalOptions.LoopUnswitch;
@@ -100,21 +99,17 @@
         }
 
         LoopPolicies loopPolicies = createLoopPolicies();
-        if (FullUnroll.getValue(options)) {
-            appendPhase(new LoopFullUnrollPhase(canonicalizer, loopPolicies));
-        }
+        appendPhase(new LoopFullUnrollPhase(canonicalizer, loopPolicies));
 
         if (OptLoopTransform.getValue(options)) {
             if (LoopPeeling.getValue(options)) {
-                appendPhase(new LoopPeelingPhase(loopPolicies));
+                appendPhase(new IncrementalCanonicalizerPhase<>(canonicalizer, new LoopPeelingPhase(loopPolicies)));
             }
             if (LoopUnswitch.getValue(options)) {
-                appendPhase(new LoopUnswitchingPhase(loopPolicies));
+                appendPhase(new IncrementalCanonicalizerPhase<>(canonicalizer, new LoopUnswitchingPhase(loopPolicies)));
             }
         }
 
-        appendPhase(canonicalizer);
-
         if (PartialEscapeAnalysis.getValue(options)) {
             appendPhase(new PartialEscapePhase(true, canonicalizer, options));
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/LowTier.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/LowTier.java	Mon Jul 01 14:57:02 2019 -0700
@@ -77,7 +77,8 @@
 
         appendPhase(new ExpandLogicPhase());
 
-        appendPhase(new FixReadsPhase(true, new SchedulePhase(GraalOptions.StressTestEarlyReads.getValue(options) ? SchedulingStrategy.EARLIEST : SchedulingStrategy.LATEST_OUT_OF_LOOPS)));
+        appendPhase(new FixReadsPhase(true,
+                        new SchedulePhase(GraalOptions.StressTestEarlyReads.getValue(options) ? SchedulingStrategy.EARLIEST : SchedulingStrategy.LATEST_OUT_OF_LOOPS_IMPLICIT_NULL_CHECKS)));
 
         appendPhase(canonicalizerWithoutGVN);
 
@@ -87,6 +88,6 @@
 
         appendPhase(new PropagateDeoptimizeProbabilityPhase());
 
-        appendPhase(new SchedulePhase(SchedulePhase.SchedulingStrategy.FINAL_SCHEDULE));
+        appendPhase(new SchedulePhase(SchedulePhase.SchedulingStrategy.LATEST_OUT_OF_LOOPS));
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/MidTier.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/phases/MidTier.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,9 +24,6 @@
 
 package org.graalvm.compiler.core.phases;
 
-import static org.graalvm.compiler.core.common.SpeculativeExecutionAttacksMitigations.GuardTargets;
-import static org.graalvm.compiler.core.common.SpeculativeExecutionAttacksMitigations.NonDeoptGuardTargets;
-import static org.graalvm.compiler.core.common.SpeculativeExecutionAttacksMitigations.Options.MitigateSpeculativeExecutionAttacks;
 import static org.graalvm.compiler.core.common.GraalOptions.ConditionalElimination;
 import static org.graalvm.compiler.core.common.GraalOptions.ImmutableCode;
 import static org.graalvm.compiler.core.common.GraalOptions.OptDeoptimizationGrouping;
@@ -35,6 +32,9 @@
 import static org.graalvm.compiler.core.common.GraalOptions.PartialUnroll;
 import static org.graalvm.compiler.core.common.GraalOptions.ReassociateInvariants;
 import static org.graalvm.compiler.core.common.GraalOptions.VerifyHeapAtReturn;
+import static org.graalvm.compiler.core.common.SpeculativeExecutionAttacksMitigations.GuardTargets;
+import static org.graalvm.compiler.core.common.SpeculativeExecutionAttacksMitigations.NonDeoptGuardTargets;
+import static org.graalvm.compiler.core.common.SpeculativeExecutionAttacksMitigations.Options.MitigateSpeculativeExecutionAttacks;
 
 import org.graalvm.compiler.loop.DefaultLoopPolicies;
 import org.graalvm.compiler.loop.LoopPolicies;
@@ -56,6 +56,7 @@
 import org.graalvm.compiler.phases.common.LoopSafepointInsertionPhase;
 import org.graalvm.compiler.phases.common.LoweringPhase;
 import org.graalvm.compiler.phases.common.VerifyHeapAtReturnPhase;
+import org.graalvm.compiler.phases.common.WriteBarrierAdditionPhase;
 import org.graalvm.compiler.phases.tiers.MidTierContext;
 
 public class MidTier extends PhaseSuite<MidTierContext> {
@@ -109,6 +110,8 @@
         }
 
         appendPhase(canonicalizer);
+
+        appendPhase(new WriteBarrierAdditionPhase());
     }
 
     public LoopPolicies createLoopPolicies() {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugOptions.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/DebugOptions.java	Mon Jul 01 14:57:02 2019 -0700
@@ -28,11 +28,14 @@
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
+import java.text.SimpleDateFormat;
+import java.util.Date;
 
 import jdk.internal.vm.compiler.collections.EconomicMap;
 import org.graalvm.compiler.options.EnumOptionKey;
 import org.graalvm.compiler.options.Option;
 import org.graalvm.compiler.options.OptionKey;
+import org.graalvm.compiler.options.OptionStability;
 import org.graalvm.compiler.options.OptionType;
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.serviceprovider.GraalServices;
@@ -92,12 +95,12 @@
     @Option(help = "Pattern for specifying scopes in which logging is enabled. " +
                    "See the Dump option for the pattern syntax.", type = OptionType.Debug)
     public static final OptionKey<String> Verify = new OptionKey<>(null);
-    @Option(help = "file:doc-files/DumpHelp.txt", type = OptionType.Debug)
+    @Option(help = "file:doc-files/DumpHelp.txt", type = OptionType.Debug, stability = OptionStability.STABLE)
     public static final OptionKey<String> Dump = new OptionKey<>(null);
     @Option(help = "Pattern for specifying scopes in which logging is enabled. " +
                    "See the Dump option for the pattern syntax.", type = OptionType.Debug)
     public static final OptionKey<String> Log = new OptionKey<>(null);
-    @Option(help = "file:doc-files/MethodFilterHelp.txt")
+    @Option(help = "file:doc-files/MethodFilterHelp.txt", stability = OptionStability.STABLE)
     public static final OptionKey<String> MethodFilter = new OptionKey<>(null);
     @Option(help = "Only check MethodFilter against the root method in the context if true, otherwise check all methods", type = OptionType.Debug)
     public static final OptionKey<Boolean> MethodFilterRootOnly = new OptionKey<>(false);
@@ -119,7 +122,7 @@
     public static final OptionKey<String> MetricsThreadFilter = new OptionKey<>(null);
     @Option(help = "Enable debug output for stub code generation and snippet preparation.", type = OptionType.Debug)
     public static final OptionKey<Boolean> DebugStubsAndSnippets = new OptionKey<>(false);
-    @Option(help = "Send Graal compiler IR to dump handlers on error.", type = OptionType.Debug)
+    @Option(help = "Send compiler IR to dump handlers on error.", type = OptionType.Debug)
     public static final OptionKey<Boolean> DumpOnError = new OptionKey<>(false);
     @Option(help = "Intercept also bailout exceptions", type = OptionType.Debug)
     public static final OptionKey<Boolean> InterceptBailout = new OptionKey<>(false);
@@ -203,7 +206,9 @@
         if (DumpPath.hasBeenSet(options)) {
             dumpDir = Paths.get(DumpPath.getValue(options));
         } else {
-            dumpDir = Paths.get(DumpPath.getValue(options), String.valueOf(GraalServices.getGlobalTimeStamp()));
+            Date date = new Date(GraalServices.getGlobalTimeStamp());
+            SimpleDateFormat formatter = new SimpleDateFormat( "YYYY.MM.dd.HH.mm.ss.SSS" );
+            dumpDir = Paths.get(DumpPath.getValue(options), formatter.format(date));
         }
         dumpDir = dumpDir.toAbsolutePath();
         if (!Files.exists(dumpDir)) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/TTY.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/TTY.java	Mon Jul 01 14:57:02 2019 -0700
@@ -118,6 +118,7 @@
 
     /**
      * The {@link PrintStream} to which all non-suppressed output from {@link TTY} is written.
+     * Substituted by {@code com.oracle.svm.graal.Target_org_graalvm_compiler_debug_TTY}.
      */
     public static final PrintStream out;
     static {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Graph.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Graph.java	Mon Jul 01 14:57:02 2019 -0700
@@ -642,30 +642,6 @@
         }
 
         @Override
-        public void nodeAdded(Node node) {
-            head.event(NodeEvent.NODE_ADDED, node);
-            next.event(NodeEvent.NODE_ADDED, node);
-        }
-
-        @Override
-        public void inputChanged(Node node) {
-            head.event(NodeEvent.INPUT_CHANGED, node);
-            next.event(NodeEvent.INPUT_CHANGED, node);
-        }
-
-        @Override
-        public void usagesDroppedToZero(Node node) {
-            head.event(NodeEvent.ZERO_USAGES, node);
-            next.event(NodeEvent.ZERO_USAGES, node);
-        }
-
-        @Override
-        public void nodeRemoved(Node node) {
-            head.event(NodeEvent.NODE_REMOVED, node);
-            next.event(NodeEvent.NODE_REMOVED, node);
-        }
-
-        @Override
         public void changed(NodeEvent e, Node node) {
             head.event(e, node);
             next.event(e, node);
@@ -1151,7 +1127,7 @@
         nodesDeletedSinceLastCompression++;
 
         if (nodeEventListener != null) {
-            nodeEventListener.event(NodeEvent.NODE_ADDED, node);
+            nodeEventListener.event(NodeEvent.NODE_REMOVED, node);
         }
 
         // nodes aren't removed from the type cache here - they will be removed during iteration
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Node.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/Node.java	Mon Jul 01 14:57:02 2019 -0700
@@ -613,6 +613,7 @@
                 assert assertTrue(newSuccessor.predecessor == null, "unexpected non-null predecessor in new successor (%s): %s, this=%s", newSuccessor, newSuccessor.predecessor, this);
                 newSuccessor.predecessor = this;
             }
+            maybeNotifyInputChanged(this);
         }
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackendFactory.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackendFactory.java	Mon Jul 01 14:57:02 2019 -0700
@@ -31,7 +31,6 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
 import org.graalvm.compiler.bytecode.BytecodeProvider;
 import org.graalvm.compiler.core.aarch64.AArch64AddressLoweringByUse;
 import org.graalvm.compiler.core.aarch64.AArch64LIRKindTool;
@@ -44,6 +43,7 @@
 import org.graalvm.compiler.hotspot.meta.AddressLoweringHotSpotSuitesProvider;
 import org.graalvm.compiler.hotspot.meta.HotSpotConstantFieldProvider;
 import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProvider;
+import org.graalvm.compiler.hotspot.meta.HotSpotGCProvider;
 import org.graalvm.compiler.hotspot.meta.HotSpotGraalConstantFieldProvider;
 import org.graalvm.compiler.hotspot.meta.HotSpotGraphBuilderPlugins;
 import org.graalvm.compiler.hotspot.meta.HotSpotHostForeignCallsProvider;
@@ -64,7 +64,6 @@
 import org.graalvm.compiler.phases.tiers.CompilerConfiguration;
 import org.graalvm.compiler.phases.util.Providers;
 import org.graalvm.compiler.replacements.aarch64.AArch64GraphBuilderPlugins;
-import org.graalvm.compiler.replacements.classfile.ClassfileBytecodeProvider;
 import org.graalvm.compiler.serviceprovider.ServiceProvider;
 import org.graalvm.compiler.word.WordTypes;
 
@@ -83,7 +82,7 @@
 import jdk.vm.ci.runtime.JVMCIBackend;
 
 @ServiceProvider(HotSpotBackendFactory.class)
-public class AArch64HotSpotBackendFactory implements HotSpotBackendFactory {
+public class AArch64HotSpotBackendFactory extends HotSpotBackendFactory {
 
     @Override
     public String getName() {
@@ -112,6 +111,8 @@
         HotSpotConstantReflectionProvider constantReflection = (HotSpotConstantReflectionProvider) jvmci.getConstantReflection();
         HotSpotConstantFieldProvider constantFieldProvider = new HotSpotGraalConstantFieldProvider(config, metaAccess);
         HotSpotLoweringProvider lowerer;
+        HotSpotStampProvider stampProvider;
+        HotSpotGCProvider gc;
         HotSpotSnippetReflectionProvider snippetReflection;
         HotSpotReplacementsImpl replacements;
         HotSpotSuitesProvider suites;
@@ -126,7 +127,7 @@
                 nativeABICallerSaveRegisters = createNativeABICallerSaveRegisters(config, codeCache.getRegisterConfig());
             }
             try (InitTimer rt = timer("create WordTypes")) {
-                wordTypes = new HotSpotWordTypes(metaAccess, target.wordJavaKind);
+                wordTypes = createWordTypes(metaAccess, target);
             }
             try (InitTimer rt = timer("create ForeignCalls provider")) {
                 foreignCalls = createForeignCalls(jvmciRuntime, graalRuntime, metaAccess, codeCache, wordTypes, nativeABICallerSaveRegisters);
@@ -134,17 +135,23 @@
             try (InitTimer rt = timer("create Lowerer provider")) {
                 lowerer = createLowerer(graalRuntime, metaAccess, foreignCalls, registers, constantReflection, target);
             }
-            HotSpotStampProvider stampProvider = new HotSpotStampProvider();
-            Providers p = new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, null, stampProvider);
+            try (InitTimer rt = timer("create stamp provider")) {
+                stampProvider = createStampProvider();
+            }
+            try (InitTimer rt = timer("create GC provider")) {
+                gc = createGCProvider(config);
+            }
+
+            Providers p = new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, null, stampProvider, gc);
 
             try (InitTimer rt = timer("create SnippetReflection provider")) {
                 snippetReflection = createSnippetReflection(graalRuntime, constantReflection, wordTypes);
             }
             try (InitTimer rt = timer("create Bytecode provider")) {
-                bytecodeProvider = new ClassfileBytecodeProvider(metaAccess, snippetReflection);
+                bytecodeProvider = createBytecodeProvider(metaAccess, snippetReflection);
             }
             try (InitTimer rt = timer("create Replacements provider")) {
-                replacements = createReplacements(p, snippetReflection, bytecodeProvider);
+                replacements = createReplacements(target, p, snippetReflection, bytecodeProvider);
             }
             try (InitTimer rt = timer("create GraphBuilderPhase plugins")) {
                 plugins = createGraphBuilderPlugins(compilerConfiguration, config, constantReflection, foreignCalls, metaAccess, snippetReflection, replacements, wordTypes, graalRuntime.getOptions());
@@ -154,8 +161,7 @@
                 suites = createSuites(config, graalRuntime, compilerConfiguration, plugins, replacements);
             }
             providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, suites, registers,
-                            snippetReflection, wordTypes,
-                            plugins);
+                            snippetReflection, wordTypes, plugins, gc);
             replacements.setProviders(providers);
         }
         try (InitTimer rt = timer("instantiate backend")) {
@@ -180,10 +186,6 @@
         return new HotSpotRegisters(AArch64HotSpotRegisterConfig.threadRegister, AArch64HotSpotRegisterConfig.heapBaseRegister, sp);
     }
 
-    protected HotSpotReplacementsImpl createReplacements(Providers p, SnippetReflectionProvider snippetReflection, BytecodeProvider bytecodeProvider) {
-        return new HotSpotReplacementsImpl(p, snippetReflection, bytecodeProvider, p.getCodeCache().getTarget());
-    }
-
     protected HotSpotHostForeignCallsProvider createForeignCalls(HotSpotJVMCIRuntime jvmciRuntime, HotSpotGraalRuntimeProvider runtime, HotSpotMetaAccessProvider metaAccess,
                     HotSpotCodeCacheProvider codeCache, WordTypes wordTypes, Value[] nativeABICallerSaveRegisters) {
         return new AArch64HotSpotForeignCallsProvider(jvmciRuntime, runtime, metaAccess, codeCache, wordTypes, nativeABICallerSaveRegisters);
@@ -196,10 +198,6 @@
         return new AddressLoweringHotSpotSuitesProvider(suitesCreator, config, runtime, addressLoweringPhase);
     }
 
-    protected HotSpotSnippetReflectionProvider createSnippetReflection(HotSpotGraalRuntimeProvider runtime, HotSpotConstantReflectionProvider constantReflection, WordTypes wordTypes) {
-        return new HotSpotSnippetReflectionProvider(runtime, constantReflection, wordTypes);
-    }
-
     protected HotSpotLoweringProvider createLowerer(HotSpotGraalRuntimeProvider runtime, HotSpotMetaAccessProvider metaAccess, HotSpotForeignCallsProvider foreignCalls,
                     HotSpotRegistersProvider registers, HotSpotConstantReflectionProvider constantReflection, TargetDescription target) {
         return new AArch64HotSpotLoweringProvider(runtime, metaAccess, foreignCalls, registers, constantReflection, target);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotJumpToExceptionHandlerInCallerOp.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotJumpToExceptionHandlerInCallerOp.java	Mon Jul 01 14:57:02 2019 -0700
@@ -71,7 +71,7 @@
     public void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) {
         leaveFrame(crb, masm, /* emitSafepoint */false, false);
 
-        if (JavaVersionUtil.JAVA_SPECIFICATION_VERSION < 8) {
+        if (JavaVersionUtil.JAVA_SPEC < 8) {
             // Restore sp from fp if the exception PC is a method handle call site.
             try (ScratchRegister sc = masm.getScratchRegister()) {
                 Register scratch = sc.getRegister();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64ArrayIndexOfStub.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64ArrayIndexOfStub.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,7 +24,6 @@
 
 package org.graalvm.compiler.hotspot.amd64;
 
-import jdk.vm.ci.meta.JavaKind;
 import org.graalvm.compiler.api.replacements.Snippet;
 import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
 import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage;
@@ -32,7 +31,6 @@
 import org.graalvm.compiler.hotspot.stubs.SnippetStub;
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.replacements.amd64.AMD64ArrayIndexOfNode;
-import jdk.internal.vm.compiler.word.Pointer;
 
 public class AMD64ArrayIndexOfStub extends SnippetStub {
 
@@ -41,52 +39,77 @@
     }
 
     @Snippet
-    private static int indexOfTwoConsecutiveBytes(Pointer arrayPointer, int arrayLength, int searchValue) {
-        return AMD64ArrayIndexOfNode.optimizedArrayIndexOf(JavaKind.Byte, true, arrayPointer, arrayLength, searchValue);
+    private static int indexOfTwoConsecutiveBytes(byte[] array, int arrayLength, int fromIndex, int searchValue) {
+        return AMD64ArrayIndexOfNode.indexOf2ConsecutiveBytes(array, arrayLength, fromIndex, searchValue);
     }
 
     @Snippet
-    private static int indexOfTwoConsecutiveChars(Pointer arrayPointer, int arrayLength, int searchValue) {
-        return AMD64ArrayIndexOfNode.optimizedArrayIndexOf(JavaKind.Char, true, arrayPointer, arrayLength, searchValue);
+    private static int indexOfTwoConsecutiveChars(char[] array, int arrayLength, int fromIndex, int searchValue) {
+        return AMD64ArrayIndexOfNode.indexOf2ConsecutiveChars(array, arrayLength, fromIndex, searchValue);
+    }
+
+    @Snippet
+    private static int indexOfTwoConsecutiveCharsCompact(byte[] array, int arrayLength, int fromIndex, int searchValue) {
+        return AMD64ArrayIndexOfNode.indexOf2ConsecutiveChars(array, arrayLength, fromIndex, searchValue);
     }
 
     @Snippet
-    private static int indexOf1Byte(Pointer arrayPointer, int arrayLength, byte b) {
-        return AMD64ArrayIndexOfNode.optimizedArrayIndexOf(JavaKind.Byte, arrayPointer, arrayLength, b);
+    private static int indexOf1Byte(byte[] array, int arrayLength, int fromIndex, byte b) {
+        return AMD64ArrayIndexOfNode.indexOf(array, arrayLength, fromIndex, b);
     }
 
     @Snippet
-    private static int indexOf2Bytes(Pointer arrayPointer, int arrayLength, byte b1, byte b2) {
-        return AMD64ArrayIndexOfNode.optimizedArrayIndexOf(JavaKind.Byte, arrayPointer, arrayLength, b1, b2);
+    private static int indexOf2Bytes(byte[] array, int arrayLength, int fromIndex, byte b1, byte b2) {
+        return AMD64ArrayIndexOfNode.indexOf(array, arrayLength, fromIndex, b1, b2);
     }
 
     @Snippet
-    private static int indexOf3Bytes(Pointer arrayPointer, int arrayLength, byte b1, byte b2, byte b3) {
-        return AMD64ArrayIndexOfNode.optimizedArrayIndexOf(JavaKind.Byte, arrayPointer, arrayLength, b1, b2, b3);
+    private static int indexOf3Bytes(byte[] array, int arrayLength, int fromIndex, byte b1, byte b2, byte b3) {
+        return AMD64ArrayIndexOfNode.indexOf(array, arrayLength, fromIndex, b1, b2, b3);
+    }
+
+    @Snippet
+    private static int indexOf4Bytes(byte[] array, int arrayLength, int fromIndex, byte b1, byte b2, byte b3, byte b4) {
+        return AMD64ArrayIndexOfNode.indexOf(array, arrayLength, fromIndex, b1, b2, b3, b4);
     }
 
     @Snippet
-    private static int indexOf4Bytes(Pointer arrayPointer, int arrayLength, byte b1, byte b2, byte b3, byte b4) {
-        return AMD64ArrayIndexOfNode.optimizedArrayIndexOf(JavaKind.Byte, arrayPointer, arrayLength, b1, b2, b3, b4);
+    private static int indexOf1Char(char[] array, int arrayLength, int fromIndex, char c) {
+        return AMD64ArrayIndexOfNode.indexOf(array, arrayLength, fromIndex, c);
     }
 
     @Snippet
-    private static int indexOf1Char(Pointer arrayPointer, int arrayLength, char c) {
-        return AMD64ArrayIndexOfNode.optimizedArrayIndexOf(JavaKind.Char, arrayPointer, arrayLength, c);
+    private static int indexOf2Chars(char[] array, int arrayLength, int fromIndex, char c1, char c2) {
+        return AMD64ArrayIndexOfNode.indexOf(array, arrayLength, fromIndex, c1, c2);
+    }
+
+    @Snippet
+    private static int indexOf3Chars(char[] array, int arrayLength, int fromIndex, char c1, char c2, char c3) {
+        return AMD64ArrayIndexOfNode.indexOf(array, arrayLength, fromIndex, c1, c2, c3);
+    }
+
+    @Snippet
+    private static int indexOf4Chars(char[] array, int arrayLength, int fromIndex, char c1, char c2, char c3, char c4) {
+        return AMD64ArrayIndexOfNode.indexOf(array, arrayLength, fromIndex, c1, c2, c3, c4);
     }
 
     @Snippet
-    private static int indexOf2Chars(Pointer arrayPointer, int arrayLength, char c1, char c2) {
-        return AMD64ArrayIndexOfNode.optimizedArrayIndexOf(JavaKind.Char, arrayPointer, arrayLength, c1, c2);
+    private static int indexOf1CharCompact(byte[] array, int arrayLength, int fromIndex, char c) {
+        return AMD64ArrayIndexOfNode.indexOf(array, arrayLength, fromIndex, c);
+    }
+
+    @Snippet
+    private static int indexOf2CharsCompact(byte[] array, int arrayLength, int fromIndex, char c1, char c2) {
+        return AMD64ArrayIndexOfNode.indexOf(array, arrayLength, fromIndex, c1, c2);
     }
 
     @Snippet
-    private static int indexOf3Chars(Pointer arrayPointer, int arrayLength, char c1, char c2, char c3) {
-        return AMD64ArrayIndexOfNode.optimizedArrayIndexOf(JavaKind.Char, arrayPointer, arrayLength, c1, c2, c3);
+    private static int indexOf3CharsCompact(byte[] array, int arrayLength, int fromIndex, char c1, char c2, char c3) {
+        return AMD64ArrayIndexOfNode.indexOf(array, arrayLength, fromIndex, c1, c2, c3);
     }
 
     @Snippet
-    private static int indexOf4Chars(Pointer arrayPointer, int arrayLength, char c1, char c2, char c3, char c4) {
-        return AMD64ArrayIndexOfNode.optimizedArrayIndexOf(JavaKind.Char, arrayPointer, arrayLength, c1, c2, c3, c4);
+    private static int indexOf4CharsCompact(byte[] array, int arrayLength, int fromIndex, char c1, char c2, char c3, char c4) {
+        return AMD64ArrayIndexOfNode.indexOf(array, arrayLength, fromIndex, c1, c2, c3, c4);
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackendFactory.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackendFactory.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,12 +25,10 @@
 package org.graalvm.compiler.hotspot.amd64;
 
 import static jdk.vm.ci.common.InitTimer.timer;
-import static org.graalvm.compiler.serviceprovider.JavaVersionUtil.JAVA_SPECIFICATION_VERSION;
 
 import java.util.ArrayList;
 import java.util.List;
 
-import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
 import org.graalvm.compiler.bytecode.BytecodeProvider;
 import org.graalvm.compiler.core.common.spi.ConstantFieldProvider;
 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
@@ -40,6 +38,7 @@
 import org.graalvm.compiler.hotspot.HotSpotReplacementsImpl;
 import org.graalvm.compiler.hotspot.meta.AddressLoweringHotSpotSuitesProvider;
 import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProvider;
+import org.graalvm.compiler.hotspot.meta.HotSpotGCProvider;
 import org.graalvm.compiler.hotspot.meta.HotSpotGraalConstantFieldProvider;
 import org.graalvm.compiler.hotspot.meta.HotSpotGraphBuilderPlugins;
 import org.graalvm.compiler.hotspot.meta.HotSpotHostForeignCallsProvider;
@@ -58,7 +57,7 @@
 import org.graalvm.compiler.phases.tiers.CompilerConfiguration;
 import org.graalvm.compiler.phases.util.Providers;
 import org.graalvm.compiler.replacements.amd64.AMD64GraphBuilderPlugins;
-import org.graalvm.compiler.replacements.classfile.ClassfileBytecodeProvider;
+import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
 import org.graalvm.compiler.serviceprovider.ServiceProvider;
 import org.graalvm.compiler.word.WordTypes;
 
@@ -76,7 +75,7 @@
 import jdk.vm.ci.runtime.JVMCIBackend;
 
 @ServiceProvider(HotSpotBackendFactory.class)
-public class AMD64HotSpotBackendFactory implements HotSpotBackendFactory {
+public class AMD64HotSpotBackendFactory extends HotSpotBackendFactory {
 
     @Override
     public String getName() {
@@ -106,6 +105,8 @@
         HotSpotConstantReflectionProvider constantReflection = (HotSpotConstantReflectionProvider) jvmci.getConstantReflection();
         ConstantFieldProvider constantFieldProvider = new HotSpotGraalConstantFieldProvider(config, metaAccess);
         HotSpotLoweringProvider lowerer;
+        HotSpotStampProvider stampProvider;
+        HotSpotGCProvider gc;
         HotSpotSnippetReflectionProvider snippetReflection;
         HotSpotReplacementsImpl replacements;
         HotSpotSuitesProvider suites;
@@ -120,7 +121,7 @@
                 nativeABICallerSaveRegisters = createNativeABICallerSaveRegisters(config, codeCache.getRegisterConfig());
             }
             try (InitTimer rt = timer("create WordTypes")) {
-                wordTypes = new HotSpotWordTypes(metaAccess, target.wordJavaKind);
+                wordTypes = createWordTypes(metaAccess, target);
             }
             try (InitTimer rt = timer("create ForeignCalls provider")) {
                 foreignCalls = createForeignCalls(jvmciRuntime, graalRuntime, metaAccess, codeCache, wordTypes, nativeABICallerSaveRegisters);
@@ -128,17 +129,23 @@
             try (InitTimer rt = timer("create Lowerer provider")) {
                 lowerer = createLowerer(graalRuntime, metaAccess, foreignCalls, registers, constantReflection, target);
             }
-            HotSpotStampProvider stampProvider = new HotSpotStampProvider();
-            Providers p = new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, null, stampProvider);
+            try (InitTimer rt = timer("create stamp provider")) {
+                stampProvider = createStampProvider();
+            }
+            try (InitTimer rt = timer("create GC provider")) {
+                gc = createGCProvider(config);
+            }
+
+            Providers p = new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, null, stampProvider, gc);
 
             try (InitTimer rt = timer("create SnippetReflection provider")) {
                 snippetReflection = createSnippetReflection(graalRuntime, constantReflection, wordTypes);
             }
             try (InitTimer rt = timer("create Bytecode provider")) {
-                bytecodeProvider = new ClassfileBytecodeProvider(metaAccess, snippetReflection);
+                bytecodeProvider = createBytecodeProvider(metaAccess, snippetReflection);
             }
             try (InitTimer rt = timer("create Replacements provider")) {
-                replacements = createReplacements(p, snippetReflection, bytecodeProvider);
+                replacements = createReplacements(target, p, snippetReflection, bytecodeProvider);
             }
             try (InitTimer rt = timer("create GraphBuilderPhase plugins")) {
                 plugins = createGraphBuilderPlugins(compilerConfiguration, config, target, constantReflection, foreignCalls, metaAccess, snippetReflection, replacements, wordTypes, options);
@@ -148,8 +155,7 @@
                 suites = createSuites(config, graalRuntime, compilerConfiguration, plugins, registers, replacements, options);
             }
             providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, suites, registers,
-                            snippetReflection, wordTypes,
-                            plugins);
+                            snippetReflection, wordTypes, plugins, gc);
             replacements.setProviders(providers);
         }
         try (InitTimer rt = timer("instantiate backend")) {
@@ -161,7 +167,7 @@
                     HotSpotConstantReflectionProvider constantReflection, HotSpotHostForeignCallsProvider foreignCalls, HotSpotMetaAccessProvider metaAccess,
                     HotSpotSnippetReflectionProvider snippetReflection, HotSpotReplacementsImpl replacements, HotSpotWordTypes wordTypes, OptionValues options) {
         Plugins plugins = HotSpotGraphBuilderPlugins.create(compilerConfiguration, config, wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, replacements, options);
-        AMD64GraphBuilderPlugins.register(plugins, replacements.getDefaultReplacementBytecodeProvider(), (AMD64) target.arch, false, JAVA_SPECIFICATION_VERSION >= 9, config.useFMAIntrinsics);
+        AMD64GraphBuilderPlugins.register(plugins, replacements.getDefaultReplacementBytecodeProvider(), (AMD64) target.arch, false, JavaVersionUtil.JAVA_SPEC >= 9, config.useFMAIntrinsics);
         return plugins;
     }
 
@@ -173,10 +179,6 @@
         return new HotSpotRegisters(AMD64.r15, AMD64.r12, AMD64.rsp);
     }
 
-    protected HotSpotReplacementsImpl createReplacements(Providers p, SnippetReflectionProvider snippetReflection, BytecodeProvider bytecodeProvider) {
-        return new HotSpotReplacementsImpl(p, snippetReflection, bytecodeProvider, p.getCodeCache().getTarget());
-    }
-
     protected AMD64HotSpotForeignCallsProvider createForeignCalls(HotSpotJVMCIRuntime jvmciRuntime, HotSpotGraalRuntimeProvider runtime, HotSpotMetaAccessProvider metaAccess,
                     HotSpotCodeCacheProvider codeCache, WordTypes wordTypes, Value[] nativeABICallerSaveRegisters) {
         return new AMD64HotSpotForeignCallsProvider(jvmciRuntime, runtime, metaAccess, codeCache, wordTypes, nativeABICallerSaveRegisters);
@@ -191,10 +193,6 @@
                         new AddressLoweringPhase(new AMD64HotSpotAddressLowering(config, registers.getHeapBaseRegister(), options)));
     }
 
-    protected HotSpotSnippetReflectionProvider createSnippetReflection(HotSpotGraalRuntimeProvider runtime, HotSpotConstantReflectionProvider constantReflection, WordTypes wordTypes) {
-        return new HotSpotSnippetReflectionProvider(runtime, constantReflection, wordTypes);
-    }
-
     protected HotSpotLoweringProvider createLowerer(HotSpotGraalRuntimeProvider runtime, HotSpotMetaAccessProvider metaAccess, HotSpotForeignCallsProvider foreignCalls,
                     HotSpotRegistersProvider registers, HotSpotConstantReflectionProvider constantReflection, TargetDescription target) {
         return new AMD64HotSpotLoweringProvider(runtime, metaAccess, foreignCalls, registers, constantReflection, target);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotForeignCallsProvider.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotForeignCallsProvider.java	Mon Jul 01 14:57:02 2019 -0700
@@ -104,6 +104,8 @@
                         registerStubCall(AMD64ArrayIndexOf.STUB_INDEX_OF_TWO_CONSECUTIVE_BYTES, LEAF, REEXECUTABLE, NO_LOCATIONS)));
         link(new AMD64ArrayIndexOfStub(AMD64ArrayIndexOf.STUB_INDEX_OF_TWO_CONSECUTIVE_CHARS, options, providers,
                         registerStubCall(AMD64ArrayIndexOf.STUB_INDEX_OF_TWO_CONSECUTIVE_CHARS, LEAF, REEXECUTABLE, NO_LOCATIONS)));
+        link(new AMD64ArrayIndexOfStub(AMD64ArrayIndexOf.STUB_INDEX_OF_TWO_CONSECUTIVE_CHARS_COMPACT, options, providers,
+                        registerStubCall(AMD64ArrayIndexOf.STUB_INDEX_OF_TWO_CONSECUTIVE_CHARS_COMPACT, LEAF, REEXECUTABLE, NO_LOCATIONS)));
         link(new AMD64ArrayIndexOfStub(AMD64ArrayIndexOf.STUB_INDEX_OF_1_BYTE, options, providers,
                         registerStubCall(AMD64ArrayIndexOf.STUB_INDEX_OF_1_BYTE, LEAF, REEXECUTABLE, NO_LOCATIONS)));
         link(new AMD64ArrayIndexOfStub(AMD64ArrayIndexOf.STUB_INDEX_OF_2_BYTES, options, providers,
@@ -120,6 +122,14 @@
                         registerStubCall(AMD64ArrayIndexOf.STUB_INDEX_OF_3_CHARS, LEAF, REEXECUTABLE, NO_LOCATIONS)));
         link(new AMD64ArrayIndexOfStub(AMD64ArrayIndexOf.STUB_INDEX_OF_4_CHARS, options, providers,
                         registerStubCall(AMD64ArrayIndexOf.STUB_INDEX_OF_4_CHARS, LEAF, REEXECUTABLE, NO_LOCATIONS)));
+        link(new AMD64ArrayIndexOfStub(AMD64ArrayIndexOf.STUB_INDEX_OF_1_CHAR_COMPACT, options, providers,
+                        registerStubCall(AMD64ArrayIndexOf.STUB_INDEX_OF_1_CHAR_COMPACT, LEAF, REEXECUTABLE, NO_LOCATIONS)));
+        link(new AMD64ArrayIndexOfStub(AMD64ArrayIndexOf.STUB_INDEX_OF_2_CHARS_COMPACT, options, providers,
+                        registerStubCall(AMD64ArrayIndexOf.STUB_INDEX_OF_2_CHARS_COMPACT, LEAF, REEXECUTABLE, NO_LOCATIONS)));
+        link(new AMD64ArrayIndexOfStub(AMD64ArrayIndexOf.STUB_INDEX_OF_3_CHARS_COMPACT, options, providers,
+                        registerStubCall(AMD64ArrayIndexOf.STUB_INDEX_OF_3_CHARS_COMPACT, LEAF, REEXECUTABLE, NO_LOCATIONS)));
+        link(new AMD64ArrayIndexOfStub(AMD64ArrayIndexOf.STUB_INDEX_OF_4_CHARS_COMPACT, options, providers,
+                        registerStubCall(AMD64ArrayIndexOf.STUB_INDEX_OF_4_CHARS_COMPACT, LEAF, REEXECUTABLE, NO_LOCATIONS)));
 
         link(new AMD64ArrayEqualsStub(AMD64ArrayEqualsStub.STUB_BOOLEAN_ARRAY_EQUALS, options, providers,
                         registerStubCall(AMD64ArrayEqualsStub.STUB_BOOLEAN_ARRAY_EQUALS, LEAF, REEXECUTABLE, NO_LOCATIONS)));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotJumpToExceptionHandlerInCallerOp.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotJumpToExceptionHandlerInCallerOp.java	Mon Jul 01 14:57:02 2019 -0700
@@ -71,7 +71,7 @@
         // Discard the return address, thus completing restoration of caller frame
         masm.incrementq(rsp, 8);
 
-        if (JavaVersionUtil.JAVA_SPECIFICATION_VERSION < 8) {
+        if (JavaVersionUtil.JAVA_SPEC < 8) {
             // Restore rsp from rbp if the exception PC is a method handle call site.
             AMD64Address dst = new AMD64Address(thread, isMethodHandleReturnOffset);
             masm.cmpl(dst, 0);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLoweringProvider.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLoweringProvider.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,7 +24,6 @@
 
 package org.graalvm.compiler.hotspot.amd64;
 
-import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
 import static org.graalvm.compiler.hotspot.HotSpotBackend.Options.GraalArithmeticStubs;
 
 import org.graalvm.compiler.api.replacements.Snippet;
@@ -43,6 +42,7 @@
 import org.graalvm.compiler.nodes.extended.ForeignCallNode;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
 import org.graalvm.compiler.options.OptionValues;
+import org.graalvm.compiler.replacements.amd64.AMD64ArrayIndexOfDispatchNode;
 import org.graalvm.compiler.replacements.amd64.AMD64ConvertSnippets;
 import org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode;
 import org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation;
@@ -67,9 +67,12 @@
     @Override
     public void initialize(OptionValues options, Iterable<DebugHandlersFactory> factories, HotSpotProviders providers, GraalHotSpotVMConfig config) {
         convertSnippets = new AMD64ConvertSnippets.Templates(options, factories, providers, providers.getSnippetReflection(), providers.getCodeCache().getTarget());
-        profileSnippets = ProfileNode.Options.ProbabilisticProfiling.getValue(options) && !JavaVersionUtil.Java8OrEarlier && GeneratePIC.getValue(options)
-                        ? new ProbabilisticProfileSnippets.Templates(options, factories, providers, providers.getCodeCache().getTarget())
-                        : null;
+        if (JavaVersionUtil.JAVA_SPEC <= 8) {
+            // AOT only introduced in JDK 9
+            profileSnippets = null;
+        } else {
+            profileSnippets = new ProbabilisticProfileSnippets.Templates(options, factories, providers, providers.getCodeCache().getTarget());
+        }
         mathSnippets = new AMD64X87MathSnippets.Templates(options, factories, providers, providers.getSnippetReflection(), providers.getCodeCache().getTarget());
         super.initialize(options, factories, providers, config);
     }
@@ -82,6 +85,8 @@
             profileSnippets.lower((ProfileNode) n, tool);
         } else if (n instanceof UnaryMathIntrinsicNode) {
             lowerUnaryMath((UnaryMathIntrinsicNode) n, tool);
+        } else if (n instanceof AMD64ArrayIndexOfDispatchNode) {
+            lowerArrayIndexOf((AMD64ArrayIndexOfDispatchNode) n);
         } else {
             super.lower(n, tool);
         }
@@ -125,6 +130,12 @@
         math.replaceAtUsages(call);
     }
 
+    private void lowerArrayIndexOf(AMD64ArrayIndexOfDispatchNode dispatchNode) {
+        StructuredGraph graph = dispatchNode.graph();
+        ForeignCallNode call = graph.add(new ForeignCallNode(foreignCalls, dispatchNode.getStubCallDescriptor(), dispatchNode.getStubCallArgs()));
+        graph.replaceFixed(dispatchNode, call);
+    }
+
     @Override
     public Integer smallestCompareWidth() {
         return 8;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.jdk9.test/src/org/graalvm/compiler/hotspot/jdk9/test/MathDoubleFMATest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.jdk9.test/src/org/graalvm/compiler/hotspot/jdk9/test/MathDoubleFMATest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -30,7 +30,10 @@
 import java.util.Collection;
 import java.util.List;
 
+import org.graalvm.compiler.api.test.Graal;
 import org.graalvm.compiler.core.test.GraalCompilerTest;
+import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
+import org.graalvm.compiler.runtime.RuntimeProvider;
 import org.graalvm.compiler.test.AddExports;
 import org.junit.Before;
 import org.junit.Test;
@@ -48,6 +51,8 @@
     @Before
     public void checkAMD64() {
         assumeTrue("skipping AMD64 specific test", getTarget().arch instanceof AMD64);
+        HotSpotGraalRuntimeProvider rt = (HotSpotGraalRuntimeProvider) Graal.getRequiredCapability(RuntimeProvider.class);
+        assumeTrue("skipping FMA specific test", rt.getVMConfig().useFMAIntrinsics);
     }
 
     @Parameters(name = "{0}, {1}, {2}")
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.jdk9.test/src/org/graalvm/compiler/hotspot/jdk9/test/MathFloatFMATest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.jdk9.test/src/org/graalvm/compiler/hotspot/jdk9/test/MathFloatFMATest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -30,7 +30,10 @@
 import java.util.Collection;
 import java.util.List;
 
+import org.graalvm.compiler.api.test.Graal;
 import org.graalvm.compiler.core.test.GraalCompilerTest;
+import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
+import org.graalvm.compiler.runtime.RuntimeProvider;
 import org.graalvm.compiler.test.AddExports;
 import org.junit.Before;
 import org.junit.Test;
@@ -48,6 +51,8 @@
     @Before
     public void checkAMD64() {
         assumeTrue("skipping AMD64 specific test", getTarget().arch instanceof AMD64);
+        HotSpotGraalRuntimeProvider rt = (HotSpotGraalRuntimeProvider) Graal.getRequiredCapability(RuntimeProvider.class);
+        assumeTrue("skipping FMA specific tests", rt.getVMConfig().useFMAIntrinsics);
     }
 
     @Parameters(name = "{0}, {1}, {2}")
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.jdk9.test/src/org/graalvm/compiler/hotspot/jdk9/test/StringUTF16ToBytesGetCharsTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.jdk9.test/src/org/graalvm/compiler/hotspot/jdk9/test/StringUTF16ToBytesGetCharsTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -32,6 +32,7 @@
 import org.graalvm.compiler.nodes.java.NewArrayNode;
 import org.graalvm.compiler.replacements.arraycopy.ArrayCopyCallNode;
 import org.graalvm.compiler.replacements.test.MethodSubstitutionTest;
+import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
 import org.graalvm.compiler.test.AddExports;
 import org.junit.Test;
 
@@ -49,7 +50,7 @@
     private static final int N_OVERFLOW = 10;
 
     public StringUTF16ToBytesGetCharsTest() {
-        assumeFalse(Java8OrEarlier);
+        assumeFalse(JavaVersionUtil.JAVA_SPEC <= 8);
     }
 
     @Test
@@ -57,7 +58,7 @@
         Class<?> javaclass = Class.forName("java.lang.StringUTF16");
 
         ResolvedJavaMethod caller = getResolvedJavaMethod(javaclass, "toBytes", char[].class, int.class, int.class);
-        StructuredGraph graph = getReplacements().getIntrinsicGraph(caller, CompilationIdentifier.INVALID_COMPILATION_ID, getDebugContext());
+        StructuredGraph graph = getReplacements().getIntrinsicGraph(caller, CompilationIdentifier.INVALID_COMPILATION_ID, getDebugContext(), null);
         assertInGraph(graph, NewArrayNode.class);
         assertInGraph(graph, ArrayCopyCallNode.class);
 
@@ -88,7 +89,7 @@
         Class<?> javaclass = Class.forName("java.lang.StringUTF16");
 
         ResolvedJavaMethod caller = getResolvedJavaMethod(javaclass, "getChars", byte[].class, int.class, int.class, char[].class, int.class);
-        StructuredGraph graph = getReplacements().getIntrinsicGraph(caller, CompilationIdentifier.INVALID_COMPILATION_ID, getDebugContext());
+        StructuredGraph graph = getReplacements().getIntrinsicGraph(caller, CompilationIdentifier.INVALID_COMPILATION_ID, getDebugContext(), null);
         assertInGraph(graph, ArrayCopyCallNode.class);
 
         InstalledCode code = getCode(caller, graph);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.lir.test/src/org/graalvm/compiler/hotspot/lir/test/MitigateExceedingMaxOopMapStackOffsetTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.hotspot.lir.test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.graalvm.compiler.core.common.LIRKind;
+import org.graalvm.compiler.hotspot.HotSpotBackend;
+import org.graalvm.compiler.lir.VirtualStackSlot;
+import org.graalvm.compiler.lir.framemap.FrameMapBuilder;
+import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
+import org.graalvm.compiler.lir.jtt.LIRTest;
+import org.graalvm.compiler.lir.jtt.LIRTestSpecification;
+import org.graalvm.compiler.lir.stackslotalloc.LSStackSlotAllocator;
+import org.graalvm.compiler.nodes.SafepointNode;
+import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration;
+import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
+import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin;
+import org.junit.Assume;
+import org.junit.Test;
+
+import jdk.vm.ci.meta.AllocatableValue;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+
+/**
+ * Tests the mitigation against overflowing the max size limit for a HotSpot OopMap. The mitigation
+ * works by {@link LSStackSlotAllocator} placing reference typed stack slots at lower offsets.
+ */
+public class MitigateExceedingMaxOopMapStackOffsetTest extends LIRTest {
+
+    /**
+     * Allocate stacks slots and initializes those at an odd index with a reference constant and
+     * those at an even index with a primitive constant.
+     */
+    private static class WriteStackValues extends LIRTestSpecification {
+        private final JavaConstant objectConstant;
+        private final JavaConstant primitiveConstant;
+
+        WriteStackValues(JavaConstant objectConstant, JavaConstant primitiveConstant) {
+            this.objectConstant = objectConstant;
+            this.primitiveConstant = primitiveConstant;
+        }
+
+        @Override
+        public void generate(LIRGeneratorTool gen) {
+            FrameMapBuilder frameMapBuilder = gen.getResult().getFrameMapBuilder();
+            LIRKind objectLirKind = LIRKind.reference(gen.target().arch.getPlatformKind(objectConstant.getJavaKind()));
+            LIRKind primitiveLirKind = LIRKind.value(gen.target().arch.getPlatformKind(primitiveConstant.getJavaKind()));
+
+            int numSlots = numPrimitiveSlots + numReferenceSlots;
+            List<AllocatableValue> slotList = new ArrayList<>(numSlots);
+            // Place reference slots at top and bottom of virtual frame
+            // with primitive slots in the middle. This tests that slot
+            // partitioning works.
+            for (int i = 0; i < numReferenceSlots / 2; i++) {
+                AllocatableValue src = gen.emitLoadConstant(objectLirKind, objectConstant);
+                VirtualStackSlot slot = frameMapBuilder.allocateSpillSlot(objectLirKind);
+                slotList.add(slot);
+                gen.emitMove(slot, src);
+            }
+            for (int i = 0; i < numPrimitiveSlots; i++) {
+                AllocatableValue src = gen.emitLoadConstant(objectLirKind, primitiveConstant);
+                VirtualStackSlot slot = frameMapBuilder.allocateSpillSlot(primitiveLirKind);
+                slotList.add(slot);
+                gen.emitMove(slot, src);
+            }
+            for (int i = numReferenceSlots / 2; i < numReferenceSlots; i++) {
+                AllocatableValue src = gen.emitLoadConstant(objectLirKind, objectConstant);
+                VirtualStackSlot slot = frameMapBuilder.allocateSpillSlot(objectLirKind);
+                slotList.add(slot);
+                gen.emitMove(slot, src);
+            }
+            slots = slotList.toArray(new AllocatableValue[slotList.size()]);
+        }
+    }
+
+    /**
+     * Read stacks slots and move their content into a blackhole.
+     */
+    private static class ReadStackValues extends LIRTestSpecification {
+
+        ReadStackValues() {
+        }
+
+        @Override
+        public void generate(LIRGeneratorTool gen) {
+            for (int i = 0; i < slots.length; i++) {
+                gen.emitBlackhole(gen.emitMove(slots[i]));
+            }
+        }
+    }
+
+    @Override
+    protected GraphBuilderConfiguration editGraphBuilderConfiguration(GraphBuilderConfiguration conf) {
+        InvocationPlugin safepointPlugin = new InvocationPlugin() {
+            @Override
+            public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
+                b.add(new SafepointNode());
+                return true;
+            }
+        };
+        conf.getPlugins().getInvocationPlugins().register(safepointPlugin, getClass(), "safepoint");
+        return super.editGraphBuilderConfiguration(conf);
+    }
+
+    /*
+     * Safepoint Snippet
+     */
+    private static void safepoint() {
+    }
+
+    private static int numPrimitiveSlots;
+    private static int numReferenceSlots;
+    private static AllocatableValue[] slots;
+
+    private static final LIRTestSpecification readStackValues = new ReadStackValues();
+
+    @SuppressWarnings("unused")
+    @LIRIntrinsic
+    public static void instrinsic(LIRTestSpecification spec) {
+    }
+
+    private static final LIRTestSpecification writeStackValues = new WriteStackValues(JavaConstant.NULL_POINTER, JavaConstant.LONG_0);
+
+    public void testStackObjects() {
+        instrinsic(writeStackValues);
+        safepoint();
+        instrinsic(readStackValues);
+    }
+
+    @Test
+    public void runStackObjects() throws Throwable {
+        int max = ((HotSpotBackend) getBackend()).getRuntime().getVMConfig().maxOopMapStackOffset;
+        Assume.assumeFalse("no limit on oop map size", max == Integer.MAX_VALUE);
+        numPrimitiveSlots = (max / 8) * 2;
+        numReferenceSlots = (max / 8) - 100; // Should be enough margin for all platforms
+        runTest("testStackObjects");
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotBackendFactory.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.sparc/src/org/graalvm/compiler/hotspot/sparc/SPARCHotSpotBackendFactory.java	Mon Jul 01 14:57:02 2019 -0700
@@ -38,7 +38,7 @@
 import org.graalvm.compiler.hotspot.meta.AddressLoweringHotSpotSuitesProvider;
 import org.graalvm.compiler.hotspot.meta.HotSpotConstantFieldProvider;
 import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProvider;
-import org.graalvm.compiler.hotspot.meta.HotSpotGraalConstantFieldProvider;
+import org.graalvm.compiler.hotspot.meta.HotSpotGCProvider;
 import org.graalvm.compiler.hotspot.meta.HotSpotGraphBuilderPlugins;
 import org.graalvm.compiler.hotspot.meta.HotSpotLoweringProvider;
 import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
@@ -55,7 +55,6 @@
 import org.graalvm.compiler.phases.common.AddressLoweringPhase;
 import org.graalvm.compiler.phases.tiers.CompilerConfiguration;
 import org.graalvm.compiler.phases.util.Providers;
-import org.graalvm.compiler.replacements.classfile.ClassfileBytecodeProvider;
 import org.graalvm.compiler.replacements.sparc.SPARCGraphBuilderPlugins;
 import org.graalvm.compiler.serviceprovider.ServiceProvider;
 
@@ -72,7 +71,7 @@
 import jdk.vm.ci.sparc.SPARC;
 
 @ServiceProvider(HotSpotBackendFactory.class)
-public class SPARCHotSpotBackendFactory implements HotSpotBackendFactory {
+public class SPARCHotSpotBackendFactory extends HotSpotBackendFactory {
 
     @Override
     public String getName() {
@@ -95,22 +94,22 @@
         HotSpotCodeCacheProvider codeCache = (HotSpotCodeCacheProvider) jvmci.getCodeCache();
         TargetDescription target = codeCache.getTarget();
         HotSpotConstantReflectionProvider constantReflection = (HotSpotConstantReflectionProvider) jvmci.getConstantReflection();
-        HotSpotConstantFieldProvider constantFieldProvider = new HotSpotGraalConstantFieldProvider(config, metaAccess);
+        HotSpotConstantFieldProvider constantFieldProvider = createConstantFieldProvider(config, metaAccess);
         Value[] nativeABICallerSaveRegisters = createNativeABICallerSaveRegisters(config, codeCache.getRegisterConfig());
-        HotSpotWordTypes wordTypes = new HotSpotWordTypes(metaAccess, target.wordJavaKind);
+        HotSpotWordTypes wordTypes = createWordTypes(metaAccess, target);
         HotSpotForeignCallsProvider foreignCalls = new SPARCHotSpotForeignCallsProvider(jvmciRuntime, runtime, metaAccess, codeCache, wordTypes, nativeABICallerSaveRegisters);
         LoweringProvider lowerer = createLowerer(runtime, metaAccess, foreignCalls, registers, constantReflection, target);
-        HotSpotStampProvider stampProvider = new HotSpotStampProvider();
-        Providers p = new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, null, stampProvider);
-        HotSpotSnippetReflectionProvider snippetReflection = new HotSpotSnippetReflectionProvider(runtime, constantReflection, wordTypes);
-        BytecodeProvider bytecodeProvider = new ClassfileBytecodeProvider(metaAccess, snippetReflection);
-        HotSpotReplacementsImpl replacements = new HotSpotReplacementsImpl(p, snippetReflection, bytecodeProvider, target);
+        HotSpotStampProvider stampProvider = createStampProvider();
+        HotSpotGCProvider gc = createGCProvider(config);
+        Providers p = new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, null, stampProvider, gc);
+        HotSpotSnippetReflectionProvider snippetReflection = createSnippetReflection(runtime, constantReflection, wordTypes);
+        BytecodeProvider bytecodeProvider = createBytecodeProvider(metaAccess, snippetReflection);
+        HotSpotReplacementsImpl replacements = createReplacements(target, p, snippetReflection, bytecodeProvider);
         Plugins plugins = createGraphBuilderPlugins(compilerConfiguration, config, metaAccess, constantReflection, foreignCalls, snippetReflection, replacements, wordTypes, runtime.getOptions());
         replacements.setGraphBuilderPlugins(plugins);
         HotSpotSuitesProvider suites = createSuites(config, runtime, compilerConfiguration, plugins, replacements);
         HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, suites, registers,
-                        snippetReflection,
-                        wordTypes, plugins);
+                        snippetReflection, wordTypes, plugins, gc);
         replacements.setProviders(providers);
 
         return createBackend(config, runtime, providers);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/BoxDeoptimizationTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/BoxDeoptimizationTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -4,9 +4,7 @@
  *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
+ * published by the Free Software Foundation.
  *
  * This code is distributed in the hope that it will be useful, but WITHOUT
  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
@@ -22,6 +20,8 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+
+
 package org.graalvm.compiler.hotspot.test;
 
 import org.graalvm.compiler.api.directives.GraalDirectives;
@@ -32,7 +32,7 @@
 import org.junit.Test;
 
 public class BoxDeoptimizationTest extends GraalCompilerTest {
-    private static boolean isJDK13OrLater = JavaVersionUtil.JAVA_SPECIFICATION_VERSION >= 13;
+    private static boolean isJDK13OrLater = JavaVersionUtil.JAVA_SPEC >= 13;
 
     public static void testInteger() {
         Object[] values = {42, new Exception()};
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CRC32CSubstitutionsTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CRC32CSubstitutionsTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,22 +24,20 @@
 
 package org.graalvm.compiler.hotspot.test;
 
+import static org.junit.Assume.assumeFalse;
+
 import java.io.DataInputStream;
 import java.io.InputStream;
-import java.nio.ByteBuffer;
-import java.util.zip.Checksum;
-
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
-
-import org.graalvm.compiler.test.GraalTest;
-import org.graalvm.compiler.core.test.GraalCompilerTest;
+import java.nio.ByteBuffer;
+import java.util.zip.Checksum;
 
+import org.graalvm.compiler.core.test.GraalCompilerTest;
+import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
 import org.junit.Test;
 
-import static org.junit.Assume.assumeFalse;
-
 /**
  * Tests compiled calls to {@link java.util.zip.CRC32C}.
  */
@@ -56,7 +54,7 @@
 
     @Test
     public void test1() throws Throwable {
-        assumeFalse(GraalTest.Java8OrEarlier);
+        assumeFalse(JavaVersionUtil.JAVA_SPEC <= 8);
         String classfileName = CRC32CSubstitutionsTest.class.getSimpleName().replace('.', '/') + ".class";
         InputStream s = CRC32CSubstitutionsTest.class.getResourceAsStream(classfileName);
         byte[] buf = new byte[s.available()];
@@ -79,7 +77,7 @@
 
     @Test
     public void test2() throws Throwable {
-        assumeFalse(GraalTest.Java8OrEarlier);
+        assumeFalse(JavaVersionUtil.JAVA_SPEC <= 8);
         String classfileName = CRC32CSubstitutionsTest.class.getSimpleName().replace('.', '/') + ".class";
         InputStream s = CRC32CSubstitutionsTest.class.getResourceAsStream(classfileName);
         byte[] buf = new byte[s.available()];
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java	Mon Jul 01 14:57:02 2019 -0700
@@ -386,6 +386,10 @@
         if (isJDK11OrHigher()) {
             // Relevant for Java flight recorder
             add(toBeInvestigated,
+                            "java/lang/CharacterDataLatin1.isDigit(I)Z",
+                            "java/lang/CharacterDataLatin1.isLowerCase(I)Z",
+                            "java/lang/CharacterDataLatin1.isUpperCase(I)Z",
+                            "java/lang/CharacterDataLatin1.isWhitespace(I)Z",
                             "jdk/jfr/internal/JVM.getEventWriter()Ljava/lang/Object;");
             if (!config.useBase64Intrinsics()) {
                 add(ignore,
@@ -393,14 +397,6 @@
             }
         }
 
-        if (isJDK12OrHigher()) {
-            add(toBeInvestigated,
-                            "java/lang/CharacterDataLatin1.isDigit(I)Z",
-                            "java/lang/CharacterDataLatin1.isLowerCase(I)Z",
-                            "java/lang/CharacterDataLatin1.isUpperCase(I)Z",
-                            "java/lang/CharacterDataLatin1.isWhitespace(I)Z");
-        }
-
         if (isJDK13OrHigher()) {
             add(toBeInvestigated,
                             "java/lang/Math.abs(I)I",
@@ -568,23 +564,23 @@
     }
 
     private static boolean isJDK9OrHigher() {
-        return JavaVersionUtil.JAVA_SPECIFICATION_VERSION >= 9;
+        return JavaVersionUtil.JAVA_SPEC >= 9;
     }
 
     private static boolean isJDK10OrHigher() {
-        return JavaVersionUtil.JAVA_SPECIFICATION_VERSION >= 10;
+        return JavaVersionUtil.JAVA_SPEC >= 10;
     }
 
     private static boolean isJDK11OrHigher() {
-        return JavaVersionUtil.JAVA_SPECIFICATION_VERSION >= 11;
+        return JavaVersionUtil.JAVA_SPEC >= 11;
     }
 
     private static boolean isJDK12OrHigher() {
-        return JavaVersionUtil.JAVA_SPECIFICATION_VERSION >= 12;
+        return JavaVersionUtil.JAVA_SPEC >= 12;
     }
 
     private static boolean isJDK13OrHigher() {
-        return JavaVersionUtil.JAVA_SPECIFICATION_VERSION >= 13;
+        return JavaVersionUtil.JAVA_SPEC >= 13;
     }
 
     public interface Refiner {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorld.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorld.java	Mon Jul 01 14:57:02 2019 -0700
@@ -31,7 +31,6 @@
 import static org.graalvm.compiler.core.test.ReflectionOptionDescriptors.extractEntries;
 import static org.graalvm.compiler.debug.MemUseTrackerKey.getCurrentThreadAllocatedBytes;
 import static org.graalvm.compiler.hotspot.test.CompileTheWorld.Options.DESCRIPTORS;
-import static org.graalvm.compiler.serviceprovider.JavaVersionUtil.Java8OrEarlier;
 import static sun.misc.Unsafe.ARRAY_BYTE_BASE_OFFSET;
 
 import java.io.ByteArrayOutputStream;
@@ -97,6 +96,7 @@
 import org.graalvm.compiler.serviceprovider.GraalUnsafeAccess;
 import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
 import jdk.internal.vm.compiler.libgraal.LibGraal;
+import jdk.internal.vm.compiler.libgraal.LibGraalScope;
 import jdk.internal.vm.compiler.libgraal.OptionsEncoder;
 
 import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider;
@@ -117,9 +117,8 @@
 public final class CompileTheWorld {
 
     /**
-     * Magic token to denote that JDK classes are to be compiled. If
-     * {@link JavaVersionUtil#Java8OrEarlier}, then the classes in {@code rt.jar} are compiled.
-     * Otherwise the classes in the Java runtime image are compiled.
+     * Magic token to denote that JDK classes are to be compiled. For JDK 8, the classes in
+     * {@code rt.jar} are compiled. Otherwise the classes in the Java runtime image are compiled.
      */
     public static final String SUN_BOOT_CLASS_PATH = "sun.boot.class.path";
 
@@ -398,7 +397,7 @@
         try (LibGraalParams libgraal = LibGraal.isAvailable() ? new LibGraalParams(compilerOptions) : null) {
             if (SUN_BOOT_CLASS_PATH.equals(inputClassPath)) {
                 String bcpEntry = null;
-                if (Java8OrEarlier) {
+                if (JavaVersionUtil.JAVA_SPEC <= 8) {
                     final String[] entries = System.getProperty(SUN_BOOT_CLASS_PATH).split(File.pathSeparator);
                     for (int i = 0; i < entries.length && bcpEntry == null; i++) {
                         String entry = entries[i];
@@ -940,6 +939,7 @@
     /**
      * Compiles a method and gathers some statistics.
      */
+    @SuppressWarnings("try")
     private void compileMethod(HotSpotResolvedJavaMethod method, int counter, LibGraalParams libgraal) {
         try {
             long start = System.currentTimeMillis();
@@ -950,32 +950,33 @@
             HotSpotInstalledCode installedCode;
             if (libgraal != null) {
                 HotSpotJVMCIRuntime runtime = HotSpotJVMCIRuntime.runtime();
-                long methodHandle = LibGraal.translate(runtime, method);
-                long isolateThread = LibGraal.getIsolateThread();
+                try (LibGraalScope scope = new LibGraalScope(runtime)) {
+                    long methodHandle = LibGraal.translate(runtime, method);
+                    long isolateThread = LibGraalScope.getIsolateThread();
 
-                StackTraceBuffer stackTraceBuffer = libgraal.getStackTraceBuffer();
+                    StackTraceBuffer stackTraceBuffer = libgraal.getStackTraceBuffer();
 
-                long stackTraceBufferAddress = stackTraceBuffer.getAddress();
-                long installedCodeHandle = compileMethodInLibgraal(isolateThread,
-                                methodHandle,
-                                useProfilingInfo,
-                                installAsDefault,
-                                libgraal.options.getAddress(),
-                                libgraal.options.size,
-                                libgraal.options.hash,
-                                stackTraceBufferAddress,
-                                stackTraceBuffer.size);
+                    long stackTraceBufferAddress = stackTraceBuffer.getAddress();
+                    long installedCodeHandle = compileMethodInLibgraal(isolateThread,
+                                    methodHandle,
+                                    useProfilingInfo,
+                                    installAsDefault,
+                                    libgraal.options.getAddress(),
+                                    libgraal.options.size,
+                                    libgraal.options.hash,
+                                    stackTraceBufferAddress,
+                                    stackTraceBuffer.size);
 
-                installedCode = LibGraal.unhand(runtime, HotSpotInstalledCode.class, installedCodeHandle);
-                if (installedCode == null) {
-                    int length = UNSAFE.getInt(stackTraceBufferAddress);
-                    byte[] data = new byte[length];
-                    UNSAFE.copyMemory(null, stackTraceBufferAddress + Integer.BYTES, data, ARRAY_BYTE_BASE_OFFSET, length);
-                    String stackTrace = new String(data).trim();
-                    println("CompileTheWorld (%d) : Error compiling method: %s", counter, method.format("%H.%n(%p):%r"));
-                    println(stackTrace);
+                    installedCode = LibGraal.unhand(runtime, HotSpotInstalledCode.class, installedCodeHandle);
+                    if (installedCode == null) {
+                        int length = UNSAFE.getInt(stackTraceBufferAddress);
+                        byte[] data = new byte[length];
+                        UNSAFE.copyMemory(null, stackTraceBufferAddress + Integer.BYTES, data, ARRAY_BYTE_BASE_OFFSET, length);
+                        String stackTrace = new String(data).trim();
+                        println("CompileTheWorld (%d) : Error compiling method: %s", counter, method.format("%H.%n(%p):%r"));
+                        println(stackTrace);
+                    }
                 }
-
             } else {
                 int entryBCI = JVMCICompiler.INVOCATION_ENTRY_BCI;
                 HotSpotCompilationRequest request = new HotSpotCompilationRequest(method, entryBCI, 0L);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ConstantPoolSubstitutionsTests.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ConstantPoolSubstitutionsTests.java	Mon Jul 01 14:57:02 2019 -0700
@@ -35,6 +35,7 @@
 import org.graalvm.compiler.nodes.Invoke;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
+import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
 import org.graalvm.compiler.test.JLModule;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -75,8 +76,8 @@
     }
 
     private static Object getConstantPoolForObject() {
-        String miscPackage = Java8OrEarlier ? "sun.misc"
-                        : (Java11OrEarlier ? "jdk.internal.misc" : "jdk.internal.access");
+        String miscPackage = JavaVersionUtil.JAVA_SPEC <= 8 ? "sun.misc"
+                        : (JavaVersionUtil.JAVA_SPEC <= 11 ? "jdk.internal.misc" : "jdk.internal.access");
         try {
             Class<?> sharedSecretsClass = Class.forName(miscPackage + ".SharedSecrets");
             Class<?> javaLangAccessClass = Class.forName(miscPackage + ".JavaLangAccess");
@@ -111,11 +112,11 @@
      * This test uses some API hidden by the JDK9 module system.
      */
     private static void addExports(Class<?> c) {
-        if (!Java8OrEarlier) {
+        if (JavaVersionUtil.JAVA_SPEC > 8) {
             Object javaBaseModule = JLModule.fromClass(String.class);
             Object cModule = JLModule.fromClass(c);
             uncheckedAddExports(javaBaseModule, "jdk.internal.reflect", cModule);
-            if (Java11OrEarlier) {
+            if (JavaVersionUtil.JAVA_SPEC <= 11) {
                 uncheckedAddExports(javaBaseModule, "jdk.internal.misc", cModule);
             } else {
                 uncheckedAddExports(javaBaseModule, "jdk.internal.access", cModule);
@@ -222,7 +223,7 @@
             cw.visit(52, ACC_SUPER, PACKAGE_NAME_INTERNAL + "/ConstantPoolTest", null, "java/lang/Object", null);
             cw.visitInnerClass(PACKAGE_NAME_INTERNAL + "/ConstantPoolTest", PACKAGE_NAME_INTERNAL + "/ConstantPoolSubstitutionsTests", "ConstantPoolTest",
                             ACC_STATIC);
-            String constantPool = Java8OrEarlier ? "sun/reflect/ConstantPool" : "jdk/internal/reflect/ConstantPool";
+            String constantPool = JavaVersionUtil.JAVA_SPEC <= 8 ? "sun/reflect/ConstantPool" : "jdk/internal/reflect/ConstantPool";
 
             mv = cw.visitMethod(0, "<init>", "()V", null, null);
             mv.visitCode();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/DeferredBarrierAdditionTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.hotspot.test;
+
+import static org.junit.Assume.assumeTrue;
+
+import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
+import org.graalvm.compiler.nodes.gc.G1PostWriteBarrier;
+import org.graalvm.compiler.nodes.gc.G1PreWriteBarrier;
+import org.graalvm.compiler.nodes.gc.G1ReferentFieldReadBarrier;
+import org.graalvm.compiler.nodes.gc.SerialWriteBarrier;
+import org.graalvm.compiler.nodes.java.AbstractNewObjectNode;
+import org.graalvm.compiler.nodes.spi.LoweringTool;
+import org.graalvm.compiler.options.OptionValues;
+import org.graalvm.compiler.phases.OptimisticOptimizations;
+import org.graalvm.compiler.phases.common.CanonicalizerPhase;
+import org.graalvm.compiler.phases.common.GuardLoweringPhase;
+import org.graalvm.compiler.phases.common.LoweringPhase;
+import org.graalvm.compiler.phases.common.WriteBarrierAdditionPhase;
+import org.graalvm.compiler.phases.common.inlining.InliningPhase;
+import org.graalvm.compiler.phases.common.inlining.policy.InlineEverythingPolicy;
+import org.graalvm.compiler.phases.tiers.HighTierContext;
+import org.graalvm.compiler.phases.tiers.MidTierContext;
+import org.graalvm.compiler.virtual.phases.ea.PartialEscapePhase;
+import org.junit.Assert;
+import org.junit.Test;
+
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+
+/**
+ * This tests that barriers which are deferrable because of ReduceInitialCardMarks are properly
+ * omitted. The rule is simply that only writes to the very last allocated object can skip the card
+ * mark. By creating references between objects only one write can skip the card mark and the other
+ * must emit a card mark.
+ */
+public class DeferredBarrierAdditionTest extends HotSpotGraalCompilerTest {
+
+    private final GraalHotSpotVMConfig config = runtime().getVMConfig();
+
+    public static Object testCrossReferences() {
+        Object[] a = new Object[1];
+        Object[] b = new Object[1];
+        a[0] = b;
+        b[0] = a;
+        return a;
+    }
+
+    @Test
+    public void testGroupAllocation() throws Exception {
+        testHelper("testCrossReferences", 1, getInitialOptions());
+    }
+
+    @SuppressWarnings("try")
+    protected void testHelper(final String snippetName, final int expectedBarriers, OptionValues options) {
+        ResolvedJavaMethod snippet = getResolvedJavaMethod(snippetName);
+        DebugContext debug = getDebugContext(options, null, snippet);
+        try (DebugContext.Scope s = debug.scope("WriteBarrierAdditionTest", snippet)) {
+            StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO, debug);
+            HighTierContext highContext = getDefaultHighTierContext();
+            MidTierContext midContext = new MidTierContext(getProviders(), getTargetProvider(), OptimisticOptimizations.ALL, graph.getProfilingInfo());
+            new InliningPhase(new InlineEverythingPolicy(), new CanonicalizerPhase()).apply(graph, highContext);
+            new CanonicalizerPhase().apply(graph, highContext);
+            new PartialEscapePhase(false, new CanonicalizerPhase(), debug.getOptions()).apply(graph, highContext);
+            new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, highContext);
+            new GuardLoweringPhase().apply(graph, midContext);
+            new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, midContext);
+            new WriteBarrierAdditionPhase().apply(graph, midContext);
+            debug.dump(DebugContext.BASIC_LEVEL, graph, "After Write Barrier Addition");
+
+            checkAssumptions(graph);
+
+            int barriers = 0;
+            if (config.useG1GC) {
+                barriers = graph.getNodes().filter(G1ReferentFieldReadBarrier.class).count() + graph.getNodes().filter(G1PreWriteBarrier.class).count() +
+                                graph.getNodes().filter(G1PostWriteBarrier.class).count();
+            } else {
+                barriers = graph.getNodes().filter(SerialWriteBarrier.class).count();
+            }
+            if (expectedBarriers != barriers) {
+                Assert.assertEquals(getScheduledGraphString(graph), expectedBarriers, barriers);
+            }
+        } catch (Throwable e) {
+            throw debug.handle(e);
+        }
+    }
+
+    protected void checkAssumptions(StructuredGraph graph) {
+        assumeTrue(graph.getNodes().filter(AbstractNewObjectNode.class).isNotEmpty());
+    }
+
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotGraalCompilerTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotGraalCompilerTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -43,7 +43,7 @@
 import jdk.vm.ci.meta.ResolvedJavaMethod;
 
 /**
- * A Graal compiler test that needs access to the {@link HotSpotGraalRuntimeProvider}.
+ * A compiler test that needs access to the {@link HotSpotGraalRuntimeProvider}.
  */
 public abstract class HotSpotGraalCompilerTest extends GraalCompilerTest {
 
@@ -73,7 +73,7 @@
         HotSpotProviders providers = rt.getHostBackend().getProviders();
         CompilationIdentifier compilationId = runtime().getHostBackend().getCompilationIdentifier(method);
         OptionValues options = getInitialOptions();
-        StructuredGraph graph = providers.getReplacements().getIntrinsicGraph(method, compilationId, getDebugContext(options));
+        StructuredGraph graph = providers.getReplacements().getIntrinsicGraph(method, compilationId, getDebugContext(options), null);
         if (graph != null) {
             return getCode(method, graph, true, true, graph.getOptions());
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotInvokeDynamicPluginTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HotSpotInvokeDynamicPluginTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,12 +24,12 @@
 
 package org.graalvm.compiler.hotspot.test;
 
-import java.util.function.IntPredicate;
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
-import jdk.vm.ci.meta.ResolvedJavaMethod;
 import java.security.PrivilegedAction;
+import java.util.function.IntPredicate;
+
 import org.graalvm.compiler.core.common.GraalOptions;
 import org.graalvm.compiler.hotspot.meta.HotSpotClassInitializationPlugin;
 import org.graalvm.compiler.hotspot.meta.HotSpotInvokeDynamicPlugin;
@@ -37,22 +37,24 @@
 import org.graalvm.compiler.hotspot.nodes.aot.ResolveDynamicStubCall;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
+import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
 import org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin.InlineInfo;
-import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.phases.OptimisticOptimizations;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
-import org.graalvm.compiler.phases.common.LoweringPhase;
 import org.graalvm.compiler.phases.common.FrameStateAssignmentPhase;
 import org.graalvm.compiler.phases.common.GuardLoweringPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
+import org.graalvm.compiler.phases.common.LoweringPhase;
 import org.graalvm.compiler.phases.tiers.MidTierContext;
 import org.junit.Assert;
 import org.junit.Test;
 
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+
 public class HotSpotInvokeDynamicPluginTest extends HotSpotGraalCompilerTest {
     @Override
     protected Plugins getDefaultGraphBuilderPlugins() {
@@ -94,7 +96,7 @@
         CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
         Assert.assertEquals(expectedResolves, graph.getNodes().filter(ResolveDynamicConstantNode.class).count());
         Assert.assertEquals(0, graph.getNodes().filter(ResolveDynamicStubCall.class).count());
-        PhaseContext context = new PhaseContext(getProviders());
+        CoreProviders context = getProviders();
         new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
         new GuardLoweringPhase().apply(graph, midTierContext);
         new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, context);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HsErrLogTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/HsErrLogTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -39,6 +39,7 @@
 
 import org.graalvm.compiler.api.directives.GraalDirectives;
 import org.graalvm.compiler.core.test.GraalCompilerTest;
+import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
 import org.graalvm.compiler.test.SubprocessUtil;
 import org.graalvm.compiler.test.SubprocessUtil.Subprocess;
 import org.junit.Assert;
@@ -54,7 +55,7 @@
     @Test
     public void test1() throws IOException, InterruptedException {
         List<String> args = new ArrayList<>();
-        if (Java8OrEarlier) {
+        if (JavaVersionUtil.JAVA_SPEC <= 8) {
             args.add("-XX:-UseJVMCIClassLoader");
         }
         args.add("-XX:+UseJVMCICompiler");
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/LoadJavaMirrorWithKlassTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/LoadJavaMirrorWithKlassTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -73,13 +73,12 @@
     }
 
     @Override
-    protected boolean checkLowTierGraph(StructuredGraph graph) {
+    protected void checkLowTierGraph(StructuredGraph graph) {
         for (ConstantNode constantNode : graph.getNodes().filter(ConstantNode.class)) {
             assert constantNode.asJavaConstant() == null || constantNode.asJavaConstant().getJavaKind() != JavaKind.Object ||
                             constantNode.asJavaConstant().isDefaultForKind() : "Found unexpected object constant " +
                                             constantNode + ", this should have been removed by the LoadJavaMirrorWithKlassPhase.";
         }
-        return true;
     }
 
     public static Class<?> classConstant() {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ObjectHashCodeInliningTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ObjectHashCodeInliningTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -42,7 +42,7 @@
     @Test
     public void testInstallCodeInvalidation() {
         for (int i = 0; i < 100000; i++) {
-            getHash(i % 1000 == 0 ? new Object() : "");
+            getHash(i % 10 == 0 ? new Object() : "");
         }
 
         ResolvedJavaMethod method = getResolvedJavaMethod("getHash");
@@ -74,8 +74,9 @@
     }
 
     @Override
-    protected boolean checkHighTierGraph(StructuredGraph graph) {
-        return containsForeignCallToIdentityHashCode(graph) && containsReadStringHash(graph);
+    protected void checkHighTierGraph(StructuredGraph graph) {
+        assert containsForeignCallToIdentityHashCode(graph) : "expected a foreign call to identity_hashcode";
+        assert containsReadStringHash(graph) : "expected a read from String.hash";
     }
 
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/TestIntrinsicCompiles.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/TestIntrinsicCompiles.java	Mon Jul 01 14:57:02 2019 -0700
@@ -72,7 +72,7 @@
                 if (plugin instanceof MethodSubstitutionPlugin) {
                     ResolvedJavaMethod method = CheckGraalIntrinsics.resolveIntrinsic(getMetaAccess(), intrinsic);
                     if (!method.isNative()) {
-                        StructuredGraph graph = providers.getReplacements().getIntrinsicGraph(method, INVALID_COMPILATION_ID, debug);
+                        StructuredGraph graph = providers.getReplacements().getIntrinsicGraph(method, INVALID_COMPILATION_ID, debug, null);
                         getCode(method, graph);
                     }
                 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/WriteBarrierAdditionTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/WriteBarrierAdditionTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -32,13 +32,12 @@
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfigBase;
-import org.graalvm.compiler.hotspot.gc.g1.G1PostWriteBarrier;
-import org.graalvm.compiler.hotspot.gc.g1.G1PreWriteBarrier;
-import org.graalvm.compiler.hotspot.gc.g1.G1ReferentFieldReadBarrier;
-import org.graalvm.compiler.hotspot.gc.shared.SerialWriteBarrier;
-import org.graalvm.compiler.hotspot.phases.WriteBarrierAdditionPhase;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
+import org.graalvm.compiler.nodes.gc.G1PostWriteBarrier;
+import org.graalvm.compiler.nodes.gc.G1PreWriteBarrier;
+import org.graalvm.compiler.nodes.gc.G1ReferentFieldReadBarrier;
+import org.graalvm.compiler.nodes.gc.SerialWriteBarrier;
 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins;
 import org.graalvm.compiler.nodes.graphbuilderconf.NodeIntrinsicPluginFactory;
 import org.graalvm.compiler.nodes.memory.HeapAccess.BarrierType;
@@ -50,13 +49,12 @@
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
 import org.graalvm.compiler.phases.common.GuardLoweringPhase;
 import org.graalvm.compiler.phases.common.LoweringPhase;
+import org.graalvm.compiler.phases.common.WriteBarrierAdditionPhase;
 import org.graalvm.compiler.phases.common.inlining.InliningPhase;
 import org.graalvm.compiler.phases.common.inlining.policy.InlineEverythingPolicy;
 import org.graalvm.compiler.phases.tiers.HighTierContext;
 import org.graalvm.compiler.phases.tiers.MidTierContext;
 import org.graalvm.compiler.replacements.NodeIntrinsificationProvider;
-import org.graalvm.compiler.word.Word;
-import jdk.internal.vm.compiler.word.WordFactory;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -257,34 +255,6 @@
         test2("testArrayCopy", src, dst, dst.length);
     }
 
-    public static class WordContainer {
-        public Word word;
-    }
-
-    public static void testWordFieldSnippet() {
-        WordContainer wordContainer = new WordContainer();
-        wordContainer.word = WordFactory.signed(42);
-    }
-
-    @Test
-    public void testWordField() throws Exception {
-        testHelper("testWordFieldSnippet", 0);
-    }
-
-    public static Word[] testWordArraySnippet(int length) {
-        Word fortyTwo = WordFactory.signed(42);
-        Word[] words = new Word[length];
-        for (int i = 0; i < length; i++) {
-            words[i] = fortyTwo;
-        }
-        return words;
-    }
-
-    @Test
-    public void testWordArray() throws Exception {
-        testHelper("testWordArraySnippet", 0);
-    }
-
     public static Object testUnsafeLoad(Unsafe theUnsafe, Object a, Object b, Object c) throws Exception {
         final int offset = (c == null ? 0 : ((Integer) c).intValue());
         final long displacement = (b == null ? 0 : ((Long) b).longValue());
@@ -311,7 +281,7 @@
             new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, highContext);
             new GuardLoweringPhase().apply(graph, midContext);
             new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, midContext);
-            new WriteBarrierAdditionPhase(config).apply(graph);
+            new WriteBarrierAdditionPhase().apply(graph, midContext);
             debug.dump(DebugContext.BASIC_LEVEL, graph, "After Write Barrier Addition");
 
             int barriers = 0;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/WriteBarrierVerificationTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,737 +0,0 @@
-/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package org.graalvm.compiler.hotspot.test;
-
-import java.util.List;
-
-import jdk.internal.vm.compiler.collections.EconomicMap;
-import org.graalvm.compiler.debug.DebugCloseable;
-import org.graalvm.compiler.debug.DebugContext;
-import org.graalvm.compiler.debug.DebugContext.Scope;
-import org.graalvm.compiler.debug.DebugDumpScope;
-import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
-import org.graalvm.compiler.hotspot.gc.g1.G1ArrayRangePostWriteBarrier;
-import org.graalvm.compiler.hotspot.gc.g1.G1ArrayRangePreWriteBarrier;
-import org.graalvm.compiler.hotspot.gc.g1.G1PostWriteBarrier;
-import org.graalvm.compiler.hotspot.gc.g1.G1PreWriteBarrier;
-import org.graalvm.compiler.hotspot.gc.shared.SerialArrayRangeWriteBarrier;
-import org.graalvm.compiler.hotspot.gc.shared.SerialWriteBarrier;
-import org.graalvm.compiler.hotspot.phases.WriteBarrierAdditionPhase;
-import org.graalvm.compiler.hotspot.phases.WriteBarrierVerificationPhase;
-import org.graalvm.compiler.nodes.AbstractBeginNode;
-import org.graalvm.compiler.nodes.AbstractMergeNode;
-import org.graalvm.compiler.nodes.FieldLocationIdentity;
-import org.graalvm.compiler.nodes.FixedNode;
-import org.graalvm.compiler.nodes.FixedWithNextNode;
-import org.graalvm.compiler.nodes.LoopBeginNode;
-import org.graalvm.compiler.nodes.LoopExitNode;
-import org.graalvm.compiler.nodes.StructuredGraph;
-import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
-import org.graalvm.compiler.nodes.memory.WriteNode;
-import org.graalvm.compiler.nodes.spi.LoweringTool;
-import org.graalvm.compiler.phases.OptimisticOptimizations;
-import org.graalvm.compiler.phases.common.CanonicalizerPhase;
-import org.graalvm.compiler.phases.common.GuardLoweringPhase;
-import org.graalvm.compiler.phases.common.LoopSafepointInsertionPhase;
-import org.graalvm.compiler.phases.common.LoweringPhase;
-import org.graalvm.compiler.phases.graph.ReentrantNodeIterator;
-import org.graalvm.compiler.phases.graph.ReentrantNodeIterator.NodeIteratorClosure;
-import org.graalvm.compiler.phases.tiers.HighTierContext;
-import org.graalvm.compiler.phases.tiers.MidTierContext;
-import jdk.internal.vm.compiler.word.LocationIdentity;
-import org.junit.Assert;
-import org.junit.Test;
-
-import jdk.vm.ci.meta.ResolvedJavaField;
-
-/**
- * The following tests validate the write barrier verification phase. For every tested snippet, an
- * array of write barrier indices and the total write barrier number are passed as parameters. The
- * indices denote the barriers that will be manually removed. The write barrier verification phase
- * runs after the write barrier removal and depending on the result an assertion might be generated.
- * The tests anticipate the presence or not of an assertion generated by the verification phase.
- */
-public class WriteBarrierVerificationTest extends HotSpotGraalCompilerTest {
-
-    public static int barrierIndex;
-
-    private final GraalHotSpotVMConfig config = runtime().getVMConfig();
-
-    public static class Container {
-
-        public Container a;
-        public Container b;
-    }
-
-    private static native void safepoint();
-
-    public static void test1Snippet(Container main) {
-        Container temp1 = new Container();
-        Container temp2 = new Container();
-        barrierIndex = 0;
-        safepoint();
-        barrierIndex = 1;
-        main.a = temp1;
-        safepoint();
-        barrierIndex = 2;
-        main.b = temp2;
-        safepoint();
-    }
-
-    @Test(expected = AssertionError.class)
-    public void test1() {
-        test("test1Snippet", 2, new int[]{1});
-    }
-
-    @Test(expected = AssertionError.class)
-    public void test2() {
-        test("test1Snippet", 2, new int[]{2});
-    }
-
-    public static void test2Snippet(Container main) {
-        Container temp1 = new Container();
-        Container temp2 = new Container();
-        barrierIndex = 0;
-        safepoint();
-        barrierIndex = 1;
-        main.a = temp1;
-        barrierIndex = 2;
-        main.b = temp2;
-        safepoint();
-    }
-
-    @Test(expected = AssertionError.class)
-    public void test3() {
-        test("test2Snippet", 2, new int[]{1});
-    }
-
-    @Test
-    public void test4() {
-        test("test2Snippet", 2, new int[]{2});
-    }
-
-    public static void test3Snippet(Container main, boolean test) {
-        Container temp1 = new Container();
-        Container temp2 = new Container();
-        barrierIndex = 0;
-        safepoint();
-        for (int i = 0; i < 10; i++) {
-            if (test) {
-                barrierIndex = 1;
-                main.a = temp1;
-                barrierIndex = 2;
-                main.b = temp2;
-            } else {
-                barrierIndex = 3;
-                main.a = temp1;
-                barrierIndex = 4;
-                main.b = temp2;
-            }
-        }
-    }
-
-    @Test(expected = AssertionError.class)
-    public void test5() {
-        test("test3Snippet", 4, new int[]{1, 2});
-    }
-
-    @Test(expected = AssertionError.class)
-    public void test6() {
-        test("test3Snippet", 4, new int[]{3, 4});
-    }
-
-    @Test(expected = AssertionError.class)
-    public void test7() {
-        test("test3Snippet", 4, new int[]{1});
-    }
-
-    @Test
-    public void test8() {
-        test("test3Snippet", 4, new int[]{2});
-    }
-
-    @Test(expected = AssertionError.class)
-    public void test9() {
-        test("test3Snippet", 4, new int[]{3});
-    }
-
-    @Test
-    public void test10() {
-        test("test3Snippet", 4, new int[]{4});
-    }
-
-    public static void test4Snippet(Container main, boolean test) {
-        Container temp1 = new Container();
-        Container temp2 = new Container();
-        safepoint();
-        barrierIndex = 1;
-        main.a = temp1;
-        for (int i = 0; i < 10; i++) {
-            if (test) {
-                barrierIndex = 2;
-                main.a = temp1;
-                barrierIndex = 3;
-                main.b = temp2;
-            } else {
-                barrierIndex = 4;
-                main.a = temp2;
-                barrierIndex = 5;
-                main.b = temp1;
-            }
-        }
-    }
-
-    @Test(expected = AssertionError.class)
-    public void test11() {
-        test("test4Snippet", 5, new int[]{2, 3});
-    }
-
-    @Test(expected = AssertionError.class)
-    public void test12() {
-        test("test4Snippet", 5, new int[]{4, 5});
-    }
-
-    @Test(expected = AssertionError.class)
-    public void test13() {
-        test("test4Snippet", 5, new int[]{1});
-    }
-
-    public static void test5Snippet(Container main) {
-        Container temp1 = new Container();
-        Container temp2 = new Container();
-        safepoint();
-        barrierIndex = 1;
-        main.a = temp1;
-        if (main.a == main.b) {
-            barrierIndex = 2;
-            main.a = temp1;
-            barrierIndex = 3;
-            main.b = temp2;
-        } else {
-            barrierIndex = 4;
-            main.a = temp2;
-            barrierIndex = 5;
-            main.b = temp1;
-        }
-        safepoint();
-    }
-
-    @Test(expected = AssertionError.class)
-    public void test14() {
-        test("test5Snippet", 5, new int[]{1});
-    }
-
-    @Test
-    public void test15() {
-        test("test5Snippet", 5, new int[]{2});
-    }
-
-    @Test
-    public void test16() {
-        test("test5Snippet", 5, new int[]{4});
-    }
-
-    @Test
-    public void test17() {
-        test("test5Snippet", 5, new int[]{3});
-    }
-
-    @Test
-    public void test18() {
-        test("test5Snippet", 5, new int[]{5});
-    }
-
-    @Test
-    public void test19() {
-        test("test5Snippet", 5, new int[]{2, 3});
-    }
-
-    @Test
-    public void test20() {
-        test("test5Snippet", 5, new int[]{4, 5});
-    }
-
-    public static void test6Snippet(Container main, boolean test) {
-        Container temp1 = new Container();
-        Container temp2 = new Container();
-        safepoint();
-        barrierIndex = 1;
-        main.a = temp1;
-        if (test) {
-            barrierIndex = 2;
-            main.a = temp1;
-            barrierIndex = 3;
-            main.b = temp1.a.a;
-        } else {
-            barrierIndex = 4;
-            main.a = temp2;
-            barrierIndex = 5;
-            main.b = temp2.a.a;
-        }
-        safepoint();
-    }
-
-    @Test(expected = AssertionError.class)
-    public void test21() {
-        test("test6Snippet", 5, new int[]{1});
-    }
-
-    @Test(expected = AssertionError.class)
-    public void test22() {
-        test("test6Snippet", 5, new int[]{1, 2});
-    }
-
-    @Test
-    public void test23() {
-        test("test6Snippet", 5, new int[]{3});
-    }
-
-    @Test
-    public void test24() {
-        test("test6Snippet", 5, new int[]{4});
-    }
-
-    public static void test7Snippet(Container main, boolean test) {
-        Container temp1 = new Container();
-        Container temp2 = new Container();
-        safepoint();
-        barrierIndex = 1;
-        main.a = temp1;
-        if (test) {
-            barrierIndex = 2;
-            main.a = temp1;
-        }
-        barrierIndex = 3;
-        main.b = temp2;
-        safepoint();
-    }
-
-    @Test
-    public void test25() {
-        test("test7Snippet", 3, new int[]{2});
-    }
-
-    @Test
-    public void test26() {
-        test("test7Snippet", 3, new int[]{3});
-    }
-
-    @Test
-    public void test27() {
-        test("test7Snippet", 3, new int[]{2, 3});
-    }
-
-    @Test(expected = AssertionError.class)
-    public void test28() {
-        test("test7Snippet", 3, new int[]{1});
-    }
-
-    public static void test8Snippet(Container main, boolean test) {
-        Container temp1 = new Container();
-        Container temp2 = new Container();
-        safepoint();
-        if (test) {
-            barrierIndex = 1;
-            main.a = temp1;
-        }
-        barrierIndex = 2;
-        main.b = temp2;
-        safepoint();
-    }
-
-    @Test(expected = AssertionError.class)
-    public void test29() {
-        test("test8Snippet", 2, new int[]{1});
-    }
-
-    @Test(expected = AssertionError.class)
-    public void test30() {
-        test("test8Snippet", 2, new int[]{2});
-    }
-
-    @Test(expected = AssertionError.class)
-    public void test31() {
-        test("test8Snippet", 2, new int[]{1, 2});
-    }
-
-    public static void test9Snippet(Container main1, Container main2, boolean test) {
-        Container temp1 = new Container();
-        Container temp2 = new Container();
-        safepoint();
-        if (test) {
-            barrierIndex = 1;
-            main1.a = temp1;
-        } else {
-            barrierIndex = 2;
-            main2.a = temp1;
-        }
-        barrierIndex = 3;
-        main1.b = temp2;
-        barrierIndex = 4;
-        main2.b = temp2;
-        safepoint();
-    }
-
-    @Test(expected = AssertionError.class)
-    public void test32() {
-        test("test9Snippet", 4, new int[]{1});
-    }
-
-    @Test(expected = AssertionError.class)
-    public void test33() {
-        test("test9Snippet", 4, new int[]{2});
-    }
-
-    @Test(expected = AssertionError.class)
-    public void test34() {
-        test("test9Snippet", 4, new int[]{3});
-    }
-
-    @Test(expected = AssertionError.class)
-    public void test35() {
-        test("test9Snippet", 4, new int[]{4});
-    }
-
-    @Test(expected = AssertionError.class)
-    public void test36() {
-        test("test9Snippet", 4, new int[]{1, 2});
-    }
-
-    @Test(expected = AssertionError.class)
-    public void test37() {
-        test("test9Snippet", 4, new int[]{3, 4});
-    }
-
-    public static void test10Snippet(Container main1, Container main2, boolean test) {
-        Container temp1 = new Container();
-        Container temp2 = new Container();
-        safepoint();
-        if (test) {
-            barrierIndex = 1;
-            main1.a = temp1;
-            barrierIndex = 2;
-            main2.a = temp2;
-        } else {
-            barrierIndex = 3;
-            main2.a = temp1;
-        }
-        barrierIndex = 4;
-        main1.b = temp2;
-        barrierIndex = 5;
-        main2.b = temp2;
-        safepoint();
-    }
-
-    @Test(expected = AssertionError.class)
-    public void test38() {
-        test("test10Snippet", 5, new int[]{1});
-    }
-
-    @Test(expected = AssertionError.class)
-    public void test39() {
-        test("test10Snippet", 5, new int[]{2});
-    }
-
-    @Test(expected = AssertionError.class)
-    public void test40() {
-        test("test10Snippet", 5, new int[]{3});
-    }
-
-    @Test(expected = AssertionError.class)
-    public void test41() {
-        test("test10Snippet", 5, new int[]{4});
-    }
-
-    @Test
-    public void test42() {
-        test("test10Snippet", 5, new int[]{5});
-    }
-
-    @Test(expected = AssertionError.class)
-    public void test43() {
-        test("test10Snippet", 5, new int[]{1, 2});
-    }
-
-    @Test(expected = AssertionError.class)
-    public void test44() {
-        test("test10Snippet", 5, new int[]{1, 2, 3});
-    }
-
-    @Test(expected = AssertionError.class)
-    public void test45() {
-        test("test10Snippet", 5, new int[]{3, 4});
-    }
-
-    public static void test11Snippet(Container main1, Container main2, Container main3, boolean test) {
-        Container temp1 = new Container();
-        Container temp2 = new Container();
-        safepoint();
-        if (test) {
-            barrierIndex = 1;
-            main1.a = temp1;
-            barrierIndex = 2;
-            main3.a = temp1;
-            if (!test) {
-                barrierIndex = 3;
-                main2.a = temp2;
-            } else {
-                barrierIndex = 4;
-                main1.a = temp2;
-                barrierIndex = 5;
-                main3.a = temp2;
-            }
-        } else {
-            barrierIndex = 6;
-            main1.b = temp2;
-            for (int i = 0; i < 10; i++) {
-                barrierIndex = 7;
-                main3.a = temp1;
-            }
-            barrierIndex = 8;
-            main3.b = temp2;
-        }
-        barrierIndex = 9;
-        main1.b = temp2;
-        barrierIndex = 10;
-        main2.b = temp2;
-        barrierIndex = 11;
-        main3.b = temp2;
-        safepoint();
-    }
-
-    @Test(expected = AssertionError.class)
-    public void test46() {
-        test("test11Snippet", 11, new int[]{1});
-    }
-
-    @Test(expected = AssertionError.class)
-    public void test47() {
-        test("test11Snippet", 11, new int[]{2});
-    }
-
-    @Test(expected = AssertionError.class)
-    public void test48() {
-        test("test11Snippet", 11, new int[]{3});
-    }
-
-    @Test(expected = AssertionError.class)
-    public void test49() {
-        test("test11Snippet", 11, new int[]{6});
-    }
-
-    @Test(expected = AssertionError.class)
-    public void test50() {
-        test("test11Snippet", 11, new int[]{7});
-    }
-
-    @Test(expected = AssertionError.class)
-    public void test51() {
-        test("test11Snippet", 11, new int[]{8});
-    }
-
-    @Test(expected = AssertionError.class)
-    public void test52() {
-        test("test11Snippet", 11, new int[]{9});
-    }
-
-    @Test(expected = AssertionError.class)
-    public void test53() {
-        test("test11Snippet", 11, new int[]{10});
-    }
-
-    @Test
-    public void test54() {
-        test("test11Snippet", 11, new int[]{4});
-    }
-
-    @Test
-    public void test55() {
-        test("test11Snippet", 11, new int[]{5});
-    }
-
-    @Test
-    public void test56() {
-        test("test11Snippet", 11, new int[]{11});
-    }
-
-    public static void test12Snippet(Container main, Container main1, boolean test) {
-        Container temp1 = new Container();
-        Container temp2 = new Container();
-        barrierIndex = 0;
-        safepoint();
-        barrierIndex = 7;
-        main1.a = temp1;
-        for (int i = 0; i < 10; i++) {
-            if (test) {
-                barrierIndex = 1;
-                main.a = temp1;
-                barrierIndex = 2;
-                main.b = temp2;
-            } else {
-                barrierIndex = 3;
-                main.a = temp1;
-                barrierIndex = 4;
-                main.b = temp2;
-            }
-        }
-        barrierIndex = 5;
-        main.a = temp1;
-        barrierIndex = 6;
-        main.b = temp1;
-        barrierIndex = 8;
-        main1.b = temp1;
-        safepoint();
-    }
-
-    @Test(expected = AssertionError.class)
-    public void test57() {
-        test("test12Snippet", 8, new int[]{5});
-    }
-
-    @Test
-    public void test58() {
-        test("test12Snippet", 8, new int[]{6});
-    }
-
-    @Test(expected = AssertionError.class)
-    public void test59() {
-        test("test12Snippet", 8, new int[]{7});
-    }
-
-    @Test(expected = AssertionError.class)
-    public void test60() {
-        test("test12Snippet", 8, new int[]{8});
-    }
-
-    public static void test13Snippet(Object[] a, Object[] b) {
-        System.arraycopy(a, 0, b, 0, a.length);
-    }
-
-    private interface GraphPredicate {
-        int apply(StructuredGraph graph);
-    }
-
-    private void test(final String snippet, final int expectedBarriers, final int... removedBarrierIndices) {
-        GraphPredicate noCheck = noArg -> expectedBarriers;
-        testPredicate(snippet, noCheck, removedBarrierIndices);
-    }
-
-    @SuppressWarnings("try")
-    private void testPredicate(final String snippet, final GraphPredicate expectedBarriers, final int... removedBarrierIndices) {
-        DebugContext debug = getDebugContext();
-        try (DebugCloseable d = debug.disableIntercept(); DebugContext.Scope s = debug.scope("WriteBarrierVerificationTest", new DebugDumpScope(snippet))) {
-            final StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES, debug);
-            HighTierContext highTierContext = getDefaultHighTierContext();
-            createInliningPhase().apply(graph, highTierContext);
-
-            MidTierContext midTierContext = new MidTierContext(getProviders(), getTargetProvider(), OptimisticOptimizations.ALL, graph.getProfilingInfo());
-
-            new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, highTierContext);
-            new GuardLoweringPhase().apply(graph, midTierContext);
-            new LoopSafepointInsertionPhase().apply(graph);
-            new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, highTierContext);
-
-            new WriteBarrierAdditionPhase(config).apply(graph);
-
-            int barriers = 0;
-            // First, the total number of expected barriers is checked.
-            if (config.useG1GC) {
-                barriers = graph.getNodes().filter(G1PreWriteBarrier.class).count() + graph.getNodes().filter(G1PostWriteBarrier.class).count() +
-                                graph.getNodes().filter(G1ArrayRangePreWriteBarrier.class).count() + graph.getNodes().filter(G1ArrayRangePostWriteBarrier.class).count();
-                Assert.assertTrue(expectedBarriers.apply(graph) * 2 == barriers);
-            } else {
-                barriers = graph.getNodes().filter(SerialWriteBarrier.class).count() + graph.getNodes().filter(SerialArrayRangeWriteBarrier.class).count();
-                Assert.assertTrue(expectedBarriers.apply(graph) == barriers);
-            }
-            ResolvedJavaField barrierIndexField = getMetaAccess().lookupJavaField(WriteBarrierVerificationTest.class.getDeclaredField("barrierIndex"));
-            LocationIdentity barrierIdentity = new FieldLocationIdentity(barrierIndexField);
-            // Iterate over all write nodes and remove barriers according to input indices.
-            NodeIteratorClosure<Boolean> closure = new NodeIteratorClosure<Boolean>() {
-
-                @Override
-                protected Boolean processNode(FixedNode node, Boolean currentState) {
-                    if (node instanceof WriteNode) {
-                        WriteNode write = (WriteNode) node;
-                        LocationIdentity obj = write.getLocationIdentity();
-                        if (obj.equals(barrierIdentity)) {
-                            /*
-                             * A "barrierIndex" variable was found and is checked against the input
-                             * barrier array.
-                             */
-                            if (eliminateBarrier(write.value().asJavaConstant().asInt(), removedBarrierIndices)) {
-                                return true;
-                            }
-                        }
-                    } else if (node instanceof SerialWriteBarrier || node instanceof G1PostWriteBarrier) {
-                        // Remove flagged write barriers.
-                        if (currentState) {
-                            graph.removeFixed(((FixedWithNextNode) node));
-                            return false;
-                        }
-                    }
-                    return currentState;
-                }
-
-                private boolean eliminateBarrier(int index, int[] map) {
-                    for (int i = 0; i < map.length; i++) {
-                        if (map[i] == index) {
-                            return true;
-                        }
-                    }
-                    return false;
-                }
-
-                @Override
-                protected EconomicMap<LoopExitNode, Boolean> processLoop(LoopBeginNode loop, Boolean initialState) {
-                    return ReentrantNodeIterator.processLoop(this, loop, initialState).exitStates;
-                }
-
-                @Override
-                protected Boolean merge(AbstractMergeNode merge, List<Boolean> states) {
-                    return false;
-                }
-
-                @Override
-                protected Boolean afterSplit(AbstractBeginNode node, Boolean oldState) {
-                    return false;
-                }
-            };
-
-            try (Scope disabled = debug.disable()) {
-                ReentrantNodeIterator.apply(closure, graph.start(), false);
-                new WriteBarrierVerificationPhase(config).apply(graph);
-            } catch (AssertionError error) {
-                /*
-                 * Catch assertion, test for expected one and re-throw in order to validate unit
-                 * test.
-                 */
-                Assert.assertTrue(error.getMessage().contains("Write barrier must be present"));
-                throw error;
-            }
-        } catch (Throwable e) {
-            throw debug.handle(e);
-        }
-    }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationTask.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationTask.java	Mon Jul 01 14:57:02 2019 -0700
@@ -32,6 +32,8 @@
 import static org.graalvm.compiler.java.BytecodeParserOptions.InlineDuringParsing;
 
 import java.io.PrintStream;
+import java.util.Collections;
+import java.util.List;
 
 import jdk.internal.vm.compiler.collections.EconomicMap;
 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
@@ -42,7 +44,9 @@
 import org.graalvm.compiler.debug.CounterKey;
 import org.graalvm.compiler.debug.DebugCloseable;
 import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.debug.DebugContext.Description;
 import org.graalvm.compiler.debug.DebugDumpScope;
+import org.graalvm.compiler.debug.DebugHandlersFactory;
 import org.graalvm.compiler.debug.TimerKey;
 import org.graalvm.compiler.options.OptionKey;
 import org.graalvm.compiler.options.OptionValues;
@@ -85,9 +89,11 @@
         }
 
         @Override
-        protected DebugContext createRetryDebugContext(OptionValues retryOptions, PrintStream logStream) {
+        protected DebugContext createRetryDebugContext(DebugContext initialDebug, OptionValues retryOptions, PrintStream logStream) {
             SnippetReflectionProvider snippetReflection = compiler.getGraalRuntime().getHostProviders().getSnippetReflection();
-            return DebugContext.create(retryOptions, logStream, new GraalDebugHandlersFactory(snippetReflection));
+            Description description = initialDebug.getDescription();
+            List<DebugHandlersFactory> factories = Collections.singletonList(new GraalDebugHandlersFactory(snippetReflection));
+            return DebugContext.create(retryOptions, description, initialDebug.getGlobalMetrics(), logStream, factories);
         }
 
         @Override
@@ -183,11 +189,19 @@
 
     }
 
-    public CompilationTask(HotSpotJVMCIRuntime jvmciRuntime, HotSpotGraalCompiler compiler, HotSpotCompilationRequest request, boolean useProfilingInfo, boolean installAsDefault) {
+    public CompilationTask(HotSpotJVMCIRuntime jvmciRuntime,
+                    HotSpotGraalCompiler compiler,
+                    HotSpotCompilationRequest request,
+                    boolean useProfilingInfo,
+                    boolean installAsDefault) {
         this(jvmciRuntime, compiler, request, useProfilingInfo, false, installAsDefault);
     }
 
-    public CompilationTask(HotSpotJVMCIRuntime jvmciRuntime, HotSpotGraalCompiler compiler, HotSpotCompilationRequest request, boolean useProfilingInfo, boolean shouldRetainLocalVariables,
+    public CompilationTask(HotSpotJVMCIRuntime jvmciRuntime,
+                    HotSpotGraalCompiler compiler,
+                    HotSpotCompilationRequest request,
+                    boolean useProfilingInfo,
+                    boolean shouldRetainLocalVariables,
                     boolean installAsDefault) {
         this.jvmciRuntime = jvmciRuntime;
         this.compiler = compiler;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationWatchDog.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationWatchDog.java	Mon Jul 01 14:57:02 2019 -0700
@@ -28,6 +28,7 @@
 
 import java.util.Arrays;
 
+import org.graalvm.compiler.core.GraalServiceThread;
 import org.graalvm.compiler.debug.TTY;
 import org.graalvm.compiler.options.Option;
 import org.graalvm.compiler.options.OptionKey;
@@ -49,10 +50,10 @@
  * dog reports a long running compilation. Every
  * {@link Options#CompilationWatchDogStackTraceInterval} seconds after that point in time where the
  * same compilation is still executing, the watch dog takes a stack trace of the compiler thread. If
- * more than {@value Options#NonFatalIdenticalCompilationSnapshots} contiguous identical stack
- * traces are seen, the watch dog reports a stuck compilation and exits the VM.
+ * more than {@link Options#NonFatalIdenticalCompilationSnapshots} contiguous identical stack traces
+ * are seen, the watch dog reports a stuck compilation and exits the VM.
  */
-class CompilationWatchDog extends Thread implements AutoCloseable {
+class CompilationWatchDog implements Runnable, AutoCloseable {
 
     public static class Options {
         // @formatter:off
@@ -112,9 +113,6 @@
 
     CompilationWatchDog(Thread compilerThread, long startDelayMilliseconds, long stackTraceIntervalMilliseconds, int nonFatalIdenticalCompilationSnapshots) {
         this.compilerThread = compilerThread;
-        this.setName("WatchDog" + getId() + "[" + compilerThread.getName() + "]");
-        this.setPriority(Thread.MAX_PRIORITY);
-        this.setDaemon(true);
         this.startDelayMilliseconds = startDelayMilliseconds;
         this.stackTraceIntervalMilliseconds = stackTraceIntervalMilliseconds;
         this.nonFatalIdenticalCompilationSnapshots = nonFatalIdenticalCompilationSnapshots;
@@ -185,7 +183,7 @@
 
     @Override
     public String toString() {
-        return getName();
+        return "WatchDog[" + compilerThread.getName() + "]";
     }
 
     @Override
@@ -305,12 +303,16 @@
             // Lazily get a watch dog thread for the current compiler thread
             CompilationWatchDog watchDog = WATCH_DOGS.get();
             if (watchDog == null) {
-                Thread currentThread = currentThread();
+                Thread currentThread = Thread.currentThread();
                 long stackTraceIntervalMilliseconds = ms(Options.CompilationWatchDogStackTraceInterval.getValue(options));
                 int nonFatalIdenticalCompilationSnapshots = Options.NonFatalIdenticalCompilationSnapshots.getValue(options);
                 watchDog = new CompilationWatchDog(currentThread, startDelayMilliseconds, stackTraceIntervalMilliseconds, nonFatalIdenticalCompilationSnapshots);
                 WATCH_DOGS.set(watchDog);
-                watchDog.start();
+                GraalServiceThread thread = new GraalServiceThread(watchDog);
+                thread.setName(thread.getId() + " " + watchDog.toString());
+                thread.setPriority(Thread.MAX_PRIORITY);
+                thread.setDaemon(true);
+                thread.start();
             }
             watchDog.startCompilation(method, id);
             return watchDog;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilerConfigurationFactory.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilerConfigurationFactory.java	Mon Jul 01 14:57:02 2019 -0700
@@ -42,6 +42,7 @@
 import org.graalvm.compiler.options.EnumOptionKey;
 import org.graalvm.compiler.options.Option;
 import org.graalvm.compiler.options.OptionKey;
+import org.graalvm.compiler.options.OptionStability;
 import org.graalvm.compiler.options.OptionType;
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.phases.BasePhase;
@@ -53,9 +54,9 @@
 import jdk.vm.ci.common.InitTimer;
 
 /**
- * A factory that creates the {@link CompilerConfiguration} the Graal compiler will use. Each
- * factory must have a unique {@link #name} and {@link #autoSelectionPriority}. The latter imposes a
- * total ordering between factories for the purpose of auto-selecting the factory to use.
+ * A factory that creates the {@link CompilerConfiguration} the compiler will use. Each factory must
+ * have a unique {@link #name} and {@link #autoSelectionPriority}. The latter imposes a total
+ * ordering between factories for the purpose of auto-selecting the factory to use.
  */
 public abstract class CompilerConfigurationFactory implements Comparable<CompilerConfigurationFactory> {
 
@@ -67,11 +68,11 @@
 
     static class Options {
         // @formatter:off
-        @Option(help = "Names the Graal compiler configuration to use. If omitted, the compiler configuration " +
+        @Option(help = "Names the compiler configuration to use. If omitted, the compiler configuration " +
                        "with the highest auto-selection priority is used. To see the set of available configurations, " +
-                       "supply the value 'help' to this option.", type = OptionType.Expert)
+                       "supply the value 'help' to this option.", type = OptionType.Expert, stability = OptionStability.STABLE)
         public static final OptionKey<String> CompilerConfiguration = new OptionKey<>(null);
-        @Option(help = "Writes to the VM log information about the Graal compiler configuration selected.", type = OptionType.User)
+        @Option(help = "Writes to the VM log information about the compiler configuration selected.", type = OptionType.User, stability = OptionStability.STABLE)
         public static final OptionKey<ShowConfigurationLevel> ShowConfiguration = new EnumOptionKey<>(ShowConfigurationLevel.none);
         // @formatter:on
     }
@@ -195,7 +196,7 @@
         try (InitTimer t = timer("CompilerConfigurationFactory.selectFactory")) {
             String value = name == null ? Options.CompilerConfiguration.getValue(options) : name;
             if ("help".equals(value)) {
-                System.out.println("The available Graal compiler configurations are:");
+                System.out.println("The available compiler configurations are:");
                 for (CompilerConfigurationFactory candidate : getAllCandidates()) {
                     System.out.println("    " + candidate.name);
                 }
@@ -208,7 +209,7 @@
                     }
                 }
                 if (factory == null) {
-                    throw new GraalError("Graal compiler configuration '%s' not found. Available configurations are: %s", value,
+                    throw new GraalError("Compiler configuration '%s' not found. Available configurations are: %s", value,
                                     getAllCandidates().stream().map(c -> c.name).collect(Collectors.joining(", ")));
                 }
             } else {
@@ -247,7 +248,7 @@
 
     private static void printConfigInfo(CompilerConfigurationFactory factory) {
         URL location = factory.getClass().getResource(factory.getClass().getSimpleName() + ".class");
-        TTY.printf("Using Graal compiler configuration '%s' provided by %s loaded from %s%n", factory.name, factory.getClass().getName(), location);
+        TTY.printf("Using compiler configuration '%s' provided by %s loaded from %s%n", factory.name, factory.getClass().getName(), location);
     }
 
     private static <C> List<String> phaseNames(PhaseSuite<C> suite) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotBackend.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotBackend.java	Mon Jul 01 14:57:02 2019 -0700
@@ -97,7 +97,7 @@
     public static class Options {
         // @formatter:off
         @Option(help = "Use Graal arithmetic stubs instead of HotSpot stubs where possible")
-        public static final OptionKey<Boolean> GraalArithmeticStubs = new OptionKey<>(JavaVersionUtil.JAVA_SPECIFICATION_VERSION >= 9);
+        public static final OptionKey<Boolean> GraalArithmeticStubs = new OptionKey<>(JavaVersionUtil.JAVA_SPEC >= 9);
         @Option(help = "Enables instruction profiling on assembler level. Valid values are a comma separated list of supported instructions." +
                         " Compare with subclasses of Assembler.InstructionCounter.", type = OptionType.Debug)
         public static final OptionKey<String> ASMInstructionProfiling = new OptionKey<>(null);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotBackendFactory.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotBackendFactory.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,25 +24,64 @@
 
 package org.graalvm.compiler.hotspot;
 
+import org.graalvm.compiler.bytecode.BytecodeProvider;
+import org.graalvm.compiler.hotspot.meta.HotSpotGCProvider;
+import org.graalvm.compiler.hotspot.meta.HotSpotGraalConstantFieldProvider;
+import org.graalvm.compiler.hotspot.meta.HotSpotSnippetReflectionProvider;
+import org.graalvm.compiler.hotspot.meta.HotSpotStampProvider;
+import org.graalvm.compiler.hotspot.word.HotSpotWordTypes;
 import org.graalvm.compiler.phases.tiers.CompilerConfiguration;
+import org.graalvm.compiler.phases.util.Providers;
+import org.graalvm.compiler.replacements.classfile.ClassfileBytecodeProvider;
 
 import jdk.vm.ci.code.Architecture;
+import jdk.vm.ci.code.TargetDescription;
+import jdk.vm.ci.hotspot.HotSpotConstantReflectionProvider;
 import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
+import jdk.vm.ci.hotspot.HotSpotMetaAccessProvider;
+
+public abstract class HotSpotBackendFactory {
+
+    protected HotSpotGraalConstantFieldProvider createConstantFieldProvider(GraalHotSpotVMConfig config, HotSpotMetaAccessProvider metaAccess) {
+        return new HotSpotGraalConstantFieldProvider(config, metaAccess);
+    }
+
+    protected HotSpotWordTypes createWordTypes(HotSpotMetaAccessProvider metaAccess, TargetDescription target) {
+        return new HotSpotWordTypes(metaAccess, target.wordJavaKind);
+    }
 
-public interface HotSpotBackendFactory {
+    protected HotSpotStampProvider createStampProvider() {
+        return new HotSpotStampProvider();
+    }
+
+    protected HotSpotGCProvider createGCProvider(GraalHotSpotVMConfig config) {
+        return new HotSpotGCProvider(config);
+    }
+
+    protected HotSpotReplacementsImpl createReplacements(TargetDescription target, Providers p, HotSpotSnippetReflectionProvider snippetReflection, BytecodeProvider bytecodeProvider) {
+        return new HotSpotReplacementsImpl(p, snippetReflection, bytecodeProvider, target);
+    }
+
+    protected ClassfileBytecodeProvider createBytecodeProvider(HotSpotMetaAccessProvider metaAccess, HotSpotSnippetReflectionProvider snippetReflection) {
+        return new ClassfileBytecodeProvider(metaAccess, snippetReflection);
+    }
+
+    protected HotSpotSnippetReflectionProvider createSnippetReflection(HotSpotGraalRuntimeProvider runtime, HotSpotConstantReflectionProvider constantReflection, HotSpotWordTypes wordTypes) {
+        return new HotSpotSnippetReflectionProvider(runtime, constantReflection, wordTypes);
+    }
 
     /**
      * Gets the name of this backend factory. This should not include the {@link #getArchitecture()
      * architecture}. The {@link CompilerConfigurationFactory} can select alternative backends based
      * on this name.
      */
-    String getName();
+    public abstract String getName();
 
     /**
      * Gets the class describing the architecture the backend created by this factory is associated
      * with.
      */
-    Class<? extends Architecture> getArchitecture();
+    public abstract Class<? extends Architecture> getArchitecture();
 
-    HotSpotBackend createBackend(HotSpotGraalRuntimeProvider runtime, CompilerConfiguration compilerConfiguration, HotSpotJVMCIRuntime jvmciRuntime, HotSpotBackend host);
+    public abstract HotSpotBackend createBackend(HotSpotGraalRuntimeProvider runtime, CompilerConfiguration compilerConfiguration, HotSpotJVMCIRuntime jvmciRuntime, HotSpotBackend host);
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompiler.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalCompiler.java	Mon Jul 01 14:57:02 2019 -0700
@@ -48,6 +48,7 @@
 import org.graalvm.compiler.java.GraphBuilderPhase;
 import org.graalvm.compiler.lir.asm.CompilationResultBuilderFactory;
 import org.graalvm.compiler.lir.phases.LIRSuites;
+import org.graalvm.compiler.nodes.Cancellable;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration;
@@ -74,7 +75,7 @@
 import jdk.vm.ci.runtime.JVMCICompiler;
 import sun.misc.Unsafe;
 
-public class HotSpotGraalCompiler implements GraalJVMCICompiler {
+public class HotSpotGraalCompiler implements GraalJVMCICompiler, Cancellable {
 
     private static final Unsafe UNSAFE = GraalUnsafeAccess.getUnsafe();
     private final HotSpotJVMCIRuntime jvmciRuntime;
@@ -86,7 +87,7 @@
     HotSpotGraalCompiler(HotSpotJVMCIRuntime jvmciRuntime, HotSpotGraalRuntimeProvider graalRuntime, OptionValues options) {
         this.jvmciRuntime = jvmciRuntime;
         this.graalRuntime = graalRuntime;
-        // It is sufficient to have one compilation counter object per Graal compiler object.
+        // It is sufficient to have one compilation counter object per compiler object.
         this.compilationCounters = Options.CompilationCountLimit.getValue(options) > 0 ? new CompilationCounters(options) : null;
         this.bootstrapWatchDog = graalRuntime.isBootstrapping() && !DebugOptions.BootstrapInitializeOnly.getValue(options) ? BootstrapWatchDog.maybeCreate(graalRuntime) : null;
     }
@@ -111,7 +112,7 @@
     @SuppressWarnings("try")
     CompilationRequestResult compileMethod(CompilationRequest request, boolean installAsDefault, OptionValues initialOptions) {
         if (graalRuntime.isShutdown()) {
-            return HotSpotCompilationRequestResult.failure(String.format("Shutdown entered"), false);
+            return HotSpotCompilationRequestResult.failure(String.format("Shutdown entered"), true);
         }
 
         ResolvedJavaMethod method = request.getMethod();
@@ -164,19 +165,31 @@
         return false;
     }
 
+    @Override
+    public boolean isCancelled() {
+        return graalRuntime.isShutdown();
+    }
+
     public StructuredGraph createGraph(ResolvedJavaMethod method, int entryBCI, boolean useProfilingInfo, CompilationIdentifier compilationId, OptionValues options, DebugContext debug) {
         HotSpotBackend backend = graalRuntime.getHostBackend();
         HotSpotProviders providers = backend.getProviders();
         final boolean isOSR = entryBCI != JVMCICompiler.INVOCATION_ENTRY_BCI;
-        StructuredGraph graph = method.isNative() || isOSR ? null : providers.getReplacements().getIntrinsicGraph(method, compilationId, debug);
+        StructuredGraph graph = method.isNative() || isOSR ? null : providers.getReplacements().getIntrinsicGraph(method, compilationId, debug, this);
 
         if (graph == null) {
             SpeculationLog speculationLog = method.getSpeculationLog();
             if (speculationLog != null) {
                 speculationLog.collectFailedSpeculations();
             }
-            graph = new StructuredGraph.Builder(options, debug, AllowAssumptions.ifTrue(OptAssumptions.getValue(options))).method(method).entryBCI(entryBCI).speculationLog(
-                            speculationLog).useProfilingInfo(useProfilingInfo).compilationId(compilationId).build();
+            // @formatter:off
+            graph = new StructuredGraph.Builder(options, debug, AllowAssumptions.ifTrue(OptAssumptions.getValue(options))).
+                            method(method).
+                            cancellable(this).
+                            entryBCI(entryBCI).
+                            speculationLog(speculationLog).
+                            useProfilingInfo(useProfilingInfo).
+                            compilationId(compilationId).build();
+            // @formatter:on
         }
         return graph;
     }
@@ -219,7 +232,11 @@
         return result;
     }
 
-    public CompilationResult compile(ResolvedJavaMethod method, int entryBCI, boolean useProfilingInfo, boolean shouldRetainLocalVariables, CompilationIdentifier compilationId,
+    public CompilationResult compile(ResolvedJavaMethod method,
+                    int entryBCI,
+                    boolean useProfilingInfo,
+                    boolean shouldRetainLocalVariables,
+                    CompilationIdentifier compilationId,
                     DebugContext debug) {
         StructuredGraph graph = createGraph(method, entryBCI, useProfilingInfo, compilationId, debug.getOptions(), debug);
         CompilationResult result = new CompilationResult(compilationId);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java	Mon Jul 01 14:57:02 2019 -0700
@@ -129,8 +129,6 @@
      */
     private AtomicReference<OptionValues> optionsRef = new AtomicReference<>();
 
-    private final HotSpotGraalCompiler compiler;
-
     private final DiagnosticsOutputDirectory outputDirectory;
     private final Map<ExceptionAction, Integer> compilationProblemsPerAction;
 
@@ -161,7 +159,6 @@
         CompilerConfiguration compilerConfiguration = compilerConfigurationFactory.createCompilerConfiguration();
         compilerConfigurationName = compilerConfigurationFactory.getName();
 
-        compiler = new HotSpotGraalCompiler(jvmciRuntime, this, options);
         if (IS_AOT) {
             management = null;
         } else {
@@ -367,7 +364,11 @@
     }
 
     private long runtimeStartTime;
-    private boolean shutdown;
+
+    /**
+     * Called from compiler threads to check whether to bail out of a compilation.
+     */
+    private volatile boolean shutdown;
 
     /**
      * Take action related to entering a new execution phase.
@@ -394,6 +395,16 @@
         BenchmarkCounters.shutdown(runtime(), optionsRef.get(), runtimeStartTime);
 
         outputDirectory.close();
+
+        shutdownLibGraal();
+    }
+
+    /**
+     * Substituted by
+     * {@code com.oracle.svm.graal.hotspot.libgraal.Target_org_graalvm_compiler_hotspot_HotSpotGraalRuntime}
+     * to call {@code org.graalvm.nativeimage.VMRuntime.shutdown()}.
+     */
+    private static void shutdownLibGraal() {
     }
 
     void clearMetrics() {
@@ -580,6 +591,7 @@
         extra.put(DebugOptions.PrintGraphHost, host);
         extra.put(DebugOptions.PrintGraphPort, port);
         OptionValues compileOptions = new OptionValues(getOptions(), extra);
+        HotSpotGraalCompiler compiler = (HotSpotGraalCompiler) runtime().getCompiler();
         compiler.compileMethod(new HotSpotCompilationRequest(hotSpotMethod, -1, 0L), false, compileOptions);
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalServices.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.hotspot;
+
+import jdk.vm.ci.hotspot.HotSpotMetaData;
+
+public class HotSpotGraalServices {
+
+    /**
+     * Get the implicit exceptions section of a {@code HotSpotMetaData} if it exists.
+     */
+    @SuppressWarnings("unused")
+    public static byte[] getImplicitExceptionBytes(HotSpotMetaData metaData) {
+        return metaData.implicitExceptionBytes();
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotReplacementsImpl.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotReplacementsImpl.java	Mon Jul 01 14:57:02 2019 -0700
@@ -41,6 +41,7 @@
 import org.graalvm.compiler.graph.NodeSourcePosition;
 import org.graalvm.compiler.hotspot.meta.HotSpotWordOperationPlugin;
 import org.graalvm.compiler.hotspot.word.HotSpotOperation;
+import org.graalvm.compiler.nodes.Cancellable;
 import org.graalvm.compiler.nodes.Invoke;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
@@ -91,7 +92,7 @@
     }
 
     @Override
-    public StructuredGraph getIntrinsicGraph(ResolvedJavaMethod method, CompilationIdentifier compilationId, DebugContext debug) {
+    public StructuredGraph getIntrinsicGraph(ResolvedJavaMethod method, CompilationIdentifier compilationId, DebugContext debug, Cancellable cancellable) {
         boolean useEncodedGraphs = UseEncodedGraphs.getValue(debug.getOptions());
         if (IS_IN_NATIVE_IMAGE || useEncodedGraphs) {
             HotSpotReplacementsImpl replacements = (HotSpotReplacementsImpl) providers.getReplacements();
@@ -101,13 +102,13 @@
                 if (useEncodedGraphs) {
                     replacements.registerMethodSubstitution(msp, method, ROOT_COMPILATION, debug.getOptions());
                 }
-                StructuredGraph methodSubstitution = replacements.getMethodSubstitution(msp, method, ROOT_COMPILATION, StructuredGraph.AllowAssumptions.YES, debug.getOptions());
+                StructuredGraph methodSubstitution = replacements.getMethodSubstitution(msp, method, ROOT_COMPILATION, StructuredGraph.AllowAssumptions.YES, cancellable, debug.getOptions());
                 methodSubstitution.resetDebug(debug);
                 return methodSubstitution;
             }
             return null;
         }
-        return super.getIntrinsicGraph(method, compilationId, debug);
+        return super.getIntrinsicGraph(method, compilationId, debug, cancellable);
     }
 
     @Override
@@ -122,7 +123,7 @@
                 }
                 // This assumes the normal path creates the graph using
                 // GraphBuilderConfiguration.getSnippetDefault with omits exception edges
-                StructuredGraph subst = getMethodSubstitution(msPlugin, targetMethod, INLINE_AFTER_PARSING, StructuredGraph.AllowAssumptions.NO, options);
+                StructuredGraph subst = getMethodSubstitution(msPlugin, targetMethod, INLINE_AFTER_PARSING, StructuredGraph.AllowAssumptions.NO, null, options);
                 return subst;
             }
         }
@@ -232,7 +233,7 @@
 
     @Override
     public StructuredGraph getMethodSubstitution(MethodSubstitutionPlugin plugin, ResolvedJavaMethod original, IntrinsicContext.CompilationContext context,
-                    StructuredGraph.AllowAssumptions allowAssumptions, OptionValues options) {
+                    StructuredGraph.AllowAssumptions allowAssumptions, Cancellable cancellable, OptionValues options) {
         boolean useEncodedGraphs = UseEncodedGraphs.getValue(options);
         if (IS_IN_NATIVE_IMAGE || useEncodedGraphs) {
             if (!IS_IN_NATIVE_IMAGE) {
@@ -242,7 +243,7 @@
             if (getEncodedSnippets() == null) {
                 throw GraalError.shouldNotReachHere("encoded snippets not found");
             }
-            return getEncodedSnippets().getMethodSubstitutionGraph(plugin, original, this, context, allowAssumptions, options);
+            return getEncodedSnippets().getMethodSubstitutionGraph(plugin, original, this, context, allowAssumptions, cancellable, options);
         }
         return null;
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotTTYStreamProvider.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotTTYStreamProvider.java	Mon Jul 01 14:57:02 2019 -0700
@@ -39,7 +39,6 @@
 import org.graalvm.compiler.options.Option;
 import org.graalvm.compiler.options.OptionKey;
 import org.graalvm.compiler.options.OptionType;
-import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.serviceprovider.GraalServices;
 import org.graalvm.compiler.serviceprovider.ServiceProvider;
 
@@ -60,7 +59,7 @@
 
     @Override
     public PrintStream getStream() {
-        return Options.LogFile.getStream(defaultOptions());
+        return Options.LogFile.getStream();
     }
 
     /**
@@ -96,22 +95,57 @@
          * operation is performed on the stream. This is required to break a deadlock in early JVMCI
          * initialization.
          */
-        static class DelayedOutputStream extends OutputStream {
+        class DelayedOutputStream extends OutputStream {
             private volatile OutputStream lazy;
 
             private OutputStream lazy() {
                 if (lazy == null) {
                     synchronized (this) {
                         if (lazy == null) {
+                            String nameTemplate = LogStreamOptionKey.this.getValue(defaultOptions());
+                            if (nameTemplate != null) {
+                                String name = makeFilename(nameTemplate);
+                                try {
+                                    final boolean enableAutoflush = true;
+                                    FileOutputStream result = new FileOutputStream(name);
+                                    if (!Services.IS_IN_NATIVE_IMAGE) {
+                                        printVMConfig(enableAutoflush, result);
+                                    } else {
+                                        // There are no VM arguments for the libgraal library.
+                                    }
+                                    lazy = result;
+                                    return lazy;
+                                } catch (FileNotFoundException e) {
+                                    throw new RuntimeException("couldn't open file: " + name, e);
+                                }
+                            }
+
                             lazy = HotSpotJVMCIRuntime.runtime().getLogStream();
                             PrintStream ps = new PrintStream(lazy);
                             ps.printf("[Use -D%sLogFile=<path> to redirect Graal log output to a file.]%n", GRAAL_OPTION_PROPERTY_PREFIX);
+                            ps.flush();
                         }
                     }
                 }
                 return lazy;
             }
 
+            @SuppressFBWarnings(value = "DLS_DEAD_LOCAL_STORE", justification = "false positive on dead store to `ps`")
+            private void printVMConfig(final boolean enableAutoflush, FileOutputStream result) {
+                /*
+                 * Add the JVM and Java arguments to the log file to help identity it.
+                 */
+                PrintStream ps = new PrintStream(result, enableAutoflush);
+                List<String> inputArguments = GraalServices.getInputArguments();
+                if (inputArguments != null) {
+                    ps.println("VM Arguments: " + String.join(" ", inputArguments));
+                }
+                String cmd = Services.getSavedProperties().get("sun.java.command");
+                if (cmd != null) {
+                    ps.println("sun.java.command=" + cmd);
+                }
+            }
+
             @Override
             public void write(byte[] b, int off, int len) throws IOException {
                 lazy().write(b, off, len);
@@ -137,32 +171,8 @@
          * Gets the print stream configured by this option. If no file is configured, the print
          * stream will output to HotSpot's {@link HotSpotJVMCIRuntime#getLogStream() log} stream.
          */
-        @SuppressFBWarnings(value = "DLS_DEAD_LOCAL_STORE", justification = "false positive on dead store to `ps`")
-        public PrintStream getStream(OptionValues options) {
-            String nameTemplate = getValue(options);
-            if (nameTemplate != null) {
-                String name = makeFilename(nameTemplate);
-                try {
-                    final boolean enableAutoflush = true;
-                    PrintStream ps = new PrintStream(new FileOutputStream(name), enableAutoflush);
-                    /*
-                     * Add the JVM and Java arguments to the log file to help identity it.
-                     */
-                    List<String> inputArguments = GraalServices.getInputArguments();
-                    if (inputArguments != null) {
-                        ps.println("VM Arguments: " + String.join(" ", inputArguments));
-                    }
-                    String cmd = Services.getSavedProperties().get("sun.java.command");
-                    if (cmd != null) {
-                        ps.println("sun.java.command=" + cmd);
-                    }
-                    return ps;
-                } catch (FileNotFoundException e) {
-                    throw new RuntimeException("couldn't open file: " + name, e);
-                }
-            } else {
-                return new PrintStream(new DelayedOutputStream());
-            }
+        public PrintStream getStream() {
+            return new PrintStream(new DelayedOutputStream());
         }
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/JVMCIVersionCheck.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/JVMCIVersionCheck.java	Mon Jul 01 14:57:02 2019 -0700
@@ -41,9 +41,8 @@
  */
 public final class JVMCIVersionCheck {
 
-    // 0.57 introduces HotSpotJVMCIRuntime.excludeFromJVMCICompilation
-    private static final int JVMCI8_MIN_MAJOR_VERSION = 0;
-    private static final int JVMCI8_MIN_MINOR_VERSION = 57;
+    private static final int JVMCI8_MIN_MAJOR_VERSION = 19;
+    private static final int JVMCI8_MIN_MINOR_VERSION = 1;
 
     private static void failVersionCheck(Map<String, String> props, boolean exit, String reason, Object... args) {
         Formatter errorMessage = new Formatter().format(reason, args);
@@ -55,7 +54,7 @@
         errorMessage.format("Currently used VM configuration is: %s%n", vmName);
         if (props.get("java.specification.version").compareTo("1.9") < 0) {
             errorMessage.format("Download the latest JVMCI JDK 8 from " +
-                            "http://www.oracle.com/technetwork/oracle-labs/program-languages/downloads/index.html or " +
+                            "https://www.oracle.com/technetwork/graalvm/downloads/index.html or " +
                             "https://github.com/graalvm/openjdk8-jvmci-builder/releases");
         } else {
             errorMessage.format("Download JDK 11 or later.");
@@ -156,6 +155,14 @@
         return false;
     }
 
+    private static String getJVMCIVersionString(int major, int minor) {
+        if (major >= 19) {
+            return String.format("%d-b%02d", major, minor);
+        } else {
+            return String.format("%d.%d", major, minor);
+        }
+    }
+
     private void run(boolean exitOnFailure, int jvmci8MinMajorVersion, int jvmci8MinMinorVersion) {
         // Don't use regular expressions to minimize Graal startup time
         if (javaSpecVersion.compareTo("1.9") < 0) {
@@ -180,8 +187,8 @@
                     if (major > jvmci8MinMajorVersion || (major >= jvmci8MinMajorVersion && minor >= jvmci8MinMinorVersion)) {
                         return;
                     }
-                    failVersionCheck(props, exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal: %d.%d < %d.%d.%n",
-                                    major, minor, jvmci8MinMajorVersion, jvmci8MinMinorVersion);
+                    failVersionCheck(props, exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal: %s < %s.%n",
+                                    getJVMCIVersionString(major, minor), getJVMCIVersionString(jvmci8MinMajorVersion, jvmci8MinMinorVersion));
                     return;
                 }
             }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/SymbolicSnippetEncoder.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/SymbolicSnippetEncoder.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -66,6 +66,7 @@
 import org.graalvm.compiler.java.GraphBuilderPhase;
 import org.graalvm.compiler.nodeinfo.Verbosity;
 import org.graalvm.compiler.nodes.CallTargetNode;
+import org.graalvm.compiler.nodes.Cancellable;
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.EncodedGraph;
 import org.graalvm.compiler.nodes.FrameState;
@@ -109,7 +110,6 @@
 import jdk.vm.ci.meta.ConstantReflectionProvider;
 import jdk.vm.ci.meta.JavaConstant;
 import jdk.vm.ci.meta.JavaKind;
-import jdk.vm.ci.meta.JavaType;
 import jdk.vm.ci.meta.MemoryAccessProvider;
 import jdk.vm.ci.meta.MethodHandleAccessProvider;
 import jdk.vm.ci.meta.ResolvedJavaField;
@@ -283,24 +283,30 @@
         }
 
         StructuredGraph getMethodSubstitutionGraph(MethodSubstitutionPlugin plugin, ResolvedJavaMethod original, ReplacementsImpl replacements, IntrinsicContext.CompilationContext context,
-                        StructuredGraph.AllowAssumptions allowAssumptions, OptionValues options) {
+                        StructuredGraph.AllowAssumptions allowAssumptions, Cancellable cancellable, OptionValues options) {
             Integer startOffset = snippetStartOffsets.get(plugin.toString() + context);
             if (startOffset == null) {
                 throw GraalError.shouldNotReachHere("plugin graph not found: " + plugin + " with " + context);
             }
 
             ResolvedJavaType accessingClass = replacements.getProviders().getMetaAccess().lookupJavaType(plugin.getDeclaringClass());
-            return decodeGraph(original, accessingClass, startOffset, replacements, context, allowAssumptions, options);
+            return decodeGraph(original, accessingClass, startOffset, replacements, context, allowAssumptions, cancellable, options);
         }
 
         @SuppressWarnings("try")
-        private StructuredGraph decodeGraph(ResolvedJavaMethod method, ResolvedJavaType accessingClass, int startOffset, ReplacementsImpl replacements,
-                        IntrinsicContext.CompilationContext context, StructuredGraph.AllowAssumptions allowAssumptions, OptionValues options) {
+        private StructuredGraph decodeGraph(ResolvedJavaMethod method,
+                        ResolvedJavaType accessingClass,
+                        int startOffset,
+                        ReplacementsImpl replacements,
+                        IntrinsicContext.CompilationContext context,
+                        StructuredGraph.AllowAssumptions allowAssumptions,
+                        Cancellable cancellable,
+                        OptionValues options) {
             Providers providers = replacements.getProviders();
             EncodedGraph encodedGraph = new SymbolicEncodedGraph(snippetEncoding, startOffset, snippetObjects, snippetNodeClasses,
                             methodKey(method), accessingClass, method.getDeclaringClass());
             try (DebugContext debug = replacements.openDebugContext("SVMSnippet_", method, options)) {
-                StructuredGraph result = new StructuredGraph.Builder(options, debug, allowAssumptions).method(method).setIsSubstitution(true).build();
+                StructuredGraph result = new StructuredGraph.Builder(options, debug, allowAssumptions).cancellable(cancellable).method(method).setIsSubstitution(true).build();
                 PEGraphDecoder graphDecoder = new SubstitutionGraphDecoder(providers, result, replacements, null, method, context, encodedGraph);
 
                 graphDecoder.decode(method, result.isSubstitution(), encodedGraph.trackNodeSourcePosition());
@@ -432,7 +438,7 @@
                             originalProvider.getConstantReflection());
             HotSpotProviders newProviders = new HotSpotProviders(originalProvider.getMetaAccess(), originalProvider.getCodeCache(), constantReflection,
                             originalProvider.getConstantFieldProvider(), originalProvider.getForeignCalls(), originalProvider.getLowerer(), null, originalProvider.getSuites(),
-                            originalProvider.getRegisters(), snippetReflection, originalProvider.getWordTypes(), originalProvider.getGraphBuilderPlugins());
+                            originalProvider.getRegisters(), snippetReflection, originalProvider.getWordTypes(), originalProvider.getGraphBuilderPlugins(), originalProvider.getGC());
             HotSpotSnippetReplacementsImpl filteringReplacements = new HotSpotSnippetReplacementsImpl(newProviders, snippetReflection,
                             originalProvider.getReplacements().getDefaultReplacementBytecodeProvider(), originalProvider.getCodeCache().getTarget());
             filteringReplacements.setGraphBuilderPlugins(originalProvider.getReplacements().getGraphBuilderPlugins());
@@ -1048,7 +1054,7 @@
         }
 
         @Override
-        protected boolean tryInvocationPlugin(CallTargetNode.InvokeKind invokeKind, ValueNode[] args, ResolvedJavaMethod targetMethod, JavaKind resultType, JavaType returnType) {
+        protected boolean tryInvocationPlugin(CallTargetNode.InvokeKind invokeKind, ValueNode[] args, ResolvedJavaMethod targetMethod, JavaKind resultType) {
             if (intrinsicContext != null && intrinsicContext.isCallToOriginal(targetMethod)) {
                 return false;
             }
@@ -1056,7 +1062,7 @@
                 // Always defer Fold until decode time but NodeIntrinsics may fold if they are able.
                 return false;
             }
-            return super.tryInvocationPlugin(invokeKind, args, targetMethod, resultType, returnType);
+            return super.tryInvocationPlugin(invokeKind, args, targetMethod, resultType);
         }
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/debug/BenchmarkCounters.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/debug/BenchmarkCounters.java	Mon Jul 01 14:57:02 2019 -0700
@@ -38,6 +38,7 @@
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicLong;
 
+import org.graalvm.compiler.core.GraalServiceThread;
 import org.graalvm.compiler.core.common.SuppressFBWarnings;
 import org.graalvm.compiler.debug.CSVUtil;
 import org.graalvm.compiler.debug.GraalError;
@@ -445,7 +446,7 @@
             enabled = true;
         }
         if (Options.TimedDynamicCounters.getValue(options) > 0) {
-            Thread thread = new Thread() {
+            Thread thread = new GraalServiceThread(new Runnable() {
                 long lastTime = System.nanoTime();
 
                 @Override
@@ -462,7 +463,7 @@
                         }
                     }
                 }
-            };
+            });
             thread.setDaemon(true);
             thread.setPriority(Thread.MAX_PRIORITY);
             thread.start();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/g1/G1ArrayRangePostWriteBarrier.java	Wed Jun 26 15:34:13 2019 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-
-package org.graalvm.compiler.hotspot.gc.g1;
-
-import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_64;
-import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_64;
-
-import org.graalvm.compiler.graph.NodeClass;
-import org.graalvm.compiler.hotspot.gc.shared.ArrayRangeWriteBarrier;
-import org.graalvm.compiler.nodeinfo.NodeInfo;
-import org.graalvm.compiler.nodes.ValueNode;
-import org.graalvm.compiler.nodes.memory.address.AddressNode;
-
-@NodeInfo(cycles = CYCLES_64, size = SIZE_64)
-public class G1ArrayRangePostWriteBarrier extends ArrayRangeWriteBarrier {
-    public static final NodeClass<G1ArrayRangePostWriteBarrier> TYPE = NodeClass.create(G1ArrayRangePostWriteBarrier.class);
-
-    public G1ArrayRangePostWriteBarrier(AddressNode address, ValueNode length, int elementStride) {
-        super(TYPE, address, length, elementStride);
-    }
-
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/g1/G1ArrayRangePreWriteBarrier.java	Wed Jun 26 15:34:13 2019 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-
-package org.graalvm.compiler.hotspot.gc.g1;
-
-import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_64;
-import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_64;
-
-import org.graalvm.compiler.graph.NodeClass;
-import org.graalvm.compiler.hotspot.gc.shared.ArrayRangeWriteBarrier;
-import org.graalvm.compiler.nodeinfo.NodeInfo;
-import org.graalvm.compiler.nodes.ValueNode;
-import org.graalvm.compiler.nodes.memory.address.AddressNode;
-
-@NodeInfo(cycles = CYCLES_64, size = SIZE_64)
-public final class G1ArrayRangePreWriteBarrier extends ArrayRangeWriteBarrier {
-    public static final NodeClass<G1ArrayRangePreWriteBarrier> TYPE = NodeClass.create(G1ArrayRangePreWriteBarrier.class);
-
-    public G1ArrayRangePreWriteBarrier(AddressNode address, ValueNode length, int elementStride) {
-        super(TYPE, address, length, elementStride);
-    }
-
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/g1/G1BarrierSet.java	Wed Jun 26 15:34:13 2019 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,145 +0,0 @@
-/*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2019, Red Hat Inc. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package org.graalvm.compiler.hotspot.gc.g1;
-
-import org.graalvm.compiler.debug.GraalError;
-import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
-import org.graalvm.compiler.hotspot.gc.shared.BarrierSet;
-import org.graalvm.compiler.nodes.StructuredGraph;
-import org.graalvm.compiler.nodes.ValueNode;
-import org.graalvm.compiler.nodes.extended.ArrayRangeWrite;
-import org.graalvm.compiler.nodes.java.AbstractCompareAndSwapNode;
-import org.graalvm.compiler.nodes.java.LoweredAtomicReadAndWriteNode;
-import org.graalvm.compiler.nodes.memory.FixedAccessNode;
-import org.graalvm.compiler.nodes.memory.HeapAccess;
-import org.graalvm.compiler.nodes.memory.ReadNode;
-import org.graalvm.compiler.nodes.memory.WriteNode;
-import org.graalvm.compiler.nodes.memory.address.AddressNode;
-import org.graalvm.compiler.nodes.type.StampTool;
-
-public class G1BarrierSet extends BarrierSet {
-
-    public G1BarrierSet(GraalHotSpotVMConfig vmConfig) {
-        super(vmConfig);
-    }
-
-    @Override
-    public void addReadNodeBarriers(ReadNode node, StructuredGraph graph) {
-        if (node.getBarrierType() == HeapAccess.BarrierType.WEAK_FIELD) {
-            G1ReferentFieldReadBarrier barrier = graph.add(new G1ReferentFieldReadBarrier(node.getAddress(), node, false));
-            graph.addAfterFixed(node, barrier);
-        }
-    }
-
-    @Override
-    public void addWriteNodeBarriers(WriteNode node, StructuredGraph graph) {
-        HeapAccess.BarrierType barrierType = node.getBarrierType();
-        switch (barrierType) {
-            case NONE:
-                // nothing to do
-                break;
-            case FIELD:
-            case ARRAY:
-            case UNKNOWN:
-                boolean init = node.getLocationIdentity().isInit();
-                if (!init || !getVMConfig().useDeferredInitBarriers) {
-                    if (!init) {
-                        // The pre barrier does nothing if the value being read is null, so it can
-                        // be explicitly skipped when this is an initializing store.
-                        addG1PreWriteBarrier(node, node.getAddress(), null, true, node.getNullCheck(), graph);
-                    }
-                    boolean precise = barrierType != HeapAccess.BarrierType.FIELD;
-                    addG1PostWriteBarrier(node, node.getAddress(), node.value(), precise, graph);
-                }
-                break;
-            default:
-                throw new GraalError("unexpected barrier type: " + barrierType);
-        }
-    }
-
-    @Override
-    public void addAtomicReadWriteNodeBarriers(LoweredAtomicReadAndWriteNode node, StructuredGraph graph) {
-        HeapAccess.BarrierType barrierType = node.getBarrierType();
-        switch (barrierType) {
-            case NONE:
-                // nothing to do
-                break;
-            case FIELD:
-            case ARRAY:
-            case UNKNOWN:
-                boolean precise = barrierType != HeapAccess.BarrierType.FIELD;
-                addG1PreWriteBarrier(node, node.getAddress(), null, true, node.getNullCheck(), graph);
-                addG1PostWriteBarrier(node, node.getAddress(), node.getNewValue(), precise, graph);
-                break;
-            default:
-                throw new GraalError("unexpected barrier type: " + barrierType);
-        }
-    }
-
-    @Override
-    public void addCASBarriers(AbstractCompareAndSwapNode node, StructuredGraph graph) {
-        HeapAccess.BarrierType barrierType = node.getBarrierType();
-        switch (barrierType) {
-            case NONE:
-                // nothing to do
-                break;
-            case FIELD:
-            case ARRAY:
-            case UNKNOWN:
-                boolean precise = barrierType != HeapAccess.BarrierType.FIELD;
-                addG1PreWriteBarrier(node, node.getAddress(), node.getExpectedValue(), false, false, graph);
-                addG1PostWriteBarrier(node, node.getAddress(), node.getNewValue(), precise, graph);
-                break;
-            default:
-                throw new GraalError("unexpected barrier type: " + barrierType);
-        }
-    }
-
-    @Override
-    public void addArrayRangeBarriers(ArrayRangeWrite write, StructuredGraph graph) {
-        if (!write.isInitialization()) {
-            // The pre barrier does nothing if the value being read is null, so it can
-            // be explicitly skipped when this is an initializing store.
-            G1ArrayRangePreWriteBarrier g1ArrayRangePreWriteBarrier = graph.add(new G1ArrayRangePreWriteBarrier(write.getAddress(), write.getLength(), write.getElementStride()));
-            graph.addBeforeFixed(write.asNode(), g1ArrayRangePreWriteBarrier);
-        }
-        G1ArrayRangePostWriteBarrier g1ArrayRangePostWriteBarrier = graph.add(new G1ArrayRangePostWriteBarrier(write.getAddress(), write.getLength(), write.getElementStride()));
-        graph.addAfterFixed(write.asNode(), g1ArrayRangePostWriteBarrier);
-    }
-
-    private static void addG1PreWriteBarrier(FixedAccessNode node, AddressNode address, ValueNode value, boolean doLoad, boolean nullCheck, StructuredGraph graph) {
-        G1PreWriteBarrier preBarrier = graph.add(new G1PreWriteBarrier(address, value, doLoad, nullCheck));
-        preBarrier.setStateBefore(node.stateBefore());
-        node.setNullCheck(false);
-        node.setStateBefore(null);
-        graph.addBeforeFixed(node, preBarrier);
-    }
-
-    private static void addG1PostWriteBarrier(FixedAccessNode node, AddressNode address, ValueNode value, boolean precise, StructuredGraph graph) {
-        final boolean alwaysNull = StampTool.isPointerAlwaysNull(value);
-        graph.addAfterFixed(node, graph.add(new G1PostWriteBarrier(address, value, precise, alwaysNull)));
-    }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/g1/G1PostWriteBarrier.java	Wed Jun 26 15:34:13 2019 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package org.graalvm.compiler.hotspot.gc.g1;
-
-import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_64;
-import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_64;
-
-import org.graalvm.compiler.graph.NodeClass;
-import org.graalvm.compiler.hotspot.gc.shared.ObjectWriteBarrier;
-import org.graalvm.compiler.nodeinfo.NodeInfo;
-import org.graalvm.compiler.nodes.ValueNode;
-import org.graalvm.compiler.nodes.memory.address.AddressNode;
-
-@NodeInfo(cycles = CYCLES_64, size = SIZE_64)
-public class G1PostWriteBarrier extends ObjectWriteBarrier {
-
-    public static final NodeClass<G1PostWriteBarrier> TYPE = NodeClass.create(G1PostWriteBarrier.class);
-    protected final boolean alwaysNull;
-
-    public G1PostWriteBarrier(AddressNode address, ValueNode value, boolean precise, boolean alwaysNull) {
-        this(TYPE, address, value, precise, alwaysNull);
-    }
-
-    private G1PostWriteBarrier(NodeClass<? extends G1PostWriteBarrier> c, AddressNode address, ValueNode value, boolean precise, boolean alwaysNull) {
-        super(c, address, value, precise);
-        this.alwaysNull = alwaysNull;
-    }
-
-    public boolean alwaysNull() {
-        return alwaysNull;
-    }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/g1/G1PreWriteBarrier.java	Wed Jun 26 15:34:13 2019 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-
-package org.graalvm.compiler.hotspot.gc.g1;
-
-import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_64;
-import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_64;
-
-import org.graalvm.compiler.graph.NodeClass;
-import org.graalvm.compiler.hotspot.gc.shared.ObjectWriteBarrier;
-import org.graalvm.compiler.nodeinfo.InputType;
-import org.graalvm.compiler.nodeinfo.NodeInfo;
-import org.graalvm.compiler.nodes.DeoptimizingNode;
-import org.graalvm.compiler.nodes.FrameState;
-import org.graalvm.compiler.nodes.ValueNode;
-import org.graalvm.compiler.nodes.memory.address.AddressNode;
-
-@NodeInfo(cycles = CYCLES_64, size = SIZE_64)
-public final class G1PreWriteBarrier extends ObjectWriteBarrier implements DeoptimizingNode.DeoptBefore {
-
-    public static final NodeClass<G1PreWriteBarrier> TYPE = NodeClass.create(G1PreWriteBarrier.class);
-
-    @OptionalInput(InputType.State) private FrameState stateBefore;
-    private final boolean nullCheck;
-    private final boolean doLoad;
-
-    public G1PreWriteBarrier(AddressNode address, ValueNode expectedObject, boolean doLoad, boolean nullCheck) {
-        super(TYPE, address, expectedObject, true);
-        this.doLoad = doLoad;
-        this.nullCheck = nullCheck;
-    }
-
-    public ValueNode getExpectedObject() {
-        return getValue();
-    }
-
-    public boolean doLoad() {
-        return doLoad;
-    }
-
-    public boolean getNullCheck() {
-        return nullCheck;
-    }
-
-    @Override
-    public boolean canDeoptimize() {
-        return nullCheck;
-    }
-
-    @Override
-    public FrameState stateBefore() {
-        return stateBefore;
-    }
-
-    @Override
-    public void setStateBefore(FrameState state) {
-        updateUsages(stateBefore, state);
-        stateBefore = state;
-    }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/g1/G1ReferentFieldReadBarrier.java	Wed Jun 26 15:34:13 2019 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package org.graalvm.compiler.hotspot.gc.g1;
-
-import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_64;
-import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_64;
-
-import org.graalvm.compiler.graph.NodeClass;
-import org.graalvm.compiler.hotspot.gc.shared.ObjectWriteBarrier;
-import org.graalvm.compiler.nodeinfo.NodeInfo;
-import org.graalvm.compiler.nodes.ValueNode;
-import org.graalvm.compiler.nodes.memory.address.AddressNode;
-
-/**
- * The {@code G1ReferentFieldReadBarrier} is added when a read access is performed to the referent
- * field of a {@link java.lang.ref.Reference} object (through a {@code LoadFieldNode} or an
- * {@code UnsafeLoadNode}). The return value of the read is passed to the snippet implementing the
- * read barrier and consequently is added to the SATB queue if the concurrent marker is enabled.
- */
-@NodeInfo(cycles = CYCLES_64, size = SIZE_64)
-public final class G1ReferentFieldReadBarrier extends ObjectWriteBarrier {
-    public static final NodeClass<G1ReferentFieldReadBarrier> TYPE = NodeClass.create(G1ReferentFieldReadBarrier.class);
-
-    private final boolean doLoad;
-
-    public G1ReferentFieldReadBarrier(AddressNode address, ValueNode expectedObject, boolean doLoad) {
-        super(TYPE, address, expectedObject, true);
-        this.doLoad = doLoad;
-    }
-
-    public ValueNode getExpectedObject() {
-        return getValue();
-    }
-
-    public boolean doLoad() {
-        return doLoad;
-    }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/shared/ArrayRangeWriteBarrier.java	Wed Jun 26 15:34:13 2019 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package org.graalvm.compiler.hotspot.gc.shared;
-
-import org.graalvm.compiler.graph.NodeClass;
-import org.graalvm.compiler.hotspot.nodes.WriteBarrier;
-import org.graalvm.compiler.nodeinfo.InputType;
-import org.graalvm.compiler.nodeinfo.NodeInfo;
-import org.graalvm.compiler.nodes.ValueNode;
-import org.graalvm.compiler.nodes.memory.address.AddressNode;
-import org.graalvm.compiler.nodes.spi.Lowerable;
-
-@NodeInfo
-public abstract class ArrayRangeWriteBarrier extends WriteBarrier implements Lowerable {
-
-    public static final NodeClass<ArrayRangeWriteBarrier> TYPE = NodeClass.create(ArrayRangeWriteBarrier.class);
-    @Input(InputType.Association) AddressNode address;
-    @Input ValueNode length;
-
-    private final int elementStride;
-
-    protected ArrayRangeWriteBarrier(NodeClass<? extends ArrayRangeWriteBarrier> c, AddressNode address, ValueNode length, int elementStride) {
-        super(c);
-        this.address = address;
-        this.length = length;
-        this.elementStride = elementStride;
-    }
-
-    public AddressNode getAddress() {
-        return address;
-    }
-
-    public ValueNode getLength() {
-        return length;
-    }
-
-    public int getElementStride() {
-        return elementStride;
-    }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/shared/BarrierSet.java	Wed Jun 26 15:34:13 2019 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2019, Red Hat Inc. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package org.graalvm.compiler.hotspot.gc.shared;
-
-import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
-import org.graalvm.compiler.nodes.StructuredGraph;
-import org.graalvm.compiler.nodes.extended.ArrayRangeWrite;
-import org.graalvm.compiler.nodes.java.AbstractCompareAndSwapNode;
-import org.graalvm.compiler.nodes.java.LoweredAtomicReadAndWriteNode;
-import org.graalvm.compiler.nodes.memory.ReadNode;
-import org.graalvm.compiler.nodes.memory.WriteNode;
-
-public abstract class BarrierSet {
-    private final GraalHotSpotVMConfig vmConfig;
-
-    protected BarrierSet(GraalHotSpotVMConfig vmConfig) {
-        this.vmConfig = vmConfig;
-    }
-
-    public final GraalHotSpotVMConfig getVMConfig() {
-        return vmConfig;
-    }
-
-    public abstract void addReadNodeBarriers(ReadNode node, StructuredGraph graph);
-
-    public abstract void addWriteNodeBarriers(WriteNode node, StructuredGraph graph);
-
-    public abstract void addAtomicReadWriteNodeBarriers(LoweredAtomicReadAndWriteNode node, StructuredGraph graph);
-
-    public abstract void addCASBarriers(AbstractCompareAndSwapNode node, StructuredGraph graph);
-
-    public abstract void addArrayRangeBarriers(ArrayRangeWrite write, StructuredGraph graph);
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/shared/CardTableBarrierSet.java	Wed Jun 26 15:34:13 2019 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,124 +0,0 @@
-/*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2019, Red Hat Inc. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package org.graalvm.compiler.hotspot.gc.shared;
-
-import org.graalvm.compiler.debug.GraalError;
-import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
-import org.graalvm.compiler.nodes.StructuredGraph;
-import org.graalvm.compiler.nodes.ValueNode;
-import org.graalvm.compiler.nodes.extended.ArrayRangeWrite;
-import org.graalvm.compiler.nodes.java.AbstractCompareAndSwapNode;
-import org.graalvm.compiler.nodes.java.LoweredAtomicReadAndWriteNode;
-import org.graalvm.compiler.nodes.memory.FixedAccessNode;
-import org.graalvm.compiler.nodes.memory.HeapAccess;
-import org.graalvm.compiler.nodes.memory.ReadNode;
-import org.graalvm.compiler.nodes.memory.WriteNode;
-import org.graalvm.compiler.nodes.memory.address.AddressNode;
-import org.graalvm.compiler.nodes.type.StampTool;
-
-public class CardTableBarrierSet extends BarrierSet {
-
-    public CardTableBarrierSet(GraalHotSpotVMConfig vmConfig) {
-        super(vmConfig);
-    }
-
-    @Override
-    public void addReadNodeBarriers(ReadNode node, StructuredGraph graph) {
-        // Nothing to do here.
-    }
-
-    @Override
-    public void addWriteNodeBarriers(WriteNode node, StructuredGraph graph) {
-        HeapAccess.BarrierType barrierType = node.getBarrierType();
-        switch (barrierType) {
-            case NONE:
-                // nothing to do
-                break;
-            case FIELD:
-            case ARRAY:
-            case UNKNOWN:
-                boolean precise = barrierType != HeapAccess.BarrierType.FIELD;
-                boolean init = node.getLocationIdentity().isInit();
-                if (!init || !getVMConfig().useDeferredInitBarriers) {
-                    addSerialPostWriteBarrier(node, node.getAddress(), node.value(), precise, graph);
-                }
-                break;
-            default:
-                throw new GraalError("unexpected barrier type: " + barrierType);
-        }
-    }
-
-    @Override
-    public void addAtomicReadWriteNodeBarriers(LoweredAtomicReadAndWriteNode node, StructuredGraph graph) {
-        HeapAccess.BarrierType barrierType = node.getBarrierType();
-        switch (barrierType) {
-            case NONE:
-                // nothing to do
-                break;
-            case FIELD:
-            case ARRAY:
-            case UNKNOWN:
-                boolean precise = barrierType != HeapAccess.BarrierType.FIELD;
-                addSerialPostWriteBarrier(node, node.getAddress(), node.getNewValue(), precise, graph);
-                break;
-            default:
-                throw new GraalError("unexpected barrier type: " + barrierType);
-        }
-    }
-
-    @Override
-    public void addCASBarriers(AbstractCompareAndSwapNode node, StructuredGraph graph) {
-        HeapAccess.BarrierType barrierType = node.getBarrierType();
-        switch (barrierType) {
-            case NONE:
-                // nothing to do
-                break;
-            case FIELD:
-            case ARRAY:
-            case UNKNOWN:
-                boolean precise = barrierType != HeapAccess.BarrierType.FIELD;
-                addSerialPostWriteBarrier(node, node.getAddress(), node.getNewValue(), precise, graph);
-                break;
-            default:
-                throw new GraalError("unexpected barrier type: " + barrierType);
-        }
-    }
-
-    @Override
-    public void addArrayRangeBarriers(ArrayRangeWrite write, StructuredGraph graph) {
-        SerialArrayRangeWriteBarrier serialArrayRangeWriteBarrier = graph.add(new SerialArrayRangeWriteBarrier(write.getAddress(), write.getLength(), write.getElementStride()));
-        graph.addAfterFixed(write.asNode(), serialArrayRangeWriteBarrier);
-    }
-
-    protected void addSerialPostWriteBarrier(FixedAccessNode node, AddressNode address, ValueNode value, boolean precise, StructuredGraph graph) {
-        final boolean alwaysNull = StampTool.isPointerAlwaysNull(value);
-        if (alwaysNull) {
-            // Serial barrier isn't needed for null value
-            return;
-        }
-        graph.addAfterFixed(node, graph.add(new SerialWriteBarrier(address, precise)));
-    }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/shared/ObjectWriteBarrier.java	Wed Jun 26 15:34:13 2019 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package org.graalvm.compiler.hotspot.gc.shared;
-
-import org.graalvm.compiler.graph.NodeClass;
-import org.graalvm.compiler.hotspot.nodes.WriteBarrier;
-import org.graalvm.compiler.nodeinfo.InputType;
-import org.graalvm.compiler.nodeinfo.NodeInfo;
-import org.graalvm.compiler.nodes.ValueNode;
-import org.graalvm.compiler.nodes.memory.address.AddressNode;
-
-@NodeInfo
-public abstract class ObjectWriteBarrier extends WriteBarrier {
-
-    public static final NodeClass<ObjectWriteBarrier> TYPE = NodeClass.create(ObjectWriteBarrier.class);
-    @Input(InputType.Association) protected AddressNode address;
-    @OptionalInput protected ValueNode value;
-    protected final boolean precise;
-
-    protected ObjectWriteBarrier(NodeClass<? extends ObjectWriteBarrier> c, AddressNode address, ValueNode value, boolean precise) {
-        super(c);
-        this.address = address;
-        this.value = value;
-        this.precise = precise;
-    }
-
-    public ValueNode getValue() {
-        return value;
-    }
-
-    public AddressNode getAddress() {
-        return address;
-    }
-
-    public boolean usePrecise() {
-        return precise;
-    }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/shared/SerialArrayRangeWriteBarrier.java	Wed Jun 26 15:34:13 2019 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package org.graalvm.compiler.hotspot.gc.shared;
-
-import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_8;
-import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_8;
-
-import org.graalvm.compiler.graph.NodeClass;
-import org.graalvm.compiler.nodeinfo.NodeInfo;
-import org.graalvm.compiler.nodes.ValueNode;
-import org.graalvm.compiler.nodes.memory.address.AddressNode;
-
-@NodeInfo(cycles = CYCLES_8, size = SIZE_8)
-public final class SerialArrayRangeWriteBarrier extends ArrayRangeWriteBarrier {
-    public static final NodeClass<SerialArrayRangeWriteBarrier> TYPE = NodeClass.create(SerialArrayRangeWriteBarrier.class);
-
-    public SerialArrayRangeWriteBarrier(AddressNode address, ValueNode length, int elementStride) {
-        super(TYPE, address, length, elementStride);
-    }
-
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/gc/shared/SerialWriteBarrier.java	Wed Jun 26 15:34:13 2019 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package org.graalvm.compiler.hotspot.gc.shared;
-
-import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_8;
-import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_4;
-
-import org.graalvm.compiler.graph.NodeClass;
-import org.graalvm.compiler.nodeinfo.NodeInfo;
-import org.graalvm.compiler.nodes.memory.address.AddressNode;
-
-@NodeInfo(cycles = CYCLES_8, size = SIZE_4)
-public class SerialWriteBarrier extends ObjectWriteBarrier {
-
-    public static final NodeClass<SerialWriteBarrier> TYPE = NodeClass.create(SerialWriteBarrier.class);
-
-    public SerialWriteBarrier(AddressNode address, boolean precise) {
-        this(TYPE, address, precise);
-    }
-
-    protected SerialWriteBarrier(NodeClass<? extends SerialWriteBarrier> c, AddressNode address, boolean precise) {
-        super(c, address, null, precise);
-    }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/AddressLoweringHotSpotSuitesProvider.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/AddressLoweringHotSpotSuitesProvider.java	Mon Jul 01 14:57:02 2019 -0700
@@ -32,8 +32,8 @@
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.phases.BasePhase;
 import org.graalvm.compiler.phases.Phase;
-import org.graalvm.compiler.phases.common.ExpandLogicPhase;
-import org.graalvm.compiler.phases.common.FixReadsPhase;
+import org.graalvm.compiler.phases.common.UseTrappingNullChecksPhase;
+import org.graalvm.compiler.phases.schedule.SchedulePhase;
 import org.graalvm.compiler.phases.tiers.LowTierContext;
 import org.graalvm.compiler.phases.tiers.Suites;
 import org.graalvm.compiler.phases.tiers.SuitesCreator;
@@ -55,10 +55,11 @@
     public Suites createSuites(OptionValues options) {
         Suites suites = super.createSuites(options);
 
-        ListIterator<BasePhase<? super LowTierContext>> findPhase = suites.getLowTier().findPhase(FixReadsPhase.class);
+        ListIterator<BasePhase<? super LowTierContext>> findPhase = suites.getLowTier().findPhase(UseTrappingNullChecksPhase.class);
         if (findPhase == null) {
-            findPhase = suites.getLowTier().findPhase(ExpandLogicPhase.class);
+            findPhase = suites.getLowTier().findPhase(SchedulePhase.class);
         }
+        findPhase.previous();
         findPhase.add(addressLowering);
 
         return suites;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,7 +26,6 @@
 
 import static jdk.vm.ci.services.Services.IS_IN_NATIVE_IMAGE;
 import static org.graalvm.compiler.core.common.GraalOptions.AlwaysInlineVTableStubs;
-import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
 import static org.graalvm.compiler.core.common.GraalOptions.InlineVTableStubs;
 import static org.graalvm.compiler.core.common.GraalOptions.OmitHotExceptionStacktrace;
 import static org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProviderImpl.OSR_MIGRATION_END;
@@ -60,13 +59,6 @@
 import org.graalvm.compiler.graph.NodeInputList;
 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
 import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
-import org.graalvm.compiler.hotspot.gc.g1.G1ArrayRangePostWriteBarrier;
-import org.graalvm.compiler.hotspot.gc.g1.G1ArrayRangePreWriteBarrier;
-import org.graalvm.compiler.hotspot.gc.g1.G1PostWriteBarrier;
-import org.graalvm.compiler.hotspot.gc.g1.G1PreWriteBarrier;
-import org.graalvm.compiler.hotspot.gc.g1.G1ReferentFieldReadBarrier;
-import org.graalvm.compiler.hotspot.gc.shared.SerialArrayRangeWriteBarrier;
-import org.graalvm.compiler.hotspot.gc.shared.SerialWriteBarrier;
 import org.graalvm.compiler.hotspot.nodes.BeginLockScopeNode;
 import org.graalvm.compiler.hotspot.nodes.HotSpotCompressionNode;
 import org.graalvm.compiler.hotspot.nodes.HotSpotDirectCallTargetNode;
@@ -82,6 +74,8 @@
 import org.graalvm.compiler.hotspot.replacements.AssertionSnippets;
 import org.graalvm.compiler.hotspot.replacements.ClassGetHubNode;
 import org.graalvm.compiler.hotspot.replacements.HashCodeSnippets;
+import org.graalvm.compiler.hotspot.replacements.HotSpotG1WriteBarrierSnippets;
+import org.graalvm.compiler.hotspot.replacements.HotSpotSerialWriteBarrierSnippets;
 import org.graalvm.compiler.hotspot.replacements.HubGetClassNode;
 import org.graalvm.compiler.hotspot.replacements.IdentityHashCodeNode;
 import org.graalvm.compiler.hotspot.replacements.InstanceOfSnippets;
@@ -92,7 +86,6 @@
 import org.graalvm.compiler.hotspot.replacements.ObjectCloneSnippets;
 import org.graalvm.compiler.hotspot.replacements.StringToBytesSnippets;
 import org.graalvm.compiler.hotspot.replacements.UnsafeLoadSnippets;
-import org.graalvm.compiler.hotspot.replacements.WriteBarrierSnippets;
 import org.graalvm.compiler.hotspot.replacements.aot.ResolveConstantSnippets;
 import org.graalvm.compiler.hotspot.replacements.arraycopy.HotSpotArraycopySnippets;
 import org.graalvm.compiler.hotspot.replacements.profiling.ProfileSnippets;
@@ -135,6 +128,13 @@
 import org.graalvm.compiler.nodes.extended.OSRStartNode;
 import org.graalvm.compiler.nodes.extended.RawLoadNode;
 import org.graalvm.compiler.nodes.extended.StoreHubNode;
+import org.graalvm.compiler.nodes.gc.G1ArrayRangePostWriteBarrier;
+import org.graalvm.compiler.nodes.gc.G1ArrayRangePreWriteBarrier;
+import org.graalvm.compiler.nodes.gc.G1PostWriteBarrier;
+import org.graalvm.compiler.nodes.gc.G1PreWriteBarrier;
+import org.graalvm.compiler.nodes.gc.G1ReferentFieldReadBarrier;
+import org.graalvm.compiler.nodes.gc.SerialArrayRangeWriteBarrier;
+import org.graalvm.compiler.nodes.gc.SerialWriteBarrier;
 import org.graalvm.compiler.nodes.java.ClassIsAssignableFromNode;
 import org.graalvm.compiler.nodes.java.DynamicNewArrayNode;
 import org.graalvm.compiler.nodes.java.DynamicNewInstanceNode;
@@ -191,7 +191,8 @@
     protected InstanceOfSnippets.Templates instanceofSnippets;
     protected NewObjectSnippets.Templates newObjectSnippets;
     protected MonitorSnippets.Templates monitorSnippets;
-    protected WriteBarrierSnippets.Templates writeBarrierSnippets;
+    protected HotSpotSerialWriteBarrierSnippets.Templates serialWriteBarrierSnippets;
+    protected HotSpotG1WriteBarrierSnippets.Templates g1WriteBarrierSnippets;
     protected LoadExceptionObjectSnippets.Templates exceptionObjectSnippets;
     protected UnsafeLoadSnippets.Templates unsafeLoadSnippets;
     protected AssertionSnippets.Templates assertionSnippets;
@@ -220,7 +221,8 @@
         instanceofSnippets = new InstanceOfSnippets.Templates(options, factories, runtime, providers, target);
         newObjectSnippets = new NewObjectSnippets.Templates(options, factories, runtime, providers, target, config);
         monitorSnippets = new MonitorSnippets.Templates(options, factories, runtime, providers, target, config.useFastLocking);
-        writeBarrierSnippets = new WriteBarrierSnippets.Templates(options, factories, runtime, providers, target, config);
+        g1WriteBarrierSnippets = new HotSpotG1WriteBarrierSnippets.Templates(options, factories, runtime, providers, target, config);
+        serialWriteBarrierSnippets = new HotSpotSerialWriteBarrierSnippets.Templates(options, factories, runtime, providers, target, config);
         exceptionObjectSnippets = new LoadExceptionObjectSnippets.Templates(options, factories, providers, target);
         unsafeLoadSnippets = new UnsafeLoadSnippets.Templates(options, factories, providers, target);
         assertionSnippets = new AssertionSnippets.Templates(options, factories, providers, target);
@@ -228,11 +230,14 @@
         stringToBytesSnippets = new StringToBytesSnippets.Templates(options, factories, providers, target);
         hashCodeSnippets = new HashCodeSnippets.Templates(options, factories, providers, target);
         resolveConstantSnippets = new ResolveConstantSnippets.Templates(options, factories, providers, target);
-        if (!JavaVersionUtil.Java8OrEarlier && GeneratePIC.getValue(options)) {
+        objectCloneSnippets = new ObjectCloneSnippets.Templates(options, factories, providers, target);
+        foreignCallSnippets = new ForeignCallSnippets.Templates(options, factories, providers, target);
+        if (JavaVersionUtil.JAVA_SPEC <= 8) {
+            // AOT only introduced in JDK 9
+            profileSnippets = null;
+        } else {
             profileSnippets = new ProfileSnippets.Templates(options, factories, providers, target);
         }
-        objectCloneSnippets = new ObjectCloneSnippets.Templates(options, factories, providers, target);
-        foreignCallSnippets = new ForeignCallSnippets.Templates(options, factories, providers, target);
     }
 
     public ArrayCopySnippets.Templates getArraycopySnippets() {
@@ -340,19 +345,19 @@
             } else if (n instanceof ArrayCopyWithDelayedLoweringNode) {
                 arraycopySnippets.lower((ArrayCopyWithDelayedLoweringNode) n, tool);
             } else if (n instanceof G1PreWriteBarrier) {
-                writeBarrierSnippets.lower((G1PreWriteBarrier) n, registers, tool);
+                g1WriteBarrierSnippets.lower((G1PreWriteBarrier) n, tool);
             } else if (n instanceof G1PostWriteBarrier) {
-                writeBarrierSnippets.lower((G1PostWriteBarrier) n, registers, tool);
+                g1WriteBarrierSnippets.lower((G1PostWriteBarrier) n, tool);
             } else if (n instanceof G1ReferentFieldReadBarrier) {
-                writeBarrierSnippets.lower((G1ReferentFieldReadBarrier) n, registers, tool);
+                g1WriteBarrierSnippets.lower((G1ReferentFieldReadBarrier) n, tool);
             } else if (n instanceof SerialWriteBarrier) {
-                writeBarrierSnippets.lower((SerialWriteBarrier) n, tool);
+                serialWriteBarrierSnippets.lower((SerialWriteBarrier) n, tool);
             } else if (n instanceof SerialArrayRangeWriteBarrier) {
-                writeBarrierSnippets.lower((SerialArrayRangeWriteBarrier) n, tool);
+                serialWriteBarrierSnippets.lower((SerialArrayRangeWriteBarrier) n, tool);
             } else if (n instanceof G1ArrayRangePreWriteBarrier) {
-                writeBarrierSnippets.lower((G1ArrayRangePreWriteBarrier) n, registers, tool);
+                g1WriteBarrierSnippets.lower((G1ArrayRangePreWriteBarrier) n, tool);
             } else if (n instanceof G1ArrayRangePostWriteBarrier) {
-                writeBarrierSnippets.lower((G1ArrayRangePostWriteBarrier) n, registers, tool);
+                g1WriteBarrierSnippets.lower((G1ArrayRangePostWriteBarrier) n, tool);
             } else if (n instanceof NewMultiArrayNode) {
                 if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
                     newObjectSnippets.lower((NewMultiArrayNode) n, tool);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGCProvider.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.hotspot.meta;
+
+import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.graph.Node;
+import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
+import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.gc.BarrierSet;
+import org.graalvm.compiler.nodes.gc.CardTableBarrierSet;
+import org.graalvm.compiler.nodes.gc.G1BarrierSet;
+import org.graalvm.compiler.nodes.java.AbstractNewObjectNode;
+import org.graalvm.compiler.nodes.memory.FixedAccessNode;
+import org.graalvm.compiler.nodes.spi.GCProvider;
+
+public class HotSpotGCProvider implements GCProvider {
+    private final BarrierSet barrierSet;
+
+    public HotSpotGCProvider(GraalHotSpotVMConfig config) {
+        this.barrierSet = createBarrierSet(config);
+    }
+
+    @Override
+    public BarrierSet getBarrierSet() {
+        return barrierSet;
+    }
+
+    private BarrierSet createBarrierSet(GraalHotSpotVMConfig config) {
+        boolean useDeferredInitBarriers = config.useDeferredInitBarriers;
+        if (config.useG1GC) {
+            return new G1BarrierSet() {
+                @Override
+                protected boolean writeRequiresPostBarrier(FixedAccessNode initializingWrite, ValueNode writtenValue) {
+                    if (!super.writeRequiresPostBarrier(initializingWrite, writtenValue)) {
+                        return false;
+                    }
+                    return !useDeferredInitBarriers || !isWriteToNewObject(initializingWrite);
+                }
+            };
+        } else {
+            return new CardTableBarrierSet() {
+                @Override
+                protected boolean writeRequiresBarrier(FixedAccessNode initializingWrite, ValueNode writtenValue) {
+                    if (!super.writeRequiresBarrier(initializingWrite, writtenValue)) {
+                        return false;
+                    }
+                    return !useDeferredInitBarriers || !isWriteToNewObject(initializingWrite);
+                }
+            };
+        }
+    }
+
+    /**
+     * For initializing writes, the last allocation executed by the JVM is guaranteed to be
+     * automatically card marked so it's safe to skip the card mark in the emitted code.
+     */
+    protected boolean isWriteToNewObject(FixedAccessNode initializingWrite) {
+        if (!initializingWrite.getLocationIdentity().isInit()) {
+            return false;
+        }
+        // This is only allowed for the last allocation in sequence
+        ValueNode base = initializingWrite.getAddress().getBase();
+        if (base instanceof AbstractNewObjectNode) {
+            Node pred = initializingWrite.predecessor();
+            while (pred != null) {
+                if (pred == base) {
+                    return true;
+                }
+                if (pred instanceof AbstractNewObjectNode) {
+                    initializingWrite.getDebug().log(DebugContext.INFO_LEVEL, "Disallowed deferred init because %s was last allocation instead of %s", pred, base);
+                    return false;
+                }
+                pred = pred.predecessor();
+            }
+        }
+        initializingWrite.getDebug().log(DebugContext.INFO_LEVEL, "Unable to find allocation for deferred init for %s with base %s", initializingWrite, base);
+        return false;
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java	Mon Jul 01 14:57:02 2019 -0700
@@ -30,7 +30,6 @@
 import static org.graalvm.compiler.hotspot.meta.HotSpotAOTProfilingPlugin.Options.TieredAOT;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.JAVA_THREAD_THREAD_OBJECT_LOCATION;
 import static org.graalvm.compiler.java.BytecodeParserOptions.InlineDuringParsing;
-import static org.graalvm.compiler.serviceprovider.JavaVersionUtil.Java8OrEarlier;
 
 import java.lang.invoke.ConstantCallSite;
 import java.lang.invoke.MutableCallSite;
@@ -101,6 +100,7 @@
 import org.graalvm.compiler.replacements.StandardGraphBuilderPlugins;
 import org.graalvm.compiler.replacements.arraycopy.ArrayCopyNode;
 import org.graalvm.compiler.serviceprovider.GraalServices;
+import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
 import org.graalvm.compiler.word.WordOperationPlugin;
 import org.graalvm.compiler.word.WordTypes;
 import jdk.internal.vm.compiler.word.LocationIdentity;
@@ -278,7 +278,7 @@
 
     private static void registerUnsafePlugins(InvocationPlugins plugins, BytecodeProvider replacementBytecodeProvider) {
         Registration r;
-        if (Java8OrEarlier) {
+        if (JavaVersionUtil.JAVA_SPEC <= 8) {
             r = new Registration(plugins, Unsafe.class, replacementBytecodeProvider);
         } else {
             r = new Registration(plugins, "jdk.internal.misc.Unsafe", replacementBytecodeProvider);
@@ -403,7 +403,7 @@
     }
 
     private static void registerStringPlugins(InvocationPlugins plugins, BytecodeProvider bytecodeProvider) {
-        if (!Java8OrEarlier) {
+        if (JavaVersionUtil.JAVA_SPEC > 8) {
             final Registration utf16r = new Registration(plugins, "java.lang.StringUTF16", bytecodeProvider);
             utf16r.registerMethodSubstitution(StringUTF16Substitutions.class, "toBytes", char[].class, int.class, int.class);
             utf16r.registerMethodSubstitution(StringUTF16Substitutions.class, "getChars", byte[].class, int.class, int.class, char[].class, int.class);
@@ -437,7 +437,7 @@
     public static final String constantPoolClass;
 
     static {
-        if (Java8OrEarlier) {
+        if (JavaVersionUtil.JAVA_SPEC <= 8) {
             cbcEncryptName = "encrypt";
             cbcDecryptName = "decrypt";
             aesEncryptName = "encryptBlock";
@@ -476,7 +476,7 @@
         Registration r = new Registration(plugins, BigInteger.class, bytecodeProvider);
         if (config.useMultiplyToLenIntrinsic()) {
             assert config.multiplyToLen != 0L;
-            if (Java8OrEarlier) {
+            if (JavaVersionUtil.JAVA_SPEC <= 8) {
                 r.registerMethodSubstitution(BigIntegerSubstitutions.class, "multiplyToLen", "multiplyToLenStatic", int[].class, int.class, int[].class, int.class,
                                 int[].class);
             } else {
@@ -503,7 +503,7 @@
         boolean useSha256 = config.useSHA256Intrinsics();
         boolean useSha512 = config.useSHA512Intrinsics();
 
-        if (!Java8OrEarlier && (useSha1 || useSha256 || useSha512)) {
+        if (JavaVersionUtil.JAVA_SPEC > 8 && (useSha1 || useSha256 || useSha512)) {
             Registration r = new Registration(plugins, "sun.security.provider.DigestBase", bytecodeProvider);
             r.registerMethodSubstitution(DigestBaseSubstitutions.class, "implCompressMultiBlock0", Receiver.class, byte[].class, int.class, int.class);
         }
@@ -602,7 +602,7 @@
         if (config.useCRC32Intrinsics) {
             Registration r = new Registration(plugins, CRC32.class, bytecodeProvider);
             r.registerMethodSubstitution(CRC32Substitutions.class, "update", int.class, int.class);
-            if (Java8OrEarlier) {
+            if (JavaVersionUtil.JAVA_SPEC <= 8) {
                 r.registerMethodSubstitution(CRC32Substitutions.class, "updateBytes", int.class, byte[].class, int.class, int.class);
                 r.registerMethodSubstitution(CRC32Substitutions.class, "updateByteBuffer", int.class, long.class, int.class, int.class);
             } else {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotHostForeignCallsProvider.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotHostForeignCallsProvider.java	Mon Jul 01 14:57:02 2019 -0700
@@ -81,24 +81,24 @@
 import static org.graalvm.compiler.hotspot.HotSpotHostBackend.THROW_DELAYED_STACKOVERFLOW_ERROR;
 import static org.graalvm.compiler.hotspot.HotSpotHostBackend.UNCOMMON_TRAP_HANDLER;
 import static org.graalvm.compiler.hotspot.replacements.AssertionSnippets.ASSERTION_VM_MESSAGE_C;
+import static org.graalvm.compiler.hotspot.replacements.HotSpotG1WriteBarrierSnippets.G1WBPOSTCALL;
+import static org.graalvm.compiler.hotspot.replacements.HotSpotG1WriteBarrierSnippets.G1WBPRECALL;
+import static org.graalvm.compiler.hotspot.replacements.HotSpotG1WriteBarrierSnippets.VALIDATE_OBJECT;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.MARK_WORD_LOCATION;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.TLAB_END_LOCATION;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.TLAB_TOP_LOCATION;
+import static org.graalvm.compiler.hotspot.replacements.Log.LOG_OBJECT;
+import static org.graalvm.compiler.hotspot.replacements.Log.LOG_PRIMITIVE;
+import static org.graalvm.compiler.hotspot.replacements.Log.LOG_PRINTF;
 import static org.graalvm.compiler.hotspot.replacements.MonitorSnippets.MONITORENTER;
 import static org.graalvm.compiler.hotspot.replacements.MonitorSnippets.MONITOREXIT;
 import static org.graalvm.compiler.hotspot.replacements.NewObjectSnippets.DYNAMIC_NEW_INSTANCE;
 import static org.graalvm.compiler.hotspot.replacements.NewObjectSnippets.DYNAMIC_NEW_INSTANCE_OR_NULL;
 import static org.graalvm.compiler.hotspot.replacements.ThreadSubstitutions.THREAD_IS_INTERRUPTED;
-import static org.graalvm.compiler.hotspot.replacements.WriteBarrierSnippets.G1WBPOSTCALL;
-import static org.graalvm.compiler.hotspot.replacements.WriteBarrierSnippets.G1WBPRECALL;
-import static org.graalvm.compiler.hotspot.replacements.WriteBarrierSnippets.VALIDATE_OBJECT;
 import static org.graalvm.compiler.hotspot.stubs.ExceptionHandlerStub.EXCEPTION_HANDLER_FOR_PC;
 import static org.graalvm.compiler.hotspot.stubs.StubUtil.VM_MESSAGE_C;
 import static org.graalvm.compiler.hotspot.stubs.UnwindExceptionToCallerStub.EXCEPTION_HANDLER_FOR_RETURN_ADDRESS;
 import static org.graalvm.compiler.nodes.java.ForeignCallDescriptors.REGISTER_FINALIZER;
-import static org.graalvm.compiler.replacements.Log.LOG_OBJECT;
-import static org.graalvm.compiler.replacements.Log.LOG_PRIMITIVE;
-import static org.graalvm.compiler.replacements.Log.LOG_PRINTF;
 import static org.graalvm.compiler.replacements.nodes.BinaryMathIntrinsicNode.BinaryOperation.POW;
 import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.COS;
 import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.EXP;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotProviders.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotProviders.java	Mon Jul 01 14:57:02 2019 -0700
@@ -50,17 +50,18 @@
     private final SnippetReflectionProvider snippetReflection;
     private final HotSpotWordTypes wordTypes;
     private final Plugins graphBuilderPlugins;
+    private final HotSpotGCProvider gc;
 
     public HotSpotProviders(MetaAccessProvider metaAccess, HotSpotCodeCacheProvider codeCache, ConstantReflectionProvider constantReflection, ConstantFieldProvider constantField,
-                    HotSpotForeignCallsProvider foreignCalls, LoweringProvider lowerer, Replacements replacements, SuitesProvider suites,
-                    HotSpotRegistersProvider registers,
-                    SnippetReflectionProvider snippetReflection, HotSpotWordTypes wordTypes, Plugins graphBuilderPlugins) {
-        super(metaAccess, codeCache, constantReflection, constantField, foreignCalls, lowerer, replacements, new HotSpotStampProvider());
+                    HotSpotForeignCallsProvider foreignCalls, LoweringProvider lowerer, Replacements replacements, SuitesProvider suites, HotSpotRegistersProvider registers,
+                    SnippetReflectionProvider snippetReflection, HotSpotWordTypes wordTypes, Plugins graphBuilderPlugins, HotSpotGCProvider gc) {
+        super(metaAccess, codeCache, constantReflection, constantField, foreignCalls, lowerer, replacements, new HotSpotStampProvider(), gc);
         this.suites = suites;
         this.registers = registers;
         this.snippetReflection = snippetReflection;
         this.wordTypes = wordTypes;
         this.graphBuilderPlugins = graphBuilderPlugins;
+        this.gc = gc;
     }
 
     @Override
@@ -94,51 +95,54 @@
     }
 
     @Override
+    public HotSpotGCProvider getGC() {
+        return gc;
+    }
+
+    @Override
     public Providers copyWith(MetaAccessProvider substitution) {
         return new HotSpotProviders(substitution, getCodeCache(), getConstantReflection(), getConstantFieldProvider(), getForeignCalls(), getLowerer(), getReplacements(), getSuites(),
-                        getRegisters(), getSnippetReflection(), getWordTypes(), getGraphBuilderPlugins());
+                        getRegisters(), getSnippetReflection(), getWordTypes(), getGraphBuilderPlugins(), getGC());
     }
 
     @Override
     public Providers copyWith(CodeCacheProvider substitution) {
         return new HotSpotProviders(getMetaAccess(), (HotSpotCodeCacheProvider) substitution, getConstantReflection(), getConstantFieldProvider(), getForeignCalls(), getLowerer(), getReplacements(),
-                        getSuites(),
-                        getRegisters(), getSnippetReflection(), getWordTypes(), getGraphBuilderPlugins());
+                        getSuites(), getRegisters(), getSnippetReflection(), getWordTypes(), getGraphBuilderPlugins(), getGC());
     }
 
     @Override
     public Providers copyWith(ConstantReflectionProvider substitution) {
         return new HotSpotProviders(getMetaAccess(), getCodeCache(), substitution, getConstantFieldProvider(), getForeignCalls(), getLowerer(), getReplacements(), getSuites(),
-                        getRegisters(), getSnippetReflection(), getWordTypes(), getGraphBuilderPlugins());
+                        getRegisters(), getSnippetReflection(), getWordTypes(), getGraphBuilderPlugins(), getGC());
     }
 
     @Override
     public Providers copyWith(ConstantFieldProvider substitution) {
         return new HotSpotProviders(getMetaAccess(), getCodeCache(), getConstantReflection(), substitution, getForeignCalls(), getLowerer(), getReplacements(), getSuites(),
-                        getRegisters(), getSnippetReflection(), getWordTypes(), getGraphBuilderPlugins());
+                        getRegisters(), getSnippetReflection(), getWordTypes(), getGraphBuilderPlugins(), getGC());
     }
 
     @Override
     public Providers copyWith(ForeignCallsProvider substitution) {
         return new HotSpotProviders(getMetaAccess(), getCodeCache(), getConstantReflection(), getConstantFieldProvider(), (HotSpotForeignCallsProvider) substitution, getLowerer(), getReplacements(),
-                        getSuites(),
-                        getRegisters(), getSnippetReflection(), getWordTypes(), getGraphBuilderPlugins());
+                        getSuites(), getRegisters(), getSnippetReflection(), getWordTypes(), getGraphBuilderPlugins(), getGC());
     }
 
     @Override
     public Providers copyWith(LoweringProvider substitution) {
         return new HotSpotProviders(getMetaAccess(), getCodeCache(), getConstantReflection(), getConstantFieldProvider(), getForeignCalls(), substitution, getReplacements(), getSuites(),
-                        getRegisters(), getSnippetReflection(), getWordTypes(), getGraphBuilderPlugins());
+                        getRegisters(), getSnippetReflection(), getWordTypes(), getGraphBuilderPlugins(), getGC());
     }
 
     @Override
     public Providers copyWith(Replacements substitution) {
         return new HotSpotProviders(getMetaAccess(), getCodeCache(), getConstantReflection(), getConstantFieldProvider(), getForeignCalls(), getLowerer(), substitution, getSuites(),
-                        getRegisters(), getSnippetReflection(), getWordTypes(), getGraphBuilderPlugins());
+                        getRegisters(), getSnippetReflection(), getWordTypes(), getGraphBuilderPlugins(), getGC());
     }
 
     public Providers copyWith(Plugins substitution) {
         return new HotSpotProviders(getMetaAccess(), getCodeCache(), getConstantReflection(), getConstantFieldProvider(), getForeignCalls(), getLowerer(), getReplacements(), getSuites(),
-                        getRegisters(), getSnippetReflection(), getWordTypes(), substitution);
+                        getRegisters(), getSnippetReflection(), getWordTypes(), substitution, getGC());
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotSuitesProvider.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotSuitesProvider.java	Mon Jul 01 14:57:02 2019 -0700
@@ -39,8 +39,6 @@
 import org.graalvm.compiler.hotspot.lir.VerifyMaxRegisterSizePhase;
 import org.graalvm.compiler.hotspot.phases.AheadOfTimeVerificationPhase;
 import org.graalvm.compiler.hotspot.phases.LoadJavaMirrorWithKlassPhase;
-import org.graalvm.compiler.hotspot.phases.WriteBarrierAdditionPhase;
-import org.graalvm.compiler.hotspot.phases.WriteBarrierVerificationPhase;
 import org.graalvm.compiler.hotspot.phases.aot.AOTInliningPolicy;
 import org.graalvm.compiler.hotspot.phases.aot.EliminateRedundantInitializationPhase;
 import org.graalvm.compiler.hotspot.phases.aot.ReplaceConstantNodesPhase;
@@ -112,11 +110,6 @@
             }
         }
 
-        ret.getMidTier().appendPhase(new WriteBarrierAdditionPhase(config));
-        if (VerifyPhases.getValue(options)) {
-            ret.getMidTier().appendPhase(new WriteBarrierVerificationPhase(config));
-        }
-
         return ret;
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotUnsafeSubstitutions.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotUnsafeSubstitutions.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,19 +24,18 @@
 
 package org.graalvm.compiler.hotspot.meta;
 
-import static org.graalvm.compiler.serviceprovider.JavaVersionUtil.Java8OrEarlier;
-
 import org.graalvm.compiler.api.replacements.ClassSubstitution;
 import org.graalvm.compiler.api.replacements.MethodSubstitution;
 import org.graalvm.compiler.hotspot.HotSpotBackend;
 import org.graalvm.compiler.nodes.ComputeObjectAddressNode;
+import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
 import org.graalvm.compiler.word.Word;
 import jdk.internal.vm.compiler.word.WordFactory;
 
 @ClassSubstitution(className = {"jdk.internal.misc.Unsafe", "sun.misc.Unsafe"})
 public class HotSpotUnsafeSubstitutions {
 
-    public static final String copyMemoryName = Java8OrEarlier ? "copyMemory" : "copyMemory0";
+    public static final String copyMemoryName = JavaVersionUtil.JAVA_SPEC <= 8 ? "copyMemory" : "copyMemory0";
 
     @SuppressWarnings("unused")
     @MethodSubstitution(isStatic = false)
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/AllocaNode.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/AllocaNode.java	Mon Jul 01 14:57:02 2019 -0700
@@ -27,8 +27,6 @@
 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2;
 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1;
 
-import java.util.BitSet;
-
 import org.graalvm.compiler.core.common.type.StampFactory;
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.lir.VirtualStackSlot;
@@ -39,7 +37,6 @@
 import org.graalvm.compiler.word.Word;
 import org.graalvm.compiler.word.WordTypes;
 
-import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.Value;
 
 /**
@@ -55,26 +52,14 @@
      */
     protected final int slots;
 
-    /**
-     * The indexes of the object pointer slots in the block. Each such object pointer slot must be
-     * initialized before any safepoint in the method otherwise the garbage collector will see
-     * garbage values when processing these slots.
-     */
-    protected final BitSet objects;
-
     public AllocaNode(@InjectedNodeParameter WordTypes wordTypes, int slots) {
-        this(slots, wordTypes.getWordKind(), new BitSet());
-    }
-
-    public AllocaNode(int slots, JavaKind wordKind, BitSet objects) {
-        super(TYPE, StampFactory.forKind(wordKind));
+        super(TYPE, StampFactory.forKind(wordTypes.getWordKind()));
         this.slots = slots;
-        this.objects = objects;
     }
 
     @Override
     public void generate(NodeLIRBuilderTool gen) {
-        VirtualStackSlot array = gen.getLIRGeneratorTool().allocateStackSlots(slots, objects, null);
+        VirtualStackSlot array = gen.getLIRGeneratorTool().allocateStackSlots(slots);
         Value result = gen.getLIRGeneratorTool().emitAddress(array);
         gen.setResult(this, result);
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/DimensionsNode.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/DimensionsNode.java	Mon Jul 01 14:57:02 2019 -0700
@@ -28,8 +28,6 @@
 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2;
 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1;
 
-import java.util.BitSet;
-
 import org.graalvm.compiler.core.common.type.StampFactory;
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.lir.VirtualStackSlot;
@@ -64,7 +62,7 @@
         int size = rank * 4;
         int wordSize = lirGen.target().wordSize;
         int slots = roundUp(size, wordSize) / wordSize;
-        VirtualStackSlot array = lirGen.allocateStackSlots(slots, new BitSet(0), null);
+        VirtualStackSlot array = lirGen.allocateStackSlots(slots);
         Value result = lirGen.emitAddress(array);
         gen.setResult(this, result);
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/MonitorCounterNode.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/MonitorCounterNode.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,8 +26,6 @@
 
 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1;
 
-import java.util.BitSet;
-
 import org.graalvm.compiler.core.common.type.StampFactory;
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.graph.NodeClass;
@@ -56,7 +54,7 @@
     @Override
     public void generate(NodeLIRBuilderTool gen) {
         assert graph().getNodes().filter(MonitorCounterNode.class).count() == 1 : "monitor counters not canonicalized to single instance";
-        VirtualStackSlot counter = gen.getLIRGeneratorTool().getResult().getFrameMapBuilder().allocateStackSlots(1, new BitSet(0), null);
+        VirtualStackSlot counter = gen.getLIRGeneratorTool().getResult().getFrameMapBuilder().allocateStackSlots(1);
         Value result = gen.getLIRGeneratorTool().emitAddress(counter);
         gen.setResult(this, result);
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/VMErrorNode.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/VMErrorNode.java	Mon Jul 01 14:57:02 2019 -0700
@@ -38,7 +38,6 @@
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.LIRLowerable;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
-import org.graalvm.compiler.replacements.Log;
 import org.graalvm.compiler.replacements.nodes.CStringConstant;
 
 import jdk.vm.ci.code.CodeUtil;
@@ -46,8 +45,8 @@
 import jdk.vm.ci.meta.Value;
 
 /**
- * Causes the VM to exit with a description of the current Java location and an optional
- * {@linkplain Log#printf(String, long) formatted} error message specified.
+ * Causes the VM to exit with a description of the current Java location and an optional printf
+ * formatted error message specified.
  */
 @NodeInfo(cycles = CYCLES_UNKNOWN, size = SIZE_UNKNOWN)
 public final class VMErrorNode extends DeoptimizingStubCall implements LIRLowerable {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/WriteBarrier.java	Wed Jun 26 15:34:13 2019 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package org.graalvm.compiler.hotspot.nodes;
-
-import org.graalvm.compiler.core.common.type.StampFactory;
-import org.graalvm.compiler.graph.NodeClass;
-import org.graalvm.compiler.nodeinfo.NodeInfo;
-import org.graalvm.compiler.nodes.FixedWithNextNode;
-import org.graalvm.compiler.nodes.spi.Lowerable;
-import org.graalvm.compiler.nodes.spi.LoweringTool;
-
-@NodeInfo
-public abstract class WriteBarrier extends FixedWithNextNode implements Lowerable {
-
-    public static final NodeClass<WriteBarrier> TYPE = NodeClass.create(WriteBarrier.class);
-
-    protected WriteBarrier(NodeClass<? extends WriteBarrier> c) {
-        super(c, StampFactory.forVoid());
-    }
-
-    @Override
-    public void lower(LoweringTool tool) {
-        assert graph().getGuardsStage().areFrameStatesAtDeopts();
-        tool.getLowerer().lower(this, tool);
-    }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/LoadConstantIndirectlyNode.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/LoadConstantIndirectlyNode.java	Mon Jul 01 14:57:02 2019 -0700
@@ -43,7 +43,6 @@
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
 import org.graalvm.compiler.nodes.util.GraphUtil;
 
-import jdk.vm.ci.hotspot.HotSpotConstantPoolObject;
 import jdk.vm.ci.hotspot.HotSpotMetaspaceConstant;
 import jdk.vm.ci.hotspot.HotSpotObjectConstant;
 import jdk.vm.ci.meta.Constant;
@@ -84,7 +83,7 @@
     public void generate(NodeLIRBuilderTool gen) {
         assert constant != null : "Expected the value to fold: " + value;
         Value result;
-        if (constant instanceof HotSpotObjectConstant || constant instanceof HotSpotConstantPoolObject) {
+        if (constant instanceof HotSpotObjectConstant) {
             result = ((HotSpotLIRGenerator) gen.getLIRGeneratorTool()).emitLoadObjectAddress(constant);
         } else if (constant instanceof HotSpotMetaspaceConstant) {
             result = ((HotSpotLIRGenerator) gen.getLIRGeneratorTool()).emitLoadMetaspaceAddress(constant, action);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveConstantStubCall.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveConstantStubCall.java	Mon Jul 01 14:57:02 2019 -0700
@@ -45,7 +45,6 @@
 import org.graalvm.compiler.nodes.util.GraphUtil;
 import org.graalvm.compiler.word.Word;
 
-import jdk.vm.ci.hotspot.HotSpotConstantPoolObject;
 import jdk.vm.ci.hotspot.HotSpotMetaspaceConstant;
 import jdk.vm.ci.hotspot.HotSpotObjectConstant;
 import jdk.vm.ci.meta.Constant;
@@ -101,7 +100,7 @@
         Value result;
         LIRFrameState fs = gen.state(this);
         assert fs != null : "The stateAfter is null";
-        if (constant instanceof HotSpotObjectConstant || constant instanceof HotSpotConstantPoolObject) {
+        if (constant instanceof HotSpotObjectConstant) {
             result = ((HotSpotLIRGenerator) gen.getLIRGeneratorTool()).emitObjectConstantRetrieval(constant, stringValue, fs);
         } else if (constant instanceof HotSpotMetaspaceConstant) {
             if (action == HotSpotConstantLoadAction.RESOLVE) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/AheadOfTimeVerificationPhase.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/AheadOfTimeVerificationPhase.java	Mon Jul 01 14:57:02 2019 -0700
@@ -28,9 +28,9 @@
 
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.nodes.type.StampTool;
 import org.graalvm.compiler.phases.VerifyPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 
 import jdk.vm.ci.hotspot.HotSpotObjectConstant;
 import jdk.vm.ci.meta.JavaKind;
@@ -41,10 +41,10 @@
  *
  * @see LoadJavaMirrorWithKlassPhase
  */
-public class AheadOfTimeVerificationPhase extends VerifyPhase<PhaseContext> {
+public class AheadOfTimeVerificationPhase extends VerifyPhase<CoreProviders> {
 
     @Override
-    protected void verify(StructuredGraph graph, PhaseContext context) {
+    protected void verify(StructuredGraph graph, CoreProviders context) {
         for (ConstantNode node : getConstantNodes(graph)) {
             if (isIllegalObjectConstant(node)) {
                 throw new VerificationError("illegal object constant: " + node);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/LoadJavaMirrorWithKlassPhase.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/LoadJavaMirrorWithKlassPhase.java	Mon Jul 01 14:57:02 2019 -0700
@@ -44,9 +44,9 @@
 import org.graalvm.compiler.nodes.memory.FloatingReadNode;
 import org.graalvm.compiler.nodes.memory.address.AddressNode;
 import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.phases.BasePhase;
 import org.graalvm.compiler.phases.common.LoweringPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 
 import jdk.vm.ci.hotspot.HotSpotObjectConstant;
 import jdk.vm.ci.hotspot.HotSpotResolvedJavaField;
@@ -68,7 +68,7 @@
  *
  * @see AheadOfTimeVerificationPhase
  */
-public class LoadJavaMirrorWithKlassPhase extends BasePhase<PhaseContext> {
+public class LoadJavaMirrorWithKlassPhase extends BasePhase<CoreProviders> {
 
     private final CompressEncoding oopEncoding;
 
@@ -76,7 +76,7 @@
         this.oopEncoding = config.useCompressedOops ? config.getOopEncoding() : null;
     }
 
-    private ValueNode getClassConstantReplacement(StructuredGraph graph, PhaseContext context, JavaConstant constant) {
+    private ValueNode getClassConstantReplacement(StructuredGraph graph, CoreProviders context, JavaConstant constant) {
         if (constant instanceof HotSpotObjectConstant) {
             ConstantReflectionProvider constantReflection = context.getConstantReflection();
             ResolvedJavaType type = constantReflection.asJavaType(constant);
@@ -131,7 +131,7 @@
     }
 
     @Override
-    protected void run(StructuredGraph graph, PhaseContext context) {
+    protected void run(StructuredGraph graph, CoreProviders context) {
         for (ConstantNode node : getConstantNodes(graph)) {
             JavaConstant constant = node.asJavaConstant();
             ValueNode freadNode = getClassConstantReplacement(graph, context, constant);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/OnStackReplacementPhase.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/OnStackReplacementPhase.java	Mon Jul 01 14:57:02 2019 -0700
@@ -282,7 +282,7 @@
         NodeIterable<EntryMarkerNode> osrNodes = graph.getNodes(EntryMarkerNode.TYPE);
         EntryMarkerNode osr = osrNodes.first();
         if (osr == null) {
-            throw new PermanentBailoutException("No OnStackReplacementNode generated");
+            throw new GraalError("No OnStackReplacementNode generated");
         }
         if (osrNodes.count() > 1) {
             throw new GraalError("Multiple OnStackReplacementNodes generated");
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/WriteBarrierAdditionPhase.java	Wed Jun 26 15:34:13 2019 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package org.graalvm.compiler.hotspot.phases;
-
-import org.graalvm.compiler.debug.DebugCloseable;
-import org.graalvm.compiler.graph.Node;
-import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
-import org.graalvm.compiler.hotspot.gc.g1.G1BarrierSet;
-import org.graalvm.compiler.hotspot.gc.shared.BarrierSet;
-import org.graalvm.compiler.hotspot.gc.shared.CardTableBarrierSet;
-import org.graalvm.compiler.nodes.StructuredGraph;
-import org.graalvm.compiler.nodes.extended.ArrayRangeWrite;
-import org.graalvm.compiler.nodes.java.AbstractCompareAndSwapNode;
-import org.graalvm.compiler.nodes.java.LoweredAtomicReadAndWriteNode;
-import org.graalvm.compiler.nodes.memory.ReadNode;
-import org.graalvm.compiler.nodes.memory.WriteNode;
-import org.graalvm.compiler.phases.Phase;
-
-public class WriteBarrierAdditionPhase extends Phase {
-
-    private BarrierSet barrierSet;
-
-    public WriteBarrierAdditionPhase(GraalHotSpotVMConfig config) {
-        this.barrierSet = createBarrierSet(config);
-    }
-
-    @SuppressWarnings("try")
-    @Override
-    protected void run(StructuredGraph graph) {
-        for (Node n : graph.getNodes()) {
-            try (DebugCloseable scope = n.graph().withNodeSourcePosition(n)) {
-                if (n instanceof ReadNode) {
-                    barrierSet.addReadNodeBarriers((ReadNode) n, graph);
-                } else if (n instanceof WriteNode) {
-                    barrierSet.addWriteNodeBarriers((WriteNode) n, graph);
-                } else if (n instanceof LoweredAtomicReadAndWriteNode) {
-                    LoweredAtomicReadAndWriteNode loweredAtomicReadAndWriteNode = (LoweredAtomicReadAndWriteNode) n;
-                    barrierSet.addAtomicReadWriteNodeBarriers(loweredAtomicReadAndWriteNode, graph);
-                } else if (n instanceof AbstractCompareAndSwapNode) {
-                    barrierSet.addCASBarriers((AbstractCompareAndSwapNode) n, graph);
-                } else if (n instanceof ArrayRangeWrite) {
-                    ArrayRangeWrite node = (ArrayRangeWrite) n;
-                    if (node.writesObjectArray()) {
-                        barrierSet.addArrayRangeBarriers(node, graph);
-                    }
-                }
-            }
-        }
-    }
-
-    @Override
-    public boolean checkContract() {
-        return false;
-    }
-
-    private BarrierSet createBarrierSet(GraalHotSpotVMConfig config) {
-        if (config.useG1GC) {
-            return createG1BarrierSet(config);
-        } else {
-            return createCardTableBarrierSet(config);
-        }
-    }
-
-    protected BarrierSet createCardTableBarrierSet(GraalHotSpotVMConfig config) {
-        return new CardTableBarrierSet(config);
-    }
-
-    protected BarrierSet createG1BarrierSet(GraalHotSpotVMConfig config) {
-        return new G1BarrierSet(config);
-    }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/WriteBarrierVerificationPhase.java	Wed Jun 26 15:34:13 2019 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,207 +0,0 @@
-/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-
-package org.graalvm.compiler.hotspot.phases;
-
-import java.util.Iterator;
-
-import org.graalvm.compiler.debug.GraalError;
-import org.graalvm.compiler.graph.Node;
-import org.graalvm.compiler.graph.NodeFlood;
-import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
-import org.graalvm.compiler.hotspot.gc.g1.G1PostWriteBarrier;
-import org.graalvm.compiler.hotspot.gc.shared.ArrayRangeWriteBarrier;
-import org.graalvm.compiler.hotspot.gc.shared.ObjectWriteBarrier;
-import org.graalvm.compiler.hotspot.gc.shared.SerialWriteBarrier;
-import org.graalvm.compiler.nodeinfo.Verbosity;
-import org.graalvm.compiler.nodes.DeoptimizingNode;
-import org.graalvm.compiler.nodes.FixedWithNextNode;
-import org.graalvm.compiler.nodes.LoopBeginNode;
-import org.graalvm.compiler.nodes.StructuredGraph;
-import org.graalvm.compiler.nodes.ValueNode;
-import org.graalvm.compiler.nodes.extended.ArrayRangeWrite;
-import org.graalvm.compiler.nodes.java.LoweredAtomicReadAndWriteNode;
-import org.graalvm.compiler.nodes.java.LogicCompareAndSwapNode;
-import org.graalvm.compiler.nodes.java.ValueCompareAndSwapNode;
-import org.graalvm.compiler.nodes.memory.FixedAccessNode;
-import org.graalvm.compiler.nodes.memory.HeapAccess;
-import org.graalvm.compiler.nodes.memory.HeapAccess.BarrierType;
-import org.graalvm.compiler.nodes.memory.ReadNode;
-import org.graalvm.compiler.nodes.memory.WriteNode;
-import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
-import org.graalvm.compiler.nodes.type.StampTool;
-import org.graalvm.compiler.nodes.util.GraphUtil;
-import org.graalvm.compiler.phases.Phase;
-
-/**
- * Verification phase that checks if, for every write, at least one write barrier is present at all
- * paths leading to the previous safepoint. For every write, necessitating a write barrier, a
- * bottom-up traversal of the graph is performed up to the previous safepoints via all possible
- * paths. If, for a certain path, no write barrier satisfying the processed write is found, an
- * assertion is generated.
- */
-public class WriteBarrierVerificationPhase extends Phase {
-
-    private final GraalHotSpotVMConfig config;
-
-    public WriteBarrierVerificationPhase(GraalHotSpotVMConfig config) {
-        this.config = config;
-    }
-
-    @Override
-    protected void run(StructuredGraph graph) {
-        processWrites(graph);
-    }
-
-    private void processWrites(StructuredGraph graph) {
-        for (Node node : graph.getNodes()) {
-            if (isObjectWrite(node) || isObjectArrayRangeWrite(node)) {
-                if (node instanceof WriteNode) {
-                    WriteNode writeNode = (WriteNode) node;
-                    if (StampTool.isPointerAlwaysNull(writeNode.value())) {
-                        continue;
-                    }
-                }
-                validateWrite(node);
-            }
-        }
-    }
-
-    private void validateWrite(Node write) {
-        /*
-         * The currently validated write is checked in order to discover if it has an appropriate
-         * attached write barrier.
-         */
-        if (hasAttachedBarrier((FixedWithNextNode) write)) {
-            return;
-        }
-        NodeFlood frontier = write.graph().createNodeFlood();
-        expandFrontier(frontier, write);
-        Iterator<Node> iterator = frontier.iterator();
-        while (iterator.hasNext()) {
-            Node currentNode = iterator.next();
-            if (isSafepoint(currentNode)) {
-                throw new AssertionError("Write barrier must be present " + write.toString(Verbosity.All) + " / " + write.inputs());
-            }
-            if (useG1GC()) {
-                if (!(currentNode instanceof G1PostWriteBarrier) || (!validateBarrier((FixedAccessNode) write, (ObjectWriteBarrier) currentNode))) {
-                    expandFrontier(frontier, currentNode);
-                }
-            } else {
-                if (!(currentNode instanceof SerialWriteBarrier) || (!validateBarrier((FixedAccessNode) write, (ObjectWriteBarrier) currentNode)) ||
-                                ((currentNode instanceof SerialWriteBarrier) && !validateBarrier((FixedAccessNode) write, (ObjectWriteBarrier) currentNode))) {
-                    expandFrontier(frontier, currentNode);
-                }
-            }
-        }
-    }
-
-    private boolean useG1GC() {
-        return config.useG1GC;
-    }
-
-    private boolean hasAttachedBarrier(FixedWithNextNode node) {
-        final Node next = node.next();
-        final Node previous = node.predecessor();
-        boolean validatePreBarrier = useG1GC() && (isObjectWrite(node) || !((ArrayRangeWrite) node).isInitialization());
-        if (node instanceof WriteNode) {
-            WriteNode writeNode = (WriteNode) node;
-            if (config.useDeferredInitBarriers && writeNode.getLocationIdentity().isInit()) {
-                return true;
-            }
-            if (writeNode.getLocationIdentity().isInit()) {
-                validatePreBarrier = false;
-            }
-        }
-        if (isObjectWrite(node)) {
-            return (isObjectBarrier(node, next) || StampTool.isPointerAlwaysNull(getValueWritten(node))) && (!validatePreBarrier || isObjectBarrier(node, previous));
-        } else if (isObjectArrayRangeWrite(node)) {
-            return (isArrayBarrier(node, next) || StampTool.isPointerAlwaysNull(getValueWritten(node))) && (!validatePreBarrier || isArrayBarrier(node, previous));
-        } else {
-            return true;
-        }
-    }
-
-    private static boolean isObjectBarrier(FixedWithNextNode node, final Node next) {
-        return next instanceof ObjectWriteBarrier && validateBarrier((FixedAccessNode) node, (ObjectWriteBarrier) next);
-    }
-
-    private static boolean isArrayBarrier(FixedWithNextNode node, final Node next) {
-        return (next instanceof ArrayRangeWriteBarrier) && ((ArrayRangeWrite) node).getAddress() == ((ArrayRangeWriteBarrier) next).getAddress();
-    }
-
-    private static boolean isObjectWrite(Node node) {
-        // Read nodes with barrier attached (G1 Ref field) are not validated yet.
-        return node instanceof FixedAccessNode && ((HeapAccess) node).getBarrierType() != BarrierType.NONE && !(node instanceof ReadNode);
-    }
-
-    private static boolean isObjectArrayRangeWrite(Node node) {
-        return node instanceof ArrayRangeWrite && ((ArrayRangeWrite) node).writesObjectArray();
-    }
-
-    private static void expandFrontier(NodeFlood frontier, Node node) {
-        for (Node previousNode : node.cfgPredecessors()) {
-            if (previousNode != null) {
-                frontier.add(previousNode);
-            }
-        }
-    }
-
-    private static boolean isSafepoint(Node node) {
-        if (node instanceof FixedAccessNode) {
-            // Implicit null checks on reads or writes do not count.
-            return false;
-        }
-        /*
-         * LoopBegin nodes are also treated as safepoints since a bottom-up analysis is performed
-         * and loop safepoints are placed before LoopEnd nodes. Possible elimination of write
-         * barriers inside loops, derived from writes outside loops, can not be permitted.
-         */
-        return ((node instanceof DeoptimizingNode) && ((DeoptimizingNode) node).canDeoptimize()) || (node instanceof LoopBeginNode);
-    }
-
-    private static ValueNode getValueWritten(FixedWithNextNode write) {
-        if (write instanceof WriteNode) {
-            return ((WriteNode) write).value();
-        } else if (write instanceof LogicCompareAndSwapNode) {
-            return ((LogicCompareAndSwapNode) write).getNewValue();
-        } else if (write instanceof LoweredAtomicReadAndWriteNode) {
-            return ((LoweredAtomicReadAndWriteNode) write).getNewValue();
-        } else {
-            throw GraalError.shouldNotReachHere(String.format("unexpected write node %s", write));
-        }
-    }
-
-    private static boolean validateBarrier(FixedAccessNode write, ObjectWriteBarrier barrier) {
-        assert write instanceof WriteNode || write instanceof LogicCompareAndSwapNode || write instanceof ValueCompareAndSwapNode ||
-                        write instanceof LoweredAtomicReadAndWriteNode : "Node must be of type requiring a write barrier " + write;
-        if (!barrier.usePrecise()) {
-            if (barrier.getAddress() instanceof OffsetAddressNode && write.getAddress() instanceof OffsetAddressNode) {
-                return GraphUtil.unproxify(((OffsetAddressNode) barrier.getAddress()).getBase()) == GraphUtil.unproxify(((OffsetAddressNode) write.getAddress()).getBase());
-            }
-        }
-        return barrier.getAddress() == write.getAddress();
-    }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/aot/EliminateRedundantInitializationPhase.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/aot/EliminateRedundantInitializationPhase.java	Mon Jul 01 14:57:02 2019 -0700
@@ -30,10 +30,6 @@
 import java.util.Iterator;
 import java.util.List;
 
-import jdk.vm.ci.hotspot.HotSpotMetaspaceConstant;
-import jdk.vm.ci.meta.Constant;
-import jdk.vm.ci.meta.ResolvedJavaType;
-
 import jdk.internal.vm.compiler.collections.EconomicSet;
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.hotspot.nodes.aot.InitializeKlassNode;
@@ -43,12 +39,16 @@
 import org.graalvm.compiler.nodes.FixedWithNextNode;
 import org.graalvm.compiler.nodes.Invoke;
 import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.phases.BasePhase;
 import org.graalvm.compiler.phases.graph.MergeableState;
 import org.graalvm.compiler.phases.graph.PostOrderNodeIterator;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 
-public class EliminateRedundantInitializationPhase extends BasePhase<PhaseContext> {
+import jdk.vm.ci.hotspot.HotSpotMetaspaceConstant;
+import jdk.vm.ci.meta.Constant;
+import jdk.vm.ci.meta.ResolvedJavaType;
+
+public class EliminateRedundantInitializationPhase extends BasePhase<CoreProviders> {
     /**
      * Find each {@link Invoke} that has a corresponding {@link InitializeKlassNode}. These
      * {@link InitializeKlassNode} are redundant and are removed.
@@ -252,7 +252,7 @@
     }
 
     @Override
-    protected void run(StructuredGraph graph, PhaseContext context) {
+    protected void run(StructuredGraph graph, CoreProviders context) {
         removeInitsAtStaticCalls(graph);
         removeRedundantInits(graph);
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/aot/ReplaceConstantNodesPhase.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/aot/ReplaceConstantNodesPhase.java	Mon Jul 01 14:57:02 2019 -0700
@@ -61,12 +61,12 @@
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.FloatingNode;
 import org.graalvm.compiler.nodes.cfg.Block;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.phases.BasePhase;
 import org.graalvm.compiler.phases.graph.ReentrantNodeIterator;
 import org.graalvm.compiler.phases.graph.ReentrantNodeIterator.NodeIteratorClosure;
 import org.graalvm.compiler.phases.schedule.SchedulePhase;
 import org.graalvm.compiler.phases.schedule.SchedulePhase.SchedulingStrategy;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 
 import jdk.vm.ci.code.BytecodeFrame;
 import jdk.vm.ci.hotspot.HotSpotMetaspaceConstant;
@@ -78,7 +78,7 @@
 import jdk.vm.ci.meta.MetaAccessProvider;
 import jdk.vm.ci.meta.ResolvedJavaType;
 
-public class ReplaceConstantNodesPhase extends BasePhase<PhaseContext> {
+public class ReplaceConstantNodesPhase extends BasePhase<CoreProviders> {
 
     private final boolean verifyFingerprints;
 
@@ -448,7 +448,7 @@
      * @param node
      * @param context
      */
-    private static void handleLoadMethodCounters(StructuredGraph graph, FrameStateMapperClosure stateMapper, LoadMethodCountersNode node, PhaseContext context) {
+    private static void handleLoadMethodCounters(StructuredGraph graph, FrameStateMapperClosure stateMapper, LoadMethodCountersNode node, CoreProviders context) {
         ResolvedJavaType type = node.getMethod().getDeclaringClass();
         Stamp hubStamp = context.getStampProvider().createHubStamp((ObjectStamp) StampFactory.objectNonNull());
         ConstantReflectionProvider constantReflection = context.getConstantReflection();
@@ -466,7 +466,7 @@
      * @param stateMapper
      * @param context
      */
-    private static void replaceLoadMethodCounters(StructuredGraph graph, FrameStateMapperClosure stateMapper, PhaseContext context) {
+    private static void replaceLoadMethodCounters(StructuredGraph graph, FrameStateMapperClosure stateMapper, CoreProviders context) {
         new SchedulePhase(SchedulingStrategy.LATEST_OUT_OF_LOOPS, true).apply(graph, false);
 
         for (LoadMethodCountersNode node : getLoadMethodCountersNodes(graph)) {
@@ -496,7 +496,7 @@
     }
 
     @Override
-    protected void run(StructuredGraph graph, PhaseContext context) {
+    protected void run(StructuredGraph graph, CoreProviders context) {
         FrameStateMapperClosure stateMapper = new FrameStateMapperClosure(graph);
         ReentrantNodeIterator.apply(stateMapper, graph.start(), null);
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/profiling/FinalizeProfileNodesPhase.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/profiling/FinalizeProfileNodesPhase.java	Mon Jul 01 14:57:02 2019 -0700
@@ -46,16 +46,16 @@
 import org.graalvm.compiler.nodes.calc.MulNode;
 import org.graalvm.compiler.nodes.cfg.Block;
 import org.graalvm.compiler.nodes.cfg.ControlFlowGraph;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.nodes.util.GraphUtil;
 import org.graalvm.compiler.options.Option;
 import org.graalvm.compiler.options.OptionKey;
 import org.graalvm.compiler.options.OptionType;
 import org.graalvm.compiler.phases.BasePhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 
 import jdk.vm.ci.meta.ResolvedJavaMethod;
 
-public class FinalizeProfileNodesPhase extends BasePhase<PhaseContext> {
+public class FinalizeProfileNodesPhase extends BasePhase<CoreProviders> {
     private int inlineeInvokeNotificationFreqLog;
 
     public static class Options {
@@ -156,7 +156,7 @@
     }
 
     @Override
-    protected void run(StructuredGraph graph, PhaseContext context) {
+    protected void run(StructuredGraph graph, CoreProviders context) {
         if (simpleMethodHeuristic(graph)) {
             removeAllProfilingNodes(graph);
             return;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotG1WriteBarrierSnippets.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.hotspot.replacements;
+
+import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfigBase.INJECTED_METAACCESS;
+import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfigBase.INJECTED_VMCONFIG;
+
+import org.graalvm.compiler.core.common.CompressEncoding;
+import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
+import org.graalvm.compiler.debug.DebugHandlersFactory;
+import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
+import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProviderImpl;
+import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
+import org.graalvm.compiler.hotspot.meta.HotSpotRegistersProvider;
+import org.graalvm.compiler.hotspot.nodes.GraalHotSpotVMConfigNode;
+import org.graalvm.compiler.hotspot.nodes.HotSpotCompressionNode;
+import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.gc.G1ArrayRangePostWriteBarrier;
+import org.graalvm.compiler.nodes.gc.G1ArrayRangePreWriteBarrier;
+import org.graalvm.compiler.nodes.gc.G1PostWriteBarrier;
+import org.graalvm.compiler.nodes.gc.G1PreWriteBarrier;
+import org.graalvm.compiler.nodes.gc.G1ReferentFieldReadBarrier;
+import org.graalvm.compiler.nodes.spi.LoweringTool;
+import org.graalvm.compiler.options.OptionValues;
+import org.graalvm.compiler.replacements.ReplacementsUtil;
+import org.graalvm.compiler.replacements.SnippetCounter.Group;
+import org.graalvm.compiler.replacements.SnippetCounter.Group.Factory;
+import org.graalvm.compiler.replacements.SnippetTemplate.AbstractTemplates;
+import org.graalvm.compiler.replacements.SnippetTemplate.SnippetInfo;
+import org.graalvm.compiler.replacements.gc.G1WriteBarrierSnippets;
+import org.graalvm.compiler.word.Word;
+import jdk.internal.vm.compiler.word.WordFactory;
+
+import jdk.vm.ci.code.Register;
+import jdk.vm.ci.code.TargetDescription;
+import jdk.vm.ci.meta.JavaKind;
+
+public final class HotSpotG1WriteBarrierSnippets extends G1WriteBarrierSnippets {
+    public static final ForeignCallDescriptor G1WBPRECALL = new ForeignCallDescriptor("write_barrier_pre", void.class, Object.class);
+    public static final ForeignCallDescriptor G1WBPOSTCALL = new ForeignCallDescriptor("write_barrier_post", void.class, Word.class);
+    public static final ForeignCallDescriptor VALIDATE_OBJECT = new ForeignCallDescriptor("validate_object", boolean.class, Word.class, Word.class);
+
+    private final GraalHotSpotVMConfig config;
+    private final Register threadRegister;
+
+    public HotSpotG1WriteBarrierSnippets(GraalHotSpotVMConfig config, HotSpotRegistersProvider registers) {
+        this.config = config;
+        this.threadRegister = registers.getThreadRegister();
+    }
+
+    @Override
+    protected Word getThread() {
+        return HotSpotReplacementsUtil.registerAsWord(threadRegister);
+    }
+
+    @Override
+    protected int wordSize() {
+        return HotSpotReplacementsUtil.wordSize();
+    }
+
+    @Override
+    protected int objectArrayIndexScale() {
+        return ReplacementsUtil.arrayIndexScale(INJECTED_METAACCESS, JavaKind.Object);
+    }
+
+    @Override
+    protected int satbQueueMarkingOffset() {
+        return HotSpotReplacementsUtil.g1SATBQueueMarkingOffset(INJECTED_VMCONFIG);
+    }
+
+    @Override
+    protected int satbQueueBufferOffset() {
+        return HotSpotReplacementsUtil.g1SATBQueueBufferOffset(INJECTED_VMCONFIG);
+    }
+
+    @Override
+    protected int satbQueueIndexOffset() {
+        return HotSpotReplacementsUtil.g1SATBQueueIndexOffset(INJECTED_VMCONFIG);
+    }
+
+    @Override
+    protected int cardQueueBufferOffset() {
+        return HotSpotReplacementsUtil.g1CardQueueBufferOffset(INJECTED_VMCONFIG);
+    }
+
+    @Override
+    protected int cardQueueIndexOffset() {
+        return HotSpotReplacementsUtil.g1CardQueueIndexOffset(INJECTED_VMCONFIG);
+    }
+
+    @Override
+    protected byte dirtyCardValue() {
+        return HotSpotReplacementsUtil.dirtyCardValue(INJECTED_VMCONFIG);
+    }
+
+    @Override
+    protected byte youngCardValue() {
+        return HotSpotReplacementsUtil.g1YoungCardValue(INJECTED_VMCONFIG);
+    }
+
+    @Override
+    protected Word cardTableAddress() {
+        return WordFactory.unsigned(GraalHotSpotVMConfigNode.cardTableAddress());
+    }
+
+    @Override
+    protected int cardTableShift() {
+        return HotSpotReplacementsUtil.cardTableShift(INJECTED_VMCONFIG);
+    }
+
+    @Override
+    protected int logOfHeapRegionGrainBytes() {
+        return GraalHotSpotVMConfigNode.logOfHeapRegionGrainBytes();
+    }
+
+    @Override
+    protected ForeignCallDescriptor preWriteBarrierCallDescriptor() {
+        return G1WBPRECALL;
+    }
+
+    @Override
+    protected ForeignCallDescriptor postWriteBarrierCallDescriptor() {
+        return G1WBPOSTCALL;
+    }
+
+    @Override
+    protected boolean verifyOops() {
+        return HotSpotReplacementsUtil.verifyOops(INJECTED_VMCONFIG);
+    }
+
+    @Override
+    protected boolean verifyBarrier() {
+        return ReplacementsUtil.REPLACEMENTS_ASSERTIONS_ENABLED || config.verifyBeforeGC || config.verifyAfterGC;
+    }
+
+    @Override
+    protected long gcTotalCollectionsAddress() {
+        return HotSpotReplacementsUtil.gcTotalCollectionsAddress(INJECTED_VMCONFIG);
+    }
+
+    @Override
+    protected ForeignCallDescriptor verifyOopCallDescriptor() {
+        return HotSpotForeignCallsProviderImpl.VERIFY_OOP;
+    }
+
+    @Override
+    protected ForeignCallDescriptor validateObjectCallDescriptor() {
+        return VALIDATE_OBJECT;
+    }
+
+    @Override
+    protected ForeignCallDescriptor printfCallDescriptor() {
+        return Log.LOG_PRINTF;
+    }
+
+    public static class Templates extends AbstractTemplates {
+        private final SnippetInfo g1PreWriteBarrier;
+        private final SnippetInfo g1ReferentReadBarrier;
+        private final SnippetInfo g1PostWriteBarrier;
+        private final SnippetInfo g1ArrayRangePreWriteBarrier;
+        private final SnippetInfo g1ArrayRangePostWriteBarrier;
+
+        private final G1WriteBarrierLowerer lowerer;
+
+        public Templates(OptionValues options, Iterable<DebugHandlersFactory> factories, Group.Factory factory, HotSpotProviders providers, TargetDescription target, GraalHotSpotVMConfig config) {
+            super(options, factories, providers, providers.getSnippetReflection(), target);
+            this.lowerer = new HotspotG1WriteBarrierLowerer(config, factory);
+
+            HotSpotG1WriteBarrierSnippets receiver = new HotSpotG1WriteBarrierSnippets(config, providers.getRegisters());
+            g1PreWriteBarrier = snippet(G1WriteBarrierSnippets.class, "g1PreWriteBarrier", null, receiver, GC_INDEX_LOCATION, GC_LOG_LOCATION, SATB_QUEUE_MARKING_LOCATION, SATB_QUEUE_INDEX_LOCATION,
+                            SATB_QUEUE_BUFFER_LOCATION);
+            g1ReferentReadBarrier = g1PreWriteBarrier;
+            g1PostWriteBarrier = snippet(G1WriteBarrierSnippets.class, "g1PostWriteBarrier", null, receiver, GC_CARD_LOCATION, GC_INDEX_LOCATION, GC_LOG_LOCATION, CARD_QUEUE_INDEX_LOCATION,
+                            CARD_QUEUE_BUFFER_LOCATION);
+            g1ArrayRangePreWriteBarrier = snippet(G1WriteBarrierSnippets.class, "g1ArrayRangePreWriteBarrier", null, receiver, GC_INDEX_LOCATION, GC_LOG_LOCATION, SATB_QUEUE_MARKING_LOCATION,
+                            SATB_QUEUE_INDEX_LOCATION, SATB_QUEUE_BUFFER_LOCATION);
+            g1ArrayRangePostWriteBarrier = snippet(G1WriteBarrierSnippets.class, "g1ArrayRangePostWriteBarrier", null, receiver, GC_CARD_LOCATION, GC_INDEX_LOCATION, GC_LOG_LOCATION,
+                            CARD_QUEUE_INDEX_LOCATION, CARD_QUEUE_BUFFER_LOCATION);
+        }
+
+        public void lower(G1PreWriteBarrier barrier, LoweringTool tool) {
+            lowerer.lower(this, g1PreWriteBarrier, barrier, tool);
+        }
+
+        public void lower(G1ReferentFieldReadBarrier barrier, LoweringTool tool) {
+            lowerer.lower(this, g1ReferentReadBarrier, barrier, tool);
+        }
+
+        public void lower(G1PostWriteBarrier barrier, LoweringTool tool) {
+            lowerer.lower(this, g1PostWriteBarrier, barrier, tool);
+        }
+
+        public void lower(G1ArrayRangePreWriteBarrier barrier, LoweringTool tool) {
+            lowerer.lower(this, g1ArrayRangePreWriteBarrier, barrier, tool);
+        }
+
+        public void lower(G1ArrayRangePostWriteBarrier barrier, LoweringTool tool) {
+            lowerer.lower(this, g1ArrayRangePostWriteBarrier, barrier, tool);
+        }
+    }
+
+    static final class HotspotG1WriteBarrierLowerer extends G1WriteBarrierLowerer {
+        private final CompressEncoding oopEncoding;
+
+        HotspotG1WriteBarrierLowerer(GraalHotSpotVMConfig config, Factory factory) {
+            super(factory);
+            oopEncoding = config.useCompressedOops ? config.getOopEncoding() : null;
+        }
+
+        @Override
+        public ValueNode uncompress(ValueNode expected) {
+            assert oopEncoding != null;
+            return HotSpotCompressionNode.uncompress(expected, oopEncoding);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotSerialWriteBarrierSnippets.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.hotspot.replacements;
+
+import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfigBase.INJECTED_VMCONFIG;
+
+import org.graalvm.compiler.debug.DebugHandlersFactory;
+import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
+import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
+import org.graalvm.compiler.hotspot.nodes.GraalHotSpotVMConfigNode;
+import org.graalvm.compiler.nodes.gc.SerialArrayRangeWriteBarrier;
+import org.graalvm.compiler.nodes.gc.SerialWriteBarrier;
+import org.graalvm.compiler.nodes.spi.LoweringTool;
+import org.graalvm.compiler.options.OptionValues;
+import org.graalvm.compiler.replacements.ReplacementsUtil;
+import org.graalvm.compiler.replacements.SnippetCounter.Group;
+import org.graalvm.compiler.replacements.SnippetTemplate.AbstractTemplates;
+import org.graalvm.compiler.replacements.SnippetTemplate.SnippetInfo;
+import org.graalvm.compiler.replacements.gc.SerialWriteBarrierSnippets;
+import org.graalvm.compiler.word.Word;
+import jdk.internal.vm.compiler.word.WordFactory;
+
+import jdk.vm.ci.code.TargetDescription;
+
+public class HotSpotSerialWriteBarrierSnippets extends SerialWriteBarrierSnippets {
+    private final GraalHotSpotVMConfig config;
+
+    public HotSpotSerialWriteBarrierSnippets(GraalHotSpotVMConfig config) {
+        this.config = config;
+    }
+
+    @Override
+    public Word cardTableAddress() {
+        return WordFactory.unsigned(GraalHotSpotVMConfigNode.cardTableAddress());
+    }
+
+    @Override
+    public int cardTableShift() {
+        return HotSpotReplacementsUtil.cardTableShift(INJECTED_VMCONFIG);
+    }
+
+    @Override
+    public boolean verifyBarrier() {
+        return ReplacementsUtil.REPLACEMENTS_ASSERTIONS_ENABLED || config.verifyBeforeGC || config.verifyAfterGC;
+    }
+
+    @Override
+    protected byte dirtyCardValue() {
+        return config.dirtyCardValue;
+    }
+
+    public static class Templates extends AbstractTemplates {
+        private final SnippetInfo serialImpreciseWriteBarrier;
+        private final SnippetInfo serialPreciseWriteBarrier;
+        private final SnippetInfo serialArrayRangeWriteBarrier;
+
+        private final SerialWriteBarrierLowerer lowerer;
+
+        public Templates(OptionValues options, Iterable<DebugHandlersFactory> factories, Group.Factory factory, HotSpotProviders providers, TargetDescription target, GraalHotSpotVMConfig config) {
+            super(options, factories, providers, providers.getSnippetReflection(), target);
+            this.lowerer = new SerialWriteBarrierLowerer(factory);
+
+            HotSpotSerialWriteBarrierSnippets receiver = new HotSpotSerialWriteBarrierSnippets(config);
+            serialImpreciseWriteBarrier = snippet(SerialWriteBarrierSnippets.class, "serialImpreciseWriteBarrier", null, receiver, GC_CARD_LOCATION);
+            serialPreciseWriteBarrier = snippet(SerialWriteBarrierSnippets.class, "serialPreciseWriteBarrier", null, receiver, GC_CARD_LOCATION);
+            serialArrayRangeWriteBarrier = snippet(SerialWriteBarrierSnippets.class, "serialArrayRangeWriteBarrier", null, receiver, GC_CARD_LOCATION);
+        }
+
+        public void lower(SerialWriteBarrier barrier, LoweringTool tool) {
+            lowerer.lower(this, serialPreciseWriteBarrier, serialImpreciseWriteBarrier, barrier, tool);
+        }
+
+        public void lower(SerialArrayRangeWriteBarrier barrier, LoweringTool tool) {
+            lowerer.lower(this, serialArrayRangeWriteBarrier, barrier, tool);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/Log.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.hotspot.replacements;
+
+import static org.graalvm.compiler.replacements.nodes.CStringConstant.cstring;
+
+import java.io.PrintStream;
+
+import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
+import org.graalvm.compiler.graph.Node.ConstantNodeParameter;
+import org.graalvm.compiler.graph.Node.NodeIntrinsic;
+import org.graalvm.compiler.nodes.extended.ForeignCallNode;
+import org.graalvm.compiler.word.Word;
+
+import jdk.vm.ci.meta.JavaKind;
+
+//JaCoCo Exclude
+
+/**
+ * Provides {@link PrintStream}-like logging facility.
+ */
+public final class Log {
+
+    public static final ForeignCallDescriptor LOG_PRIMITIVE = new ForeignCallDescriptor("logPrimitive", void.class, int.class, long.class, boolean.class);
+    public static final ForeignCallDescriptor LOG_OBJECT = new ForeignCallDescriptor("logObject", void.class, Object.class, boolean.class, boolean.class);
+    public static final ForeignCallDescriptor LOG_PRINTF = new ForeignCallDescriptor("logPrintf", void.class, Word.class, long.class, long.class, long.class);
+
+    @NodeIntrinsic(ForeignCallNode.class)
+    private static native void log(@ConstantNodeParameter ForeignCallDescriptor logObject, Object object, boolean asString, boolean newline);
+
+    @NodeIntrinsic(ForeignCallNode.class)
+    private static native void log(@ConstantNodeParameter ForeignCallDescriptor logPrimitive, int typeChar, long value, boolean newline);
+
+    @NodeIntrinsic(ForeignCallNode.class)
+    private static native void printf(@ConstantNodeParameter ForeignCallDescriptor logPrintf, Word format, long v1, long v2, long v3);
+
+    public static void print(boolean value) {
+        log(LOG_PRIMITIVE, JavaKind.Boolean.getTypeChar(), value ? 1L : 0L, false);
+    }
+
+    public static void print(byte value) {
+        log(LOG_PRIMITIVE, JavaKind.Byte.getTypeChar(), value, false);
+    }
+
+    public static void print(char value) {
+        log(LOG_PRIMITIVE, JavaKind.Char.getTypeChar(), value, false);
+    }
+
+    public static void print(short value) {
+        log(LOG_PRIMITIVE, JavaKind.Short.getTypeChar(), value, false);
+    }
+
+    public static void print(int value) {
+        log(LOG_PRIMITIVE, JavaKind.Int.getTypeChar(), value, false);
+    }
+
+    public static void print(long value) {
+        log(LOG_PRIMITIVE, JavaKind.Long.getTypeChar(), value, false);
+    }
+
+    /**
+     * Prints a formatted string to the log stream.
+     *
+     * @param format a C style printf format value that can contain at most one conversion specifier
+     *            (i.e., a sequence of characters starting with '%').
+     * @param value the value associated with the conversion specifier
+     */
+    public static void printf(String format, long value) {
+        printf(LOG_PRINTF, cstring(format), value, 0L, 0L);
+    }
+
+    public static void printf(String format, long v1, long v2) {
+        printf(LOG_PRINTF, cstring(format), v1, v2, 0L);
+    }
+
+    public static void printf(String format, long v1, long v2, long v3) {
+        printf(LOG_PRINTF, cstring(format), v1, v2, v3);
+    }
+
+    public static void print(float value) {
+        if (Float.isNaN(value)) {
+            print("NaN");
+        } else if (value == Float.POSITIVE_INFINITY) {
+            print("Infinity");
+        } else if (value == Float.NEGATIVE_INFINITY) {
+            print("-Infinity");
+        } else {
+            log(LOG_PRIMITIVE, JavaKind.Float.getTypeChar(), Float.floatToRawIntBits(value), false);
+        }
+    }
+
+    public static void print(double value) {
+        if (Double.isNaN(value)) {
+            print("NaN");
+        } else if (value == Double.POSITIVE_INFINITY) {
+            print("Infinity");
+        } else if (value == Double.NEGATIVE_INFINITY) {
+            print("-Infinity");
+        } else {
+            log(LOG_PRIMITIVE, JavaKind.Double.getTypeChar(), Double.doubleToRawLongBits(value), false);
+        }
+    }
+
+    public static void print(String value) {
+        log(LOG_OBJECT, value, true, false);
+    }
+
+    public static void printObject(Object o) {
+        log(LOG_OBJECT, o, false, false);
+    }
+
+    public static void println(boolean value) {
+        log(LOG_PRIMITIVE, JavaKind.Boolean.getTypeChar(), value ? 1L : 0L, true);
+    }
+
+    public static void println(byte value) {
+        log(LOG_PRIMITIVE, JavaKind.Byte.getTypeChar(), value, true);
+    }
+
+    public static void println(char value) {
+        log(LOG_PRIMITIVE, JavaKind.Char.getTypeChar(), value, true);
+    }
+
+    public static void println(short value) {
+        log(LOG_PRIMITIVE, JavaKind.Short.getTypeChar(), value, true);
+    }
+
+    public static void println(int value) {
+        log(LOG_PRIMITIVE, JavaKind.Int.getTypeChar(), value, true);
+    }
+
+    public static void println(long value) {
+        log(LOG_PRIMITIVE, JavaKind.Long.getTypeChar(), value, true);
+    }
+
+    public static void println(float value) {
+        if (Float.isNaN(value)) {
+            println("NaN");
+        } else if (value == Float.POSITIVE_INFINITY) {
+            println("Infinity");
+        } else if (value == Float.NEGATIVE_INFINITY) {
+            println("-Infinity");
+        } else {
+            log(LOG_PRIMITIVE, JavaKind.Float.getTypeChar(), Float.floatToRawIntBits(value), true);
+        }
+    }
+
+    public static void println(double value) {
+        if (Double.isNaN(value)) {
+            println("NaN");
+        } else if (value == Double.POSITIVE_INFINITY) {
+            println("Infinity");
+        } else if (value == Double.NEGATIVE_INFINITY) {
+            println("-Infinity");
+        } else {
+            log(LOG_PRIMITIVE, JavaKind.Double.getTypeChar(), Double.doubleToRawLongBits(value), true);
+        }
+    }
+
+    public static void println(String value) {
+        log(LOG_OBJECT, value, true, true);
+    }
+
+    public static void printlnObject(Object o) {
+        log(LOG_OBJECT, o, false, true);
+    }
+
+    public static void println() {
+        println("");
+    }
+}
+
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/MonitorSnippets.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/MonitorSnippets.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -122,7 +122,6 @@
 import org.graalvm.compiler.nodes.type.StampTool;
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.phases.common.inlining.InliningUtil;
-import org.graalvm.compiler.replacements.Log;
 import org.graalvm.compiler.replacements.SnippetCounter;
 import org.graalvm.compiler.replacements.SnippetTemplate.AbstractTemplates;
 import org.graalvm.compiler.replacements.SnippetTemplate.Arguments;
@@ -753,7 +752,8 @@
     public static class Templates extends AbstractTemplates {
 
         private final SnippetInfo monitorenter = snippet(MonitorSnippets.class, "monitorenter");
-        private final SnippetInfo monitorexit = snippet(MonitorSnippets.class, "monitorexit");
+        private final SnippetInfo monitorexit = snippet(MonitorSnippets.class, "monitorexit", DISPLACED_MARK_WORD_LOCATION, OBJECT_MONITOR_OWNER_LOCATION, OBJECT_MONITOR_CXQ_LOCATION,
+                        OBJECT_MONITOR_ENTRY_LIST_LOCATION, OBJECT_MONITOR_RECURSION_LOCATION, OBJECT_MONITOR_SUCC_LOCATION);
         private final SnippetInfo monitorenterStub = snippet(MonitorSnippets.class, "monitorenterStub");
         private final SnippetInfo monitorexitStub = snippet(MonitorSnippets.class, "monitorexitStub");
         private final SnippetInfo initCounter = snippet(MonitorSnippets.class, "initCounter");
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/NewObjectSnippets.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/NewObjectSnippets.java	Mon Jul 01 14:57:02 2019 -0700
@@ -38,6 +38,7 @@
 import static org.graalvm.compiler.hotspot.HotSpotBackend.NEW_MULTI_ARRAY;
 import static org.graalvm.compiler.hotspot.HotSpotBackend.NEW_MULTI_ARRAY_OR_NULL;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.CLASS_ARRAY_KLASS_LOCATION;
+import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.CLASS_STATE_LOCATION;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.HUB_WRITE_LOCATION;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.MARK_WORD_LOCATION;
 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.PROTOTYPE_MARK_WORD_LOCATION;
@@ -604,7 +605,7 @@
         } else {
             // Use Word instead of int to avoid extension to long in generated code
             Word off = WordFactory.signed(offset);
-            if (useBulkZeroing && probability(SLOW_PATH_PROBABILITY, size >= getMinimalBulkZeroingSize(INJECTED_OPTIONVALUES))) {
+            if (useBulkZeroing && value == 0 && probability(SLOW_PATH_PROBABILITY, (size - offset) >= getMinimalBulkZeroingSize(INJECTED_OPTIONVALUES))) {
                 if (theCounters != null && theCounters.instanceBulkInit != null) {
                     theCounters.instanceBulkInit.inc();
                 }
@@ -623,7 +624,6 @@
                 for (; off.rawValue() < size; off = off.add(8)) {
                     memory.initializeLong(off, value, LocationIdentity.init());
                 }
-
             }
         }
     }
@@ -714,9 +714,10 @@
 
     public static class Templates extends AbstractTemplates {
 
-        private final SnippetInfo allocateInstance = snippet(NewObjectSnippets.class, "allocateInstance", MARK_WORD_LOCATION, HUB_WRITE_LOCATION, TLAB_TOP_LOCATION, TLAB_END_LOCATION);
+        private final SnippetInfo allocateInstance = snippet(NewObjectSnippets.class, "allocateInstance", MARK_WORD_LOCATION, HUB_WRITE_LOCATION, TLAB_TOP_LOCATION, TLAB_END_LOCATION,
+                        PROTOTYPE_MARK_WORD_LOCATION);
         private final SnippetInfo allocateInstancePIC = snippet(NewObjectSnippets.class, "allocateInstancePIC", MARK_WORD_LOCATION, HUB_WRITE_LOCATION, TLAB_TOP_LOCATION,
-                        TLAB_END_LOCATION);
+                        TLAB_END_LOCATION, PROTOTYPE_MARK_WORD_LOCATION);
         private final SnippetInfo allocateArray = snippet(NewObjectSnippets.class, "allocateArray", MARK_WORD_LOCATION, HUB_WRITE_LOCATION, TLAB_TOP_LOCATION, TLAB_END_LOCATION);
         private final SnippetInfo allocateArrayPIC = snippet(NewObjectSnippets.class, "allocateArrayPIC", MARK_WORD_LOCATION, HUB_WRITE_LOCATION, TLAB_TOP_LOCATION, TLAB_END_LOCATION);
         private final SnippetInfo allocatePrimitiveArrayPIC = snippet(NewObjectSnippets.class, "allocatePrimitiveArrayPIC", MARK_WORD_LOCATION, HUB_WRITE_LOCATION, TLAB_TOP_LOCATION,
@@ -724,7 +725,7 @@
         private final SnippetInfo allocateArrayDynamic = snippet(NewObjectSnippets.class, "allocateArrayDynamic", MARK_WORD_LOCATION, HUB_WRITE_LOCATION, TLAB_TOP_LOCATION,
                         TLAB_END_LOCATION);
         private final SnippetInfo allocateInstanceDynamic = snippet(NewObjectSnippets.class, "allocateInstanceDynamic", MARK_WORD_LOCATION, HUB_WRITE_LOCATION, TLAB_TOP_LOCATION,
-                        TLAB_END_LOCATION);
+                        TLAB_END_LOCATION, PROTOTYPE_MARK_WORD_LOCATION, CLASS_STATE_LOCATION);
         private final SnippetInfo newmultiarray = snippet(NewObjectSnippets.class, "newmultiarray", TLAB_TOP_LOCATION, TLAB_END_LOCATION);
         private final SnippetInfo newmultiarrayPIC = snippet(NewObjectSnippets.class, "newmultiarrayPIC", TLAB_TOP_LOCATION, TLAB_END_LOCATION);
         private final SnippetInfo verifyHeap = snippet(NewObjectSnippets.class, "verifyHeap");
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/SHA2Substitutions.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/SHA2Substitutions.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,9 +24,8 @@
 
 package org.graalvm.compiler.hotspot.replacements;
 
-import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfig.INJECTED_METAACCESS;
 import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfigBase.INJECTED_INTRINSIC_CONTEXT;
-import static org.graalvm.compiler.serviceprovider.JavaVersionUtil.Java8OrEarlier;
+import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfigBase.INJECTED_METAACCESS;
 
 import org.graalvm.compiler.api.replacements.ClassSubstitution;
 import org.graalvm.compiler.api.replacements.Fold;
@@ -37,6 +36,7 @@
 import org.graalvm.compiler.nodes.extended.RawLoadNode;
 import org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext;
 import org.graalvm.compiler.replacements.ReplacementsUtil;
+import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
 import org.graalvm.compiler.word.Word;
 import jdk.internal.vm.compiler.word.LocationIdentity;
 import jdk.internal.vm.compiler.word.WordFactory;
@@ -46,7 +46,7 @@
 @ClassSubstitution(className = "sun.security.provider.SHA2", optional = true)
 public class SHA2Substitutions {
 
-    public static final String implCompressName = Java8OrEarlier ? "implCompress" : "implCompress0";
+    public static final String implCompressName = JavaVersionUtil.JAVA_SPEC <= 8 ? "implCompress" : "implCompress0";
 
     @MethodSubstitution(isStatic = false)
     static void implCompress0(Object receiver, byte[] buf, int ofs) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/SHA5Substitutions.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/SHA5Substitutions.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,7 +26,6 @@
 
 import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfigBase.INJECTED_INTRINSIC_CONTEXT;
 import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfigBase.INJECTED_METAACCESS;
-import static org.graalvm.compiler.serviceprovider.JavaVersionUtil.Java8OrEarlier;
 
 import org.graalvm.compiler.api.replacements.ClassSubstitution;
 import org.graalvm.compiler.api.replacements.Fold;
@@ -38,6 +37,7 @@
 import org.graalvm.compiler.nodes.extended.RawLoadNode;
 import org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext;
 import org.graalvm.compiler.replacements.ReplacementsUtil;
+import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
 import org.graalvm.compiler.word.Word;
 import jdk.internal.vm.compiler.word.LocationIdentity;
 import jdk.internal.vm.compiler.word.WordFactory;
@@ -47,7 +47,7 @@
 @ClassSubstitution(className = "sun.security.provider.SHA5", optional = true)
 public class SHA5Substitutions {
 
-    public static final String implCompressName = Java8OrEarlier ? "implCompress" : "implCompress0";
+    public static final String implCompressName = JavaVersionUtil.JAVA_SPEC <= 8 ? "implCompress" : "implCompress0";
 
     @MethodSubstitution(isStatic = false)
     static void implCompress0(Object receiver, byte[] buf, int ofs) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/SHASubstitutions.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/SHASubstitutions.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,7 +26,6 @@
 
 import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfigBase.INJECTED_INTRINSIC_CONTEXT;
 import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfigBase.INJECTED_METAACCESS;
-import static org.graalvm.compiler.serviceprovider.JavaVersionUtil.Java8OrEarlier;
 
 import org.graalvm.compiler.api.replacements.ClassSubstitution;
 import org.graalvm.compiler.api.replacements.Fold;
@@ -38,6 +37,7 @@
 import org.graalvm.compiler.nodes.extended.RawLoadNode;
 import org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext;
 import org.graalvm.compiler.replacements.ReplacementsUtil;
+import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
 import org.graalvm.compiler.word.Word;
 import jdk.internal.vm.compiler.word.LocationIdentity;
 import jdk.internal.vm.compiler.word.WordFactory;
@@ -47,7 +47,7 @@
 @ClassSubstitution(className = "sun.security.provider.SHA", optional = true)
 public class SHASubstitutions {
 
-    public static final String implCompressName = Java8OrEarlier ? "implCompress" : "implCompress0";
+    public static final String implCompressName = JavaVersionUtil.JAVA_SPEC <= 8 ? "implCompress" : "implCompress0";
 
     @MethodSubstitution(isStatic = false)
     static void implCompress0(Object receiver, byte[] buf, int ofs) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/WriteBarrierSnippets.java	Wed Jun 26 15:34:13 2019 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,621 +0,0 @@
-/*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package org.graalvm.compiler.hotspot.replacements;
-
-import static jdk.vm.ci.code.MemoryBarriers.STORE_LOAD;
-import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfig.INJECTED_VMCONFIG;
-import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfigBase.INJECTED_METAACCESS;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.cardTableShift;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.dirtyCardValue;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.g1CardQueueBufferOffset;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.g1CardQueueIndexOffset;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.g1SATBQueueBufferOffset;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.g1SATBQueueIndexOffset;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.g1SATBQueueMarkingOffset;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.g1YoungCardValue;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.registerAsWord;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.verifyOop;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.verifyOops;
-import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.wordSize;
-import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.FREQUENT_PROBABILITY;
-import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.LIKELY_PROBABILITY;
-import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.NOT_FREQUENT_PROBABILITY;
-import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.probability;
-import static org.graalvm.compiler.replacements.SnippetTemplate.DEFAULT_REPLACER;
-
-import org.graalvm.compiler.api.replacements.Snippet;
-import org.graalvm.compiler.api.replacements.Snippet.ConstantParameter;
-import org.graalvm.compiler.core.common.CompressEncoding;
-import org.graalvm.compiler.core.common.GraalOptions;
-import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
-import org.graalvm.compiler.debug.DebugHandlersFactory;
-import org.graalvm.compiler.graph.Node.ConstantNodeParameter;
-import org.graalvm.compiler.graph.Node.NodeIntrinsic;
-import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
-import org.graalvm.compiler.hotspot.gc.g1.G1ArrayRangePostWriteBarrier;
-import org.graalvm.compiler.hotspot.gc.g1.G1ArrayRangePreWriteBarrier;
-import org.graalvm.compiler.hotspot.gc.g1.G1PostWriteBarrier;
-import org.graalvm.compiler.hotspot.gc.g1.G1PreWriteBarrier;
-import org.graalvm.compiler.hotspot.gc.g1.G1ReferentFieldReadBarrier;
-import org.graalvm.compiler.hotspot.gc.shared.SerialArrayRangeWriteBarrier;
-import org.graalvm.compiler.hotspot.gc.shared.SerialWriteBarrier;
-import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
-import org.graalvm.compiler.hotspot.meta.HotSpotRegistersProvider;
-import org.graalvm.compiler.hotspot.nodes.GraalHotSpotVMConfigNode;
-import org.graalvm.compiler.hotspot.nodes.HotSpotCompressionNode;
-import org.graalvm.compiler.hotspot.nodes.VMErrorNode;
-import org.graalvm.compiler.nodes.NamedLocationIdentity;
-import org.graalvm.compiler.nodes.NodeView;
-import org.graalvm.compiler.nodes.PiNode;
-import org.graalvm.compiler.nodes.SnippetAnchorNode;
-import org.graalvm.compiler.nodes.StructuredGraph;
-import org.graalvm.compiler.nodes.ValueNode;
-import org.graalvm.compiler.nodes.extended.FixedValueAnchorNode;
-import org.graalvm.compiler.nodes.extended.ForeignCallNode;
-import org.graalvm.compiler.nodes.extended.MembarNode;
-import org.graalvm.compiler.nodes.extended.NullCheckNode;
-import org.graalvm.compiler.nodes.memory.HeapAccess.BarrierType;
-import org.graalvm.compiler.nodes.memory.address.AddressNode;
-import org.graalvm.compiler.nodes.memory.address.AddressNode.Address;
-import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
-import org.graalvm.compiler.nodes.spi.LoweringTool;
-import org.graalvm.compiler.nodes.type.NarrowOopStamp;
-import org.graalvm.compiler.options.OptionValues;
-import org.graalvm.compiler.replacements.Log;
-import org.graalvm.compiler.replacements.ReplacementsUtil;
-import org.graalvm.compiler.replacements.SnippetCounter;
-import org.graalvm.compiler.replacements.SnippetCounter.Group;
-import org.graalvm.compiler.replacements.SnippetTemplate.AbstractTemplates;
-import org.graalvm.compiler.replacements.SnippetTemplate.Arguments;
-import org.graalvm.compiler.replacements.SnippetTemplate.SnippetInfo;
-import org.graalvm.compiler.replacements.Snippets;
-import org.graalvm.compiler.replacements.nodes.AssertionNode;
-import org.graalvm.compiler.replacements.nodes.DirectStoreNode;
-import org.graalvm.compiler.word.Word;
-import jdk.internal.vm.compiler.word.LocationIdentity;
-import jdk.internal.vm.compiler.word.Pointer;
-import jdk.internal.vm.compiler.word.UnsignedWord;
-import jdk.internal.vm.compiler.word.WordFactory;
-
-import jdk.vm.ci.code.Register;
-import jdk.vm.ci.code.TargetDescription;
-import jdk.vm.ci.meta.JavaKind;
-
-public class WriteBarrierSnippets implements Snippets {
-
-    static class Counters {
-        Counters(SnippetCounter.Group.Factory factory) {
-            Group countersWriteBarriers = factory.createSnippetCounterGroup("WriteBarriers");
-            serialWriteBarrierCounter = new SnippetCounter(countersWriteBarriers, "serialWriteBarrier", "Number of Serial Write Barriers");
-            g1AttemptedPreWriteBarrierCounter = new SnippetCounter(countersWriteBarriers, "g1AttemptedPreWriteBarrier", "Number of attempted G1 Pre Write Barriers");
-            g1EffectivePreWriteBarrierCounter = new SnippetCounter(countersWriteBarriers, "g1EffectivePreWriteBarrier", "Number of effective G1 Pre Write Barriers");
-            g1ExecutedPreWriteBarrierCounter = new SnippetCounter(countersWriteBarriers, "g1ExecutedPreWriteBarrier", "Number of executed G1 Pre Write Barriers");
-            g1AttemptedPostWriteBarrierCounter = new SnippetCounter(countersWriteBarriers, "g1AttemptedPostWriteBarrier", "Number of attempted G1 Post Write Barriers");
-            g1EffectiveAfterXORPostWriteBarrierCounter = new SnippetCounter(countersWriteBarriers, "g1EffectiveAfterXORPostWriteBarrier",
-                            "Number of effective G1 Post Write Barriers (after passing the XOR test)");
-            g1EffectiveAfterNullPostWriteBarrierCounter = new SnippetCounter(countersWriteBarriers, "g1EffectiveAfterNullPostWriteBarrier",
-                            "Number of effective G1 Post Write Barriers (after passing the NULL test)");
-            g1ExecutedPostWriteBarrierCounter = new SnippetCounter(countersWriteBarriers, "g1ExecutedPostWriteBarrier", "Number of executed G1 Post Write Barriers");
-
-        }
-
-        final SnippetCounter serialWriteBarrierCounter;
-        final SnippetCounter g1AttemptedPreWriteBarrierCounter;
-        final SnippetCounter g1EffectivePreWriteBarrierCounter;
-        final SnippetCounter g1ExecutedPreWriteBarrierCounter;
-        final SnippetCounter g1AttemptedPostWriteBarrierCounter;
-        final SnippetCounter g1EffectiveAfterXORPostWriteBarrierCounter;
-        final SnippetCounter g1EffectiveAfterNullPostWriteBarrierCounter;
-        final SnippetCounter g1ExecutedPostWriteBarrierCounter;
-    }
-
-    public static final LocationIdentity GC_CARD_LOCATION = NamedLocationIdentity.mutable("GC-Card");
-    public static final LocationIdentity GC_LOG_LOCATION = NamedLocationIdentity.mutable("GC-Log");
-    public static final LocationIdentity GC_INDEX_LOCATION = NamedLocationIdentity.mutable("GC-Index");
-
-    private static void serialWriteBarrier(Pointer ptr, Counters counters) {
-        counters.serialWriteBarrierCounter.inc();
-        final long startAddress = GraalHotSpotVMConfigNode.cardTableAddress();
-        Word base = (Word) ptr.unsignedShiftRight(cardTableShift(INJECTED_VMCONFIG));
-        if (((int) startAddress) == startAddress && GraalHotSpotVMConfigNode.isCardTableAddressConstant()) {
-            base.writeByte((int) startAddress, (byte) 0, GC_CARD_LOCATION);
-        } else {
-            base.writeByte(WordFactory.unsigned(startAddress), (byte) 0, GC_CARD_LOCATION);
-        }
-    }
-
-    @Snippet
-    public static void serialImpreciseWriteBarrier(Object object, @ConstantParameter boolean verifyBarrier, @ConstantParameter Counters counters) {
-        if (verifyBarrier) {
-            verifyNotArray(object);
-        }
-        serialWriteBarrier(Word.objectToTrackedPointer(object), counters);
-    }
-
-    @Snippet
-    public static void serialPreciseWriteBarrier(Address address, @ConstantParameter Counters counters) {
-        serialWriteBarrier(Word.fromAddress(address), counters);
-    }
-
-    @Snippet
-    public static void serialArrayRangeWriteBarrier(Address address, int length, @ConstantParameter int elementStride) {
-        if (length == 0) {
-            return;
-        }
-        int cardShift = cardTableShift(INJECTED_VMCONFIG);
-        final long cardStart = GraalHotSpotVMConfigNode.cardTableAddress();
-        long start = getPointerToFirstArrayElement(address, length, elementStride) >>> cardShift;
-        long end = getPointerToLastArrayElement(address, length, elementStride) >>> cardShift;
-        long count = end - start + 1;
-        while (count-- > 0) {
-            DirectStoreNode.storeBoolean((start + cardStart) + count, false, JavaKind.Boolean);
-        }
-    }
-
-    @Snippet
-    public static void g1PreWriteBarrier(Address address, Object object, Object expectedObject, @ConstantParameter boolean doLoad, @ConstantParameter boolean nullCheck,
-                    @ConstantParameter Register threadRegister, @ConstantParameter boolean trace, @ConstantParameter Counters counters) {
-        if (nullCheck) {
-            NullCheckNode.nullCheck(address);
-        }
-        Word thread = registerAsWord(threadRegister);
-        verifyOop(object);
-        Object fixedExpectedObject = FixedValueAnchorNode.getObject(expectedObject);
-        Word field = Word.fromAddress(address);
-        Pointer previousOop = Word.objectToTrackedPointer(fixedExpectedObject);
-        byte markingValue = thread.readByte(g1SATBQueueMarkingOffset(INJECTED_VMCONFIG));
-        int gcCycle = 0;
-        if (trace) {
-            Pointer gcTotalCollectionsAddress = WordFactory.pointer(HotSpotReplacementsUtil.gcTotalCollectionsAddress(INJECTED_VMCONFIG));
-            gcCycle = (int) gcTotalCollectionsAddress.readLong(0);
-            log(trace, "[%d] G1-Pre Thread %p Object %p\n", gcCycle, thread.rawValue(), Word.objectToTrackedPointer(object).rawValue());
-            log(trace, "[%d] G1-Pre Thread %p Expected Object %p\n", gcCycle, thread.rawValue(), Word.objectToTrackedPointer(fixedExpectedObject).rawValue());
-            log(trace, "[%d] G1-Pre Thread %p Field %p\n", gcCycle, thread.rawValue(), field.rawValue());
-            log(trace, "[%d] G1-Pre Thread %p Marking %d\n", gcCycle, thread.rawValue(), markingValue);
-            log(trace, "[%d] G1-Pre Thread %p DoLoad %d\n", gcCycle, thread.rawValue(), doLoad ? 1L : 0L);
-        }
-        counters.g1AttemptedPreWriteBarrierCounter.inc();
-        // If the concurrent marker is enabled, the barrier is issued.
-        if (probability(NOT_FREQUENT_PROBABILITY, markingValue != (byte) 0)) {
-            // If the previous value has to be loaded (before the write), the load is issued.
-            // The load is always issued except the cases of CAS and referent field.
-            if (probability(LIKELY_PROBABILITY, doLoad)) {
-                previousOop = Word.objectToTrackedPointer(field.readObject(0, BarrierType.NONE));
-                if (trace) {
-                    log(trace, "[%d] G1-Pre Thread %p Previous Object %p\n ", gcCycle, thread.rawValue(), previousOop.rawValue());
-                    verifyOop(previousOop.toObject());
-                }
-            }
-            counters.g1EffectivePreWriteBarrierCounter.inc();
-            // If the previous value is null the barrier should not be issued.
-            if (probability(FREQUENT_PROBABILITY, previousOop.notEqual(0))) {
-                counters.g1ExecutedPreWriteBarrierCounter.inc();
-                // If the thread-local SATB buffer is full issue a native call which will
-                // initialize a new one and add the entry.
-                Word indexAddress = thread.add(g1SATBQueueIndexOffset(INJECTED_VMCONFIG));
-                Word indexValue = indexAddress.readWord(0);
-                if (probability(FREQUENT_PROBABILITY, indexValue.notEqual(0))) {
-                    Word bufferAddress = thread.readWord(g1SATBQueueBufferOffset(INJECTED_VMCONFIG));
-                    Word nextIndex = indexValue.subtract(wordSize());
-                    Word logAddress = bufferAddress.add(nextIndex);
-                    // Log the object to be marked as well as update the SATB's buffer next index.
-                    logAddress.writeWord(0, previousOop, GC_LOG_LOCATION);
-                    indexAddress.writeWord(0, nextIndex, GC_INDEX_LOCATION);
-                } else {
-                    g1PreBarrierStub(G1WBPRECALL, previousOop.toObject());
-                }
-            }
-        }
-    }
-
-    @Snippet
-    public static void g1PostWriteBarrier(Address address, Object object, Object value, @ConstantParameter boolean usePrecise, @ConstantParameter boolean verifyBarrier,
-                    @ConstantParameter Register threadRegister, @ConstantParameter boolean trace, @ConstantParameter Counters counters) {
-        Word thread = registerAsWord(threadRegister);
-        Object fixedValue = FixedValueAnchorNode.getObject(value);
-        verifyOop(object);
-        verifyOop(fixedValue);
-        validateObject(object, fixedValue);
-        Pointer oop;
-        if (usePrecise) {
-            oop = Word.fromAddress(address);
-        } else {
-            if (verifyBarrier) {
-                verifyNotArray(object);
-            }
-            oop = Word.objectToTrackedPointer(object);
-        }
-        int gcCycle = 0;
-        if (trace) {
-            Pointer gcTotalCollectionsAddress = WordFactory.pointer(HotSpotReplacementsUtil.gcTotalCollectionsAddress(INJECTED_VMCONFIG));
-            gcCycle = (int) gcTotalCollectionsAddress.readLong(0);
-            log(trace, "[%d] G1-Post Thread: %p Object: %p\n", gcCycle, thread.rawValue(), Word.objectToTrackedPointer(object).rawValue());
-            log(trace, "[%d] G1-Post Thread: %p Field: %p\n", gcCycle, thread.rawValue(), oop.rawValue());
-        }
-        Pointer writtenValue = Word.objectToTrackedPointer(fixedValue);
-        // The result of the xor reveals whether the installed pointer crosses heap regions.
-        // In case it does the write barrier has to be issued.
-        final int logOfHeapRegionGrainBytes = GraalHotSpotVMConfigNode.logOfHeapRegionGrainBytes();
-        UnsignedWord xorResult = (oop.xor(writtenValue)).unsignedShiftRight(logOfHeapRegionGrainBytes);
-
-        // Calculate the address of the card to be enqueued to the
-        // thread local card queue.
-        UnsignedWord cardBase = oop.unsignedShiftRight(cardTableShift(INJECTED_VMCONFIG));
-        final long startAddress = GraalHotSpotVMConfigNode.cardTableAddress();
-        int displacement = 0;
-        if (((int) startAddress) == startAddress && GraalHotSpotVMConfigNode.isCardTableAddressConstant()) {
-            displacement = (int) startAddress;
-        } else {
-            cardBase = cardBase.add(WordFactory.unsigned(startAddress));
-        }
-        Word cardAddress = (Word) cardBase.add(displacement);
-
-        counters.g1AttemptedPostWriteBarrierCounter.inc();
-        if (probability(FREQUENT_PROBABILITY, xorResult.notEqual(0))) {
-            counters.g1EffectiveAfterXORPostWriteBarrierCounter.inc();
-
-            // If the written value is not null continue with the barrier addition.
-            if (probability(FREQUENT_PROBABILITY, writtenValue.notEqual(0))) {
-                byte cardByte = cardAddress.readByte(0, GC_CARD_LOCATION);
-                counters.g1EffectiveAfterNullPostWriteBarrierCounter.inc();
-
-                // If the card is already dirty, (hence already enqueued) skip the insertion.
-                if (probability(NOT_FREQUENT_PROBABILITY, cardByte != g1YoungCardValue(INJECTED_VMCONFIG))) {
-                    MembarNode.memoryBarrier(STORE_LOAD, GC_CARD_LOCATION);
-                    byte cardByteReload = cardAddress.readByte(0, GC_CARD_LOCATION);
-                    if (probability(NOT_FREQUENT_PROBABILITY, cardByteReload != dirtyCardValue(INJECTED_VMCONFIG))) {
-                        log(trace, "[%d] G1-Post Thread: %p Card: %p \n", gcCycle, thread.rawValue(), WordFactory.unsigned((int) cardByte).rawValue());
-                        cardAddress.writeByte(0, (byte) 0, GC_CARD_LOCATION);
-                        counters.g1ExecutedPostWriteBarrierCounter.inc();
-
-                        // If the thread local card queue is full, issue a native call which will
-                        // initialize a new one and add the card entry.
-                        Word indexAddress = thread.add(g1CardQueueIndexOffset(INJECTED_VMCONFIG));
-                        Word indexValue = thread.readWord(g1CardQueueIndexOffset(INJECTED_VMCONFIG));
-                        if (probability(FREQUENT_PROBABILITY, indexValue.notEqual(0))) {
-                            Word bufferAddress = thread.readWord(g1CardQueueBufferOffset(INJECTED_VMCONFIG));
-                            Word nextIndex = indexValue.subtract(wordSize());
-                            Word logAddress = bufferAddress.add(nextIndex);
-                            // Log the object to be scanned as well as update
-                            // the card queue's next index.
-                            logAddress.writeWord(0, cardAddress, GC_LOG_LOCATION);
-                            indexAddress.writeWord(0, nextIndex, GC_INDEX_LOCATION);
-                        } else {
-                            g1PostBarrierStub(G1WBPOSTCALL, cardAddress);
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    private static void verifyNotArray(Object object) {
-        if (object != null) {
-            // Manually build the null check and cast because we're in snippet that's lowered late.
-            AssertionNode.assertion(false, !PiNode.piCastNonNull(object, SnippetAnchorNode.anchor()).getClass().isArray(), "imprecise card mark used with array");
-        }
-    }
-
-    @Snippet
-    public static void g1ArrayRangePreWriteBarrier(Address address, int length, @ConstantParameter int elementStride, @ConstantParameter Register threadRegister) {
-        Word thread = registerAsWord(threadRegister);
-        byte markingValue = thread.readByte(g1SATBQueueMarkingOffset(INJECTED_VMCONFIG));
-        // If the concurrent marker is not enabled or the vector length is zero, return.
-        if (markingValue == (byte) 0 || length == 0) {
-            return;
-        }
-        Word bufferAddress = thread.readWord(g1SATBQueueBufferOffset(INJECTED_VMCONFIG));
-        Word indexAddress = thread.add(g1SATBQueueIndexOffset(INJECTED_VMCONFIG));
-        long indexValue = indexAddress.readWord(0).rawValue();
-        final int scale = ReplacementsUtil.arrayIndexScale(INJECTED_METAACCESS, JavaKind.Object);
-        long start = getPointerToFirstArrayElement(address, length, elementStride);
-
-        for (int i = 0; i < length; i++) {
-            Word arrElemPtr = WordFactory.pointer(start + i * scale);
-            Pointer oop = Word.objectToTrackedPointer(arrElemPtr.readObject(0, BarrierType.NONE));
-            verifyOop(oop.toObject());
-            if (oop.notEqual(0)) {
-                if (indexValue != 0) {
-                    indexValue = indexValue - wordSize();
-                    Word logAddress = bufferAddress.add(WordFactory.unsigned(indexValue));
-                    // Log the object to be marked as well as update the SATB's buffer next index.
-                    logAddress.writeWord(0, oop, GC_LOG_LOCATION);
-                    indexAddress.writeWord(0, WordFactory.unsigned(indexValue), GC_INDEX_LOCATION);
-                } else {
-                    g1PreBarrierStub(G1WBPRECALL, oop.toObject());
-                }
-            }
-        }
-    }
-
-    @Snippet
-    public static void g1ArrayRangePostWriteBarrier(Address address, int length, @ConstantParameter int elementStride, @ConstantParameter Register threadRegister) {
-        if (length == 0) {
-            return;
-        }
-        Word thread = registerAsWord(threadRegister);
-        Word bufferAddress = thread.readWord(g1CardQueueBufferOffset(INJECTED_VMCONFIG));
-        Word indexAddress = thread.add(g1CardQueueIndexOffset(INJECTED_VMCONFIG));
-        long indexValue = thread.readWord(g1CardQueueIndexOffset(INJECTED_VMCONFIG)).rawValue();
-
-        int cardShift = cardTableShift(INJECTED_VMCONFIG);
-        final long cardStart = GraalHotSpotVMConfigNode.cardTableAddress();
-        long start = getPointerToFirstArrayElement(address, length, elementStride) >>> cardShift;
-        long end = getPointerToLastArrayElement(address, length, elementStride) >>> cardShift;
-        long count = end - start + 1;
-
-        while (count-- > 0) {
-            Word cardAddress = WordFactory.unsigned((start + cardStart) + count);
-            byte cardByte = cardAddress.readByte(0, GC_CARD_LOCATION);
-            // If the card is already dirty, (hence already enqueued) skip the insertion.
-            if (probability(NOT_FREQUENT_PROBABILITY, cardByte != g1YoungCardValue(INJECTED_VMCONFIG))) {
-                MembarNode.memoryBarrier(STORE_LOAD, GC_CARD_LOCATION);
-                byte cardByteReload = cardAddress.readByte(0, GC_CARD_LOCATION);
-                if (probability(NOT_FREQUENT_PROBABILITY, cardByteReload != dirtyCardValue(INJECTED_VMCONFIG))) {
-                    cardAddress.writeByte(0, (byte) 0, GC_CARD_LOCATION);
-                    // If the thread local card queue is full, issue a native call which will
-                    // initialize a new one and add the card entry.
-                    if (indexValue != 0) {
-                        indexValue = indexValue - wordSize();
-                        Word logAddress = bufferAddress.add(WordFactory.unsigned(indexValue));
-                        // Log the object to be scanned as well as update
-                        // the card queue's next index.
-                        logAddress.writeWord(0, cardAddress, GC_LOG_LOCATION);
-                        indexAddress.writeWord(0, WordFactory.unsigned(indexValue), GC_INDEX_LOCATION);
-                    } else {
-                        g1PostBarrierStub(G1WBPOSTCALL, cardAddress);
-                    }
-                }
-            }
-        }
-    }
-
-    private static long getPointerToFirstArrayElement(Address address, int length, int elementStride) {
-        long result = Word.fromAddress(address).rawValue();
-        if (elementStride < 0) {
-            // the address points to the place after the last array element
-            result = result + elementStride * length;
-        }
-        return result;
-    }
-
-    private static long getPointerToLastArrayElement(Address address, int length, int elementStride) {
-        long result = Word.fromAddress(address).rawValue();
-        if (elementStride < 0) {
-            // the address points to the place after the last array element
-            result = result + elementStride;
-        } else {
-            result = result + (length - 1) * elementStride;
-        }
-        return result;
-    }
-
-    public static final ForeignCallDescriptor G1WBPRECALL = new ForeignCallDescriptor("write_barrier_pre", void.class, Object.class);
-
-    @NodeIntrinsic(ForeignCallNode.class)
-    private static native void g1PreBarrierStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Object object);
-
-    public static final ForeignCallDescriptor G1WBPOSTCALL = new ForeignCallDescriptor("write_barrier_post", void.class, Word.class);
-
-    @NodeIntrinsic(ForeignCallNode.class)
-    public static native void g1PostBarrierStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Word card);
-
-    public static class Templates extends AbstractTemplates {
-
-        private final SnippetInfo serialImpreciseWriteBarrier = snippet(WriteBarrierSnippets.class, "serialImpreciseWriteBarrier", GC_CARD_LOCATION);
-        private final SnippetInfo serialPreciseWriteBarrier = snippet(WriteBarrierSnippets.class, "serialPreciseWriteBarrier", GC_CARD_LOCATION);
-        private final SnippetInfo serialArrayRangeWriteBarrier = snippet(WriteBarrierSnippets.class, "serialArrayRangeWriteBarrier");
-        private final SnippetInfo g1PreWriteBarrier = snippet(WriteBarrierSnippets.class, "g1PreWriteBarrier", GC_INDEX_LOCATION, GC_LOG_LOCATION);
-        private final SnippetInfo g1ReferentReadBarrier = g1PreWriteBarrier;
-        private final SnippetInfo g1PostWriteBarrier = snippet(WriteBarrierSnippets.class, "g1PostWriteBarrier", GC_CARD_LOCATION, GC_INDEX_LOCATION, GC_LOG_LOCATION);
-        private final SnippetInfo g1ArrayRangePreWriteBarrier = snippet(WriteBarrierSnippets.class, "g1ArrayRangePreWriteBarrier", GC_INDEX_LOCATION, GC_LOG_LOCATION);
-        private final SnippetInfo g1ArrayRangePostWriteBarrier = snippet(WriteBarrierSnippets.class, "g1ArrayRangePostWriteBarrier", GC_CARD_LOCATION, GC_INDEX_LOCATION, GC_LOG_LOCATION);
-
-        private final CompressEncoding oopEncoding;
-        private final Counters counters;
-        private final boolean verifyBarrier;
-        private final long gcTotalCollectionsAddress;
-
-        public Templates(OptionValues options, Iterable<DebugHandlersFactory> factories, Group.Factory factory, HotSpotProviders providers, TargetDescription target,
-                        GraalHotSpotVMConfig config) {
-            super(options, factories, providers, providers.getSnippetReflection(), target);
-            this.oopEncoding = config.useCompressedOops ? config.getOopEncoding() : null;
-            this.verifyBarrier = ReplacementsUtil.REPLACEMENTS_ASSERTIONS_ENABLED || config.verifyBeforeGC || config.verifyAfterGC;
-            this.gcTotalCollectionsAddress = config.gcTotalCollectionsAddress();
-            this.counters = new Counters(factory);
-        }
-
-        public boolean traceBarrier(StructuredGraph graph) {
-            long startCycle = GraalOptions.GCDebugStartCycle.getValue(graph.getOptions());
-            return startCycle > 0 && ((Pointer) WordFactory.pointer(gcTotalCollectionsAddress)).readLong(0) > startCycle;
-        }
-
-        public void lower(SerialWriteBarrier writeBarrier, LoweringTool tool) {
-            Arguments args;
-            if (writeBarrier.usePrecise()) {
-                args = new Arguments(serialPreciseWriteBarrier, writeBarrier.graph().getGuardsStage(), tool.getLoweringStage());
-                args.add("address", writeBarrier.getAddress());
-            } else {
-                args = new Arguments(serialImpreciseWriteBarrier, writeBarrier.graph().getGuardsStage(), tool.getLoweringStage());
-                OffsetAddressNode address = (OffsetAddressNode) writeBarrier.getAddress();
-                args.add("object", address.getBase());
-                args.addConst("verifyBarrier", verifyBarrier);
-            }
-            args.addConst("counters", counters);
-            template(writeBarrier, args).instantiate(providers.getMetaAccess(), writeBarrier, DEFAULT_REPLACER, args);
-        }
-
-        public void lower(SerialArrayRangeWriteBarrier arrayRangeWriteBarrier, LoweringTool tool) {
-            Arguments args = new Arguments(serialArrayRangeWriteBarrier, arrayRangeWriteBarrier.graph().getGuardsStage(), tool.getLoweringStage());
-            args.add("address", arrayRangeWriteBarrier.getAddress());
-            args.add("length", arrayRangeWriteBarrier.getLength());
-            args.addConst("elementStride", arrayRangeWriteBarrier.getElementStride());
-            template(arrayRangeWriteBarrier, args).instantiate(providers.getMetaAccess(), arrayRangeWriteBarrier, DEFAULT_REPLACER, args);
-        }
-
-        public void lower(G1PreWriteBarrier writeBarrierPre, HotSpotRegistersProvider registers, LoweringTool tool) {
-            Arguments args = new Arguments(g1PreWriteBarrier, writeBarrierPre.graph().getGuardsStage(), tool.getLoweringStage());
-            AddressNode address = writeBarrierPre.getAddress();
-            args.add("address", address);
-            if (address instanceof OffsetAddressNode) {
-                args.add("object", ((OffsetAddressNode) address).getBase());
-            } else {
-                args.add("object", null);
-            }
-
-            ValueNode expected = writeBarrierPre.getExpectedObject();
-            if (expected != null && expected.stamp(NodeView.DEFAULT) instanceof NarrowOopStamp) {
-                assert oopEncoding != null;
-                expected = HotSpotCompressionNode.uncompress(expected, oopEncoding);
-            }
-            args.add("expectedObject", expected);
-
-            args.addConst("doLoad", writeBarrierPre.doLoad());
-            args.addConst("nullCheck", writeBarrierPre.getNullCheck());
-            args.addConst("threadRegister", registers.getThreadRegister());
-            args.addConst("trace", traceBarrier(writeBarrierPre.graph()));
-            args.addConst("counters", counters);
-            template(writeBarrierPre, args).instantiate(providers.getMetaAccess(), writeBarrierPre, DEFAULT_REPLACER, args);
-        }
-
-        public void lower(G1ReferentFieldReadBarrier readBarrier, HotSpotRegistersProvider registers, LoweringTool tool) {
-            Arguments args = new Arguments(g1ReferentReadBarrier, readBarrier.graph().getGuardsStage(), tool.getLoweringStage());
-            AddressNode address = readBarrier.getAddress();
-            args.add("address", address);
-            if (address instanceof OffsetAddressNode) {
-                args.add("object", ((OffsetAddressNode) address).getBase());
-            } else {
-                args.add("object", null);
-            }
-
-            ValueNode expected = readBarrier.getExpectedObject();
-            if (expected != null && expected.stamp(NodeView.DEFAULT) instanceof NarrowOopStamp) {
-                assert oopEncoding != null;
-                expected = HotSpotCompressionNode.uncompress(expected, oopEncoding);
-            }
-
-            args.add("expectedObject", expected);
-            args.addConst("doLoad", readBarrier.doLoad());
-            args.addConst("nullCheck", false);
-            args.addConst("threadRegister", registers.getThreadRegister());
-            args.addConst("trace", traceBarrier(readBarrier.graph()));
-            args.addConst("counters", counters);
-            template(readBarrier, args).instantiate(providers.getMetaAccess(), readBarrier, DEFAULT_REPLACER, args);
-        }
-
-        public void lower(G1PostWriteBarrier writeBarrierPost, HotSpotRegistersProvider registers, LoweringTool tool) {
-            StructuredGraph graph = writeBarrierPost.graph();
-            if (writeBarrierPost.alwaysNull()) {
-                graph.removeFixed(writeBarrierPost);
-                return;
-            }
-            Arguments args = new Arguments(g1PostWriteBarrier, graph.getGuardsStage(), tool.getLoweringStage());
-            AddressNode address = writeBarrierPost.getAddress();
-            args.add("address", address);
-            if (address instanceof OffsetAddressNode) {
-                args.add("object", ((OffsetAddressNode) address).getBase());
-            } else {
-                assert writeBarrierPost.usePrecise() : "found imprecise barrier that's not an object access " + writeBarrierPost;
-                args.add("object", null);
-            }
-
-            ValueNode value = writeBarrierPost.getValue();
-            if (value.stamp(NodeView.DEFAULT) instanceof NarrowOopStamp) {
-                assert oopEncoding != null;
-                value = HotSpotCompressionNode.uncompress(value, oopEncoding);
-            }
-            args.add("value", value);
-
-            args.addConst("usePrecise", writeBarrierPost.usePrecise());
-            args.addConst("verifyBarrier", verifyBarrier);
-            args.addConst("threadRegister", registers.getThreadRegister());
-            args.addConst("trace", traceBarrier(writeBarrierPost.graph()));
-            args.addConst("counters", counters);
-            template(writeBarrierPost, args).instantiate(providers.getMetaAccess(), writeBarrierPost, DEFAULT_REPLACER, args);
-        }
-
-        public void lower(G1ArrayRangePreWriteBarrier arrayRangeWriteBarrier, HotSpotRegistersProvider registers, LoweringTool tool) {
-            Arguments args = new Arguments(g1ArrayRangePreWriteBarrier, arrayRangeWriteBarrier.graph().getGuardsStage(), tool.getLoweringStage());
-            args.add("address", arrayRangeWriteBarrier.getAddress());
-            args.add("length", arrayRangeWriteBarrier.getLength());
-            args.addConst("elementStride", arrayRangeWriteBarrier.getElementStride());
-            args.addConst("threadRegister", registers.getThreadRegister());
-            template(arrayRangeWriteBarrier, args).instantiate(providers.getMetaAccess(), arrayRangeWriteBarrier, DEFAULT_REPLACER, args);
-        }
-
-        public void lower(G1ArrayRangePostWriteBarrier arrayRangeWriteBarrier, HotSpotRegistersProvider registers, LoweringTool tool) {
-            Arguments args = new Arguments(g1ArrayRangePostWriteBarrier, arrayRangeWriteBarrier.graph().getGuardsStage(), tool.getLoweringStage());
-            args.add("address", arrayRangeWriteBarrier.getAddress());
-            args.add("length", arrayRangeWriteBarrier.getLength());
-            args.addConst("elementStride", arrayRangeWriteBarrier.getElementStride());
-            args.addConst("threadRegister", registers.getThreadRegister());
-            template(arrayRangeWriteBarrier, args).instantiate(providers.getMetaAccess(), arrayRangeWriteBarrier, DEFAULT_REPLACER, args);
-        }
-    }
-
-    /**
-     * Log method of debugging purposes.
-     */
-    public static void log(boolean enabled, String format, long value) {
-        if (enabled) {
-            Log.printf(format, value);
-        }
-    }
-
-    public static void log(boolean enabled, String format, long value1, long value2) {
-        if (enabled) {
-            Log.printf(format, value1, value2);
-        }
-    }
-
-    public static void log(boolean enabled, String format, long value1, long value2, long value3) {
-        if (enabled) {
-            Log.printf(format, value1, value2, value3);
-        }
-    }
-
-    /**
-     * Validation helper method which performs sanity checks on write operations. The addresses of
-     * both the object and the value being written are checked in order to determine if they reside
-     * in a valid heap region. If an object is stale, an invalid access is performed in order to
-     * prematurely crash the VM and debug the stack trace of the faulty method.
-     */
-    public static void validateObject(Object parent, Object child) {
-        if (verifyOops(INJECTED_VMCONFIG) && child != null) {
-            Word parentWord = Word.objectToTrackedPointer(parent);
-            Word childWord = Word.objectToTrackedPointer(child);
-            if (!validateOop(VALIDATE_OBJECT, parentWord, childWord)) {
-                log(true, "Verification ERROR, Parent: %p Child: %p\n", parentWord.rawValue(), childWord.rawValue());
-                VMErrorNode.vmError("Verification ERROR, Parent: %p\n", parentWord.rawValue());
-            }
-        }
-    }
-
-    public static final ForeignCallDescriptor VALIDATE_OBJECT = new ForeignCallDescriptor("validate_object", boolean.class, Word.class, Word.class);
-
-    @NodeIntrinsic(ForeignCallNode.class)
-    private static native boolean validateOop(@ConstantNodeParameter ForeignCallDescriptor descriptor, Word parent, Word object);
-
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/OutOfBoundsExceptionStub.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/OutOfBoundsExceptionStub.java	Mon Jul 01 14:57:02 2019 -0700
@@ -48,7 +48,7 @@
     }
 
     // JDK-8201593: Print array length in ArrayIndexOutOfBoundsException.
-    private static final boolean PRINT_LENGTH_IN_EXCEPTION = JavaVersionUtil.JAVA_SPECIFICATION_VERSION >= 11;
+    private static final boolean PRINT_LENGTH_IN_EXCEPTION = JavaVersionUtil.JAVA_SPEC >= 11;
     private static final int MAX_INT_STRING_SIZE = Integer.toString(Integer.MIN_VALUE).length();
     private static final String STR_INDEX = "Index ";
     private static final String STR_OUTOFBOUNDSFORLENGTH = " out of bounds for length ";
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/SnippetStub.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/SnippetStub.java	Mon Jul 01 14:57:02 2019 -0700
@@ -42,7 +42,6 @@
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
 import org.graalvm.compiler.phases.common.LoweringPhase;
 import org.graalvm.compiler.phases.common.RemoveValueProxyPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.graalvm.compiler.replacements.SnippetTemplate;
 import org.graalvm.compiler.replacements.Snippets;
 
@@ -104,9 +103,8 @@
             new RemoveValueProxyPhase().apply(graph);
             graph.setGuardsStage(GuardsStage.FLOATING_GUARDS);
             CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
-            PhaseContext context = new PhaseContext(providers);
-            canonicalizer.apply(graph, context);
-            new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
+            canonicalizer.apply(graph, providers);
+            new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, providers);
         } catch (Throwable e) {
             throw debug.handle(e);
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/StubUtil.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/stubs/StubUtil.java	Mon Jul 01 14:57:02 2019 -0700
@@ -39,7 +39,7 @@
 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
 import org.graalvm.compiler.hotspot.nodes.StubForeignCallNode;
 import org.graalvm.compiler.hotspot.nodes.VMErrorNode;
-import org.graalvm.compiler.replacements.Log;
+import org.graalvm.compiler.hotspot.replacements.Log;
 import org.graalvm.compiler.word.Word;
 import jdk.internal.vm.compiler.word.WordFactory;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java	Mon Jul 01 14:57:02 2019 -0700
@@ -35,7 +35,6 @@
 import static jdk.vm.ci.meta.DeoptimizationReason.JavaSubroutineMismatch;
 import static jdk.vm.ci.meta.DeoptimizationReason.NullCheckException;
 import static jdk.vm.ci.meta.DeoptimizationReason.RuntimeConstraint;
-import static jdk.vm.ci.meta.DeoptimizationReason.TypeCheckedInliningViolated;
 import static jdk.vm.ci.meta.DeoptimizationReason.UnreachedCode;
 import static jdk.vm.ci.meta.DeoptimizationReason.Unresolved;
 import static jdk.vm.ci.runtime.JVMCICompiler.INVOCATION_ENTRY_BCI;
@@ -256,8 +255,6 @@
 import static org.graalvm.compiler.java.BytecodeParserOptions.TraceBytecodeParserLevel;
 import static org.graalvm.compiler.java.BytecodeParserOptions.TraceInlineDuringParsing;
 import static org.graalvm.compiler.java.BytecodeParserOptions.TraceParserPlugins;
-import static org.graalvm.compiler.java.BytecodeParserOptions.UseGuardedIntrinsics;
-import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.LIKELY_PROBABILITY;
 import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.LUDICROUSLY_FAST_PATH_PROBABILITY;
 import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.LUDICROUSLY_SLOW_PATH_PROBABILITY;
 import static org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext.CompilationContext.INLINE_DURING_PARSING;
@@ -288,6 +285,7 @@
 import org.graalvm.compiler.bytecode.ResolvedJavaMethodBytecodeProvider;
 import org.graalvm.compiler.core.common.GraalOptions;
 import org.graalvm.compiler.core.common.PermanentBailoutException;
+import org.graalvm.compiler.core.common.RetryableBailoutException;
 import org.graalvm.compiler.core.common.calc.CanonicalCondition;
 import org.graalvm.compiler.core.common.calc.Condition;
 import org.graalvm.compiler.core.common.calc.Condition.CanonicalizedCondition;
@@ -355,6 +353,7 @@
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.UnwindNode;
 import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.ValuePhiNode;
 import org.graalvm.compiler.nodes.calc.AddNode;
 import org.graalvm.compiler.nodes.calc.AndNode;
 import org.graalvm.compiler.nodes.calc.CompareNode;
@@ -390,7 +389,6 @@
 import org.graalvm.compiler.nodes.extended.IntegerSwitchNode;
 import org.graalvm.compiler.nodes.extended.LoadArrayComponentHubNode;
 import org.graalvm.compiler.nodes.extended.LoadHubNode;
-import org.graalvm.compiler.nodes.extended.LoadMethodNode;
 import org.graalvm.compiler.nodes.extended.MembarNode;
 import org.graalvm.compiler.nodes.extended.StateSplitProxyNode;
 import org.graalvm.compiler.nodes.extended.ValueAnchorNode;
@@ -449,7 +447,6 @@
 import jdk.vm.ci.meta.JavaMethod;
 import jdk.vm.ci.meta.JavaType;
 import jdk.vm.ci.meta.JavaTypeProfile;
-import jdk.vm.ci.meta.JavaTypeProfile.ProfiledType;
 import jdk.vm.ci.meta.LineNumberTable;
 import jdk.vm.ci.meta.MetaAccessProvider;
 import jdk.vm.ci.meta.ProfilingInfo;
@@ -627,7 +624,8 @@
     }
 
     static class IntrinsicScope extends InliningScope {
-        boolean sawInvalidFrameState;
+        StateSplit returnStateSplit;
+        ArrayList<StateSplit> invalidStateUsers;
 
         IntrinsicScope(BytecodeParser parser) {
             super(parser);
@@ -650,30 +648,64 @@
                 isRootCompilation = false;
             }
             processPlaceholderFrameStates(isRootCompilation);
-            if (sawInvalidFrameState) {
+            if (invalidStateUsers != null) {
                 JavaKind returnKind = parser.getInvokeReturnType().getJavaKind();
-                FrameStateBuilder frameStateBuilder = parser.frameState;
-                ValueNode returnValue = frameStateBuilder.pop(returnKind);
-                StructuredGraph graph = parser.lastInstr.graph();
-                StateSplitProxyNode proxy = graph.add(new StateSplitProxyNode(returnValue));
-                parser.lastInstr.setNext(proxy);
-                frameStateBuilder.push(returnKind, proxy);
-                proxy.setStateAfter(parser.createFrameState(parser.stream.nextBCI(), proxy));
-                parser.lastInstr = proxy;
+                ValueNode returnValue = parser.frameState.pop(returnKind);
+                if (invalidStateUsers.size() == 1 && invalidStateUsers.get(0) == parser.lastInstr) {
+                    updateSplitFrameState(invalidStateUsers.get(0), returnKind, returnValue);
+                } else if (parser.lastInstr instanceof MergeNode) {
+                    ValuePhiNode returnValues = null;
+                    MergeNode merge = (MergeNode) parser.lastInstr;
+
+                    if (returnValue instanceof ValuePhiNode && ((ValuePhiNode) returnValue).merge() == parser.lastInstr) {
+                        returnValues = (ValuePhiNode) returnValue;
+                    }
+                    if (invalidStateUsers.remove(merge)) {
+                        updateSplitFrameState(merge, returnKind, returnValue);
+                    }
+                    for (EndNode pred : merge.cfgPredecessors()) {
+                        Node lastPred = pred.predecessor();
+                        if (invalidStateUsers.remove(lastPred)) {
+                            ValueNode predReturnValue = returnValue;
+                            if (returnValues != null) {
+                                int index = merge.phiPredecessorIndex(pred);
+                                predReturnValue = ((ValuePhiNode) returnValue).valueAt(index);
+                            }
+                            updateSplitFrameState((StateSplit) lastPred, returnKind, predReturnValue);
+                        }
+                    }
+                    if (invalidStateUsers.size() != 0) {
+                        throw new GraalError("unexpected StateSplit above merge %s", invalidStateUsers);
+                    }
+                } else {
+                    throw new GraalError("unexpected node between return StateSplit and last instruction %s", parser.lastInstr);
+                }
+                // Restore the original return value
+                parser.frameState.push(returnKind, returnValue);
+            }
+        }
+
+        private void updateSplitFrameState(StateSplit split, JavaKind returnKind, ValueNode returnValue) {
+            parser.frameState.push(returnKind, returnValue);
+            FrameState oldState = split.stateAfter();
+            split.setStateAfter(parser.createFrameState(parser.stream.nextBCI(), split));
+            parser.frameState.pop(returnKind);
+            if (oldState.hasNoUsages()) {
+                oldState.safeDelete();
             }
         }
 
         @Override
         protected void handleReturnMismatch(StructuredGraph g, FrameState fs) {
-            // If the intrinsic returns a non-void value, then any frame
-            // state with an empty stack is invalid as it cannot
-            // be used to deoptimize to just after the call returns.
-            // These invalid frame states are expected to be removed
-            // by later compilation stages.
-            FrameState newFrameState = g.add(new FrameState(BytecodeFrame.INVALID_FRAMESTATE_BCI));
-            newFrameState.setNodeSourcePosition(fs.getNodeSourcePosition());
-            fs.replaceAndDelete(newFrameState);
-            sawInvalidFrameState = true;
+            if (invalidStateUsers == null) {
+                invalidStateUsers = new ArrayList<>();
+            }
+            for (Node use : fs.usages()) {
+                if (!(use instanceof StateSplit)) {
+                    throw new GraalError("Expected StateSplit for return mismatch");
+                }
+                invalidStateUsers.add((StateSplit) use);
+            }
         }
     }
 
@@ -999,6 +1031,11 @@
                 beginNode.safeDelete();
             }
         }
+        if (graph.isOSR() && getParent() == null && graph.getNodes().filter(EntryMarkerNode.class).isEmpty()) {
+            // This should generally be a transient condition because of inconsistent profile
+            // information.
+            throw new RetryableBailoutException("OSR entry point wasn't parsed");
+        }
     }
 
     /**
@@ -1734,10 +1771,7 @@
             return null;
         }
 
-        JavaType returnType = targetMethod.getSignature().getReturnType(method.getDeclaringClass());
-        if (graphBuilderConfig.eagerResolving() || parsingIntrinsic()) {
-            returnType = returnType.resolve(targetMethod.getDeclaringClass());
-        }
+        JavaType returnType = maybeEagerlyResolve(targetMethod.getSignature().getReturnType(method.getDeclaringClass()), targetMethod.getDeclaringClass());
         if (invokeKind.hasReceiver()) {
             args[0] = maybeEmitExplicitNullCheck(args[0]);
         }
@@ -1763,8 +1797,8 @@
                 return null;
             }
 
-            if (!invokeKind.isIndirect() || (UseGuardedIntrinsics.getValue(options) && !GeneratePIC.getValue(options))) {
-                if (tryInvocationPlugin(invokeKind, args, targetMethod, resultType, returnType)) {
+            if (!invokeKind.isIndirect()) {
+                if (tryInvocationPlugin(invokeKind, args, targetMethod, resultType)) {
                     if (TraceParserPlugins.getValue(options)) {
                         traceWithContext("used invocation plugin for %s", targetMethod.format("%h.%n(%p)"));
                     }
@@ -2040,184 +2074,8 @@
         }
     }
 
-    protected static class IntrinsicGuard {
-        final FixedWithNextNode lastInstr;
-        final Mark mark;
-        final AbstractBeginNode nonIntrinsicBranch;
-        final ValueNode receiver;
-        final JavaTypeProfile profile;
-
-        public IntrinsicGuard(FixedWithNextNode lastInstr, ValueNode receiver, Mark mark, AbstractBeginNode nonIntrinsicBranch, JavaTypeProfile profile) {
-            this.lastInstr = lastInstr;
-            this.receiver = receiver;
-            this.mark = mark;
-            this.nonIntrinsicBranch = nonIntrinsicBranch;
-            this.profile = profile;
-        }
-    }
-
-    /**
-     * Weaves a test of the receiver type to ensure the dispatch will select {@code targetMethod}
-     * and not another method that overrides it. This should only be called if there is an
-     * {@link InvocationPlugin} for {@code targetMethod} and the invocation is indirect.
-     *
-     * The control flow woven around the intrinsic is as follows:
-     *
-     * <pre>
-     *  if (LoadMethod(LoadHub(receiver)) == targetMethod) {
-     *       <intrinsic for targetMethod>
-     *  } else {
-     *       <virtual call to targetMethod>
-     *  }
-     * </pre>
-     *
-     * The {@code else} branch is woven by {@link #afterInvocationPluginExecution}.
-     *
-     * @return {@code null} if the intrinsic cannot be used otherwise an object to be used by
-     *         {@link #afterInvocationPluginExecution} to weave code for the non-intrinsic branch
-     */
-    protected IntrinsicGuard guardIntrinsic(ValueNode[] args, ResolvedJavaMethod targetMethod, InvocationPluginReceiver pluginReceiver) {
-        ValueNode intrinsicReceiver = args[0];
-        ResolvedJavaType receiverType = StampTool.typeOrNull(intrinsicReceiver);
-        if (receiverType == null) {
-            // The verifier guarantees it to be at least type declaring targetMethod
-            receiverType = targetMethod.getDeclaringClass();
-        }
-        ResolvedJavaMethod resolvedMethod = receiverType.resolveMethod(targetMethod, method.getDeclaringClass());
-        if (resolvedMethod == null || resolvedMethod.equals(targetMethod)) {
-            assert resolvedMethod == null || targetMethod.getDeclaringClass().isAssignableFrom(resolvedMethod.getDeclaringClass());
-            Mark mark = graph.getMark();
-            FixedWithNextNode currentLastInstr = lastInstr;
-            ValueNode nonNullReceiver = pluginReceiver.get();
-            Stamp methodStamp = getStampProvider().createMethodStamp();
-            LoadHubNode hub = graph.unique(new LoadHubNode(getStampProvider(), nonNullReceiver));
-            LoadMethodNode actual = append(new LoadMethodNode(methodStamp, targetMethod, receiverType, method.getDeclaringClass(), hub));
-            ConstantNode expected = graph.unique(ConstantNode.forConstant(methodStamp, targetMethod.getEncoding(), getMetaAccess()));
-            LogicNode compare = graph.addOrUniqueWithInputs(
-                            CompareNode.createCompareNode(getConstantReflection(), getMetaAccess(), options, null, CanonicalCondition.EQ, actual, expected, NodeView.DEFAULT));
-
-            JavaTypeProfile profile = null;
-            if (profilingInfo != null && this.optimisticOpts.useTypeCheckHints(getOptions())) {
-                profile = profilingInfo.getTypeProfile(bci());
-                if (profile != null) {
-                    JavaTypeProfile newProfile = adjustProfileForInvocationPlugin(profile, targetMethod);
-                    if (newProfile != profile) {
-                        if (newProfile.getTypes().length == 0) {
-                            // All profiled types select the intrinsic so
-                            // emit a fixed guard instead of an if-then-else.
-                            lastInstr = append(new FixedGuardNode(compare, TypeCheckedInliningViolated, InvalidateReprofile, false));
-                            return new IntrinsicGuard(currentLastInstr, intrinsicReceiver, mark, null, null);
-                        }
-                    } else {
-                        // No profiled types select the intrinsic so emit a virtual call
-                        return null;
-                    }
-                    profile = newProfile;
-                }
-            }
-
-            AbstractBeginNode intrinsicBranch = graph.add(new BeginNode());
-            AbstractBeginNode nonIntrinsicBranch = graph.add(new BeginNode());
-            // In the adjustment above, we filter out receiver types that select the intrinsic as
-            // virtual call target. This means the recorded types in the adjusted profile will
-            // definitely not call into the intrinsic. Note that the following branch probability is
-            // still not precise -- the previously-not-recorded receiver types in the original
-            // profile might or might not call into the intrinsic. Yet we accumulate them into the
-            // probability of the intrinsic branch, assuming that the not-recorded types will only
-            // be a small fraction.
-            append(new IfNode(compare, intrinsicBranch, nonIntrinsicBranch, profile != null ? profile.getNotRecordedProbability() : LIKELY_PROBABILITY));
-            lastInstr = intrinsicBranch;
-            return new IntrinsicGuard(currentLastInstr, intrinsicReceiver, mark, nonIntrinsicBranch, profile);
-        } else {
-            // Receiver selects an overriding method so emit a virtual call
-            return null;
-        }
-    }
-
-    /**
-     * Adjusts the profile for an indirect invocation of a virtual method for which there is an
-     * intrinsic. The adjustment made by this method is to remove all types from the profile that do
-     * not override {@code targetMethod}.
-     *
-     * @param profile the profile to adjust
-     * @param targetMethod the virtual method for which there is an intrinsic
-     * @return the adjusted profile or the original {@code profile} object if no adjustment was made
-     */
-    protected JavaTypeProfile adjustProfileForInvocationPlugin(JavaTypeProfile profile, ResolvedJavaMethod targetMethod) {
-        if (profile.getTypes().length > 0) {
-            List<ProfiledType> retained = new ArrayList<>();
-            double notRecordedProbability = profile.getNotRecordedProbability();
-            for (ProfiledType ptype : profile.getTypes()) {
-                if (!ptype.getType().resolveMethod(targetMethod, method.getDeclaringClass()).equals(targetMethod)) {
-                    retained.add(ptype);
-                } else {
-                    notRecordedProbability += ptype.getProbability();
-                }
-            }
-            if (!retained.isEmpty()) {
-                if (retained.size() != profile.getTypes().length) {
-                    return new JavaTypeProfile(profile.getNullSeen(), notRecordedProbability, retained.toArray(new ProfiledType[retained.size()]));
-                }
-            } else {
-                return new JavaTypeProfile(profile.getNullSeen(), notRecordedProbability, new ProfiledType[0]);
-            }
-        }
-        return profile;
-    }
-
-    /**
-     * Performs any action required after execution of an invocation plugin. This includes
-     * {@linkplain InvocationPluginAssertions#check checking} invocation plugin invariants as well
-     * as weaving the {@code else} branch of the code woven by {@link #guardIntrinsic} if
-     * {@code guard != null}.
-     */
-    protected void afterInvocationPluginExecution(boolean pluginHandledInvoke, InvocationPluginAssertions assertions, IntrinsicGuard intrinsicGuard,
-                    InvokeKind invokeKind, ValueNode[] args, ResolvedJavaMethod targetMethod, JavaKind resultType, JavaType returnType) {
-        assert assertions.check(pluginHandledInvoke);
-        if (intrinsicGuard != null) {
-            if (pluginHandledInvoke) {
-                if (intrinsicGuard.nonIntrinsicBranch != null) {
-                    // Intrinsic emitted: emit a virtual call to the target method and
-                    // merge it with the intrinsic branch
-                    EndNode intrinsicEnd = append(new EndNode());
-
-                    FrameStateBuilder intrinsicState = null;
-                    FrameStateBuilder nonIntrinisicState = null;
-                    if (resultType != JavaKind.Void) {
-                        intrinsicState = frameState.copy();
-                        frameState.pop(resultType);
-                        nonIntrinisicState = frameState;
-                    }
-
-                    lastInstr = intrinsicGuard.nonIntrinsicBranch;
-                    createNonInlinedInvoke(getActionForInvokeExceptionEdge(null), bci(), args, targetMethod, invokeKind, resultType, returnType, intrinsicGuard.profile);
-
-                    EndNode nonIntrinsicEnd = append(new EndNode());
-                    AbstractMergeNode mergeNode = graph.add(new MergeNode());
-
-                    mergeNode.addForwardEnd(intrinsicEnd);
-                    if (intrinsicState != null) {
-                        intrinsicState.merge(mergeNode, nonIntrinisicState);
-                        frameState = intrinsicState;
-                    }
-                    mergeNode.addForwardEnd(nonIntrinsicEnd);
-                    mergeNode.setStateAfter(frameState.create(stream.nextBCI(), mergeNode));
-
-                    lastInstr = mergeNode;
-                }
-            } else {
-                // Intrinsic was not applied: remove intrinsic guard
-                // and restore the original receiver node in the arguments array
-                intrinsicGuard.lastInstr.setNext(null);
-                GraphUtil.removeNewNodes(graph, intrinsicGuard.mark);
-                lastInstr = intrinsicGuard.lastInstr;
-                args[0] = intrinsicGuard.receiver;
-            }
-        }
-    }
-
     @SuppressWarnings("try")
-    protected boolean tryInvocationPlugin(InvokeKind invokeKind, ValueNode[] args, ResolvedJavaMethod targetMethod, JavaKind resultType, JavaType returnType) {
+    protected boolean tryInvocationPlugin(InvokeKind invokeKind, ValueNode[] args, ResolvedJavaMethod targetMethod, JavaKind resultType) {
         InvocationPlugin plugin = graphBuilderConfig.getPlugins().getInvocationPlugins().lookupInvocation(targetMethod);
         if (plugin != null) {
 
@@ -2227,24 +2085,15 @@
             }
 
             InvocationPluginReceiver pluginReceiver = invocationPluginReceiver.init(targetMethod, args);
-
-            IntrinsicGuard intrinsicGuard = null;
-            if (invokeKind.isIndirect()) {
-                intrinsicGuard = guardIntrinsic(args, targetMethod, pluginReceiver);
-                if (intrinsicGuard == null) {
-                    return false;
-                } else if (intrinsicGuard.nonIntrinsicBranch == null) {
-                    assert lastInstr instanceof FixedGuardNode;
-                }
-            }
+            assert invokeKind.isDirect() : "Cannot apply invocation plugin on an indirect call site.";
 
             InvocationPluginAssertions assertions = Assertions.assertionsEnabled() ? new InvocationPluginAssertions(plugin, args, targetMethod, resultType) : null;
             try (DebugCloseable context = openNodeContext(targetMethod)) {
                 if (plugin.execute(this, targetMethod, pluginReceiver, args)) {
-                    afterInvocationPluginExecution(true, assertions, intrinsicGuard, invokeKind, args, targetMethod, resultType, returnType);
+                    assert assertions.check(true);
                     return !plugin.isDecorator();
                 } else {
-                    afterInvocationPluginExecution(false, assertions, intrinsicGuard, invokeKind, args, targetMethod, resultType, returnType);
+                    assert assertions.check(false);
                 }
             }
         }
@@ -2630,8 +2479,9 @@
         FixedWithNextNode calleeBeforeUnwindNode = null;
         ValueNode calleeUnwindValue = null;
 
-        try (InliningScope s = parsingIntrinsic() ? null : (calleeIntrinsicContext != null ? new IntrinsicScope(this, targetMethod, args)
-                        : new InliningScope(this, targetMethod, args))) {
+        try (InliningScope s = parsingIntrinsic() ? null
+                        : (calleeIntrinsicContext != null ? new IntrinsicScope(this, targetMethod, args)
+                                        : new InliningScope(this, targetMethod, args))) {
             BytecodeParser parser = graphBuilderInstance.createBytecodeParser(graph, this, targetMethod, INVOCATION_ENTRY_BCI, calleeIntrinsicContext);
             FrameStateBuilder startFrameState = new FrameStateBuilder(parser, parser.code, graph, graphBuilderConfig.retainLocalVariables());
             if (!targetMethod.isStatic()) {
@@ -2642,7 +2492,6 @@
 
             List<ReturnToCallerData> calleeReturnDataList = parser.returnDataList;
 
-            processCalleeReturn(targetMethod, s, calleeReturnDataList);
             /*
              * Propagate any side effects into the caller when parsing intrinsics.
              */
@@ -2652,6 +2501,8 @@
                 }
             }
 
+            processCalleeReturn(targetMethod, s, calleeReturnDataList);
+
             calleeBeforeUnwindNode = parser.getBeforeUnwindNode();
             if (calleeBeforeUnwindNode != null) {
                 calleeUnwindValue = parser.getUnwindValue();
@@ -2743,7 +2594,7 @@
                 if (stateSplit.hasSideEffect()) {
                     assert stateSplit != null;
                     if (stateAfter.bci == BytecodeFrame.AFTER_BCI) {
-                        assert stateAfter.usages().count() == 1;
+                        assert stateAfter.hasExactlyOneUsage();
                         assert stateAfter.usages().first() == stateSplit;
                         FrameState state;
                         if (returnVal.getStackKind() == JavaKind.Illegal) {
@@ -4233,7 +4084,7 @@
 
     private String unresolvedMethodAssertionMessage(JavaMethod result) {
         String message = result.format("%H.%n(%P)%R");
-        if (JavaVersionUtil.Java8OrEarlier) {
+        if (JavaVersionUtil.JAVA_SPEC <= 8) {
             JavaType declaringClass = result.getDeclaringClass();
             String className = declaringClass.getName();
             switch (className) {
@@ -4324,6 +4175,13 @@
         }
     }
 
+    protected JavaType maybeEagerlyResolve(JavaType type, ResolvedJavaType accessingClass) {
+        if (graphBuilderConfig.eagerResolving() || parsingIntrinsic()) {
+            return type.resolve(accessingClass);
+        }
+        return type;
+    }
+
     protected void maybeEagerlyInitialize(ResolvedJavaType resolvedType) {
         if (!resolvedType.isInitialized() && eagerInitializing) {
             initialize(resolvedType);
@@ -5350,4 +5208,3 @@
         return n == 0 ? "" : format("%" + n + "s", "");
     }
 }
-
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParserOptions.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParserOptions.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -66,8 +66,5 @@
 
     @Option(help = "When creating info points hide the methods of the substitutions.", type = OptionType.Debug)
     public static final OptionKey<Boolean> HideSubstitutionStates = new OptionKey<>(false);
-
-    @Option(help = "Use intrinsics guarded by a virtual dispatch test at indirect call sites.", type = OptionType.Debug)
-    public static final OptionKey<Boolean> UseGuardedIntrinsics = new OptionKey<>(true);
     // @formatter:on
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/FrameStateBuilder.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/FrameStateBuilder.java	Mon Jul 01 14:57:02 2019 -0700
@@ -43,7 +43,6 @@
 
 import org.graalvm.compiler.bytecode.Bytecode;
 import org.graalvm.compiler.bytecode.ResolvedJavaMethodBytecode;
-import org.graalvm.compiler.core.common.GraalOptions;
 import org.graalvm.compiler.core.common.PermanentBailoutException;
 import org.graalvm.compiler.core.common.type.StampFactory;
 import org.graalvm.compiler.core.common.type.StampPair;
@@ -146,7 +145,7 @@
 
         this.monitorIds = EMPTY_MONITOR_ARRAY;
         this.graph = graph;
-        this.clearNonLiveLocals = GraalOptions.OptClearNonLiveLocals.getValue(graph.getOptions()) && !shouldRetainLocalVariables;
+        this.clearNonLiveLocals = !shouldRetainLocalVariables;
         this.canVerifyKind = true;
     }
 
@@ -275,8 +274,6 @@
         clearNonLiveLocals = other.clearNonLiveLocals;
         monitorIds = other.monitorIds.length == 0 ? other.monitorIds : other.monitorIds.clone();
 
-        assert locals.length == code.getMaxLocals();
-        assert stack.length == Math.max(1, code.getMaxStackSize());
         assert lockedObjects.length == monitorIds.length;
     }
 
@@ -791,7 +788,7 @@
     public ValueNode pop(JavaKind slotKind) {
         if (slotKind.needsTwoSlots()) {
             ValueNode s = xpop();
-            assert s == TWO_SLOT_MARKER;
+            assert s == TWO_SLOT_MARKER : s;
         }
         ValueNode x = xpop();
         assert verifyKind(slotKind, x);
@@ -835,7 +832,7 @@
                 /* Ignore second slot of two-slot value. */
                 x = xpop();
             }
-            assert x != null && x != TWO_SLOT_MARKER;
+            assert x != null && x != TWO_SLOT_MARKER : x;
             result[i] = x;
         }
         return result;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/lang/UnaryMath.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/lang/UnaryMath.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,6 +26,7 @@
 
 import org.graalvm.compiler.jtt.JTTTest;
 import org.graalvm.compiler.options.OptionValues;
+import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
 
 import jdk.vm.ci.meta.ResolvedJavaMethod;
 
@@ -37,7 +38,7 @@
      * Tests a unary {@link Math} method on a wide range of values.
      */
     void testManyValues(OptionValues options, ResolvedJavaMethod method) throws AssertionError {
-        if (!Java8OrEarlier) {
+        if (JavaVersionUtil.JAVA_SPEC > 8) {
             /*
              * GR-8276: Allow for variance on JVMCI > 8 until a JVMCI version that includes
              * https://github.com/graalvm/graal-jvmci-8/commit/
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/optimize/NestedLoop_EA.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/optimize/NestedLoop_EA.java	Mon Jul 01 14:57:02 2019 -0700
@@ -129,8 +129,7 @@
     }
 
     @Override
-    protected boolean checkHighTierGraph(StructuredGraph graph) {
+    protected void checkHighTierGraph(StructuredGraph graph) {
         assert graph.getNodes().filter(CommitAllocationNode.class).count() == 0 : "all allocations should be virtualized";
-        return true;
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/optimize/TrichotomyFloats.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.jtt.optimize;
+
+import org.junit.Test;
+
+import org.graalvm.compiler.jtt.JTTTest;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/*
+ * Tests comparison-based canonicalizations for floats.
+ */
+@RunWith(Parameterized.class)
+public class TrichotomyFloats extends JTTTest {
+
+    public static int test0(float x, float y) {
+        return x < y ? -1 : (x == y ? 0 : 1);
+    }
+
+    public static int test1(float x, float y) {
+        return x < y ? 1 : (x == y ? 0 : -1);
+    }
+
+    public static int test2(float x, float y) {
+        return x == y ? 0 : (x < y ? -1 : 1);
+    }
+
+    public static int test3(float x, float y) {
+        return x == y ? 0 : (x < y ? 1 : -1);
+    }
+
+    public static int test4(float x, float y) {
+        return x == y ? 0 : (x > y ? -1 : 1);
+    }
+
+    public static int test5(float x, float y) {
+        return x == y ? 0 : (x > y ? 1 : -1);
+    }
+
+    public static int test6(float x, float y) {
+        return x < y ? 1 : (x > y ? -1 : 0);
+    }
+
+    public static int test7(float x, float y) {
+        return x < y ? -1 : (x > y ? 1 : 0);
+    }
+
+    @Parameter(value = 0) public float x;
+    @Parameter(value = 1) public float y;
+
+    @Parameters(name = "x = {0}, y = {1}")
+    public static Collection<Object[]> data() {
+        List<Object[]> parameters = new ArrayList<>();
+        float[] floats = {Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY, Float.NaN, 0f, -1f, Float.MIN_VALUE, Float.MAX_VALUE};
+        for (float f1 : floats) {
+            for (float f2 : floats) {
+                parameters.add(new Object[]{f1, f2});
+            }
+        }
+        return parameters;
+    }
+
+    @Test
+    public void run0() {
+        runTest("test0", x, y);
+    }
+
+    @Test
+    public void run1() {
+        runTest("test1", x, y);
+    }
+
+    @Test
+    public void run2() {
+        runTest("test2", x, y);
+    }
+
+    @Test
+    public void run3() {
+        runTest("test3", x, y);
+    }
+
+    @Test
+    public void run4() {
+        runTest("test4", x, y);
+    }
+
+    @Test
+    public void run5() {
+        runTest("test5", x, y);
+    }
+
+    @Test
+    public void run6() {
+        runTest("test6", x, y);
+    }
+
+    @Test
+    public void run7() {
+        runTest("test7", x, y);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64BitFieldOp.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, Arm Limited and affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+
+package org.graalvm.compiler.lir.aarch64;
+
+import jdk.vm.ci.code.Register;
+import jdk.vm.ci.meta.AllocatableValue;
+import org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler;
+import org.graalvm.compiler.debug.GraalError;
+import org.graalvm.compiler.lir.LIRInstructionClass;
+import org.graalvm.compiler.lir.Opcode;
+import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
+
+import static jdk.vm.ci.code.ValueUtil.asRegister;
+import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
+
+/**
+ * Bit field ops for AArch64.
+ */
+public class AArch64BitFieldOp extends AArch64LIRInstruction {
+    public enum BitFieldOpCode {
+        UBFX,
+        UBFIZ,
+    }
+
+    private static final LIRInstructionClass<AArch64BitFieldOp> TYPE = LIRInstructionClass.create(AArch64BitFieldOp.class);
+
+    @Opcode private final AArch64BitFieldOp.BitFieldOpCode opcode;
+    @Def protected AllocatableValue result;
+    @Use({REG}) protected AllocatableValue input;
+    private final int lsb;
+    private final int width;
+
+    public AArch64BitFieldOp(AArch64BitFieldOp.BitFieldOpCode opcode, AllocatableValue result,
+                    AllocatableValue input, int lsb, int width) {
+        super(TYPE);
+        this.opcode = opcode;
+        this.result = result;
+        this.input = input;
+        this.lsb = lsb;
+        this.width = width;
+    }
+
+    @Override
+    protected void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) {
+        Register dst = asRegister(result);
+        Register src = asRegister(input);
+        final int size = input.getPlatformKind().getSizeInBytes() * Byte.SIZE;
+        switch (opcode) {
+            case UBFX:
+                masm.ubfm(size, dst, src, lsb, lsb + width - 1);
+                break;
+            case UBFIZ:
+                masm.ubfm(size, dst, src, size - lsb, width - 1);
+                break;
+            default:
+                throw GraalError.shouldNotReachHere();
+        }
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64Move.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64Move.java	Mon Jul 01 14:57:02 2019 -0700
@@ -433,7 +433,10 @@
     }
 
     static void reg2stack(CompilationResultBuilder crb, AArch64MacroAssembler masm, AllocatableValue result, AllocatableValue input) {
-        AArch64Address dest = loadStackSlotAddress(crb, masm, asStackSlot(result), Value.ILLEGAL);
+        AArch64Address dest;
+        try (ScratchRegister scratch = masm.getScratchRegister()) {
+            dest = loadStackSlotAddress(crb, masm, asStackSlot(result), scratch.getRegister());
+        }
         Register src = asRegister(input);
         // use the slot kind to define the operand size
         AArch64Kind kind = (AArch64Kind) result.getPlatformKind();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayEqualsOp.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayEqualsOp.java	Mon Jul 01 14:57:02 2019 -0700
@@ -48,6 +48,7 @@
 import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
 
 import static jdk.vm.ci.code.ValueUtil.asRegister;
+import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.XOR;
 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.ILLEGAL;
 import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
 
@@ -79,10 +80,10 @@
     @Alive({REG}) private Value array1Value;
     @Alive({REG}) private Value array2Value;
     @Alive({REG}) private Value lengthValue;
-    @Temp({REG}) private Value temp1;
-    @Temp({REG}) private Value temp2;
+    @Temp({REG, ILLEGAL}) private Value temp1;
+    @Temp({REG, ILLEGAL}) private Value temp2;
     @Temp({REG}) private Value temp3;
-    @Temp({REG}) private Value temp4;
+    @Temp({REG, ILLEGAL}) private Value temp4;
 
     @Temp({REG, ILLEGAL}) private Value temp5;
     @Temp({REG, ILLEGAL}) private Value tempXMM;
@@ -114,12 +115,22 @@
         this.lengthValue = length;
 
         // Allocate some temporaries.
-        this.temp1 = tool.newVariable(LIRKind.unknownReference(tool.target().arch.getWordKind()));
-        this.temp2 = tool.newVariable(LIRKind.unknownReference(tool.target().arch.getWordKind()));
+        if (supportsSSE41(tool.target()) && canGenerateConstantLengthCompare(tool.target()) && !constantLengthCompareNeedsTmpArrayPointers()) {
+            this.temp1 = Value.ILLEGAL;
+            this.temp2 = Value.ILLEGAL;
+        } else {
+            this.temp1 = tool.newVariable(LIRKind.unknownReference(tool.target().arch.getWordKind()));
+            this.temp2 = tool.newVariable(LIRKind.unknownReference(tool.target().arch.getWordKind()));
+        }
         this.temp3 = tool.newVariable(LIRKind.value(tool.target().arch.getWordKind()));
-        this.temp4 = tool.newVariable(LIRKind.value(tool.target().arch.getWordKind()));
+        if (supportsSSE41(tool.target()) && canGenerateConstantLengthCompare(tool.target())) {
+            this.temp4 = Value.ILLEGAL;
+            this.temp5 = Value.ILLEGAL;
+        } else {
+            this.temp4 = tool.newVariable(LIRKind.value(tool.target().arch.getWordKind()));
+            this.temp5 = kind1.isNumericFloat() || kind1 != kind2 ? tool.newVariable(LIRKind.value(tool.target().arch.getWordKind())) : Value.ILLEGAL;
+        }
 
-        this.temp5 = kind1.isNumericFloat() || kind1 != kind2 ? tool.newVariable(LIRKind.value(tool.target().arch.getWordKind())) : Value.ILLEGAL;
         if (kind1 == JavaKind.Float) {
             this.tempXMM = tool.newVariable(LIRKind.value(AMD64Kind.SINGLE));
         } else if (kind1 == JavaKind.Double) {
@@ -157,21 +168,19 @@
     @Override
     public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
         Register result = asRegister(resultValue);
-        Register array1 = asRegister(temp1);
-        Register array2 = asRegister(temp2);
 
         Label trueLabel = new Label();
         Label falseLabel = new Label();
         Label done = new Label();
 
-        // Load array base addresses.
-        masm.leaq(array1, new AMD64Address(asRegister(array1Value), arrayBaseOffset1));
-        masm.leaq(array2, new AMD64Address(asRegister(array2Value), arrayBaseOffset2));
-
         if (canGenerateConstantLengthCompare(crb.target)) {
-            emitConstantLengthArrayCompareBytes(crb, masm, array1, array2, asRegister(temp3), asRegister(temp4),
-                            new Register[]{asRegister(vectorTemp1), asRegister(vectorTemp2), asRegister(vectorTemp3), asRegister(vectorTemp4)}, falseLabel);
+            emitConstantLengthArrayCompareBytes(crb, masm, new Register[]{asRegister(vectorTemp1), asRegister(vectorTemp2), asRegister(vectorTemp3), asRegister(vectorTemp4)}, falseLabel);
         } else {
+            Register array1 = asRegister(temp1);
+            Register array2 = asRegister(temp2);
+            // Load array base addresses.
+            masm.leaq(array1, new AMD64Address(asRegister(array1Value), arrayBaseOffset1));
+            masm.leaq(array2, new AMD64Address(asRegister(array2Value), arrayBaseOffset2));
             Register length = asRegister(temp3);
             // Get array length.
             masm.movl(length, asRegister(lengthValue));
@@ -705,6 +714,15 @@
         masm.subq(index, range);
     }
 
+    private boolean constantLengthCompareNeedsTmpArrayPointers() {
+        AVXKind.AVXSize vSize = vectorSize;
+        if (constantLength < getElementsPerVector(vectorSize)) {
+            vSize = AVXKind.AVXSize.XMM;
+        }
+        int vectorCount = constantLength & ~(2 * getElementsPerVector(vSize) - 1);
+        return vectorCount > 0;
+    }
+
     /**
      * Emits specialized assembly for checking equality of memory regions
      * {@code arrayPtr1[0..nBytes]} and {@code arrayPtr2[0..nBytes]}. If they match, execution
@@ -713,16 +731,15 @@
     private void emitConstantLengthArrayCompareBytes(
                     CompilationResultBuilder crb,
                     AMD64MacroAssembler asm,
-                    Register arrayPtr1,
-                    Register arrayPtr2,
-                    Register tmp1,
-                    Register tmp2,
                     Register[] tmpVectors,
                     Label noMatch) {
         if (constantLength == 0) {
             // do nothing
             return;
         }
+        Register arrayPtr1 = asRegister(array1Value);
+        Register arrayPtr2 = asRegister(array2Value);
+        Register tmp = asRegister(temp3);
         AVXKind.AVXSize vSize = vectorSize;
         if (constantLength < getElementsPerVector(vectorSize)) {
             vSize = AVXKind.AVXSize.XMM;
@@ -731,17 +748,15 @@
         if (elementsPerVector > constantLength) {
             assert kind1 == kind2;
             int byteLength = constantLength << arrayIndexScale1.log2;
-            // array is shorter than any vector register, use regular CMP instructions
+            // array is shorter than any vector register, use regular XOR instructions
             int movSize = (byteLength < 2) ? 1 : ((byteLength < 4) ? 2 : ((byteLength < 8) ? 4 : 8));
-            emitMovBytes(asm, tmp1, new AMD64Address(arrayPtr1), movSize);
-            emitMovBytes(asm, tmp2, new AMD64Address(arrayPtr2), movSize);
-            emitCmpBytes(asm, tmp1, tmp2, movSize);
-            asm.jcc(AMD64Assembler.ConditionFlag.NotEqual, noMatch);
+            emitMovBytes(asm, tmp, new AMD64Address(arrayPtr1, arrayBaseOffset1), movSize);
+            emitXorBytes(asm, tmp, new AMD64Address(arrayPtr2, arrayBaseOffset2), movSize);
+            asm.jccb(AMD64Assembler.ConditionFlag.NotZero, noMatch);
             if (byteLength > movSize) {
-                emitMovBytes(asm, tmp1, new AMD64Address(arrayPtr1, byteLength - movSize), movSize);
-                emitMovBytes(asm, tmp2, new AMD64Address(arrayPtr2, byteLength - movSize), movSize);
-                emitCmpBytes(asm, tmp1, tmp2, movSize);
-                asm.jcc(AMD64Assembler.ConditionFlag.NotEqual, noMatch);
+                emitMovBytes(asm, tmp, new AMD64Address(arrayPtr1, arrayBaseOffset1 + byteLength - movSize), movSize);
+                emitXorBytes(asm, tmp, new AMD64Address(arrayPtr2, arrayBaseOffset2 + byteLength - movSize), movSize);
+                asm.jccb(AMD64Assembler.ConditionFlag.NotZero, noMatch);
             }
         } else {
             int elementsPerVectorLoop = 2 * elementsPerVector;
@@ -750,37 +765,41 @@
             int bytesPerVector = vSize.getBytes();
             if (vectorCount > 0) {
                 Label loopBegin = new Label();
-                asm.leaq(arrayPtr1, new AMD64Address(arrayPtr1, vectorCount << arrayIndexScale1.log2));
-                asm.leaq(arrayPtr2, new AMD64Address(arrayPtr2, vectorCount << arrayIndexScale2.log2));
-                asm.movq(tmp1, -vectorCount);
+                Register tmpArrayPtr1 = asRegister(temp1);
+                Register tmpArrayPtr2 = asRegister(temp2);
+                asm.leaq(tmpArrayPtr1, new AMD64Address(arrayPtr1, vectorCount << arrayIndexScale1.log2));
+                asm.leaq(tmpArrayPtr2, new AMD64Address(arrayPtr2, vectorCount << arrayIndexScale2.log2));
+                arrayPtr1 = tmpArrayPtr1;
+                arrayPtr2 = tmpArrayPtr2;
+                asm.movq(tmp, -vectorCount);
                 asm.align(crb.target.wordSize * 2);
                 asm.bind(loopBegin);
-                emitVectorLoad1(asm, tmpVectors[0], arrayPtr1, tmp1, 0, vSize);
-                emitVectorLoad2(asm, tmpVectors[1], arrayPtr2, tmp1, 0, vSize);
-                emitVectorLoad1(asm, tmpVectors[2], arrayPtr1, tmp1, scaleDisplacement1(bytesPerVector), vSize);
-                emitVectorLoad2(asm, tmpVectors[3], arrayPtr2, tmp1, scaleDisplacement2(bytesPerVector), vSize);
+                emitVectorLoad1(asm, tmpVectors[0], arrayPtr1, tmp, arrayBaseOffset1, vSize);
+                emitVectorLoad2(asm, tmpVectors[1], arrayPtr2, tmp, arrayBaseOffset2, vSize);
+                emitVectorLoad1(asm, tmpVectors[2], arrayPtr1, tmp, arrayBaseOffset1 + scaleDisplacement1(bytesPerVector), vSize);
+                emitVectorLoad2(asm, tmpVectors[3], arrayPtr2, tmp, arrayBaseOffset2 + scaleDisplacement2(bytesPerVector), vSize);
                 emitVectorXor(asm, tmpVectors[0], tmpVectors[1], vSize);
                 emitVectorXor(asm, tmpVectors[2], tmpVectors[3], vSize);
                 emitVectorTest(asm, tmpVectors[0], vSize);
-                asm.jcc(AMD64Assembler.ConditionFlag.NotZero, noMatch);
+                asm.jccb(AMD64Assembler.ConditionFlag.NotZero, noMatch);
                 emitVectorTest(asm, tmpVectors[2], vSize);
-                asm.jcc(AMD64Assembler.ConditionFlag.NotZero, noMatch);
-                asm.addq(tmp1, elementsPerVectorLoop);
-                asm.jcc(AMD64Assembler.ConditionFlag.NotZero, loopBegin);
+                asm.jccb(AMD64Assembler.ConditionFlag.NotZero, noMatch);
+                asm.addq(tmp, elementsPerVectorLoop);
+                asm.jccb(AMD64Assembler.ConditionFlag.NotZero, loopBegin);
             }
             if (tailCount > 0) {
-                emitVectorLoad1(asm, tmpVectors[0], arrayPtr1, (tailCount << arrayIndexScale1.log2) - scaleDisplacement1(bytesPerVector), vSize);
-                emitVectorLoad2(asm, tmpVectors[1], arrayPtr2, (tailCount << arrayIndexScale2.log2) - scaleDisplacement2(bytesPerVector), vSize);
+                emitVectorLoad1(asm, tmpVectors[0], arrayPtr1, arrayBaseOffset1 + (tailCount << arrayIndexScale1.log2) - scaleDisplacement1(bytesPerVector), vSize);
+                emitVectorLoad2(asm, tmpVectors[1], arrayPtr2, arrayBaseOffset2 + (tailCount << arrayIndexScale2.log2) - scaleDisplacement2(bytesPerVector), vSize);
                 emitVectorXor(asm, tmpVectors[0], tmpVectors[1], vSize);
                 if (tailCount > elementsPerVector) {
-                    emitVectorLoad1(asm, tmpVectors[2], arrayPtr1, 0, vSize);
-                    emitVectorLoad2(asm, tmpVectors[3], arrayPtr2, 0, vSize);
+                    emitVectorLoad1(asm, tmpVectors[2], arrayPtr1, arrayBaseOffset1, vSize);
+                    emitVectorLoad2(asm, tmpVectors[3], arrayPtr2, arrayBaseOffset2, vSize);
                     emitVectorXor(asm, tmpVectors[2], tmpVectors[3], vSize);
                     emitVectorTest(asm, tmpVectors[2], vSize);
-                    asm.jcc(AMD64Assembler.ConditionFlag.NotZero, noMatch);
+                    asm.jccb(AMD64Assembler.ConditionFlag.NotZero, noMatch);
                 }
                 emitVectorTest(asm, tmpVectors[0], vSize);
-                asm.jcc(AMD64Assembler.ConditionFlag.NotZero, noMatch);
+                asm.jccb(AMD64Assembler.ConditionFlag.NotZero, noMatch);
             }
         }
     }
@@ -817,11 +836,23 @@
         }
     }
 
-    private static void emitCmpBytes(AMD64MacroAssembler asm, Register dst, Register src, int size) {
-        if (size < 8) {
-            asm.cmpl(dst, src);
-        } else {
-            asm.cmpq(dst, src);
+    private static void emitXorBytes(AMD64MacroAssembler asm, Register dst, AMD64Address src, int size) {
+        OperandSize opSize = getOperandSize(size);
+        XOR.getRMOpcode(opSize).emit(asm, opSize, dst, src);
+    }
+
+    private static OperandSize getOperandSize(int size) {
+        switch (size) {
+            case 1:
+                return OperandSize.BYTE;
+            case 2:
+                return OperandSize.WORD;
+            case 4:
+                return OperandSize.DWORD;
+            case 8:
+                return OperandSize.QWORD;
+            default:
+                throw new IllegalStateException();
         }
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayIndexOfOp.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayIndexOfOp.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,30 +24,43 @@
 
 package org.graalvm.compiler.lir.amd64;
 
-import jdk.vm.ci.amd64.AMD64;
-import jdk.vm.ci.amd64.AMD64.CPUFeature;
-import jdk.vm.ci.amd64.AMD64Kind;
-import jdk.vm.ci.code.Register;
-import jdk.vm.ci.meta.JavaKind;
-import jdk.vm.ci.meta.Value;
+import static jdk.vm.ci.code.ValueUtil.asRegister;
+import static jdk.vm.ci.code.ValueUtil.isRegister;
+import static jdk.vm.ci.code.ValueUtil.isStackSlot;
+import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.CONST;
+import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.ILLEGAL;
+import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
+import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.STACK;
+
+import java.util.Objects;
+
 import org.graalvm.compiler.asm.Label;
 import org.graalvm.compiler.asm.amd64.AMD64Address;
+import org.graalvm.compiler.asm.amd64.AMD64Address.Scale;
 import org.graalvm.compiler.asm.amd64.AMD64Assembler;
+import org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64RMOp;
 import org.graalvm.compiler.asm.amd64.AMD64Assembler.VexMoveOp;
 import org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRMIOp;
 import org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRMOp;
 import org.graalvm.compiler.asm.amd64.AMD64Assembler.VexRVMOp;
+import org.graalvm.compiler.asm.amd64.AMD64BaseAssembler.OperandSize;
 import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler;
 import org.graalvm.compiler.asm.amd64.AVXKind;
 import org.graalvm.compiler.core.common.LIRKind;
+import org.graalvm.compiler.core.common.NumUtil;
+import org.graalvm.compiler.lir.ConstantValue;
 import org.graalvm.compiler.lir.LIRInstructionClass;
 import org.graalvm.compiler.lir.Opcode;
 import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
 import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
 
-import static jdk.vm.ci.code.ValueUtil.asRegister;
-import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.ILLEGAL;
-import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
+import jdk.vm.ci.amd64.AMD64;
+import jdk.vm.ci.amd64.AMD64.CPUFeature;
+import jdk.vm.ci.amd64.AMD64Kind;
+import jdk.vm.ci.code.Register;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.Value;
 
 /**
  */
@@ -55,24 +68,23 @@
 public final class AMD64ArrayIndexOfOp extends AMD64LIRInstruction {
     public static final LIRInstructionClass<AMD64ArrayIndexOfOp> TYPE = LIRInstructionClass.create(AMD64ArrayIndexOfOp.class);
 
-    private final JavaKind kind;
-    private final int vmPageSize;
+    private final JavaKind valueKind;
     private final int nValues;
     private final boolean findTwoConsecutive;
     private final AMD64Kind vectorKind;
+    private final int arrayBaseOffset;
+    private final Scale arrayIndexScale;
 
     @Def({REG}) protected Value resultValue;
     @Alive({REG}) protected Value arrayPtrValue;
-    @Use({REG}) protected Value arrayLengthValue;
-    @Alive({REG}) protected Value searchValue1;
-    @Alive({REG, ILLEGAL}) protected Value searchValue2;
-    @Alive({REG, ILLEGAL}) protected Value searchValue3;
-    @Alive({REG, ILLEGAL}) protected Value searchValue4;
-    @Temp({REG}) protected Value arraySlotsRemaining;
+    @Alive({REG}) protected Value arrayLengthValue;
+    @Use({REG}) protected Value fromIndexValue;
+    @Alive({REG, STACK, CONST}) protected Value searchValue1;
+    @Alive({REG, STACK, CONST, ILLEGAL}) protected Value searchValue2;
+    @Alive({REG, STACK, CONST, ILLEGAL}) protected Value searchValue3;
+    @Alive({REG, STACK, CONST, ILLEGAL}) protected Value searchValue4;
     @Temp({REG}) protected Value comparisonResult1;
-    @Temp({REG}) protected Value comparisonResult2;
-    @Temp({REG}) protected Value comparisonResult3;
-    @Temp({REG}) protected Value comparisonResult4;
+    @Temp({REG, ILLEGAL}) protected Value comparisonResult2;
     @Temp({REG, ILLEGAL}) protected Value vectorCompareVal1;
     @Temp({REG, ILLEGAL}) protected Value vectorCompareVal2;
     @Temp({REG, ILLEGAL}) protected Value vectorCompareVal3;
@@ -82,31 +94,30 @@
     @Temp({REG, ILLEGAL}) protected Value vectorArray3;
     @Temp({REG, ILLEGAL}) protected Value vectorArray4;
 
-    public AMD64ArrayIndexOfOp(JavaKind kind, boolean findTwoConsecutive, int vmPageSize, int maxVectorSize, LIRGeneratorTool tool, Value result, Value arrayPtr, Value arrayLength,
-                    Value... searchValues) {
+    public AMD64ArrayIndexOfOp(JavaKind arrayKind, JavaKind valueKind, boolean findTwoConsecutive, int maxVectorSize, LIRGeneratorTool tool,
+                    Value result, Value arrayPtr, Value arrayLength, Value fromIndex, Value... searchValues) {
         super(TYPE);
-        this.kind = kind;
+        this.valueKind = valueKind;
+        this.arrayBaseOffset = tool.getProviders().getMetaAccess().getArrayBaseOffset(arrayKind);
+        this.arrayIndexScale = Objects.requireNonNull(Scale.fromInt(tool.getProviders().getMetaAccess().getArrayIndexScale(valueKind)));
         this.findTwoConsecutive = findTwoConsecutive;
-        this.vmPageSize = vmPageSize;
         assert 0 < searchValues.length && searchValues.length <= 4;
-        assert byteMode(kind) || charMode(kind);
+        assert byteMode(valueKind) || charMode(valueKind);
         assert supports(tool, CPUFeature.SSE2) || supports(tool, CPUFeature.AVX) || supportsAVX2(tool);
         nValues = searchValues.length;
         assert !findTwoConsecutive || nValues == 1;
         resultValue = result;
         arrayPtrValue = arrayPtr;
         arrayLengthValue = arrayLength;
+        fromIndexValue = fromIndex;
         searchValue1 = searchValues[0];
         searchValue2 = nValues > 1 ? searchValues[1] : Value.ILLEGAL;
         searchValue3 = nValues > 2 ? searchValues[2] : Value.ILLEGAL;
         searchValue4 = nValues > 3 ? searchValues[3] : Value.ILLEGAL;
-        arraySlotsRemaining = tool.newVariable(LIRKind.value(AMD64Kind.DWORD));
-        comparisonResult1 = tool.newVariable(LIRKind.value(AMD64Kind.DWORD));
-        comparisonResult2 = tool.newVariable(LIRKind.value(AMD64Kind.DWORD));
-        comparisonResult3 = tool.newVariable(LIRKind.value(AMD64Kind.DWORD));
-        comparisonResult4 = tool.newVariable(LIRKind.value(AMD64Kind.DWORD));
-        vectorKind = supportsAVX2(tool) && (maxVectorSize < 0 || maxVectorSize >= 32) ? byteMode(kind) ? AMD64Kind.V256_BYTE : AMD64Kind.V256_WORD
-                        : byteMode(kind) ? AMD64Kind.V128_BYTE : AMD64Kind.V128_WORD;
+        comparisonResult1 = tool.newVariable(LIRKind.value(tool.target().arch.getWordKind()));
+        comparisonResult2 = findTwoConsecutive ? tool.newVariable(LIRKind.value(tool.target().arch.getWordKind())) : Value.ILLEGAL;
+        vectorKind = supportsAVX2(tool) && (maxVectorSize < 0 || maxVectorSize >= 32) ? byteMode(valueKind) ? AMD64Kind.V256_BYTE : AMD64Kind.V256_WORD
+                        : byteMode(valueKind) ? AMD64Kind.V128_BYTE : AMD64Kind.V128_WORD;
         vectorCompareVal1 = tool.newVariable(LIRKind.value(vectorKind));
         vectorCompareVal2 = nValues > 1 ? tool.newVariable(LIRKind.value(vectorKind)) : Value.ILLEGAL;
         vectorCompareVal3 = nValues > 2 ? tool.newVariable(LIRKind.value(vectorKind)) : Value.ILLEGAL;
@@ -126,7 +137,7 @@
     }
 
     private JavaKind getComparisonKind() {
-        return findTwoConsecutive ? (byteMode(kind) ? JavaKind.Char : JavaKind.Int) : kind;
+        return findTwoConsecutive ? (byteMode(valueKind) ? JavaKind.Char : JavaKind.Int) : valueKind;
     }
 
     private AVXKind.AVXSize getVectorSize() {
@@ -135,15 +146,16 @@
 
     @Override
     public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler asm) {
+        int nVectors = nValues == 1 ? 4 : nValues == 2 ? 2 : 1;
         Register arrayPtr = asRegister(arrayPtrValue);
         Register arrayLength = asRegister(arrayLengthValue);
-        Register result = asRegister(resultValue);
-        Register slotsRemaining = asRegister(arraySlotsRemaining);
-        Register[] searchValue = {
-                        nValues > 0 ? asRegister(searchValue1) : null,
-                        nValues > 1 ? asRegister(searchValue2) : null,
-                        nValues > 2 ? asRegister(searchValue3) : null,
-                        nValues > 3 ? asRegister(searchValue4) : null,
+        Register fromIndex = asRegister(fromIndexValue);
+        Register index = asRegister(resultValue);
+        Value[] searchValue = {
+                        nValues > 0 ? searchValue1 : null,
+                        nValues > 1 ? searchValue2 : null,
+                        nValues > 2 ? searchValue3 : null,
+                        nValues > 3 ? searchValue4 : null,
         };
         Register[] vecCmp = {
                         nValues > 0 ? asRegister(vectorCompareVal1) : null,
@@ -159,60 +171,9 @@
         };
         Register[] cmpResult = {
                         asRegister(comparisonResult1),
-                        asRegister(comparisonResult2),
-                        asRegister(comparisonResult3),
-                        asRegister(comparisonResult4),
+                        findTwoConsecutive ? asRegister(comparisonResult2) : null,
         };
-        Label retFound = new Label();
-        Label retNotFound = new Label();
-        Label end = new Label();
-
-        // load array length
-        // important: this must be the first register manipulation, since arrayLengthValue is
-        // annotated with @Use
-        asm.movl(slotsRemaining, arrayLength);
-        // load array pointer
-        asm.movq(result, arrayPtr);
-        // move search values to vectors
-        for (int i = 0; i < nValues; i++) {
-            if (asm.supports(CPUFeature.AVX)) {
-                VexMoveOp.VMOVD.emit(asm, AVXKind.AVXSize.DWORD, vecCmp[i], searchValue[i]);
-            } else {
-                asm.movdl(vecCmp[i], searchValue[i]);
-            }
-        }
-        // fill comparison vector with copies of the search value
-        for (int i = 0; i < nValues; i++) {
-            emitBroadcast(asm, getComparisonKind(), vecCmp[i], vecArray[0], getVectorSize());
-        }
-
-        emitArrayIndexOfChars(crb, asm, result, slotsRemaining, searchValue, vecCmp, vecArray, cmpResult, retFound, retNotFound);
-
-        // return -1 (no match)
-        asm.bind(retNotFound);
-        asm.movq(result, -1);
-        asm.jmpb(end);
-
-        asm.bind(retFound);
-        // convert array pointer to offset
-        asm.subq(result, arrayPtr);
-        if (charMode(kind)) {
-            asm.shrq(result, 1);
-        }
-        asm.bind(end);
-    }
-
-    private void emitArrayIndexOfChars(CompilationResultBuilder crb, AMD64MacroAssembler asm,
-                    Register arrayPtr,
-                    Register slotsRemaining,
-                    Register[] searchValue,
-                    Register[] vecCmp,
-                    Register[] vecArray,
-                    Register[] cmpResult,
-                    Label retFound,
-                    Label retNotFound) {
-        int nVectors = nValues == 1 ? 4 : nValues == 2 ? 2 : 1;
-        AVXKind.AVXSize vectorSize = getVectorSize();
+        Label ret = new Label();
 
         Label bulkVectorLoop = new Label();
         Label singleVectorLoop = new Label();
@@ -222,225 +183,276 @@
                         new Label(),
                         new Label(),
         };
-        Label lessThanVectorSizeRemaining = new Label();
-        Label lessThanVectorSizeRemainingLoop = new Label();
-        Label bulkVectorLoopExit = nVectors == 1 ? lessThanVectorSizeRemaining : singleVectorLoop;
-        int bytesPerVector = vectorSize.getBytes();
-        int arraySlotsPerVector = vectorSize.getBytes() / kind.getByteCount();
-        int singleVectorLoopCondition = arraySlotsPerVector;
-        int bulkSize = arraySlotsPerVector * nVectors;
-        int bulkSizeBytes = bytesPerVector * nVectors;
-        int bulkLoopCondition = bulkSize;
-        int[] vectorOffsets;
-        JavaKind vectorCompareKind = kind;
+        Label runVectorized = new Label();
+        Label elementWiseLoop = new Label();
+        Label elementWiseFound = new Label();
+        Label elementWiseNotFound = new Label();
+        Label skipBulkVectorLoop = new Label();
+        int vectorSize = getVectorSize().getBytes() / valueKind.getByteCount();
+        int bulkSize = vectorSize * nVectors;
+        JavaKind vectorCompareKind = valueKind;
         if (findTwoConsecutive) {
-            singleVectorLoopCondition++;
-            bulkLoopCondition++;
             bulkSize /= 2;
-            bulkSizeBytes /= 2;
-            vectorOffsets = new int[]{0, kind.getByteCount(), bytesPerVector, bytesPerVector + kind.getByteCount()};
-            vectorCompareKind = byteMode(kind) ? JavaKind.Char : JavaKind.Int;
+            vectorCompareKind = byteMode(valueKind) ? JavaKind.Char : JavaKind.Int;
+        }
+        // index = fromIndex + vectorSize (+1 if findTwoConsecutive)
+        // important: this must be the first register manipulation, since fromIndex is
+        // annotated with @Use
+        asm.leaq(index, new AMD64Address(fromIndex, vectorSize + (findTwoConsecutive ? 1 : 0)));
+
+        // check if vector vector load is in bounds
+        asm.cmpq(index, arrayLength);
+        asm.jccb(AMD64Assembler.ConditionFlag.LessEqual, runVectorized);
+
+        // search range is smaller than vector size, do element-wise comparison
+
+        // index = fromIndex (+ 1 if findTwoConsecutive)
+        asm.subq(index, vectorSize);
+        // check if enough array slots remain
+        asm.cmpq(index, arrayLength);
+        asm.jccb(AMD64Assembler.ConditionFlag.GreaterEqual, elementWiseNotFound);
+        // compare one-by-one
+        asm.bind(elementWiseLoop);
+        // check for match
+        OperandSize cmpSize = getOpSize(getComparisonKind());
+        // address = findTwoConsecutive ? array[index - 1] : array[index]
+        AMD64Address arrayAddr = new AMD64Address(arrayPtr, index, arrayIndexScale, arrayBaseOffset - (findTwoConsecutive ? valueKind.getByteCount() : 0));
+        boolean valuesOnStack = searchValuesOnStack(searchValue);
+        if (valuesOnStack) {
+            (cmpSize == OperandSize.BYTE ? AMD64RMOp.MOVB : AMD64RMOp.MOV).emit(asm, cmpSize, cmpResult[0], arrayAddr);
+            for (int i = 0; i < nValues; i++) {
+                if (isConstant(searchValue[i])) {
+                    int imm = asConstant(searchValue[i]).asInt();
+                    AMD64Assembler.AMD64BinaryArithmetic.CMP.getMIOpcode(cmpSize, NumUtil.isByte(imm)).emit(asm, cmpSize, cmpResult[0], imm);
+                } else if (isStackSlot(searchValue[i])) {
+                    AMD64Assembler.AMD64BinaryArithmetic.CMP.getRMOpcode(cmpSize).emit(asm, cmpSize, cmpResult[0], (AMD64Address) crb.asAddress(searchValue[i]));
+                } else {
+                    AMD64Assembler.AMD64BinaryArithmetic.CMP.getRMOpcode(cmpSize).emit(asm, cmpSize, cmpResult[0], asRegister(searchValue[i]));
+                }
+                asm.jccb(AMD64Assembler.ConditionFlag.Equal, elementWiseFound);
+            }
         } else {
-            vectorOffsets = new int[]{0, bytesPerVector, bytesPerVector * 2, bytesPerVector * 3};
+            for (int i = 0; i < nValues; i++) {
+                if (isConstant(searchValue[i])) {
+                    int imm = asConstant(searchValue[i]).asInt();
+                    AMD64Assembler.AMD64BinaryArithmetic.CMP.getMIOpcode(cmpSize, NumUtil.isByte(imm)).emit(asm, cmpSize, arrayAddr, imm);
+                } else {
+                    AMD64Assembler.AMD64BinaryArithmetic.CMP.getRMOpcode(cmpSize).emit(asm, cmpSize, asRegister(searchValue[i]), arrayAddr);
+                }
+                asm.jccb(AMD64Assembler.ConditionFlag.Equal, elementWiseFound);
+            }
+        }
+        // adjust index
+        asm.incrementq(index, 1);
+        // continue loop
+        asm.cmpq(index, arrayLength);
+        asm.jccb(AMD64Assembler.ConditionFlag.Less, elementWiseLoop);
+
+        asm.bind(elementWiseNotFound);
+        asm.xorq(index, index);
+
+        if (findTwoConsecutive) {
+            asm.bind(elementWiseFound);
+            asm.decrementq(index, 1);
+        } else {
+            asm.decrementq(index, 1);
+            asm.bind(elementWiseFound);
+        }
+        asm.jmp(ret);
+
+        // vectorized implementation
+        asm.bind(runVectorized);
+
+        // move search values to vectors
+        for (int i = 0; i < nValues; i++) {
+            // fill comparison vector with copies of the search value
+            broadcastSearchValue(crb, asm, vecCmp[i], searchValue[i], cmpResult[0], vecArray[0]);
         }
 
-        // load copy of low part of array pointer
-        Register tmpArrayPtrLow = cmpResult[0];
-        asm.movl(tmpArrayPtrLow, arrayPtr);
-
-        // check if bulk vector load is in bounds
-        asm.cmpl(slotsRemaining, bulkLoopCondition);
-        asm.jcc(AMD64Assembler.ConditionFlag.Below, bulkVectorLoopExit);
-
-        // check if array pointer is aligned to bulkSize
-        asm.andl(tmpArrayPtrLow, bulkSizeBytes - 1);
-        asm.jcc(AMD64Assembler.ConditionFlag.Zero, bulkVectorLoop);
+        // do one unaligned vector comparison pass and adjust alignment afterwards
+        emitVectorCompare(asm, vectorCompareKind, findTwoConsecutive ? 2 : 1, arrayPtr, index, vecCmp, vecArray, cmpResult, vectorFound, false, false);
 
-        // do one unaligned bulk comparison pass and adjust alignment afterwards
-        emitVectorCompare(asm, vectorCompareKind, vectorSize, nValues, nVectors, vectorOffsets, arrayPtr, vecCmp, vecArray, cmpResult, vectorFound, false);
-        // load copy of low part of array pointer
-        asm.movl(tmpArrayPtrLow, arrayPtr);
-        // adjust array pointer
-        asm.addq(arrayPtr, bulkSizeBytes);
-        // adjust number of array slots remaining
-        asm.subl(slotsRemaining, bulkSize);
-        // get offset to bulk size alignment
-        asm.andl(tmpArrayPtrLow, bulkSizeBytes - 1);
-        emitBytesToArraySlots(asm, kind, tmpArrayPtrLow);
-        // adjust array pointer to bulk size alignment
-        asm.andq(arrayPtr, ~(bulkSizeBytes - 1));
-        // adjust number of array slots remaining
-        asm.addl(slotsRemaining, tmpArrayPtrLow);
+        // adjust index to vector size alignment
+        asm.leaq(cmpResult[0], new AMD64Address(arrayPtr, arrayBaseOffset));
+        if (charMode(valueKind)) {
+            asm.shrq(cmpResult[0], 1);
+        }
+        asm.addq(index, cmpResult[0]);
+        // adjust to next lower multiple of vector size
+        asm.andq(index, ~(vectorSize - 1));
+        asm.subq(index, cmpResult[0]);
+        // add bulk size
+        asm.addq(index, bulkSize);
+
         // check if there are enough array slots remaining for the bulk loop
-        asm.cmpl(slotsRemaining, bulkLoopCondition);
-        asm.jcc(AMD64Assembler.ConditionFlag.Below, bulkVectorLoopExit);
+        asm.cmpq(index, arrayLength);
+        asm.jccb(AMD64Assembler.ConditionFlag.Greater, skipBulkVectorLoop);
 
         emitAlign(crb, asm);
         asm.bind(bulkVectorLoop);
         // memory-aligned bulk comparison
-        emitVectorCompare(asm, vectorCompareKind, vectorSize, nValues, nVectors, vectorOffsets, arrayPtr, vecCmp, vecArray, cmpResult, vectorFound, !findTwoConsecutive);
-        // adjust number of array slots remaining
-        asm.subl(slotsRemaining, bulkSize);
-        // adjust array pointer
-        asm.addq(arrayPtr, bulkSizeBytes);
+        emitVectorCompare(asm, vectorCompareKind, nVectors, arrayPtr, index, vecCmp, vecArray, cmpResult, vectorFound, false, !findTwoConsecutive);
+        // adjust index
+        asm.addq(index, bulkSize);
         // check if there are enough array slots remaining for the bulk loop
-        asm.cmpl(slotsRemaining, bulkLoopCondition);
-        asm.jcc(AMD64Assembler.ConditionFlag.Below, bulkVectorLoopExit);
-        // continue loop
-        asm.jmp(bulkVectorLoop);
+        asm.cmpq(index, arrayLength);
+        asm.jccb(AMD64Assembler.ConditionFlag.LessEqual, bulkVectorLoop);
 
-        if (nVectors > 1) {
+        asm.bind(skipBulkVectorLoop);
+        if ((findTwoConsecutive && nVectors == 2) || nVectors == 1) {
+            // do last load from end of array
+            asm.movq(index, arrayLength);
+            // compare
+            emitVectorCompare(asm, vectorCompareKind, findTwoConsecutive ? 2 : 1, arrayPtr, index, vecCmp, vecArray, cmpResult, vectorFound, true, false);
+        } else {
+            // remove bulk offset
+            asm.subq(index, bulkSize);
             emitAlign(crb, asm);
             // same loop as bulkVectorLoop, with only one vector
             asm.bind(singleVectorLoop);
-            // check if single vector load is in bounds
-            asm.cmpl(slotsRemaining, singleVectorLoopCondition);
-            asm.jcc(AMD64Assembler.ConditionFlag.Below, lessThanVectorSizeRemaining);
+            // add vector size
+            asm.addq(index, vectorSize);
+            // check if vector load is in bounds
+            asm.cmpq(index, arrayLength);
+            // if load would be over bounds, set the load to the end of the array
+            asm.cmovq(AMD64Assembler.ConditionFlag.Greater, index, arrayLength);
             // compare
-            emitVectorCompare(asm, vectorCompareKind, vectorSize, nValues, findTwoConsecutive ? 2 : 1, vectorOffsets, arrayPtr, vecCmp, vecArray, cmpResult, vectorFound, false);
-            // adjust number of array slots remaining
-            asm.subl(slotsRemaining, arraySlotsPerVector);
-            // adjust array pointer
-            asm.addq(arrayPtr, bytesPerVector);
-            // continue loop
-            asm.jmpb(singleVectorLoop);
-        }
-
-        asm.bind(lessThanVectorSizeRemaining);
-        // check if any array slots remain
-        asm.testl(slotsRemaining, slotsRemaining);
-        asm.jcc(AMD64Assembler.ConditionFlag.Zero, retNotFound);
-
-        // a vector compare will read out of bounds of the input array.
-        // check if the out-of-bounds read would cross a memory page boundary.
-        // load copy of low part of array pointer
-        asm.movl(tmpArrayPtrLow, arrayPtr);
-        // check if pointer + vector size would cross the page boundary
-        asm.andl(tmpArrayPtrLow, (vmPageSize - 1));
-        asm.cmpl(tmpArrayPtrLow, (vmPageSize - (findTwoConsecutive ? bytesPerVector + kind.getByteCount() : bytesPerVector)));
-        // if the page boundary would be crossed, do byte/character-wise comparison instead.
-        asm.jccb(AMD64Assembler.ConditionFlag.Above, lessThanVectorSizeRemainingLoop);
-
-        Label[] overBoundsMatch = {new Label(), new Label()};
-        // otherwise, do a vector compare that reads beyond array bounds
-        emitVectorCompare(asm, vectorCompareKind, vectorSize, nValues, findTwoConsecutive ? 2 : 1, vectorOffsets, arrayPtr, vecCmp, vecArray, cmpResult, overBoundsMatch, false);
-        // no match
-        asm.jmp(retNotFound);
-        if (findTwoConsecutive) {
-            Label overBoundsFinish = new Label();
-            asm.bind(overBoundsMatch[1]);
-            // get match offset of second result
-            asm.bsfq(cmpResult[1], cmpResult[1]);
-            asm.addl(cmpResult[1], kind.getByteCount());
-            // replace first result with second and continue
-            asm.movl(cmpResult[0], cmpResult[1]);
-            asm.jmpb(overBoundsFinish);
-
-            asm.bind(overBoundsMatch[0]);
-            emitFindTwoCharPrefixMinResult(asm, kind, cmpResult, overBoundsFinish);
-        } else {
-            asm.bind(overBoundsMatch[0]);
-            // find match offset
-            asm.bsfq(cmpResult[0], cmpResult[0]);
+            emitVectorCompare(asm, vectorCompareKind, findTwoConsecutive ? 2 : 1, arrayPtr, index, vecCmp, vecArray, cmpResult, vectorFound, true, false);
+            // check if there are enough array slots remaining for the loop
+            asm.cmpq(index, arrayLength);
+            asm.jccb(AMD64Assembler.ConditionFlag.Less, singleVectorLoop);
         }
 
-        // adjust array pointer for match result
-        asm.addq(arrayPtr, cmpResult[0]);
-        if (charMode(kind)) {
-            // convert byte offset to chars
-            asm.shrl(cmpResult[0], 1);
-        }
-        // check if offset of matched value is greater than number of bytes remaining / out of array
-        // bounds
+        asm.movl(index, -1);
+        asm.jmpb(ret);
+
         if (findTwoConsecutive) {
-            asm.decrementl(slotsRemaining);
-        }
-        asm.cmpl(cmpResult[0], slotsRemaining);
-        // match is out of bounds, return no match
-        asm.jcc(AMD64Assembler.ConditionFlag.GreaterEqual, retNotFound);
-        // adjust number of array slots remaining
-        if (findTwoConsecutive) {
-            asm.incrementl(slotsRemaining, 1);
+            Label vectorFound2Done = new Label();
+
+            // vectorFound[0] and vectorFound[2] behave like the single-char case
+            asm.bind(vectorFound[2]);
+            // add static offset
+            asm.subq(index, getResultIndexDelta(2));
+            asm.jmpb(vectorFound2Done);
+
+            asm.bind(vectorFound[0]);
+            // add static offset
+            asm.subq(index, getResultIndexDelta(0));
+            asm.bind(vectorFound2Done);
+            // find offset
+            asm.bsfq(cmpResult[0], cmpResult[0]);
+            if (charMode(valueKind)) {
+                // convert byte offset to chars
+                asm.shrl(cmpResult[0], 1);
+            }
+            // add offset to index
+            asm.addq(index, cmpResult[0]);
+            asm.jmpb(ret);
+
+            Label minResult = new Label();
+            Label minResultDone = new Label();
+
+            // in vectorFound[1] and vectorFound[3], we have to check the results 0 and 2 as well
+            if (nVectors > 2) {
+                asm.bind(vectorFound[3]);
+                // add offset
+                asm.subq(index, getResultIndexDelta(3));
+                asm.jmpb(minResult);
+            }
+
+            asm.bind(vectorFound[1]);
+            // add offset
+            asm.subq(index, getResultIndexDelta(1));
+
+            asm.bind(minResult);
+            // find offset 0
+            asm.bsfq(cmpResult[1], cmpResult[1]);
+            // check if second result is also a match
+            asm.testq(cmpResult[0], cmpResult[0]);
+            asm.jccb(AMD64Assembler.ConditionFlag.Zero, minResultDone);
+            // find offset 1
+            asm.bsfq(cmpResult[0], cmpResult[0]);
+            asm.addq(cmpResult[0], valueKind.getByteCount());
+            // if first result is greater than second, replace it with the second result
+            asm.cmpq(cmpResult[1], cmpResult[0]);
+            asm.cmovq(AMD64Assembler.ConditionFlag.Greater, cmpResult[1], cmpResult[0]);
+            asm.bind(minResultDone);
+            if (charMode(valueKind)) {
+                // convert byte offset to chars
+                asm.shrl(cmpResult[1], 1);
+            }
+            // add offset to index
+            asm.addq(index, cmpResult[1]);
+        } else {
+            Label end = new Label();
+            for (int i = 0; i < nVectors; i++) {
+                asm.bind(vectorFound[i]);
+                // add static offset
+                asm.subq(index, getResultIndexDelta(i));
+                if (i < nVectors - 1) {
+                    asm.jmpb(end);
+                }
+            }
+            asm.bind(end);
+            // find offset
+            asm.bsfq(cmpResult[0], cmpResult[0]);
+            if (charMode(valueKind)) {
+                // convert byte offset to chars
+                asm.shrl(cmpResult[0], 1);
+            }
+            // add offset to index
+            asm.addq(index, cmpResult[0]);
         }
-        asm.subl(slotsRemaining, cmpResult[0]);
-        // match is in bounds, return offset
-        asm.jmp(retFound);
+        asm.bind(ret);
+    }
 
-        // compare remaining slots in the array one-by-one
-        asm.bind(lessThanVectorSizeRemainingLoop);
-        // check if enough array slots remain
-        asm.cmpl(slotsRemaining, findTwoConsecutive ? 1 : 0);
-        asm.jcc(AMD64Assembler.ConditionFlag.LessEqual, retNotFound);
-        // load char / byte
-        if (byteMode(kind)) {
-            if (findTwoConsecutive) {
-                asm.movzwl(cmpResult[0], new AMD64Address(arrayPtr));
-            } else {
-                asm.movzbl(cmpResult[0], new AMD64Address(arrayPtr));
-            }
-        } else {
-            if (findTwoConsecutive) {
-                asm.movl(cmpResult[0], new AMD64Address(arrayPtr));
-            } else {
-                asm.movzwl(cmpResult[0], new AMD64Address(arrayPtr));
+    private boolean searchValuesOnStack(Value[] searchValue) {
+        for (int i = 0; i < nValues; i++) {
+            if (isStackSlot(searchValue[i])) {
+                return true;
             }
         }
-        // check for match
-        for (int i = 0; i < nValues; i++) {
-            emitCompareInst(asm, getComparisonKind(), cmpResult[0], searchValue[i]);
-            asm.jcc(AMD64Assembler.ConditionFlag.Equal, retFound);
-        }
-        // adjust number of array slots remaining
-        asm.decrementl(slotsRemaining);
-        // adjust array pointer
-        asm.addq(arrayPtr, kind.getByteCount());
-        // continue loop
-        asm.jmpb(lessThanVectorSizeRemainingLoop);
+        return false;
+    }
 
-        for (int i = 1; i < nVectors; i += (findTwoConsecutive ? 2 : 1)) {
-            emitVectorFoundWithOffset(asm, kind, vectorOffsets[i], arrayPtr, cmpResult[i], slotsRemaining, vectorFound[i], retFound);
-        }
+    private int getResultIndexDelta(int i) {
+        return (((findTwoConsecutive ? i / 2 : i) + 1) * (getVectorSize().getBytes() / valueKind.getByteCount())) + (findTwoConsecutive ? (i & 1) : 0);
+    }
 
-        if (findTwoConsecutive) {
-            asm.bind(vectorFound[2]);
-            asm.addq(arrayPtr, vectorOffsets[2]);
-            // adjust number of array slots remaining
-            asm.subl(slotsRemaining, charMode(kind) ? vectorOffsets[2] / 2 : vectorOffsets[2]);
-            asm.movl(cmpResult[0], cmpResult[2]);
-            asm.movl(cmpResult[1], cmpResult[3]);
-            asm.bind(vectorFound[0]);
-            emitFindTwoCharPrefixMinResult(asm, kind, cmpResult, new Label());
+    private int getVectorOffset(int i) {
+        return arrayBaseOffset - getResultIndexDelta(i) * valueKind.getByteCount();
+    }
+
+    private void broadcastSearchValue(CompilationResultBuilder crb, AMD64MacroAssembler asm, Register dst, Value srcVal, Register tmpReg, Register tmpVector) {
+        Register src = asRegOrTmpReg(crb, asm, srcVal, tmpReg);
+        if (asm.supports(CPUFeature.AVX)) {
+            VexMoveOp.VMOVD.emit(asm, AVXKind.AVXSize.DWORD, dst, src);
         } else {
-            asm.bind(vectorFound[0]);
-            // find index of first set bit in bit mask
-            asm.bsfq(cmpResult[0], cmpResult[0]);
+            asm.movdl(dst, src);
         }
-        // add offset to array pointer
-        asm.addq(arrayPtr, cmpResult[0]);
-        if (charMode(kind)) {
-            // convert byte offset to chars
-            asm.shrl(cmpResult[0], 1);
-        }
-        // adjust number of array slots remaining
-        asm.subl(slotsRemaining, cmpResult[0]);
-        asm.jmpb(retFound);
+        emitBroadcast(asm, getComparisonKind(), dst, tmpVector, getVectorSize());
     }
 
-    private static void emitFindTwoCharPrefixMinResult(AMD64MacroAssembler asm, JavaKind kind, Register[] cmpResult, Label done) {
-        // find match offset
-        asm.bsfq(cmpResult[0], cmpResult[0]);
-        // check if second result is also a match
-        asm.testl(cmpResult[1], cmpResult[1]);
-        asm.jcc(AMD64Assembler.ConditionFlag.Zero, done);
-        // get match offset of second result
-        asm.bsfq(cmpResult[1], cmpResult[1]);
-        asm.addl(cmpResult[1], kind.getByteCount());
-        // check if first result is less than second
-        asm.cmpl(cmpResult[0], cmpResult[1]);
-        asm.jcc(AMD64Assembler.ConditionFlag.LessEqual, done);
-        // first result is greater than second, replace it with the second result
-        asm.movl(cmpResult[0], cmpResult[1]);
-        asm.bind(done);
+    private static boolean isConstant(Value val) {
+        assert !(val instanceof ConstantValue) || ((ConstantValue) val).isJavaConstant();
+        return val instanceof ConstantValue;
+    }
+
+    private static JavaConstant asConstant(Value val) {
+        return ((ConstantValue) val).getJavaConstant();
+    }
+
+    private static Register asRegOrTmpReg(CompilationResultBuilder crb, AMD64MacroAssembler asm, Value val, Register tmpReg) {
+        if (isRegister(val)) {
+            return asRegister(val);
+        } else if (isStackSlot(val)) {
+            asm.movl(tmpReg, (AMD64Address) crb.asAddress(val));
+            return tmpReg;
+        } else {
+            assert isConstant(val);
+            asm.movl(tmpReg, asConstant(val).asInt());
+            return tmpReg;
+        }
     }
 
     private static void emitAlign(CompilationResultBuilder crb, AMD64MacroAssembler asm) {
@@ -493,92 +505,64 @@
         }
     }
 
-    /**
-     * Convert a byte offset stored in {@code bytes} to an array index offset.
-     */
-    private static void emitBytesToArraySlots(AMD64MacroAssembler asm, JavaKind kind, Register bytes) {
-        if (charMode(kind)) {
-            asm.shrl(bytes, 1);
-        } else {
-            assert byteMode(kind);
-        }
-    }
-
-    private static void emitVectorCompare(AMD64MacroAssembler asm,
+    private void emitVectorCompare(AMD64MacroAssembler asm,
                     JavaKind kind,
-                    AVXKind.AVXSize vectorSize,
-                    int nValues,
                     int nVectors,
-                    int[] vectorOffsets,
                     Register arrayPtr,
+                    Register index,
                     Register[] vecCmp,
                     Register[] vecArray,
                     Register[] cmpResult,
                     Label[] vectorFound,
+                    boolean shortJmp,
                     boolean alignedLoad) {
         // load array contents into vectors
-        for (int i = 0; i < nValues; i++) {
-            for (int j = 0; j < nVectors; j++) {
-                emitArrayLoad(asm, vectorSize, vecArray[(i * nVectors) + j], arrayPtr, vectorOffsets[j], alignedLoad);
+        for (int i = 0; i < nVectors; i++) {
+            int base = i * nValues;
+            for (int j = 0; j < nValues; j++) {
+                emitArrayLoad(asm, getVectorSize(), vecArray[base + j], arrayPtr, index, getVectorOffset(nVectors - (i + 1)), alignedLoad);
             }
         }
         // compare all loaded bytes to the search value.
         // matching bytes are set to 0xff, non-matching bytes are set to 0x00.
-        for (int i = 0; i < nValues; i++) {
-            for (int j = 0; j < nVectors; j++) {
-                emitVectorCompareInst(asm, kind, vectorSize, vecArray[(i * nVectors) + j], vecCmp[i]);
+        if (!findTwoConsecutive) {
+            for (int i = 0; i < nVectors; i++) {
+                int base = i * nValues;
+                for (int j = 0; j < nValues; j++) {
+                    emitVectorCompareInst(asm, kind, getVectorSize(), vecArray[base + j], vecCmp[j]);
+                    if ((j & 1) == 1) {
+                        emitPOR(asm, getVectorSize(), vecArray[base + j - 1], vecArray[base + j]);
+                    }
+                }
+                if (nValues > 2) {
+                    emitPOR(asm, getVectorSize(), vecArray[base], vecArray[base + 2]);
+                }
+                emitMOVMSK(asm, getVectorSize(), cmpResult[0], vecArray[base]);
+                emitJnz(asm, cmpResult[0], vectorFound[nVectors - (i + 1)], shortJmp);
             }
-        }
-        // create 32-bit-masks from the most significant bit of every byte in the comparison
-        // results.
-        for (int i = 0; i < nValues * nVectors; i++) {
-            emitMOVMSK(asm, vectorSize, cmpResult[i], vecArray[i]);
-        }
-        // join results of comparisons against multiple values
-        for (int stride = 1; stride < nValues; stride *= 2) {
-            for (int i = 0; i < nVectors; i++) {
-                for (int j = 0; j + stride < nValues; j += stride * 2) {
-                    asm.orl(cmpResult[i + (j * nVectors)], cmpResult[i + ((j + stride) * nVectors)]);
-                }
+        } else {
+            for (int i = 0; i < nVectors; i += 2) {
+                emitVectorCompareInst(asm, kind, getVectorSize(), vecArray[i], vecCmp[0]);
+                emitVectorCompareInst(asm, kind, getVectorSize(), vecArray[i + 1], vecCmp[0]);
+                emitMOVMSK(asm, getVectorSize(), cmpResult[1], vecArray[i]);
+                emitMOVMSK(asm, getVectorSize(), cmpResult[0], vecArray[i + 1]);
+                emitJnz(asm, cmpResult[1], vectorFound[nVectors - (i + 1)], shortJmp);
+                emitJnz(asm, cmpResult[0], vectorFound[nVectors - (i + 2)], shortJmp);
             }
         }
-        // check if a match was found
-        for (int i = 0; i < nVectors; i++) {
-            asm.testl(cmpResult[i], cmpResult[i]);
-            asm.jcc(AMD64Assembler.ConditionFlag.NotZero, vectorFound[i]);
-        }
     }
 
-    private static void emitVectorFoundWithOffset(AMD64MacroAssembler asm,
-                    JavaKind kind,
-                    int resultOffset,
-                    Register result,
-                    Register cmpResult,
-                    Register slotsRemaining,
-                    Label entry,
-                    Label ret) {
-        asm.bind(entry);
-        if (resultOffset > 0) {
-            // adjust array pointer
-            asm.addq(result, resultOffset);
-            // adjust number of array slots remaining
-            asm.subl(slotsRemaining, charMode(kind) ? resultOffset / 2 : resultOffset);
+    private static void emitJnz(AMD64MacroAssembler asm, Register cond, Label tgt, boolean shortJmp) {
+        asm.testl(cond, cond);
+        if (shortJmp) {
+            asm.jccb(AMD64Assembler.ConditionFlag.NotZero, tgt);
+        } else {
+            asm.jcc(AMD64Assembler.ConditionFlag.NotZero, tgt);
         }
-        // find index of first set bit in bit mask
-        asm.bsfq(cmpResult, cmpResult);
-        // add offset to array pointer
-        asm.addq(result, cmpResult);
-        if (charMode(kind)) {
-            // convert byte offset to chars
-            asm.shrl(cmpResult, 1);
-        }
-        // adjust number of array slots remaining
-        asm.subl(slotsRemaining, cmpResult);
-        asm.jmpb(ret);
     }
 
-    private static void emitArrayLoad(AMD64MacroAssembler asm, AVXKind.AVXSize vectorSize, Register vecDst, Register arrayPtr, int offset, boolean alignedLoad) {
-        AMD64Address src = new AMD64Address(arrayPtr, offset);
+    private void emitArrayLoad(AMD64MacroAssembler asm, AVXKind.AVXSize vectorSize, Register vecDst, Register arrayPtr, Register index, int offset, boolean alignedLoad) {
+        AMD64Address src = new AMD64Address(arrayPtr, index, arrayIndexScale, offset);
         if (asm.supports(CPUFeature.AVX)) {
             VexMoveOp loadOp = alignedLoad ? VexMoveOp.VMOVDQA : VexMoveOp.VMOVDQU;
             loadOp.emit(asm, vectorSize, vecDst, src);
@@ -621,6 +605,15 @@
         }
     }
 
+    private static void emitPOR(AMD64MacroAssembler asm, AVXKind.AVXSize vectorSize, Register dst, Register vecSrc) {
+        if (asm.supports(CPUFeature.AVX)) {
+            VexRVMOp.VPOR.emit(asm, vectorSize, dst, dst, vecSrc);
+        } else {
+            // SSE
+            asm.por(dst, vecSrc);
+        }
+    }
+
     private static void emitMOVMSK(AMD64MacroAssembler asm, AVXKind.AVXSize vectorSize, Register dst, Register vecSrc) {
         if (asm.supports(CPUFeature.AVX)) {
             VexRMOp.VPMOVMSKB.emit(asm, vectorSize, dst, vecSrc);
@@ -630,20 +623,17 @@
         }
     }
 
-    private static void emitCompareInst(AMD64MacroAssembler asm, JavaKind kind, Register dst, Register src) {
+    private static OperandSize getOpSize(JavaKind kind) {
         switch (kind) {
             case Byte:
-                asm.cmpb(dst, src);
-                break;
+                return OperandSize.BYTE;
             case Short:
             case Char:
-                asm.cmpw(dst, src);
-                break;
+                return OperandSize.WORD;
             case Int:
-                asm.cmpl(dst, src);
-                break;
+                return OperandSize.DWORD;
             default:
-                asm.cmpq(dst, src);
+                return OperandSize.QWORD;
         }
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/BailoutAndRestartBackendException.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/BailoutAndRestartBackendException.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,24 +25,12 @@
 package org.graalvm.compiler.lir;
 
 import org.graalvm.compiler.core.common.PermanentBailoutException;
-import org.graalvm.compiler.options.Option;
-import org.graalvm.compiler.options.OptionKey;
-import org.graalvm.compiler.options.OptionType;
 
 /**
  * Restarts the {@link LIR low-level} compilation with a modified configuration.
- * {@link BailoutAndRestartBackendException.Options#LIRUnlockBackendRestart LIRUnlockBackendRestart}
- * needs to be enabled. Use only for debugging purposes only.
  */
 public abstract class BailoutAndRestartBackendException extends PermanentBailoutException {
 
-    public static class Options {
-        // @formatter:off
-        @Option(help = "Unlock backend restart feature.", type = OptionType.Debug)
-        public static final OptionKey<Boolean> LIRUnlockBackendRestart = new OptionKey<>(false);
-        // @formatter:on
-    }
-
     private static final long serialVersionUID = 792969002851591180L;
 
     public BailoutAndRestartBackendException(String msg) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/LIR.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/LIR.java	Mon Jul 01 14:57:02 2019 -0700
@@ -34,8 +34,8 @@
 import org.graalvm.compiler.core.common.cfg.BlockMap;
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.lir.StandardOp.BlockEndOp;
+import org.graalvm.compiler.lir.StandardOp.LabelHoldingOp;
 import org.graalvm.compiler.lir.StandardOp.LabelOp;
-import org.graalvm.compiler.lir.StandardOp.LabelHoldingOp;
 import org.graalvm.compiler.lir.gen.LIRGenerator;
 import org.graalvm.compiler.options.OptionValues;
 
@@ -72,7 +72,11 @@
     /**
      * Creates a new LIR instance for the specified compilation.
      */
-    public LIR(AbstractControlFlowGraph<?> cfg, AbstractBlockBase<?>[] linearScanOrder, AbstractBlockBase<?>[] codeEmittingOrder, OptionValues options, DebugContext debug) {
+    public LIR(AbstractControlFlowGraph<?> cfg,
+                    AbstractBlockBase<?>[] linearScanOrder,
+                    AbstractBlockBase<?>[] codeEmittingOrder,
+                    OptionValues options,
+                    DebugContext debug) {
         this.cfg = cfg;
         this.codeEmittingOrder = codeEmittingOrder;
         this.linearScanOrder = linearScanOrder;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/dfa/LocationMarkerPhase.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/dfa/LocationMarkerPhase.java	Mon Jul 01 14:57:02 2019 -0700
@@ -37,14 +37,15 @@
 import org.graalvm.compiler.lir.gen.LIRGenerationResult;
 import org.graalvm.compiler.lir.phases.AllocationPhase;
 
+import jdk.vm.ci.code.ReferenceMap;
 import jdk.vm.ci.code.Register;
 import jdk.vm.ci.code.RegisterAttributes;
 import jdk.vm.ci.code.TargetDescription;
 import jdk.vm.ci.meta.Value;
 
 /**
- * Mark all live references for a frame state. The frame state use this information to build the OOP
- * maps.
+ * Mark all live references for a frame state. The frame state uses this information to build the
+ * {@link ReferenceMap}s.
  */
 public final class LocationMarkerPhase extends AllocationPhase {
 
@@ -93,7 +94,6 @@
             }
 
             ReferenceMapBuilder refMap = frameMap.newReferenceMapBuilder();
-            frameMap.addLiveValues(refMap);
             values.addLiveValues(refMap);
 
             info.debugInfo().setReferenceMap(refMap.finish(info));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/framemap/FrameMap.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/framemap/FrameMap.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,13 +24,9 @@
 
 package org.graalvm.compiler.lir.framemap;
 
-import java.util.ArrayList;
-import java.util.BitSet;
-import java.util.List;
-
+import org.graalvm.compiler.core.common.LIRKind;
 import org.graalvm.compiler.core.common.NumUtil;
 import org.graalvm.compiler.core.common.PermanentBailoutException;
-import org.graalvm.compiler.core.common.LIRKind;
 
 import jdk.vm.ci.code.Architecture;
 import jdk.vm.ci.code.CallingConvention;
@@ -38,14 +34,13 @@
 import jdk.vm.ci.code.RegisterConfig;
 import jdk.vm.ci.code.StackSlot;
 import jdk.vm.ci.code.TargetDescription;
-import jdk.vm.ci.meta.Value;
 import jdk.vm.ci.meta.ValueKind;
 
 /**
  * This class is used to build the stack frame layout for a compiled method. A {@link StackSlot} is
  * used to index slots of the frame relative to the stack pointer. The frame size is only fixed
  * after register allocation when all spill slots have been allocated. Both the outgoing argument
- * area and the spill are can grow until then. Therefore, outgoing arguments are indexed from the
+ * area and the spill area can grow until then. Therefore, outgoing arguments are indexed from the
  * stack pointer, while spill slots are indexed from the beginning of the frame (and the total frame
  * size has to be added to get the actual offset from the stack pointer).
  */
@@ -91,11 +86,6 @@
     protected boolean hasOutgoingStackArguments;
 
     /**
-     * The list of stack slots allocated in this frame that are present in every reference map.
-     */
-    private final List<StackSlot> objectStackSlots;
-
-    /**
      * Records whether an offset to an incoming stack argument was ever returned by
      * {@link #offsetForStackSlot(StackSlot)}.
      */
@@ -110,7 +100,6 @@
         this.registerConfig = registerConfig == null ? codeCache.getRegisterConfig() : registerConfig;
         this.frameSize = -1;
         this.outgoingSize = codeCache.getMinimumOutgoingSize();
-        this.objectStackSlots = new ArrayList<>();
         this.referenceMapFactory = referenceMapFactory;
     }
 
@@ -122,12 +111,6 @@
         return target;
     }
 
-    public void addLiveValues(ReferenceMapBuilder refMap) {
-        for (Value value : objectStackSlots) {
-            refMap.addLiveValue(value);
-        }
-    }
-
     protected int returnAddressSize() {
         return getTarget().arch.getReturnAddressSize();
     }
@@ -235,19 +218,6 @@
     }
 
     /**
-     * Reserves a new spill slot in the frame of the method being compiled. The returned slot is
-     * aligned on its natural alignment, i.e., an 8-byte spill slot is aligned at an 8-byte
-     * boundary.
-     *
-     * @param kind The kind of the spill slot to be reserved.
-     * @param additionalOffset
-     * @return A spill slot denoting the reserved memory area.
-     */
-    protected StackSlot allocateNewSpillSlot(ValueKind<?> kind, int additionalOffset) {
-        return StackSlot.get(kind, -spillSize + additionalOffset, true);
-    }
-
-    /**
      * Returns the spill slot size for the given {@link ValueKind}. The default value is the size in
      * bytes for the target architecture.
      *
@@ -270,7 +240,11 @@
         assert frameSize == -1 : "frame size must not yet be fixed";
         int size = spillSlotSize(kind);
         spillSize = NumUtil.roundUp(spillSize + size, size);
-        return allocateNewSpillSlot(kind, 0);
+        return newStackSlot(kind);
+    }
+
+    private StackSlot newStackSlot(ValueKind<?> kind) {
+        return StackSlot.get(kind, -spillSize, true);
     }
 
     /**
@@ -288,46 +262,15 @@
      * requested number of slots is 0, this method returns {@code null}.
      *
      * @param slots the number of slots to reserve
-     * @param objects specifies the indexes of the object pointer slots. The caller is responsible
-     *            for guaranteeing that each such object pointer slot is initialized before any
-     *            instruction that uses a reference map. Without this guarantee, the garbage
-     *            collector could see garbage object values.
      * @return the first reserved stack slot (i.e., at the lowest address)
      */
-    public StackSlot allocateStackSlots(int slots, BitSet objects) {
+    public StackSlot allocateStackSlots(int slots) {
         assert frameSize == -1 : "frame size must not yet be fixed";
         if (slots == 0) {
             return null;
         }
-        spillSize += spillSlotRangeSize(slots);
-
-        if (!objects.isEmpty()) {
-            assert objects.length() <= slots;
-            StackSlot result = null;
-            for (int slotIndex = 0; slotIndex < slots; slotIndex++) {
-                StackSlot objectSlot = null;
-                if (objects.get(slotIndex)) {
-                    objectSlot = allocateNewSpillSlot(LIRKind.reference(getTarget().arch.getWordKind()), slotIndex * getTarget().wordSize);
-                    addObjectStackSlot(objectSlot);
-                }
-                if (slotIndex == 0) {
-                    if (objectSlot != null) {
-                        result = objectSlot;
-                    } else {
-                        result = allocateNewSpillSlot(LIRKind.value(getTarget().arch.getWordKind()), 0);
-                    }
-                }
-            }
-            assert result != null;
-            return result;
-
-        } else {
-            return allocateNewSpillSlot(LIRKind.value(getTarget().arch.getWordKind()), 0);
-        }
-    }
-
-    protected void addObjectStackSlot(StackSlot objectSlot) {
-        objectStackSlots.add(objectSlot);
+        spillSize = NumUtil.roundUp(spillSize + spillSlotRangeSize(slots), getTarget().wordSize);
+        return newStackSlot(LIRKind.value(getTarget().arch.getWordKind()));
     }
 
     public ReferenceMapBuilder newReferenceMapBuilder() {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/framemap/FrameMapBuilder.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/framemap/FrameMapBuilder.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,9 +24,6 @@
 
 package org.graalvm.compiler.lir.framemap;
 
-import java.util.BitSet;
-import java.util.List;
-
 import org.graalvm.compiler.lir.VirtualStackSlot;
 import org.graalvm.compiler.lir.gen.LIRGenerationResult;
 
@@ -56,15 +53,9 @@
      * requested number of slots is 0, this method returns {@code null}.
      *
      * @param slots the number of slots to reserve
-     * @param objects specifies the indexes of the object pointer slots. The caller is responsible
-     *            for guaranteeing that each such object pointer slot is initialized before any
-     *            instruction that uses a reference map. Without this guarantee, the garbage
-     *            collector could see garbage object values.
-     * @param outObjectStackSlots if non-null, the object pointer slots allocated are added to this
-     *            list
      * @return the first reserved stack slot (i.e., at the lowest address)
      */
-    public abstract VirtualStackSlot allocateStackSlots(int slots, BitSet objects, List<VirtualStackSlot> outObjectStackSlots);
+    public abstract VirtualStackSlot allocateStackSlots(int slots);
 
     public abstract RegisterConfig getRegisterConfig();
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/framemap/FrameMapBuilderImpl.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/framemap/FrameMapBuilderImpl.java	Mon Jul 01 14:57:02 2019 -0700
@@ -27,14 +27,12 @@
 import static org.graalvm.compiler.lir.LIRValueUtil.isVirtualStackSlot;
 
 import java.util.ArrayList;
-import java.util.BitSet;
 import java.util.EnumSet;
 import java.util.List;
 
 import org.graalvm.compiler.core.common.LIRKind;
 import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
 import org.graalvm.compiler.debug.DebugContext;
-import org.graalvm.compiler.debug.GraalError;
 import org.graalvm.compiler.lir.InstructionValueConsumer;
 import org.graalvm.compiler.lir.LIR;
 import org.graalvm.compiler.lir.LIRInstruction;
@@ -46,7 +44,6 @@
 import jdk.vm.ci.code.CallingConvention;
 import jdk.vm.ci.code.CodeCacheProvider;
 import jdk.vm.ci.code.RegisterConfig;
-import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.Value;
 import jdk.vm.ci.meta.ValueKind;
 
@@ -80,14 +77,11 @@
     }
 
     @Override
-    public VirtualStackSlot allocateStackSlots(int slots, BitSet objects, List<VirtualStackSlot> outObjectStackSlots) {
+    public VirtualStackSlot allocateStackSlots(int slots) {
         if (slots == 0) {
             return null;
         }
-        if (outObjectStackSlots != null) {
-            throw GraalError.unimplemented();
-        }
-        VirtualStackSlotRange slot = new VirtualStackSlotRange(numStackSlots++, slots, objects, LIRKind.fromJavaKind(frameMap.getTarget().arch, JavaKind.Object));
+        VirtualStackSlotRange slot = new VirtualStackSlotRange(numStackSlots++, slots, LIRKind.value(frameMap.getTarget().arch.getWordKind()));
         stackSlots.add(slot);
         return slot;
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/framemap/VirtualStackSlotRange.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/framemap/VirtualStackSlotRange.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,8 +24,6 @@
 
 package org.graalvm.compiler.lir.framemap;
 
-import java.util.BitSet;
-
 import org.graalvm.compiler.core.common.LIRKind;
 import org.graalvm.compiler.lir.VirtualStackSlot;
 
@@ -37,21 +35,14 @@
  */
 public class VirtualStackSlotRange extends VirtualStackSlot {
 
-    private final BitSet objects;
     private final int slots;
 
-    public VirtualStackSlotRange(int id, int slots, BitSet objects, LIRKind kind) {
+    public VirtualStackSlotRange(int id, int slots, LIRKind kind) {
         super(id, kind);
         this.slots = slots;
-        this.objects = (BitSet) objects.clone();
     }
 
     public int getSlots() {
         return slots;
     }
-
-    public BitSet getObjects() {
-        return (BitSet) objects.clone();
-    }
-
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/LIRGeneratorTool.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/LIRGeneratorTool.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,9 +24,6 @@
 
 package org.graalvm.compiler.lir.gen;
 
-import java.util.BitSet;
-import java.util.List;
-
 import org.graalvm.compiler.core.common.CompressEncoding;
 import org.graalvm.compiler.core.common.LIRKind;
 import org.graalvm.compiler.core.common.calc.Condition;
@@ -274,7 +271,7 @@
     }
 
     @SuppressWarnings("unused")
-    default Variable emitArrayIndexOf(JavaKind kind, boolean findTwoConsecutive, Value sourcePointer, Value sourceCount, Value... searchValues) {
+    default Variable emitArrayIndexOf(JavaKind arrayKind, JavaKind valueKind, boolean findTwoConsecutive, Value sourcePointer, Value sourceCount, Value fromIndex, Value... searchValues) {
         throw GraalError.unimplemented("String.indexOf substitution is not implemented on this architecture");
     }
 
@@ -324,8 +321,8 @@
      */
     void emitSpeculationFence();
 
-    default VirtualStackSlot allocateStackSlots(int slots, BitSet objects, List<VirtualStackSlot> outObjectStackSlots) {
-        return getResult().getFrameMapBuilder().allocateStackSlots(slots, objects, outObjectStackSlots);
+    default VirtualStackSlot allocateStackSlots(int slots) {
+        return getResult().getFrameMapBuilder().allocateStackSlots(slots);
     }
 
     default Value emitReadCallerStackPointer(Stamp wordStamp) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/stackslotalloc/LSStackSlotAllocator.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/stackslotalloc/LSStackSlotAllocator.java	Mon Jul 01 14:57:02 2019 -0700
@@ -33,11 +33,12 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Deque;
-import java.util.EnumMap;
 import java.util.EnumSet;
 import java.util.PriorityQueue;
+import java.util.function.Predicate;
 
 import jdk.internal.vm.compiler.collections.EconomicSet;
+import org.graalvm.compiler.core.common.LIRKind;
 import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
 import org.graalvm.compiler.debug.DebugCloseable;
 import org.graalvm.compiler.debug.DebugContext;
@@ -49,6 +50,7 @@
 import org.graalvm.compiler.lir.LIRInstruction.OperandMode;
 import org.graalvm.compiler.lir.ValueProcedure;
 import org.graalvm.compiler.lir.VirtualStackSlot;
+import org.graalvm.compiler.lir.framemap.FrameMap;
 import org.graalvm.compiler.lir.framemap.FrameMapBuilderTool;
 import org.graalvm.compiler.lir.framemap.SimpleVirtualStackSlot;
 import org.graalvm.compiler.lir.framemap.VirtualStackSlotRange;
@@ -58,6 +60,7 @@
 import org.graalvm.compiler.options.Option;
 import org.graalvm.compiler.options.OptionType;
 
+import jdk.vm.ci.code.CodeUtil;
 import jdk.vm.ci.code.StackSlot;
 import jdk.vm.ci.code.TargetDescription;
 import jdk.vm.ci.meta.Value;
@@ -156,7 +159,15 @@
             }
             // step 4: allocate stack slots
             try (DebugCloseable t = AllocateSlotsTimer.start(debug)) {
-                allocateStackSlots();
+                /*
+                 * Allocate primitive spill slots before reference spill slots. This ensures a
+                 * ReferenceMap will be as compact as possible and only exceed the encoding limit of
+                 * a stack offset if there are really too many objects live on the stack at an
+                 * instruction with a ReferenceMap (as opposed to the method simply having a very
+                 * large frame).
+                 */
+                allocateStackSlots(IS_PRIMITIVE_INTERVAL);
+                allocateStackSlots(IS_REFERENCE_INTERVAL);
             }
             if (debug.isDumpEnabled(DebugContext.VERBOSE_LEVEL)) {
                 dumpIntervals("After stack slot allocation");
@@ -226,29 +237,44 @@
         // ====================
 
         @SuppressWarnings("try")
-        private void allocateStackSlots() {
-            // create unhandled lists
+        private void allocateStackSlots(Predicate<StackInterval> predicate) {
             for (StackInterval interval : stackSlotMap) {
-                if (interval != null) {
+                if (interval != null && (predicate == null || predicate.test(interval))) {
                     unhandled.add(interval);
                 }
             }
-
             for (StackInterval current = activateNext(); current != null; current = activateNext()) {
                 try (Indent indent = debug.logAndIndent("allocate %s", current)) {
                     allocateSlot(current);
                 }
             }
 
+            // Cannot re-use free slots between rounds of slot allocation
+            freeSlots = null;
+            active.clear();
         }
 
+        private static final Predicate<StackInterval> IS_REFERENCE_INTERVAL = new Predicate<StackInterval>() {
+            @Override
+            public boolean test(StackInterval interval) {
+                return !((LIRKind) interval.kind()).isValue();
+            }
+        };
+
+        private static final Predicate<StackInterval> IS_PRIMITIVE_INTERVAL = new Predicate<StackInterval>() {
+            @Override
+            public boolean test(StackInterval interval) {
+                return ((LIRKind) interval.kind()).isValue();
+            }
+        };
+
         private void allocateSlot(StackInterval current) {
             VirtualStackSlot virtualSlot = current.getOperand();
             final StackSlot location;
             if (virtualSlot instanceof VirtualStackSlotRange) {
                 // No reuse of ranges (yet).
                 VirtualStackSlotRange slotRange = (VirtualStackSlotRange) virtualSlot;
-                location = frameMapBuilder.getFrameMap().allocateStackSlots(slotRange.getSlots(), slotRange.getObjects());
+                location = frameMapBuilder.getFrameMap().allocateStackSlots(slotRange.getSlots());
                 StackSlotAllocatorUtil.virtualFramesize.add(debug, frameMapBuilder.getFrameMap().spillSlotRangeSize(slotRange.getSlots()));
                 StackSlotAllocatorUtil.allocatedSlots.increment(debug);
             } else {
@@ -274,59 +300,44 @@
             current.setLocation(location);
         }
 
-        private enum SlotSize {
-            Size1,
-            Size2,
-            Size4,
-            Size8,
-            Illegal;
-        }
-
-        private SlotSize forKind(ValueKind<?> kind) {
-            switch (frameMapBuilder.getFrameMap().spillSlotSize(kind)) {
-                case 1:
-                    return SlotSize.Size1;
-                case 2:
-                    return SlotSize.Size2;
-                case 4:
-                    return SlotSize.Size4;
-                case 8:
-                    return SlotSize.Size8;
-                default:
-                    return SlotSize.Illegal;
-            }
-        }
-
-        private EnumMap<SlotSize, Deque<StackSlot>> freeSlots;
+        /**
+         * Map from log2 of {@link FrameMap#spillSlotSize(ValueKind) a spill slot size} to a list of
+         * free stack slots.
+         */
+        private ArrayList<Deque<StackSlot>> freeSlots;
 
         /**
-         * @return The list of free stack slots for {@code size} or {@code null} if there is none.
+         * @return The list of free stack slots for {@code index} or {@code null} if there is none.
          */
-        private Deque<StackSlot> getOrNullFreeSlots(SlotSize size) {
+        private Deque<StackSlot> getNullOrFreeSlots(int index) {
             if (freeSlots == null) {
                 return null;
             }
-            return freeSlots.get(size);
+            if (index < freeSlots.size()) {
+                return freeSlots.get(index);
+            }
+            return null;
         }
 
         /**
-         * @return the list of free stack slots for {@code size}. If there is none a list is
+         * @return the list of free stack slots for {@code index}. If there is none a list is
          *         created.
          */
-        private Deque<StackSlot> getOrInitFreeSlots(SlotSize size) {
-            assert size != SlotSize.Illegal;
-            Deque<StackSlot> freeList;
-            if (freeSlots != null) {
-                freeList = freeSlots.get(size);
-            } else {
-                freeSlots = new EnumMap<>(SlotSize.class);
-                freeList = null;
+        private Deque<StackSlot> getOrInitFreeSlots(int index) {
+            Deque<StackSlot> freeList = null;
+            if (freeSlots == null) {
+                freeSlots = new ArrayList<>(6);
+            } else if (index < freeSlots.size()) {
+                freeList = freeSlots.get(index);
             }
             if (freeList == null) {
+                int requiredSize = index + 1;
+                for (int i = freeSlots.size(); i < requiredSize; i++) {
+                    freeSlots.add(null);
+                }
                 freeList = new ArrayDeque<>();
-                freeSlots.put(size, freeList);
+                freeSlots.set(index, freeList);
             }
-            assert freeList != null;
             return freeList;
         }
 
@@ -335,11 +346,8 @@
          */
         private StackSlot findFreeSlot(SimpleVirtualStackSlot slot) {
             assert slot != null;
-            SlotSize size = forKind(slot.getValueKind());
-            if (size == SlotSize.Illegal) {
-                return null;
-            }
-            Deque<StackSlot> freeList = getOrNullFreeSlots(size);
+            int size = log2SpillSlotSize(slot.getValueKind());
+            Deque<StackSlot> freeList = getNullOrFreeSlots(size);
             if (freeList == null) {
                 return null;
             }
@@ -350,13 +358,16 @@
          * Adds a stack slot to the list of free slots.
          */
         private void freeSlot(StackSlot slot) {
-            SlotSize size = forKind(slot.getValueKind());
-            if (size == SlotSize.Illegal) {
-                return;
-            }
+            int size = log2SpillSlotSize(slot.getValueKind());
             getOrInitFreeSlots(size).addLast(slot);
         }
 
+        private int log2SpillSlotSize(ValueKind<?> kind) {
+            int size = frameMapBuilder.getFrameMap().spillSlotSize(kind);
+            assert CodeUtil.isPowerOf2(size);
+            return CodeUtil.log2(size);
+        }
+
         /**
          * Gets the next unhandled interval and finishes handled intervals.
          */
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/stackslotalloc/SimpleStackSlotAllocator.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/stackslotalloc/SimpleStackSlotAllocator.java	Mon Jul 01 14:57:02 2019 -0700
@@ -113,6 +113,6 @@
     }
 
     protected StackSlot mapVirtualStackSlotRange(FrameMapBuilderTool builder, VirtualStackSlotRange virtualStackSlot) {
-        return builder.getFrameMap().allocateStackSlots(virtualStackSlot.getSlots(), virtualStackSlot.getObjects());
+        return builder.getFrameMap().allocateStackSlots(virtualStackSlot.getSlots());
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop.phases/src/org/graalvm/compiler/loop/phases/ContextlessLoopPhase.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop.phases/src/org/graalvm/compiler/loop/phases/ContextlessLoopPhase.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,7 +26,7 @@
 
 import org.graalvm.compiler.loop.LoopPolicies;
 import org.graalvm.compiler.nodes.StructuredGraph;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 
 public abstract class ContextlessLoopPhase<P extends LoopPolicies> extends LoopPhase<P> {
 
@@ -45,7 +45,7 @@
     protected abstract void run(StructuredGraph graph);
 
     @Override
-    protected final void run(StructuredGraph graph, PhaseContext context) {
+    protected final void run(StructuredGraph graph, CoreProviders context) {
         run(graph);
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop.phases/src/org/graalvm/compiler/loop/phases/ConvertDeoptimizeToGuardPhase.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop.phases/src/org/graalvm/compiler/loop/phases/ConvertDeoptimizeToGuardPhase.java	Mon Jul 01 14:57:02 2019 -0700
@@ -59,12 +59,12 @@
 import org.graalvm.compiler.nodes.ValuePhiNode;
 import org.graalvm.compiler.nodes.calc.CompareNode;
 import org.graalvm.compiler.nodes.cfg.Block;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.nodes.spi.LoweringProvider;
 import org.graalvm.compiler.nodes.util.GraphUtil;
 import org.graalvm.compiler.phases.BasePhase;
 import org.graalvm.compiler.phases.common.DeadCodeEliminationPhase;
 import org.graalvm.compiler.phases.common.LazyValue;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 
 import jdk.vm.ci.meta.Constant;
 import jdk.vm.ci.meta.DeoptimizationAction;
@@ -81,10 +81,10 @@
  * {@link DeoptimizeNode} as close to the {@link ControlSplitNode} as possible.
  *
  */
-public class ConvertDeoptimizeToGuardPhase extends BasePhase<PhaseContext> {
+public class ConvertDeoptimizeToGuardPhase extends BasePhase<CoreProviders> {
     @Override
     @SuppressWarnings("try")
-    protected void run(final StructuredGraph graph, PhaseContext context) {
+    protected void run(final StructuredGraph graph, CoreProviders context) {
         assert graph.hasValueProxies() : "ConvertDeoptimizeToGuardPhase always creates proxies";
         assert !graph.getGuardsStage().areFrameStatesAtDeopts() : graph.getGuardsStage();
         LazyValue<LoopsData> lazyLoops = new LazyValue<>(() -> new LoopsData(graph));
@@ -110,7 +110,7 @@
         new DeadCodeEliminationPhase(Optional).apply(graph);
     }
 
-    private static void trySplitFixedGuard(FixedGuardNode fixedGuard, PhaseContext context, LazyValue<LoopsData> lazyLoops) {
+    private static void trySplitFixedGuard(FixedGuardNode fixedGuard, CoreProviders context, LazyValue<LoopsData> lazyLoops) {
         LogicNode condition = fixedGuard.condition();
         if (condition instanceof CompareNode) {
             CompareNode compare = (CompareNode) condition;
@@ -126,7 +126,7 @@
         }
     }
 
-    private static void processFixedGuardAndPhis(FixedGuardNode fixedGuard, PhaseContext context, CompareNode compare, ValueNode x, ValuePhiNode xPhi, ValueNode y, ValuePhiNode yPhi,
+    private static void processFixedGuardAndPhis(FixedGuardNode fixedGuard, CoreProviders context, CompareNode compare, ValueNode x, ValuePhiNode xPhi, ValueNode y, ValuePhiNode yPhi,
                     LazyValue<LoopsData> lazyLoops) {
         AbstractBeginNode pred = AbstractBeginNode.prevBegin(fixedGuard);
         if (pred instanceof AbstractMergeNode) {
@@ -143,7 +143,7 @@
     }
 
     @SuppressWarnings("try")
-    private static void processFixedGuardAndMerge(FixedGuardNode fixedGuard, PhaseContext context, CompareNode compare, ValueNode x, ValuePhiNode xPhi, ValueNode y, ValuePhiNode yPhi,
+    private static void processFixedGuardAndMerge(FixedGuardNode fixedGuard, CoreProviders context, CompareNode compare, ValueNode x, ValuePhiNode xPhi, ValueNode y, ValuePhiNode yPhi,
                     AbstractMergeNode merge, LazyValue<LoopsData> lazyLoops) {
         List<EndNode> mergePredecessors = merge.cfgPredecessors().snapshot();
         for (AbstractEndNode mergePredecessor : mergePredecessors) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop.phases/src/org/graalvm/compiler/loop/phases/LoopFullUnrollPhase.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop.phases/src/org/graalvm/compiler/loop/phases/LoopFullUnrollPhase.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,14 +24,15 @@
 
 package org.graalvm.compiler.loop.phases;
 
+import org.graalvm.compiler.core.common.GraalOptions;
 import org.graalvm.compiler.debug.CounterKey;
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.loop.LoopEx;
 import org.graalvm.compiler.loop.LoopPolicies;
 import org.graalvm.compiler.loop.LoopsData;
 import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 
 public class LoopFullUnrollPhase extends LoopPhase<LoopPolicies> {
 
@@ -44,26 +45,28 @@
     }
 
     @Override
-    protected void run(StructuredGraph graph, PhaseContext context) {
-        DebugContext debug = graph.getDebug();
-        if (graph.hasLoops()) {
-            boolean peeled;
-            do {
-                peeled = false;
-                final LoopsData dataCounted = new LoopsData(graph);
-                dataCounted.detectedCountedLoops();
-                for (LoopEx loop : dataCounted.countedLoops()) {
-                    if (getPolicies().shouldFullUnroll(loop)) {
-                        debug.log("FullUnroll %s", loop);
-                        LoopTransformations.fullUnroll(loop, context, canonicalizer);
-                        FULLY_UNROLLED_LOOPS.increment(debug);
-                        debug.dump(DebugContext.DETAILED_LEVEL, graph, "FullUnroll %s", loop);
-                        peeled = true;
-                        break;
+    protected void run(StructuredGraph graph, CoreProviders context) {
+        if (GraalOptions.FullUnroll.getValue(graph.getOptions())) {
+            DebugContext debug = graph.getDebug();
+            if (graph.hasLoops()) {
+                boolean peeled;
+                do {
+                    peeled = false;
+                    final LoopsData dataCounted = new LoopsData(graph);
+                    dataCounted.detectedCountedLoops();
+                    for (LoopEx loop : dataCounted.countedLoops()) {
+                        if (getPolicies().shouldFullUnroll(loop)) {
+                            debug.log("FullUnroll %s", loop);
+                            LoopTransformations.fullUnroll(loop, context, canonicalizer);
+                            FULLY_UNROLLED_LOOPS.increment(debug);
+                            debug.dump(DebugContext.DETAILED_LEVEL, graph, "FullUnroll %s", loop);
+                            peeled = true;
+                            break;
+                        }
                     }
-                }
-                dataCounted.deleteUnusedNodes();
-            } while (peeled);
+                    dataCounted.deleteUnusedNodes();
+                } while (peeled);
+            }
         }
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop.phases/src/org/graalvm/compiler/loop/phases/LoopPartialUnrollPhase.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop.phases/src/org/graalvm/compiler/loop/phases/LoopPartialUnrollPhase.java	Mon Jul 01 14:57:02 2019 -0700
@@ -33,9 +33,9 @@
 import org.graalvm.compiler.nodes.LoopBeginNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.extended.OpaqueNode;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
 import org.graalvm.compiler.phases.common.util.EconomicSetNodeEventListener;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 
 public class LoopPartialUnrollPhase extends LoopPhase<LoopPolicies> {
 
@@ -48,7 +48,7 @@
 
     @Override
     @SuppressWarnings("try")
-    protected void run(StructuredGraph graph, PhaseContext context) {
+    protected void run(StructuredGraph graph, CoreProviders context) {
         if (graph.hasLoops()) {
             EconomicSetNodeEventListener listener = new EconomicSetNodeEventListener();
             boolean changed = true;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop.phases/src/org/graalvm/compiler/loop/phases/LoopPeelingPhase.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop.phases/src/org/graalvm/compiler/loop/phases/LoopPeelingPhase.java	Mon Jul 01 14:57:02 2019 -0700
@@ -29,7 +29,7 @@
 import org.graalvm.compiler.loop.LoopPolicies;
 import org.graalvm.compiler.loop.LoopsData;
 import org.graalvm.compiler.nodes.StructuredGraph;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 
 public class LoopPeelingPhase extends LoopPhase<LoopPolicies> {
 
@@ -39,7 +39,7 @@
 
     @Override
     @SuppressWarnings("try")
-    protected void run(StructuredGraph graph, PhaseContext context) {
+    protected void run(StructuredGraph graph, CoreProviders context) {
         DebugContext debug = graph.getDebug();
         if (graph.hasLoops()) {
             LoopsData data = new LoopsData(graph);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop.phases/src/org/graalvm/compiler/loop/phases/LoopPhase.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop.phases/src/org/graalvm/compiler/loop/phases/LoopPhase.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,10 +25,10 @@
 package org.graalvm.compiler.loop.phases;
 
 import org.graalvm.compiler.loop.LoopPolicies;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.phases.BasePhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 
-public abstract class LoopPhase<P extends LoopPolicies> extends BasePhase<PhaseContext> {
+public abstract class LoopPhase<P extends LoopPolicies> extends BasePhase<CoreProviders> {
     private P policies;
 
     public LoopPhase(P policies) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop.phases/src/org/graalvm/compiler/loop/phases/LoopTransformations.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop.phases/src/org/graalvm/compiler/loop/phases/LoopTransformations.java	Mon Jul 01 14:57:02 2019 -0700
@@ -65,8 +65,8 @@
 import org.graalvm.compiler.nodes.calc.IntegerLessThanNode;
 import org.graalvm.compiler.nodes.extended.OpaqueNode;
 import org.graalvm.compiler.nodes.extended.SwitchNode;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 
 public abstract class LoopTransformations {
 
@@ -79,7 +79,7 @@
         loop.loopBegin().setLoopFrequency(Math.max(0.0, loop.loopBegin().loopFrequency() - 1));
     }
 
-    public static void fullUnroll(LoopEx loop, PhaseContext context, CanonicalizerPhase canonicalizer) {
+    public static void fullUnroll(LoopEx loop, CoreProviders context, CanonicalizerPhase canonicalizer) {
         // assert loop.isCounted(); //TODO (gd) strengthen : counted with known trip count
         LoopBeginNode loopBegin = loop.loopBegin();
         StructuredGraph graph = loopBegin.graph();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop.test/src/org/graalvm/compiler/loop/test/LoopPartialUnrollTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop.test/src/org/graalvm/compiler/loop/test/LoopPartialUnrollTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -62,14 +62,14 @@
 public class LoopPartialUnrollTest extends GraalCompilerTest {
 
     @Override
-    protected boolean checkMidTierGraph(StructuredGraph graph) {
+    protected void checkMidTierGraph(StructuredGraph graph) {
         NodeIterable<LoopBeginNode> loops = graph.getNodes().filter(LoopBeginNode.class);
         for (LoopBeginNode loop : loops) {
             if (loop.isMainLoop()) {
-                return true;
+                return;
             }
         }
-        return false;
+        fail("expected a main loop");
     }
 
     public static long sumWithEqualityLimit(int[] text) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopEx.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopEx.java	Mon Jul 01 14:57:02 2019 -0700
@@ -387,7 +387,7 @@
                 if (loop.isOutsideLoop(op)) {
                     continue;
                 }
-                if (op.usages().count() == 1 && op.usages().first() == baseIvNode) {
+                if (op.hasExactlyOneUsage() && op.usages().first() == baseIvNode) {
                     /*
                      * This is just the base induction variable increment with no other uses so
                      * don't bother reporting it.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.microbenchmarks/src/org/graalvm/compiler/microbenchmarks/graal/ConditionalEliminationBenchmark.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.microbenchmarks/src/org/graalvm/compiler/microbenchmarks/graal/ConditionalEliminationBenchmark.java	Mon Jul 01 14:57:02 2019 -0700
@@ -28,7 +28,6 @@
 import org.graalvm.compiler.microbenchmarks.graal.util.GraphState;
 import org.graalvm.compiler.microbenchmarks.graal.util.MethodSpec;
 import org.graalvm.compiler.phases.common.ConditionalEliminationPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.openjdk.jmh.annotations.Benchmark;
 
 public class ConditionalEliminationBenchmark extends GraalBenchmark {
@@ -109,12 +108,12 @@
 
     @Benchmark
     public void nullness(Nullness s, GraalState g) {
-        new ConditionalEliminationPhase(false).apply(s.graph, new PhaseContext(g.providers));
+        new ConditionalEliminationPhase(false).apply(s.graph, g.providers);
     }
 
     @Benchmark
     public void newDominatorConditionalElimination(Nullness s, GraalState g) {
-        new ConditionalEliminationPhase(false).apply(s.graph, new PhaseContext(g.providers));
+        new ConditionalEliminationPhase(false).apply(s.graph, g.providers);
     }
 
     @MethodSpec(declaringClass = ConditionalEliminationBenchmark.class, name = "searchSnippet")
@@ -165,6 +164,6 @@
 
     @Benchmark
     public void search(Search s, GraalState g) {
-        new ConditionalEliminationPhase(false).apply(s.graph, new PhaseContext(g.providers));
+        new ConditionalEliminationPhase(false).apply(s.graph, g.providers);
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/IfNodeCanonicalizationTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/IfNodeCanonicalizationTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,22 +24,21 @@
 
 package org.graalvm.compiler.nodes.test;
 
-import org.junit.Assert;
-import org.junit.Ignore;
-import org.junit.Test;
-
 import org.graalvm.compiler.api.directives.GraalDirectives;
 import org.graalvm.compiler.core.test.GraalCompilerTest;
 import org.graalvm.compiler.graph.Node;
+import org.graalvm.compiler.loop.phases.ConvertDeoptimizeToGuardPhase;
 import org.graalvm.compiler.nodes.IfNode;
 import org.graalvm.compiler.nodes.LogicNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
 import org.graalvm.compiler.nodes.calc.SubNode;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
-import org.graalvm.compiler.loop.phases.ConvertDeoptimizeToGuardPhase;
 import org.graalvm.compiler.phases.common.IterativeConditionalEliminationPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
+import org.junit.Assert;
+import org.junit.Ignore;
+import org.junit.Test;
 
 /**
  * A few tests of expected simplifications by
@@ -156,7 +155,7 @@
     public void test(String name, Class<? extends Node> expectedClass, int expectedCount) {
         StructuredGraph graph = parseEager(name, AllowAssumptions.YES);
 
-        PhaseContext context = new PhaseContext(getProviders());
+        CoreProviders context = getProviders();
         CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
         new ConvertDeoptimizeToGuardPhase().apply(graph, context);
         graph.clearAllStateAfter();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/LoopPhiCanonicalizerTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/LoopPhiCanonicalizerTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,18 +24,17 @@
 
 package org.graalvm.compiler.nodes.test;
 
-import org.junit.Assert;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
 import org.graalvm.compiler.core.test.GraalCompilerTest;
 import org.graalvm.compiler.graph.iterators.NodePredicate;
 import org.graalvm.compiler.nodes.LoopBeginNode;
 import org.graalvm.compiler.nodes.PhiNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
 
 public class LoopPhiCanonicalizerTest extends GraalCompilerTest {
 
@@ -66,7 +65,7 @@
         StructuredGraph graph = parseEager("loopSnippet", AllowAssumptions.YES);
         NodePredicate loopPhis = node -> node instanceof PhiNode && ((PhiNode) node).merge() instanceof LoopBeginNode;
 
-        PhaseContext context = new PhaseContext(getProviders());
+        CoreProviders context = getProviders();
         Assert.assertEquals(5, graph.getNodes().filter(loopPhis).count());
         new CanonicalizerPhase().apply(graph, context);
         Assert.assertEquals(2, graph.getNodes().filter(loopPhis).count());
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/ShortCircuitOrNodeTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/ShortCircuitOrNodeTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -39,12 +39,12 @@
 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin;
 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins;
 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
 import org.graalvm.compiler.phases.common.FloatingReadPhase;
 import org.graalvm.compiler.phases.common.IncrementalCanonicalizerPhase;
 import org.graalvm.compiler.phases.common.LoweringPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -377,7 +377,7 @@
         for (int i = 1; i <= 64; ++i) {
             String snippet = "testCascadeSnippet" + i;
             StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES);
-            PhaseContext context = new PhaseContext(getProviders());
+            CoreProviders context = getProviders();
             CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
             canonicalizer.apply(graph, context);
             new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/GraphEncoder.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/GraphEncoder.java	Mon Jul 01 14:57:02 2019 -0700
@@ -512,8 +512,8 @@
 
             if (expectedNode instanceof EndNode) {
                 /* Visit the merge node, which is the one and only usage of the EndNode. */
-                assert expectedNode.usages().count() == 1;
-                assert actualNode.usages().count() == 1;
+                assert expectedNode.hasExactlyOneUsage();
+                assert actualNode.hasExactlyOneUsage();
                 verifyNodesEqual(expectedNode.usages(), actualNode.usages(), nodeMapping, workList, false);
             }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/IfNode.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/IfNode.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -40,6 +40,7 @@
 import org.graalvm.compiler.bytecode.Bytes;
 import org.graalvm.compiler.bytecode.ResolvedJavaMethodBytecode;
 import org.graalvm.compiler.core.common.calc.Condition;
+import org.graalvm.compiler.core.common.type.FloatStamp;
 import org.graalvm.compiler.core.common.type.IntegerStamp;
 import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.core.common.type.StampFactory;
@@ -56,6 +57,7 @@
 import org.graalvm.compiler.graph.spi.SimplifierTool;
 import org.graalvm.compiler.nodeinfo.InputType;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.calc.AddNode;
 import org.graalvm.compiler.nodes.calc.CompareNode;
 import org.graalvm.compiler.nodes.calc.ConditionalNode;
 import org.graalvm.compiler.nodes.calc.IntegerBelowNode;
@@ -295,7 +297,8 @@
             return;
         }
 
-        if (falseSuccessor().hasNoUsages() && (!(falseSuccessor() instanceof LoopExitNode)) && falseSuccessor().next() instanceof IfNode) {
+        if (falseSuccessor().hasNoUsages() && (!(falseSuccessor() instanceof LoopExitNode)) && falseSuccessor().next() instanceof IfNode &&
+                        !(((IfNode) falseSuccessor().next()).falseSuccessor() instanceof LoopExitNode)) {
             AbstractBeginNode intermediateBegin = falseSuccessor();
             IfNode nextIf = (IfNode) intermediateBegin.next();
             double probabilityB = (1.0 - this.trueSuccessorProbability) * nextIf.trueSuccessorProbability;
@@ -465,7 +468,7 @@
                 return false;
             }
             MergeNode merge = (MergeNode) trueEnd.merge();
-            if (merge.usages().count() != 1 || merge.phis().count() != 1) {
+            if (!merge.hasExactlyOneUsage() || merge.phis().count() != 1) {
                 return false;
             }
 
@@ -789,6 +792,7 @@
             ValueNode trueValue = trueEnd.result();
             ValueNode falseValue = falseEnd.result();
             ValueNode value = null;
+            boolean needsProxy = false;
             if (trueValue != null) {
                 if (trueValue == falseValue) {
                     value = trueValue;
@@ -797,8 +801,20 @@
                     if (value == null) {
                         return false;
                     }
+                    needsProxy = true;
                 }
             }
+
+            if (trueSuccessor() instanceof LoopExitNode) {
+                LoopBeginNode loopBegin = ((LoopExitNode) trueSuccessor()).loopBegin();
+                assert loopBegin == ((LoopExitNode) falseSuccessor()).loopBegin();
+                LoopExitNode loopExitNode = graph().add(new LoopExitNode(loopBegin));
+                graph().addBeforeFixed(this, loopExitNode);
+                if (graph().hasValueProxies() && needsProxy) {
+                    value = graph().addOrUnique(new ValueProxyNode(value, loopExitNode));
+                }
+            }
+
             ReturnNode newReturn = graph().add(new ReturnNode(value));
             replaceAtPredecessor(newReturn);
             GraphUtil.killCFG(this);
@@ -834,7 +850,7 @@
                  * we can collapse all proxy nodes on one loop exit, the surviving one, which will
                  * be the true successor
                  */
-                if (falseSuccessor.anchored().isEmpty() && falseSuccessor.usages().isNotEmpty()) {
+                if (falseSuccessor.anchored().isEmpty() && falseSuccessor.hasUsages()) {
                     for (Node n : falseSuccessor.usages().snapshot()) {
                         assert n instanceof ProxyNode;
                         ((ProxyNode) n).setProxyPoint((LoopExitNode) trueSuccessor);
@@ -844,7 +860,7 @@
                  * The true successor (surviving loop exit) can have usages, namely proxy nodes, the
                  * false successor however, must not have usages any more after the code above
                  */
-                assert trueSuccessor.anchored().isEmpty() && falseSuccessor.usages().isEmpty();
+                assert trueSuccessor.anchored().isEmpty() && falseSuccessor.hasNoUsages();
                 return this.graph().addOrUnique(new ValueProxyNode(replacement, (LoopExitNode) trueSuccessor));
             }
         }
@@ -947,16 +963,18 @@
             if (constant.isJavaConstant() && conditional.trueValue().isJavaConstant() && conditional.falseValue().isJavaConstant() && condition() instanceof CompareNode &&
                             conditional.condition() instanceof CompareNode) {
 
-                Condition cond1 = ((CompareNode) condition()).condition().asCondition();
+                CompareNode condition1 = (CompareNode) condition();
+                Condition cond1 = condition1.condition().asCondition();
                 if (negateCondition) {
                     cond1 = cond1.negate();
                 }
                 // cond1 is EQ, NE, LT, or GE
-                Condition cond2 = ((CompareNode) conditional.condition()).condition().asCondition();
-                ValueNode x = ((CompareNode) condition()).getX();
-                ValueNode y = ((CompareNode) condition()).getY();
-                ValueNode x2 = ((CompareNode) conditional.condition()).getX();
-                ValueNode y2 = ((CompareNode) conditional.condition()).getY();
+                CompareNode condition2 = (CompareNode) conditional.condition();
+                Condition cond2 = condition2.condition().asCondition();
+                ValueNode x = condition1.getX();
+                ValueNode y = condition1.getY();
+                ValueNode x2 = condition2.getX();
+                ValueNode y2 = condition2.getY();
                 // `x cond1 y ? c1 : (x2 cond2 y2 ? c2 : c3)`
                 boolean sameVars = x == x2 && y == y2;
                 if (!sameVars && x == y2 && y == x2) {
@@ -964,62 +982,89 @@
                     cond2 = cond2.mirror();
                 }
                 if (sameVars) {
+
                     JavaKind stackKind = conditional.trueValue().stamp(NodeView.from(tool)).getStackKind();
                     assert !stackKind.isNumericFloat();
 
-                    ValueNode v1 = constant;
-                    ValueNode v2 = conditional.trueValue();
-                    ValueNode v3 = conditional.falseValue();
+                    long c1 = constant.asJavaConstant().asLong();
+                    long c2 = conditional.trueValue().asJavaConstant().asLong();
+                    long c3 = conditional.falseValue().asJavaConstant().asLong();
 
-                    long c1 = v1.asJavaConstant().asLong();
-                    long c2 = v2.asJavaConstant().asLong();
-                    long c3 = v3.asJavaConstant().asLong();
+                    // canonicalize cond2
+                    cond2 = cond2.join(cond1.negate());
+                    if (cond2 == null) {
+                        // mixing signed and unsigned cases, or useless combination of conditions
+                        return null;
+                    }
+                    // derive cond3 from cond1 and cond2
+                    Condition cond3 = cond1.negate().join(cond2.negate());
+                    if (cond3 == null) {
+                        // mixing signed and unsigned cases, or useless combination of conditions
+                        return null;
+                    }
+                    boolean unsigned = cond1.isUnsigned() || cond2.isUnsigned();
+
+                    long expected1 = expectedConstantForNormalize(cond1);
+                    long expected2 = expectedConstantForNormalize(cond2);
+                    long expected3 = expectedConstantForNormalize(cond3);
 
-                    if (cond1 == Condition.LT && cond2 == Condition.EQ && c1 == -1 && c2 == 0 && c3 == 1) {
-                        // x < y ? -1 : (x == y ? 0 : 1) => x cmp y
-                        return graph().unique(new NormalizeCompareNode(x, y, stackKind, false));
-                    } else if (cond1 == Condition.LT && cond2 == Condition.EQ && c1 == 1 && c2 == 0 && c3 == -1) {
-                        // x < y ? 1 : (x == y ? 0 : -1) => y cmp x
-                        return graph().unique(new NormalizeCompareNode(y, x, stackKind, false));
-                    } else if (cond1 == Condition.EQ && cond2 == Condition.LT && c1 == 0 && c2 == -1 && c3 == 1) {
-                        // x == y ? 0 : (x < y ? -1 : 1) => x cmp y
-                        return graph().unique(new NormalizeCompareNode(x, y, stackKind, false));
-                    } else if (cond1 == Condition.EQ && cond2 == Condition.LT && c1 == 0 && c2 == 1 && c3 == -1) {
-                        // x == y ? 0 : (x < y ? 1 : -1) => y cmp x
-                        return graph().unique(new NormalizeCompareNode(y, x, stackKind, false));
-                    } else if (cond1 == Condition.EQ && cond2 == Condition.GT && c1 == 0 && c2 == -1 && c3 == 1) {
-                        // x == y ? 0 : (x > y ? -1 : 1) => y cmp x
-                        return graph().unique(new NormalizeCompareNode(y, x, stackKind, false));
-                    } else if (cond1 == Condition.EQ && cond2 == Condition.GT && c1 == 0 && c2 == 1 && c3 == -1) {
-                        // x == y ? 0 : (x > y ? 1 : -1) => x cmp y
-                        return graph().unique(new NormalizeCompareNode(x, y, stackKind, false));
-                    } else if (cond1 == Condition.LT && cond2 == Condition.GT && c1 == 1 && c2 == -1 && c3 == 0) {
-                        // x < y ? 1 : (x > y ? -1 : 0) => y cmp x
-                        return graph().unique(new NormalizeCompareNode(y, x, stackKind, false));
-                    } else if (cond1 == Condition.LT && cond2 == Condition.GT && c1 == -1 && c2 == 1 && c3 == 0) {
-                        // x < y ? -1 : (x > y ? 1 : 0) => x cmp y
-                        return graph().unique(new NormalizeCompareNode(x, y, stackKind, false));
+                    if (c1 == expected1 && c2 == expected2 && c3 == expected3) {
+                        // normal order
+                    } else if (c1 == 0 - expected1 && c2 == 0 - expected2 && c3 == 0 - expected3) {
+                        // reverse order
+                        ValueNode tmp = x;
+                        x = y;
+                        y = tmp;
+                    } else {
+                        // cannot be expressed by NormalizeCompareNode
+                        return null;
                     }
+                    if (unsigned) {
+                        // for unsigned comparisons, we need to add MIN_VALUE (see
+                        // Long.compareUnsigned)
+                        ValueNode minValue = graph().unique(ConstantNode.forIntegerStamp(x.stamp,
+                                        x.stamp.getStackKind().getMinValue()));
+                        x = graph().unique(new AddNode(x, minValue));
+                        y = graph().unique(new AddNode(y, minValue));
+                    }
+                    boolean unorderedLess = false;
+                    if (x.stamp instanceof FloatStamp && (((FloatStamp) x.stamp).canBeNaN() || ((FloatStamp) y.stamp).canBeNaN())) {
+                        // we may encounter NaNs, check the unordered value
+                        // (following the original condition's "unorderedIsTrue" path)
+                        long unorderedValue = condition1.unorderedIsTrue() ? c1 : condition2.unorderedIsTrue() ? c2 : c3;
+                        if (unorderedValue == 0) {
+                            // returning "0" for unordered is not possible
+                            return null;
+                        }
+                        unorderedLess = unorderedValue == -1;
+                    }
+                    return graph().unique(new NormalizeCompareNode(x, y, stackKind, unorderedLess));
                 }
             }
         }
         return null;
     }
 
+    private static long expectedConstantForNormalize(Condition condition) {
+        if (condition == Condition.EQ) {
+            return 0;
+        } else if (condition == Condition.LT || condition == Condition.BT) {
+            return -1;
+        } else {
+            assert condition == Condition.GT || condition == Condition.AT;
+            return 1;
+        }
+    }
+
     /**
      * Take an if that is immediately dominated by a merge with a single phi and split off any paths
-     * where the test would be statically decidable creating a new merge below the approriate side
+     * where the test would be statically decidable creating a new merge below the appropriate side
      * of the IfNode. Any undecidable tests will continue to use the original IfNode.
      *
      * @param tool
      */
     @SuppressWarnings("try")
     private boolean splitIfAtPhi(SimplifierTool tool) {
-        if (graph().getGuardsStage().areFrameStatesAtSideEffects()) {
-            // Disabled until we make sure we have no FrameState-less merges at this stage
-            return false;
-        }
-
         if (!(predecessor() instanceof MergeNode)) {
             return false;
         }
@@ -1028,15 +1073,14 @@
             // Don't bother.
             return false;
         }
-        if (merge.usages().count() != 1 || merge.phis().count() != 1) {
+        if (merge.getUsageCount() != 1 || merge.phis().count() != 1) {
             return false;
         }
-        if (merge.stateAfter() != null) {
-            /* We'll get the chance to simplify this after frame state assignment. */
+        if (graph().getGuardsStage().areFrameStatesAtSideEffects() && merge.stateAfter() == null) {
             return false;
         }
         PhiNode phi = merge.phis().first();
-        if (phi.usages().count() != 1) {
+        if (phi.getUsageCount() != 1) {
             /*
              * For simplicity the below code assumes assumes the phi goes dead at the end so skip
              * this case.
@@ -1061,7 +1105,6 @@
         /* Each successor of the if gets a new merge if needed. */
         MergeNode trueMerge = null;
         MergeNode falseMerge = null;
-        assert merge.stateAfter() == null;
 
         for (EndNode end : merge.forwardEnds().snapshot()) {
             Node value = phi.valueAt(end);
@@ -1070,12 +1113,12 @@
                 merge.removeEnd(end);
                 if (((LogicConstantNode) result).getValue()) {
                     if (trueMerge == null) {
-                        trueMerge = insertMerge(trueSuccessor());
+                        trueMerge = insertMerge(trueSuccessor(), merge.stateAfter());
                     }
                     trueMerge.addForwardEnd(end);
                 } else {
                     if (falseMerge == null) {
-                        falseMerge = insertMerge(falseSuccessor());
+                        falseMerge = insertMerge(falseSuccessor(), merge.stateAfter());
                     }
                     falseMerge.addForwardEnd(end);
                 }
@@ -1096,13 +1139,13 @@
                 ((FixedWithNextNode) end.predecessor()).setNext(newIfNode);
 
                 if (trueMerge == null) {
-                    trueMerge = insertMerge(trueSuccessor());
+                    trueMerge = insertMerge(trueSuccessor(), merge.stateAfter());
                 }
                 trueBegin.setNext(graph().add(new EndNode()));
                 trueMerge.addForwardEnd((EndNode) trueBegin.next());
 
                 if (falseMerge == null) {
-                    falseMerge = insertMerge(falseSuccessor());
+                    falseMerge = insertMerge(falseSuccessor(), merge.stateAfter());
                 }
                 falseBegin.setNext(graph().add(new EndNode()));
                 falseMerge.addForwardEnd((EndNode) falseBegin.next());
@@ -1129,7 +1172,7 @@
      *         dead after the optimization.
      */
     private static boolean conditionUses(LogicNode condition, PhiNode phi) {
-        if (condition.usages().count() != 1) {
+        if (!condition.hasExactlyOneUsage()) {
             return false;
         }
         if (condition instanceof ShortCircuitOrNode) {
@@ -1222,7 +1265,7 @@
     }
 
     @SuppressWarnings("try")
-    private MergeNode insertMerge(AbstractBeginNode begin) {
+    private MergeNode insertMerge(AbstractBeginNode begin, FrameState stateAfter) {
         MergeNode merge = graph().add(new MergeNode());
         if (!begin.anchored().isEmpty()) {
             Object before = null;
@@ -1245,6 +1288,7 @@
         next.replaceAtPredecessor(merge);
         theBegin.setNext(graph().add(new EndNode()));
         merge.addForwardEnd((EndNode) theBegin.next());
+        merge.setStateAfter(stateAfter);
         merge.setNext(next);
         return merge;
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/StructuredGraph.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/StructuredGraph.java	Mon Jul 01 14:57:02 2019 -0700
@@ -678,7 +678,7 @@
         if (node instanceof AbstractBeginNode) {
             ((AbstractBeginNode) node).prepareDelete();
         }
-        assert node.hasNoUsages() : node + " " + node.usages().count() + ", " + node.usages().first();
+        assert node.hasNoUsages() : node + " " + node.getUsageCount() + ", " + node.usages().first();
         GraphUtil.unlinkFixedNode(node);
         node.safeDelete();
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ReinterpretNode.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ReinterpretNode.java	Mon Jul 01 14:57:02 2019 -0700
@@ -44,6 +44,7 @@
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.ArithmeticLIRLowerable;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
+import org.graalvm.compiler.serviceprovider.BufferUtil;
 
 import jdk.vm.ci.code.CodeUtil;
 import jdk.vm.ci.meta.JavaKind;
@@ -83,7 +84,7 @@
         ByteBuffer buffer = ByteBuffer.wrap(new byte[c.getSerializedSize()]).order(ByteOrder.nativeOrder());
         c.serialize(buffer);
 
-        buffer.rewind();
+        BufferUtil.asBaseBuffer(buffer).rewind();
         SerializableConstant ret = ((ArithmeticStamp) stamp).deserialize(buffer);
 
         assert !buffer.hasRemaining();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SignedDivNode.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SignedDivNode.java	Mon Jul 01 14:57:02 2019 -0700
@@ -122,7 +122,7 @@
             ValueNode dividend = forX;
             int log2 = CodeUtil.log2(abs);
             // no rounding if dividend is positive or if its low bits are always 0
-            if (stampX.canBeNegative() || (stampX.upMask() & (abs - 1)) != 0) {
+            if (stampX.canBeNegative() && (stampX.upMask() & (abs - 1)) != 0) {
                 int bits = PrimitiveStamp.getBits(forX.stamp(view));
                 RightShiftNode sign = new RightShiftNode(forX, ConstantNode.forInt(bits - 1));
                 UnsignedRightShiftNode round = new UnsignedRightShiftNode(sign, ConstantNode.forInt(bits - log2));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/cfg/ControlFlowGraph.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/cfg/ControlFlowGraph.java	Mon Jul 01 14:57:02 2019 -0700
@@ -210,7 +210,7 @@
     public static void addDeferredExit(DeferredExit[] deferredExits, Block b) {
         Loop<Block> outermostExited = b.getDominator().getLoop();
         Loop<Block> exitBlockLoop = b.getLoop();
-        assert outermostExited != null;
+        assert outermostExited != null : "Dominator must be in a loop. Possible cause is a missing loop exit node.";
         while (outermostExited.getParent() != null && outermostExited.getParent() != exitBlockLoop) {
             outermostExited = outermostExited.getParent();
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/ArrayRangeWrite.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/ArrayRangeWrite.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,8 +25,8 @@
 package org.graalvm.compiler.nodes.extended;
 
 import org.graalvm.compiler.graph.NodeInterface;
-import org.graalvm.compiler.nodes.FixedWithNextNode;
 import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.memory.FixedAccessNode;
 import org.graalvm.compiler.nodes.memory.address.AddressNode;
 
 public interface ArrayRangeWrite extends NodeInterface {
@@ -52,5 +52,5 @@
     int getElementStride();
 
     @Override
-    FixedWithNextNode asNode();
+    FixedAccessNode asNode();
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/IntegerSwitchNode.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/IntegerSwitchNode.java	Mon Jul 01 14:57:02 2019 -0700
@@ -220,7 +220,7 @@
             return false;
         }
         LoadIndexedNode loadIndexed = (LoadIndexedNode) value();
-        if (loadIndexed.usages().count() > 1) {
+        if (loadIndexed.hasMoreThanOneUsage()) {
             /*
              * The array load is necessary for other reasons too, so there is no benefit optimizing
              * the switch.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/ArrayRangeWriteBarrier.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.nodes.gc;
+
+import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.memory.address.AddressNode;
+import org.graalvm.compiler.nodes.spi.Lowerable;
+
+@NodeInfo
+public abstract class ArrayRangeWriteBarrier extends WriteBarrier implements Lowerable {
+
+    public static final NodeClass<ArrayRangeWriteBarrier> TYPE = NodeClass.create(ArrayRangeWriteBarrier.class);
+    @Input ValueNode length;
+
+    private final int elementStride;
+
+    protected ArrayRangeWriteBarrier(NodeClass<? extends ArrayRangeWriteBarrier> c, AddressNode address, ValueNode length, int elementStride) {
+        super(c, address);
+        this.length = length;
+        this.elementStride = elementStride;
+    }
+
+    public ValueNode getLength() {
+        return length;
+    }
+
+    public int getElementStride() {
+        return elementStride;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/BarrierSet.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, Red Hat Inc. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.nodes.gc;
+
+import org.graalvm.compiler.nodes.memory.FixedAccessNode;
+
+public interface BarrierSet {
+    void addBarriers(FixedAccessNode n);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/CardTableBarrierSet.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, Red Hat Inc. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.nodes.gc;
+
+import org.graalvm.compiler.core.common.type.AbstractObjectStamp;
+import org.graalvm.compiler.debug.GraalError;
+import org.graalvm.compiler.nodes.NodeView;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.extended.ArrayRangeWrite;
+import org.graalvm.compiler.nodes.java.AbstractCompareAndSwapNode;
+import org.graalvm.compiler.nodes.java.LoweredAtomicReadAndWriteNode;
+import org.graalvm.compiler.nodes.memory.FixedAccessNode;
+import org.graalvm.compiler.nodes.memory.HeapAccess;
+import org.graalvm.compiler.nodes.memory.HeapAccess.BarrierType;
+import org.graalvm.compiler.nodes.memory.ReadNode;
+import org.graalvm.compiler.nodes.memory.WriteNode;
+import org.graalvm.compiler.nodes.memory.address.AddressNode;
+import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
+import org.graalvm.compiler.nodes.type.StampTool;
+import org.graalvm.compiler.nodes.util.GraphUtil;
+
+public class CardTableBarrierSet implements BarrierSet {
+    public CardTableBarrierSet() {
+    }
+
+    @Override
+    public void addBarriers(FixedAccessNode n) {
+        if (n instanceof ReadNode) {
+            // nothing to do
+        } else if (n instanceof WriteNode) {
+            WriteNode write = (WriteNode) n;
+            addWriteBarrier(write, write.value());
+        } else if (n instanceof LoweredAtomicReadAndWriteNode) {
+            LoweredAtomicReadAndWriteNode atomic = (LoweredAtomicReadAndWriteNode) n;
+            addWriteBarrier(atomic, atomic.getNewValue());
+        } else if (n instanceof AbstractCompareAndSwapNode) {
+            AbstractCompareAndSwapNode cmpSwap = (AbstractCompareAndSwapNode) n;
+            addWriteBarrier(cmpSwap, cmpSwap.getNewValue());
+        } else if (n instanceof ArrayRangeWrite) {
+            addArrayRangeBarriers((ArrayRangeWrite) n);
+        } else {
+            GraalError.guarantee(n.getBarrierType() == BarrierType.NONE, "missed a node that requires a GC barrier: %s", n.getClass());
+        }
+    }
+
+    public boolean needsBarrier(FixedAccessNode n) {
+        if (n instanceof ReadNode) {
+            return false;
+        } else if (n instanceof WriteNode) {
+            WriteNode write = (WriteNode) n;
+            return needsWriteBarrier(write, write.value());
+        } else if (n instanceof LoweredAtomicReadAndWriteNode) {
+            LoweredAtomicReadAndWriteNode atomic = (LoweredAtomicReadAndWriteNode) n;
+            return needsWriteBarrier(atomic, atomic.getNewValue());
+        } else if (n instanceof AbstractCompareAndSwapNode) {
+            AbstractCompareAndSwapNode cmpSwap = (AbstractCompareAndSwapNode) n;
+            return needsWriteBarrier(cmpSwap, cmpSwap.getNewValue());
+        } else if (n instanceof ArrayRangeWrite) {
+            return needsWriteBarrier((ArrayRangeWrite) n);
+        } else {
+            GraalError.guarantee(n.getBarrierType() == BarrierType.NONE, "missed a node that requires a GC barrier: %s", n.getClass());
+            return false;
+        }
+    }
+
+    public boolean hasBarrier(FixedAccessNode n) {
+        if (n instanceof ReadNode) {
+            return false;
+        } else if (n instanceof WriteNode) {
+            WriteNode write = (WriteNode) n;
+            return hasWriteBarrier(write);
+        } else if (n instanceof LoweredAtomicReadAndWriteNode) {
+            LoweredAtomicReadAndWriteNode atomic = (LoweredAtomicReadAndWriteNode) n;
+            return hasWriteBarrier(atomic);
+        } else if (n instanceof AbstractCompareAndSwapNode) {
+            AbstractCompareAndSwapNode cmpSwap = (AbstractCompareAndSwapNode) n;
+            return hasWriteBarrier(cmpSwap);
+        } else if (n instanceof ArrayRangeWrite) {
+            return hasWriteBarrier((ArrayRangeWrite) n);
+        } else {
+            GraalError.guarantee(n.getBarrierType() == BarrierType.NONE, "missed a node that requires a GC barrier: %s", n.getClass());
+            return false;
+        }
+    }
+
+    public boolean isMatchingBarrier(FixedAccessNode n, WriteBarrier barrier) {
+        if (n instanceof ReadNode) {
+            return false;
+        } else if (n instanceof WriteNode || n instanceof LoweredAtomicReadAndWriteNode || n instanceof AbstractCompareAndSwapNode || n instanceof ArrayRangeWrite) {
+            return barrier instanceof SerialWriteBarrier && matches(n, (SerialWriteBarrier) barrier);
+        } else {
+            throw GraalError.shouldNotReachHere("Unexpected node: " + n.getClass());
+        }
+    }
+
+    public void addArrayRangeBarriers(ArrayRangeWrite write) {
+        if (needsWriteBarrier(write)) {
+            StructuredGraph graph = write.asNode().graph();
+            SerialArrayRangeWriteBarrier serialArrayRangeWriteBarrier = graph.add(new SerialArrayRangeWriteBarrier(write.getAddress(), write.getLength(), write.getElementStride()));
+            graph.addAfterFixed(write.asNode(), serialArrayRangeWriteBarrier);
+        }
+    }
+
+    private void addWriteBarrier(FixedAccessNode node, ValueNode writtenValue) {
+        if (needsWriteBarrier(node, writtenValue)) {
+            addSerialPostWriteBarrier(node, node.getAddress(), node.graph());
+        }
+    }
+
+    public boolean needsWriteBarrier(FixedAccessNode node, ValueNode writtenValue) {
+        assert !(node instanceof ArrayRangeWrite);
+        HeapAccess.BarrierType barrierType = node.getBarrierType();
+        switch (barrierType) {
+            case NONE:
+                return false;
+            case FIELD:
+            case ARRAY:
+            case UNKNOWN:
+                return writeRequiresBarrier(node, writtenValue);
+            default:
+                throw new GraalError("unexpected barrier type: " + barrierType);
+        }
+    }
+
+    @SuppressWarnings("unused")
+    protected boolean writeRequiresBarrier(FixedAccessNode node, ValueNode writtenValue) {
+        // Null writes can skip the card mark.
+        return isNonNullObjectValue(writtenValue);
+    }
+
+    public static boolean needsWriteBarrier(ArrayRangeWrite write) {
+        return write.writesObjectArray();
+    }
+
+    private static boolean hasWriteBarrier(FixedAccessNode node) {
+        return node.next() instanceof SerialWriteBarrier && matches(node, (SerialWriteBarrier) node.next());
+    }
+
+    private static boolean hasWriteBarrier(ArrayRangeWrite write) {
+        FixedAccessNode node = write.asNode();
+        return node.next() instanceof SerialArrayRangeWriteBarrier && matches(write, (SerialArrayRangeWriteBarrier) node.next());
+    }
+
+    private static void addSerialPostWriteBarrier(FixedAccessNode node, AddressNode address, StructuredGraph graph) {
+        boolean precise = node.getBarrierType() != HeapAccess.BarrierType.FIELD;
+        graph.addAfterFixed(node, graph.add(new SerialWriteBarrier(address, precise)));
+    }
+
+    private static boolean isNonNullObjectValue(ValueNode value) {
+        return value.stamp(NodeView.DEFAULT) instanceof AbstractObjectStamp && !StampTool.isPointerAlwaysNull(value);
+    }
+
+    private static boolean matches(FixedAccessNode node, SerialWriteBarrier barrier) {
+        if (!barrier.usePrecise()) {
+            if (barrier.getAddress() instanceof OffsetAddressNode && node.getAddress() instanceof OffsetAddressNode) {
+                return GraphUtil.unproxify(((OffsetAddressNode) barrier.getAddress()).getBase()) == GraphUtil.unproxify(((OffsetAddressNode) node.getAddress()).getBase());
+            }
+        }
+        return barrier.getAddress() == node.getAddress();
+    }
+
+    private static boolean matches(ArrayRangeWrite node, SerialArrayRangeWriteBarrier barrier) {
+        return barrier.getAddress() == node.getAddress() && node.getLength() == barrier.getLength() && node.getElementStride() == barrier.getElementStride();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/G1ArrayRangePostWriteBarrier.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+
+package org.graalvm.compiler.nodes.gc;
+
+import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_64;
+import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_64;
+
+import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.memory.address.AddressNode;
+
+@NodeInfo(cycles = CYCLES_64, size = SIZE_64)
+public class G1ArrayRangePostWriteBarrier extends ArrayRangeWriteBarrier {
+    public static final NodeClass<G1ArrayRangePostWriteBarrier> TYPE = NodeClass.create(G1ArrayRangePostWriteBarrier.class);
+
+    public G1ArrayRangePostWriteBarrier(AddressNode address, ValueNode length, int elementStride) {
+        super(TYPE, address, length, elementStride);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/G1ArrayRangePreWriteBarrier.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+
+package org.graalvm.compiler.nodes.gc;
+
+import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_64;
+import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_64;
+
+import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.memory.address.AddressNode;
+
+@NodeInfo(cycles = CYCLES_64, size = SIZE_64)
+public final class G1ArrayRangePreWriteBarrier extends ArrayRangeWriteBarrier {
+    public static final NodeClass<G1ArrayRangePreWriteBarrier> TYPE = NodeClass.create(G1ArrayRangePreWriteBarrier.class);
+
+    public G1ArrayRangePreWriteBarrier(AddressNode address, ValueNode length, int elementStride) {
+        super(TYPE, address, length, elementStride);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/G1BarrierSet.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, Red Hat Inc. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.nodes.gc;
+
+import org.graalvm.compiler.core.common.type.AbstractObjectStamp;
+import org.graalvm.compiler.debug.GraalError;
+import org.graalvm.compiler.nodes.NodeView;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.extended.ArrayRangeWrite;
+import org.graalvm.compiler.nodes.java.AbstractCompareAndSwapNode;
+import org.graalvm.compiler.nodes.java.LoweredAtomicReadAndWriteNode;
+import org.graalvm.compiler.nodes.memory.FixedAccessNode;
+import org.graalvm.compiler.nodes.memory.HeapAccess;
+import org.graalvm.compiler.nodes.memory.HeapAccess.BarrierType;
+import org.graalvm.compiler.nodes.memory.ReadNode;
+import org.graalvm.compiler.nodes.memory.WriteNode;
+import org.graalvm.compiler.nodes.memory.address.AddressNode;
+import org.graalvm.compiler.nodes.type.StampTool;
+
+public class G1BarrierSet implements BarrierSet {
+    public G1BarrierSet() {
+    }
+
+    @Override
+    public void addBarriers(FixedAccessNode n) {
+        if (n instanceof ReadNode) {
+            addReadNodeBarriers((ReadNode) n);
+        } else if (n instanceof WriteNode) {
+            WriteNode write = (WriteNode) n;
+            addWriteBarriers(write, write.value(), null, true, write.getNullCheck());
+        } else if (n instanceof LoweredAtomicReadAndWriteNode) {
+            LoweredAtomicReadAndWriteNode atomic = (LoweredAtomicReadAndWriteNode) n;
+            addWriteBarriers(atomic, atomic.getNewValue(), null, true, atomic.getNullCheck());
+        } else if (n instanceof AbstractCompareAndSwapNode) {
+            AbstractCompareAndSwapNode cmpSwap = (AbstractCompareAndSwapNode) n;
+            addWriteBarriers(cmpSwap, cmpSwap.getNewValue(), cmpSwap.getExpectedValue(), false, false);
+        } else if (n instanceof ArrayRangeWrite) {
+            addArrayRangeBarriers((ArrayRangeWrite) n);
+        } else {
+            GraalError.guarantee(n.getBarrierType() == BarrierType.NONE, "missed a node that requires a GC barrier: %s", n.getClass());
+        }
+    }
+
+    private static void addReadNodeBarriers(ReadNode node) {
+        if (node.getBarrierType() == HeapAccess.BarrierType.WEAK_FIELD) {
+            StructuredGraph graph = node.graph();
+            G1ReferentFieldReadBarrier barrier = graph.add(new G1ReferentFieldReadBarrier(node.getAddress(), node, false));
+            graph.addAfterFixed(node, barrier);
+        }
+    }
+
+    private void addWriteBarriers(FixedAccessNode node, ValueNode writtenValue, ValueNode expectedValue, boolean doLoad, boolean nullCheck) {
+        HeapAccess.BarrierType barrierType = node.getBarrierType();
+        switch (barrierType) {
+            case NONE:
+                // nothing to do
+                break;
+            case FIELD:
+            case ARRAY:
+            case UNKNOWN:
+                if (isObjectValue(writtenValue)) {
+                    StructuredGraph graph = node.graph();
+                    boolean init = node.getLocationIdentity().isInit();
+                    if (!init) {
+                        // The pre barrier does nothing if the value being read is null, so it can
+                        // be explicitly skipped when this is an initializing store.
+                        addG1PreWriteBarrier(node, node.getAddress(), expectedValue, doLoad, nullCheck, graph);
+                    }
+                    if (writeRequiresPostBarrier(node, writtenValue)) {
+                        boolean precise = barrierType != HeapAccess.BarrierType.FIELD;
+                        addG1PostWriteBarrier(node, node.getAddress(), writtenValue, precise, graph);
+                    }
+                }
+                break;
+            default:
+                throw new GraalError("unexpected barrier type: " + barrierType);
+        }
+    }
+
+    @SuppressWarnings("unused")
+    protected boolean writeRequiresPostBarrier(FixedAccessNode initializingWrite, ValueNode writtenValue) {
+        // Without help from the runtime all writes require an explicit post barrier.
+        return true;
+    }
+
+    private static void addArrayRangeBarriers(ArrayRangeWrite write) {
+        if (write.writesObjectArray()) {
+            StructuredGraph graph = write.asNode().graph();
+            if (!write.isInitialization()) {
+                // The pre barrier does nothing if the value being read is null, so it can
+                // be explicitly skipped when this is an initializing store.
+                G1ArrayRangePreWriteBarrier g1ArrayRangePreWriteBarrier = graph.add(new G1ArrayRangePreWriteBarrier(write.getAddress(), write.getLength(), write.getElementStride()));
+                graph.addBeforeFixed(write.asNode(), g1ArrayRangePreWriteBarrier);
+            }
+            G1ArrayRangePostWriteBarrier g1ArrayRangePostWriteBarrier = graph.add(new G1ArrayRangePostWriteBarrier(write.getAddress(), write.getLength(), write.getElementStride()));
+            graph.addAfterFixed(write.asNode(), g1ArrayRangePostWriteBarrier);
+        }
+    }
+
+    private static void addG1PreWriteBarrier(FixedAccessNode node, AddressNode address, ValueNode value, boolean doLoad, boolean nullCheck, StructuredGraph graph) {
+        G1PreWriteBarrier preBarrier = graph.add(new G1PreWriteBarrier(address, value, doLoad, nullCheck));
+        preBarrier.setStateBefore(node.stateBefore());
+        node.setNullCheck(false);
+        node.setStateBefore(null);
+        graph.addBeforeFixed(node, preBarrier);
+    }
+
+    private static void addG1PostWriteBarrier(FixedAccessNode node, AddressNode address, ValueNode value, boolean precise, StructuredGraph graph) {
+        final boolean alwaysNull = StampTool.isPointerAlwaysNull(value);
+        graph.addAfterFixed(node, graph.add(new G1PostWriteBarrier(address, value, precise, alwaysNull)));
+    }
+
+    private static boolean isObjectValue(ValueNode value) {
+        return value.stamp(NodeView.DEFAULT) instanceof AbstractObjectStamp;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/G1PostWriteBarrier.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.nodes.gc;
+
+import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_64;
+import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_64;
+
+import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.memory.address.AddressNode;
+
+@NodeInfo(cycles = CYCLES_64, size = SIZE_64)
+public class G1PostWriteBarrier extends ObjectWriteBarrier {
+
+    public static final NodeClass<G1PostWriteBarrier> TYPE = NodeClass.create(G1PostWriteBarrier.class);
+    protected final boolean alwaysNull;
+
+    public G1PostWriteBarrier(AddressNode address, ValueNode value, boolean precise, boolean alwaysNull) {
+        this(TYPE, address, value, precise, alwaysNull);
+    }
+
+    private G1PostWriteBarrier(NodeClass<? extends G1PostWriteBarrier> c, AddressNode address, ValueNode value, boolean precise, boolean alwaysNull) {
+        super(c, address, value, precise);
+        this.alwaysNull = alwaysNull;
+    }
+
+    public boolean alwaysNull() {
+        return alwaysNull;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/G1PreWriteBarrier.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+
+package org.graalvm.compiler.nodes.gc;
+
+import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_64;
+import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_64;
+
+import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.nodeinfo.InputType;
+import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.DeoptimizingNode;
+import org.graalvm.compiler.nodes.FrameState;
+import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.memory.address.AddressNode;
+
+@NodeInfo(cycles = CYCLES_64, size = SIZE_64)
+public final class G1PreWriteBarrier extends ObjectWriteBarrier implements DeoptimizingNode.DeoptBefore {
+
+    public static final NodeClass<G1PreWriteBarrier> TYPE = NodeClass.create(G1PreWriteBarrier.class);
+
+    @OptionalInput(InputType.State) private FrameState stateBefore;
+    private final boolean nullCheck;
+    private final boolean doLoad;
+
+    public G1PreWriteBarrier(AddressNode address, ValueNode expectedObject, boolean doLoad, boolean nullCheck) {
+        super(TYPE, address, expectedObject, true);
+        assert doLoad == (expectedObject == null);
+        this.doLoad = doLoad;
+        this.nullCheck = nullCheck;
+    }
+
+    public ValueNode getExpectedObject() {
+        return getValue();
+    }
+
+    public boolean doLoad() {
+        return doLoad;
+    }
+
+    public boolean getNullCheck() {
+        return nullCheck;
+    }
+
+    @Override
+    public boolean canDeoptimize() {
+        return nullCheck;
+    }
+
+    @Override
+    public FrameState stateBefore() {
+        return stateBefore;
+    }
+
+    @Override
+    public void setStateBefore(FrameState state) {
+        updateUsages(stateBefore, state);
+        stateBefore = state;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/G1ReferentFieldReadBarrier.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.nodes.gc;
+
+import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_64;
+import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_64;
+
+import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.memory.address.AddressNode;
+
+/**
+ * The {@code G1ReferentFieldReadBarrier} is added when a read access is performed to the referent
+ * field of a {@link java.lang.ref.Reference} object (through a {@code LoadFieldNode} or an
+ * {@code UnsafeLoadNode}). The return value of the read is passed to the snippet implementing the
+ * read barrier and consequently is added to the SATB queue if the concurrent marker is enabled.
+ */
+@NodeInfo(cycles = CYCLES_64, size = SIZE_64)
+public final class G1ReferentFieldReadBarrier extends ObjectWriteBarrier {
+    public static final NodeClass<G1ReferentFieldReadBarrier> TYPE = NodeClass.create(G1ReferentFieldReadBarrier.class);
+
+    private final boolean doLoad;
+
+    public G1ReferentFieldReadBarrier(AddressNode address, ValueNode expectedObject, boolean doLoad) {
+        super(TYPE, address, expectedObject, true);
+        this.doLoad = doLoad;
+    }
+
+    public ValueNode getExpectedObject() {
+        return getValue();
+    }
+
+    public boolean doLoad() {
+        return doLoad;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/ObjectWriteBarrier.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.nodes.gc;
+
+import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.memory.address.AddressNode;
+
+@NodeInfo
+public abstract class ObjectWriteBarrier extends WriteBarrier {
+
+    public static final NodeClass<ObjectWriteBarrier> TYPE = NodeClass.create(ObjectWriteBarrier.class);
+    @OptionalInput protected ValueNode value;
+    protected final boolean precise;
+
+    protected ObjectWriteBarrier(NodeClass<? extends ObjectWriteBarrier> c, AddressNode address, ValueNode value, boolean precise) {
+        super(c, address);
+        this.value = value;
+        this.precise = precise;
+    }
+
+    public ValueNode getValue() {
+        return value;
+    }
+
+    public boolean usePrecise() {
+        return precise;
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/SerialArrayRangeWriteBarrier.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.nodes.gc;
+
+import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_8;
+import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_8;
+
+import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.memory.address.AddressNode;
+
+@NodeInfo(cycles = CYCLES_8, size = SIZE_8)
+public final class SerialArrayRangeWriteBarrier extends ArrayRangeWriteBarrier {
+    public static final NodeClass<SerialArrayRangeWriteBarrier> TYPE = NodeClass.create(SerialArrayRangeWriteBarrier.class);
+
+    public SerialArrayRangeWriteBarrier(AddressNode address, ValueNode length, int elementStride) {
+        super(TYPE, address, length, elementStride);
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/SerialWriteBarrier.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.nodes.gc;
+
+import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_8;
+import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_4;
+
+import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.memory.address.AddressNode;
+
+@NodeInfo(cycles = CYCLES_8, size = SIZE_4)
+public class SerialWriteBarrier extends ObjectWriteBarrier {
+    public static final NodeClass<SerialWriteBarrier> TYPE = NodeClass.create(SerialWriteBarrier.class);
+
+    protected boolean verifyOnly;
+
+    public SerialWriteBarrier(AddressNode address, boolean precise) {
+        this(TYPE, address, precise);
+    }
+
+    protected SerialWriteBarrier(NodeClass<? extends SerialWriteBarrier> c, AddressNode address, boolean precise) {
+        super(c, address, null, precise);
+    }
+
+    public void setVerifyOnly(boolean value) {
+        this.verifyOnly = value;
+    }
+
+    public boolean getVerifyOnly() {
+        return verifyOnly;
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/gc/WriteBarrier.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.nodes.gc;
+
+import org.graalvm.compiler.core.common.type.StampFactory;
+import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.nodeinfo.InputType;
+import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.FixedWithNextNode;
+import org.graalvm.compiler.nodes.memory.address.AddressNode;
+import org.graalvm.compiler.nodes.spi.Lowerable;
+import org.graalvm.compiler.nodes.spi.LoweringTool;
+
+@NodeInfo
+public abstract class WriteBarrier extends FixedWithNextNode implements Lowerable {
+
+    public static final NodeClass<WriteBarrier> TYPE = NodeClass.create(WriteBarrier.class);
+    @Input(InputType.Association) AddressNode address;
+
+    protected WriteBarrier(NodeClass<? extends WriteBarrier> c, AddressNode address) {
+        super(c, StampFactory.forVoid());
+        this.address = address;
+    }
+
+    @Override
+    public void lower(LoweringTool tool) {
+        assert graph().getGuardsStage().areFrameStatesAtDeopts();
+        tool.getLowerer().lower(this, tool);
+    }
+
+    public AddressNode getAddress() {
+        return address;
+    }
+}
+
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/MethodSubstitutionPlugin.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/MethodSubstitutionPlugin.java	Mon Jul 01 14:57:02 2019 -0700
@@ -192,7 +192,12 @@
             if (!IS_IN_NATIVE_IMAGE && UseEncodedGraphs.getValue(b.getOptions())) {
                 b.getReplacements().registerMethodSubstitution(this, targetMethod, INLINE_AFTER_PARSING, b.getOptions());
             }
-            StructuredGraph subst = b.getReplacements().getMethodSubstitution(this, targetMethod, INLINE_AFTER_PARSING, StructuredGraph.AllowAssumptions.ifNonNull(b.getAssumptions()), b.getOptions());
+            StructuredGraph subst = b.getReplacements().getMethodSubstitution(this,
+                            targetMethod,
+                            INLINE_AFTER_PARSING,
+                            StructuredGraph.AllowAssumptions.ifNonNull(b.getAssumptions()),
+                            null /* cancellable */,
+                            b.getOptions());
             if (subst == null) {
                 throw new GraalError("No graphs found for substitution %s", this);
             }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/MethodCallTargetNode.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/MethodCallTargetNode.java	Mon Jul 01 14:57:02 2019 -0700
@@ -274,4 +274,8 @@
         }
         return null;
     }
+
+    public void setJavaTypeProfile(JavaTypeProfile profile) {
+        this.profile = profile;
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/FloatableAccessNode.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/FloatableAccessNode.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -52,7 +52,7 @@
         super(c, address, location, stamp, guard, barrierType, nullCheck, stateBefore);
     }
 
-    public abstract FloatingAccessNode asFloatingNode(MemoryNode lastLocationAccess);
+    public abstract FloatingAccessNode asFloatingNode();
 
     protected boolean forceFixed;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/ReadNode.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/ReadNode.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
 
 package org.graalvm.compiler.nodes.memory;
 
+import static org.graalvm.compiler.nodeinfo.InputType.Memory;
 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2;
 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1;
 import static org.graalvm.compiler.nodes.NamedLocationIdentity.ARRAY_LENGTH_LOCATION;
@@ -43,6 +44,7 @@
 import org.graalvm.compiler.nodes.FrameState;
 import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.ValueNodeUtil;
 import org.graalvm.compiler.nodes.extended.GuardingNode;
 import org.graalvm.compiler.nodes.memory.address.AddressNode;
 import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
@@ -60,10 +62,12 @@
  * Reads an {@linkplain FixedAccessNode accessed} value.
  */
 @NodeInfo(nameTemplate = "Read#{p#location/s}", cycles = CYCLES_2, size = SIZE_1)
-public class ReadNode extends FloatableAccessNode implements LIRLowerableAccess, Canonicalizable, Virtualizable, GuardingNode {
+public class ReadNode extends FloatableAccessNode implements LIRLowerableAccess, Canonicalizable, Virtualizable, GuardingNode, MemoryAccess {
 
     public static final NodeClass<ReadNode> TYPE = NodeClass.create(ReadNode.class);
 
+    @OptionalInput(Memory) MemoryNode lastLocationAccess;
+
     public ReadNode(AddressNode address, LocationIdentity location, Stamp stamp, BarrierType barrierType) {
         this(TYPE, address, location, stamp, null, barrierType, false, null);
     }
@@ -71,6 +75,18 @@
     protected ReadNode(NodeClass<? extends ReadNode> c, AddressNode address, LocationIdentity location, Stamp stamp, GuardingNode guard, BarrierType barrierType, boolean nullCheck,
                     FrameState stateBefore) {
         super(c, address, location, stamp, guard, barrierType, nullCheck, stateBefore);
+        this.lastLocationAccess = null;
+    }
+
+    @Override
+    public MemoryNode getLastLocationAccess() {
+        return lastLocationAccess;
+    }
+
+    @Override
+    public void setLastLocationAccess(MemoryNode newlla) {
+        updateUsages(ValueNodeUtil.asNode(lastLocationAccess), ValueNodeUtil.asNode(newlla));
+        lastLocationAccess = newlla;
     }
 
     @Override
@@ -96,7 +112,7 @@
 
     @SuppressWarnings("try")
     @Override
-    public FloatingAccessNode asFloatingNode(MemoryNode lastLocationAccess) {
+    public FloatingAccessNode asFloatingNode() {
         try (DebugCloseable position = withNodeSourcePosition()) {
             return graph().unique(new FloatingReadNode(getAddress(), getLocationIdentity(), lastLocationAccess, stamp(NodeView.DEFAULT), getGuard(), getBarrierType()));
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/address/IndexAddressNode.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/memory/address/IndexAddressNode.java	Mon Jul 01 14:57:02 2019 -0700
@@ -43,12 +43,18 @@
     @Input ValueNode array;
     @Input ValueNode index;
 
+    private final JavaKind arrayKind;
     private final JavaKind elementKind;
 
     public IndexAddressNode(ValueNode array, ValueNode index, JavaKind elementKind) {
+        this(array, index, elementKind, elementKind);
+    }
+
+    public IndexAddressNode(ValueNode array, ValueNode index, JavaKind arrayKind, JavaKind elementKind) {
         super(TYPE);
         this.array = array;
         this.index = index;
+        this.arrayKind = arrayKind;
         this.elementKind = elementKind;
     }
 
@@ -71,6 +77,10 @@
         return Long.MAX_VALUE;
     }
 
+    public JavaKind getArrayKind() {
+        return arrayKind;
+    }
+
     public JavaKind getElementKind() {
         return elementKind;
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/CoreProviders.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/CoreProviders.java	Mon Jul 01 14:57:02 2019 -0700
@@ -45,4 +45,6 @@
     StampProvider getStampProvider();
 
     ForeignCallsProvider getForeignCalls();
+
+    GCProvider getGC();
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/CoreProvidersDelegate.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.nodes.spi;
+
+import org.graalvm.compiler.core.common.spi.ConstantFieldProvider;
+import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
+
+import jdk.vm.ci.meta.ConstantReflectionProvider;
+import jdk.vm.ci.meta.MetaAccessProvider;
+
+public class CoreProvidersDelegate implements CoreProviders {
+
+    private final CoreProviders providers;
+
+    protected CoreProvidersDelegate(CoreProviders providers) {
+        this.providers = providers;
+    }
+
+    @Override
+    public MetaAccessProvider getMetaAccess() {
+        return providers.getMetaAccess();
+    }
+
+    @Override
+    public ConstantReflectionProvider getConstantReflection() {
+        return providers.getConstantReflection();
+    }
+
+    @Override
+    public ConstantFieldProvider getConstantFieldProvider() {
+        return providers.getConstantFieldProvider();
+    }
+
+    @Override
+    public LoweringProvider getLowerer() {
+        return providers.getLowerer();
+    }
+
+    @Override
+    public Replacements getReplacements() {
+        return providers.getReplacements();
+    }
+
+    @Override
+    public StampProvider getStampProvider() {
+        return providers.getStampProvider();
+    }
+
+    @Override
+    public ForeignCallsProvider getForeignCalls() {
+        return providers.getForeignCalls();
+    }
+
+    @Override
+    public GCProvider getGC() {
+        return providers.getGC();
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/CoreProvidersImpl.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/CoreProvidersImpl.java	Mon Jul 01 14:57:02 2019 -0700
@@ -38,9 +38,10 @@
     protected final Replacements replacements;
     protected final StampProvider stampProvider;
     protected final ForeignCallsProvider foreignCalls;
+    protected final GCProvider gc;
 
     protected CoreProvidersImpl(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, ConstantFieldProvider constantFieldProvider, LoweringProvider lowerer,
-                    Replacements replacements, StampProvider stampProvider, ForeignCallsProvider foreignCalls) {
+                    Replacements replacements, StampProvider stampProvider, ForeignCallsProvider foreignCalls, GCProvider gc) {
         this.metaAccess = metaAccess;
         this.constantReflection = constantReflection;
         this.constantFieldProvider = constantFieldProvider;
@@ -48,6 +49,7 @@
         this.replacements = replacements;
         this.stampProvider = stampProvider;
         this.foreignCalls = foreignCalls;
+        this.gc = gc;
     }
 
     @Override
@@ -84,4 +86,9 @@
     public ForeignCallsProvider getForeignCalls() {
         return foreignCalls;
     }
+
+    @Override
+    public GCProvider getGC() {
+        return gc;
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/DelegatingReplacements.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/DelegatingReplacements.java	Mon Jul 01 14:57:02 2019 -0700
@@ -29,6 +29,7 @@
 import org.graalvm.compiler.core.common.CompilationIdentifier;
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.graph.NodeSourcePosition;
+import org.graalvm.compiler.nodes.Cancellable;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration;
 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderPlugin;
@@ -76,8 +77,8 @@
 
     @Override
     public StructuredGraph getMethodSubstitution(MethodSubstitutionPlugin plugin, ResolvedJavaMethod original, IntrinsicContext.CompilationContext context,
-                    StructuredGraph.AllowAssumptions allowAssumptions, OptionValues options) {
-        return delegate.getMethodSubstitution(plugin, original, context, allowAssumptions, options);
+                    StructuredGraph.AllowAssumptions allowAssumptions, Cancellable cancellable, OptionValues options) {
+        return delegate.getMethodSubstitution(plugin, original, context, allowAssumptions, cancellable, options);
     }
 
     @Override
@@ -91,8 +92,8 @@
     }
 
     @Override
-    public StructuredGraph getIntrinsicGraph(ResolvedJavaMethod method, CompilationIdentifier compilationId, DebugContext debug) {
-        return delegate.getIntrinsicGraph(method, compilationId, debug);
+    public StructuredGraph getIntrinsicGraph(ResolvedJavaMethod method, CompilationIdentifier compilationId, DebugContext debug, Cancellable cancellable) {
+        return delegate.getIntrinsicGraph(method, compilationId, debug, cancellable);
     }
 
     @Override
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/GCProvider.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.nodes.spi;
+
+import org.graalvm.compiler.nodes.gc.BarrierSet;
+
+public interface GCProvider {
+    /** Returns the barrier set that is used to insert the needed read/write barriers. */
+    BarrierSet getBarrierSet();
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/Replacements.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/Replacements.java	Mon Jul 01 14:57:02 2019 -0700
@@ -30,6 +30,7 @@
 import org.graalvm.compiler.core.common.CompilationIdentifier;
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.graph.NodeSourcePosition;
+import org.graalvm.compiler.nodes.Cancellable;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration;
 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderPlugin;
@@ -86,11 +87,12 @@
      * @param original the method being substituted
      * @param context the kind of inlining to be performed for the substitution
      * @param allowAssumptions
+     * @param cancellable
      * @param options
      * @return the method substitution graph, if any, that is derived from {@code method}
      */
     StructuredGraph getMethodSubstitution(MethodSubstitutionPlugin plugin, ResolvedJavaMethod original, IntrinsicContext.CompilationContext context,
-                    StructuredGraph.AllowAssumptions allowAssumptions, OptionValues options);
+                    StructuredGraph.AllowAssumptions allowAssumptions, Cancellable cancellable, OptionValues options);
 
     /**
      * Registers a plugin as a substitution.
@@ -115,9 +117,10 @@
      * @param method
      * @param compilationId
      * @param debug
+     * @param cancellable
      * @return an intrinsic graph that can be compiled and installed for {@code method} or null
      */
-    StructuredGraph getIntrinsicGraph(ResolvedJavaMethod method, CompilationIdentifier compilationId, DebugContext debug);
+    StructuredGraph getIntrinsicGraph(ResolvedJavaMethod method, CompilationIdentifier compilationId, DebugContext debug, Cancellable cancellable);
 
     /**
      * Determines if there may be a
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/Option.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/Option.java	Mon Jul 01 14:57:02 2019 -0700
@@ -64,4 +64,9 @@
      * Specifies the type of the option.
      */
     OptionType type() default OptionType.Debug;
+
+    /**
+     * Specifies the stability of the option.
+     */
+    OptionStability stability() default OptionStability.EXPERIMENTAL;
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/OptionStability.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.options;
+
+/**
+ * Categorizes options according to their stability.
+ */
+public enum OptionStability {
+
+    /**
+     * A stable option is expected to remain available for many releases. End users can rely on such
+     * an option being present. A stable option can still be removed but will go through a clear
+     * deprecating process before being removed.
+     */
+    STABLE,
+
+    /**
+     * An experimental option has no guarantees of stability and might be removed at any point.
+     */
+    EXPERIMENTAL
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/OptionsParser.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.options/src/org/graalvm/compiler/options/OptionsParser.java	Mon Jul 01 14:57:02 2019 -0700
@@ -67,15 +67,12 @@
              */
             loader = ClassLoader.getSystemClassLoader();
         }
-        Iterable<OptionDescriptors> result = ServiceLoader.load(OptionDescriptors.class, loader);
-        if (IS_BUILDING_NATIVE_IMAGE) {
-            ArrayList<OptionDescriptors> optionDescriptors = new ArrayList<>();
-            for (OptionDescriptors descriptors : result) {
-                optionDescriptors.add(descriptors);
-            }
-            OptionsParser.cachedOptionDescriptors = optionDescriptors;
-        }
-        return result;
+        return ServiceLoader.load(OptionDescriptors.class, loader);
+    }
+
+    public static void setCachedOptionDescriptors(List<OptionDescriptors> cachedOptionDescriptors) {
+        assert IS_BUILDING_NATIVE_IMAGE : "Used to pre-initialize the option descriptors during native image generation";
+        OptionsParser.cachedOptionDescriptors = cachedOptionDescriptors;
     }
 
     /**
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/CanonicalizerPhase.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/CanonicalizerPhase.java	Mon Jul 01 14:57:02 2019 -0700
@@ -42,6 +42,7 @@
 import org.graalvm.compiler.graph.spi.Canonicalizable.BinaryCommutative;
 import org.graalvm.compiler.graph.spi.SimplifierTool;
 import org.graalvm.compiler.nodeinfo.InputType;
+import org.graalvm.compiler.nodes.AbstractBeginNode;
 import org.graalvm.compiler.nodes.AbstractMergeNode;
 import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.ControlSinkNode;
@@ -52,18 +53,18 @@
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.calc.FloatingNode;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.nodes.util.GraphUtil;
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.phases.BasePhase;
 import org.graalvm.compiler.phases.Phase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 
 import jdk.vm.ci.meta.Assumptions;
 import jdk.vm.ci.meta.Constant;
 import jdk.vm.ci.meta.ConstantReflectionProvider;
 import jdk.vm.ci.meta.MetaAccessProvider;
 
-public class CanonicalizerPhase extends BasePhase<PhaseContext> {
+public class CanonicalizerPhase extends BasePhase<CoreProviders> {
 
     private static final int MAX_ITERATION_PER_NODE = 10;
     private static final CounterKey COUNTER_CANONICALIZED_NODES = DebugContext.counter("CanonicalizedNodes");
@@ -121,7 +122,7 @@
     }
 
     @Override
-    protected void run(StructuredGraph graph, PhaseContext context) {
+    protected void run(StructuredGraph graph, CoreProviders context) {
         new Instance(context).run(graph);
     }
 
@@ -129,11 +130,11 @@
      * @param newNodesMark only the {@linkplain Graph#getNewNodes(Mark) new nodes} specified by this
      *            mark are processed
      */
-    public void applyIncremental(StructuredGraph graph, PhaseContext context, Mark newNodesMark) {
+    public void applyIncremental(StructuredGraph graph, CoreProviders context, Mark newNodesMark) {
         applyIncremental(graph, context, newNodesMark, true);
     }
 
-    public void applyIncremental(StructuredGraph graph, PhaseContext context, Mark newNodesMark, boolean dumpGraph) {
+    public void applyIncremental(StructuredGraph graph, CoreProviders context, Mark newNodesMark, boolean dumpGraph) {
         new Instance(context, newNodesMark).apply(graph, dumpGraph);
     }
 
@@ -141,19 +142,19 @@
      * @param workingSet the initial working set of nodes on which the canonicalizer works, should
      *            be an auto-grow node bitmap
      */
-    public void applyIncremental(StructuredGraph graph, PhaseContext context, Iterable<? extends Node> workingSet) {
+    public void applyIncremental(StructuredGraph graph, CoreProviders context, Iterable<? extends Node> workingSet) {
         applyIncremental(graph, context, workingSet, true);
     }
 
-    public void applyIncremental(StructuredGraph graph, PhaseContext context, Iterable<? extends Node> workingSet, boolean dumpGraph) {
+    public void applyIncremental(StructuredGraph graph, CoreProviders context, Iterable<? extends Node> workingSet, boolean dumpGraph) {
         new Instance(context, workingSet).apply(graph, dumpGraph);
     }
 
-    public void applyIncremental(StructuredGraph graph, PhaseContext context, Iterable<? extends Node> workingSet, Mark newNodesMark) {
+    public void applyIncremental(StructuredGraph graph, CoreProviders context, Iterable<? extends Node> workingSet, Mark newNodesMark) {
         applyIncremental(graph, context, workingSet, newNodesMark, true);
     }
 
-    public void applyIncremental(StructuredGraph graph, PhaseContext context, Iterable<? extends Node> workingSet, Mark newNodesMark, boolean dumpGraph) {
+    public void applyIncremental(StructuredGraph graph, CoreProviders context, Iterable<? extends Node> workingSet, Mark newNodesMark, boolean dumpGraph) {
         new Instance(context, workingSet, newNodesMark).apply(graph, dumpGraph);
     }
 
@@ -164,26 +165,26 @@
     private final class Instance extends Phase {
 
         private final Mark newNodesMark;
-        private final PhaseContext context;
+        private final CoreProviders context;
         private final Iterable<? extends Node> initWorkingSet;
 
         private NodeWorkList workList;
         private Tool tool;
         private DebugContext debug;
 
-        private Instance(PhaseContext context) {
+        private Instance(CoreProviders context) {
             this(context, null, null);
         }
 
-        private Instance(PhaseContext context, Iterable<? extends Node> workingSet) {
+        private Instance(CoreProviders context, Iterable<? extends Node> workingSet) {
             this(context, workingSet, null);
         }
 
-        private Instance(PhaseContext context, Mark newNodesMark) {
+        private Instance(CoreProviders context, Mark newNodesMark) {
             this(context, null, newNodesMark);
         }
 
-        private Instance(PhaseContext context, Iterable<? extends Node> workingSet, Mark newNodesMark) {
+        private Instance(CoreProviders context, Iterable<? extends Node> workingSet, Mark newNodesMark) {
             this.newNodesMark = newNodesMark;
             this.context = context;
             this.initWorkingSet = workingSet;
@@ -207,12 +208,14 @@
             if (!wholeGraph) {
                 workList.addAll(graph.getNewNodes(newNodesMark));
             }
+
             tool = new Tool(graph.getAssumptions(), graph.getOptions());
             processWorkSet(graph);
         }
 
         @SuppressWarnings("try")
-        private void processWorkSet(StructuredGraph graph) {
+        private int processWorkSet(StructuredGraph graph) {
+            int sum = 0;
             NodeEventListener listener = new NodeEventListener() {
 
                 @Override
@@ -228,6 +231,13 @@
                             workList.add(usage);
                         }
                     }
+
+                    if (node instanceof AbstractBeginNode) {
+                        AbstractBeginNode abstractBeginNode = (AbstractBeginNode) node;
+                        if (abstractBeginNode.predecessor() != null) {
+                            workList.add(abstractBeginNode.predecessor());
+                        }
+                    }
                 }
 
                 @Override
@@ -242,8 +252,10 @@
                     if (changed && debug.isDumpEnabled(DebugContext.DETAILED_LEVEL)) {
                         debug.dump(DebugContext.DETAILED_LEVEL, graph, "CanonicalizerPhase %s", n);
                     }
+                    ++sum;
                 }
             }
+            return sum;
         }
 
         /**
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ConditionalEliminationPhase.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ConditionalEliminationPhase.java	Mon Jul 01 14:57:02 2019 -0700
@@ -56,6 +56,7 @@
 import org.graalvm.compiler.nodes.AbstractMergeNode;
 import org.graalvm.compiler.nodes.BinaryOpLogicNode;
 import org.graalvm.compiler.nodes.ConditionAnchorNode;
+import org.graalvm.compiler.nodes.DeoptimizeNode;
 import org.graalvm.compiler.nodes.DeoptimizingGuard;
 import org.graalvm.compiler.nodes.EndNode;
 import org.graalvm.compiler.nodes.FixedGuardNode;
@@ -90,20 +91,20 @@
 import org.graalvm.compiler.nodes.extended.ValueAnchorNode;
 import org.graalvm.compiler.nodes.java.InstanceOfNode;
 import org.graalvm.compiler.nodes.java.TypeSwitchNode;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.nodes.spi.NodeWithState;
 import org.graalvm.compiler.nodes.spi.StampInverter;
 import org.graalvm.compiler.nodes.util.GraphUtil;
 import org.graalvm.compiler.phases.BasePhase;
 import org.graalvm.compiler.phases.schedule.SchedulePhase;
 import org.graalvm.compiler.phases.schedule.SchedulePhase.SchedulingStrategy;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 
 import jdk.vm.ci.meta.DeoptimizationAction;
 import jdk.vm.ci.meta.JavaConstant;
 import jdk.vm.ci.meta.SpeculationLog.Speculation;
 import jdk.vm.ci.meta.TriState;
 
-public class ConditionalEliminationPhase extends BasePhase<PhaseContext> {
+public class ConditionalEliminationPhase extends BasePhase<CoreProviders> {
 
     private static final CounterKey counterStampsRegistered = DebugContext.counter("StampsRegistered");
     private static final CounterKey counterStampsFound = DebugContext.counter("StampsFound");
@@ -123,7 +124,7 @@
 
     @Override
     @SuppressWarnings("try")
-    protected void run(StructuredGraph graph, PhaseContext context) {
+    protected void run(StructuredGraph graph, CoreProviders context) {
         try (DebugContext.Scope s = graph.getDebug().scope("DominatorConditionalElimination")) {
             BlockMap<List<Node>> blockToNodes = null;
             NodeMap<Block> nodeToBlock = null;
@@ -154,7 +155,7 @@
     }
 
     protected ControlFlowGraph.RecursiveVisitor<?> createVisitor(StructuredGraph graph, @SuppressWarnings("unused") ControlFlowGraph cfg, BlockMap<List<Node>> blockToNodes,
-                    NodeMap<Block> nodeToBlock, PhaseContext context) {
+                    NodeMap<Block> nodeToBlock, CoreProviders context) {
         return new Instance(graph, blockToNodes, nodeToBlock, context);
     }
 
@@ -302,7 +303,7 @@
          */
         private Deque<DeoptimizingGuard> pendingTests;
 
-        public Instance(StructuredGraph graph, BlockMap<List<Node>> blockToNodes, NodeMap<Block> nodeToBlock, PhaseContext context) {
+        public Instance(StructuredGraph graph, BlockMap<List<Node>> blockToNodes, NodeMap<Block> nodeToBlock, CoreProviders context) {
             this.graph = graph;
             this.debug = graph.getDebug();
             this.blockToNodes = blockToNodes;
@@ -335,19 +336,26 @@
             if (!tryProveGuardCondition(node, node.getCondition(), (guard, result, guardedValueStamp, newInput) -> {
                 if (result != node.isNegated()) {
                     node.replaceAndDelete(guard.asNode());
+                    if (guard instanceof DeoptimizingGuard && !((DeoptimizingGuard) guard).isNegated()) {
+                        rebuildPiNodes((DeoptimizingGuard) guard);
+                    }
                 } else {
-                    /*
-                     * Don't kill this branch immediately because `killCFG` can have complex
-                     * implications in the presence of loops: it might replace or delete nodes in
-                     * other branches or even above the kill point. Instead of killing immediately,
-                     * just leave the graph in a state that is easy to simplify by a subsequent
-                     * canonicalizer phase.
-                     */
-                    FixedGuardNode deopt = new FixedGuardNode(LogicConstantNode.forBoolean(result, node.graph()), node.getReason(), node.getAction(), node.getSpeculation(), node.isNegated(),
-                                    node.getNodeSourcePosition());
                     AbstractBeginNode beginNode = (AbstractBeginNode) node.getAnchor();
-                    graph.addAfterFixed(beginNode, node.graph().add(deopt));
 
+                    if (beginNode.next() instanceof DeoptimizeNode) {
+                        // This branch is already dead.
+                    } else {
+                        /*
+                         * Don't kill this branch immediately because `killCFG` can have complex
+                         * implications in the presence of loops: it might replace or delete nodes
+                         * in other branches or even above the kill point. Instead of killing
+                         * immediately, just leave the graph in a state that is easy to simplify by
+                         * a subsequent canonicalizer phase.
+                         */
+                        FixedGuardNode deopt = new FixedGuardNode(LogicConstantNode.forBoolean(result, node.graph()), node.getReason(), node.getAction(), node.getSpeculation(), node.isNegated(),
+                                        node.getNodeSourcePosition());
+                        graph.addAfterFixed(beginNode, node.graph().add(deopt));
+                    }
                 }
                 return true;
             })) {
@@ -361,41 +369,14 @@
                     node.replaceAtUsages(guard.asNode());
                     GraphUtil.unlinkFixedNode(node);
                     GraphUtil.killWithUnusedFloatingInputs(node);
+                    if (guard instanceof DeoptimizingGuard && !((DeoptimizingGuard) guard).isNegated()) {
+                        rebuildPiNodes((DeoptimizingGuard) guard);
+                    }
                 } else {
                     node.setCondition(LogicConstantNode.forBoolean(result, node.graph()), node.isNegated());
                     // Don't kill this branch immediately, see `processGuard`.
                 }
 
-                if (guard instanceof DeoptimizingGuard && !node.isNegated() && !((DeoptimizingGuard) guard).isNegated()) {
-                    LogicNode newCondition = ((DeoptimizingGuard) guard.asNode()).getCondition();
-                    if (newCondition instanceof InstanceOfNode) {
-                        InstanceOfNode inst = (InstanceOfNode) newCondition;
-                        ValueNode originalValue = GraphUtil.skipPi(inst.getValue());
-                        PiNode pi = null;
-                        // Ensure that any Pi that's weaker than what the instanceof proves is
-                        // replaced by one derived from the instanceof itself.
-                        for (PiNode existing : guard.asNode().usages().filter(PiNode.class).snapshot()) {
-                            if (!existing.isAlive()) {
-                                continue;
-                            }
-                            if (originalValue != GraphUtil.skipPi(existing.object())) {
-                                // Somehow these are unrelated values so leave it alone
-                                continue;
-                            }
-                            // If the pi has a weaker stamp or the same stamp but a different input
-                            // then replace it.
-                            boolean strongerStamp = !existing.piStamp().join(inst.getCheckedStamp()).equals(inst.getCheckedStamp());
-                            boolean differentStamp = !existing.piStamp().equals(inst.getCheckedStamp());
-                            boolean differentObject = existing.object() != inst.getValue();
-                            if (!strongerStamp && (differentStamp || differentObject)) {
-                                if (pi == null) {
-                                    pi = graph.unique(new PiNode(inst.getValue(), inst.getCheckedStamp(), (ValueNode) guard));
-                                }
-                                existing.replaceAndDelete(pi);
-                            }
-                        }
-                    }
-                }
                 debug.log("Kill fixed guard %s", node);
                 return true;
             })) {
@@ -403,6 +384,59 @@
             }
         }
 
+        private void rebuildPiNodes(DeoptimizingGuard guard) {
+            LogicNode newCondition = guard.getCondition();
+            if (newCondition instanceof InstanceOfNode) {
+                InstanceOfNode inst = (InstanceOfNode) newCondition;
+                ValueNode originalValue = GraphUtil.skipPi(inst.getValue());
+                PiNode pi = null;
+                // Ensure that any Pi that's weaker than what the instanceof proves is
+                // replaced by one derived from the instanceof itself.
+                for (PiNode existing : guard.asNode().usages().filter(PiNode.class).snapshot()) {
+                    if (!existing.isAlive()) {
+                        continue;
+                    }
+                    if (originalValue != GraphUtil.skipPi(existing.object())) {
+                        // Somehow these are unrelated values so leave it alone
+                        continue;
+                    }
+                    // If the pi has a weaker stamp or the same stamp but a different input
+                    // then replace it.
+                    boolean strongerStamp = !existing.piStamp().join(inst.getCheckedStamp()).equals(inst.getCheckedStamp());
+                    boolean differentCheckedStamp = !existing.piStamp().equals(inst.getCheckedStamp());
+                    boolean differentObject = existing.object() != inst.getValue();
+                    if (!strongerStamp && (differentCheckedStamp || differentObject)) {
+                        if (pi == null) {
+                            pi = graph.unique(new PiNode(inst.getValue(), inst.getCheckedStamp(), (ValueNode) guard));
+                        }
+                        if (!pi.stamp(NodeView.DEFAULT).join(existing.stamp(NodeView.DEFAULT)).equals(pi.stamp(NodeView.DEFAULT))) {
+                            /*
+                             * With a code sequence like null check, type check, null check of type
+                             * checked value, CE will use the first null check to prove the second
+                             * null check so the graph ends up a Pi guarded by the first null check
+                             * but consuming the output Pi from the type check check. In this case
+                             * we should still canonicalize the checked stamp for consistency.
+                             */
+                            if (differentCheckedStamp) {
+                                PiNode alternatePi = graph.unique(new PiNode(existing.object(), inst.getCheckedStamp(), (ValueNode) guard));
+                                /*
+                                 * If the resulting stamp is as good or better then do the
+                                 * replacement. However when interface types are involved it's
+                                 * possible that improving the checked stamp merges types which
+                                 * appear unrelated so there's we must skip the replacement.
+                                 */
+                                if (alternatePi.stamp(NodeView.DEFAULT).join(existing.stamp(NodeView.DEFAULT)).equals(alternatePi.stamp(NodeView.DEFAULT))) {
+                                    existing.replaceAndDelete(alternatePi);
+                                }
+                            }
+                            continue;
+                        }
+                        existing.replaceAndDelete(pi);
+                    }
+                }
+            }
+        }
+
         protected void processIf(IfNode node) {
             tryProveCondition(node.condition(), (guard, result, guardedValueStamp, newInput) -> {
                 node.setCondition(LogicConstantNode.forBoolean(result, node.graph()));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FixReadsPhase.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FixReadsPhase.java	Mon Jul 01 14:57:02 2019 -0700
@@ -69,6 +69,7 @@
 import org.graalvm.compiler.nodes.memory.FloatingReadNode;
 import org.graalvm.compiler.nodes.memory.MemoryAccess;
 import org.graalvm.compiler.nodes.memory.MemoryPhiNode;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.nodes.util.GraphUtil;
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.phases.BasePhase;
@@ -77,7 +78,6 @@
 import org.graalvm.compiler.phases.schedule.SchedulePhase;
 import org.graalvm.compiler.phases.schedule.SchedulePhase.SchedulingStrategy;
 import org.graalvm.compiler.phases.tiers.LowTierContext;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 
 import jdk.vm.ci.meta.Assumptions;
 import jdk.vm.ci.meta.Constant;
@@ -638,7 +638,7 @@
         }
     }
 
-    protected ControlFlowGraph.RecursiveVisitor<?> createVisitor(StructuredGraph graph, ScheduleResult schedule, PhaseContext context) {
+    protected ControlFlowGraph.RecursiveVisitor<?> createVisitor(StructuredGraph graph, ScheduleResult schedule, CoreProviders context) {
         return new RawConditionalEliminationVisitor(graph, schedule, context.getMetaAccess(), replaceInputsWithConstants);
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FloatingReadPhase.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/FloatingReadPhase.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -381,7 +381,8 @@
                 assert accessNode.getNullCheck() == false;
                 MemoryNode lastLocationAccess = state.getLastLocationAccess(locationIdentity);
                 try (DebugCloseable position = accessNode.withNodeSourcePosition()) {
-                    FloatingAccessNode floatingNode = accessNode.asFloatingNode(lastLocationAccess);
+                    FloatingAccessNode floatingNode = accessNode.asFloatingNode();
+                    assert floatingNode.getLastLocationAccess() == lastLocationAccess;
                     graph.replaceFixedWithFloating(accessNode, floatingNode);
                 }
             }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/IncrementalCanonicalizerPhase.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/IncrementalCanonicalizerPhase.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,16 +26,16 @@
 
 import org.graalvm.compiler.graph.Graph.NodeEventScope;
 import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.phases.BasePhase;
 import org.graalvm.compiler.phases.PhaseSuite;
 import org.graalvm.compiler.phases.common.util.EconomicSetNodeEventListener;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 
 /**
  * A phase suite that applies {@linkplain CanonicalizerPhase canonicalization} to a graph after all
  * phases in the suite have been applied if any of the phases changed the graph.
  */
-public class IncrementalCanonicalizerPhase<C extends PhaseContext> extends PhaseSuite<C> {
+public class IncrementalCanonicalizerPhase<C extends CoreProviders> extends PhaseSuite<C> {
 
     private final CanonicalizerPhase canonicalizer;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/IterativeConditionalEliminationPhase.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/IterativeConditionalEliminationPhase.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,20 +24,21 @@
 
 package org.graalvm.compiler.phases.common;
 
-import static org.graalvm.compiler.graph.Graph.NodeEvent.NODE_ADDED;
-
-import org.graalvm.compiler.core.common.RetryableBailoutException;
+import org.graalvm.compiler.core.common.GraalOptions;
+import org.graalvm.compiler.core.common.PermanentBailoutException;
+import org.graalvm.compiler.debug.TTY;
 import org.graalvm.compiler.graph.Graph.NodeEventScope;
 import org.graalvm.compiler.graph.Node;
-import org.graalvm.compiler.graph.spi.Simplifiable;
 import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.phases.BasePhase;
 import org.graalvm.compiler.phases.common.util.EconomicSetNodeEventListener;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
+import org.graalvm.compiler.phases.common.util.TracingNodeEventListener;
 
-public class IterativeConditionalEliminationPhase extends BasePhase<PhaseContext> {
+public class IterativeConditionalEliminationPhase extends BasePhase<CoreProviders> {
 
-    private static final int MAX_ITERATIONS = 256;
+    private static final boolean DEBUG_PHASE = false;
+    private static final int DEBUG_MAX_ITERATIONS = 256;
 
     private final CanonicalizerPhase canonicalizer;
     private final boolean fullSchedule;
@@ -49,25 +50,46 @@
 
     @Override
     @SuppressWarnings("try")
-    protected void run(StructuredGraph graph, PhaseContext context) {
-        EconomicSetNodeEventListener listener = new EconomicSetNodeEventListener().exclude(NODE_ADDED);
+    protected void run(StructuredGraph graph, CoreProviders context) {
+        final int maxIterations = GraalOptions.ConditionalEliminationMaxIterations.getValue(graph.getOptions());
+        EconomicSetNodeEventListener listener = new EconomicSetNodeEventListener();
         int count = 0;
+
         while (true) {
+            count++;
             try (NodeEventScope nes = graph.trackNodeEvents(listener)) {
                 new ConditionalEliminationPhase(fullSchedule).apply(graph, context);
             }
             if (listener.getNodes().isEmpty()) {
                 break;
             }
-            for (Node node : graph.getNodes()) {
-                if (node instanceof Simplifiable) {
-                    listener.getNodes().add(node);
-                }
-            }
+
             canonicalizer.applyIncremental(graph, context, listener.getNodes());
             listener.getNodes().clear();
-            if (++count > MAX_ITERATIONS) {
-                throw new RetryableBailoutException("Number of iterations in ConditionalEliminationPhase phase exceeds %d", MAX_ITERATIONS);
+
+            if (count >= maxIterations) {
+                if (DEBUG_PHASE) {
+                    if (count >= DEBUG_MAX_ITERATIONS - 5) {
+                        TTY.println();
+                        TTY.println("------------------------------------");
+                        TTY.println("Iteration " + count);
+                        TTY.println("Conditional elimination changed nodes: ");
+                        for (Node n : listener.getNodes()) {
+                            TTY.println(n.toString());
+                            for (Node input : n.inputs()) {
+                                TTY.println("    input: " + input);
+                            }
+                        }
+                        TTY.println("Canonicalization with node listener: ");
+                        try (NodeEventScope debugNes = graph.trackNodeEvents(new TracingNodeEventListener())) {
+                            canonicalizer.applyIncremental(graph, context, listener.getNodes());
+                        }
+                    }
+                    if (count >= DEBUG_MAX_ITERATIONS) {
+                        throw new PermanentBailoutException("Number of iterations in ConditionalEliminationPhase phase exceeds %d", DEBUG_MAX_ITERATIONS);
+                    }
+                }
+                break;
             }
         }
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/LoweringPhase.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/LoweringPhase.java	Mon Jul 01 14:57:02 2019 -0700
@@ -79,7 +79,6 @@
 import org.graalvm.compiler.phases.BasePhase;
 import org.graalvm.compiler.phases.Phase;
 import org.graalvm.compiler.phases.schedule.SchedulePhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.meta.ConstantReflectionProvider;
@@ -92,7 +91,7 @@
 /**
  * Processes all {@link Lowerable} nodes to do their lowering.
  */
-public class LoweringPhase extends BasePhase<PhaseContext> {
+public class LoweringPhase extends BasePhase<CoreProviders> {
 
     @NodeInfo(cycles = CYCLES_IGNORED, size = SIZE_IGNORED)
     static final class DummyGuardHandle extends ValueNode implements GuardedNode {
@@ -128,12 +127,12 @@
 
     final class LoweringToolImpl implements LoweringTool {
 
-        private final PhaseContext context;
+        private final CoreProviders context;
         private final NodeBitMap activeGuards;
         private AnchoringNode guardAnchor;
         private FixedWithNextNode lastFixedNode;
 
-        LoweringToolImpl(PhaseContext context, AnchoringNode guardAnchor, NodeBitMap activeGuards, FixedWithNextNode lastFixedNode) {
+        LoweringToolImpl(CoreProviders context, AnchoringNode guardAnchor, NodeBitMap activeGuards, FixedWithNextNode lastFixedNode) {
             this.context = context;
             this.guardAnchor = guardAnchor;
             this.activeGuards = activeGuards;
@@ -252,7 +251,7 @@
      * @param graph a graph that was just {@linkplain #lower lowered}
      * @throws AssertionError if the check fails
      */
-    private boolean checkPostLowering(StructuredGraph graph, PhaseContext context) {
+    private boolean checkPostLowering(StructuredGraph graph, CoreProviders context) {
         Mark expectedMark = graph.getMark();
         lower(graph, context, LoweringMode.VERIFY_LOWERING);
         Mark mark = graph.getMark();
@@ -261,13 +260,13 @@
     }
 
     @Override
-    protected void run(final StructuredGraph graph, PhaseContext context) {
+    protected void run(final StructuredGraph graph, CoreProviders context) {
         lower(graph, context, LoweringMode.LOWERING);
         assert checkPostLowering(graph, context);
     }
 
-    private void lower(StructuredGraph graph, PhaseContext context, LoweringMode mode) {
-        IncrementalCanonicalizerPhase<PhaseContext> incrementalCanonicalizer = new IncrementalCanonicalizerPhase<>(canonicalizer);
+    private void lower(StructuredGraph graph, CoreProviders context, LoweringMode mode) {
+        IncrementalCanonicalizerPhase<CoreProviders> incrementalCanonicalizer = new IncrementalCanonicalizerPhase<>(canonicalizer);
         incrementalCanonicalizer.appendPhase(new Round(context, mode, graph.getOptions()));
         incrementalCanonicalizer.apply(graph, context);
         assert graph.verify();
@@ -351,12 +350,12 @@
 
     private final class Round extends Phase {
 
-        private final PhaseContext context;
+        private final CoreProviders context;
         private final LoweringMode mode;
         private ScheduleResult schedule;
         private final SchedulePhase schedulePhase;
 
-        private Round(PhaseContext context, LoweringMode mode, OptionValues options) {
+        private Round(CoreProviders context, LoweringMode mode, OptionValues options) {
             this.context = context;
             this.mode = mode;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/NodeCounterPhase.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/NodeCounterPhase.java	Mon Jul 01 14:57:02 2019 -0700
@@ -27,13 +27,13 @@
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.options.Option;
 import org.graalvm.compiler.options.OptionKey;
 import org.graalvm.compiler.options.OptionType;
 import org.graalvm.compiler.phases.BasePhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 
-public class NodeCounterPhase extends BasePhase<PhaseContext> {
+public class NodeCounterPhase extends BasePhase<CoreProviders> {
 
     private Stage stage;
 
@@ -55,7 +55,7 @@
     }
 
     @Override
-    protected void run(StructuredGraph graph, PhaseContext context) {
+    protected void run(StructuredGraph graph, CoreProviders context) {
 
         for (Node node : graph.getNodes()) {
             String nodeName = node.getNodeClass().getClazz().getSimpleName();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/PropagateDeoptimizeProbabilityPhase.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/PropagateDeoptimizeProbabilityPhase.java	Mon Jul 01 14:57:02 2019 -0700
@@ -35,18 +35,18 @@
 import org.graalvm.compiler.nodes.ControlSplitNode;
 import org.graalvm.compiler.nodes.FixedNode;
 import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.phases.BasePhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 
 /**
  * This phase will make sure that the branch leading towards this deopt has 0.0 probability.
  *
  */
-public class PropagateDeoptimizeProbabilityPhase extends BasePhase<PhaseContext> {
+public class PropagateDeoptimizeProbabilityPhase extends BasePhase<CoreProviders> {
 
     @Override
     @SuppressWarnings("try")
-    protected void run(final StructuredGraph graph, PhaseContext context) {
+    protected void run(final StructuredGraph graph, CoreProviders context) {
         assert !graph.hasValueProxies() : "ConvertDeoptimizeToGuardPhase always creates proxies";
 
         if (graph.hasNode(AbstractDeoptimizeNode.TYPE)) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/UseTrappingNullChecksPhase.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/UseTrappingNullChecksPhase.java	Mon Jul 01 14:57:02 2019 -0700
@@ -41,6 +41,7 @@
 import org.graalvm.compiler.nodes.DeoptimizeNode;
 import org.graalvm.compiler.nodes.DeoptimizingFixedWithNextNode;
 import org.graalvm.compiler.nodes.DynamicDeoptimizeNode;
+import org.graalvm.compiler.nodes.EndNode;
 import org.graalvm.compiler.nodes.FixedNode;
 import org.graalvm.compiler.nodes.IfNode;
 import org.graalvm.compiler.nodes.LogicNode;
@@ -115,6 +116,7 @@
                 reasons = reasonPhi.values().snapshot();
                 expectedPhis++;
             } else if (!reason.isConstant()) {
+                merge.getDebug().log("Non constant reason %s", merge);
                 return;
             }
 
@@ -135,29 +137,41 @@
             }
 
             int index = 0;
-            for (AbstractEndNode end : merge.cfgPredecessors().snapshot()) {
+            List<EndNode> predecessors = merge.cfgPredecessors().snapshot();
+            for (AbstractEndNode end : predecessors) {
+                Node endPredecesssor = end.predecessor();
                 ValueNode thisReason = reasons != null ? reasons.get(index) : reason;
                 ValueNode thisSpeculation = speculations != null ? speculations.get(index) : speculation;
+                if (!merge.isAlive()) {
+                    // When evacuating a merge the last successor simplfies the merge away so it
+                    // must be handled specially.
+                    assert predecessors.get(predecessors.size() - 1) == end : "must be last end";
+                    endPredecesssor = deopt.predecessor();
+                    thisSpeculation = deopt.getSpeculation();
+                    thisReason = deopt.getActionAndReason();
+                }
+
                 index++;
                 if (!thisReason.isConstant() || !thisSpeculation.isConstant()) {
-                    continue;
-                }
-                Speculation speculationConstant = metaAccessProvider.decodeSpeculation(thisSpeculation.asJavaConstant(), deopt.graph().getSpeculationLog());
-                if (!speculationConstant.equals(SpeculationLog.NO_SPECULATION)) {
+                    end.getDebug().log("Non constant deopt %s", end);
                     continue;
                 }
                 DeoptimizationReason deoptimizationReason = metaAccessProvider.decodeDeoptReason(thisReason.asJavaConstant());
-                tryUseTrappingNullCheck(deopt, end.predecessor(), deoptimizationReason, SpeculationLog.NO_SPECULATION, implicitNullCheckLimit);
+                Speculation speculationConstant = metaAccessProvider.decodeSpeculation(thisSpeculation.asJavaConstant(), deopt.graph().getSpeculationLog());
+                tryUseTrappingNullCheck(deopt, endPredecesssor, deoptimizationReason, speculationConstant, implicitNullCheckLimit);
             }
         }
     }
 
     private static void tryUseTrappingNullCheck(AbstractDeoptimizeNode deopt, Node predecessor, DeoptimizationReason deoptimizationReason, Speculation speculation, long implicitNullCheckLimit) {
+        assert predecessor != null;
         if (deoptimizationReason != DeoptimizationReason.NullCheckException && deoptimizationReason != DeoptimizationReason.UnreachedCode) {
+            deopt.getDebug().log(DebugContext.INFO_LEVEL, "Not a null check or unreached %s", predecessor);
             return;
         }
         assert speculation != null;
         if (!speculation.equals(SpeculationLog.NO_SPECULATION)) {
+            deopt.getDebug().log(DebugContext.INFO_LEVEL, "Has a speculation %s", predecessor);
             return;
         }
         if (predecessor instanceof AbstractMergeNode) {
@@ -169,6 +183,8 @@
             }
         } else if (predecessor instanceof AbstractBeginNode) {
             checkPredecessor(deopt, predecessor, deoptimizationReason, implicitNullCheckLimit);
+        } else {
+            deopt.getDebug().log(DebugContext.INFO_LEVEL, "Not a Begin or Merge %s", predecessor);
         }
     }
 
@@ -233,6 +249,7 @@
                         deopt.graph().removeSplit(ifNode, nonTrappingContinuation);
                         trappingNullCheck = fixedAccessNode;
                         counterTrappingNullCheckExistingRead.increment(debug);
+                        deopt.getDebug().log("Added implicit null check to %s", fixedAccessNode);
                     }
                 }
             }
@@ -242,6 +259,7 @@
             // Need to add a null check node.
             trappingNullCheck = deopt.graph().add(new NullCheckNode(value));
             deopt.graph().replaceSplit(ifNode, trappingNullCheck, nonTrappingContinuation);
+            deopt.getDebug().log("Inserted NullCheckNode %s", trappingNullCheck);
         }
 
         trappingNullCheck.setStateBefore(deopt.stateBefore());
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/WriteBarrierAdditionPhase.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.phases.common;
+
+import org.graalvm.compiler.debug.DebugCloseable;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.gc.BarrierSet;
+import org.graalvm.compiler.nodes.memory.FixedAccessNode;
+import org.graalvm.compiler.phases.BasePhase;
+import org.graalvm.compiler.phases.tiers.MidTierContext;
+
+public class WriteBarrierAdditionPhase extends BasePhase<MidTierContext> {
+    @SuppressWarnings("try")
+    @Override
+    protected void run(StructuredGraph graph, MidTierContext context) {
+        BarrierSet barrierSet = context.getGC().getBarrierSet();
+        for (FixedAccessNode n : graph.getNodes().filter(FixedAccessNode.class)) {
+            try (DebugCloseable scope = n.graph().withNodeSourcePosition(n)) {
+                barrierSet.addBarriers(n);
+            }
+        }
+    }
+
+    @Override
+    public boolean checkContract() {
+        return false;
+    }
+}
+
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/InliningUtil.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/InliningUtil.java	Mon Jul 01 14:57:02 2019 -0700
@@ -381,7 +381,7 @@
             throw new IllegalStateException("Inlined graph is in invalid state: " + inlineGraph);
         }
         for (Node node : inlineGraph.getNodes()) {
-            if (node == entryPointNode || (node == entryPointNode.stateAfter() && node.usages().count() == 1) || node instanceof ParameterNode) {
+            if (node == entryPointNode || (node == entryPointNode.stateAfter() && node.hasExactlyOneUsage()) || node instanceof ParameterNode) {
                 // Do nothing.
             } else {
                 nodes.add(node);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/walker/InliningData.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/inlining/walker/InliningData.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -145,7 +145,11 @@
         OptionValues options = rootGraph.getOptions();
         if (method == null) {
             return "the method is not resolved";
-        } else if (method.isNative() && (!Intrinsify.getValue(options) || !context.getReplacements().hasSubstitution(method, invokeBci))) {
+        } else if (method.isNative() && !(Intrinsify.getValue(options) &&
+                        context.getReplacements().getSubstitution(method, invokeBci, rootGraph.trackNodeSourcePosition(), null, options) != null)) {
+            // We have conditional intrinsic, e.g., String.intern, which may not have inlineable
+            // graph depending on the context. The getSubstitution test ensures the inlineable
+            // graph is present.
             return "it is a non-intrinsic native method";
         } else if (method.isAbstract()) {
             return "it is an abstract method";
@@ -155,8 +159,6 @@
             return "it is marked non-inlinable";
         } else if (countRecursiveInlining(method) > MaximumRecursiveInlining.getValue(options)) {
             return "it exceeds the maximum recursive inlining depth";
-        } else if (!method.hasBytecodes()) {
-            return "it has no bytecodes to inline";
         } else {
             if (new OptimisticOptimizations(rootGraph.getProfilingInfo(method), options).lessOptimisticThan(context.getOptimisticOptimizations())) {
                 return "the callee uses less optimistic optimizations than caller";
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/util/EconomicSetNodeEventListener.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/util/EconomicSetNodeEventListener.java	Mon Jul 01 14:57:02 2019 -0700
@@ -33,6 +33,7 @@
 import org.graalvm.compiler.graph.Graph.NodeEventListener;
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.graph.Node.IndirectCanonicalization;
+import org.graalvm.compiler.nodes.AbstractBeginNode;
 
 /**
  * A simple {@link NodeEventListener} implementation that accumulates event nodes in a
@@ -48,7 +49,7 @@
      */
     public EconomicSetNodeEventListener() {
         this.nodes = EconomicSet.create(Equivalence.IDENTITY);
-        this.filter = EnumSet.allOf(NodeEvent.class);
+        this.filter = EnumSet.of(NodeEvent.INPUT_CHANGED, NodeEvent.NODE_ADDED, NodeEvent.ZERO_USAGES);
     }
 
     /**
@@ -71,12 +72,23 @@
     @Override
     public void changed(NodeEvent e, Node node) {
         if (filter.contains(e)) {
-            nodes.add(node);
+            add(node);
             if (node instanceof IndirectCanonicalization) {
                 for (Node usage : node.usages()) {
-                    nodes.add(usage);
+                    add(usage);
                 }
             }
+
+            if (node instanceof AbstractBeginNode) {
+                AbstractBeginNode abstractBeginNode = (AbstractBeginNode) node;
+                add(abstractBeginNode.predecessor());
+            }
+        }
+    }
+
+    private void add(Node n) {
+        if (n != null) {
+            nodes.add(n);
         }
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/util/TracingNodeEventListener.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.phases.common.util;
+
+import org.graalvm.compiler.debug.TTY;
+import org.graalvm.compiler.graph.Graph.NodeEvent;
+import org.graalvm.compiler.graph.Graph.NodeEventListener;
+import org.graalvm.compiler.graph.Node;
+
+/**
+ * A simple {@link NodeEventListener} implementation that traces events to TTY for debugging
+ * purposes.
+ */
+public class TracingNodeEventListener extends NodeEventListener {
+
+    @Override
+    public void changed(NodeEvent e, Node node) {
+        TTY.println(e.toString() + ": " + node);
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/PhaseSuite.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/PhaseSuite.java	Mon Jul 01 14:57:02 2019 -0700
@@ -195,10 +195,7 @@
                 return true;
             } else if (phase instanceof PhaseSuite) {
                 PhaseSuite<C> innerSuite = (PhaseSuite<C>) phase;
-                if (innerSuite.removePhase(phaseClass)) {
-                    if (innerSuite.phases.isEmpty()) {
-                        it.set(newPhase);
-                    }
+                if (innerSuite.replacePhase(phaseClass, newPhase)) {
                     return true;
                 }
             }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/schedule/SchedulePhase.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/schedule/SchedulePhase.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -94,7 +94,7 @@
         EARLIEST,
         LATEST,
         LATEST_OUT_OF_LOOPS,
-        FINAL_SCHEDULE;
+        LATEST_OUT_OF_LOOPS_IMPLICIT_NULL_CHECKS;
 
         public boolean isEarliest() {
             return this == EARLIEST || this == EARLIEST_WITH_GUARD_ORDER;
@@ -103,6 +103,14 @@
         public boolean isLatest() {
             return !isEarliest();
         }
+
+        public boolean scheduleOutOfLoops() {
+            return this == LATEST_OUT_OF_LOOPS || this == LATEST_OUT_OF_LOOPS_IMPLICIT_NULL_CHECKS;
+        }
+
+        public boolean considerImplicitNullChecks() {
+            return this == LATEST_OUT_OF_LOOPS_IMPLICIT_NULL_CHECKS;
+        }
     }
 
     private final SchedulingStrategy selectedStrategy;
@@ -228,8 +236,14 @@
                     } else {
                         Block latestBlock = null;
 
+                        if (currentBlock.getFirstDominated() == null && !(currentNode instanceof VirtualState)) {
+                            // This block doesn't dominate any other blocks =>
+                            // node must be scheduled in earliest block.
+                            latestBlock = currentBlock;
+                        }
+
                         LocationIdentity constrainingLocation = null;
-                        if (currentNode instanceof FloatingReadNode) {
+                        if (latestBlock == null && currentNode instanceof FloatingReadNode) {
                             // We are scheduling a floating read node => check memory
                             // anti-dependencies.
                             FloatingReadNode floatingReadNode = (FloatingReadNode) currentNode;
@@ -544,7 +558,7 @@
 
                 assert latestBlock != null : currentNode;
 
-                if (strategy == SchedulingStrategy.FINAL_SCHEDULE || strategy == SchedulingStrategy.LATEST_OUT_OF_LOOPS) {
+                if (strategy.scheduleOutOfLoops()) {
                     Block currentBlock = latestBlock;
                     while (currentBlock.getLoopDepth() > earliestBlock.getLoopDepth() && currentBlock != earliestBlock.getDominator()) {
                         Block previousCurrentBlock = currentBlock;
@@ -564,27 +578,25 @@
                 }
             }
 
-            if (latestBlock != earliestBlock && currentNode instanceof FloatingReadNode) {
-
-                FloatingReadNode floatingReadNode = (FloatingReadNode) currentNode;
-                if (isImplicitNullOpportunity(floatingReadNode, earliestBlock) &&
-                                earliestBlock.getRelativeFrequency() < latestBlock.getRelativeFrequency() * IMPLICIT_NULL_CHECK_OPPORTUNITY_PROBABILITY_FACTOR) {
-                    latestBlock = earliestBlock;
-                }
+            if (latestBlock != earliestBlock && strategy.considerImplicitNullChecks() && isImplicitNullOpportunity(currentNode, earliestBlock) &&
+                            earliestBlock.getRelativeFrequency() < latestBlock.getRelativeFrequency() * IMPLICIT_NULL_CHECK_OPPORTUNITY_PROBABILITY_FACTOR) {
+                latestBlock = earliestBlock;
             }
 
             selectLatestBlock(currentNode, earliestBlock, latestBlock, currentNodeMap, watchListMap, constrainingLocation, latestBlockToNodesMap);
         }
 
-        private static boolean isImplicitNullOpportunity(FloatingReadNode floatingReadNode, Block block) {
-
-            Node pred = block.getBeginNode().predecessor();
-            if (pred instanceof IfNode) {
-                IfNode ifNode = (IfNode) pred;
-                if (ifNode.condition() instanceof IsNullNode) {
-                    IsNullNode isNullNode = (IsNullNode) ifNode.condition();
-                    if (getUnproxifiedUncompressed(floatingReadNode.getAddress().getBase()) == getUnproxifiedUncompressed(isNullNode.getValue())) {
-                        return true;
+        protected static boolean isImplicitNullOpportunity(Node currentNode, Block block) {
+            if (currentNode instanceof FloatingReadNode) {
+                FloatingReadNode floatingReadNode = (FloatingReadNode) currentNode;
+                Node pred = block.getBeginNode().predecessor();
+                if (pred instanceof IfNode) {
+                    IfNode ifNode = (IfNode) pred;
+                    if (ifNode.condition() instanceof IsNullNode && ifNode.getTrueSuccessorProbability() == 0.0) {
+                        IsNullNode isNullNode = (IsNullNode) ifNode.condition();
+                        if (getUnproxifiedUncompressed(floatingReadNode.getAddress().getBase()) == getUnproxifiedUncompressed(isNullNode.getValue())) {
+                            return true;
+                        }
                     }
                 }
             }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/tiers/HighTierContext.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/tiers/HighTierContext.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,11 +24,12 @@
 
 package org.graalvm.compiler.phases.tiers;
 
+import org.graalvm.compiler.nodes.spi.CoreProvidersDelegate;
 import org.graalvm.compiler.phases.OptimisticOptimizations;
 import org.graalvm.compiler.phases.PhaseSuite;
 import org.graalvm.compiler.phases.util.Providers;
 
-public class HighTierContext extends PhaseContext {
+public class HighTierContext extends CoreProvidersDelegate {
 
     private final PhaseSuite<HighTierContext> graphBuilderSuite;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/tiers/LowTierContext.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/tiers/LowTierContext.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,11 +24,12 @@
 
 package org.graalvm.compiler.phases.tiers;
 
+import org.graalvm.compiler.nodes.spi.CoreProvidersDelegate;
 import org.graalvm.compiler.phases.util.Providers;
 
 import jdk.vm.ci.code.TargetDescription;
 
-public class LowTierContext extends PhaseContext {
+public class LowTierContext extends CoreProvidersDelegate {
 
     private final TargetProvider target;
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/tiers/MidTierContext.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/tiers/MidTierContext.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,13 +24,14 @@
 
 package org.graalvm.compiler.phases.tiers;
 
+import org.graalvm.compiler.nodes.spi.CoreProvidersDelegate;
 import org.graalvm.compiler.phases.OptimisticOptimizations;
 import org.graalvm.compiler.phases.util.Providers;
 
 import jdk.vm.ci.code.TargetDescription;
 import jdk.vm.ci.meta.ProfilingInfo;
 
-public class MidTierContext extends PhaseContext {
+public class MidTierContext extends CoreProvidersDelegate {
 
     private final TargetProvider target;
     private final OptimisticOptimizations optimisticOpts;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/tiers/PhaseContext.java	Wed Jun 26 15:34:13 2019 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package org.graalvm.compiler.phases.tiers;
-
-import org.graalvm.compiler.core.common.spi.ConstantFieldProvider;
-import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
-import org.graalvm.compiler.nodes.spi.CoreProviders;
-import org.graalvm.compiler.nodes.spi.LoweringProvider;
-import org.graalvm.compiler.nodes.spi.Replacements;
-import org.graalvm.compiler.nodes.spi.StampProvider;
-
-import jdk.vm.ci.meta.ConstantReflectionProvider;
-import jdk.vm.ci.meta.MetaAccessProvider;
-
-public class PhaseContext implements CoreProviders {
-
-    private final CoreProviders providers;
-
-    public PhaseContext(CoreProviders providers) {
-        this.providers = providers;
-    }
-
-    @Override
-    public MetaAccessProvider getMetaAccess() {
-        return providers.getMetaAccess();
-    }
-
-    @Override
-    public ConstantReflectionProvider getConstantReflection() {
-        return providers.getConstantReflection();
-    }
-
-    @Override
-    public ConstantFieldProvider getConstantFieldProvider() {
-        return providers.getConstantFieldProvider();
-    }
-
-    @Override
-    public LoweringProvider getLowerer() {
-        return providers.getLowerer();
-    }
-
-    @Override
-    public Replacements getReplacements() {
-        return providers.getReplacements();
-    }
-
-    @Override
-    public StampProvider getStampProvider() {
-        return providers.getStampProvider();
-    }
-
-    @Override
-    public ForeignCallsProvider getForeignCalls() {
-        return providers.getForeignCalls();
-    }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/util/Providers.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/util/Providers.java	Mon Jul 01 14:57:02 2019 -0700
@@ -27,11 +27,12 @@
 import org.graalvm.compiler.core.common.spi.CodeGenProviders;
 import org.graalvm.compiler.core.common.spi.ConstantFieldProvider;
 import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.nodes.spi.CoreProvidersImpl;
+import org.graalvm.compiler.nodes.spi.GCProvider;
 import org.graalvm.compiler.nodes.spi.LoweringProvider;
 import org.graalvm.compiler.nodes.spi.Replacements;
 import org.graalvm.compiler.nodes.spi.StampProvider;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 
 import jdk.vm.ci.code.CodeCacheProvider;
 import jdk.vm.ci.meta.ConstantReflectionProvider;
@@ -45,19 +46,19 @@
     private final CodeCacheProvider codeCache;
 
     public Providers(MetaAccessProvider metaAccess, CodeCacheProvider codeCache, ConstantReflectionProvider constantReflection, ConstantFieldProvider constantFieldProvider,
-                    ForeignCallsProvider foreignCalls, LoweringProvider lowerer, Replacements replacements, StampProvider stampProvider) {
-        super(metaAccess, constantReflection, constantFieldProvider, lowerer, replacements, stampProvider, foreignCalls);
+                    ForeignCallsProvider foreignCalls, LoweringProvider lowerer, Replacements replacements, StampProvider stampProvider, GCProvider gc) {
+        super(metaAccess, constantReflection, constantFieldProvider, lowerer, replacements, stampProvider, foreignCalls, gc);
         this.codeCache = codeCache;
     }
 
     public Providers(Providers copyFrom) {
         this(copyFrom.getMetaAccess(), copyFrom.getCodeCache(), copyFrom.getConstantReflection(), copyFrom.getConstantFieldProvider(), copyFrom.getForeignCalls(), copyFrom.getLowerer(),
-                        copyFrom.getReplacements(), copyFrom.getStampProvider());
+                        copyFrom.getReplacements(), copyFrom.getStampProvider(), copyFrom.getGC());
     }
 
-    public Providers(PhaseContext copyFrom) {
+    public Providers(CoreProviders copyFrom) {
         this(copyFrom.getMetaAccess(), null, copyFrom.getConstantReflection(), copyFrom.getConstantFieldProvider(), null, copyFrom.getLowerer(), copyFrom.getReplacements(),
-                        copyFrom.getStampProvider());
+                        copyFrom.getStampProvider(), copyFrom.getGC());
     }
 
     @Override
@@ -67,41 +68,46 @@
 
     public Providers copyWith(MetaAccessProvider substitution) {
         assert this.getClass() == Providers.class : "must override";
-        return new Providers(substitution, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, stampProvider);
+        return new Providers(substitution, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, stampProvider, gc);
     }
 
     public Providers copyWith(CodeCacheProvider substitution) {
         assert this.getClass() == Providers.class : "must override";
-        return new Providers(metaAccess, substitution, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, stampProvider);
+        return new Providers(metaAccess, substitution, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, stampProvider, gc);
     }
 
     public Providers copyWith(ConstantReflectionProvider substitution) {
         assert this.getClass() == Providers.class : "must override";
-        return new Providers(metaAccess, codeCache, substitution, constantFieldProvider, foreignCalls, lowerer, replacements, stampProvider);
+        return new Providers(metaAccess, codeCache, substitution, constantFieldProvider, foreignCalls, lowerer, replacements, stampProvider, gc);
     }
 
     public Providers copyWith(ConstantFieldProvider substitution) {
         assert this.getClass() == Providers.class : "must override";
-        return new Providers(metaAccess, codeCache, constantReflection, substitution, foreignCalls, lowerer, replacements, stampProvider);
+        return new Providers(metaAccess, codeCache, constantReflection, substitution, foreignCalls, lowerer, replacements, stampProvider, gc);
     }
 
     public Providers copyWith(ForeignCallsProvider substitution) {
         assert this.getClass() == Providers.class : "must override";
-        return new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, substitution, lowerer, replacements, stampProvider);
+        return new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, substitution, lowerer, replacements, stampProvider, gc);
     }
 
     public Providers copyWith(LoweringProvider substitution) {
         assert this.getClass() == Providers.class : "must override";
-        return new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, substitution, replacements, stampProvider);
+        return new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, substitution, replacements, stampProvider, gc);
     }
 
     public Providers copyWith(Replacements substitution) {
         assert this.getClass() == Providers.class : "must override in " + getClass();
-        return new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, substitution, stampProvider);
+        return new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, substitution, stampProvider, gc);
     }
 
     public Providers copyWith(StampProvider substitution) {
         assert this.getClass() == Providers.class : "must override";
-        return new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, substitution);
+        return new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, substitution, gc);
+    }
+
+    public Providers copyWith(GCProvider substitution) {
+        assert this.getClass() == Providers.class : "must override";
+        return new Providers(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, stampProvider, substitution);
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64GraphBuilderPlugins.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64GraphBuilderPlugins.java	Mon Jul 01 14:57:02 2019 -0700
@@ -31,9 +31,6 @@
 import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.LOG10;
 import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.SIN;
 import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.TAN;
-import static org.graalvm.compiler.serviceprovider.JavaVersionUtil.JAVA_SPECIFICATION_VERSION;
-import static org.graalvm.compiler.serviceprovider.JavaVersionUtil.Java11OrEarlier;
-import static org.graalvm.compiler.serviceprovider.JavaVersionUtil.Java8OrEarlier;
 
 import org.graalvm.compiler.bytecode.BytecodeProvider;
 import org.graalvm.compiler.lir.aarch64.AArch64ArithmeticLIRGeneratorTool.RoundingMode;
@@ -51,6 +48,7 @@
 import org.graalvm.compiler.replacements.nodes.BinaryMathIntrinsicNode;
 import org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode;
 import org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation;
+import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
 import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.meta.JavaKind;
@@ -166,7 +164,7 @@
     }
 
     private static void registerStringLatin1Plugins(InvocationPlugins plugins, BytecodeProvider replacementsBytecodeProvider) {
-        if (JAVA_SPECIFICATION_VERSION >= 9) {
+        if (JavaVersionUtil.JAVA_SPEC >= 9) {
             Registration r = new Registration(plugins, "java.lang.StringLatin1", replacementsBytecodeProvider);
             r.setAllowOverwrite(true);
             r.registerMethodSubstitution(AArch64StringLatin1Substitutions.class, "compareTo", byte[].class, byte[].class);
@@ -175,7 +173,7 @@
     }
 
     private static void registerStringUTF16Plugins(InvocationPlugins plugins, BytecodeProvider replacementsBytecodeProvider) {
-        if (JAVA_SPECIFICATION_VERSION >= 9) {
+        if (JavaVersionUtil.JAVA_SPEC >= 9) {
             Registration r = new Registration(plugins, "java.lang.StringUTF16", replacementsBytecodeProvider);
             r.setAllowOverwrite(true);
             r.registerMethodSubstitution(AArch64StringUTF16Substitutions.class, "compareTo", byte[].class, byte[].class);
@@ -186,10 +184,10 @@
     private static void registerUnsafePlugins(InvocationPlugins plugins, BytecodeProvider replacementsBytecodeProvider) {
         registerUnsafePlugins(new Registration(plugins, Unsafe.class),
                         new JavaKind[]{JavaKind.Int, JavaKind.Long, JavaKind.Object}, "Object");
-        if (!Java8OrEarlier) {
+        if (JavaVersionUtil.JAVA_SPEC > 8) {
             registerUnsafePlugins(new Registration(plugins, "jdk.internal.misc.Unsafe", replacementsBytecodeProvider),
                             new JavaKind[]{JavaKind.Int, JavaKind.Long, JavaKind.Object},
-                            Java11OrEarlier ? "Object" : "Reference");
+                            JavaVersionUtil.JAVA_SPEC <= 11 ? "Object" : "Reference");
         }
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64ArrayIndexOf.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64ArrayIndexOf.java	Mon Jul 01 14:57:02 2019 -0700
@@ -25,101 +25,100 @@
 package org.graalvm.compiler.replacements.amd64;
 
 import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
-import org.graalvm.compiler.graph.Node.ConstantNodeParameter;
-import org.graalvm.compiler.nodes.extended.ForeignCallNode;
-import jdk.internal.vm.compiler.word.Pointer;
-
-import static org.graalvm.compiler.graph.Node.NodeIntrinsic;
 
 public class AMD64ArrayIndexOf {
 
     public static final ForeignCallDescriptor STUB_INDEX_OF_TWO_CONSECUTIVE_BYTES = new ForeignCallDescriptor(
-                    "indexOfTwoConsecutiveBytes", int.class, Pointer.class, int.class, int.class);
+                    "indexOfTwoConsecutiveBytes", int.class, byte[].class, int.class, int.class, int.class);
     public static final ForeignCallDescriptor STUB_INDEX_OF_TWO_CONSECUTIVE_CHARS = new ForeignCallDescriptor(
-                    "indexOfTwoConsecutiveChars", int.class, Pointer.class, int.class, int.class);
+                    "indexOfTwoConsecutiveChars", int.class, char[].class, int.class, int.class, int.class);
+    public static final ForeignCallDescriptor STUB_INDEX_OF_TWO_CONSECUTIVE_CHARS_COMPACT = new ForeignCallDescriptor(
+                    "indexOfTwoConsecutiveCharsCompact", int.class, byte[].class, int.class, int.class, int.class);
     public static final ForeignCallDescriptor STUB_INDEX_OF_1_BYTE = new ForeignCallDescriptor(
-                    "indexOf1Byte", int.class, Pointer.class, int.class, byte.class);
+                    "indexOf1Byte", int.class, byte[].class, int.class, int.class, byte.class);
     public static final ForeignCallDescriptor STUB_INDEX_OF_2_BYTES = new ForeignCallDescriptor(
-                    "indexOf2Bytes", int.class, Pointer.class, int.class, byte.class, byte.class);
+                    "indexOf2Bytes", int.class, byte[].class, int.class, int.class, byte.class, byte.class);
     public static final ForeignCallDescriptor STUB_INDEX_OF_3_BYTES = new ForeignCallDescriptor(
-                    "indexOf3Bytes", int.class, Pointer.class, int.class, byte.class, byte.class, byte.class);
+                    "indexOf3Bytes", int.class, byte[].class, int.class, int.class, byte.class, byte.class, byte.class);
     public static final ForeignCallDescriptor STUB_INDEX_OF_4_BYTES = new ForeignCallDescriptor(
-                    "indexOf4Bytes", int.class, Pointer.class, int.class, byte.class, byte.class, byte.class, byte.class);
+                    "indexOf4Bytes", int.class, byte[].class, int.class, int.class, byte.class, byte.class, byte.class, byte.class);
     public static final ForeignCallDescriptor STUB_INDEX_OF_1_CHAR = new ForeignCallDescriptor(
-                    "indexOf1Char", int.class, Pointer.class, int.class, char.class);
+                    "indexOf1Char", int.class, char[].class, int.class, int.class, char.class);
     public static final ForeignCallDescriptor STUB_INDEX_OF_2_CHARS = new ForeignCallDescriptor(
-                    "indexOf2Chars", int.class, Pointer.class, int.class, char.class, char.class);
+                    "indexOf2Chars", int.class, char[].class, int.class, int.class, char.class, char.class);
     public static final ForeignCallDescriptor STUB_INDEX_OF_3_CHARS = new ForeignCallDescriptor(
-                    "indexOf3Chars", int.class, Pointer.class, int.class, char.class, char.class, char.class);
+                    "indexOf3Chars", int.class, char[].class, int.class, int.class, char.class, char.class, char.class);
     public static final ForeignCallDescriptor STUB_INDEX_OF_4_CHARS = new ForeignCallDescriptor(
-                    "indexOf4Chars", int.class, Pointer.class, int.class, char.class, char.class, char.class, char.class);
+                    "indexOf4Chars", int.class, char[].class, int.class, int.class, char.class, char.class, char.class, char.class);
+    public static final ForeignCallDescriptor STUB_INDEX_OF_1_CHAR_COMPACT = new ForeignCallDescriptor(
+                    "indexOf1CharCompact", int.class, byte[].class, int.class, int.class, char.class);
+    public static final ForeignCallDescriptor STUB_INDEX_OF_2_CHARS_COMPACT = new ForeignCallDescriptor(
+                    "indexOf2CharsCompact", int.class, byte[].class, int.class, int.class, char.class, char.class);
+    public static final ForeignCallDescriptor STUB_INDEX_OF_3_CHARS_COMPACT = new ForeignCallDescriptor(
+                    "indexOf3CharsCompact", int.class, byte[].class, int.class, int.class, char.class, char.class, char.class);
+    public static final ForeignCallDescriptor STUB_INDEX_OF_4_CHARS_COMPACT = new ForeignCallDescriptor(
+                    "indexOf4CharsCompact", int.class, byte[].class, int.class, int.class, char.class, char.class, char.class, char.class);
 
-    public static int indexOfTwoConsecutiveBytes(Pointer arrayPointer, int arrayLength, byte b1, byte b2) {
+    public static int indexOfTwoConsecutiveBytes(byte[] array, int arrayLength, int fromIndex, byte b1, byte b2) {
         int searchValue = (Byte.toUnsignedInt(b2) << Byte.SIZE) | Byte.toUnsignedInt(b1);
-        return callInt(STUB_INDEX_OF_TWO_CONSECUTIVE_BYTES, arrayPointer, arrayLength, searchValue);
+        return AMD64ArrayIndexOfDispatchNode.indexOf2ConsecutiveBytes(STUB_INDEX_OF_TWO_CONSECUTIVE_BYTES, array, arrayLength, fromIndex, searchValue);
     }
 
-    public static int indexOfTwoConsecutiveChars(Pointer arrayPointer, int arrayLength, char c1, char c2) {
+    public static int indexOfTwoConsecutiveChars(char[] array, int arrayLength, int fromIndex, char c1, char c2) {
         int searchValue = (c2 << Character.SIZE) | c1;
-        return callInt(STUB_INDEX_OF_TWO_CONSECUTIVE_CHARS, arrayPointer, arrayLength, searchValue);
+        return AMD64ArrayIndexOfDispatchNode.indexOf2ConsecutiveChars(STUB_INDEX_OF_TWO_CONSECUTIVE_CHARS, array, arrayLength, fromIndex, searchValue);
     }
 
-    public static int indexOf1Byte(Pointer arrayPointer, int arrayLength, byte b) {
-        return callByte1(STUB_INDEX_OF_1_BYTE, arrayPointer, arrayLength, b);
-    }
-
-    public static int indexOf2Bytes(Pointer arrayPointer, int arrayLength, byte b1, byte b2) {
-        return callByte2(STUB_INDEX_OF_2_BYTES, arrayPointer, arrayLength, b1, b2);
-    }
-
-    public static int indexOf3Bytes(Pointer arrayPointer, int arrayLength, byte b1, byte b2, byte b3) {
-        return callByte3(STUB_INDEX_OF_3_BYTES, arrayPointer, arrayLength, b1, b2, b3);
+    public static int indexOfTwoConsecutiveChars(byte[] array, int arrayLength, int fromIndex, char c1, char c2) {
+        int searchValue = (c2 << Character.SIZE) | c1;
+        return AMD64ArrayIndexOfDispatchNode.indexOf2ConsecutiveChars(STUB_INDEX_OF_TWO_CONSECUTIVE_CHARS_COMPACT, array, arrayLength, fromIndex, searchValue);
     }
 
-    public static int indexOf4Bytes(Pointer arrayPointer, int arrayLength, byte b1, byte b2, byte b3, byte b4) {
-        return callByte4(STUB_INDEX_OF_4_BYTES, arrayPointer, arrayLength, b1, b2, b3, b4);
+    public static int indexOf1Byte(byte[] array, int arrayLength, int fromIndex, byte b) {
+        return AMD64ArrayIndexOfDispatchNode.indexOf(STUB_INDEX_OF_1_BYTE, array, arrayLength, fromIndex, b);
     }
 
-    public static int indexOf1Char(Pointer arrayPointer, int arrayLength, char c) {
-        return callChar1(STUB_INDEX_OF_1_CHAR, arrayPointer, arrayLength, c);
+    public static int indexOf2Bytes(byte[] array, int arrayLength, int fromIndex, byte b1, byte b2) {
+        return AMD64ArrayIndexOfDispatchNode.indexOf(STUB_INDEX_OF_2_BYTES, array, arrayLength, fromIndex, b1, b2);
     }
 
-    public static int indexOf2Chars(Pointer arrayPointer, int arrayLength, char c1, char c2) {
-        return callChar2(STUB_INDEX_OF_2_CHARS, arrayPointer, arrayLength, c1, c2);
+    public static int indexOf3Bytes(byte[] array, int arrayLength, int fromIndex, byte b1, byte b2, byte b3) {
+        return AMD64ArrayIndexOfDispatchNode.indexOf(STUB_INDEX_OF_3_BYTES, array, arrayLength, fromIndex, b1, b2, b3);
     }
 
-    public static int indexOf3Chars(Pointer arrayPointer, int arrayLength, char c1, char c2, char c3) {
-        return callChar3(STUB_INDEX_OF_3_CHARS, arrayPointer, arrayLength, c1, c2, c3);
+    public static int indexOf4Bytes(byte[] array, int arrayLength, int fromIndex, byte b1, byte b2, byte b3, byte b4) {
+        return AMD64ArrayIndexOfDispatchNode.indexOf(STUB_INDEX_OF_4_BYTES, array, arrayLength, fromIndex, b1, b2, b3, b4);
     }
 
-    public static int indexOf4Chars(Pointer arrayPointer, int arrayLength, char c1, char c2, char c3, char c4) {
-        return callChar4(STUB_INDEX_OF_4_CHARS, arrayPointer, arrayLength, c1, c2, c3, c4);
+    public static int indexOf1Char(char[] array, int arrayLength, int fromIndex, char c) {
+        return AMD64ArrayIndexOfDispatchNode.indexOf(STUB_INDEX_OF_1_CHAR, array, arrayLength, fromIndex, c);
+    }
+
+    public static int indexOf2Chars(char[] array, int arrayLength, int fromIndex, char c1, char c2) {
+        return AMD64ArrayIndexOfDispatchNode.indexOf(STUB_INDEX_OF_2_CHARS, array, arrayLength, fromIndex, c1, c2);
     }
 
-    @NodeIntrinsic(value = ForeignCallNode.class)
-    private static native int callInt(@ConstantNodeParameter ForeignCallDescriptor descriptor, Pointer arrayPointer, int arrayLength, int v1);
-
-    @NodeIntrinsic(value = ForeignCallNode.class)
-    private static native int callByte1(@ConstantNodeParameter ForeignCallDescriptor descriptor, Pointer arrayPointer, int arrayLength, byte v1);
+    public static int indexOf3Chars(char[] array, int arrayLength, int fromIndex, char c1, char c2, char c3) {
+        return AMD64ArrayIndexOfDispatchNode.indexOf(STUB_INDEX_OF_3_CHARS, array, arrayLength, fromIndex, c1, c2, c3);
+    }
 
-    @NodeIntrinsic(value = ForeignCallNode.class)
-    private static native int callByte2(@ConstantNodeParameter ForeignCallDescriptor descriptor, Pointer arrayPointer, int arrayLength, byte v1, byte v2);
+    public static int indexOf4Chars(char[] array, int arrayLength, int fromIndex, char c1, char c2, char c3, char c4) {
+        return AMD64ArrayIndexOfDispatchNode.indexOf(STUB_INDEX_OF_4_CHARS, array, arrayLength, fromIndex, c1, c2, c3, c4);
+    }
 
-    @NodeIntrinsic(value = ForeignCallNode.class)
-    private static native int callByte3(@ConstantNodeParameter ForeignCallDescriptor descriptor, Pointer arrayPointer, int arrayLength, byte v1, byte v2, byte v3);
+    public static int indexOf1Char(byte[] array, int arrayLength, int fromIndex, char c) {
+        return AMD64ArrayIndexOfDispatchNode.indexOf(STUB_INDEX_OF_1_CHAR_COMPACT, array, arrayLength, fromIndex, c);
+    }
 
-    @NodeIntrinsic(value = ForeignCallNode.class)
-    private static native int callByte4(@ConstantNodeParameter ForeignCallDescriptor descriptor, Pointer arrayPointer, int arrayLength, byte v1, byte v2, byte v3, byte v4);
-
-    @NodeIntrinsic(value = ForeignCallNode.class)
-    private static native int callChar1(@ConstantNodeParameter ForeignCallDescriptor descriptor, Pointer arrayPointer, int arrayLength, char v1);
+    public static int indexOf2Chars(byte[] array, int arrayLength, int fromIndex, char c1, char c2) {
+        return AMD64ArrayIndexOfDispatchNode.indexOf(STUB_INDEX_OF_2_CHARS_COMPACT, array, arrayLength, fromIndex, c1, c2);
+    }
 
-    @NodeIntrinsic(value = ForeignCallNode.class)
-    private static native int callChar2(@ConstantNodeParameter ForeignCallDescriptor descriptor, Pointer arrayPointer, int arrayLength, char v1, char v2);
+    public static int indexOf3Chars(byte[] array, int arrayLength, int fromIndex, char c1, char c2, char c3) {
+        return AMD64ArrayIndexOfDispatchNode.indexOf(STUB_INDEX_OF_3_CHARS_COMPACT, array, arrayLength, fromIndex, c1, c2, c3);
+    }
 
-    @NodeIntrinsic(value = ForeignCallNode.class)
-    private static native int callChar3(@ConstantNodeParameter ForeignCallDescriptor descriptor, Pointer arrayPointer, int arrayLength, char v1, char v2, char v3);
-
-    @NodeIntrinsic(value = ForeignCallNode.class)
-    private static native int callChar4(@ConstantNodeParameter ForeignCallDescriptor descriptor, Pointer arrayPointer, int arrayLength, char v1, char v2, char v3, char v4);
+    public static int indexOf4Chars(byte[] array, int arrayLength, int fromIndex, char c1, char c2, char c3, char c4) {
+        return AMD64ArrayIndexOfDispatchNode.indexOf(STUB_INDEX_OF_4_CHARS_COMPACT, array, arrayLength, fromIndex, c1, c2, c3, c4);
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64ArrayIndexOfDispatchNode.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,310 @@
+/*
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.replacements.amd64;
+
+import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_512;
+
+import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
+import org.graalvm.compiler.core.common.type.StampFactory;
+import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.graph.NodeInputList;
+import org.graalvm.compiler.nodeinfo.InputType;
+import org.graalvm.compiler.nodeinfo.NodeCycles;
+import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.DeoptimizingNode;
+import org.graalvm.compiler.nodes.FixedWithNextNode;
+import org.graalvm.compiler.nodes.FrameState;
+import org.graalvm.compiler.nodes.NamedLocationIdentity;
+import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.ValueNodeUtil;
+import org.graalvm.compiler.nodes.memory.MemoryAccess;
+import org.graalvm.compiler.nodes.memory.MemoryNode;
+import org.graalvm.compiler.nodes.spi.Lowerable;
+import org.graalvm.compiler.nodes.spi.LoweringTool;
+import jdk.internal.vm.compiler.word.LocationIdentity;
+
+import jdk.vm.ci.meta.JavaKind;
+
+/**
+ * This node is a placeholder for all variants of intrinsified indexof-operations. It may be lowered
+ * to a {@link AMD64ArrayIndexOfNode} or a specialized snippet.
+ */
+@NodeInfo(size = SIZE_512, cycles = NodeCycles.CYCLES_UNKNOWN)
+public class AMD64ArrayIndexOfDispatchNode extends FixedWithNextNode implements Lowerable, MemoryAccess, DeoptimizingNode.DeoptBefore {
+
+    public static final NodeClass<AMD64ArrayIndexOfDispatchNode> TYPE = NodeClass.create(AMD64ArrayIndexOfDispatchNode.class);
+
+    private final ForeignCallDescriptor stubCallDescriptor;
+    private final JavaKind arrayKind;
+    private final JavaKind valueKind;
+    private final boolean findTwoConsecutive;
+
+    @Input private ValueNode arrayPointer;
+    @Input private ValueNode arrayLength;
+    @Input private ValueNode fromIndex;
+    @Input private NodeInputList<ValueNode> searchValues;
+
+    @OptionalInput(InputType.Memory) private MemoryNode lastLocationAccess;
+    @OptionalInput(InputType.State) protected FrameState stateBefore;
+
+    public AMD64ArrayIndexOfDispatchNode(@ConstantNodeParameter ForeignCallDescriptor stubCallDescriptor, @ConstantNodeParameter JavaKind arrayKind, @ConstantNodeParameter JavaKind valueKind,
+                    @ConstantNodeParameter boolean findTwoConsecutive, ValueNode arrayPointer, ValueNode arrayLength, ValueNode fromIndex, ValueNode... searchValues) {
+        super(TYPE, StampFactory.forKind(JavaKind.Int));
+        this.stubCallDescriptor = stubCallDescriptor;
+        this.arrayKind = arrayKind;
+        this.valueKind = valueKind;
+        this.findTwoConsecutive = findTwoConsecutive;
+        this.arrayPointer = arrayPointer;
+        this.arrayLength = arrayLength;
+        this.fromIndex = fromIndex;
+        this.searchValues = new NodeInputList<>(this, searchValues);
+    }
+
+    public boolean isFindTwoConsecutive() {
+        return findTwoConsecutive;
+    }
+
+    public ValueNode getArrayPointer() {
+        return arrayPointer;
+    }
+
+    public ValueNode getArrayLength() {
+        return arrayLength;
+    }
+
+    public ValueNode getFromIndex() {
+        return fromIndex;
+    }
+
+    public NodeInputList<ValueNode> getSearchValues() {
+        return searchValues;
+    }
+
+    @Override
+    public boolean canDeoptimize() {
+        return true;
+    }
+
+    @Override
+    public void setStateBefore(FrameState f) {
+        updateUsages(stateBefore, f);
+        stateBefore = f;
+    }
+
+    @Override
+    public FrameState stateBefore() {
+        return stateBefore;
+    }
+
+    public ForeignCallDescriptor getStubCallDescriptor() {
+        return stubCallDescriptor;
+    }
+
+    public int getNumberOfValues() {
+        return searchValues.size();
+    }
+
+    public JavaKind getArrayKind() {
+        return arrayKind;
+    }
+
+    public JavaKind getValueKind() {
+        return valueKind;
+    }
+
+    public JavaKind getComparisonKind() {
+        return findTwoConsecutive ? (valueKind == JavaKind.Byte ? JavaKind.Char : JavaKind.Int) : valueKind;
+    }
+
+    public ValueNode[] getStubCallArgs() {
+        ValueNode[] ret = new ValueNode[searchValues.size() + 3];
+        ret[0] = arrayPointer;
+        ret[1] = arrayLength;
+        ret[2] = fromIndex;
+        for (int i = 0; i < searchValues.size(); i++) {
+            ret[3 + i] = searchValues.get(i);
+        }
+        return ret;
+    }
+
+    public AMD64ArrayIndexOfDispatchNode(@ConstantNodeParameter ForeignCallDescriptor stubCallDescriptor, @ConstantNodeParameter JavaKind arrayKind, @ConstantNodeParameter JavaKind valueKind,
+                    ValueNode arrayPointer, ValueNode arrayLength, ValueNode fromIndex, ValueNode... searchValues) {
+        this(stubCallDescriptor, arrayKind, valueKind, false, arrayPointer, arrayLength, fromIndex, searchValues);
+    }
+
+    @Override
+    public LocationIdentity getLocationIdentity() {
+        return NamedLocationIdentity.getArrayLocation(arrayKind);
+    }
+
+    @Override
+    public void lower(LoweringTool tool) {
+        tool.getLowerer().lower(this, tool);
+    }
+
+    @Override
+    public MemoryNode getLastLocationAccess() {
+        return lastLocationAccess;
+    }
+
+    @Override
+    public void setLastLocationAccess(MemoryNode lla) {
+        updateUsages(ValueNodeUtil.asNode(lastLocationAccess), ValueNodeUtil.asNode(lla));
+        lastLocationAccess = lla;
+    }
+
+    @NodeIntrinsic
+    private static native int optimizedArrayIndexOf(
+                    @ConstantNodeParameter ForeignCallDescriptor descriptor,
+                    @ConstantNodeParameter JavaKind arrayKind,
+                    @ConstantNodeParameter JavaKind valueKind,
+                    @ConstantNodeParameter boolean findTwoConsecutive,
+                    Object array, int arrayLength, int fromIndex, byte v1);
+
+    @NodeIntrinsic
+    private static native int optimizedArrayIndexOf(
+                    @ConstantNodeParameter ForeignCallDescriptor descriptor,
+                    @ConstantNodeParameter JavaKind arrayKind,
+                    @ConstantNodeParameter JavaKind valueKind,
+                    @ConstantNodeParameter boolean findTwoConsecutive,
+                    Object array, int arrayLength, int fromIndex, byte v1, byte v2);
+
+    @NodeIntrinsic
+    private static native int optimizedArrayIndexOf(
+                    @ConstantNodeParameter ForeignCallDescriptor descriptor,
+                    @ConstantNodeParameter JavaKind arrayKind,
+                    @ConstantNodeParameter JavaKind valueKind,
+                    @ConstantNodeParameter boolean findTwoConsecutive,
+                    Object array, int arrayLength, int fromIndex, byte v1, byte v2, byte v3);
+
+    @NodeIntrinsic
+    private static native int optimizedArrayIndexOf(
+                    @ConstantNodeParameter ForeignCallDescriptor descriptor,
+                    @ConstantNodeParameter JavaKind arrayKind,
+                    @ConstantNodeParameter JavaKind valueKind,
+                    @ConstantNodeParameter boolean findTwoConsecutive,
+                    Object array, int arrayLength, int fromIndex, byte v1, byte v2, byte v3, byte v4);
+
+    @NodeIntrinsic
+    private static native int optimizedArrayIndexOf(
+                    @ConstantNodeParameter ForeignCallDescriptor descriptor,
+                    @ConstantNodeParameter JavaKind arrayKind,
+                    @ConstantNodeParameter JavaKind valueKind,
+                    @ConstantNodeParameter boolean findTwoConsecutive,
+                    Object array, int arrayLength, int fromIndex, char v1);
+
+    @NodeIntrinsic
+    private static native int optimizedArrayIndexOf(
+                    @ConstantNodeParameter ForeignCallDescriptor descriptor,
+                    @ConstantNodeParameter JavaKind arrayKind,
+                    @ConstantNodeParameter JavaKind valueKind,
+                    @ConstantNodeParameter boolean findTwoConsecutive,
+                    Object array, int arrayLength, int fromIndex, char v1, char v2);
+
+    @NodeIntrinsic
+    private static native int optimizedArrayIndexOf(
+                    @ConstantNodeParameter ForeignCallDescriptor descriptor,
+                    @ConstantNodeParameter JavaKind arrayKind,
+                    @ConstantNodeParameter JavaKind valueKind,
+                    @ConstantNodeParameter boolean findTwoConsecutive,
+                    Object array, int arrayLength, int fromIndex, char v1, char v2, char v3);
+
+    @NodeIntrinsic
+    private static native int optimizedArrayIndexOf(
+                    @ConstantNodeParameter ForeignCallDescriptor descriptor,
+                    @ConstantNodeParameter JavaKind arrayKind,
+                    @ConstantNodeParameter JavaKind valueKind,
+                    @ConstantNodeParameter boolean findTwoConsecutive,
+                    Object array, int arrayLength, int fromIndex, char v1, char v2, char v3, char v4);
+
+    @NodeIntrinsic
+    private static native int optimizedArrayIndexOf(
+                    @ConstantNodeParameter ForeignCallDescriptor descriptor,
+                    @ConstantNodeParameter JavaKind arrayKind,
+                    @ConstantNodeParameter JavaKind valueKind,
+                    @ConstantNodeParameter boolean findTwoConsecutive,
+                    Object array, int arrayLength, int fromIndex, int searchValue);
+
+    public static int indexOf(@ConstantNodeParameter ForeignCallDescriptor descriptor, byte[] array, int arrayLength, int fromIndex, byte v1) {
+        return optimizedArrayIndexOf(descriptor, JavaKind.Byte, JavaKind.Byte, false, array, arrayLength, fromIndex, v1);
+    }
+
+    public static int indexOf(@ConstantNodeParameter ForeignCallDescriptor descriptor, byte[] array, int arrayLength, int fromIndex, byte v1, byte v2) {
+        return optimizedArrayIndexOf(descriptor, JavaKind.Byte, JavaKind.Byte, false, array, arrayLength, fromIndex, v1, v2);
+    }
+
+    public static int indexOf(@ConstantNodeParameter ForeignCallDescriptor descriptor, byte[] array, int arrayLength, int fromIndex, byte v1, byte v2, byte v3) {
+        return optimizedArrayIndexOf(descriptor, JavaKind.Byte, JavaKind.Byte, false, array, arrayLength, fromIndex, v1, v2, v3);
+    }
+
+    public static int indexOf(@ConstantNodeParameter ForeignCallDescriptor descriptor, byte[] array, int arrayLength, int fromIndex, byte v1, byte v2, byte v3, byte v4) {
+        return optimizedArrayIndexOf(descriptor, JavaKind.Byte, JavaKind.Byte, false, array, arrayLength, fromIndex, v1, v2, v3, v4);
+    }
+
+    public static int indexOf(@ConstantNodeParameter ForeignCallDescriptor descriptor, byte[] array, int arrayLength, int fromIndex, char v1) {
+        return optimizedArrayIndexOf(descriptor, JavaKind.Byte, JavaKind.Char, false, array, arrayLength, fromIndex, v1);
+    }
+
+    public static int indexOf(@ConstantNodeParameter ForeignCallDescriptor descriptor, byte[] array, int arrayLength, int fromIndex, char v1, char v2) {
+        return optimizedArrayIndexOf(descriptor, JavaKind.Byte, JavaKind.Char, false, array, arrayLength, fromIndex, v1, v2);
+    }
+
+    public static int indexOf(@ConstantNodeParameter ForeignCallDescriptor descriptor, byte[] array, int arrayLength, int fromIndex, char v1, char v2, char v3) {
+        return optimizedArrayIndexOf(descriptor, JavaKind.Byte, JavaKind.Char, false, array, arrayLength, fromIndex, v1, v2, v3);
+    }
+
+    public static int indexOf(@ConstantNodeParameter ForeignCallDescriptor descriptor, byte[] array, int arrayLength, int fromIndex, char v1, char v2, char v3, char v4) {
+        return optimizedArrayIndexOf(descriptor, JavaKind.Byte, JavaKind.Char, false, array, arrayLength, fromIndex, v1, v2, v3, v4);
+    }
+
+    public static int indexOf(@ConstantNodeParameter ForeignCallDescriptor descriptor, char[] array, int arrayLength, int fromIndex, char v1) {
+        return optimizedArrayIndexOf(descriptor, JavaKind.Char, JavaKind.Char, false, array, arrayLength, fromIndex, v1);
+    }
+
+    public static int indexOf(@ConstantNodeParameter ForeignCallDescriptor descriptor, char[] array, int arrayLength, int fromIndex, char v1, char v2) {
+        return optimizedArrayIndexOf(descriptor, JavaKind.Char, JavaKind.Char, false, array, arrayLength, fromIndex, v1, v2);
+    }
+
+    public static int indexOf(@ConstantNodeParameter ForeignCallDescriptor descriptor, char[] array, int arrayLength, int fromIndex, char v1, char v2, char v3) {
+        return optimizedArrayIndexOf(descriptor, JavaKind.Char, JavaKind.Char, false, array, arrayLength, fromIndex, v1, v2, v3);
+    }
+
+    public static int indexOf(@ConstantNodeParameter ForeignCallDescriptor descriptor, char[] array, int arrayLength, int fromIndex, char v1, char v2, char v3, char v4) {
+        return optimizedArrayIndexOf(descriptor, JavaKind.Char, JavaKind.Char, false, array, arrayLength, fromIndex, v1, v2, v3, v4);
+    }
+
+    public static int indexOf2ConsecutiveBytes(@ConstantNodeParameter ForeignCallDescriptor descriptor, byte[] array, int arrayLength, int fromIndex, int values) {
+        return optimizedArrayIndexOf(descriptor, JavaKind.Byte, JavaKind.Byte, true, array, arrayLength, fromIndex, values);
+    }
+
+    public static int indexOf2ConsecutiveChars(@ConstantNodeParameter ForeignCallDescriptor descriptor, byte[] array, int arrayLength, int fromIndex, int values) {
+        return optimizedArrayIndexOf(descriptor, JavaKind.Byte, JavaKind.Char, true, array, arrayLength, fromIndex, values);
+    }
+
+    public static int indexOf2ConsecutiveChars(@ConstantNodeParameter ForeignCallDescriptor descriptor, char[] array, int arrayLength, int fromIndex, int values) {
+        return optimizedArrayIndexOf(descriptor, JavaKind.Char, JavaKind.Char, true, array, arrayLength, fromIndex, values);
+    }
+}
+
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64ArrayIndexOfNode.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64ArrayIndexOfNode.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,8 +24,8 @@
 
 package org.graalvm.compiler.replacements.amd64;
 
-import jdk.vm.ci.meta.JavaKind;
-import jdk.vm.ci.meta.Value;
+import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_512;
+
 import org.graalvm.compiler.core.common.type.StampFactory;
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.graph.NodeInputList;
@@ -41,41 +41,46 @@
 import org.graalvm.compiler.nodes.spi.LIRLowerable;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
 import jdk.internal.vm.compiler.word.LocationIdentity;
-import jdk.internal.vm.compiler.word.Pointer;
 
-import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_512;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.Value;
 
 @NodeInfo(size = SIZE_512, cycles = NodeCycles.CYCLES_UNKNOWN)
 public class AMD64ArrayIndexOfNode extends FixedWithNextNode implements LIRLowerable, MemoryAccess {
 
     public static final NodeClass<AMD64ArrayIndexOfNode> TYPE = NodeClass.create(AMD64ArrayIndexOfNode.class);
 
-    private final JavaKind kind;
+    private final JavaKind arrayKind;
+    private final JavaKind valueKind;
     private final boolean findTwoConsecutive;
 
     @Input private ValueNode arrayPointer;
     @Input private ValueNode arrayLength;
+    @Input private ValueNode fromIndex;
     @Input private NodeInputList<ValueNode> searchValues;
 
     @OptionalInput(InputType.Memory) private MemoryNode lastLocationAccess;
 
-    public AMD64ArrayIndexOfNode(@ConstantNodeParameter JavaKind kind, @ConstantNodeParameter boolean findTwoConsecutive,
-                    ValueNode arrayPointer, ValueNode arrayLength, ValueNode... searchValues) {
+    public AMD64ArrayIndexOfNode(@ConstantNodeParameter JavaKind arrayKind, @ConstantNodeParameter JavaKind valueKind, @ConstantNodeParameter boolean findTwoConsecutive,
+                    ValueNode arrayPointer, ValueNode arrayLength, ValueNode fromIndex, ValueNode... searchValues) {
         super(TYPE, StampFactory.forKind(JavaKind.Int));
-        this.kind = kind;
+        this.arrayKind = arrayKind;
+        this.valueKind = valueKind;
         this.findTwoConsecutive = findTwoConsecutive;
         this.arrayPointer = arrayPointer;
         this.arrayLength = arrayLength;
+        this.fromIndex = fromIndex;
         this.searchValues = new NodeInputList<>(this, searchValues);
     }
 
-    public AMD64ArrayIndexOfNode(@ConstantNodeParameter JavaKind kind, ValueNode arrayPointer, ValueNode arrayLength, ValueNode... searchValues) {
-        this(kind, false, arrayPointer, arrayLength, searchValues);
+    public AMD64ArrayIndexOfNode(@ConstantNodeParameter JavaKind arrayKind, @ConstantNodeParameter JavaKind valueKind,
+                    ValueNode arrayPointer, ValueNode arrayLength, ValueNode fromIndex, ValueNode... searchValues) {
+        this(arrayKind, valueKind, false, arrayPointer, arrayLength, fromIndex, searchValues);
     }
 
     @Override
     public LocationIdentity getLocationIdentity() {
-        return NamedLocationIdentity.getArrayLocation(kind);
+        return NamedLocationIdentity.getArrayLocation(arrayKind);
     }
 
     @Override
@@ -84,7 +89,8 @@
         for (int i = 0; i < searchValues.size(); i++) {
             searchValueOperands[i] = gen.operand(searchValues.get(i));
         }
-        Value result = gen.getLIRGeneratorTool().emitArrayIndexOf(kind, findTwoConsecutive, gen.operand(arrayPointer), gen.operand(arrayLength), searchValueOperands);
+        Value result = gen.getLIRGeneratorTool().emitArrayIndexOf(arrayKind, valueKind, findTwoConsecutive,
+                        gen.operand(arrayPointer), gen.operand(arrayLength), gen.operand(fromIndex), searchValueOperands);
         gen.setResult(this, result);
     }
 
@@ -100,30 +106,125 @@
     }
 
     @NodeIntrinsic
-    public static native int optimizedArrayIndexOf(@ConstantNodeParameter JavaKind kind, @ConstantNodeParameter boolean findTwoConsecutive,
-                    Pointer arrayPointer, int arrayLength, int searchValue);
+    private static native int optimizedArrayIndexOf(
+                    @ConstantNodeParameter JavaKind arrayKind,
+                    @ConstantNodeParameter JavaKind valueKind,
+                    @ConstantNodeParameter boolean findTwoConsecutive,
+                    Object array, int arrayLength, int fromIndex, byte v1);
+
+    @NodeIntrinsic
+    private static native int optimizedArrayIndexOf(
+                    @ConstantNodeParameter JavaKind arrayKind,
+                    @ConstantNodeParameter JavaKind valueKind,
+                    @ConstantNodeParameter boolean findTwoConsecutive,
+                    Object array, int arrayLength, int fromIndex, byte v1, byte v2);
+
+    @NodeIntrinsic
+    private static native int optimizedArrayIndexOf(
+                    @ConstantNodeParameter JavaKind arrayKind,
+                    @ConstantNodeParameter JavaKind valueKind,
+                    @ConstantNodeParameter boolean findTwoConsecutive,
+                    Object array, int arrayLength, int fromIndex, byte v1, byte v2, byte v3);
 
     @NodeIntrinsic
-    public static native int optimizedArrayIndexOf(@ConstantNodeParameter JavaKind kind, Pointer arrayPointer, int arrayLength, char c1);
+    private static native int optimizedArrayIndexOf(
+                    @ConstantNodeParameter JavaKind arrayKind,
+                    @ConstantNodeParameter JavaKind valueKind,
+                    @ConstantNodeParameter boolean findTwoConsecutive,
+                    Object array, int arrayLength, int fromIndex, byte v1, byte v2, byte v3, byte v4);
+
+    @NodeIntrinsic
+    private static native int optimizedArrayIndexOf(
+                    @ConstantNodeParameter JavaKind arrayKind,
+                    @ConstantNodeParameter JavaKind valueKind,
+                    @ConstantNodeParameter boolean findTwoConsecutive,
+                    Object array, int arrayLength, int fromIndex, char v1);
 
     @NodeIntrinsic
-    public static native int optimizedArrayIndexOf(@ConstantNodeParameter JavaKind kind, Pointer arrayPointer, int arrayLength, char c1, char c2);
+    private static native int optimizedArrayIndexOf(
+                    @ConstantNodeParameter JavaKind arrayKind,
+                    @ConstantNodeParameter JavaKind valueKind,
+                    @ConstantNodeParameter boolean findTwoConsecutive,
+                    Object array, int arrayLength, int fromIndex, char v1, char v2);
 
     @NodeIntrinsic
-    public static native int optimizedArrayIndexOf(@ConstantNodeParameter JavaKind kind, Pointer arrayPointer, int arrayLength, char c1, char c2, char c3);
+    private static native int optimizedArrayIndexOf(
+                    @ConstantNodeParameter JavaKind arrayKind,
+                    @ConstantNodeParameter JavaKind valueKind,
+                    @ConstantNodeParameter boolean findTwoConsecutive,
+                    Object array, int arrayLength, int fromIndex, char v1, char v2, char v3);
+
+    @NodeIntrinsic
+    private static native int optimizedArrayIndexOf(
+                    @ConstantNodeParameter JavaKind arrayKind,
+                    @ConstantNodeParameter JavaKind valueKind,
+                    @ConstantNodeParameter boolean findTwoConsecutive,
+                    Object array, int arrayLength, int fromIndex, char v1, char v2, char v3, char v4);
 
     @NodeIntrinsic
-    public static native int optimizedArrayIndexOf(@ConstantNodeParameter JavaKind kind, Pointer arrayPointer, int arrayLength, char c1, char c2, char c3, char c4);
+    private static native int optimizedArrayIndexOf(
+                    @ConstantNodeParameter JavaKind arrayKind,
+                    @ConstantNodeParameter JavaKind valueKind,
+                    @ConstantNodeParameter boolean findTwoConsecutive,
+                    Object array, int arrayLength, int fromIndex, int searchValue);
+
+    public static int indexOf(byte[] array, int arrayLength, int fromIndex, byte v1) {
+        return optimizedArrayIndexOf(JavaKind.Byte, JavaKind.Byte, false, array, arrayLength, fromIndex, v1);
+    }
+
+    public static int indexOf(byte[] array, int arrayLength, int fromIndex, byte v1, byte v2) {
+        return optimizedArrayIndexOf(JavaKind.Byte, JavaKind.Byte, false, array, arrayLength, fromIndex, v1, v2);
+    }
 
-    @NodeIntrinsic
-    public static native int optimizedArrayIndexOf(@ConstantNodeParameter JavaKind kind, Pointer arrayPointer, int arrayLength, byte c1);
+    public static int indexOf(byte[] array, int arrayLength, int fromIndex, byte v1, byte v2, byte v3) {
+        return optimizedArrayIndexOf(JavaKind.Byte, JavaKind.Byte, false, array, arrayLength, fromIndex, v1, v2, v3);
+    }
+
+    public static int indexOf(byte[] array, int arrayLength, int fromIndex, byte v1, byte v2, byte v3, byte v4) {
+        return optimizedArrayIndexOf(JavaKind.Byte, JavaKind.Byte, false, array, arrayLength, fromIndex, v1, v2, v3, v4);
+    }
+
+    public static int indexOf(byte[] array, int arrayLength, int fromIndex, char v1) {
+        return optimizedArrayIndexOf(JavaKind.Byte, JavaKind.Char, false, array, arrayLength, fromIndex, v1);
+    }
+
+    public static int indexOf(byte[] array, int arrayLength, int fromIndex, char v1, char v2) {
+        return optimizedArrayIndexOf(JavaKind.Byte, JavaKind.Char, false, array, arrayLength, fromIndex, v1, v2);
+    }
 
-    @NodeIntrinsic
-    public static native int optimizedArrayIndexOf(@ConstantNodeParameter JavaKind kind, Pointer arrayPointer, int arrayLength, byte c1, byte c2);
+    public static int indexOf(byte[] array, int arrayLength, int fromIndex, char v1, char v2, char v3) {
+        return optimizedArrayIndexOf(JavaKind.Byte, JavaKind.Char, false, array, arrayLength, fromIndex, v1, v2, v3);
+    }
+
+    public static int indexOf(byte[] array, int arrayLength, int fromIndex, char v1, char v2, char v3, char v4) {
+        return optimizedArrayIndexOf(JavaKind.Byte, JavaKind.Char, false, array, arrayLength, fromIndex, v1, v2, v3, v4);
+    }
+
+    public static int indexOf(char[] array, int arrayLength, int fromIndex, char v1) {
+        return optimizedArrayIndexOf(JavaKind.Char, JavaKind.Char, false, array, arrayLength, fromIndex, v1);
+    }
+
+    public static int indexOf(char[] array, int arrayLength, int fromIndex, char v1, char v2) {
+        return optimizedArrayIndexOf(JavaKind.Char, JavaKind.Char, false, array, arrayLength, fromIndex, v1, v2);
+    }
 
-    @NodeIntrinsic
-    public static native int optimizedArrayIndexOf(@ConstantNodeParameter JavaKind kind, Pointer arrayPointer, int arrayLength, byte c1, byte c2, byte c3);
+    public static int indexOf(char[] array, int arrayLength, int fromIndex, char v1, char v2, char v3) {
+        return optimizedArrayIndexOf(JavaKind.Char, JavaKind.Char, false, array, arrayLength, fromIndex, v1, v2, v3);
+    }
+
+    public static int indexOf(char[] array, int arrayLength, int fromIndex, char v1, char v2, char v3, char v4) {
+        return optimizedArrayIndexOf(JavaKind.Char, JavaKind.Char, false, array, arrayLength, fromIndex, v1, v2, v3, v4);
+    }
 
-    @NodeIntrinsic
-    public static native int optimizedArrayIndexOf(@ConstantNodeParameter JavaKind kind, Pointer arrayPointer, int arrayLength, byte c1, byte c2, byte c3, byte c4);
+    public static int indexOf2ConsecutiveBytes(byte[] array, int arrayLength, int fromIndex, int values) {
+        return optimizedArrayIndexOf(JavaKind.Byte, JavaKind.Byte, true, array, arrayLength, fromIndex, values);
+    }
+
+    public static int indexOf2ConsecutiveChars(byte[] array, int arrayLength, int fromIndex, int values) {
+        return optimizedArrayIndexOf(JavaKind.Byte, JavaKind.Char, true, array, arrayLength, fromIndex, values);
+    }
+
+    public static int indexOf2ConsecutiveChars(char[] array, int arrayLength, int fromIndex, int values) {
+        return optimizedArrayIndexOf(JavaKind.Char, JavaKind.Char, true, array, arrayLength, fromIndex, values);
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64GraphBuilderPlugins.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64GraphBuilderPlugins.java	Mon Jul 01 14:57:02 2019 -0700
@@ -32,8 +32,6 @@
 import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.LOG10;
 import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.SIN;
 import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.TAN;
-import static org.graalvm.compiler.serviceprovider.JavaVersionUtil.Java11OrEarlier;
-import static org.graalvm.compiler.serviceprovider.JavaVersionUtil.Java8OrEarlier;
 
 import java.util.Arrays;
 
@@ -62,6 +60,7 @@
 import org.graalvm.compiler.replacements.nodes.FusedMultiplyAddNode;
 import org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode;
 import org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation;
+import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
 
 import jdk.vm.ci.amd64.AMD64;
 import jdk.vm.ci.amd64.AMD64.CPUFeature;
@@ -95,7 +94,7 @@
     }
 
     private static void registerThreadPlugins(InvocationPlugins plugins, AMD64 arch) {
-        if (!Java8OrEarlier) {
+        if (JavaVersionUtil.JAVA_SPEC > 8) {
             // Pause instruction introduced with SSE2
             if (arch.getFeatures().contains(AMD64.CPUFeature.SSE2)) {
                 Registration r = new Registration(plugins, Thread.class);
@@ -177,7 +176,7 @@
             registerRound(r, "floor", RoundingMode.DOWN);
         }
 
-        if (useFMAIntrinsics && !Java8OrEarlier && arch.getFeatures().contains(CPUFeature.FMA)) {
+        if (useFMAIntrinsics && JavaVersionUtil.JAVA_SPEC > 8 && arch.getFeatures().contains(CPUFeature.FMA)) {
             registerFMA(r);
         }
     }
@@ -248,7 +247,7 @@
     }
 
     private static void registerStringPlugins(InvocationPlugins plugins, BytecodeProvider replacementsBytecodeProvider) {
-        if (Java8OrEarlier) {
+        if (JavaVersionUtil.JAVA_SPEC <= 8) {
             Registration r;
             r = new Registration(plugins, String.class, replacementsBytecodeProvider);
             r.setAllowOverwrite(true);
@@ -284,9 +283,10 @@
 
     private static void registerUnsafePlugins(InvocationPlugins plugins, BytecodeProvider replacementsBytecodeProvider, boolean explicitUnsafeNullChecks) {
         registerUnsafePlugins(new Registration(plugins, Unsafe.class), explicitUnsafeNullChecks, new JavaKind[]{JavaKind.Int, JavaKind.Long, JavaKind.Object}, true);
-        if (!Java8OrEarlier) {
+        if (JavaVersionUtil.JAVA_SPEC > 8) {
             registerUnsafePlugins(new Registration(plugins, "jdk.internal.misc.Unsafe", replacementsBytecodeProvider), explicitUnsafeNullChecks,
-                            new JavaKind[]{JavaKind.Boolean, JavaKind.Byte, JavaKind.Char, JavaKind.Short, JavaKind.Int, JavaKind.Long, JavaKind.Object}, Java11OrEarlier);
+                            new JavaKind[]{JavaKind.Boolean, JavaKind.Byte, JavaKind.Char, JavaKind.Short, JavaKind.Int, JavaKind.Long, JavaKind.Object},
+                            JavaVersionUtil.JAVA_SPEC <= 11);
         }
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringLatin1Substitutions.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringLatin1Substitutions.java	Mon Jul 01 14:57:02 2019 -0700
@@ -112,12 +112,7 @@
             // Note: fromIndex might be near -1>>>1.
             return -1;
         }
-        Pointer sourcePointer = byteOffsetPointer(value, fromIndex);
-        int result = AMD64ArrayIndexOf.indexOf1Byte(sourcePointer, length - fromIndex, (byte) ch);
-        if (result != -1) {
-            return result + fromIndex;
-        }
-        return result;
+        return AMD64ArrayIndexOf.indexOf1Byte(value, length, fromIndex, (byte) ch);
     }
 
     @MethodSubstitution
@@ -137,37 +132,25 @@
             // The empty string contains nothing except the empty string.
             return -1;
         }
-        int totalOffset = fromIndex;
         if (targetCount == 1) {
-            Pointer sourcePointer = byteOffsetPointer(source, totalOffset);
-            int indexOfResult = AMD64ArrayIndexOf.indexOf1Byte(sourcePointer, sourceCount - fromIndex, target[0]);
-            if (indexOfResult >= 0) {
-                return indexOfResult + totalOffset;
-            }
-            return indexOfResult;
+            return AMD64ArrayIndexOf.indexOf1Byte(source, sourceCount, fromIndex, target[0]);
         } else if (targetCount == 2) {
-            Pointer sourcePointer = byteOffsetPointer(source, totalOffset);
-            int indexOfResult = AMD64ArrayIndexOf.indexOfTwoConsecutiveBytes(sourcePointer, sourceCount - fromIndex, target[0], target[1]);
-            if (indexOfResult >= 0) {
-                return indexOfResult + totalOffset;
-            }
-            return indexOfResult;
+            return AMD64ArrayIndexOf.indexOfTwoConsecutiveBytes(source, sourceCount, fromIndex, target[0], target[1]);
         } else {
-            int haystackLength = sourceCount - (fromIndex + (targetCount - 2));
-            while (haystackLength > 0) {
-                Pointer sourcePointer = byteOffsetPointer(source, totalOffset);
-                int indexOfResult = AMD64ArrayIndexOf.indexOfTwoConsecutiveBytes(sourcePointer, haystackLength, target[0], target[1]);
+            int haystackLength = sourceCount - (targetCount - 2);
+            int offset = fromIndex;
+            while (offset < haystackLength) {
+                int indexOfResult = AMD64ArrayIndexOf.indexOfTwoConsecutiveBytes(source, haystackLength, offset, target[0], target[1]);
                 if (indexOfResult < 0) {
                     return -1;
                 }
-                totalOffset += indexOfResult;
-                haystackLength -= (indexOfResult + 1);
-                Pointer cmpSourcePointer = byteOffsetPointer(source, totalOffset);
+                offset = indexOfResult;
+                Pointer cmpSourcePointer = byteOffsetPointer(source, offset);
                 Pointer targetPointer = pointer(target);
                 if (ArrayRegionEqualsNode.regionEquals(cmpSourcePointer, targetPointer, targetCount, JavaKind.Byte)) {
-                    return totalOffset;
+                    return offset;
                 }
-                totalOffset++;
+                offset++;
             }
             return -1;
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringSubstitutions.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringSubstitutions.java	Mon Jul 01 14:57:02 2019 -0700
@@ -84,29 +84,17 @@
         }
 
         if (targetCount == 1) {
-            Pointer sourcePointer = Word.objectToTrackedPointer(source).add(charArrayBaseOffset(INJECTED)).add(totalOffset * charArrayIndexScale(INJECTED));
-            int indexOfResult = AMD64ArrayIndexOf.indexOf1Char(sourcePointer, sourceCount - fromIndex, target[targetOffset]);
-            if (indexOfResult >= 0) {
-                return indexOfResult + totalOffset;
-            }
-            return indexOfResult;
+            return AMD64ArrayIndexOf.indexOf1Char(source, sourceCount, totalOffset, target[targetOffset]);
         } else if (targetCount == 2) {
-            Pointer sourcePointer = Word.objectToTrackedPointer(source).add(charArrayBaseOffset(INJECTED)).add(totalOffset * charArrayIndexScale(INJECTED));
-            int indexOfResult = AMD64ArrayIndexOf.indexOfTwoConsecutiveChars(sourcePointer, sourceCount - fromIndex, target[targetOffset], target[targetOffset + 1]);
-            if (indexOfResult >= 0) {
-                return indexOfResult + totalOffset;
-            }
-            return indexOfResult;
+            return AMD64ArrayIndexOf.indexOfTwoConsecutiveChars(source, sourceCount, totalOffset, target[targetOffset], target[targetOffset + 1]);
         } else {
-            int haystackLength = sourceCount - (fromIndex + (targetCount - 2));
-            while (haystackLength > 0) {
-                Pointer sourcePointer = Word.objectToTrackedPointer(source).add(charArrayBaseOffset(INJECTED)).add(totalOffset * charArrayIndexScale(INJECTED));
-                int indexOfResult = AMD64ArrayIndexOf.indexOfTwoConsecutiveChars(sourcePointer, haystackLength, target[targetOffset], target[targetOffset + 1]);
+            int haystackLength = sourceCount - (targetCount - 2);
+            while (totalOffset < haystackLength) {
+                int indexOfResult = AMD64ArrayIndexOf.indexOfTwoConsecutiveChars(source, haystackLength, totalOffset, target[targetOffset], target[targetOffset + 1]);
                 if (indexOfResult < 0) {
                     return -1;
                 }
-                totalOffset += indexOfResult;
-                haystackLength -= (indexOfResult + 1);
+                totalOffset = indexOfResult;
                 Pointer cmpSourcePointer = Word.objectToTrackedPointer(source).add(charArrayBaseOffset(INJECTED)).add(totalOffset * charArrayIndexScale(INJECTED));
                 Pointer targetPointer = Word.objectToTrackedPointer(target).add(charArrayBaseOffset(INJECTED)).add(targetOffset * charArrayIndexScale(INJECTED));
                 if (ArrayRegionEqualsNode.regionEquals(cmpSourcePointer, targetPointer, targetCount, JavaKind.Char)) {
@@ -133,13 +121,7 @@
 
         if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
             char[] sourceArray = StringSubstitutions.getValue(source);
-
-            Pointer sourcePointer = Word.objectToTrackedPointer(sourceArray).add(charArrayBaseOffset(INJECTED)).add(fromIndex * charArrayIndexScale(INJECTED));
-            int result = AMD64ArrayIndexOf.indexOf1Char(sourcePointer, sourceCount - fromIndex, (char) ch);
-            if (result != -1) {
-                return result + fromIndex;
-            }
-            return result;
+            return AMD64ArrayIndexOf.indexOf1Char(sourceArray, sourceCount, fromIndex, (char) ch);
         } else {
             return indexOf(source, ch, origFromIndex);
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringUTF16Substitutions.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64StringUTF16Substitutions.java	Mon Jul 01 14:57:02 2019 -0700
@@ -103,12 +103,7 @@
 
     @MethodSubstitution
     public static int indexOfCharUnsafe(byte[] value, int ch, int fromIndex, int max) {
-        Pointer sourcePointer = charOffsetPointer(value, fromIndex);
-        int result = AMD64ArrayIndexOf.indexOf1Char(sourcePointer, max - fromIndex, (char) ch);
-        if (result != -1) {
-            return result + fromIndex;
-        }
-        return result;
+        return AMD64ArrayIndexOf.indexOf1Char(value, max, fromIndex, (char) ch);
     }
 
     private static Word pointer(byte[] target) {
@@ -125,39 +120,26 @@
         ReplacementsUtil.runtimeAssert(targetCount > 0, "StringUTF16.indexOfUnsafe invalid args: targetCount <= 0");
         ReplacementsUtil.runtimeAssert(targetCount <= length(target), "StringUTF16.indexOfUnsafe invalid args: targetCount > length(target)");
         ReplacementsUtil.runtimeAssert(sourceCount >= targetCount, "StringUTF16.indexOfUnsafe invalid args: sourceCount < targetCount");
-        int totalOffset = fromIndex;
         if (targetCount == 1) {
-            Pointer sourcePointer = charOffsetPointer(source, totalOffset);
-            int indexOfResult = AMD64ArrayIndexOf.indexOf1Char(sourcePointer, sourceCount - fromIndex, StringUTF16Substitutions.getChar(target, 0));
-            if (indexOfResult >= 0) {
-                return indexOfResult + totalOffset;
-            }
-            return indexOfResult;
+            return AMD64ArrayIndexOf.indexOf1Char(source, sourceCount, fromIndex, StringUTF16Substitutions.getChar(target, 0));
         } else if (targetCount == 2) {
-            Pointer sourcePointer = charOffsetPointer(source, totalOffset);
-            int indexOfResult = AMD64ArrayIndexOf.indexOfTwoConsecutiveChars(sourcePointer, sourceCount - fromIndex, StringUTF16Substitutions.getChar(target, 0),
-                            StringUTF16Substitutions.getChar(target, 1));
-            if (indexOfResult >= 0) {
-                return indexOfResult + totalOffset;
-            }
-            return indexOfResult;
+            return AMD64ArrayIndexOf.indexOfTwoConsecutiveChars(source, sourceCount, fromIndex, StringUTF16Substitutions.getChar(target, 0), StringUTF16Substitutions.getChar(target, 1));
         } else {
-            int haystackLength = sourceCount - (fromIndex + (targetCount - 2));
-            while (haystackLength > 0) {
-                Pointer sourcePointer = charOffsetPointer(source, totalOffset);
-                int indexOfResult = AMD64ArrayIndexOf.indexOfTwoConsecutiveChars(sourcePointer, haystackLength, StringUTF16Substitutions.getChar(target, 0),
+            int haystackLength = sourceCount - (targetCount - 2);
+            int offset = fromIndex;
+            while (offset < haystackLength) {
+                int indexOfResult = AMD64ArrayIndexOf.indexOfTwoConsecutiveChars(source, haystackLength, offset, StringUTF16Substitutions.getChar(target, 0),
                                 StringUTF16Substitutions.getChar(target, 1));
                 if (indexOfResult < 0) {
                     return -1;
                 }
-                totalOffset += indexOfResult;
-                haystackLength -= (indexOfResult + 1);
-                Pointer cmpSourcePointer = charOffsetPointer(source, totalOffset);
+                offset = indexOfResult;
+                Pointer cmpSourcePointer = charOffsetPointer(source, offset);
                 Pointer targetPointer = pointer(target);
                 if (ArrayRegionEqualsNode.regionEquals(cmpSourcePointer, targetPointer, targetCount, JavaKind.Char)) {
-                    return totalOffset;
+                    return offset;
                 }
-                totalOffset++;
+                offset++;
             }
             return -1;
         }
@@ -169,37 +151,25 @@
         ReplacementsUtil.runtimeAssert(targetCount > 0, "StringUTF16.indexOfLatin1Unsafe invalid args: targetCount <= 0");
         ReplacementsUtil.runtimeAssert(targetCount <= target.length, "StringUTF16.indexOfLatin1Unsafe invalid args: targetCount > length(target)");
         ReplacementsUtil.runtimeAssert(sourceCount >= targetCount, "StringUTF16.indexOfLatin1Unsafe invalid args: sourceCount < targetCount");
-        int totalOffset = fromIndex;
         if (targetCount == 1) {
-            Pointer sourcePointer = charOffsetPointer(source, totalOffset);
-            int indexOfResult = AMD64ArrayIndexOf.indexOf1Char(sourcePointer, sourceCount - fromIndex, (char) Byte.toUnsignedInt(target[0]));
-            if (indexOfResult >= 0) {
-                return indexOfResult + totalOffset;
-            }
-            return indexOfResult;
+            return AMD64ArrayIndexOf.indexOf1Char(source, sourceCount, fromIndex, (char) Byte.toUnsignedInt(target[0]));
         } else if (targetCount == 2) {
-            Pointer sourcePointer = charOffsetPointer(source, totalOffset);
-            int indexOfResult = AMD64ArrayIndexOf.indexOfTwoConsecutiveChars(sourcePointer, sourceCount - fromIndex, (char) Byte.toUnsignedInt(target[0]), (char) Byte.toUnsignedInt(target[1]));
-            if (indexOfResult >= 0) {
-                return indexOfResult + totalOffset;
-            }
-            return indexOfResult;
+            return AMD64ArrayIndexOf.indexOfTwoConsecutiveChars(source, sourceCount, fromIndex, (char) Byte.toUnsignedInt(target[0]), (char) Byte.toUnsignedInt(target[1]));
         } else {
-            int haystackLength = sourceCount - (fromIndex + (targetCount - 2));
-            while (haystackLength > 0) {
-                Pointer sourcePointer = charOffsetPointer(source, totalOffset);
-                int indexOfResult = AMD64ArrayIndexOf.indexOfTwoConsecutiveChars(sourcePointer, haystackLength, (char) Byte.toUnsignedInt(target[0]), (char) Byte.toUnsignedInt(target[1]));
+            int haystackLength = sourceCount - (targetCount - 2);
+            int offset = fromIndex;
+            while (offset < haystackLength) {
+                int indexOfResult = AMD64ArrayIndexOf.indexOfTwoConsecutiveChars(source, haystackLength, offset, (char) Byte.toUnsignedInt(target[0]), (char) Byte.toUnsignedInt(target[1]));
                 if (indexOfResult < 0) {
                     return -1;
                 }
-                totalOffset += indexOfResult;
-                haystackLength -= (indexOfResult + 1);
-                Pointer cmpSourcePointer = charOffsetPointer(source, totalOffset);
+                offset = indexOfResult;
+                Pointer cmpSourcePointer = charOffsetPointer(source, offset);
                 Pointer targetPointer = pointer(target);
                 if (ArrayRegionEqualsNode.regionEquals(cmpSourcePointer, targetPointer, targetCount, JavaKind.Char, JavaKind.Byte)) {
-                    return totalOffset;
+                    return offset;
                 }
-                totalOffset++;
+                offset++;
             }
             return -1;
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/ArraysSubstitutionsTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/ArraysSubstitutionsTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -33,7 +33,6 @@
 import org.graalvm.compiler.phases.OptimisticOptimizations;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
 import org.graalvm.compiler.phases.tiers.HighTierContext;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.graalvm.compiler.replacements.nodes.ArrayEqualsNode;
 import org.graalvm.compiler.virtual.phases.ea.PartialEscapePhase;
 import org.junit.Assert;
@@ -133,7 +132,7 @@
         StructuredGraph graph = parseEager("testCanonicalLengthSnippet", AllowAssumptions.NO);
         HighTierContext context = new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
         createInliningPhase().apply(graph, context);
-        new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders()));
+        new CanonicalizerPhase().apply(graph, getProviders());
 
         Assert.assertTrue(graph.getNodes(ReturnNode.TYPE).first().result().asJavaConstant().asLong() == 0);
     }
@@ -149,7 +148,7 @@
         StructuredGraph graph = parseEager("testCanonicalEqualSnippet", AllowAssumptions.NO);
         HighTierContext context = new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
         createInliningPhase().apply(graph, context);
-        new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders()));
+        new CanonicalizerPhase().apply(graph, getProviders());
 
         Assert.assertTrue(graph.getNodes(ReturnNode.TYPE).first().result().asJavaConstant().asLong() == 1);
     }
@@ -163,9 +162,9 @@
         StructuredGraph graph = parseEager("testVirtualEqualSnippet", AllowAssumptions.NO);
         HighTierContext context = new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
         createInliningPhase().apply(graph, context);
-        new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders()));
+        new CanonicalizerPhase().apply(graph, getProviders());
         new PartialEscapePhase(false, new CanonicalizerPhase(), graph.getOptions()).apply(graph, context);
-        new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders()));
+        new CanonicalizerPhase().apply(graph, getProviders());
 
         Assert.assertTrue(graph.getNodes(ReturnNode.TYPE).first().result().asJavaConstant().asLong() == 1);
     }
@@ -181,9 +180,9 @@
         StructuredGraph graph = parseEager("testVirtualNotEqualSnippet", AllowAssumptions.NO);
         HighTierContext context = getDefaultHighTierContext();
         createInliningPhase().apply(graph, context);
-        new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders()));
+        new CanonicalizerPhase().apply(graph, getProviders());
         new PartialEscapePhase(false, new CanonicalizerPhase(), graph.getOptions()).apply(graph, context);
-        new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders()));
+        new CanonicalizerPhase().apply(graph, getProviders());
 
         Assert.assertTrue(graph.getNodes(ReturnNode.TYPE).first().result().asJavaConstant().asLong() == 0);
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/DeoptimizeOnExceptionTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/DeoptimizeOnExceptionTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -34,6 +34,7 @@
 import org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin;
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.phases.common.AbstractInliningPhase;
+import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
 import org.graalvm.compiler.test.ExportingClassLoader;
 import org.junit.Assert;
 import org.junit.Assume;
@@ -103,7 +104,7 @@
 
     @Test
     public void test3() {
-        Assume.assumeTrue("Only works on jdk8 right now", Java8OrEarlier);
+        Assume.assumeTrue("Only works on jdk8 right now", JavaVersionUtil.JAVA_SPEC <= 8);
         ResolvedJavaMethod method = getResolvedJavaMethod("test3Snippet");
 
         for (int i = 0; i < 2; i++) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/DerivedOopTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/DerivedOopTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -266,8 +266,8 @@
     }
 
     @Override
-    protected boolean checkHighTierGraph(StructuredGraph graph) {
+    protected void checkHighTierGraph(StructuredGraph graph) {
         assert graph.getNodes().filter(WordCastNode.class).count() > 0 : "DerivedOopTest.toLong should be intrinsified";
-        return super.checkHighTierGraph(graph);
+        super.checkHighTierGraph(graph);
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/FoldTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/FoldTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -94,14 +94,13 @@
     }
 
     @Override
-    protected boolean checkHighTierGraph(StructuredGraph graph) {
+    protected void checkHighTierGraph(StructuredGraph graph) {
         // check that folding happened correctly
         StartNode start = graph.start();
         assert start.next() instanceof ReturnNode : "expected ReturnNode, got " + start.next();
 
         ReturnNode ret = (ReturnNode) start.next();
         assert ret.result().isConstant() : "expected ConstantNode, got " + ret.result();
-        return true;
     }
 
     @Test
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/InvokerSignatureMismatchTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.replacements.test;
+
+import static org.graalvm.compiler.test.SubprocessUtil.getVMCommandLine;
+import static org.graalvm.compiler.test.SubprocessUtil.withoutDebuggerArguments;
+
+import org.junit.Test;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Type;
+
+import java.io.File;
+import java.lang.invoke.MethodHandles;
+import java.util.List;
+
+import org.graalvm.compiler.core.test.CustomizedBytecodePatternTest;
+import org.graalvm.compiler.test.SubprocessUtil;
+import org.graalvm.compiler.test.SubprocessUtil.Subprocess;
+
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+
+public class InvokerSignatureMismatchTest {
+
+    @Test
+    public void test() throws Throwable {
+        List<String> args = withoutDebuggerArguments(getVMCommandLine());
+        String classPath = System.getProperty("java.class.path");
+        classPath = classPath + File.pathSeparator + TestISMBL.class.getProtectionDomain().getCodeSource().getLocation().getPath();
+        args.add("-Xbootclasspath/a:" + classPath);
+        args.add("-XX:-TieredCompilation");
+        args.add("-XX:+EnableJVMCI");
+        args.add("-XX:+UseJVMCICompiler");
+
+        args.add(TestISMBL.class.getName());
+        Subprocess proc = SubprocessUtil.java(args);
+        if (proc.exitCode != 0) {
+            System.out.println(proc);
+        }
+    }
+}
+
+class TestISMBL extends CustomizedBytecodePatternTest {
+
+    public static void main(String[] args) {
+        try {
+            new TestISMBL().test();
+        } catch (Throwable e) {
+            e.printStackTrace();
+            System.exit(1);
+        }
+        System.exit(0);
+    }
+
+    private void test() throws Throwable {
+        getClass("java/lang/invoke/MHHelper");
+        Class<?> testClass = getClass("ISMTest");
+
+        ResolvedJavaMethod mL = getResolvedJavaMethod(testClass, "mainLink");
+        ResolvedJavaMethod mI = getResolvedJavaMethod(testClass, "mainInvoke");
+        executeActual(mL, null, 100);
+        executeActual(mI, null, 100);
+    }
+
+    @Override
+    protected Class<?> getClass(String className) throws ClassNotFoundException {
+        if (className.equals("java/lang/invoke/MHHelper")) {
+            return super.getClassBL(className, MethodHandles.lookup());
+        } else {
+            return super.getClass(className);
+        }
+    }
+
+    @Override
+    protected byte[] generateClass(String className) {
+        String[] exceptions = new String[]{"java/lang/Throwable"};
+        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
+        cw.visit(52, ACC_SUPER | ACC_PUBLIC, className, null, "java/lang/Object", null);
+
+        if (className.equals("java/lang/invoke/MHHelper")) {
+            MethodVisitor internalMemberName = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "internalMemberName", "(Ljava/lang/invoke/MethodHandle;)Ljava/lang/Object;", null, exceptions);
+            internalMemberName.visitCode();
+            internalMemberName.visitVarInsn(ALOAD, 0);
+            internalMemberName.visitMethodInsn(INVOKEVIRTUAL, "java/lang/invoke/MethodHandle", "internalMemberName", "()Ljava/lang/invoke/MemberName;", false);
+            internalMemberName.visitInsn(ARETURN);
+            internalMemberName.visitMaxs(1, 1);
+            internalMemberName.visitEnd();
+
+            MethodVisitor linkToStatic = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "linkToStatic", "(FLjava/lang/Object;)I", null, exceptions);
+            linkToStatic.visitCode();
+            linkToStatic.visitVarInsn(FLOAD, 0);
+            linkToStatic.visitVarInsn(ALOAD, 1);
+            linkToStatic.visitMethodInsn(INVOKESTATIC, "java/lang/invoke/MethodHandle", "linkToStatic", "(FLjava/lang/Object;)I", false);
+            linkToStatic.visitInsn(IRETURN);
+            linkToStatic.visitMaxs(1, 1);
+            linkToStatic.visitEnd();
+
+            MethodVisitor invokeBasicI = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "invokeBasicI", "(Ljava/lang/invoke/MethodHandle;F)I", null, exceptions);
+            invokeBasicI.visitCode();
+            invokeBasicI.visitVarInsn(ALOAD, 0);
+            invokeBasicI.visitVarInsn(FLOAD, 1);
+            invokeBasicI.visitMethodInsn(INVOKEVIRTUAL, "java/lang/invoke/MethodHandle", "invokeBasic", "(F)I", false);
+            invokeBasicI.visitInsn(IRETURN);
+            invokeBasicI.visitMaxs(1, 1);
+            invokeBasicI.visitEnd();
+
+        } else {
+            assert className.equals("ISMTest") : className;
+            cw.visitField(ACC_FINAL | ACC_STATIC, "INT_MH", "Ljava/lang/invoke/MethodHandle;", null, null).visitAnnotation("Ljava/lang/invoke/Stable.class;", true).visitEnd();
+            MethodVisitor clinit = cw.visitMethod(ACC_STATIC, "<clinit>", "()V", null, exceptions);
+            clinit.visitCode();
+            clinit.visitInsn(ACONST_NULL);
+            clinit.visitVarInsn(ASTORE, 0);
+            clinit.visitMethodInsn(INVOKESTATIC, "java/lang/invoke/MethodHandles", "lookup", "()Ljava/lang/invoke/MethodHandles$Lookup;", false);
+            clinit.visitLdcInsn(Type.getObjectType(className));
+            clinit.visitLdcInsn("bodyI");
+            clinit.visitFieldInsn(GETSTATIC, "java/lang/Integer", "TYPE", "Ljava/lang/Class;");
+            clinit.visitFieldInsn(GETSTATIC, "java/lang/Integer", "TYPE", "Ljava/lang/Class;");
+            clinit.visitMethodInsn(INVOKESTATIC, "java/lang/invoke/MethodType", "methodType", "(Ljava/lang/Class;Ljava/lang/Class;)Ljava/lang/invoke/MethodType;", false);
+            clinit.visitMethodInsn(INVOKEVIRTUAL, "java/lang/invoke/MethodHandles$Lookup", "findStatic",
+                            "(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/MethodHandle;", false);
+            clinit.visitFieldInsn(PUTSTATIC, className, "INT_MH", "Ljava/lang/invoke/MethodHandle;");
+            clinit.visitInsn(RETURN);
+            clinit.visitMaxs(1, 1);
+            clinit.visitEnd();
+
+            MethodVisitor mainLink = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "mainLink", "(I)I", null, exceptions);
+            mainLink.visitCode();
+            mainLink.visitFieldInsn(GETSTATIC, className, "INT_MH", "Ljava/lang/invoke/MethodHandle;");
+            mainLink.visitMethodInsn(INVOKESTATIC, "java/lang/invoke/MHHelper", "internalMemberName", "(Ljava/lang/invoke/MethodHandle;)Ljava/lang/Object;", false);
+            mainLink.visitVarInsn(ASTORE, 1);
+            mainLink.visitVarInsn(ILOAD, 0);
+            mainLink.visitInsn(I2F);
+            mainLink.visitVarInsn(ALOAD, 1);
+            mainLink.visitMethodInsn(INVOKESTATIC, "java/lang/invoke/MHHelper", "linkToStatic", "(FLjava/lang/Object;)I", false);
+            mainLink.visitInsn(IRETURN);
+            mainLink.visitMaxs(1, 1);
+            mainLink.visitEnd();
+
+            MethodVisitor mainInvoke = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "mainInvoke", "(I)I", null, exceptions);
+            mainInvoke.visitCode();
+            mainInvoke.visitFieldInsn(GETSTATIC, className, "INT_MH", "Ljava/lang/invoke/MethodHandle;");
+            mainInvoke.visitVarInsn(ILOAD, 0);
+            mainInvoke.visitInsn(I2F);
+            mainInvoke.visitMethodInsn(INVOKESTATIC, "java/lang/invoke/MHHelper", "invokeBasicI", "(Ljava/lang/invoke/MethodHandle;F)I", false);
+            mainInvoke.visitInsn(IRETURN);
+            mainInvoke.visitMaxs(1, 1);
+            mainInvoke.visitEnd();
+
+            MethodVisitor bodyI = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "bodyI", "(I)I", null, null);
+            bodyI.visitCode();
+            bodyI.visitVarInsn(ILOAD, 0);
+            bodyI.visitIntInsn(SIPUSH, 1023);
+            bodyI.visitInsn(IAND);
+            bodyI.visitInsn(IRETURN);
+            bodyI.visitMaxs(1, 1);
+            bodyI.visitEnd();
+        }
+        cw.visitEnd();
+        return cw.toByteArray();
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/PEGraphDecoderTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/PEGraphDecoderTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -43,9 +43,9 @@
 import org.graalvm.compiler.nodes.memory.ReadNode;
 import org.graalvm.compiler.nodes.memory.address.AddressNode;
 import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.phases.OptimisticOptimizations;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.graalvm.compiler.replacements.CachingPEGraphDecoder;
 import jdk.internal.vm.compiler.word.LocationIdentity;
 import org.junit.Test;
@@ -138,13 +138,13 @@
             registerPlugins(graphBuilderConfig.getPlugins().getInvocationPlugins());
             targetGraph = new StructuredGraph.Builder(getInitialOptions(), debug, AllowAssumptions.YES).method(testMethod).build();
             CachingPEGraphDecoder decoder = new CachingPEGraphDecoder(getTarget().arch, targetGraph, getProviders(), graphBuilderConfig, OptimisticOptimizations.NONE, AllowAssumptions.YES,
-                            null, null, new InlineInvokePlugin[]{new InlineAll()}, null, null, null, null);
+                            null, null, new InlineInvokePlugin[]{new InlineAll()}, null, null, null, null, null);
 
             decoder.decode(testMethod, false, false);
             debug.dump(DebugContext.BASIC_LEVEL, targetGraph, "Target Graph");
             targetGraph.verify();
 
-            PhaseContext context = new PhaseContext(getProviders());
+            CoreProviders context = getProviders();
             new CanonicalizerPhase().apply(targetGraph, context);
             targetGraph.verify();
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/ReplacementsParseTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/ReplacementsParseTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -69,7 +69,7 @@
 import org.graalvm.compiler.phases.common.GuardLoweringPhase;
 import org.graalvm.compiler.phases.common.LoweringPhase;
 import org.graalvm.compiler.phases.tiers.HighTierContext;
-import org.graalvm.compiler.test.GraalTest;
+import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
 import jdk.internal.vm.compiler.word.LocationIdentity;
 import org.junit.Assert;
 import org.junit.Assume;
@@ -375,7 +375,7 @@
 
     @Test
     public void testNextAfter() {
-        Assume.assumeFalse(GraalTest.Java8OrEarlier);
+        Assume.assumeFalse(JavaVersionUtil.JAVA_SPEC <= 8);
         double[] inArray = new double[1024];
         double[] outArray = new double[1024];
         for (int i = 0; i < inArray.length; i++) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/RootMethodSubstitutionTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/RootMethodSubstitutionTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -34,6 +34,7 @@
 import org.graalvm.compiler.core.target.Backend;
 import org.graalvm.compiler.core.test.GraalCompilerTest;
 import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.nodes.Cancellable;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin;
 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins;
@@ -51,7 +52,7 @@
 
 /**
  * Exercise
- * {@link org.graalvm.compiler.nodes.spi.Replacements#getIntrinsicGraph(ResolvedJavaMethod, CompilationIdentifier, DebugContext)}
+ * {@link org.graalvm.compiler.nodes.spi.Replacements#getIntrinsicGraph(ResolvedJavaMethod, CompilationIdentifier, DebugContext, Cancellable)}
  * with regular method substitutions and encoded graphs.
  */
 @RunWith(Parameterized.class)
@@ -113,14 +114,14 @@
     private StructuredGraph getIntrinsicGraph(boolean useEncodedGraphs) {
         OptionValues options = new OptionValues(getDebugContext().getOptions(), GraalOptions.UseEncodedGraphs, useEncodedGraphs);
         DebugContext debugContext = DebugContext.create(options, getDebugContext().getDescription(), getDebugHandlersFactories());
-        return getReplacements().getIntrinsicGraph(method, CompilationIdentifier.INVALID_COMPILATION_ID, debugContext);
+        return getReplacements().getIntrinsicGraph(method, CompilationIdentifier.INVALID_COMPILATION_ID, debugContext, null);
     }
 
     StructuredGraph expectedGraph;
     StructuredGraph actualGraph;
 
     @Override
-    protected boolean checkHighTierGraph(StructuredGraph graph) {
+    protected void checkHighTierGraph(StructuredGraph graph) {
         // Capture the graphs after high tier
         if (expectedGraph == null) {
             expectedGraph = (StructuredGraph) graph.copy(graph.getDebug());
@@ -128,7 +129,7 @@
             assert actualGraph == null;
             actualGraph = (StructuredGraph) graph.copy(graph.getDebug());
         }
-        return super.checkHighTierGraph(graph);
+        super.checkHighTierGraph(graph);
     }
 
     @Test
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringCompareToTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringCompareToTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -91,7 +91,7 @@
         OptionValues options;
         boolean needCheckNode = true;
 
-        if (JavaVersionUtil.Java8OrEarlier) {
+        if (JavaVersionUtil.JAVA_SPEC <= 8) {
             needCheckNode = false;
         } else {
             List<String> vmArgs = GraalServices.getInputArguments();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringCompressInflateTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringCompressInflateTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -35,6 +35,7 @@
 import org.graalvm.compiler.replacements.amd64.AMD64StringLatin1Substitutions;
 import org.graalvm.compiler.replacements.amd64.AMD64StringUTF16CompressNode;
 import org.graalvm.compiler.replacements.amd64.AMD64StringUTF16Substitutions;
+import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
 import org.graalvm.compiler.test.AddExports;
 import org.junit.Before;
 import org.junit.Test;
@@ -55,7 +56,7 @@
 
     @Before
     public void checkAMD64() {
-        assumeFalse(Java8OrEarlier);
+        assumeFalse(JavaVersionUtil.JAVA_SPEC <= 8);
         // Test case is (currently) AMD64 only.
         assumeTrue(getTarget().arch instanceof AMD64);
     }
@@ -114,7 +115,7 @@
         Class<?> javaclass = Class.forName("java.lang.StringLatin1");
 
         ResolvedJavaMethod caller = getResolvedJavaMethod(javaclass, "inflate", byte[].class, int.class, byte[].class, int.class, int.class);
-        StructuredGraph graph = getReplacements().getIntrinsicGraph(caller, CompilationIdentifier.INVALID_COMPILATION_ID, getDebugContext());
+        StructuredGraph graph = getReplacements().getIntrinsicGraph(caller, CompilationIdentifier.INVALID_COMPILATION_ID, getDebugContext(), null);
         assertInGraph(graph, AMD64StringLatin1InflateNode.class);
 
         InstalledCode code = getCode(caller, graph);
@@ -152,7 +153,7 @@
         Class<?> javaclass = Class.forName("java.lang.StringLatin1");
 
         ResolvedJavaMethod caller = getResolvedJavaMethod(javaclass, "inflate", byte[].class, int.class, char[].class, int.class, int.class);
-        StructuredGraph graph = getReplacements().getIntrinsicGraph(caller, CompilationIdentifier.INVALID_COMPILATION_ID, getDebugContext());
+        StructuredGraph graph = getReplacements().getIntrinsicGraph(caller, CompilationIdentifier.INVALID_COMPILATION_ID, getDebugContext(), null);
         assertInGraph(graph, AMD64StringLatin1InflateNode.class);
 
         InstalledCode code = getCode(caller, graph);
@@ -217,7 +218,7 @@
         Class<?> javaclass = Class.forName("java.lang.StringUTF16");
 
         ResolvedJavaMethod caller = getResolvedJavaMethod(javaclass, "compress", byte[].class, int.class, byte[].class, int.class, int.class);
-        StructuredGraph graph = getReplacements().getIntrinsicGraph(caller, CompilationIdentifier.INVALID_COMPILATION_ID, getDebugContext());
+        StructuredGraph graph = getReplacements().getIntrinsicGraph(caller, CompilationIdentifier.INVALID_COMPILATION_ID, getDebugContext(), null);
         assertInGraph(graph, AMD64StringUTF16CompressNode.class);
 
         InstalledCode code = getCode(caller, graph);
@@ -253,7 +254,7 @@
         Class<?> javaclass = Class.forName("java.lang.StringUTF16");
 
         ResolvedJavaMethod caller = getResolvedJavaMethod(javaclass, "compress", char[].class, int.class, byte[].class, int.class, int.class);
-        StructuredGraph graph = getReplacements().getIntrinsicGraph(caller, CompilationIdentifier.INVALID_COMPILATION_ID, getDebugContext());
+        StructuredGraph graph = getReplacements().getIntrinsicGraph(caller, CompilationIdentifier.INVALID_COMPILATION_ID, getDebugContext(), null);
         assertInGraph(graph, AMD64StringUTF16CompressNode.class);
 
         InstalledCode code = getCode(caller, graph);
@@ -299,7 +300,7 @@
         TestMethods(String testmname, Class<?> javaclass, Class<?> intrinsicClass, String javamname, Class<?>... params) {
             javamethod = getResolvedJavaMethod(javaclass, javamname, params);
             testmethod = getResolvedJavaMethod(testmname);
-            testgraph = getReplacements().getIntrinsicGraph(javamethod, CompilationIdentifier.INVALID_COMPILATION_ID, getDebugContext());
+            testgraph = getReplacements().getIntrinsicGraph(javamethod, CompilationIdentifier.INVALID_COMPILATION_ID, getDebugContext(), null);
             assertInGraph(testgraph, intrinsicClass);
 
             assert javamethod != null;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringSubstitutionsTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/StringSubstitutionsTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -27,6 +27,7 @@
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.replacements.StringSubstitutions;
 import org.graalvm.compiler.replacements.nodes.ArrayEqualsNode;
+import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
 import org.junit.Test;
 
 import jdk.vm.ci.code.InstalledCode;
@@ -65,7 +66,7 @@
 
     @Test
     public void testEquals() {
-        if (!Java8OrEarlier) {
+        if (JavaVersionUtil.JAVA_SPEC > 8) {
             // StringSubstitutions are disabled in 1.9
             return;
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/SubstitutionsTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/SubstitutionsTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -130,7 +130,7 @@
     }
 
     @Override
-    protected boolean checkHighTierGraph(StructuredGraph graph) {
+    protected void checkHighTierGraph(StructuredGraph graph) {
         // Check that the graph contains the expected test nodes.
         NodeIterable<ReturnNode> retNodes = graph.getNodes().filter(ReturnNode.class);
         Assert.assertTrue("expected exactly one ReturnNode", retNodes.count() == 1);
@@ -151,8 +151,6 @@
         value.safeDelete();
         guard.safeDelete();
         graph.removeFixed(memory);
-
-        return true;
     }
 
     @Test
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/classfile/ClassfileBytecodeProviderTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/classfile/ClassfileBytecodeProviderTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -109,6 +109,7 @@
 import org.graalvm.compiler.replacements.classfile.ClassfileBytecode;
 import org.graalvm.compiler.replacements.classfile.ClassfileBytecodeProvider;
 import org.graalvm.compiler.runtime.RuntimeProvider;
+import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
 
 import jdk.vm.ci.meta.ConstantPool;
 import jdk.vm.ci.meta.JavaField;
@@ -153,7 +154,7 @@
 
         Assume.assumeTrue(VerifyPhase.class.desiredAssertionStatus());
 
-        String propertyName = Java8OrEarlier ? "sun.boot.class.path" : "jdk.module.path";
+        String propertyName = JavaVersionUtil.JAVA_SPEC <= 8 ? "sun.boot.class.path" : "jdk.module.path";
         String bootclasspath = System.getProperty(propertyName);
         Assert.assertNotNull("Cannot find value of " + propertyName, bootclasspath);
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/classfile/RedefineIntrinsicTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/classfile/RedefineIntrinsicTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -54,6 +54,7 @@
 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins;
 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration;
 import org.graalvm.compiler.replacements.test.ReplacementsTest;
+import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
 import org.graalvm.compiler.test.SubprocessUtil.Subprocess;
 import org.junit.Assert;
 import org.junit.Test;
@@ -110,7 +111,7 @@
             return;
         }
         String recursionPropName = getClass().getName() + ".recursion";
-        if (Java8OrEarlier || Boolean.getBoolean(recursionPropName)) {
+        if (JavaVersionUtil.JAVA_SPEC <= 8 || Boolean.getBoolean(recursionPropName)) {
             testHelper();
         } else {
             List<String> vmArgs = withoutDebuggerArguments(getVMCommandLine());
@@ -206,7 +207,7 @@
         assumeTrue("VM name not in <pid>@<host> format: " + vmName, p != -1);
         String pid = vmName.substring(0, p);
         Class<?> c;
-        if (Java8OrEarlier) {
+        if (JavaVersionUtil.JAVA_SPEC <= 8) {
             ClassLoader cl = ToolProvider.getSystemToolClassLoader();
             c = Class.forName("com.sun.tools.attach.VirtualMachine", true, cl);
         } else {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/CachingPEGraphDecoder.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/CachingPEGraphDecoder.java	Mon Jul 01 14:57:02 2019 -0700
@@ -46,9 +46,10 @@
 import org.graalvm.compiler.nodes.graphbuilderconf.MethodSubstitutionPlugin;
 import org.graalvm.compiler.nodes.graphbuilderconf.NodePlugin;
 import org.graalvm.compiler.nodes.graphbuilderconf.ParameterPlugin;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
+import org.graalvm.compiler.phases.BasePhase;
 import org.graalvm.compiler.phases.OptimisticOptimizations;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.graalvm.compiler.phases.util.Providers;
 
 import jdk.vm.ci.code.Architecture;
@@ -65,11 +66,13 @@
     protected final OptimisticOptimizations optimisticOpts;
     private final AllowAssumptions allowAssumptions;
     private final EconomicMap<ResolvedJavaMethod, EncodedGraph> graphCache;
+    private final BasePhase<? super CoreProviders> postParsingPhase;
 
     public CachingPEGraphDecoder(Architecture architecture, StructuredGraph graph, Providers providers, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts,
                     AllowAssumptions allowAssumptions, LoopExplosionPlugin loopExplosionPlugin, InvocationPlugins invocationPlugins, InlineInvokePlugin[] inlineInvokePlugins,
                     ParameterPlugin parameterPlugin,
-                    NodePlugin[] nodePlugins, ResolvedJavaMethod callInlinedMethod, SourceLanguagePositionProvider sourceLanguagePositionProvider) {
+                    NodePlugin[] nodePlugins, ResolvedJavaMethod callInlinedMethod, SourceLanguagePositionProvider sourceLanguagePositionProvider,
+                    BasePhase<? super CoreProviders> postParsingPhase) {
         super(architecture, graph, providers, loopExplosionPlugin,
                         invocationPlugins, inlineInvokePlugins, parameterPlugin, nodePlugins, callInlinedMethod, sourceLanguagePositionProvider);
 
@@ -77,6 +80,7 @@
         this.graphBuilderConfig = graphBuilderConfig;
         this.optimisticOpts = optimisticOpts;
         this.allowAssumptions = allowAssumptions;
+        this.postParsingPhase = postParsingPhase;
         this.graphCache = EconomicMap.create();
     }
 
@@ -90,7 +94,7 @@
         if (isSubstitution && (UseEncodedGraphs.getValue(options) || IS_IN_NATIVE_IMAGE)) {
             // These must go through Replacements to find the graph to use.
             graphToEncode = providers.getReplacements().getMethodSubstitution(plugin, method, INLINE_AFTER_PARSING, allowAssumptions,
-                            options);
+                            null, options);
         } else {
             graphToEncode = buildGraph(method, plugin, intrinsicBytecodeProvider, isSubstitution);
         }
@@ -101,8 +105,7 @@
          * initial graph.
          */
         try (DebugContext.Scope scope = debug.scope("createGraph", graphToEncode)) {
-            PhaseContext context = new PhaseContext(providers);
-            new ConvertDeoptimizeToGuardPhase().apply(graphToEncode, context);
+            new ConvertDeoptimizeToGuardPhase().apply(graphToEncode, providers);
         } catch (Throwable t) {
             throw debug.handle(t);
         }
@@ -125,13 +128,14 @@
         // @formatter:on
         try (DebugContext.Scope scope = debug.scope("createGraph", graphToEncode)) {
             IntrinsicContext initialIntrinsicContext = intrinsicBytecodeProvider != null
-                            ? new IntrinsicContext(method, plugin.getSubstitute(providers.getMetaAccess()), intrinsicBytecodeProvider, INLINE_AFTER_PARSING) : null;
+                            ? new IntrinsicContext(method, plugin.getSubstitute(providers.getMetaAccess()), intrinsicBytecodeProvider, INLINE_AFTER_PARSING)
+                            : null;
             GraphBuilderPhase.Instance graphBuilderPhaseInstance = createGraphBuilderPhaseInstance(initialIntrinsicContext);
             graphBuilderPhaseInstance.apply(graphToEncode);
-
-            PhaseContext context = new PhaseContext(providers);
-            new CanonicalizerPhase().apply(graphToEncode, context);
-
+            new CanonicalizerPhase().apply(graphToEncode, providers);
+            if (postParsingPhase != null) {
+                postParsingPhase.apply(graphToEncode, providers);
+            }
         } catch (Throwable ex) {
             throw debug.handle(ex);
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ConstantBindingParameterPlugin.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ConstantBindingParameterPlugin.java	Mon Jul 01 14:57:02 2019 -0700
@@ -55,26 +55,28 @@
 
     @Override
     public FloatingNode interceptParameter(GraphBuilderTool b, int index, StampPair stamp) {
-        Object arg = constantArgs[index];
-        if (arg != null) {
-            ConstantNode constantNode;
-            if (arg instanceof ConstantNode) {
-                ConstantNode otherCon = (ConstantNode) arg;
-                if (otherCon.graph() != b.getGraph()) {
-                    /*
-                     * This is a node from another graph, so copy over extra state into a new
-                     * ConstantNode.
-                     */
-                    constantNode = ConstantNode.forConstant(stamp.getTrustedStamp(), otherCon.getValue(), otherCon.getStableDimension(), otherCon.isDefaultStable(), metaAccess);
+        if (index < constantArgs.length) {
+            Object arg = constantArgs[index];
+            if (arg != null) {
+                ConstantNode constantNode;
+                if (arg instanceof ConstantNode) {
+                    ConstantNode otherCon = (ConstantNode) arg;
+                    if (otherCon.graph() != b.getGraph()) {
+                        /*
+                         * This is a node from another graph, so copy over extra state into a new
+                         * ConstantNode.
+                         */
+                        constantNode = ConstantNode.forConstant(stamp.getTrustedStamp(), otherCon.getValue(), otherCon.getStableDimension(), otherCon.isDefaultStable(), metaAccess);
+                    } else {
+                        constantNode = otherCon;
+                    }
+                } else if (arg instanceof Constant) {
+                    constantNode = ConstantNode.forConstant(stamp.getTrustedStamp(), (Constant) arg, metaAccess);
                 } else {
-                    constantNode = otherCon;
+                    constantNode = ConstantNode.forConstant(snippetReflection.forBoxed(stamp.getTrustedStamp().getStackKind(), arg), metaAccess);
                 }
-            } else if (arg instanceof Constant) {
-                constantNode = ConstantNode.forConstant(stamp.getTrustedStamp(), (Constant) arg, metaAccess);
-            } else {
-                constantNode = ConstantNode.forConstant(snippetReflection.forBoxed(stamp.getTrustedStamp().getStackKind(), arg), metaAccess);
+                return constantNode;
             }
-            return constantNode;
         }
         return null;
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/DefaultJavaLoweringProvider.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/DefaultJavaLoweringProvider.java	Mon Jul 01 14:57:02 2019 -0700
@@ -48,7 +48,6 @@
 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
 import org.graalvm.compiler.core.common.LIRKind;
 import org.graalvm.compiler.core.common.spi.ForeignCallsProvider;
-import org.graalvm.compiler.core.common.type.AbstractObjectStamp;
 import org.graalvm.compiler.core.common.type.IntegerStamp;
 import org.graalvm.compiler.core.common.type.ObjectStamp;
 import org.graalvm.compiler.core.common.type.Stamp;
@@ -140,7 +139,6 @@
 import org.graalvm.compiler.replacements.SnippetLowerableMemoryNode.SnippetLowering;
 import org.graalvm.compiler.replacements.nodes.BinaryMathIntrinsicNode;
 import org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode;
-import org.graalvm.compiler.word.WordTypes;
 import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.code.CodeUtil;
@@ -166,7 +164,6 @@
     protected final TargetDescription target;
     private final boolean useCompressedOops;
     private final ResolvedJavaType objectArrayType;
-    private final WordTypes wordTypes;
 
     private BoxingSnippets.Templates boxingSnippets;
     private ConstantStringIndexOfSnippets.Templates indexOfSnippets;
@@ -177,7 +174,6 @@
         this.target = target;
         this.useCompressedOops = useCompressedOops;
         this.objectArrayType = metaAccess.lookupJavaType(Object[].class);
-        this.wordTypes = new WordTypes(metaAccess, target.wordJavaKind);
     }
 
     public void initialize(OptionValues options, Iterable<DebugHandlersFactory> factories, SnippetCounter.Group.Factory factory, Providers providers, SnippetReflectionProvider snippetReflection) {
@@ -436,6 +432,10 @@
     }
 
     public AddressNode createArrayAddress(StructuredGraph graph, ValueNode array, JavaKind elementKind, ValueNode index) {
+        return createArrayAddress(graph, array, elementKind, elementKind, index);
+    }
+
+    public AddressNode createArrayAddress(StructuredGraph graph, ValueNode array, JavaKind arrayKind, JavaKind elementKind, ValueNode index) {
         ValueNode wordIndex;
         if (target.wordSize > 4) {
             wordIndex = graph.unique(new SignExtendNode(index, target.wordSize * 8));
@@ -447,14 +447,14 @@
         int shift = CodeUtil.log2(metaAccess.getArrayIndexScale(elementKind));
         ValueNode scaledIndex = graph.unique(new LeftShiftNode(wordIndex, ConstantNode.forInt(shift, graph)));
 
-        int base = metaAccess.getArrayBaseOffset(elementKind);
+        int base = metaAccess.getArrayBaseOffset(arrayKind);
         ValueNode offset = graph.unique(new AddNode(scaledIndex, ConstantNode.forIntegerKind(target.wordJavaKind, base, graph)));
 
         return graph.unique(new OffsetAddressNode(array, offset));
     }
 
     protected void lowerIndexAddressNode(IndexAddressNode indexAddress) {
-        AddressNode lowered = createArrayAddress(indexAddress.graph(), indexAddress.getArray(), indexAddress.getElementKind(), indexAddress.getIndex());
+        AddressNode lowered = createArrayAddress(indexAddress.graph(), indexAddress.getArray(), indexAddress.getArrayKind(), indexAddress.getElementKind(), indexAddress.getIndex());
         indexAddress.replaceAndDelete(lowered);
     }
 
@@ -517,7 +517,7 @@
 
         AddressNode address = createArrayIndexAddress(graph, array, elementKind, storeIndexed.index(), boundsCheck);
         WriteNode memoryWrite = graph.add(new WriteNode(address, NamedLocationIdentity.getArrayLocation(elementKind), implicitStoreConvert(graph, elementKind, value),
-                        arrayStoreBarrierType(array, storeIndexed.elementKind())));
+                        arrayStoreBarrierType(storeIndexed.elementKind())));
         memoryWrite.setGuard(boundsCheck);
         if (condition != null) {
             tool.createGuard(storeIndexed, condition, DeoptimizationReason.ArrayStoreException, DeoptimizationAction.InvalidateReprofile);
@@ -792,11 +792,11 @@
                                 long offset = fieldOffset(field);
                                 if (offset >= 0) {
                                     address = createOffsetAddress(graph, newObject, offset);
-                                    barrierType = fieldInitializationBarrier(field);
+                                    barrierType = fieldInitializationBarrier(entryKind);
                                 }
                             } else {
                                 address = createOffsetAddress(graph, newObject, metaAccess.getArrayBaseOffset(entryKind) + i * metaAccess.getArrayIndexScale(entryKind));
-                                barrierType = arrayInitializationBarrier(newObject, entryKind);
+                                barrierType = arrayInitializationBarrier(entryKind);
                             }
                             if (address != null) {
                                 WriteNode write = new WriteNode(address, LocationIdentity.init(), implicitStoreConvert(graph, entryKind, value), barrierType);
@@ -829,7 +829,7 @@
                                     barrierType = fieldStoreBarrierType(virtualInstance.field(i));
                                 } else {
                                     address = createArrayAddress(graph, newObject, virtual.entryKind(i), ConstantNode.forInt(i, graph));
-                                    barrierType = arrayStoreBarrierType(newObject, virtual.entryKind(i));
+                                    barrierType = arrayStoreBarrierType(virtual.entryKind(i));
                                 }
                                 if (address != null) {
                                     WriteNode write = new WriteNode(address, LocationIdentity.init(), implicitStoreConvert(graph, JavaKind.Object, allocValue), barrierType);
@@ -943,50 +943,25 @@
     }
 
     protected BarrierType fieldStoreBarrierType(ResolvedJavaField field) {
-        JavaKind fieldKind = wordTypes.asKind(field.getType());
-        if (fieldKind == JavaKind.Object) {
+        if (getStorageKind(field) == JavaKind.Object) {
             return BarrierType.FIELD;
         }
         return BarrierType.NONE;
     }
 
-    /**
-     * If the given value is indeed an array, and its elements are of a word type, return the
-     * correct word kind; in all other cases, return the defaultElementKind. This is needed for
-     * determining the correct write barrier type.
-     *
-     * @param array a value that is expected to have an array stamp
-     * @param defaultElementKind the array's element kind without taking word types into account
-     * @return the element kind of the array taking word types into account
-     */
-    protected JavaKind maybeWordArrayElementKind(ValueNode array, JavaKind defaultElementKind) {
-        JavaKind elementKind = defaultElementKind;
-        Stamp arrayStamp = array.stamp(NodeView.DEFAULT);
-        if (arrayStamp instanceof AbstractObjectStamp && arrayStamp.hasValues()) {
-            ResolvedJavaType arrayType = ((AbstractObjectStamp) arrayStamp).type();
-            if (arrayType != null && arrayType.getComponentType() != null) {
-                elementKind = wordTypes.asKind(arrayType.getComponentType());
-            }
-        }
-        return elementKind;
-    }
-
-    protected BarrierType arrayStoreBarrierType(ValueNode array, JavaKind elementKind) {
-        JavaKind kind = maybeWordArrayElementKind(array, elementKind);
-        if (kind == JavaKind.Object) {
+    protected BarrierType arrayStoreBarrierType(JavaKind elementKind) {
+        if (elementKind == JavaKind.Object) {
             return BarrierType.ARRAY;
         }
         return BarrierType.NONE;
     }
 
-    public BarrierType fieldInitializationBarrier(ResolvedJavaField field) {
-        JavaKind fieldKind = wordTypes.asKind(field.getType());
-        return fieldKind == JavaKind.Object ? BarrierType.FIELD : BarrierType.NONE;
+    public BarrierType fieldInitializationBarrier(JavaKind entryKind) {
+        return entryKind == JavaKind.Object ? BarrierType.FIELD : BarrierType.NONE;
     }
 
-    public BarrierType arrayInitializationBarrier(ValueNode array, JavaKind entryKind) {
-        JavaKind kind = maybeWordArrayElementKind(array, entryKind);
-        return kind == JavaKind.Object ? BarrierType.ARRAY : BarrierType.NONE;
+    public BarrierType arrayInitializationBarrier(JavaKind entryKind) {
+        return entryKind == JavaKind.Object ? BarrierType.ARRAY : BarrierType.NONE;
     }
 
     private BarrierType unsafeStoreBarrierType(RawStoreNode store) {
@@ -1002,9 +977,7 @@
             // Array types must use a precise barrier, so if the type is unknown or is a supertype
             // of Object[] then treat it as an array.
             if (type != null && type.isArray()) {
-                return arrayStoreBarrierType(object, JavaKind.Object);
-            } else if (type != null && wordTypes.isWord(type)) {
-                return BarrierType.NONE;
+                return BarrierType.ARRAY;
             } else if (type == null || type.isAssignableFrom(objectArrayType)) {
                 return BarrierType.UNKNOWN;
             } else {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/Log.java	Wed Jun 26 15:34:13 2019 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,193 +0,0 @@
-/*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package org.graalvm.compiler.replacements;
-
-import static org.graalvm.compiler.replacements.nodes.CStringConstant.cstring;
-
-import java.io.PrintStream;
-
-import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
-import org.graalvm.compiler.graph.Node.ConstantNodeParameter;
-import org.graalvm.compiler.graph.Node.NodeIntrinsic;
-import org.graalvm.compiler.nodes.extended.ForeignCallNode;
-import org.graalvm.compiler.word.Word;
-
-import jdk.vm.ci.meta.JavaKind;
-
-//JaCoCo Exclude
-
-/**
- * Provides {@link PrintStream}-like logging facility.
- */
-public final class Log {
-
-    public static final ForeignCallDescriptor LOG_PRIMITIVE = new ForeignCallDescriptor("logPrimitive", void.class, int.class, long.class, boolean.class);
-    public static final ForeignCallDescriptor LOG_OBJECT = new ForeignCallDescriptor("logObject", void.class, Object.class, boolean.class, boolean.class);
-    public static final ForeignCallDescriptor LOG_PRINTF = new ForeignCallDescriptor("logPrintf", void.class, Word.class, long.class, long.class, long.class);
-
-    @NodeIntrinsic(ForeignCallNode.class)
-    private static native void log(@ConstantNodeParameter ForeignCallDescriptor logObject, Object object, boolean asString, boolean newline);
-
-    @NodeIntrinsic(ForeignCallNode.class)
-    private static native void log(@ConstantNodeParameter ForeignCallDescriptor logPrimitive, int typeChar, long value, boolean newline);
-
-    @NodeIntrinsic(ForeignCallNode.class)
-    private static native void printf(@ConstantNodeParameter ForeignCallDescriptor logPrintf, Word format, long v1, long v2, long v3);
-
-    public static void print(boolean value) {
-        log(LOG_PRIMITIVE, JavaKind.Boolean.getTypeChar(), value ? 1L : 0L, false);
-    }
-
-    public static void print(byte value) {
-        log(LOG_PRIMITIVE, JavaKind.Byte.getTypeChar(), value, false);
-    }
-
-    public static void print(char value) {
-        log(LOG_PRIMITIVE, JavaKind.Char.getTypeChar(), value, false);
-    }
-
-    public static void print(short value) {
-        log(LOG_PRIMITIVE, JavaKind.Short.getTypeChar(), value, false);
-    }
-
-    public static void print(int value) {
-        log(LOG_PRIMITIVE, JavaKind.Int.getTypeChar(), value, false);
-    }
-
-    public static void print(long value) {
-        log(LOG_PRIMITIVE, JavaKind.Long.getTypeChar(), value, false);
-    }
-
-    /**
-     * Prints a formatted string to the log stream.
-     *
-     * @param format a C style printf format value that can contain at most one conversion specifier
-     *            (i.e., a sequence of characters starting with '%').
-     * @param value the value associated with the conversion specifier
-     */
-    public static void printf(String format, long value) {
-        printf(LOG_PRINTF, cstring(format), value, 0L, 0L);
-    }
-
-    public static void printf(String format, long v1, long v2) {
-        printf(LOG_PRINTF, cstring(format), v1, v2, 0L);
-    }
-
-    public static void printf(String format, long v1, long v2, long v3) {
-        printf(LOG_PRINTF, cstring(format), v1, v2, v3);
-    }
-
-    public static void print(float value) {
-        if (Float.isNaN(value)) {
-            print("NaN");
-        } else if (value == Float.POSITIVE_INFINITY) {
-            print("Infinity");
-        } else if (value == Float.NEGATIVE_INFINITY) {
-            print("-Infinity");
-        } else {
-            log(LOG_PRIMITIVE, JavaKind.Float.getTypeChar(), Float.floatToRawIntBits(value), false);
-        }
-    }
-
-    public static void print(double value) {
-        if (Double.isNaN(value)) {
-            print("NaN");
-        } else if (value == Double.POSITIVE_INFINITY) {
-            print("Infinity");
-        } else if (value == Double.NEGATIVE_INFINITY) {
-            print("-Infinity");
-        } else {
-            log(LOG_PRIMITIVE, JavaKind.Double.getTypeChar(), Double.doubleToRawLongBits(value), false);
-        }
-    }
-
-    public static void print(String value) {
-        log(LOG_OBJECT, value, true, false);
-    }
-
-    public static void printObject(Object o) {
-        log(LOG_OBJECT, o, false, false);
-    }
-
-    public static void println(boolean value) {
-        log(LOG_PRIMITIVE, JavaKind.Boolean.getTypeChar(), value ? 1L : 0L, true);
-    }
-
-    public static void println(byte value) {
-        log(LOG_PRIMITIVE, JavaKind.Byte.getTypeChar(), value, true);
-    }
-
-    public static void println(char value) {
-        log(LOG_PRIMITIVE, JavaKind.Char.getTypeChar(), value, true);
-    }
-
-    public static void println(short value) {
-        log(LOG_PRIMITIVE, JavaKind.Short.getTypeChar(), value, true);
-    }
-
-    public static void println(int value) {
-        log(LOG_PRIMITIVE, JavaKind.Int.getTypeChar(), value, true);
-    }
-
-    public static void println(long value) {
-        log(LOG_PRIMITIVE, JavaKind.Long.getTypeChar(), value, true);
-    }
-
-    public static void println(float value) {
-        if (Float.isNaN(value)) {
-            println("NaN");
-        } else if (value == Float.POSITIVE_INFINITY) {
-            println("Infinity");
-        } else if (value == Float.NEGATIVE_INFINITY) {
-            println("-Infinity");
-        } else {
-            log(LOG_PRIMITIVE, JavaKind.Float.getTypeChar(), Float.floatToRawIntBits(value), true);
-        }
-    }
-
-    public static void println(double value) {
-        if (Double.isNaN(value)) {
-            println("NaN");
-        } else if (value == Double.POSITIVE_INFINITY) {
-            println("Infinity");
-        } else if (value == Double.NEGATIVE_INFINITY) {
-            println("-Infinity");
-        } else {
-            log(LOG_PRIMITIVE, JavaKind.Double.getTypeChar(), Double.doubleToRawLongBits(value), true);
-        }
-    }
-
-    public static void println(String value) {
-        log(LOG_OBJECT, value, true, true);
-    }
-
-    public static void printlnObject(Object o) {
-        log(LOG_OBJECT, o, false, true);
-    }
-
-    public static void println() {
-        println("");
-    }
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ReplacementsImpl.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/ReplacementsImpl.java	Mon Jul 01 14:57:02 2019 -0700
@@ -67,6 +67,7 @@
 import org.graalvm.compiler.java.GraphBuilderPhase.Instance;
 import org.graalvm.compiler.loop.phases.ConvertDeoptimizeToGuardPhase;
 import org.graalvm.compiler.nodes.CallTargetNode;
+import org.graalvm.compiler.nodes.Cancellable;
 import org.graalvm.compiler.nodes.Invoke;
 import org.graalvm.compiler.nodes.StateSplit;
 import org.graalvm.compiler.nodes.StructuredGraph;
@@ -86,7 +87,6 @@
 import org.graalvm.compiler.phases.OptimisticOptimizations;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
 import org.graalvm.compiler.phases.common.DeadCodeEliminationPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.graalvm.compiler.phases.util.Providers;
 import org.graalvm.compiler.word.Word;
 import org.graalvm.compiler.word.WordOperationPlugin;
@@ -263,7 +263,7 @@
 
     @Override
     public StructuredGraph getMethodSubstitution(MethodSubstitutionPlugin plugin, ResolvedJavaMethod original, IntrinsicContext.CompilationContext context,
-                    StructuredGraph.AllowAssumptions allowAssumptions, OptionValues options) {
+                    StructuredGraph.AllowAssumptions allowAssumptions, Cancellable cancellable, OptionValues options) {
         // Method substitutions are parsed by the BytecodeParser.
         return null;
     }
@@ -330,7 +330,7 @@
 
     @SuppressWarnings("try")
     @Override
-    public StructuredGraph getIntrinsicGraph(ResolvedJavaMethod method, CompilationIdentifier compilationId, DebugContext debug) {
+    public StructuredGraph getIntrinsicGraph(ResolvedJavaMethod method, CompilationIdentifier compilationId, DebugContext debug, Cancellable cancellable) {
         MethodSubstitutionPlugin msPlugin = getMethodSubstitution(method);
         if (msPlugin != null) {
             ResolvedJavaMethod substMethod = msPlugin.getSubstitute(providers.getMetaAccess());
@@ -560,7 +560,7 @@
 
                 createGraphBuilder(replacements.providers, config, OptimisticOptimizations.NONE, initialIntrinsicContext).apply(graph);
 
-                new CanonicalizerPhase().apply(graph, new PhaseContext(replacements.providers));
+                new CanonicalizerPhase().apply(graph, replacements.providers);
             } catch (Throwable e) {
                 throw debug.handle(e);
             }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetTemplate.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetTemplate.java	Mon Jul 01 14:57:02 2019 -0700
@@ -119,6 +119,7 @@
 import org.graalvm.compiler.nodes.memory.MemoryNode;
 import org.graalvm.compiler.nodes.memory.MemoryPhiNode;
 import org.graalvm.compiler.nodes.spi.ArrayLengthProvider;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
 import org.graalvm.compiler.nodes.spi.MemoryProxy;
 import org.graalvm.compiler.nodes.util.GraphUtil;
@@ -133,7 +134,6 @@
 import org.graalvm.compiler.phases.common.LoweringPhase;
 import org.graalvm.compiler.phases.common.RemoveValueProxyPhase;
 import org.graalvm.compiler.phases.common.inlining.InliningUtil;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 import org.graalvm.compiler.phases.util.Providers;
 import org.graalvm.compiler.replacements.nodes.ExplodeLoopNode;
 import org.graalvm.compiler.replacements.nodes.LoadSnippetVarargParameterNode;
@@ -633,6 +633,10 @@
             }
         }
 
+        public Providers getProviders() {
+            return providers;
+        }
+
         public static Method findMethod(Class<? extends Snippets> declaringClass, String methodName, Method except) {
             for (Method m : declaringClass.getDeclaredMethods()) {
                 if (m.getName().equals(methodName) && !m.equals(except)) {
@@ -698,7 +702,7 @@
          * Gets a template for a given key, creating it first if necessary.
          */
         @SuppressWarnings("try")
-        protected SnippetTemplate template(ValueNode replacee, final Arguments args) {
+        public SnippetTemplate template(ValueNode replacee, final Arguments args) {
             StructuredGraph graph = replacee.graph();
             DebugContext outer = graph.getDebug();
             SnippetTemplate template = Options.UseSnippetTemplateCache.getValue(options) && args.cacheable ? templates.get(args.cacheKey) : null;
@@ -770,8 +774,6 @@
         ResolvedJavaMethod method = snippetGraph.method();
         Signature signature = method.getSignature();
 
-        PhaseContext phaseContext = new PhaseContext(providers);
-
         // Copy snippet graph, replacing constant parameters with given arguments
         final StructuredGraph snippetCopy = new StructuredGraph.Builder(options, debug).name(snippetGraph.name).method(snippetGraph.method()).trackNodeSourcePosition(
                         snippetGraph.trackNodeSourcePosition()).setIsSubstitution(true).build();
@@ -880,7 +882,7 @@
                 }
             }
 
-            explodeLoops(snippetCopy, phaseContext);
+            explodeLoops(snippetCopy, providers);
 
             GuardsStage guardsStage = args.cacheKey.guardsStage;
             // Perform lowering on the snippet
@@ -889,7 +891,7 @@
             }
             snippetCopy.setGuardsStage(guardsStage);
             try (DebugContext.Scope s = debug.scope("LoweringSnippetTemplate", snippetCopy)) {
-                new LoweringPhase(new CanonicalizerPhase(), args.cacheKey.loweringStage).apply(snippetCopy, phaseContext);
+                new LoweringPhase(new CanonicalizerPhase(), args.cacheKey.loweringStage).apply(snippetCopy, providers);
             } catch (Throwable e) {
                 throw debug.handle(e);
             }
@@ -1045,7 +1047,7 @@
         return true;
     }
 
-    public static void explodeLoops(final StructuredGraph snippetCopy, PhaseContext phaseContext) {
+    public static void explodeLoops(final StructuredGraph snippetCopy, CoreProviders providers) {
         // Do any required loop explosion
         boolean exploded = false;
         do {
@@ -1057,8 +1059,8 @@
                 if (loopBegin != null) {
                     LoopEx loop = new LoopsData(snippetCopy).loop(loopBegin);
                     Mark mark = snippetCopy.getMark();
-                    LoopTransformations.fullUnroll(loop, phaseContext, new CanonicalizerPhase());
-                    new CanonicalizerPhase().applyIncremental(snippetCopy, phaseContext, mark, false);
+                    LoopTransformations.fullUnroll(loop, providers, new CanonicalizerPhase());
+                    new CanonicalizerPhase().applyIncremental(snippetCopy, providers, mark, false);
                     loop.deleteUnusedNodes();
                 }
                 GraphUtil.removeFixedWithUnusedInputs(explodeLoop);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java	Mon Jul 01 14:57:02 2019 -0700
@@ -33,8 +33,6 @@
 import static jdk.vm.ci.code.MemoryBarriers.STORE_LOAD;
 import static jdk.vm.ci.code.MemoryBarriers.STORE_STORE;
 import static org.graalvm.compiler.nodes.NamedLocationIdentity.OFF_HEAP_LOCATION;
-import static org.graalvm.compiler.serviceprovider.JavaVersionUtil.Java11OrEarlier;
-import static org.graalvm.compiler.serviceprovider.JavaVersionUtil.Java8OrEarlier;
 
 import java.lang.reflect.Array;
 import java.lang.reflect.Field;
@@ -133,6 +131,7 @@
 import org.graalvm.compiler.replacements.nodes.arithmetic.IntegerSubExactNode;
 import org.graalvm.compiler.replacements.nodes.arithmetic.IntegerSubExactOverflowNode;
 import org.graalvm.compiler.replacements.nodes.arithmetic.IntegerSubExactSplitNode;
+import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
 import org.graalvm.compiler.serviceprovider.SpeculationReasonGroup;
 import jdk.internal.vm.compiler.word.LocationIdentity;
 
@@ -188,7 +187,7 @@
         Field coder = null;
         try {
             STRING_VALUE_FIELD = String.class.getDeclaredField("value");
-            if (!Java8OrEarlier) {
+            if (JavaVersionUtil.JAVA_SPEC > 8) {
                 coder = String.class.getDeclaredField("coder");
             }
         } catch (NoSuchFieldException e) {
@@ -227,7 +226,7 @@
             }
         });
 
-        if (Java8OrEarlier) {
+        if (JavaVersionUtil.JAVA_SPEC <= 8) {
             r.registerMethodSubstitution(StringSubstitutions.class, "equals", Receiver.class, Object.class);
 
             r.register7("indexOf", char[].class, int.class, int.class, char[].class, int.class, int.class, int.class, new StringIndexOfConstantPlugin());
@@ -384,7 +383,7 @@
 
     public static void registerPlatformSpecificUnsafePlugins(InvocationPlugins plugins, BytecodeProvider bytecodeProvider, boolean explicitUnsafeNullChecks, JavaKind[] supportedCasKinds) {
         registerPlatformSpecificUnsafePlugins(supportedCasKinds, new Registration(plugins, Unsafe.class), true, explicitUnsafeNullChecks);
-        if (!Java8OrEarlier) {
+        if (JavaVersionUtil.JAVA_SPEC > 8) {
             registerPlatformSpecificUnsafePlugins(supportedCasKinds, new Registration(plugins, "jdk.internal.misc.Unsafe", bytecodeProvider), false, explicitUnsafeNullChecks);
         }
 
@@ -394,14 +393,14 @@
         if (java8OrEarlier) {
             unsafeCompareAndSwapPluginsRegistrar.register(r, "compareAndSwap", explicitUnsafeNullChecks, new JavaKind[]{JavaKind.Int, JavaKind.Long, JavaKind.Object}, true);
         } else {
-            unsafeCompareAndSwapPluginsRegistrar.register(r, "compareAndSet", explicitUnsafeNullChecks, supportedCasKinds, Java11OrEarlier);
-            unsafeCompareAndExchangePluginsRegistrar.register(r, "compareAndExchange", explicitUnsafeNullChecks, supportedCasKinds, Java11OrEarlier);
+            unsafeCompareAndSwapPluginsRegistrar.register(r, "compareAndSet", explicitUnsafeNullChecks, supportedCasKinds, JavaVersionUtil.JAVA_SPEC <= 11);
+            unsafeCompareAndExchangePluginsRegistrar.register(r, "compareAndExchange", explicitUnsafeNullChecks, supportedCasKinds, JavaVersionUtil.JAVA_SPEC <= 11);
         }
     }
 
     private static void registerUnsafePlugins(InvocationPlugins plugins, BytecodeProvider bytecodeProvider, boolean explicitUnsafeNullChecks) {
         registerUnsafePlugins(new Registration(plugins, Unsafe.class), true, explicitUnsafeNullChecks);
-        if (!Java8OrEarlier) {
+        if (JavaVersionUtil.JAVA_SPEC > 8) {
             registerUnsafePlugins(new Registration(plugins, "jdk.internal.misc.Unsafe", bytecodeProvider), false, explicitUnsafeNullChecks);
         }
     }
@@ -410,7 +409,7 @@
         for (JavaKind kind : JavaKind.values()) {
             if ((kind.isPrimitive() && kind != JavaKind.Void) || kind == JavaKind.Object) {
                 Class<?> javaClass = kind == JavaKind.Object ? Object.class : kind.toJavaClass();
-                String kindName = (kind == JavaKind.Object && !sunMiscUnsafe && !Java11OrEarlier) ? "Reference" : kind.name();
+                String kindName = (kind == JavaKind.Object && !sunMiscUnsafe && !(JavaVersionUtil.JAVA_SPEC <= 11)) ? "Reference" : kind.name();
                 String getName = "get" + kindName;
                 String putName = "put" + kindName;
                 // Object-based accesses
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/gc/G1WriteBarrierSnippets.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,524 @@
+/*
+ * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.replacements.gc;
+
+import static jdk.vm.ci.code.MemoryBarriers.STORE_LOAD;
+import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.FREQUENT_PROBABILITY;
+import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.NOT_FREQUENT_PROBABILITY;
+import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.probability;
+
+import org.graalvm.compiler.api.replacements.Snippet;
+import org.graalvm.compiler.api.replacements.Snippet.ConstantParameter;
+import org.graalvm.compiler.core.common.GraalOptions;
+import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
+import org.graalvm.compiler.graph.Node.ConstantNodeParameter;
+import org.graalvm.compiler.graph.Node.NodeIntrinsic;
+import org.graalvm.compiler.nodes.NamedLocationIdentity;
+import org.graalvm.compiler.nodes.NodeView;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.extended.FixedValueAnchorNode;
+import org.graalvm.compiler.nodes.extended.ForeignCallNode;
+import org.graalvm.compiler.nodes.extended.MembarNode;
+import org.graalvm.compiler.nodes.extended.NullCheckNode;
+import org.graalvm.compiler.nodes.gc.G1ArrayRangePostWriteBarrier;
+import org.graalvm.compiler.nodes.gc.G1ArrayRangePreWriteBarrier;
+import org.graalvm.compiler.nodes.gc.G1PostWriteBarrier;
+import org.graalvm.compiler.nodes.gc.G1PreWriteBarrier;
+import org.graalvm.compiler.nodes.gc.G1ReferentFieldReadBarrier;
+import org.graalvm.compiler.nodes.memory.HeapAccess.BarrierType;
+import org.graalvm.compiler.nodes.memory.address.AddressNode;
+import org.graalvm.compiler.nodes.memory.address.AddressNode.Address;
+import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
+import org.graalvm.compiler.nodes.spi.LoweringTool;
+import org.graalvm.compiler.nodes.type.NarrowOopStamp;
+import org.graalvm.compiler.replacements.SnippetCounter;
+import org.graalvm.compiler.replacements.SnippetCounter.Group;
+import org.graalvm.compiler.replacements.SnippetTemplate;
+import org.graalvm.compiler.replacements.SnippetTemplate.AbstractTemplates;
+import org.graalvm.compiler.replacements.SnippetTemplate.Arguments;
+import org.graalvm.compiler.replacements.SnippetTemplate.SnippetInfo;
+import org.graalvm.compiler.replacements.Snippets;
+import org.graalvm.compiler.replacements.nodes.AssertionNode;
+import org.graalvm.compiler.replacements.nodes.CStringConstant;
+import org.graalvm.compiler.word.Word;
+import jdk.internal.vm.compiler.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.Pointer;
+import jdk.internal.vm.compiler.word.UnsignedWord;
+import jdk.internal.vm.compiler.word.WordFactory;
+
+public abstract class G1WriteBarrierSnippets extends WriteBarrierSnippets implements Snippets {
+
+    public static final LocationIdentity GC_LOG_LOCATION = NamedLocationIdentity.mutable("GC-Log");
+    public static final LocationIdentity GC_INDEX_LOCATION = NamedLocationIdentity.mutable("GC-Index");
+    public static final LocationIdentity SATB_QUEUE_MARKING_LOCATION = NamedLocationIdentity.mutable("GC-Queue-Marking");
+    public static final LocationIdentity SATB_QUEUE_INDEX_LOCATION = NamedLocationIdentity.mutable("GC-Queue-Index");
+    public static final LocationIdentity SATB_QUEUE_BUFFER_LOCATION = NamedLocationIdentity.mutable("GC-Queue-Buffer");
+    public static final LocationIdentity CARD_QUEUE_INDEX_LOCATION = NamedLocationIdentity.mutable("GC-Card-Queue-Index");
+    public static final LocationIdentity CARD_QUEUE_BUFFER_LOCATION = NamedLocationIdentity.mutable("GC-Card-Queue-Buffer");
+
+    public static class Counters {
+        Counters(SnippetCounter.Group.Factory factory) {
+            Group countersWriteBarriers = factory.createSnippetCounterGroup("G1 WriteBarriers");
+            g1AttemptedPreWriteBarrierCounter = new SnippetCounter(countersWriteBarriers, "g1AttemptedPreWriteBarrier", "Number of attempted G1 Pre Write Barriers");
+            g1EffectivePreWriteBarrierCounter = new SnippetCounter(countersWriteBarriers, "g1EffectivePreWriteBarrier", "Number of effective G1 Pre Write Barriers");
+            g1ExecutedPreWriteBarrierCounter = new SnippetCounter(countersWriteBarriers, "g1ExecutedPreWriteBarrier", "Number of executed G1 Pre Write Barriers");
+            g1AttemptedPostWriteBarrierCounter = new SnippetCounter(countersWriteBarriers, "g1AttemptedPostWriteBarrier", "Number of attempted G1 Post Write Barriers");
+            g1EffectiveAfterXORPostWriteBarrierCounter = new SnippetCounter(countersWriteBarriers, "g1EffectiveAfterXORPostWriteBarrier",
+                            "Number of effective G1 Post Write Barriers (after passing the XOR test)");
+            g1EffectiveAfterNullPostWriteBarrierCounter = new SnippetCounter(countersWriteBarriers, "g1EffectiveAfterNullPostWriteBarrier",
+                            "Number of effective G1 Post Write Barriers (after passing the NULL test)");
+            g1ExecutedPostWriteBarrierCounter = new SnippetCounter(countersWriteBarriers, "g1ExecutedPostWriteBarrier", "Number of executed G1 Post Write Barriers");
+        }
+
+        final SnippetCounter g1AttemptedPreWriteBarrierCounter;
+        final SnippetCounter g1EffectivePreWriteBarrierCounter;
+        final SnippetCounter g1ExecutedPreWriteBarrierCounter;
+        final SnippetCounter g1AttemptedPostWriteBarrierCounter;
+        final SnippetCounter g1EffectiveAfterXORPostWriteBarrierCounter;
+        final SnippetCounter g1EffectiveAfterNullPostWriteBarrierCounter;
+        final SnippetCounter g1ExecutedPostWriteBarrierCounter;
+    }
+
+    @Snippet
+    public void g1PreWriteBarrier(Address address, Object object, Object expectedObject, @ConstantParameter boolean doLoad, @ConstantParameter boolean nullCheck,
+                    @ConstantParameter int traceStartCycle, @ConstantParameter Counters counters) {
+        if (nullCheck) {
+            NullCheckNode.nullCheck(address);
+        }
+        Word thread = getThread();
+        verifyOop(object);
+        Word field = Word.fromAddress(address);
+        byte markingValue = thread.readByte(satbQueueMarkingOffset(), SATB_QUEUE_MARKING_LOCATION);
+
+        boolean trace = isTracingActive(traceStartCycle);
+        int gcCycle = 0;
+        if (trace) {
+            Pointer gcTotalCollectionsAddress = WordFactory.pointer(gcTotalCollectionsAddress());
+            gcCycle = (int) gcTotalCollectionsAddress.readLong(0);
+            log(trace, "[%d] G1-Pre Thread %p Object %p\n", gcCycle, thread.rawValue(), Word.objectToTrackedPointer(object).rawValue());
+            log(trace, "[%d] G1-Pre Thread %p Expected Object %p\n", gcCycle, thread.rawValue(), Word.objectToTrackedPointer(expectedObject).rawValue());
+            log(trace, "[%d] G1-Pre Thread %p Field %p\n", gcCycle, thread.rawValue(), field.rawValue());
+            log(trace, "[%d] G1-Pre Thread %p Marking %d\n", gcCycle, thread.rawValue(), markingValue);
+            log(trace, "[%d] G1-Pre Thread %p DoLoad %d\n", gcCycle, thread.rawValue(), doLoad ? 1L : 0L);
+        }
+
+        counters.g1AttemptedPreWriteBarrierCounter.inc();
+        // If the concurrent marker is enabled, the barrier is issued.
+        if (probability(NOT_FREQUENT_PROBABILITY, markingValue != (byte) 0)) {
+            // If the previous value has to be loaded (before the write), the load is issued.
+            // The load is always issued except the cases of CAS and referent field.
+            Object previousObject;
+            if (doLoad) {
+                previousObject = field.readObject(0, BarrierType.NONE);
+                if (trace) {
+                    log(trace, "[%d] G1-Pre Thread %p Previous Object %p\n ", gcCycle, thread.rawValue(), Word.objectToTrackedPointer(previousObject).rawValue());
+                    verifyOop(previousObject);
+                }
+            } else {
+                previousObject = FixedValueAnchorNode.getObject(expectedObject);
+            }
+
+            counters.g1EffectivePreWriteBarrierCounter.inc();
+            // If the previous value is null the barrier should not be issued.
+            if (probability(FREQUENT_PROBABILITY, previousObject != null)) {
+                counters.g1ExecutedPreWriteBarrierCounter.inc();
+                // If the thread-local SATB buffer is full issue a native call which will
+                // initialize a new one and add the entry.
+                Word indexAddress = thread.add(satbQueueIndexOffset());
+                Word indexValue = indexAddress.readWord(0, SATB_QUEUE_INDEX_LOCATION);
+                if (probability(FREQUENT_PROBABILITY, indexValue.notEqual(0))) {
+                    Word bufferAddress = thread.readWord(satbQueueBufferOffset(), SATB_QUEUE_BUFFER_LOCATION);
+                    Word nextIndex = indexValue.subtract(wordSize());
+                    Word logAddress = bufferAddress.add(nextIndex);
+                    // Log the object to be marked as well as update the SATB's buffer next index.
+                    Word previousOop = Word.objectToTrackedPointer(previousObject);
+                    logAddress.writeWord(0, previousOop, GC_LOG_LOCATION);
+                    indexAddress.writeWord(0, nextIndex, GC_INDEX_LOCATION);
+                } else {
+                    g1PreBarrierStub(previousObject);
+                }
+            }
+        }
+    }
+
+    @Snippet
+    public void g1PostWriteBarrier(Address address, Object object, Object value, @ConstantParameter boolean usePrecise, @ConstantParameter int traceStartCycle,
+                    @ConstantParameter Counters counters) {
+        Word thread = getThread();
+        Object fixedValue = FixedValueAnchorNode.getObject(value);
+        verifyOop(object);
+        verifyOop(fixedValue);
+        validateObject(object, fixedValue);
+
+        Pointer oop;
+        if (usePrecise) {
+            oop = Word.fromAddress(address);
+        } else {
+            if (verifyBarrier()) {
+                verifyNotArray(object);
+            }
+            oop = Word.objectToTrackedPointer(object);
+        }
+
+        boolean trace = isTracingActive(traceStartCycle);
+        int gcCycle = 0;
+        if (trace) {
+            Pointer gcTotalCollectionsAddress = WordFactory.pointer(gcTotalCollectionsAddress());
+            gcCycle = (int) gcTotalCollectionsAddress.readLong(0);
+            log(trace, "[%d] G1-Post Thread: %p Object: %p\n", gcCycle, thread.rawValue(), Word.objectToTrackedPointer(object).rawValue());
+            log(trace, "[%d] G1-Post Thread: %p Field: %p\n", gcCycle, thread.rawValue(), oop.rawValue());
+        }
+        Pointer writtenValue = Word.objectToTrackedPointer(fixedValue);
+        // The result of the xor reveals whether the installed pointer crosses heap regions.
+        // In case it does the write barrier has to be issued.
+        final int logOfHeapRegionGrainBytes = logOfHeapRegionGrainBytes();
+        UnsignedWord xorResult = (oop.xor(writtenValue)).unsignedShiftRight(logOfHeapRegionGrainBytes);
+
+        counters.g1AttemptedPostWriteBarrierCounter.inc();
+        if (probability(FREQUENT_PROBABILITY, xorResult.notEqual(0))) {
+            counters.g1EffectiveAfterXORPostWriteBarrierCounter.inc();
+            // If the written value is not null continue with the barrier addition.
+            if (probability(FREQUENT_PROBABILITY, writtenValue.notEqual(0))) {
+                // Calculate the address of the card to be enqueued to the
+                // thread local card queue.
+                Word cardAddress = cardTableAddress().add(oop.unsignedShiftRight(cardTableShift()));
+
+                byte cardByte = cardAddress.readByte(0, GC_CARD_LOCATION);
+                counters.g1EffectiveAfterNullPostWriteBarrierCounter.inc();
+
+                // If the card is already dirty, (hence already enqueued) skip the insertion.
+                if (probability(NOT_FREQUENT_PROBABILITY, cardByte != youngCardValue())) {
+                    MembarNode.memoryBarrier(STORE_LOAD, GC_CARD_LOCATION);
+                    byte cardByteReload = cardAddress.readByte(0, GC_CARD_LOCATION);
+                    if (probability(NOT_FREQUENT_PROBABILITY, cardByteReload != dirtyCardValue())) {
+                        log(trace, "[%d] G1-Post Thread: %p Card: %p \n", gcCycle, thread.rawValue(), WordFactory.unsigned((int) cardByte).rawValue());
+                        cardAddress.writeByte(0, dirtyCardValue(), GC_CARD_LOCATION);
+                        counters.g1ExecutedPostWriteBarrierCounter.inc();
+
+                        // If the thread local card queue is full, issue a native call which will
+                        // initialize a new one and add the card entry.
+                        Word indexValue = thread.readWord(cardQueueIndexOffset(), CARD_QUEUE_INDEX_LOCATION);
+                        if (probability(FREQUENT_PROBABILITY, indexValue.notEqual(0))) {
+                            Word bufferAddress = thread.readWord(cardQueueBufferOffset(), CARD_QUEUE_BUFFER_LOCATION);
+                            Word nextIndex = indexValue.subtract(wordSize());
+                            Word logAddress = bufferAddress.add(nextIndex);
+                            Word indexAddress = thread.add(cardQueueIndexOffset());
+                            // Log the object to be scanned as well as update
+                            // the card queue's next index.
+                            logAddress.writeWord(0, cardAddress, GC_LOG_LOCATION);
+                            indexAddress.writeWord(0, nextIndex, GC_INDEX_LOCATION);
+                        } else {
+                            g1PostBarrierStub(cardAddress);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    @Snippet
+    public void g1ArrayRangePreWriteBarrier(Address address, int length, @ConstantParameter int elementStride) {
+        Word thread = getThread();
+        byte markingValue = thread.readByte(satbQueueMarkingOffset(), SATB_QUEUE_MARKING_LOCATION);
+        // If the concurrent marker is not enabled or the vector length is zero, return.
+        if (probability(FREQUENT_PROBABILITY, markingValue == (byte) 0 || length == 0)) {
+            return;
+        }
+
+        Word bufferAddress = thread.readWord(satbQueueBufferOffset(), SATB_QUEUE_BUFFER_LOCATION);
+        Word indexAddress = thread.add(satbQueueIndexOffset());
+        long indexValue = indexAddress.readWord(0, SATB_QUEUE_INDEX_LOCATION).rawValue();
+        int scale = objectArrayIndexScale();
+        Word start = getPointerToFirstArrayElement(address, length, elementStride);
+
+        for (int i = 0; i < length; i++) {
+            Word arrElemPtr = start.add(i * scale);
+            Object previousObject = arrElemPtr.readObject(0, BarrierType.NONE);
+            verifyOop(previousObject);
+            if (probability(FREQUENT_PROBABILITY, previousObject != null)) {
+                if (probability(FREQUENT_PROBABILITY, indexValue != 0)) {
+                    indexValue = indexValue - wordSize();
+                    Word logAddress = bufferAddress.add(WordFactory.unsigned(indexValue));
+                    // Log the object to be marked as well as update the SATB's buffer next index.
+                    Word previousOop = Word.objectToTrackedPointer(previousObject);
+                    logAddress.writeWord(0, previousOop, GC_LOG_LOCATION);
+                    indexAddress.writeWord(0, WordFactory.unsigned(indexValue), GC_INDEX_LOCATION);
+                } else {
+                    g1PreBarrierStub(previousObject);
+                }
+            }
+        }
+    }
+
+    @Snippet
+    public void g1ArrayRangePostWriteBarrier(Address address, int length, @ConstantParameter int elementStride) {
+        if (probability(NOT_FREQUENT_PROBABILITY, length == 0)) {
+            return;
+        }
+
+        Word thread = getThread();
+        Word bufferAddress = thread.readWord(cardQueueBufferOffset(), CARD_QUEUE_BUFFER_LOCATION);
+        Word indexAddress = thread.add(cardQueueIndexOffset());
+        long indexValue = thread.readWord(cardQueueIndexOffset(), CARD_QUEUE_INDEX_LOCATION).rawValue();
+
+        int cardShift = cardTableShift();
+        Word cardStart = cardTableAddress();
+        Word start = cardStart.add(getPointerToFirstArrayElement(address, length, elementStride).unsignedShiftRight(cardShift));
+        Word end = cardStart.add(getPointerToLastArrayElement(address, length, elementStride).unsignedShiftRight(cardShift));
+
+        Word cur = start;
+        do {
+            byte cardByte = cur.readByte(0, GC_CARD_LOCATION);
+            // If the card is already dirty, (hence already enqueued) skip the insertion.
+            if (probability(NOT_FREQUENT_PROBABILITY, cardByte != youngCardValue())) {
+                MembarNode.memoryBarrier(STORE_LOAD, GC_CARD_LOCATION);
+                byte cardByteReload = cur.readByte(0, GC_CARD_LOCATION);
+                if (probability(NOT_FREQUENT_PROBABILITY, cardByteReload != dirtyCardValue())) {
+                    cur.writeByte(0, dirtyCardValue(), GC_CARD_LOCATION);
+                    // If the thread local card queue is full, issue a native call which will
+                    // initialize a new one and add the card entry.
+                    if (probability(FREQUENT_PROBABILITY, indexValue != 0)) {
+                        indexValue = indexValue - wordSize();
+                        Word logAddress = bufferAddress.add(WordFactory.unsigned(indexValue));
+                        // Log the object to be scanned as well as update
+                        // the card queue's next index.
+                        logAddress.writeWord(0, cur, GC_LOG_LOCATION);
+                        indexAddress.writeWord(0, WordFactory.unsigned(indexValue), GC_INDEX_LOCATION);
+                    } else {
+                        g1PostBarrierStub(cur);
+                    }
+                }
+            }
+            cur = cur.add(1);
+        } while (cur.belowOrEqual(end));
+    }
+
+    protected abstract Word getThread();
+
+    protected abstract int wordSize();
+
+    protected abstract int objectArrayIndexScale();
+
+    protected abstract int satbQueueMarkingOffset();
+
+    protected abstract int satbQueueBufferOffset();
+
+    protected abstract int satbQueueIndexOffset();
+
+    protected abstract int cardQueueBufferOffset();
+
+    protected abstract int cardQueueIndexOffset();
+
+    protected abstract byte dirtyCardValue();
+
+    protected abstract byte youngCardValue();
+
+    protected abstract Word cardTableAddress();
+
+    protected abstract int cardTableShift();
+
+    protected abstract int logOfHeapRegionGrainBytes();
+
+    protected abstract ForeignCallDescriptor preWriteBarrierCallDescriptor();
+
+    protected abstract ForeignCallDescriptor postWriteBarrierCallDescriptor();
+
+    // the data below is only needed for the verification logic
+    protected abstract boolean verifyOops();
+
+    protected abstract boolean verifyBarrier();
+
+    protected abstract long gcTotalCollectionsAddress();
+
+    protected abstract ForeignCallDescriptor verifyOopCallDescriptor();
+
+    protected abstract ForeignCallDescriptor validateObjectCallDescriptor();
+
+    protected abstract ForeignCallDescriptor printfCallDescriptor();
+
+    private boolean isTracingActive(int traceStartCycle) {
+        return traceStartCycle > 0 && ((Pointer) WordFactory.pointer(gcTotalCollectionsAddress())).readLong(0) > traceStartCycle;
+    }
+
+    private void log(boolean enabled, String format, long value1, long value2, long value3) {
+        if (enabled) {
+            printf(printfCallDescriptor(), CStringConstant.cstring(format), value1, value2, value3);
+        }
+    }
+
+    /**
+     * Validation helper method which performs sanity checks on write operations. The addresses of
+     * both the object and the value being written are checked in order to determine if they reside
+     * in a valid heap region. If an object is stale, an invalid access is performed in order to
+     * prematurely crash the VM and debug the stack trace of the faulty method.
+     */
+    private void validateObject(Object parent, Object child) {
+        if (verifyOops() && child != null) {
+            Word parentWord = Word.objectToTrackedPointer(parent);
+            Word childWord = Word.objectToTrackedPointer(child);
+            boolean success = validateOop(validateObjectCallDescriptor(), parentWord, childWord);
+            AssertionNode.assertion(false, success, "Verification ERROR, Parent: %p Child: %p\n", parentWord.rawValue(), childWord.rawValue());
+        }
+    }
+
+    private void verifyOop(Object object) {
+        if (verifyOops()) {
+            verifyOopStub(verifyOopCallDescriptor(), object);
+        }
+    }
+
+    private void g1PreBarrierStub(Object previousObject) {
+        g1PreBarrierStub(preWriteBarrierCallDescriptor(), previousObject);
+    }
+
+    private void g1PostBarrierStub(Word cardAddress) {
+        g1PostBarrierStub(postWriteBarrierCallDescriptor(), cardAddress);
+    }
+
+    @NodeIntrinsic(ForeignCallNode.class)
+    private static native Object verifyOopStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Object object);
+
+    @NodeIntrinsic(ForeignCallNode.class)
+    private static native boolean validateOop(@ConstantNodeParameter ForeignCallDescriptor descriptor, Word parent, Word object);
+
+    @NodeIntrinsic(ForeignCallNode.class)
+    private static native void g1PreBarrierStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Object object);
+
+    @NodeIntrinsic(ForeignCallNode.class)
+    private static native void g1PostBarrierStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Word card);
+
+    @NodeIntrinsic(ForeignCallNode.class)
+    private static native void printf(@ConstantNodeParameter ForeignCallDescriptor logPrintf, Word format, long v1, long v2, long v3);
+
+    public abstract static class G1WriteBarrierLowerer {
+        private final Counters counters;
+
+        public G1WriteBarrierLowerer(Group.Factory factory) {
+            this.counters = new Counters(factory);
+        }
+
+        public void lower(AbstractTemplates templates, SnippetInfo snippet, G1PreWriteBarrier barrier, LoweringTool tool) {
+            Arguments args = new Arguments(snippet, barrier.graph().getGuardsStage(), tool.getLoweringStage());
+            AddressNode address = barrier.getAddress();
+            args.add("address", address);
+            if (address instanceof OffsetAddressNode) {
+                args.add("object", ((OffsetAddressNode) address).getBase());
+            } else {
+                args.add("object", null);
+            }
+
+            ValueNode expected = barrier.getExpectedObject();
+            if (expected != null && expected.stamp(NodeView.DEFAULT) instanceof NarrowOopStamp) {
+                expected = uncompress(expected);
+            }
+            args.add("expectedObject", expected);
+
+            args.addConst("doLoad", barrier.doLoad());
+            args.addConst("nullCheck", barrier.getNullCheck());
+            args.addConst("traceStartCycle", traceStartCycle(barrier.graph()));
+            args.addConst("counters", counters);
+
+            templates.template(barrier, args).instantiate(templates.getProviders().getMetaAccess(), barrier, SnippetTemplate.DEFAULT_REPLACER, args);
+        }
+
+        public void lower(AbstractTemplates templates, SnippetInfo snippet, G1ReferentFieldReadBarrier barrier, LoweringTool tool) {
+            Arguments args = new Arguments(snippet, barrier.graph().getGuardsStage(), tool.getLoweringStage());
+            AddressNode address = barrier.getAddress();
+            args.add("address", address);
+            if (address instanceof OffsetAddressNode) {
+                args.add("object", ((OffsetAddressNode) address).getBase());
+            } else {
+                args.add("object", null);
+            }
+
+            ValueNode expected = barrier.getExpectedObject();
+            if (expected != null && expected.stamp(NodeView.DEFAULT) instanceof NarrowOopStamp) {
+                expected = uncompress(expected);
+            }
+
+            args.add("expectedObject", expected);
+            args.addConst("doLoad", barrier.doLoad());
+            args.addConst("nullCheck", false);
+            args.addConst("traceStartCycle", traceStartCycle(barrier.graph()));
+            args.addConst("counters", counters);
+
+            templates.template(barrier, args).instantiate(templates.getProviders().getMetaAccess(), barrier, SnippetTemplate.DEFAULT_REPLACER, args);
+        }
+
+        public void lower(AbstractTemplates templates, SnippetInfo snippet, G1PostWriteBarrier barrier, LoweringTool tool) {
+            if (barrier.alwaysNull()) {
+                barrier.graph().removeFixed(barrier);
+                return;
+            }
+
+            Arguments args = new Arguments(snippet, barrier.graph().getGuardsStage(), tool.getLoweringStage());
+            AddressNode address = barrier.getAddress();
+            args.add("address", address);
+            if (address instanceof OffsetAddressNode) {
+                args.add("object", ((OffsetAddressNode) address).getBase());
+            } else {
+                assert barrier.usePrecise() : "found imprecise barrier that's not an object access " + barrier;
+                args.add("object", null);
+            }
+
+            ValueNode value = barrier.getValue();
+            if (value.stamp(NodeView.DEFAULT) instanceof NarrowOopStamp) {
+                value = uncompress(value);
+            }
+            args.add("value", value);
+
+            args.addConst("usePrecise", barrier.usePrecise());
+            args.addConst("traceStartCycle", traceStartCycle(barrier.graph()));
+            args.addConst("counters", counters);
+
+            templates.template(barrier, args).instantiate(templates.getProviders().getMetaAccess(), barrier, SnippetTemplate.DEFAULT_REPLACER, args);
+        }
+
+        public void lower(AbstractTemplates templates, SnippetInfo snippet, G1ArrayRangePreWriteBarrier barrier, LoweringTool tool) {
+            Arguments args = new Arguments(snippet, barrier.graph().getGuardsStage(), tool.getLoweringStage());
+            args.add("address", barrier.getAddress());
+            args.add("length", barrier.getLength());
+            args.addConst("elementStride", barrier.getElementStride());
+
+            templates.template(barrier, args).instantiate(templates.getProviders().getMetaAccess(), barrier, SnippetTemplate.DEFAULT_REPLACER, args);
+        }
+
+        public void lower(AbstractTemplates templates, SnippetInfo snippet, G1ArrayRangePostWriteBarrier barrier, LoweringTool tool) {
+            Arguments args = new Arguments(snippet, barrier.graph().getGuardsStage(), tool.getLoweringStage());
+            args.add("address", barrier.getAddress());
+            args.add("length", barrier.getLength());
+            args.addConst("elementStride", barrier.getElementStride());
+
+            templates.template(barrier, args).instantiate(templates.getProviders().getMetaAccess(), barrier, SnippetTemplate.DEFAULT_REPLACER, args);
+        }
+
+        private static int traceStartCycle(StructuredGraph graph) {
+            return GraalOptions.GCDebugStartCycle.getValue(graph.getOptions());
+        }
+
+        protected abstract ValueNode uncompress(ValueNode value);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/gc/SerialWriteBarrierSnippets.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.replacements.gc;
+
+import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.NOT_FREQUENT_PROBABILITY;
+import static org.graalvm.compiler.nodes.extended.BranchProbabilityNode.probability;
+import static org.graalvm.compiler.replacements.SnippetTemplate.DEFAULT_REPLACER;
+
+import org.graalvm.compiler.api.replacements.Snippet;
+import org.graalvm.compiler.api.replacements.Snippet.ConstantParameter;
+import org.graalvm.compiler.nodes.gc.SerialArrayRangeWriteBarrier;
+import org.graalvm.compiler.nodes.gc.SerialWriteBarrier;
+import org.graalvm.compiler.nodes.memory.address.AddressNode.Address;
+import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
+import org.graalvm.compiler.nodes.spi.LoweringTool;
+import org.graalvm.compiler.replacements.SnippetCounter;
+import org.graalvm.compiler.replacements.SnippetCounter.Group;
+import org.graalvm.compiler.replacements.SnippetTemplate.AbstractTemplates;
+import org.graalvm.compiler.replacements.SnippetTemplate.Arguments;
+import org.graalvm.compiler.replacements.SnippetTemplate.SnippetInfo;
+import org.graalvm.compiler.replacements.Snippets;
+import org.graalvm.compiler.replacements.nodes.AssertionNode;
+import org.graalvm.compiler.word.Word;
+import jdk.internal.vm.compiler.word.Pointer;
+
+public abstract class SerialWriteBarrierSnippets extends WriteBarrierSnippets implements Snippets {
+    static class Counters {
+        Counters(SnippetCounter.Group.Factory factory) {
+            Group countersWriteBarriers = factory.createSnippetCounterGroup("Serial WriteBarriers");
+            serialWriteBarrierCounter = new SnippetCounter(countersWriteBarriers, "serialWriteBarrier", "Number of Serial Write Barriers");
+        }
+
+        final SnippetCounter serialWriteBarrierCounter;
+    }
+
+    @Snippet
+    public void serialImpreciseWriteBarrier(Object object, @ConstantParameter Counters counters, @ConstantParameter boolean verifyOnly) {
+        if (verifyBarrier()) {
+            verifyNotArray(object);
+        }
+        serialWriteBarrier(Word.objectToTrackedPointer(object), counters, verifyOnly);
+    }
+
+    @Snippet
+    public void serialPreciseWriteBarrier(Address address, @ConstantParameter Counters counters, @ConstantParameter boolean verifyOnly) {
+        serialWriteBarrier(Word.fromAddress(address), counters, verifyOnly);
+    }
+
+    @Snippet
+    public void serialArrayRangeWriteBarrier(Address address, int length, @ConstantParameter int elementStride) {
+        if (probability(NOT_FREQUENT_PROBABILITY, length == 0)) {
+            return;
+        }
+
+        int cardShift = cardTableShift();
+        Word cardTableAddress = cardTableAddress();
+        Word start = cardTableAddress.add(getPointerToFirstArrayElement(address, length, elementStride).unsignedShiftRight(cardShift));
+        Word end = cardTableAddress.add(getPointerToLastArrayElement(address, length, elementStride).unsignedShiftRight(cardShift));
+
+        Word cur = start;
+        do {
+            cur.writeByte(0, dirtyCardValue(), GC_CARD_LOCATION);
+            cur = cur.add(1);
+        } while (cur.belowOrEqual(end));
+    }
+
+    private void serialWriteBarrier(Pointer ptr, Counters counters, boolean verifyOnly) {
+        if (!verifyOnly) {
+            counters.serialWriteBarrierCounter.inc();
+        }
+
+        Word base = cardTableAddress().add(ptr.unsignedShiftRight(cardTableShift()));
+        if (verifyOnly) {
+            byte cardValue = base.readByte(0, GC_CARD_LOCATION);
+            AssertionNode.assertion(false, cardValue == dirtyCardValue(), "card must be dirty");
+        } else {
+            base.writeByte(0, dirtyCardValue(), GC_CARD_LOCATION);
+        }
+    }
+
+    protected abstract Word cardTableAddress();
+
+    protected abstract int cardTableShift();
+
+    protected abstract boolean verifyBarrier();
+
+    protected abstract byte dirtyCardValue();
+
+    public static class SerialWriteBarrierLowerer {
+        private final Counters counters;
+
+        public SerialWriteBarrierLowerer(Group.Factory factory) {
+            this.counters = new Counters(factory);
+        }
+
+        public void lower(AbstractTemplates templates, SnippetInfo preciseSnippet, SnippetInfo impreciseSnippet, SerialWriteBarrier barrier, LoweringTool tool) {
+            Arguments args;
+            if (barrier.usePrecise()) {
+                args = new Arguments(preciseSnippet, barrier.graph().getGuardsStage(), tool.getLoweringStage());
+                args.add("address", barrier.getAddress());
+            } else {
+                args = new Arguments(impreciseSnippet, barrier.graph().getGuardsStage(), tool.getLoweringStage());
+                OffsetAddressNode address = (OffsetAddressNode) barrier.getAddress();
+                args.add("object", address.getBase());
+            }
+            args.addConst("counters", counters);
+            args.addConst("verifyOnly", barrier.getVerifyOnly());
+
+            templates.template(barrier, args).instantiate(templates.getProviders().getMetaAccess(), barrier, DEFAULT_REPLACER, args);
+        }
+
+        public void lower(AbstractTemplates templates, SnippetInfo snippet, SerialArrayRangeWriteBarrier barrier, LoweringTool tool) {
+            Arguments args = new Arguments(snippet, barrier.graph().getGuardsStage(), tool.getLoweringStage());
+            args.add("address", barrier.getAddress());
+            args.add("length", barrier.getLength());
+            args.addConst("elementStride", barrier.getElementStride());
+
+            templates.template(barrier, args).instantiate(templates.getProviders().getMetaAccess(), barrier, DEFAULT_REPLACER, args);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/gc/WriteBarrierSnippets.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.replacements.gc;
+
+import org.graalvm.compiler.nodes.NamedLocationIdentity;
+import org.graalvm.compiler.nodes.PiNode;
+import org.graalvm.compiler.nodes.SnippetAnchorNode;
+import org.graalvm.compiler.nodes.memory.address.AddressNode.Address;
+import org.graalvm.compiler.replacements.nodes.AssertionNode;
+import org.graalvm.compiler.word.Word;
+import jdk.internal.vm.compiler.word.LocationIdentity;
+import jdk.internal.vm.compiler.word.WordFactory;
+
+public abstract class WriteBarrierSnippets {
+    public static final LocationIdentity GC_CARD_LOCATION = NamedLocationIdentity.mutable("GC-Card");
+
+    protected static void verifyNotArray(Object object) {
+        if (object != null) {
+            // Manually build the null check and cast because we're in snippet that's lowered late.
+            AssertionNode.assertion(false, !PiNode.piCastNonNull(object, SnippetAnchorNode.anchor()).getClass().isArray(), "imprecise card mark used with array");
+        }
+    }
+
+    protected static Word getPointerToFirstArrayElement(Address address, int length, int elementStride) {
+        long result = Word.fromAddress(address).rawValue();
+        if (elementStride < 0) {
+            // the address points to the place after the last array element
+            result = result + elementStride * length;
+        }
+        return WordFactory.unsigned(result);
+    }
+
+    protected static Word getPointerToLastArrayElement(Address address, int length, int elementStride) {
+        long result = Word.fromAddress(address).rawValue();
+        if (elementStride < 0) {
+            // the address points to the place after the last array element
+            result = result + elementStride;
+        } else {
+            result = result + (length - 1) * elementStride;
+        }
+        return WordFactory.unsigned(result);
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/DirectStoreNode.java	Wed Jun 26 15:34:13 2019 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-/*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package org.graalvm.compiler.replacements.nodes;
-
-import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2;
-import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1;
-
-import org.graalvm.compiler.core.common.LIRKind;
-import org.graalvm.compiler.core.common.type.StampFactory;
-import org.graalvm.compiler.graph.NodeClass;
-import org.graalvm.compiler.nodeinfo.NodeInfo;
-import org.graalvm.compiler.nodes.FixedWithNextNode;
-import org.graalvm.compiler.nodes.StateSplit;
-import org.graalvm.compiler.nodes.ValueNode;
-import org.graalvm.compiler.nodes.extended.RawStoreNode;
-import org.graalvm.compiler.nodes.spi.LIRLowerable;
-import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
-
-import jdk.vm.ci.meta.JavaKind;
-import jdk.vm.ci.meta.Value;
-
-/**
- * A special purpose store node that differs from {@link RawStoreNode} in that it is not a
- * {@link StateSplit} and takes a computed address instead of an object.
- */
-@NodeInfo(cycles = CYCLES_2, size = SIZE_1)
-public final class DirectStoreNode extends FixedWithNextNode implements LIRLowerable {
-
-    public static final NodeClass<DirectStoreNode> TYPE = NodeClass.create(DirectStoreNode.class);
-    @Input protected ValueNode address;
-    @Input protected ValueNode value;
-    protected final JavaKind kind;
-
-    public DirectStoreNode(ValueNode address, ValueNode value, JavaKind kind) {
-        super(TYPE, StampFactory.forVoid());
-        this.address = address;
-        this.value = value;
-        this.kind = kind;
-    }
-
-    @Override
-    public void generate(NodeLIRBuilderTool gen) {
-        Value v = gen.operand(value);
-        LIRKind lirKind = LIRKind.fromJavaKind(gen.getLIRGeneratorTool().target().arch, kind);
-        gen.getLIRGeneratorTool().getArithmetic().emitStore(lirKind, gen.operand(address), v, null);
-    }
-
-    public ValueNode getAddress() {
-        return address;
-    }
-
-    public ValueNode getValue() {
-        return value;
-    }
-
-    @NodeIntrinsic
-    public static native void storeBoolean(long address, boolean value, @ConstantNodeParameter JavaKind kind);
-}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MacroNode.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MacroNode.java	Mon Jul 01 14:57:02 2019 -0700
@@ -49,6 +49,7 @@
 import org.graalvm.compiler.nodes.StructuredGraph.GuardsStage;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.nodes.spi.Lowerable;
 import org.graalvm.compiler.nodes.spi.LoweringTool;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
@@ -57,7 +58,6 @@
 import org.graalvm.compiler.phases.common.LoweringPhase;
 import org.graalvm.compiler.phases.common.RemoveValueProxyPhase;
 import org.graalvm.compiler.phases.common.inlining.InliningUtil;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 import jdk.internal.vm.compiler.word.LocationIdentity;
 
 import jdk.vm.ci.meta.JavaKind;
@@ -160,7 +160,7 @@
      */
     @SuppressWarnings("try")
     protected StructuredGraph lowerReplacement(final StructuredGraph replacementGraph, LoweringTool tool) {
-        final PhaseContext c = new PhaseContext(tool.getProviders());
+        final CoreProviders c = tool.getProviders();
         if (!graph().hasValueProxies()) {
             new RemoveValueProxyPhase().apply(replacementGraph);
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MethodHandleNode.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/MethodHandleNode.java	Mon Jul 01 14:57:02 2019 -0700
@@ -206,7 +206,8 @@
                     StampPair returnStamp, ValueNode[] arguments) {
         ValueNode methodHandleNode = getReceiver(arguments);
         if (methodHandleNode.isConstant()) {
-            return getTargetInvokeNode(adder, intrinsicMethod, bci, returnStamp, arguments, methodHandleAccess.resolveInvokeBasicTarget(methodHandleNode.asJavaConstant(), true), original);
+            return getTargetInvokeNode(adder, intrinsicMethod, methodHandleAccess, bci, returnStamp, arguments, methodHandleAccess.resolveInvokeBasicTarget(methodHandleNode.asJavaConstant(), true),
+                            original);
         }
         return null;
     }
@@ -227,7 +228,7 @@
                     StampPair returnStamp, ValueNode[] arguments) {
         ValueNode memberNameNode = getMemberName(arguments);
         if (memberNameNode.isConstant()) {
-            return getTargetInvokeNode(adder, intrinsicMethod, bci, returnStamp, arguments, methodHandleAccess.resolveLinkToTarget(memberNameNode.asJavaConstant()), original);
+            return getTargetInvokeNode(adder, intrinsicMethod, methodHandleAccess, bci, returnStamp, arguments, methodHandleAccess.resolveLinkToTarget(memberNameNode.asJavaConstant()), original);
         }
         return null;
     }
@@ -241,9 +242,10 @@
      *
      * @return invoke node for the member name target
      */
-    private static InvokeNode getTargetInvokeNode(GraphAdder adder, IntrinsicMethod intrinsicMethod, int bci, StampPair returnStamp, ValueNode[] originalArguments, ResolvedJavaMethod target,
+    private static InvokeNode getTargetInvokeNode(GraphAdder adder, IntrinsicMethod intrinsicMethod, MethodHandleAccessProvider methodHandleAccess, int bci, StampPair returnStamp,
+                    ValueNode[] originalArguments, ResolvedJavaMethod target,
                     ResolvedJavaMethod original) {
-        if (target == null) {
+        if (target == null || !isConsistentInfo(methodHandleAccess, original, target)) {
             return null;
         }
 
@@ -390,4 +392,84 @@
             return new InvokeNode(callTarget, bci);
         }
     }
+
+    /**
+     * Checks basic type consistency of low level method handle intrinsics.
+     *
+     * @param original declared method
+     * @param target resolved method
+     * @return true if original is type consistent with target
+     */
+    private static boolean isConsistentInfo(MethodHandleAccessProvider methodHandleAccess, ResolvedJavaMethod original, ResolvedJavaMethod target) {
+        IntrinsicMethod originalIntrinsicMethod = methodHandleAccess.lookupMethodHandleIntrinsic(original);
+        assert originalIntrinsicMethod == IntrinsicMethod.INVOKE_BASIC ||
+                        originalIntrinsicMethod == IntrinsicMethod.LINK_TO_STATIC ||
+                        originalIntrinsicMethod == IntrinsicMethod.LINK_TO_SPECIAL ||
+                        originalIntrinsicMethod == IntrinsicMethod.LINK_TO_VIRTUAL ||
+                        originalIntrinsicMethod == IntrinsicMethod.LINK_TO_INTERFACE;
+        IntrinsicMethod targetIntrinsicMethod = methodHandleAccess.lookupMethodHandleIntrinsic(target);
+        Signature originalSignature = original.getSignature();
+        Signature targetSignature = target.getSignature();
+
+        boolean invokeThroughMHIntrinsic = originalIntrinsicMethod != null && targetIntrinsicMethod == null;
+        if (!invokeThroughMHIntrinsic) {
+            return (original.getName().equals(target.getName())) && (originalSignature.equals(targetSignature));
+        }
+
+        // Linkers have appendix argument which is not passed to callee.
+        int hasAppendix = (originalIntrinsicMethod == IntrinsicMethod.LINK_TO_STATIC ||
+                        originalIntrinsicMethod == IntrinsicMethod.LINK_TO_SPECIAL ||
+                        originalIntrinsicMethod == IntrinsicMethod.LINK_TO_VIRTUAL ||
+                        originalIntrinsicMethod == IntrinsicMethod.LINK_TO_INTERFACE) ? 1 : 0;
+        if (originalSignature.getParameterCount(original.hasReceiver()) != (targetSignature.getParameterCount(target.hasReceiver()) + hasAppendix)) {
+            return false; // parameter count mismatch
+        }
+        int senderBase = 0;
+        int receiverBase = 0;
+        switch (originalIntrinsicMethod) {
+            case LINK_TO_VIRTUAL:
+            case LINK_TO_INTERFACE:
+            case LINK_TO_SPECIAL: {
+                if (target.isStatic()) {
+                    return false;
+                }
+                if (originalSignature.getParameterKind(0).isPrimitive()) {
+                    return false; // receiver should be an oop
+                }
+                senderBase = 1; // skip receiver
+                break;
+            }
+            case LINK_TO_STATIC: {
+                if (target.hasReceiver()) {
+                    return false;
+                }
+                break;
+            }
+            case INVOKE_BASIC: {
+                if (target.isStatic()) {
+                    if (targetSignature.getParameterKind(0).isPrimitive()) {
+                        return false; // receiver should be an oop
+                    }
+                    receiverBase = 1; // skip receiver
+                }
+                break;
+            }
+            default:
+                break;
+        }
+        assert (targetSignature.getParameterCount(false) - receiverBase) == (originalSignature.getParameterCount(false) - senderBase - hasAppendix) : "argument count mismatch";
+        int argCount = targetSignature.getParameterCount(false) - receiverBase;
+        for (int i = 0; i < argCount; i++) {
+            if (originalSignature.getParameterKind(senderBase + i).getStackKind() != targetSignature.getParameterKind(receiverBase + i).getStackKind()) {
+                return false;
+            }
+        }
+        // Only check the return type if the symbolic info has non-void return type.
+        // I.e. the return value of the resolved method can be dropped.
+        if (originalSignature.getReturnKind() != JavaKind.Void &&
+                        originalSignature.getReturnKind().getStackKind() != targetSignature.getReturnKind().getStackKind()) {
+            return false;
+        }
+        return true; // no mismatch found
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/BufferUtil.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.serviceprovider;
+
+import java.nio.Buffer;
+
+/**
+ * Covariant return types for some methods in the {@code java.nio.Buffer} were
+ * <a href="https://bugs.openjdk.java.net/browse/JDK-4774077">introduced in JDK 9</a>.
+ *
+ * If calls to these methods are compiled with javac from JDK 9+ using {@code -target 8 -source 8}
+ * then the call sites will invoke the covariant methods in the subclass. For example:
+ *
+ * <pre>
+ * static void reset(ByteBuffer buf) {
+ *     buf.reset();
+ * }
+ * </pre>
+ *
+ * will result in:
+ *
+ * <pre>
+ *    0: aload_0
+ *    1: invokevirtual #7  // Method java/nio/ByteBuffer.reset:()Ljava/nio/ByteBuffer;
+ *    4: pop
+ *    5: return
+ * </pre>
+ *
+ * This will result in a {@link NoSuchMethodError} when run on JDK 8. The workaround for this is to
+ * {@linkplain #asBaseBuffer(Buffer) coerce} the receiver for calls to the covariant methods to
+ * {@link Buffer}.
+ */
+public final class BufferUtil {
+
+    /**
+     * Coerces {@code obj} to be of type {@link Buffer}. This is required instead of a cast as
+     * {@code org.graalvm.compiler.core.test.VerifyBufferUsage} is based on Graal graphs which will
+     * have had redundant casts eliminated by the bytecode parser.
+     */
+    public static Buffer asBaseBuffer(Buffer obj) {
+        return obj;
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/GraalServices.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/GraalServices.java	Mon Jul 01 14:57:02 2019 -0700
@@ -89,7 +89,15 @@
             synchronized (servicesCache) {
                 ArrayList<S> providersList = new ArrayList<>();
                 for (S provider : providers) {
-                    providersList.add(provider);
+                    /*
+                     * When building libgraal, we want providers that comes from the Graal community
+                     * and enterprise modules but not those available on the native-image class
+                     * path.
+                     */
+                    Module module = provider.getClass().getModule();
+                    if (module.isNamed()) {
+                        providersList.add(provider);
+                    }
                 }
                 providers = providersList;
                 servicesCache.put(service, providersList);
@@ -101,7 +109,7 @@
     }
 
     protected static <S> Iterable<S> load0(Class<S> service) {
-        Iterable<S> iterable = ServiceLoader.load(service, GraalServices.class.getClassLoader());
+        Iterable<S> iterable = ServiceLoader.load(service);
         return new Iterable<>() {
             @Override
             public Iterator<S> iterator() {
@@ -136,7 +144,9 @@
      * @param other all JVMCI packages will be opened to the module defining this class
      */
     static void openJVMCITo(Class<?> other) {
-        if (IS_IN_NATIVE_IMAGE) return;
+        if (IS_IN_NATIVE_IMAGE) {
+            return;
+        }
 
         Module jvmciModule = JVMCI_MODULE;
         Module otherModule = other.getModule();
@@ -526,6 +536,6 @@
      * was produced as a result of a call to a {@code valueOf} method.
      */
     public static void markVirtualObjectAsAutoBox(VirtualObject virtualObject) {
-       virtualObject.setIsAutoBox(true);
+        virtualObject.setIsAutoBox(true);
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/JavaVersionUtil.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/JavaVersionUtil.java	Mon Jul 01 14:57:02 2019 -0700
@@ -43,17 +43,7 @@
      * The integer value corresponding to the value of the {@code java.specification.version} system
      * property after any leading {@code "1."} has been stripped.
      */
-    public static final int JAVA_SPECIFICATION_VERSION = getJavaSpecificationVersion();
-
-    /**
-     * Determines if the Java runtime is version 8 or earlier.
-     */
-    public static final boolean Java8OrEarlier = JAVA_SPECIFICATION_VERSION <= 8;
-
-    /**
-     * Determines if the Java runtime is version 11 or earlier.
-     */
-    public static final boolean Java11OrEarlier = JAVA_SPECIFICATION_VERSION <= 11;
+    public static final int JAVA_SPEC = getJavaSpecificationVersion();
 
     private JavaVersionUtil() {
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.test/src/org/graalvm/compiler/test/ExportingClassLoader.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.test/src/org/graalvm/compiler/test/ExportingClassLoader.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,20 +24,22 @@
 
 package org.graalvm.compiler.test;
 
+import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
+
 /**
  * A class loader that exports all packages in the module defining the class loader to all classes
  * in the unnamed module associated with the loader.
  */
 public class ExportingClassLoader extends ClassLoader {
     public ExportingClassLoader() {
-        if (!GraalTest.Java8OrEarlier) {
+        if (JavaVersionUtil.JAVA_SPEC > 8) {
             JLModule.fromClass(getClass()).exportAllPackagesTo(JLModule.getUnnamedModuleFor(this));
         }
     }
 
     public ExportingClassLoader(ClassLoader parent) {
         super(parent);
-        if (!GraalTest.Java8OrEarlier) {
+        if (JavaVersionUtil.JAVA_SPEC > 8) {
             JLModule.fromClass(getClass()).exportAllPackagesTo(JLModule.getUnnamedModuleFor(this));
         }
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.test/src/org/graalvm/compiler/test/GraalTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.test/src/org/graalvm/compiler/test/GraalTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -44,7 +44,6 @@
 import org.graalvm.compiler.debug.GlobalMetrics;
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.serviceprovider.GraalServices;
-import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.AssumptionViolatedException;
@@ -73,9 +72,6 @@
         }
     }
 
-    public static final boolean Java8OrEarlier = JavaVersionUtil.Java8OrEarlier;
-    public static final boolean Java11OrEarlier = JavaVersionUtil.Java11OrEarlier;
-
     protected Method getMethod(String methodName) {
         return getMethod(getClass(), methodName);
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.test/src/org/graalvm/compiler/test/JLModule.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.test/src/org/graalvm/compiler/test/JLModule.java	Mon Jul 01 14:57:02 2019 -0700
@@ -28,6 +28,8 @@
 import java.lang.reflect.Method;
 import java.util.Set;
 
+import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
+
 /**
  * Facade for the {@code java.lang.Module} class introduced in JDK9 that allows tests to be
  * developed against JDK8 but use module logic if deployed on JDK9.
@@ -35,7 +37,7 @@
 public class JLModule {
 
     static {
-        if (GraalTest.Java8OrEarlier) {
+        if (JavaVersionUtil.JAVA_SPEC <= 8) {
             throw new AssertionError("Use of " + JLModule.class + " only allowed if " + GraalTest.class.getName() + ".JDK8OrEarlier is false");
         }
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.test/src/org/graalvm/compiler/test/SubprocessUtil.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.test/src/org/graalvm/compiler/test/SubprocessUtil.java	Mon Jul 01 14:57:02 2019 -0700
@@ -249,7 +249,7 @@
         return new Subprocess(command, process.waitFor(), output);
     }
 
-    private static final boolean isJava8OrEarlier = JavaVersionUtil.Java8OrEarlier;
+    private static final boolean isJava8OrEarlier = JavaVersionUtil.JAVA_SPEC <= 8;
 
     private static boolean hasArg(String optionName) {
         if (optionName.equals("-cp") || optionName.equals("-classpath")) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/EarlyReadEliminationPhase.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/EarlyReadEliminationPhase.java	Mon Jul 01 14:57:02 2019 -0700
@@ -29,10 +29,10 @@
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult;
 import org.graalvm.compiler.nodes.cfg.ControlFlowGraph;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 
-public class EarlyReadEliminationPhase extends EffectsPhase<PhaseContext> {
+public class EarlyReadEliminationPhase extends EffectsPhase<CoreProviders> {
 
     private final boolean considerGuards;
 
@@ -47,14 +47,14 @@
     }
 
     @Override
-    protected void run(StructuredGraph graph, PhaseContext context) {
+    protected void run(StructuredGraph graph, CoreProviders context) {
         if (VirtualUtil.matches(graph, EscapeAnalyzeOnly.getValue(graph.getOptions()))) {
             runAnalysis(graph, context);
         }
     }
 
     @Override
-    protected Closure<?> createEffectsClosure(PhaseContext context, ScheduleResult schedule, ControlFlowGraph cfg) {
+    protected Closure<?> createEffectsClosure(CoreProviders context, ScheduleResult schedule, ControlFlowGraph cfg) {
         assert schedule == null;
         return new ReadEliminationClosure(cfg, considerGuards);
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/EffectsPhase.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/EffectsPhase.java	Mon Jul 01 14:57:02 2019 -0700
@@ -31,19 +31,18 @@
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.graph.Graph.NodeEventScope;
 import org.graalvm.compiler.graph.Node;
-import org.graalvm.compiler.graph.spi.Simplifiable;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult;
 import org.graalvm.compiler.nodes.cfg.ControlFlowGraph;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.phases.BasePhase;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
 import org.graalvm.compiler.phases.common.DeadCodeEliminationPhase;
 import org.graalvm.compiler.phases.common.util.EconomicSetNodeEventListener;
 import org.graalvm.compiler.phases.graph.ReentrantBlockIterator;
 import org.graalvm.compiler.phases.schedule.SchedulePhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 
-public abstract class EffectsPhase<PhaseContextT extends PhaseContext> extends BasePhase<PhaseContextT> {
+public abstract class EffectsPhase<CoreProvidersT extends CoreProviders> extends BasePhase<CoreProvidersT> {
 
     public abstract static class Closure<T> extends ReentrantBlockIterator.BlockIteratorClosure<T> {
 
@@ -69,12 +68,12 @@
     }
 
     @Override
-    protected void run(StructuredGraph graph, PhaseContextT context) {
+    protected void run(StructuredGraph graph, CoreProvidersT context) {
         runAnalysis(graph, context);
     }
 
     @SuppressWarnings("try")
-    public boolean runAnalysis(StructuredGraph graph, PhaseContextT context) {
+    public boolean runAnalysis(StructuredGraph graph, CoreProvidersT context) {
         boolean changed = false;
         CompilationAlarm compilationAlarm = CompilationAlarm.current();
         DebugContext debug = graph.getDebug();
@@ -99,21 +98,15 @@
                         EconomicSetNodeEventListener listener = new EconomicSetNodeEventListener();
                         try (NodeEventScope nes = graph.trackNodeEvents(listener)) {
                             closure.applyEffects();
-                        }
 
-                        if (debug.isDumpEnabled(DebugContext.VERBOSE_LEVEL)) {
-                            debug.dump(DebugContext.VERBOSE_LEVEL, graph, "%s iteration", getName());
+                            if (debug.isDumpEnabled(DebugContext.VERBOSE_LEVEL)) {
+                                debug.dump(DebugContext.VERBOSE_LEVEL, graph, "%s iteration", getName());
+                            }
+
+                            new DeadCodeEliminationPhase(Required).apply(graph);
                         }
 
-                        new DeadCodeEliminationPhase(Required).apply(graph);
-
-                        EconomicSet<Node> changedNodes = listener.getNodes();
-                        for (Node node : graph.getNodes()) {
-                            if (node instanceof Simplifiable) {
-                                changedNodes.add(node);
-                            }
-                        }
-                        postIteration(graph, context, changedNodes);
+                        postIteration(graph, context, listener.getNodes());
                     }
 
                     if (closure.hasChanged()) {
@@ -129,11 +122,11 @@
         return changed;
     }
 
-    protected void postIteration(final StructuredGraph graph, final PhaseContextT context, EconomicSet<Node> changedNodes) {
+    protected void postIteration(final StructuredGraph graph, final CoreProvidersT context, EconomicSet<Node> changedNodes) {
         if (canonicalizer != null) {
             canonicalizer.applyIncremental(graph, context, changedNodes);
         }
     }
 
-    protected abstract Closure<?> createEffectsClosure(PhaseContextT context, ScheduleResult schedule, ControlFlowGraph cfg);
+    protected abstract Closure<?> createEffectsClosure(CoreProvidersT context, ScheduleResult schedule, ControlFlowGraph cfg);
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/GraphEffectList.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/GraphEffectList.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
 
 import java.util.ArrayList;
 
+import org.graalvm.compiler.debug.DebugCloseable;
 import org.graalvm.compiler.debug.DebugContext;
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.nodes.ControlSinkNode;
@@ -196,11 +197,14 @@
 
     public void replaceWithSink(FixedWithNextNode node, ControlSinkNode sink) {
         add("kill if branch", new Effect() {
+            @SuppressWarnings("try")
             @Override
             public void apply(StructuredGraph graph, ArrayList<Node> obsoleteNodes) {
-                graph.addWithoutUnique(sink);
-                node.replaceAtPredecessor(sink);
-                GraphUtil.killCFG(node);
+                try (DebugCloseable position = graph.withNodeSourcePosition(node)) {
+                    graph.addWithoutUnique(sink);
+                    node.replaceAtPredecessor(sink);
+                    GraphUtil.killCFG(node);
+                }
             }
 
             @Override
@@ -221,33 +225,36 @@
      * @param insertBefore
      *
      */
+    @SuppressWarnings("try")
     public void replaceAtUsages(ValueNode node, ValueNode replacement, FixedNode insertBefore) {
         assert node != null && replacement != null : node + " " + replacement;
         assert !node.hasUsages() || node.stamp(NodeView.DEFAULT).isCompatible(replacement.stamp(NodeView.DEFAULT)) : "Replacement node stamp not compatible " + node.stamp(NodeView.DEFAULT) + " vs " +
                         replacement.stamp(NodeView.DEFAULT);
         add("replace at usages", (graph, obsoleteNodes) -> {
-            assert node.isAlive();
-            ValueNode replacementNode = graph.addOrUniqueWithInputs(replacement);
-            assert replacementNode.isAlive();
-            assert insertBefore != null;
-            if (replacementNode instanceof FixedWithNextNode && ((FixedWithNextNode) replacementNode).next() == null) {
-                graph.addBeforeFixed(insertBefore, (FixedWithNextNode) replacementNode);
+            try (DebugCloseable position = graph.withNodeSourcePosition(node)) {
+                assert node.isAlive();
+                ValueNode replacementNode = graph.addOrUniqueWithInputs(replacement);
+                assert replacementNode.isAlive();
+                assert insertBefore != null;
+                if (replacementNode instanceof FixedWithNextNode && ((FixedWithNextNode) replacementNode).next() == null) {
+                    graph.addBeforeFixed(insertBefore, (FixedWithNextNode) replacementNode);
+                }
+                /*
+                 * Keep the (better) stamp information when replacing a node with another one if the
+                 * replacement has a less precise stamp than the original node. This can happen for
+                 * example in the context of read nodes and unguarded pi nodes where the pi will be
+                 * used to improve the stamp information of the read. Such a read might later be
+                 * replaced with a read with a less precise stamp.
+                 */
+                if (node.hasUsages() && !node.stamp(NodeView.DEFAULT).equals(replacementNode.stamp(NodeView.DEFAULT))) {
+                    replacementNode = graph.unique(new PiNode(replacementNode, node.stamp(NodeView.DEFAULT)));
+                }
+                node.replaceAtUsages(replacementNode);
+                if (node instanceof FixedWithNextNode) {
+                    GraphUtil.unlinkFixedNode((FixedWithNextNode) node);
+                }
+                obsoleteNodes.add(node);
             }
-            /*
-             * Keep the (better) stamp information when replacing a node with another one if the
-             * replacement has a less precise stamp than the original node. This can happen for
-             * example in the context of read nodes and unguarded pi nodes where the pi will be used
-             * to improve the stamp information of the read. Such a read might later be replaced
-             * with a read with a less precise stamp.
-             */
-            if (node.hasUsages() && !node.stamp(NodeView.DEFAULT).equals(replacementNode.stamp(NodeView.DEFAULT))) {
-                replacementNode = graph.unique(new PiNode(replacementNode, node.stamp(NodeView.DEFAULT)));
-            }
-            node.replaceAtUsages(replacementNode);
-            if (node instanceof FixedWithNextNode) {
-                GraphUtil.unlinkFixedNode((FixedWithNextNode) node);
-            }
-            obsoleteNodes.add(node);
         });
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PartialEscapePhase.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PartialEscapePhase.java	Mon Jul 01 14:57:02 2019 -0700
@@ -32,6 +32,7 @@
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult;
 import org.graalvm.compiler.nodes.cfg.ControlFlowGraph;
+import org.graalvm.compiler.nodes.spi.CoreProviders;
 import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
 import org.graalvm.compiler.options.Option;
 import org.graalvm.compiler.options.OptionKey;
@@ -39,9 +40,8 @@
 import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.phases.BasePhase;
 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
-import org.graalvm.compiler.phases.tiers.PhaseContext;
 
-public class PartialEscapePhase extends EffectsPhase<PhaseContext> {
+public class PartialEscapePhase extends EffectsPhase<CoreProviders> {
 
     static class Options {
         //@formatter:off
@@ -51,24 +51,24 @@
     }
 
     private final boolean readElimination;
-    private final BasePhase<PhaseContext> cleanupPhase;
+    private final BasePhase<CoreProviders> cleanupPhase;
 
     public PartialEscapePhase(boolean iterative, CanonicalizerPhase canonicalizer, OptionValues options) {
         this(iterative, Options.OptEarlyReadElimination.getValue(options), canonicalizer, null, options);
     }
 
-    public PartialEscapePhase(boolean iterative, CanonicalizerPhase canonicalizer, BasePhase<PhaseContext> cleanupPhase, OptionValues options) {
+    public PartialEscapePhase(boolean iterative, CanonicalizerPhase canonicalizer, BasePhase<CoreProviders> cleanupPhase, OptionValues options) {
         this(iterative, Options.OptEarlyReadElimination.getValue(options), canonicalizer, cleanupPhase, options);
     }
 
-    public PartialEscapePhase(boolean iterative, boolean readElimination, CanonicalizerPhase canonicalizer, BasePhase<PhaseContext> cleanupPhase, OptionValues options) {
+    public PartialEscapePhase(boolean iterative, boolean readElimination, CanonicalizerPhase canonicalizer, BasePhase<CoreProviders> cleanupPhase, OptionValues options) {
         super(iterative ? EscapeAnalysisIterations.getValue(options) : 1, canonicalizer);
         this.readElimination = readElimination;
         this.cleanupPhase = cleanupPhase;
     }
 
     @Override
-    protected void postIteration(StructuredGraph graph, PhaseContext context, EconomicSet<Node> changedNodes) {
+    protected void postIteration(StructuredGraph graph, CoreProviders context, EconomicSet<Node> changedNodes) {
         super.postIteration(graph, context, changedNodes);
         if (cleanupPhase != null) {
             cleanupPhase.apply(graph, context);
@@ -76,7 +76,7 @@
     }
 
     @Override
-    protected void run(StructuredGraph graph, PhaseContext context) {
+    protected void run(StructuredGraph graph, CoreProviders context) {
         if (VirtualUtil.matches(graph, EscapeAnalyzeOnly.getValue(graph.getOptions()))) {
             if (readElimination || graph.hasVirtualizableAllocation()) {
                 runAnalysis(graph, context);
@@ -85,7 +85,7 @@
     }
 
     @Override
-    protected Closure<?> createEffectsClosure(PhaseContext context, ScheduleResult schedule, ControlFlowGraph cfg) {
+    protected Closure<?> createEffectsClosure(CoreProviders context, ScheduleResult schedule, ControlFlowGraph cfg) {
         for (VirtualObjectNode virtual : cfg.graph.getNodes(VirtualObjectNode.TYPE)) {
             virtual.resetObjectId();
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphOutput.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphOutput.java	Mon Jul 01 14:57:02 2019 -0700
@@ -38,7 +38,7 @@
  *
  * @param <G> the type of graph this instance handles
  * @param <M> the type of methods this instance handles
- * @since 1.0 a {@link WritableByteChannel} is implemented
+ * @since 19.0 a {@link WritableByteChannel} is implemented
  */
 public final class GraphOutput<G, M> implements Closeable, WritableByteChannel {
     private final GraphProtocol<G, ?, ?, ?, ?, M, ?, ?, ?, ?> printer;
@@ -112,7 +112,7 @@
      * Checks if the {@link GraphOutput} is open.
      *
      * @return true if the {@link GraphOutput} is open.
-     * @since 1.0
+     * @since 19.0
      */
     @Override
     public boolean isOpen() {
@@ -125,7 +125,7 @@
      * @param src the bytes to write
      * @return the number of bytes written, possibly zero
      * @throws IOException in case of IO error
-     * @since 1.0
+     * @since 19.0
      */
     @Override
     public int write(ByteBuffer src) throws IOException {
@@ -178,7 +178,7 @@
          *
          * @param embedded if {@code true} the builder creates an embedded {@link GraphOutput}
          * @return this builder
-         * @since 1.0
+         * @since 19.0
          */
         public Builder<G, N, M> embedded(boolean embedded) {
             this.embeddedGraphOutput = embedded;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphProtocol.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphProtocol.java	Mon Jul 01 14:57:02 2019 -0700
@@ -28,6 +28,7 @@
 import java.io.IOException;
 import java.net.URI;
 import java.net.URISyntaxException;
+import java.nio.Buffer;
 import java.nio.ByteBuffer;
 import java.nio.channels.WritableByteChannel;
 import java.nio.charset.Charset;
@@ -86,6 +87,13 @@
     final int versionMinor;
     private boolean printing;
 
+    /**
+     * See {@code org.graalvm.compiler.serviceprovider.BufferUtil}.
+     */
+    private static Buffer asBaseBuffer(Buffer obj) {
+        return obj;
+    }
+
     GraphProtocol(WritableByteChannel channel, int major, int minor, boolean embedded) throws IOException {
         if (major > MAJOR_VERSION || (major == MAJOR_VERSION && minor > MINOR_VERSION)) {
             throw new IllegalArgumentException("Unrecognized version " + major + "." + minor);
@@ -328,7 +336,7 @@
     }
 
     private void flush() throws IOException {
-        buffer.flip();
+        asBaseBuffer(buffer).flip();
         /*
          * Try not to let interrupted threads abort the write. There's still a race here but an
          * interrupt that's been pending for a long time shouldn't stop this writing.
@@ -411,12 +419,12 @@
         while (b.position() < limit) {
             int toWrite = Math.min(limit - b.position(), buffer.capacity());
             ensureAvailable(toWrite);
-            b.limit(b.position() + toWrite);
+            asBaseBuffer(b).limit(b.position() + toWrite);
             try {
                 buffer.put(b);
                 written += toWrite;
             } finally {
-                b.limit(limit);
+                asBaseBuffer(b).limit(limit);
             }
         }
         return written;
@@ -430,7 +438,7 @@
             int sizeInBytes = b.length * 4;
             ensureAvailable(sizeInBytes);
             buffer.asIntBuffer().put(b);
-            buffer.position(buffer.position() + sizeInBytes);
+            asBaseBuffer(buffer).position(buffer.position() + sizeInBytes);
         }
     }
 
@@ -442,7 +450,7 @@
             int sizeInBytes = b.length * 8;
             ensureAvailable(sizeInBytes);
             buffer.asDoubleBuffer().put(b);
-            buffer.position(buffer.position() + sizeInBytes);
+            asBaseBuffer(buffer).position(buffer.position() + sizeInBytes);
         }
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/package-info.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/package-info.java	Mon Jul 01 14:57:02 2019 -0700
@@ -61,8 +61,8 @@
  * <a href="doc-files/diamond.bgv">diamond.bgv</a> file generated from the above diamond structure
  * graph.
  * <p>
- * The primary <b>IGV</b> focus is on graphs used by Graal compiler. As such they aren't plain
- * graphs, but contain various compiler oriented attributes:
+ * The primary <b>IGV</b> focus is on graphs used by the compiler. As such they aren't plain graphs,
+ * but contain various compiler oriented attributes:
  * <ul>
  * <li>{@linkplain org.graalvm.graphio.GraphBlocks code blocks} information</li>
  * <li>{@linkplain org.graalvm.graphio.GraphElements method and fields} information</li>
@@ -80,7 +80,7 @@
  * <a href="http://wiki.apidesign.org/wiki/Singletonizer">singletonizer</a> API pattern again - e.g.
  * no need to change your existing data structures, just implement the operations provided by the
  * interfaces you pass into the builder. By combining these interfaces together you can get as rich,
- * colorful, source linked graphs as Graal compiler produces to describe its optimizations.
+ * colorful, source linked graphs as the compiler produces to describe its optimizations.
  */
 
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.util.test/src/org/graalvm/util/test/CollectionSizeTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.util.test/src/org/graalvm/util/test/CollectionSizeTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -28,7 +28,7 @@
 
 import jdk.internal.vm.compiler.collections.EconomicMap;
 import jdk.internal.vm.compiler.collections.Equivalence;
-import org.graalvm.compiler.test.GraalTest;
+import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
 import org.graalvm.util.ObjectSizeEstimate;
 import org.junit.Assume;
 import org.junit.Test;
@@ -40,7 +40,7 @@
      */
     @Test
     public void testSize() {
-        Assume.assumeTrue("Not working in JDK9 due to module visibility.", GraalTest.Java8OrEarlier);
+        Assume.assumeTrue("Not working in JDK9 due to module visibility.", JavaVersionUtil.JAVA_SPEC <= 8);
         EconomicMap<Object, Object> map = EconomicMap.create(Equivalence.IDENTITY);
         assertEquals(49, ObjectSizeEstimate.forObject(map).getTotalBytes());
 
@@ -59,7 +59,7 @@
      */
     @Test
     public void testCompress() {
-        Assume.assumeTrue("Not working in JDK9 due to module visibility.", GraalTest.Java8OrEarlier);
+        Assume.assumeTrue("Not working in JDK9 due to module visibility.", JavaVersionUtil.JAVA_SPEC <= 8);
         EconomicMap<Object, Object> map = EconomicMap.create();
 
         // Measuring size of map with one entry.
--- a/src/jdk.jdi/share/classes/com/sun/jdi/doc-files/signature.html	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.jdi/share/classes/com/sun/jdi/doc-files/signature.html	Mon Jul 01 14:57:02 2019 -0700
@@ -40,7 +40,6 @@
 </STYLE>
 </HEAD>
 <BODY style="background-color:white">
-<div role="main">
 <h1>JDI Type Signatures</h1>
 <Table Border="0">
 <caption style="font-size:x-large"><b>JDI Type Signatures</b></caption>
@@ -74,6 +73,5 @@
 </pre>has the following type signature:
 <pre>    (ILjava/lang/String;[I)J
 </pre>
-</div>
 </BODY>
 </HTML>
--- a/src/jdk.jdwp.agent/share/native/libjdwp/debugInit.c	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.jdwp.agent/share/native/libjdwp/debugInit.c	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -873,7 +873,6 @@
  "launch=<command line>            run debugger on event             none\n"
  "onthrow=<exception name>         debug on throw                    none\n"
  "onuncaught=y|n                   debug on any uncaught?            n\n"
- "onjcmd=y|n                       start debug via jcmd?             n\n"
  "timeout=<timeout value>          for listen/attach in milliseconds n\n"
  "mutf8=y|n                        output modified utf-8             n\n"
  "quiet=y|n                        control over terminal messages    n\n"));
--- a/src/jdk.zipfs/share/classes/module-info.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/src/jdk.zipfs/share/classes/module-info.java	Mon Jul 01 14:57:02 2019 -0700
@@ -60,7 +60,7 @@
  *
  * <tbody>
  * <tr>
- *   <td scope="row">create</td>
+ *   <th scope="row">create</th>
  *   <td>java.lang.String</td>
  *   <td>false</td>
  *   <td>
@@ -69,7 +69,7 @@
  *   </td>
  * </tr>
  * <tr>
- *   <td scope="row">encoding</td>
+ *   <th scope="row">encoding</th>
  *   <td>java.lang.String</td>
  *   <td>UTF-8</td>
  *   <td>
--- a/test/hotspot/gtest/utilities/test_concurrentHashtable.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/hotspot/gtest/utilities/test_concurrentHashtable.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -36,24 +36,22 @@
 // Amusingly as long as they do not assert they are mt-safe.
 #define SIZE_32 5
 
-struct Pointer;
-
-typedef ConcurrentHashTable<uintptr_t, Pointer, mtInternal> SimpleTestTable;
-typedef ConcurrentHashTable<uintptr_t, Pointer, mtInternal>::MultiGetHandle SimpleTestGetHandle;
-
-// Simplest working CRPT implementation for the hash-table.
-struct Pointer : public SimpleTestTable::BaseConfig {
-  static uintx get_hash(const uintptr_t& value, bool* dead_hash) {
+struct Pointer : public AllStatic {
+  typedef uintptr_t Value;
+  static uintx get_hash(const Value& value, bool* dead_hash) {
     return (uintx)value;
   }
-  static void* allocate_node(size_t size, const uintptr_t& value) {
+  static void* allocate_node(size_t size, const Value& value) {
     return ::malloc(size);
   }
-  static void free_node(void* memory, const uintptr_t& value) {
+  static void free_node(void* memory, const Value& value) {
     ::free(memory);
   }
 };
 
+typedef ConcurrentHashTable<Pointer, mtInternal> SimpleTestTable;
+typedef ConcurrentHashTable<Pointer, mtInternal>::MultiGetHandle SimpleTestGetHandle;
+
 struct SimpleTestLookup {
   uintptr_t _val;
   SimpleTestLookup(uintptr_t val) : _val(val) {}
@@ -414,18 +412,23 @@
 
 //#############################################################################################
 
-class TestInterface;
-
-typedef ConcurrentHashTable<uintptr_t, TestInterface, mtInternal> TestTable;
-typedef ConcurrentHashTable<uintptr_t, TestInterface, mtInternal>::MultiGetHandle TestGetHandle;
-
-class TestInterface : public TestTable::BaseConfig {
+class TestInterface : public AllStatic {
 public:
-  static uintx get_hash(const uintptr_t& value, bool* dead_hash) {
+  typedef uintptr_t Value;
+  static uintx get_hash(const Value& value, bool* dead_hash) {
     return (uintx)(value + 18446744073709551557ul) * 18446744073709551557ul;
   }
+  static void* allocate_node(size_t size, const Value& value) {
+    return AllocateHeap(size, mtInternal);
+  }
+  static void free_node(void* memory, const Value& value) {
+    FreeHeap(memory);
+  }
 };
 
+typedef ConcurrentHashTable<TestInterface, mtInternal> TestTable;
+typedef ConcurrentHashTable<TestInterface, mtInternal>::MultiGetHandle TestGetHandle;
+
 struct TestLookup {
   uintptr_t _val;
   TestLookup(uintptr_t val) : _val(val) {}
--- a/test/hotspot/jtreg/TEST.groups	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/hotspot/jtreg/TEST.groups	Mon Jul 01 14:57:02 2019 -0700
@@ -275,6 +275,7 @@
  -runtime/ErrorHandling/ErrorHandler.java \
  -runtime/ErrorHandling/TestHeapDumpOnOutOfMemoryError.java \
  -runtime/ErrorHandling/TimeoutInErrorHandlingTest.java \
+ -runtime/InvocationTests \
  -runtime/logging/MonitorMismatchTest.java \
  -runtime/memory/ReserveMemory.java \
  -runtime/memory/RunUnitTestsConcurrently.java \
@@ -327,6 +328,7 @@
  -runtime/appcds/ExtraSymbols.java \
  -runtime/appcds/LongClassListPath.java \
  -runtime/appcds/LotsOfClasses.java \
+ -runtime/appcds/RelativePath.java \
  -runtime/appcds/SharedArchiveConsistency.java \
  -runtime/appcds/UnusedCPDuringDump.java \
  -runtime/appcds/VerifierTest_1B.java
@@ -384,6 +386,7 @@
   serviceability/ \
  -runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java \
  -runtime/CompressedOops/UseCompressedOops.java \
+ -runtime/InvocationTests \
  -runtime/Thread/TestThreadDumpMonitorContention.java \
  -:tier1_runtime \
  -:tier1_serviceability \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/c1/CCEMessageTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8225644
+ * @summary C1 dumps incorrect class name in CCE message
+ * @run main/othervm compiler.c1.CCEMessageTest
+ * @run main/othervm -Xcomp -XX:TieredStopAtLevel=1 compiler.c1.CCEMessageTest
+ */
+
+package compiler.c1;
+
+public class CCEMessageTest {
+    public static void main(String... args) {
+        String[] s = null;
+        try {
+            s = (String[])new Object[1];
+        } catch (ClassCastException cce) {
+            if (!cce.getMessage().contains("[Ljava.lang.String;"))
+                throw new AssertionError("Incorrect CCE message", cce);
+        }
+        if (s != null)
+            throw new AssertionError("Unexpected error");
+    }
+}
--- a/test/hotspot/jtreg/compiler/codecache/stress/UnexpectedDeoptimizationAllTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test UnexpectedDeoptimizationAllTest
- * @key stress
- * @summary stressing code cache by forcing unexpected deoptimizations of all methods
- * @library /test/lib /
- * @modules java.base/jdk.internal.misc
- *          java.management
- *
- * @build sun.hotspot.WhiteBox compiler.codecache.stress.Helper compiler.codecache.stress.TestCaseImpl
- * @run driver ClassFileInstaller sun.hotspot.WhiteBox
- *                                sun.hotspot.WhiteBox$WhiteBoxPermission
- * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
- *                   -XX:+WhiteBoxAPI -XX:-DeoptimizeRandom
- *                   -XX:CompileCommand=dontinline,compiler.codecache.stress.Helper$TestCase::method
- *                   -XX:-SegmentedCodeCache
- *                   compiler.codecache.stress.UnexpectedDeoptimizationAllTest
- * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
- *                   -XX:+WhiteBoxAPI -XX:-DeoptimizeRandom
- *                   -XX:CompileCommand=dontinline,compiler.codecache.stress.Helper$TestCase::method
- *                   -XX:+SegmentedCodeCache
- *                   compiler.codecache.stress.UnexpectedDeoptimizationAllTest
- */
-
-package compiler.codecache.stress;
-
-public class UnexpectedDeoptimizationAllTest implements Runnable {
-
-    public static void main(String[] args) {
-        new CodeCacheStressRunner(new UnexpectedDeoptimizationAllTest()).runTest();
-    }
-
-    @Override
-    public void run() {
-        Helper.WHITE_BOX.deoptimizeAll();
-        try {
-            Thread.sleep(10);
-        } catch (Exception e) {
-        }
-    }
-
-}
--- a/test/hotspot/jtreg/compiler/jvmci/common/patches/jdk.internal.vm.ci/jdk/vm/ci/hotspot/CompilerToVMHelper.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/hotspot/jtreg/compiler/jvmci/common/patches/jdk.internal.vm.ci/jdk/vm/ci/hotspot/CompilerToVMHelper.java	Mon Jul 01 14:57:02 2019 -0700
@@ -101,11 +101,6 @@
         }
     }
 
-    public static Object resolveConstantInPool(ConstantPool constantPool, int cpi) {
-        DirectHotSpotObjectConstantImpl obj = (DirectHotSpotObjectConstantImpl) CTVM.resolveConstantInPool((HotSpotConstantPool) constantPool, cpi);
-        return obj.object;
-    }
-
     public static Object resolvePossiblyCachedConstantInPool(ConstantPool constantPool, int cpi) {
         DirectHotSpotObjectConstantImpl obj = (DirectHotSpotObjectConstantImpl) CTVM.resolvePossiblyCachedConstantInPool((HotSpotConstantPool) constantPool, cpi);
         return obj.object;
--- a/test/hotspot/jtreg/compiler/jvmci/compilerToVM/ResolveConstantInPoolTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,122 +0,0 @@
-/*
- * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @bug 8136421
- * @requires vm.jvmci
- * @library /test/lib /
- * @library ../common/patches
- * @modules java.base/jdk.internal.access
- *          java.base/jdk.internal.reflect
- *          java.base/jdk.internal.org.objectweb.asm
- *          jdk.internal.vm.ci/jdk.vm.ci.hotspot
- *          jdk.internal.vm.ci/jdk.vm.ci.runtime
- *          jdk.internal.vm.ci/jdk.vm.ci.meta
- *
- * @build jdk.internal.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper sun.hotspot.WhiteBox
- * @run driver ClassFileInstaller sun.hotspot.WhiteBox
- *                                sun.hotspot.WhiteBox$WhiteBoxPermission
- * @run main/othervm -Xbootclasspath/a:.
- *                   -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
- *                   -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
- *                   -XX:-UseJVMCICompiler
- *                   compiler.jvmci.compilerToVM.ResolveConstantInPoolTest
- */
-
-package compiler.jvmci.compilerToVM;
-
-import compiler.jvmci.compilerToVM.ConstantPoolTestCase.ConstantTypes;
-import compiler.jvmci.compilerToVM.ConstantPoolTestCase.Validator;
-import compiler.jvmci.compilerToVM.ConstantPoolTestsHelper.DummyClasses;
-import jdk.test.lib.Asserts;
-import jdk.vm.ci.hotspot.CompilerToVMHelper;
-import jdk.vm.ci.meta.ConstantPool;
-
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodType;
-import java.util.HashMap;
-import java.util.Map;
-
-import static compiler.jvmci.compilerToVM.ConstantPoolTestCase.ConstantTypes.CONSTANT_METHODHANDLE;
-import static compiler.jvmci.compilerToVM.ConstantPoolTestCase.ConstantTypes.CONSTANT_METHODTYPE;
-
-/**
- * Test for {@code jdk.vm.ci.hotspot.CompilerToVM.resolveConstantInPool} method
- */
-public class ResolveConstantInPoolTest {
-
-    private static final String NOT_NULL_MSG
-            = "Object returned by resolveConstantInPool method should not be null";
-
-    public static void main(String[] args) throws Exception {
-        Map<ConstantTypes, Validator> typeTests = new HashMap<>();
-        typeTests.put(CONSTANT_METHODHANDLE, ResolveConstantInPoolTest::validateMethodHandle);
-        typeTests.put(CONSTANT_METHODTYPE, ResolveConstantInPoolTest::validateMethodType);
-        ConstantPoolTestCase testCase = new ConstantPoolTestCase(typeTests);
-        testCase.test();
-        // The next "Class.forName" and repeating "testCase.test()"
-        // are here for the following reason.
-        // The first test run is without dummy class initialization,
-        // which means no constant pool cache exists.
-        // The second run is with initialized class (with constant pool cache available).
-        // Some CompilerToVM methods require different input
-        // depending on whether CP cache exists or not.
-        for (DummyClasses dummy : DummyClasses.values()) {
-            Class.forName(dummy.klass.getName());
-        }
-        testCase.test();
-    }
-
-    private static void validateMethodHandle(ConstantPool constantPoolCTVM,
-                                             ConstantTypes cpType,
-                                             DummyClasses dummyClass,
-                                             int index) {
-        Object constantInPool = CompilerToVMHelper.resolveConstantInPool(constantPoolCTVM, index);
-        String msg = String.format("%s for index %d", NOT_NULL_MSG, index);
-        Asserts.assertNotNull(constantInPool, msg);
-        if (!(constantInPool instanceof MethodHandle)) {
-            msg = String.format("Wrong constant pool entry accessed by index"
-                                        + " %d: %s, but should be subclass of %s",
-                                index,
-                                constantInPool.getClass(),
-                                MethodHandle.class.getName());
-            throw new AssertionError(msg);
-        }
-    }
-
-    private static void validateMethodType(ConstantPool constantPoolCTVM,
-                                           ConstantTypes cpType,
-                                           DummyClasses dummyClass,
-                                           int index) {
-        Object constantInPool = CompilerToVMHelper.resolveConstantInPool(constantPoolCTVM, index);
-        String msg = String.format("%s for index %d", NOT_NULL_MSG, index);
-        Asserts.assertNotNull(constantInPool, msg);
-        Class mtToVerify = constantInPool.getClass();
-        Class mtToRefer = MethodType.class;
-        msg = String.format("Wrong method type class accessed by"
-                                    + " constant pool index %d",
-                            index);
-        Asserts.assertEQ(mtToRefer, mtToVerify, msg);
-    }
-}
--- a/test/hotspot/jtreg/compiler/jvmci/compilerToVM/ResolvePossiblyCachedConstantInPoolTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/hotspot/jtreg/compiler/jvmci/compilerToVM/ResolvePossiblyCachedConstantInPoolTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -24,6 +24,7 @@
 /*
  * @test
  * @bug 8138708
+ * @bug 8136421
  * @requires vm.jvmci
  * @library /test/lib /
  * @library ../common/patches
@@ -54,9 +55,13 @@
 import jdk.vm.ci.hotspot.CompilerToVMHelper;
 import jdk.vm.ci.meta.ConstantPool;
 
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodType;
 import java.util.HashMap;
 import java.util.Map;
 
+import static compiler.jvmci.compilerToVM.ConstantPoolTestCase.ConstantTypes.CONSTANT_METHODHANDLE;
+import static compiler.jvmci.compilerToVM.ConstantPoolTestCase.ConstantTypes.CONSTANT_METHODTYPE;
 import static compiler.jvmci.compilerToVM.ConstantPoolTestCase.ConstantTypes.CONSTANT_STRING;
 
 /**
@@ -67,10 +72,17 @@
     public static void main(String[] args) throws Exception {
         Map<ConstantTypes, Validator> typeTests = new HashMap<>();
         typeTests.put(CONSTANT_STRING, ResolvePossiblyCachedConstantInPoolTest::validateString);
+        typeTests.put(CONSTANT_METHODHANDLE, ResolvePossiblyCachedConstantInPoolTest::validateMethodHandle);
+        typeTests.put(CONSTANT_METHODTYPE, ResolvePossiblyCachedConstantInPoolTest::validateMethodType);
         ConstantPoolTestCase testCase = new ConstantPoolTestCase(typeTests);
-        // The next "Class.forName" is here for the following reason.
-        // When class is initialized, constant pool cache is available.
-        // This method works only with cached constant pool.
+        testCase.test();
+        // The next "Class.forName" and repeating "testCase.test()"
+        // are here for the following reason.
+        // The first test run is without dummy class initialization,
+        // which means no constant pool cache exists.
+        // The second run is with initialized class (with constant pool cache available).
+        // Some CompilerToVM methods require different input
+        // depending on whether CP cache exists or not.
         for (DummyClasses dummy : DummyClasses.values()) {
             Class.forName(dummy.klass.getName());
         }
@@ -101,4 +113,40 @@
         String msg = String.format("Wrong string accessed by %sconstant pool index %d", cached, index);
         Asserts.assertEQ(stringToRefer, stringToVerify, msg);
     }
+
+    private static final String NOT_NULL_MSG
+            = "Object returned by resolvePossiblyCachedConstantInPool method should not be null";
+
+
+    private static void validateMethodHandle(ConstantPool constantPoolCTVM,
+                                             ConstantTypes cpType,
+                                             DummyClasses dummyClass,
+                                             int index) {
+        Object constantInPool = CompilerToVMHelper.resolvePossiblyCachedConstantInPool(constantPoolCTVM, index);
+        String msg = String.format("%s for index %d", NOT_NULL_MSG, index);
+        Asserts.assertNotNull(constantInPool, msg);
+        if (!(constantInPool instanceof MethodHandle)) {
+            msg = String.format("Wrong constant pool entry accessed by index"
+                                        + " %d: %s, but should be subclass of %s",
+                                index,
+                                constantInPool.getClass(),
+                                MethodHandle.class.getName());
+            throw new AssertionError(msg);
+        }
+    }
+
+    private static void validateMethodType(ConstantPool constantPoolCTVM,
+                                           ConstantTypes cpType,
+                                           DummyClasses dummyClass,
+                                           int index) {
+        Object constantInPool = CompilerToVMHelper.resolvePossiblyCachedConstantInPool(constantPoolCTVM, index);
+        String msg = String.format("%s for index %d", NOT_NULL_MSG, index);
+        Asserts.assertNotNull(constantInPool, msg);
+        Class mtToVerify = constantInPool.getClass();
+        Class mtToRefer = MethodType.class;
+        msg = String.format("Wrong method type class accessed by"
+                                    + " constant pool index %d",
+                            index);
+        Asserts.assertEQ(mtToRefer, mtToVerify, msg);
+    }
 }
--- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestMetaAccessProvider.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestMetaAccessProvider.java	Mon Jul 01 14:57:02 2019 -0700
@@ -68,16 +68,22 @@
                     metaAccess.encodeDeoptActionAndReason(DEOPT_ACTION, DEOPT_REASON, DEBUG_IDS[3]).asInt()
     };
 
+    private static boolean isUnsafeAnoymous(ResolvedJavaType type) {
+        return type.getHostClass() != null;
+    }
+
     @Test
     public void lookupJavaTypeTest() {
         for (Class<?> c : classes) {
             ResolvedJavaType type = metaAccess.lookupJavaType(c);
             assertNotNull(c.toString(), type);
-            assertEquals(c.toString(), type.getName(), toInternalName(c.getName()));
-            assertEquals(c.toString(), type.getName(), toInternalName(type.toJavaName()));
-            assertEquals(c.toString(), c.getName(), type.toClassName());
-            if (!type.isArray()) {
-                assertEquals(c.toString(), c.getName(), type.toJavaName());
+            if (!isUnsafeAnoymous(type)) {
+                assertEquals(c.toString(), type.getName(), toInternalName(c.getName()));
+                assertEquals(c.toString(), type.getName(), toInternalName(type.toJavaName()));
+                assertEquals(c.toString(), c.getName(), type.toClassName());
+                if (!type.isArray()) {
+                    assertEquals(c.toString(), c.getName(), type.toJavaName());
+                }
             }
         }
     }
@@ -92,7 +98,9 @@
         ResolvedJavaType[] result = metaAccess.lookupJavaTypes(classes.toArray(new Class<?>[classes.size()]));
         int counter = 0;
         for (Class<?> aClass : classes) {
-            assertEquals("Unexpected javaType: " + result[counter] + " while expecting of class: " + aClass, result[counter].toClassName(), aClass.getName());
+            if (!isUnsafeAnoymous(result[counter])) {
+                assertEquals("Unexpected javaType: " + result[counter] + " while expecting of class: " + aClass, result[counter].toClassName(), aClass.getName());
+            }
             counter++;
         }
     }
--- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java	Mon Jul 01 14:57:02 2019 -0700
@@ -161,7 +161,11 @@
         for (Class<?> c : classes) {
             ResolvedJavaType type = metaAccess.lookupJavaType(c);
             ResolvedJavaType host = type.getHostClass();
-            assertNull(host);
+            if (!type.equals(predicateType)) {
+                assertNull(host);
+            } else {
+                assertNotNull(host);
+            }
         }
 
         class LocalClass {}
--- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TypeUniverse.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TypeUniverse.java	Mon Jul 01 14:57:02 2019 -0700
@@ -51,6 +51,7 @@
 import java.util.Queue;
 import java.util.Set;
 import java.util.TreeMap;
+import java.util.function.Predicate;
 import java.util.stream.Collectors;
 
 import static java.lang.reflect.Modifier.isFinal;
@@ -68,6 +69,7 @@
     public static final ConstantReflectionProvider constantReflection = JVMCI.getRuntime().getHostJVMCIBackend().getConstantReflection();
     public static final Collection<Class<?>> classes = new HashSet<>();
     public static final Set<ResolvedJavaType> javaTypes;
+    public static final ResolvedJavaType predicateType;
     public static final Map<Class<?>, Class<?>> arrayClasses = new HashMap<>();
 
     private static List<ConstantValue> constants;
@@ -116,6 +118,9 @@
         for (Class<?> c : initialClasses) {
             addClass(c);
         }
+        Predicate<String> predicate = s -> s.length() == 1;
+        addClass(predicate.getClass());
+        predicateType = metaAccess.lookupJavaType(predicate.getClass());
 
         javaTypes = Collections.unmodifiableSet(classes.stream().map(c -> metaAccess.lookupJavaType(c)).collect(Collectors.toSet()));
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/arguments/TestMaxRAMFlags.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package gc.arguments;
+
+/*
+ * @test TestMaxRAMFlags
+ * @key gc
+ * @bug 8222252
+ * @summary Verify correct MaxHeapSize and UseCompressedOops when MaxRAM and MaxRAMPercentage
+ * are specified.
+ * @library /test/lib
+ * @library /
+ * @requires vm.bits == "64"
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main gc.arguments.TestMaxRAMFlags
+ * @author bob.vandette@oracle.com
+ */
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+public class TestMaxRAMFlags {
+
+  private static void checkMaxRAMSize(long maxram, int maxrampercent, boolean forcecoop, long expectheap, boolean expectcoop) throws Exception {
+
+    ArrayList<String> args = new ArrayList<String>();
+    args.add("-XX:MaxRAM=" + maxram);
+    args.add("-XX:MaxRAMPercentage=" + maxrampercent);
+    if (forcecoop) {
+      args.add("-XX:+UseCompressedOops");
+    }
+
+    args.add("-XX:+PrintFlagsFinal");
+    args.add("-version");
+
+    ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(args.toArray(new String[0]));
+    OutputAnalyzer output = new OutputAnalyzer(pb.start());
+    output.shouldHaveExitValue(0);
+    String stdout = output.getStdout();
+
+    long actualheap = new Long(getFlagValue("MaxHeapSize", stdout)).longValue();
+    if (actualheap != expectheap) {
+      throw new RuntimeException("MaxHeapSize value set to " + actualheap +
+        ", expected " + expectheap + " when running with the following flags: " + Arrays.asList(args).toString());
+    }
+
+    boolean actualcoop = getFlagBoolValue("UseCompressedOops", stdout);
+    if (actualcoop != expectcoop) {
+      throw new RuntimeException("UseCompressedOops set to " + actualcoop +
+        ", expected " + expectcoop + " when running with the following flags: " + Arrays.asList(args).toString());
+    }
+  }
+
+  private static long getHeapBaseMinAddress() throws Exception {
+    ArrayList<String> args = new ArrayList<String>();
+    args.add("-XX:+PrintFlagsFinal");
+    args.add("-version");
+
+    ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(args.toArray(new String[0]));
+    OutputAnalyzer output = new OutputAnalyzer(pb.start());
+    output.shouldHaveExitValue(0);
+    String stdout = output.getStdout();
+    return (new Long(getFlagValue("HeapBaseMinAddress", stdout)).longValue());
+  }
+
+  private static String getFlagValue(String flag, String where) {
+    Matcher m = Pattern.compile(flag + "\\s+:?=\\s+\\d+").matcher(where);
+    if (!m.find()) {
+      throw new RuntimeException("Could not find value for flag " + flag + " in output string");
+    }
+    String match = m.group();
+    return match.substring(match.lastIndexOf(" ") + 1, match.length());
+  }
+
+  private static boolean getFlagBoolValue(String flag, String where) {
+    Matcher m = Pattern.compile(flag + "\\s+:?= (true|false)").matcher(where);
+    if (!m.find()) {
+      throw new RuntimeException("Could not find value for flag " + flag + " in output string");
+    }
+    return m.group(1).equals("true");
+  }
+
+  public static void main(String args[]) throws Exception {
+    // Tests
+    // 1. Verify that MaxRAMPercentage overrides UseCompressedOops Ergo
+    // 2. Verify that UseCompressedOops forces compressed oops limit even
+    //    when other flags are specified.
+
+    long oneG = 1L * 1024L * 1024L * 1024L;
+
+    // Hotspot startup logic reduces MaxHeapForCompressedOops by HeapBaseMinAddress
+    // in order to get zero based compressed oops offsets.
+    long heapbaseminaddr = getHeapBaseMinAddress();
+    long maxcoopheap = TestUseCompressedOopsErgoTools.getMaxHeapForCompressedOops(new String [0]) - heapbaseminaddr;
+
+    // Args: MaxRAM , MaxRAMPercentage, forcecoop, expect heap, expect coop
+    checkMaxRAMSize(maxcoopheap - oneG, 100, false, maxcoopheap - oneG, true);
+    checkMaxRAMSize(maxcoopheap + oneG, 100, false, maxcoopheap + oneG, false);
+    checkMaxRAMSize(maxcoopheap + oneG, 100, true, maxcoopheap, true);
+  }
+}
--- a/test/hotspot/jtreg/gc/g1/TestGCLogMessages.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/hotspot/jtreg/gc/g1/TestGCLogMessages.java	Mon Jul 01 14:57:02 2019 -0700
@@ -95,21 +95,28 @@
         new LogMessageWithLevel("Post Evacuate Collection Set", Level.INFO),
         new LogMessageWithLevel("Other", Level.INFO),
 
-        // Update RS
-        new LogMessageWithLevel("Update RS", Level.DEBUG),
+        // Merge Heap Roots
+        new LogMessageWithLevel("Merge Heap Roots", Level.INFO),
+        new LogMessageWithLevel("Remembered Sets", Level.DEBUG),
+        new LogMessageWithLevel("Merged Sparse", Level.DEBUG),
+        new LogMessageWithLevel("Merged Fine", Level.DEBUG),
+        new LogMessageWithLevel("Merged Coarse", Level.DEBUG),
+        new LogMessageWithLevel("Hot Card Cache", Level.DEBUG),
+        new LogMessageWithLevel("Log Buffers", Level.DEBUG),
         new LogMessageWithLevel("Processed Buffers", Level.DEBUG),
-        new LogMessageWithLevel("Scanned Cards", Level.DEBUG),
+        new LogMessageWithLevel("Dirty Cards", Level.DEBUG),
         new LogMessageWithLevel("Skipped Cards", Level.DEBUG),
-        new LogMessageWithLevel("Scan HCC", Level.DEBUG),
-        // Scan RS
-        new LogMessageWithLevel("Scan RS", Level.DEBUG),
+        // Scan Heap Roots
+        new LogMessageWithLevel("Scan Heap Roots", Level.DEBUG),
         new LogMessageWithLevel("Scanned Cards", Level.DEBUG),
-        new LogMessageWithLevel("Claimed Cards", Level.DEBUG),
-        new LogMessageWithLevel("Skipped Cards", Level.DEBUG),
+        new LogMessageWithLevel("Scanned Blocks", Level.DEBUG),
+        new LogMessageWithLevel("Claimed Chunks", Level.DEBUG),
+        // Code Roots Scan
+        new LogMessageWithLevel("Code Root Scan", Level.DEBUG),
         // Object Copy
         new LogMessageWithLevel("Object Copy", Level.DEBUG),
-        new LogMessageWithLevel("Scanned Cards", Level.DEBUG),
-        new LogMessageWithLevel("Claimed Cards", Level.DEBUG),
+        new LogMessageWithLevel("LAB Waste", Level.DEBUG),
+        new LogMessageWithLevel("LAB Undo Waste", Level.DEBUG),
         // Ext Root Scan
         new LogMessageWithLevel("Thread Roots", Level.TRACE),
         new LogMessageWithLevel("Universe Roots", Level.TRACE),
@@ -133,6 +140,7 @@
         new LogMessageWithLevel("Table Fixup", Level.DEBUG),
         new LogMessageWithLevel("Expand Heap After Collection", Level.DEBUG),
         new LogMessageWithLevel("Region Register", Level.DEBUG),
+        new LogMessageWithLevel("Prepare Heap Roots", Level.DEBUG),
         // Free CSet
         new LogMessageWithLevel("Free Collection Set", Level.DEBUG),
         new LogMessageWithLevel("Free Collection Set Serial", Level.TRACE),
--- a/test/hotspot/jtreg/gc/shenandoah/TestEvilSyncBug.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/TestEvilSyncBug.java	Mon Jul 01 14:57:02 2019 -0700
@@ -61,7 +61,6 @@
                             "-XX:+UnlockDiagnosticVMOptions",
                             "-XX:+UseShenandoahGC",
                             "-XX:ShenandoahGCHeuristics=aggressive",
-                            "-XX:+ShenandoahStoreCheck",
                             "TestEvilSyncBug", "test");
                     OutputAnalyzer output = new OutputAnalyzer(pb.start());
                     output.shouldHaveExitValue(0);
--- a/test/hotspot/jtreg/gc/shenandoah/TestVerifyJCStress.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/TestVerifyJCStress.java	Mon Jul 01 14:57:02 2019 -0700
@@ -30,31 +30,31 @@
  *          java.management
  * @run main/othervm  -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions
  *                    -XX:+UseShenandoahGC -Xmx1g -Xms1g
- *                    -XX:+ShenandoahStoreCheck -XX:+ShenandoahVerify -XX:+VerifyObjectEquals
+ *                    -XX:+ShenandoahVerify -XX:+VerifyObjectEquals
  *                    -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC
  *                    TestVerifyJCStress
  *
  * @run main/othervm  -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions
  *                    -XX:+UseShenandoahGC -Xmx1g -Xms1g
- *                    -XX:+ShenandoahStoreCheck -XX:+ShenandoahVerify -XX:+VerifyObjectEquals
+ *                    -XX:+ShenandoahVerify -XX:+VerifyObjectEquals
  *                    -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC
  *                    TestVerifyJCStress
  *
  * @run main/othervm  -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions
  *                    -XX:+UseShenandoahGC -Xmx1g -Xms1g
- *                    -XX:+ShenandoahStoreCheck -XX:+ShenandoahVerify -XX:+VerifyObjectEquals -XX:+ShenandoahVerifyOptoBarriers
+ *                    -XX:+ShenandoahVerify -XX:+VerifyObjectEquals -XX:+ShenandoahVerifyOptoBarriers
  *                    -XX:ShenandoahGCHeuristics=adaptive
  *                    TestVerifyJCStress
  *
  * @run main/othervm  -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions
  *                    -XX:+UseShenandoahGC -Xmx1g -Xms1g
- *                    -XX:+ShenandoahStoreCheck -XX:+ShenandoahVerify -XX:+VerifyObjectEquals -XX:+ShenandoahVerifyOptoBarriers
+ *                    -XX:+ShenandoahVerify -XX:+VerifyObjectEquals -XX:+ShenandoahVerifyOptoBarriers
  *                    -XX:ShenandoahGCHeuristics=static
  *                    TestVerifyJCStress
  *
  * @run main/othervm  -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions
  *                    -XX:+UseShenandoahGC -Xmx1g -Xms1g
- *                    -XX:+ShenandoahStoreCheck -XX:+ShenandoahVerify -XX:+VerifyObjectEquals -XX:+ShenandoahVerifyOptoBarriers
+ *                    -XX:+ShenandoahVerify -XX:+VerifyObjectEquals -XX:+ShenandoahVerifyOptoBarriers
  *                    -XX:ShenandoahGCHeuristics=traversal
  *                    TestVerifyJCStress
  */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/InvocationTests/invokeinterface/Checker.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package invokeinterface;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+public class Checker extends shared.Checker {
+    private Class interfaceClass;
+
+    public Checker(Class interfaceClass, Class dynamicTargetClass) {
+        super(interfaceClass, dynamicTargetClass);
+
+        if (staticTargetClass.isInterface()) {
+            this.interfaceClass = staticTargetClass;
+        } else {
+            throw new RuntimeException("Static target class should be an interface.");
+        }
+    }
+
+    public String check (Class callerClass) {
+        // Check access rights to interface for caller
+        if (!checkAccess(interfaceClass, callerClass)) {
+            return "java.lang.IllegalAccessError";
+        }
+
+        // NSME is thrown when interface doesn't declare the method
+        if (getDeclaredMethod(interfaceClass) == null) {
+            return "java.lang.NoSuchMethodError";
+        }
+
+        // 9.1.5 Access to Interface Member Names
+        // "All interface members are implicitly public. They are
+        // accessible outside the package where the interface is
+        // declared if the interface is also declared public or
+        // protected, in accordance with the rules of 6.6."
+
+        // Search for method declaration in the hierarchy
+        Class klass = dynamicTargetClass;
+
+        while (klass != Object.class) {
+            Method method = getDeclaredMethod(klass);
+
+            if (method != null) {
+                int modifiers = method.getModifiers();
+
+                // Check whether obtained method is public and isn't abstract
+                if ( Modifier.isPublic(modifiers))
+                {
+                    if (Modifier.isAbstract(modifiers)) {
+                        return "java.lang.AbstractMethodError";
+                    } else {
+                        return String.format("%s.%s"
+                            , method.getDeclaringClass().getSimpleName()
+                            , methodName
+                            );
+                    }
+                } else {
+                    // IAE is thrown when located method isn't PUBLIC
+                    // or private.  Private methods are skipped when
+                    // looking for an interface method.
+                    if (!Modifier.isPrivate(modifiers)) {
+                        return "java.lang.IllegalAccessError";
+                    }
+                }
+            }
+
+            klass = klass.getSuperclass();
+        }
+
+        // No method declaration is found
+        return "java.lang.AbstractMethodError";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/InvocationTests/invokeinterface/ClassGenerator.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package invokeinterface;
+
+import jdk.internal.org.objectweb.asm.Opcodes;
+import shared.GenericClassGenerator;
+
+/*******************************************************************/
+class ClassGenerator extends GenericClassGenerator<ClassGenerator> {
+    public ClassGenerator(String fullClassName) {
+        super(fullClassName);
+    }
+
+    public ClassGenerator(String fullClassName, String parentClassName) {
+        super(fullClassName, parentClassName);
+    }
+
+    public ClassGenerator(String fullClassName, String parentClassName, int flags) {
+        super(fullClassName, parentClassName, flags);
+    }
+
+    public ClassGenerator(String fullClassName, String parentClassName, int flags, String[] implementedInterfaces) {
+        super(fullClassName, parentClassName, flags, implementedInterfaces);
+    }
+
+    // Add target method call site into current class
+    public ClassGenerator addCaller(String targetClass) {
+        return super.addCaller(targetClass, Opcodes.INVOKEINTERFACE);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/InvocationTests/invokeinterface/Generator.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,279 @@
+/*
+ * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ * INVOKE_INTERFACE EXPECTED RESULTS
+ *
+ * Let C be the class of objectref. The actual method to be invoked is selected
+ * by the following lookup procedure:
+ *     - If C contains a declaration for an instance method with the same name
+ *     and descriptor as the resolved method, then this is the method to be
+ *     invoked, and the lookup procedure terminates.
+ *
+ *     - Otherwise, if C has a superclass, this same lookup procedure is
+ *     performed recursively using the direct superclass of C; the method to be
+ *     invoked is the result of the recursive invocation of this lookup
+ *     procedure.
+ *
+ * Otherwise, if the class of objectref does not implement the resolved
+ * interface, invokeinterface throws an IncompatibleClassChangeError?.
+ *
+ * Otherwise, if no method matching the resolved name and descriptor is
+ * selected, invokeinterface throws an AbstractMethodError?.
+ *
+ * Otherwise, if the selected method is not public, invokeinterface throws an
+ * IllegalAccessError. Note that it cannot be private because private methods
+ * are ignored when searching for an interface method.
+ *
+ * My translation:
+ *      1. Resolve compile-time class/method.
+ *      2. Look up runtime class C, if it contains a name/signature match,
+ *      and it is not private, invoke it.
+ *      3. If it does not, recursively lookup direct superclass of C.
+ *      4. If selected method is not public, throw IllegalAccessError
+ *
+ * InvokeInterface Results:
+ *    - A interface class, declares A.m
+ *    - A compile-time resolved class
+ *    - C runtime resolved class
+ *    - InvokeInterface will ALWAYS invoke C.m if C.m exists and is not private,
+ *    regardless of overriding or accessibility
+ *    - InvokeInterface will invoke a non-private B.m if C.m does not exist,
+ *    regardless of overriding or accessibility
+ *
+ * Note: assuming Interface is public
+ *
+ * TODO: member interfaces can be protected and private and have special hiding
+ * rules (JLS 8.5)
+ */
+
+package invokeinterface;
+
+import static jdk.internal.org.objectweb.asm.Opcodes.*;
+import shared.AbstractGenerator;
+import shared.AccessType;
+import shared.Utils;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class Generator extends AbstractGenerator {
+    public Generator(String[] args) {
+        super(args);
+    }
+
+    protected Checker getChecker(Class paramClass, Class targetClass) {
+        return new Checker(paramClass, targetClass);
+    }
+
+    public static void main (String[] args) throws Exception {
+        new Generator(args).run();
+    }
+
+    private void run() throws Exception {
+        // Specify package names
+        String pkg1 = "a.";
+        String pkg2 = "b.";
+        String pkg3 = "c.";
+        String pkgIntf = "i.";
+        String[] packages = new String[] { "", pkg1, pkg2, pkg3, pkgIntf };
+
+        int testNum = 0;
+        boolean isPassed = true;
+
+        // Hierarchy
+        // The following triples will be used during further
+        // hierarchy construction and will specify packages for A, B and C
+        String[][] packageSets = new String[][] {
+              {   "",   "",   "", ""}
+            , {   "",   "",   "", pkgIntf }
+
+            , {   "", pkg1, pkg1, "" }
+            , {   "", pkg1, pkg1, pkg1 }
+            , {   "", pkg1, pkg1, pkgIntf }
+
+            , {   "", pkg1, pkg2, "" }
+            , {   "", pkg1, pkg2, pkg1}
+            , {   "", pkg1, pkg2, pkg2}
+            , {   "", pkg1, pkg2, pkgIntf}
+
+            , { pkg1, pkg1, pkg1, pkg1 }
+            , { pkg1, pkg1, pkg1, pkgIntf }
+
+            , { pkg1, pkg1, pkg2, pkg1 }
+            , { pkg1, pkg1, pkg2, pkg2 }
+            , { pkg1, pkg1, pkg2, pkgIntf }
+
+            , { pkg1, pkg2, pkg1, pkg1 }
+            , { pkg1, pkg2, pkg1, pkg2 }
+            , { pkg1, pkg2, pkg1, pkgIntf }
+
+            , { pkg1, pkg2, pkg2, pkg1 }
+            , { pkg1, pkg2, pkg2, pkg2 }
+            , { pkg1, pkg2, pkg2, pkgIntf }
+        };
+
+        String [] header = new String[] {
+            String.format("%30s %68s %25s", "Method access modifiers", "Call site location", "Status")
+                , String.format("%5s  %-12s %-12s %-12s %-12s   %7s %7s %7s %7s %7s %7s %7s"
+                        , "  # "
+                        , "A.m()"
+                        , "B.m()"
+                        , "C.m()"
+                        , "I.m()"
+                        , "  C  "
+                        , "pkgC "
+                        , "  B  "
+                        , " pkgB"
+                        , "  A  "
+                        , "pkgA"
+                        , "Intf"
+                        )
+                , "--------------------------------------------------------------------------------------------------------------------"
+        };
+
+        for (String aHeader : header) {
+            System.out.println(aHeader);
+        }
+
+        for (String[] pkgSet : packageSets) {
+            String packageA = pkgSet[0];
+            String packageB = pkgSet[1];
+            String packageC = pkgSet[2];
+
+            String packageIntf = pkgSet[3];
+
+            String classNameA = packageA + "A";
+            String classNameB = packageB + "B";
+            String classNameC = packageC + "C";
+            String classNameIntf = packageIntf + "I";
+
+            // For all possible access modifier combinations
+            for (AccessType accessA : AccessType.values()) {
+                for (AccessType accessB : AccessType.values()) {
+                    for (AccessType accessC : AccessType.values()) {
+                        for (AccessType accessIntf : AccessType.values()) {
+
+                            if (accessIntf == AccessType.UNDEF) {
+                                continue;
+                            }
+
+                            for (int I = 0; I < 4; I++) {
+                                boolean isAbstractA = ((I & 1) != 0);
+                                boolean isAbstractB = ((I & 2) != 0);
+
+                                testNum++;
+
+                                Map<String, byte[]> classes = new HashMap<String, byte[]>();
+
+                                // TODO: add non-PUBLIC interfaces, then particular call sites will affect the results
+
+                                // Generate interface Intf
+                                classes.put(
+                                        classNameIntf
+                                        , new ClassGenerator( classNameIntf
+                                                            , "java.lang.Object"
+                                                            , ACC_ABSTRACT | ACC_INTERFACE | accessIntf.value())
+                                            .addTargetMethod(AccessType.PUBLIC)
+                                            .getClassFile()
+                                        );
+
+                                // Generate class A
+                                classes.put(
+                                        classNameA
+                                        , new ClassGenerator( classNameA
+                                                            , "java.lang.Object"
+                                                            , ACC_PUBLIC | ( isAbstractA ? ACC_ABSTRACT : 0))
+                                            .addTargetMethod(accessA)
+                                            .addCaller(classNameIntf)
+                                            .getClassFile()
+                                        );
+
+                                // Generate class B
+                                classes.put(
+                                        classNameB
+                                        , new ClassGenerator( classNameB
+                                                            , classNameA
+                                                            , ACC_PUBLIC | ( isAbstractB ? ACC_ABSTRACT : 0)
+                                                            , new String[] { Utils.getInternalName(classNameIntf) })
+                                            .addTargetMethod(accessB)
+                                            .addCaller(classNameIntf)
+                                            .getClassFile()
+                                        );
+
+                                // Generate class C
+                                classes.put( classNameC
+                                           , new ClassGenerator( classNameC, classNameB )
+                                               .addTargetMethod(accessC)
+                                               .addCaller(classNameIntf)
+                                               .getClassFile()
+                                           );
+
+                                // Generate package callers
+                                for (String pkg : packages) {
+                                    classes.put( pkg+"Caller"
+                                               , new ClassGenerator(pkg+"Caller")
+                                                   .addCaller(classNameIntf)
+                                                   .getClassFile()
+                                               );
+                                }
+
+                                String caseDescription =
+                                        String.format("%-12s %-12s %-12s %-12s| "
+                                            , (isAbstractA ? "! " : "  ") + classNameA + " " + accessA
+                                            , (isAbstractB ? "! " : "  ") + classNameB + " " + accessB
+                                            , classNameC + " " + accessC
+                                            , accessIntf + " " + classNameIntf
+                                            );
+
+                                String[] callSites = new String[] {
+                                        classNameC
+                                        , packageC+"Caller"
+                                        , classNameB
+                                        , packageB+"Caller"
+                                        , classNameA
+                                        , packageA+"Caller"
+                                        , packageIntf+"Caller"
+                                };
+
+                                boolean result = exec(classes, caseDescription, classNameIntf, classNameC, callSites);
+                                isPassed = isPassed && result;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        // Print footer
+
+        for (int i = header.length-1; i >= 0; i--) {
+            System.out.println(header[i]);
+        }
+
+        if (executeTests) {
+            System.out.printf("\nEXECUTION STATUS: %s\n", (isPassed? "PASSED" : "FAILED"));
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/InvocationTests/invokeinterfaceTests.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ * @test
+ * @bug 8224137
+ * @summary Run invokeinterface invocation tests
+ * @library /test/lib
+ * @modules java.base/jdk.internal.org.objectweb.asm
+ *          java.base/jdk.internal.misc
+ * @compile shared/AbstractGenerator.java shared/AccessCheck.java shared/AccessType.java
+ *          shared/Caller.java shared/ExecutorGenerator.java shared/Utils.java
+ *          shared/ByteArrayClassLoader.java shared/Checker.java shared/GenericClassGenerator.java
+ * @compile invokeinterface/Checker.java invokeinterface/ClassGenerator.java
+ *          invokeinterface/Generator.java
+ *
+ * @run main/othervm/timeout=1800 invokeinterfaceTests
+ */
+
+import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.compiler.InMemoryJavaCompiler;
+
+public class invokeinterfaceTests {
+
+    public static void runTest(String classFileVersion, String option) throws Exception {
+        System.out.println("\ninvokeinterface invocation tests, option: " + option +
+                           ", class file version: " + classFileVersion);
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(false, "-Xmx128M", option,
+            "invokeinterface.Generator", "--classfile_version=" + classFileVersion);
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+        try {
+            output.shouldContain("EXECUTION STATUS: PASSED");
+            output.shouldHaveExitValue(0);
+        } catch (Throwable e) {
+            System.out.println(
+                "\nNote that an entry such as 'B.m/C.m' in the failure chart means that" +
+                " the test case failed because method B.m was invoked but the test " +
+                "expected method C.m to be invoked. Similarly, a result such as 'AME/C.m'" +
+                " means that an AbstractMethodError exception was thrown but the test" +
+                " case expected method C.m to be invoked.");
+            System.out.println(
+                "\nAlso note that passing --dump to invokeinterface.Generator will" +
+                " dump the generated classes (for debugging purposes).\n");
+
+            System.exit(1);
+        }
+    }
+
+    public static void main(String args[]) throws Throwable {
+        // Get current major class file version and test with it.
+        byte klassbuf[] = InMemoryJavaCompiler.compile("blah", "public class blah { }");
+        int major_version = klassbuf[6] << 8 | klassbuf[7];
+        runTest(String.valueOf(major_version), "-Xint");
+        runTest(String.valueOf(major_version), "-Xcomp");
+
+        // Test old class file version.
+        runTest("51", "-Xint"); // JDK-7
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/InvocationTests/invokespecial/Checker.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package invokespecial;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+public class Checker extends shared.Checker {
+
+    public Checker(Class staticTargetClass, Class dynamicTargetClass) {
+        super(staticTargetClass, dynamicTargetClass);
+    }
+
+    public String check (Class callerClass) {
+        /*
+         * If objectref is null, the invokespecial instruction throws a NullPointerException.
+         */
+        if (dynamicTargetClass == null) {
+            return "java.lang.NullPointerException";
+        }
+
+        /*
+         * TODO: find a citiation from spec for this case
+         */
+        Method resolvedMethod;
+        try {
+            // May throw VerifyError
+            resolvedMethod = getMethodInHierarchy(staticTargetClass);
+        } catch (Throwable e) {
+            return e.getClass().getName();
+        }
+
+        if (resolvedMethod == null) {
+            return "java.lang.NoSuchMethodError";
+        }
+
+       /*
+        * If:
+        *   - the resolved method is protected (4.7)
+        *   - it is a member of a superclass of the current class
+        *   - the method is not declared in the same run-time package (5.3) as the current class
+        * then:
+        *   the class of objectref must be either the current class or a subclass of the
+        * current class.
+        */
+
+        if (Modifier.isProtected(resolvedMethod.getModifiers())) {
+            Method methodInSuperclass = getMethodInHierarchy(resolvedMethod.getDeclaringClass().getSuperclass());
+
+            if (methodInSuperclass != null) {
+                String resolvedMethodPkg = getClassPackageName(resolvedMethod.getDeclaringClass());
+                String methodInSuperclassPkg = getClassPackageName(methodInSuperclass.getDeclaringClass());
+
+                if (!resolvedMethodPkg.equals(methodInSuperclassPkg)) {
+                    //TODO: clarify this
+//                    if (callerClass == methodInSuperclass.getDeclaringClass()) {
+//                        return "java.lang.IllegalAccessError";
+//                    }
+                }
+            }
+        }
+
+       /*
+        * The resolved method is selected for invocation unless all of
+        * the following conditions are true:
+        *     * TODO: The ACC_SUPER flag (see Table 4.1, "Class access and property
+        *       modifiers") is set for the current class.
+        *     * The class of the resolved method is a superclass of the
+        *       current class - assumed by construction procedure
+        *
+        *     * The resolved method is not an instance initialization method (3.9).
+        */
+        if (!"<init>".equals(methodName)) {
+           /*
+            * Let C be the direct superclass of the current class:
+            *    * If C contains a declaration for an instance method with the same
+            *      name and descriptor as the resolved method, then this method will be
+            *      invoked. The lookup procedure terminates.
+            *    * Otherwise, if C has a superclass, this same lookup procedure is
+            *      performed recursively using the direct superclass of C. The method to
+            *      be invoked is the result of the recursive invocation of this lookup
+            *      procedure.
+            *    * Otherwise, an AbstractMethodError is raised.
+            *      TODO: so far, sometimes NSME is thrown
+            */
+            Class klass = dynamicTargetClass.getSuperclass();
+
+            while (klass != Object.class) {
+                Method method = getDeclaredMethod(klass);
+
+                if (method != null) {
+                    /*
+                     * If the resolved method is a class (static) method, the
+                     * invokespecial instruction throws an IncompatibleClassChangeError.
+                     */
+                    if (Modifier.isStatic(method.getModifiers())) {
+                        return "java.lang.IncompatibleClassChangeError";
+                    }
+
+                    // Check access rights
+                    if ( checkAccess(method, callerClass)
+//                         && !(
+//                                 Modifier.isProtected(method.getModifiers())
+//                                 && (
+//                                     staticTargetClass.isAssignableFrom(callerClass)
+//                                     || getClassPackageName(staticTargetClass).equals(getClassPackageName(callerClass))
+//                                    )
+//
+//                            )
+                        )
+                    {
+                        return String.format("%s.%s"
+                                , method.getDeclaringClass().getSimpleName()
+                                , methodName
+                                );
+                    } else {
+                        // IAE is thrown when located method can't be accessed from the call site
+                        return "java.lang.IllegalAccessError";
+                    }
+                }
+
+                klass = klass.getSuperclass();
+            }
+
+            return "java.lang.AbstractMethodError";
+        } else {
+            // The resolved method is an instance initialization method (3.9).
+        }
+
+        // TODO: change
+        return "---";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/InvocationTests/invokespecial/ClassGenerator.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package invokespecial;
+
+import jdk.internal.org.objectweb.asm.Opcodes;
+import shared.GenericClassGenerator;
+
+/*******************************************************************/
+class ClassGenerator extends GenericClassGenerator<ClassGenerator> {
+    public ClassGenerator(String fullClassName, String parentClassName, int flags) {
+        super(fullClassName, parentClassName, flags);
+    }
+
+    // Add target method call site into current class
+    public ClassGenerator addCaller(String targetClass) {
+        return super.addCaller(targetClass, Opcodes.INVOKESPECIAL);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/InvocationTests/invokespecial/Generator.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,452 @@
+/*
+ * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ * INVOKESPECIAL EXPECTED RESULTS
+ *
+ * From JVMS 3rd edition: invokespecial instruction:
+ *
+ * Invoke instance method; special handling for superclass, private, and instance
+ * initialization method invocations
+ *
+ * The named method is resolved (5.4.3.3). Finally, if the resolved method is
+ * protected (4.7), and it is a member of a superclass of the current class, and
+ * the method is not declared in the same run-time package (5.3) as the current
+ * class, then the class of objectref must be either the current class or a
+ * subclass of the current class.
+ *
+ * Next, the resolved method is selected for invocation unless all of the
+ * following conditions are true:
+ *     * The ACC_SUPER flag (see Table 4.1, "Class access and property modifiers") is set for the current class.
+ *     * The class of the resolved method is a superclass of the current class.
+ *     * The resolved method is not an instance initialization method (3.9).
+ *
+ * If the above conditions are true, the actual method to be invoked is selected
+ * by the following lookup procedure. Let C be the direct superclass of the
+ * current class:
+ *     * If C contains a declaration for an instance method with the same name and
+ *       descriptor as the resolved method, then this method will be invoked.
+ *       The lookup procedure terminates.
+ *
+ *     * Otherwise, if C has a superclass, this same lookup procedure is performed
+ *       recursively using the direct superclass of C. The method to be invoked is
+ *       the result of the recursive invocation of this lookup procedure.
+ *
+ *     * Otherwise, an AbstractMethodError? is raised.
+ *
+ * During resolution of the symbolic reference to the method, any of the
+ * exceptions pertaining to method resolution documented in Section 5.4.3.3 can be
+ * thrown.
+ *
+ * Otherwise, if the resolved method is an instance initialization method, and the
+ * class in which it is declared is not the class symbolically referenced by the
+ * instruction, a NoSuchMethodError? is thrown.
+ *
+ * Otherwise, if the resolved method is a class (static) method, the invokespecial
+ * instruction throws an IncompatibleClassChangeError?.
+ *
+ * Otherwise, if no method matching the resolved name and descriptor is selected,
+ * invokespecial throws an AbstractMethodError?.
+ *
+ * Otherwise, if the selected method is abstract, invokespecial throws an
+ * AbstractMethodError?.
+ *
+ * RUNTIME EXCEPTIONS
+ *
+ * Otherwise, if objectref is null, the invokespecial instruction throws a NullPointerException?.
+ *
+ * Otherwise, if the selected method is native and the code that implements the
+ * method cannot be bound, invokespecial throws an UnsatisfiedLinkError?.
+ *
+ * NOTES
+ *
+ * The difference between the invokespecial and the invokevirtual instructions is
+ * that invokevirtual invokes a method based on the class of the object. The
+ * invokespecial instruction is used to invoke instance initialization methods
+ * (3.9) as well as private methods and methods of a superclass of the current
+ * class.
+ *
+ * ACC_SUPER:
+ *
+ * The setting of the ACC_SUPER flag indicates which of two alternative semantics
+ * for its invokespecial instruction the Java virtual machine is to express; the
+ * ACC_SUPER flag exists for backward compatibility for code compiled by Sun's
+ * older compilers for the Java programming language. All new implementations of
+ * the Java virtual machine should implement the semantics for invokespecial
+ * documented in this specification. All new compilers to the instruction set of
+ * the Java virtual machine should set the ACC_SUPER flag. Sun's older compilers
+ * generated ClassFile? flags with ACC_SUPER unset. Sun's older Java virtual
+ * machine implementations ignore the flag if it is set.
+ *
+ * ACC_SUPER 0x0020 Treat superclass methods specially when invoked by the
+ * invokespecial instruction.
+ *
+ * My Translation:
+ *     1. compile-time resolved class B
+ *     2. A,B,C direct superclass relationships
+ *     3. If B.m is protected
+ *          - if the caller is in B
+ *                then runtime resolved class must be in B or C
+ *          - if the caller is in C
+ *                then runtime resolved class must be in C
+ *     TODO: otherwise what is thrown? <noWikiWord>AbstractMethodError?
+ *     4. If B.m is an instance initialization method,
+ *          invoke B.m
+ *     5. If backward compatible caller does not set ACC_SUPER,
+ *          invoke B.m
+ *     6. If B is not a superclass of the caller, e.g. A is caller, or unrelated X
+ *        is the caller, invoke B.m
+ *     7. Otherwise:
+ *        If superclass of caller contains name/sig match, use it
+ *        Else, recursively through that superclass
+ *     8. If none found, throw AbstractMethodError
+ *
+ * Note: there is NO mention of overriding or accessibility in determining
+ * resolved method, except for if the compile-time type is protected.
+ *
+ * Case 1: B.m is protected
+ *         Caller in A: if runtime resolved class in A.m, AbstractMethodError
+ *         Caller in B: if runtime resolved class in A.m, AbstractMethodError
+ * Case 2: B.m is an instance initialization method
+ *         Always invoke B.m
+ * Case 3: older javac, caller does not set ACC_SUPER
+ *         Always invoke B.m
+ * Case 4: A or X (not in hierarchy) calls invokespecial on B.m, invoke B.m
+ * Case 5: Caller in B:
+ *           if A.m exists, call it, else <noWikiWord>AbstractMethodError
+ *         Caller in C:
+ *           if B.m exists, call it
+ *           if B.m does not exist, and A.m exists, call it
+ */
+
+//   TODO: classes without ACC_SUPER attribute
+//   TODO: B.m is an instance initialization method
+
+/*
+ *   invokespecial <method-spec>
+ *
+ * invokespecial is used in certain special cases to invoke a method
+ * Specifically, invokespecial is used to invoke:
+ *      - the instance initialization method, <init>
+ *      - a private method of this
+ *      - a method in a superclass of this
+ *
+ * The main use of invokespecial is to invoke an object's instance
+ * initialization method, <init>, during the construction phase for a new object.
+ * For example, when you write in Java:
+ *
+ *      new StringBuffer()
+ *
+ * code like the following is generated:
+ *      new java/lang/StringBuffer         ; create a new StringBuffer
+ *      dup                                ; make an extra reference to the new instance
+ *                                         ; now call an instance initialization method
+ *      invokespecial java/lang/StringBuffer/<init>()V
+ *                                         ; stack now contains an initialized StringBuffer.
+ *
+ * invokespecial is also used by the Java language by the 'super' keyword to
+ * access a superclass's version of a method. For example, in the class:
+ *
+ *     class Example {
+ *         // override equals
+ *         public boolean equals(Object x) {
+ *              // call Object's version of equals
+ *              return super.equals(x);
+ *         }
+ *     }
+ *
+ * the 'super.equals(x)' expression is compiled to:
+ *
+ *     aload_0  ; push 'this' onto the stack
+ *     aload_1  ; push the first argument (i.e. x) onto the stack
+ *              ; now invoke Object's equals() method.
+ *     invokespecial java/lang/Object/equals(Ljava/lang/Object;)Z
+ *
+ * Finally, invokespecial is used to invoke a private method. Remember that
+ * private methods are only visible to other methods belonging the same class as
+ * the private method.
+ *
+ * Before performing the method invocation, the class and the method identified
+ * by <method-spec> are resolved. See Chapter 9 for a description of how methods
+ * are resolved.
+ *
+ * invokespecial first looks at the descriptor given in <method-spec>, and
+ * determines how many argument words the method takes (this may be zero). It
+ * pops these arguments off the operand stack. Next it pops objectref (a
+ * reference to an object) off the operand stack. objectref must be an instance
+ * of the class named in <method-spec>, or one of its subclasses. The interpreter
+ * searches the list of methods defined by the class named in <method-spec>,
+ * looking for a method called methodname whose descriptor is descriptor. This
+ * search is not based on the runtime type of objectref, but on the compile time
+ * type given in <method-spec>.
+ *
+ * Once a method has been located, invokespecial calls the method. First, if
+ * the method is marked as synchronized, the monitor associated with objectref is
+ * entered. Next, a new stack frame structure is established on the call stack.
+ * Then the arguments for the method (which were popped off the current method's
+ * operand stack) are placed in local variables of the new stack frame structure.
+ * arg1 is stored in local variable 1, arg2 is stored in local variable 2 and so
+ * on. objectref is stored in local variable 0 (the local variable used for the
+ * special Java variable this). Finally, execution continues at the first
+ *instruction in the bytecode of the new method.
+ *
+ * Methods marked as native are handled slightly differently. For native
+ * methods, the runtime system locates the platform-specific code for the method,
+ * loading it and linking it into the JVM if necessary. Then the native method
+ * code is executed with the arguments popped from the operand stack. The exact
+ * mechanism used to invoke native methods is implementation-specific.
+ *
+ * When the method called by invokespecial returns, any single (or double) word
+ * return result is placed on the operand stack of the current method. If the
+ * invoked method was marked as synchronized, the monitor associated with
+ * objectref is exited. Execution continues at the instruction that follows
+ * invokespecial in the bytecode.
+ *
+ * Notes
+ *
+ * 1. In Java Virtual Machine implementations prior to version JDK 1.02, this
+ * instruction was called invokenonvirtual, and was less restrictive than
+ * invokespecial - it wasn't limited to invoking only superclass, private or
+ * <init> methods. The class access flag ACC_SUPER (see Chapter 4) is used to
+ * indicate which semantics are used by a class. In older class files, the
+ * ACC_SUPER flag is unset. In all new classes, the ACC_SUPER flag should be set,
+ * indicating that the restrictions enforced by invokespecial are obeyed. (In
+ * practice, all the common uses of invokenonvirtual continue to be supported
+ * by invokespecial, so this change should have little impact on JVM users).
+ *
+ */
+
+package invokespecial;
+
+import static jdk.internal.org.objectweb.asm.Opcodes.*;
+import shared.AbstractGenerator;
+import shared.AccessType;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class Generator extends AbstractGenerator {
+    public static void main (String[] args) throws Exception {
+        new Generator(args).run();
+    }
+    public Generator(String[] args) {
+        super(args);
+    }
+
+    protected Checker getChecker(Class paramClass, Class targetClass) {
+        return new Checker(paramClass, targetClass);
+    }
+
+    public void run() throws Exception {
+        // Specify package names
+        String pkg1 = "a.";
+        String pkg2 = "b.";
+        String[] packages = new String[] { "", pkg1, pkg2 };
+
+        boolean isPassed = true;
+
+        // HIERARCHIES
+        // The following triples will be used during further
+        // hierarchy construction and will specify packages for A, B and C
+        String[][] packageSets = new String[][] {
+              {   "",   "",   "" }
+            , {   "", pkg1, pkg1 }
+            , {   "", pkg1, pkg2 }
+            , { pkg1,   "", pkg1 }
+            , { pkg1,   "", pkg2 }
+            , { pkg1, pkg1,   "" }
+            , { pkg1, pkg2,   "" }
+            , { pkg1, pkg1, pkg1 }
+            , { pkg1, pkg1, pkg2 }
+            , { pkg1, pkg2, pkg1 }
+            , { pkg1, pkg2, pkg2 }
+        };
+
+        String [] header = new String[] {
+            String.format("%30s %35s", "Method access modifiers", "Call site location")
+                , String.format("%4s  %-10s %-10s %-10s   %7s %7s %7s %7s %7s %7s %7s"
+                        , "  # "
+                        , "A.m()"
+                        , "B.m()"
+                        , "C.m()"
+                        , "  A  "
+                        , "pkgA"
+                        , "  B  "
+                        , " pkgB"
+                        , "  C  "
+                        , "pkgC "
+                        , "  X  "
+                        )
+                , "-----------------------------------------------------------------------------------------------------------"
+        };
+
+        // Print header
+        for (String str : header) {
+            System.out.println(str);
+        }
+
+        // Iterate over all interesting package combinations
+        for (String[] pkgSet : packageSets) {
+            String packageA = pkgSet[0];
+            String packageB = pkgSet[1];
+            String packageC = pkgSet[2];
+
+            String classNameA = packageA + "A";
+            String classNameB = packageB + "B";
+            String classNameC = packageC + "C";
+
+            // For all possible access modifier combinations
+            for (AccessType accessFlagA : AccessType.values()) {
+                for (AccessType accessFlagB : AccessType.values()) {
+                    for (AccessType accessFlagC : AccessType.values()) {
+                        Map<String, byte[]> classes = new HashMap<String, byte[]>();
+
+                        String calleeClassName = classNameB;
+                        int classFlags = ACC_PUBLIC;
+
+                        // The following hierarhcy is created:
+                        //     c.C extends b.B extends a.A extends Object - base hierarchy
+                        //     X extends Object - external caller
+                        //     c.Caller, b.Caller, a.Caller extends Object - package callers
+
+                        // Generate result storage
+                        classes.put(
+                                "Result"
+                                , new ClassGenerator(
+                                    "Result"
+                                    , "java.lang.Object"
+                                    , ACC_PUBLIC
+                                    )
+                                .addField(
+                                    ACC_PUBLIC | ACC_STATIC
+                                    , "value"
+                                    , "java.lang.String"
+                                    )
+                                .getClassFile()
+                                );
+
+                        // Generate class A
+                        classes.put(
+                                classNameA
+                                , new ClassGenerator(
+                                    classNameA
+                                    , "java.lang.Object"
+                                    , classFlags
+                                    )
+                                .addTargetConstructor(accessFlagA)
+                                .addTargetMethod(accessFlagA)
+                                .addCaller(calleeClassName)
+                                .getClassFile()
+                                );
+
+                        // Generate class B
+                        classes.put(
+                                classNameB
+                                , new ClassGenerator(
+                                    classNameB
+                                    , classNameA
+                                    , classFlags
+                                    )
+                                .addTargetConstructor(accessFlagB)
+                                .addTargetMethod(accessFlagB)
+                                .addCaller(calleeClassName)
+                                .getClassFile()
+                                );
+
+                        // Generate class C
+                        classes.put(
+                                classNameC
+                                , new ClassGenerator(
+                                    classNameC
+                                    , classNameB
+                                    , classFlags
+                                    )
+                                .addTargetConstructor(accessFlagC)
+                                .addTargetMethod(accessFlagC)
+                                .addCaller(calleeClassName)
+                                .getClassFile()
+                                );
+
+                        // Generate class X
+                        String classNameX = "x.X";
+                        classes.put(
+                                classNameX
+                                , new ClassGenerator(
+                                    classNameX
+                                    , "java.lang.Object"
+                                    , classFlags
+                                    )
+                                .addTargetMethod(accessFlagC)
+                                .addCaller(calleeClassName)
+                                .getClassFile()
+                                );
+
+                        // Generate package callers
+                        for (String pkg : packages) {
+                            classes.put(
+                                    pkg+"Caller"
+                                    , new ClassGenerator(
+                                        pkg+"Caller"
+                                        , "java.lang.Object"
+                                        , classFlags
+                                        )
+                                    .addCaller(calleeClassName)
+                                    .getClassFile()
+                                    );
+                        }
+
+                        String[] callSites = new String[] {
+                                classNameA
+                                , packageA+"Caller"
+                                , classNameB
+                                , packageB+"Caller"
+                                , classNameC
+                                , packageC+"Caller"
+                                , classNameX
+                        };
+
+                        String caseDescription = String.format(
+                                    "%-10s %-10s %-10s| "
+                                    , classNameA + " " + accessFlagA
+                                    , classNameB + " " + accessFlagB
+                                    , classNameC + " " + accessFlagC
+                                    );
+
+                        boolean result = exec(classes, caseDescription, calleeClassName, classNameC, callSites);
+                        isPassed = isPassed && result;
+                    }
+                }
+            }
+        }
+
+        // Print footer
+        for (int i = header.length-1; i >= 0; i--) {
+            System.out.println(header[i]);
+        }
+
+        if (executeTests) {
+            System.out.printf("\nEXECUTION STATUS: %s\n", (isPassed? "PASSED" : "FAILED"));
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/InvocationTests/invokespecialTests.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ * @test
+ * @bug 8224137
+ * @summary Run invokespecial invocation tests
+ * @library /test/lib
+ * @modules java.base/jdk.internal.org.objectweb.asm
+ *          java.base/jdk.internal.misc
+ * @compile shared/AbstractGenerator.java shared/AccessCheck.java shared/AccessType.java
+ *          shared/Caller.java shared/ExecutorGenerator.java shared/Utils.java
+ *          shared/ByteArrayClassLoader.java shared/Checker.java shared/GenericClassGenerator.java
+ * @compile invokespecial/Checker.java invokespecial/ClassGenerator.java invokespecial/Generator.java
+ *
+ * @run main/othervm/timeout=1800 invokespecialTests
+ */
+
+import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.compiler.InMemoryJavaCompiler;
+
+public class invokespecialTests {
+
+    public static void runTest(String classFileVersion, String option) throws Exception {
+        System.out.println("\ninvokespecial invocation tests, option: " + option +
+                           ", class file version: " + classFileVersion);
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(false, "-Xmx128M", option,
+            "invokespecial.Generator", "--classfile_version=" + classFileVersion);
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+        try {
+            output.shouldContain("EXECUTION STATUS: PASSED");
+            output.shouldHaveExitValue(0);
+        } catch (Throwable e) {
+            System.out.println(
+                "\nNote that an entry such as 'B.m/C.m' in the failure chart means that" +
+                " the test case failed because method B.m was invoked but the test " +
+                "expected method C.m to be invoked. Similarly, a result such as 'AME/C.m'" +
+                " means that an AbstractMethodError exception was thrown but the test" +
+                " case expected method C.m to be invoked.");
+            System.out.println(
+                "\nAlso note that passing --dump to invokespecial.Generator will" +
+                " dump the generated classes (for debugging purposes).\n");
+            System.exit(1);
+        }
+    }
+
+    public static void main(String args[]) throws Throwable {
+        // Get current major class file version and test with it.
+        byte klassbuf[] = InMemoryJavaCompiler.compile("blah", "public class blah { }");
+        int major_version = klassbuf[6] << 8 | klassbuf[7];
+        runTest(String.valueOf(major_version), "-Xint");
+        runTest(String.valueOf(major_version), "-Xcomp");
+
+        // Test old class file version.
+        runTest("51", "-Xint"); // JDK-7
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/InvocationTests/invokevirtual/Checker.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package invokevirtual;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+
+public class Checker extends shared.Checker {
+    public Checker(Class staticTargetClass, Class dynamicTargetClass) {
+        super(staticTargetClass, dynamicTargetClass);
+    }
+
+    public String check (Class callerClass) {
+        Method m;
+        try {
+            // May cause java.lang.VerifyError
+            m = getOverriddenMethod();
+        } catch (Throwable e) {
+            return e.getClass().getName();
+        }
+
+        // Check method accessibility (it's a static property, according to JLS #6.6: Access Control)
+        if (m != null) {
+            Method staticTargetMethod = getDeclaredMethod(staticTargetClass);
+
+            if (checkAccess(staticTargetMethod, callerClass)) {
+                // Can't invoke abstract method
+                if ( Modifier.isAbstract(m.getModifiers())) {
+                    return "java.lang.AbstractMethodError";
+                }
+
+                return String.format("%s.%s"
+                        , m.getDeclaringClass().getSimpleName()
+                        , methodName
+                        );
+            } else {
+                // if method isn't accessible, IllegalAccessError is thrown
+                return "java.lang.IllegalAccessError";
+            }
+        } else {
+            // if method == null, NoSuchMethodError is thrown
+            return "java.lang.NoSuchMethodError";
+        }
+    }
+
+    public Method getOverriddenMethod() {
+        return getOverriddenMethod(staticTargetClass, dynamicTargetClass);
+    }
+
+    public Method getOverriddenMethod(Class staticTarget, Class dynamicTarget) {
+        // Assertion #1. C is a subclass of A
+        if (!staticTarget.isAssignableFrom(dynamicTarget)) {
+            return null;
+        }
+
+        Method staticTargetMethod = getDeclaredMethod(staticTarget);
+        Method dynamicTargetMethod = getDeclaredMethod(dynamicTarget);
+
+        if (staticTarget.equals(dynamicTarget)) {
+            return staticTargetMethod;
+        }
+
+        // TODO: ? need to find out the right behavior
+        if (staticTargetMethod == null) {
+            return null;
+        }
+
+        // Dynamic target doesn't have desired method, so check it's superclass
+        if (dynamicTargetMethod == null) {
+            return getOverriddenMethod(staticTarget, dynamicTarget.getSuperclass());
+        } else {
+            // Private method can't override anything
+            if (Modifier.isPrivate(dynamicTargetMethod.getModifiers())) {
+                return getOverriddenMethod(staticTarget, dynamicTarget.getSuperclass());
+            }
+        }
+
+        // TODO: abstract methods
+
+        //Assertion #3.a: A.m2 is PUB || PROT || (PP && PKG(A) == PKG(C))
+        int staticTargetModifiers = staticTargetMethod.getModifiers();
+        {
+            boolean isPublic = Modifier.isPublic(staticTargetModifiers);
+            boolean isProtected = Modifier.isProtected(staticTargetModifiers);
+            boolean isPrivate = Modifier.isPrivate(staticTargetModifiers) ;
+            String staticTargetPkg = getClassPackageName(staticTarget);
+            String dynamicTargetPkg = getClassPackageName(dynamicTarget);
+
+            if ( isPublic || isProtected
+                 || ( !isPublic && !isProtected && !isPrivate
+                      && staticTargetPkg.equals(dynamicTargetPkg)
+                    ))
+            {
+                return dynamicTargetMethod;
+            }
+        }
+        // OR
+        //Assertion #3.b: exists m3: C.m1 != B.m3, A.m2 != B.m3, B.m3 overrides A.m2, C.m1 overrides B.m3
+        Class ancestor = dynamicTarget.getSuperclass();
+        while (ancestor != staticTarget) {
+            Method OverriddenM2 = getOverriddenMethod(staticTarget, ancestor);
+            Method m3 = getDeclaredMethod(ancestor);
+            Method m1 = getOverriddenMethod(ancestor, dynamicTarget);
+
+            if (m1 != null && m3 != null) {
+                if (m1.equals(dynamicTargetMethod) && m3.equals(OverriddenM2)) {
+                    return dynamicTargetMethod;
+                }
+            } else {
+                if (m1 == null && dynamicTargetMethod == null
+                    && m3 == null && OverriddenM2 == null)
+                {
+                    return null;
+                }
+            }
+
+            ancestor = ancestor.getSuperclass();
+        }
+
+        return getOverriddenMethod(staticTarget, dynamicTarget.getSuperclass());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/InvocationTests/invokevirtual/ClassGenerator.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package invokevirtual;
+
+import jdk.internal.org.objectweb.asm.Opcodes;
+import shared.GenericClassGenerator;
+
+/*******************************************************************/
+class ClassGenerator extends GenericClassGenerator<ClassGenerator> {
+    public ClassGenerator(String fullClassName) {
+        super(fullClassName);
+    }
+
+    public ClassGenerator(String fullClassName, String parentClassName) {
+        super(fullClassName, parentClassName);
+    }
+
+    public ClassGenerator(String fullClassName, String parentClassName, int flags) {
+        super(fullClassName, parentClassName, flags);
+    }
+
+    // Add target method call site into current class
+    public ClassGenerator addCaller(String targetClass) {
+        return super.addCaller(targetClass, Opcodes.INVOKEVIRTUAL);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/InvocationTests/invokevirtual/Generator.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package invokevirtual;
+
+import static jdk.internal.org.objectweb.asm.Opcodes.ACC_ABSTRACT;
+import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PUBLIC;
+import shared.AbstractGenerator;
+import shared.AccessType;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class Generator extends AbstractGenerator {
+    public Generator(String[] args) {
+        super(args);
+    }
+
+    public static void main (String[] args) throws Exception {
+        new Generator(args).run();
+    }
+
+    protected Checker getChecker(Class paramClass, Class targetClass) {
+        return new Checker(paramClass, targetClass);
+    }
+
+    private void run() throws Exception {
+        // Specify package names
+        String pkg1 = "a.";
+        String pkg2 = "b.";
+        String pkg3 = "c.";
+        String[] packages = new String[] { "", pkg1, pkg2, pkg3 };
+
+        boolean isPassed = true;
+
+        // Hierarchy
+        // The following triples will be used during further
+        // hierarchy construction and will specify packages for A, B and C
+        String[][] packageSets = new String[][] {
+                {   "",   "",   "" }
+                , {   "", pkg1, pkg1 }
+                , {   "", pkg1, pkg2 }
+                , { pkg1, pkg1, pkg1 }
+                , { pkg1, pkg1, pkg2 }
+                , { pkg1, pkg2, pkg1 }
+                , { pkg1, pkg2, pkg2 }
+        };
+
+        String [] header = new String[] {
+                String.format("%30s %45s %20s", "Method access modifiers", "Call site location", "Status")
+                , String.format("%4s  %-12s %-12s %-12s   %7s %7s %7s %7s %7s %7s"
+                        , "  # "
+                        , "A.m()"
+                        , "B.m()"
+                        , "C.m()"
+                        , "  A  "
+                        , "pkgA "
+                        , "  B  "
+                        , " pkgB"
+                        , "  C  "
+                        , "pkgC "
+                        )
+                , "-------------------------------------------------------------------------------------------------"
+        };
+
+        for (String str : header) {
+            System.out.println(str);
+        }
+
+        for (String[] pkgSet : packageSets) {
+            String packageA = pkgSet[0];
+            String packageB = pkgSet[1];
+            String packageC = pkgSet[2];
+
+            String classNameA = packageA + "A";
+            String classNameB = packageB + "B";
+            String classNameC = packageC + "C";
+
+            String staticCallerParam = classNameA;
+
+            // For all possible access modifier combinations
+            for (AccessType accessA : AccessType.values()) {
+                for (AccessType accessB : AccessType.values()) {
+                    for (AccessType accessC : AccessType.values()) {
+
+                        if (accessA == AccessType.UNDEF) {
+                            continue;
+                        }
+
+                        for (int I = 0; I < 4; I++) {
+                            boolean isAbstractA = ((I & 1) != 0);
+                            boolean isAbstractB = ((I & 2) != 0);
+
+                            Map<String, byte[]> classes = new HashMap<String, byte[]>();
+
+                            // Generate class A
+                            classes.put(
+                                    classNameA
+                                    , new ClassGenerator( classNameA
+                                                        , "java.lang.Object"
+                                                        , ACC_PUBLIC | (isAbstractA ? ACC_ABSTRACT : 0))
+                                        .addTargetMethod( accessA
+                                                        , (isAbstractA ? ACC_ABSTRACT : 0))
+                                        .addCaller(staticCallerParam)
+                                        .getClassFile()
+                            );
+
+                            // Generate class B
+                            classes.put(
+                                    classNameB
+                                    , new ClassGenerator( classNameB
+                                                        , classNameA
+                                                        , ACC_PUBLIC | (isAbstractB ? ACC_ABSTRACT : 0))
+                                    .addTargetMethod( accessB
+                                                    , (isAbstractB ? ACC_ABSTRACT : 0))
+                                    .addCaller(staticCallerParam)
+                                    .getClassFile()
+                            );
+
+                            // Generate class C
+                            classes.put(
+                                    classNameC
+                                    , new ClassGenerator(classNameC, classNameB)
+                                        .addTargetMethod(accessC)
+                                        .addCaller(staticCallerParam)
+                                        .getClassFile()
+                            );
+
+                            // Generate package callers
+                            for (String pkg : packages) {
+                                classes.put(
+                                        pkg+"Caller"
+                                        , new ClassGenerator(pkg+"Caller")
+                                        .addCaller(staticCallerParam)
+                                        .getClassFile()
+                                );
+                            }
+
+                            String[] callSites = new String[] {
+                                    classNameA
+                                    , packageA+"Caller"
+                                    , classNameB
+                                    , packageB+"Caller"
+                                    , classNameC
+                                    , packageC+"Caller"
+                            };
+
+
+                            String caseDescription =
+                                    String.format("%-12s %-12s %-12s| "
+                                        , (isAbstractA ? "! " : "  ") + classNameA + " " + accessA
+                                        , (isAbstractB ? "! " : "  ") + classNameB + " " + accessB
+                                        , classNameC + " " + accessC
+                                    );
+
+                            boolean result = exec(classes, caseDescription, staticCallerParam, classNameC, callSites);
+                            isPassed = isPassed && result;
+                        }
+                    }
+                }
+            }
+        }
+
+        // Print footer
+        for (int i = header.length-1; i >= 0; i--) {
+            System.out.println(header[i]);
+        }
+
+        if (executeTests) {
+            System.out.printf("\nEXECUTION STATUS: %s\n", (isPassed? "PASSED" : "FAILED"));
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/InvocationTests/invokevirtualTests.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ * @test
+ * @bug 8224137
+ * @summary Run invokevirtual invocation tests
+ * @library /test/lib
+ * @modules java.base/jdk.internal.org.objectweb.asm
+ *          java.base/jdk.internal.misc
+ * @compile shared/AbstractGenerator.java shared/AccessCheck.java shared/AccessType.java
+ *          shared/Caller.java shared/ExecutorGenerator.java shared/Utils.java
+ *          shared/ByteArrayClassLoader.java shared/Checker.java shared/GenericClassGenerator.java
+ * @compile invokevirtual/Checker.java invokevirtual/ClassGenerator.java invokevirtual/Generator.java
+ *
+ * @run main/othervm/timeout=1800 invokevirtualTests
+ */
+
+import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.compiler.InMemoryJavaCompiler;
+
+public class invokevirtualTests {
+
+    public static void runTest(String classFileVersion, String option) throws Exception {
+        System.out.println("\ninvokevirtual invocation tests, option: " + option +
+                           ", class file version: " + classFileVersion);
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(false, "-Xmx128M", option,
+            "invokevirtual.Generator", "--classfile_version=" + classFileVersion);
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+        try {
+            output.shouldContain("EXECUTION STATUS: PASSED");
+            output.shouldHaveExitValue(0);
+        } catch (Throwable e) {
+            System.out.println(
+                "\nNote that an entry such as 'B.m/C.m' in the failure chart means that" +
+                " the test case failed because method B.m was invoked but the test " +
+                "expected method C.m to be invoked. Similarly, a result such as 'AME/C.m'" +
+                " means that an AbstractMethodError exception was thrown but the test" +
+                " case expected method C.m to be invoked.");
+            System.out.println(
+                "\nAlso note that passing --dump to invokevirtual.Generator will" +
+                " dump the generated classes (for debugging purposes).\n");
+            System.exit(1);
+        }
+    }
+
+    public static void main(String args[]) throws Throwable {
+        // Get current major class file version and test with it.
+        byte klassbuf[] = InMemoryJavaCompiler.compile("blah", "public class blah { }");
+        int major_version = klassbuf[6] << 8 | klassbuf[7];
+        runTest(String.valueOf(major_version), "-Xint");
+// Uncomment the below test once JDK-8226588 is fixed
+//      runTest(String.valueOf(major_version), "-Xcomp");
+
+        // Test old class file version.
+        runTest("51", "-Xint"); // JDK-7
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/InvocationTests/shared/AbstractGenerator.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package shared;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ *
+ */
+public abstract class AbstractGenerator {
+    protected final boolean dumpClasses;
+    protected final boolean executeTests;
+    private static int testNum = 0;
+
+    protected AbstractGenerator(String[] args) {
+        List<String> params = new ArrayList<String>(Arrays.asList(args));
+
+        if (params.contains("--help")) {
+            Utils.printHelp();
+            System.exit(0);
+        }
+
+        dumpClasses = params.contains("--dump");
+        executeTests = !params.contains("--noexecute");
+
+        params.remove("--dump");
+        params.remove("--noexecute");
+
+        Utils.init(params);
+    }
+
+    /*******************************************************************/
+    public static void writeToFile(File dir, Map<String, byte[]> classes) {
+        for (String name : classes.keySet()) {
+            try {
+                writeToFile(dir, name, classes.get(name));
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    /*******************************************************************/
+    public static void writeToFile(File dir, String fullName, byte[] classBytecode) {
+        if (!dir.isDirectory()) {
+            throw new RuntimeException("Invalid parameter: dir doesn't point to an existing directory");
+        }
+
+        File classFile =
+            new File(
+                    dir.getPath() + File.separator
+                    + fullName.replaceAll("\\.", File.separator)
+                    + ".class"
+                    );
+
+        classFile.getParentFile().mkdirs();
+
+        try {
+            FileOutputStream fos = new FileOutputStream(classFile);
+            try {
+                fos.write(classBytecode);
+            } finally {
+                fos.close();
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    protected boolean exec(Map<String, byte[]> classes, String description, String calleeClassName, String classNameC, String[] callSites) throws ClassNotFoundException {
+        boolean isPassed = true;
+
+        testNum++;
+
+        String caseDescription = String.format("%4d| %s", testNum, description);
+
+        // Create test executor for a single case
+        classes.put(
+                ExecutorGenerator.className
+                , new ExecutorGenerator(
+                        caseDescription
+                        , calleeClassName
+                        , classNameC
+                    ).generateExecutor(callSites)
+        );
+
+        // Dump generated set to disk, if needed
+        if (dumpClasses) {
+            File dir = new File("classes" + File.separator + String.format("%04d", testNum));
+            dir.mkdirs();
+            writeToFile(dir, classes);
+        }
+
+        ByteArrayClassLoader loader = new ByteArrayClassLoader(classes);
+
+        Class paramClass;
+        Class targetClass;
+        Checker checker;
+
+        try {
+            paramClass = loader.loadClass(calleeClassName);
+            targetClass = loader.loadClass(classNameC);
+
+            checker = getChecker(paramClass, targetClass);
+        } catch (Throwable e) {
+            String result = Checker.abbreviateResult(e.getClass().getName());
+
+            System.out.printf(caseDescription);
+
+            for (String site : callSites) {
+                System.out.printf(" %7s", result);
+            }
+
+            System.out.println("");
+
+            return true;
+        }
+
+        if (executeTests) {
+            // Check runtime behavior
+            Caller caller = new Caller(loader, checker, paramClass, targetClass);
+            boolean printedCaseDes = false;
+            for (String site : callSites) {
+                String callResult = caller.call(site);
+
+                if (!caller.isPassed()) {
+                    isPassed = false;
+                    if (!printedCaseDes) {
+                        System.out.printf(caseDescription);
+                        printedCaseDes = true;
+                    }
+                    System.out.printf(" %7s", callResult);
+                }
+            }
+            if (!caller.isPassed()) {
+                System.out.println(" |   FAILED");
+            }
+        } else {
+            for (String site : callSites) {
+                String result = checker.check(loader.loadClass(site));
+                System.out.printf(" %7s", Checker.abbreviateResult(result));
+            }
+        }
+
+        return isPassed;
+    }
+
+    protected abstract Checker getChecker(Class paramClass, Class targetClass);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/InvocationTests/shared/AccessCheck.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package shared;
+
+import static jdk.internal.org.objectweb.asm.Opcodes.*;
+
+/**
+ *
+ * @author vi158347
+ */
+public class AccessCheck {
+    public static boolean isAbstract(int access) {
+        return (access & ACC_ABSTRACT) != 0;
+    }
+
+    public static boolean isPublic(int access) {
+        return (access & ACC_PUBLIC) != 0;
+    }
+
+    public static boolean isProtected(int access) {
+        return (access & ACC_PROTECTED) != 0;
+    }
+
+    public static boolean isPackagePrivate(int access) {
+        return !isPublic(access) && !isProtected(access) && !isPrivate(access);
+    }
+
+    public static boolean isPrivate(int access) {
+        return (access & ACC_PRIVATE) != 0;
+    }
+
+    public static boolean isInterface(int access) {
+        return (access & ACC_INTERFACE) != 0;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/InvocationTests/shared/AccessType.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package shared;
+
+import static jdk.internal.org.objectweb.asm.Opcodes.*;
+
+public enum AccessType {
+      PUBLIC           ("PUB")   { public int value() { return ACC_PUBLIC; } }
+    , PROTECTED        ("PROT")  { public int value() { return ACC_PROTECTED; } }
+    , PACKAGE_PRIVATE  ("PP")    { public int value() { return 0; } }
+    , PRIVATE          ("PRIV")  { public int value() { return ACC_PRIVATE; } }
+    , UNDEF            ("UNDEF") { public int value() { return -1; } }
+    ;
+
+    private String name;
+
+    AccessType(String name) {
+        this.name = name;
+    }
+
+    public abstract int value();
+
+    public String toString() {
+        return name;
+    }
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/InvocationTests/shared/ByteArrayClassLoader.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package shared;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/*******************************************************************/
+// Class loader which has local class file storage in memory
+/*******************************************************************/
+
+public class ByteArrayClassLoader extends ClassLoader {
+    private Map<String, byte[]> classes;
+
+    public ByteArrayClassLoader() {
+        classes = new HashMap<String, byte[]>();
+    }
+
+    public ByteArrayClassLoader(Map<String, byte[]> classes) {
+        this.classes = classes;
+    }
+
+    public void appendClass(String name, byte[] classFile) {
+        classes.put(name, classFile);
+    }
+
+    public Class findClass (String name) throws ClassNotFoundException {
+        if (classes.containsKey(name)) {
+            byte[] classData = classes.get(name);
+            return defineClass(name, classData, 0, classData.length);
+        } else {
+            throw new ClassNotFoundException("Can't find requested class: " + name);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/InvocationTests/shared/Caller.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package shared;
+
+import java.lang.reflect.InvocationTargetException;
+
+/*******************************************************************/
+// Invoke different target method callers
+/*******************************************************************/
+
+public class Caller {
+    private ClassLoader loader;
+    private Class paramClass;
+    private Class targetClass;
+    private boolean passed = true;
+    private Checker checker;
+
+    public Caller(ClassLoader loader, Checker checker,
+                  Class paramClass, Class targetClass) {
+        this.loader = loader;
+        this.paramClass = paramClass;
+        this.targetClass = targetClass;
+        this.checker = checker;
+    }
+
+    public boolean isPassed() {
+        return passed;
+    }
+
+    public String call(String invoker) {
+        try {
+            Class clazz = loader.loadClass(invoker);
+
+            String expectedBehavior = checker.check(clazz);
+
+            String result = null;
+            Throwable exc = null;
+            try {
+                java.lang.reflect.Method m = clazz.getDeclaredMethod("call", paramClass);
+                result = (String) m.invoke(null, targetClass.newInstance());
+            } catch (InvocationTargetException e) {
+                exc = e.getCause();
+            } catch (Throwable e) {
+                exc = e;
+            }
+
+            if (result == null) {
+                if (exc != null) {
+                    result = exc.getClass().getName();
+                } else {
+                    result = "null";
+                }
+            }
+
+            if (!(result.equals(expectedBehavior) || "".equals(expectedBehavior)) ) {
+                passed = false;
+                result = String.format("%s/%s", result, expectedBehavior);
+            }
+
+            return Checker.abbreviateResult(result);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/InvocationTests/shared/Checker.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package shared;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+public abstract class Checker {
+    protected Class staticTargetClass;
+    protected Class dynamicTargetClass;
+    protected String methodName;
+
+    public abstract String check (Class callSite);
+
+    public Checker(Class staticTargetClass, Class dynamicTargetClass) {
+        if (!staticTargetClass.isAssignableFrom(dynamicTargetClass)) {
+            throw new RuntimeException("Dynamic target class should be a subclass of the static target class.");
+        }
+
+        // **********************************************
+        // NB!!! All classes are assumed to be PUBLIC !!!
+        // **********************************************
+        Class klass = dynamicTargetClass;
+        while (klass != Object.class) {
+            if (!Modifier.isPublic(klass.getModifiers())) {
+                throw new AssertionError("Class "+klass.getName()+" isn't public.");
+            }
+
+            klass = klass.getSuperclass();
+        }
+
+        this.methodName = Utils.TARGET_METHOD_NAME;
+        this.staticTargetClass = staticTargetClass;
+        this.dynamicTargetClass = dynamicTargetClass;
+    }
+
+    protected Method getMethodInHierarchy (Class klass) {
+        return getMethodInHierarchy(klass, methodName);
+    }
+
+    protected Method getMethodInHierarchy (Class klass, String name) {
+        while (klass != null) {
+            Method method = getDeclaredMethod (klass, name);
+
+            if ( method != null) {
+// TODO: why doesn't this check work in VM?
+//                int modifiers = method.getModifiers();
+//
+//                if (Modifier.isPrivate(modifiers)) {
+//                    if (klass == initialClass) {
+//                        return method;
+//                    }
+//                } else {
+//                    return method;
+//                }
+                return method;
+            }
+            klass = klass.getSuperclass();
+        }
+
+        return null;
+    }
+
+    protected Method getMethod (Class klass) {
+        return getMethod (klass, methodName);
+    }
+
+    protected Method getDeclaredMethod (Class klass) {
+        return getDeclaredMethod (klass, methodName);
+    }
+
+    static protected Method getMethod (Class klass, String name) {
+        return findMethod (klass.getMethods(), name);
+    }
+
+    static protected Method getDeclaredMethod (Class klass, String name) {
+        return findMethod (klass.getDeclaredMethods(), name);
+    }
+
+    static protected Method findMethod (Method[] methods, String name) {
+        for (Method method : methods) {
+            if (name.equals(method.getName())) {
+                return method;
+            }
+        }
+
+        return null;
+    }
+
+    static public String getClassPackageName(Class klass) {
+        String name = klass.getName();
+        return getClassPackageName(name);
+    }
+
+    static public String getClassPackageName(String name) {
+        int lastDotIndex = name.lastIndexOf('.');
+        if (lastDotIndex > -1) {
+            return name.substring(0, lastDotIndex);
+        } else {
+            return "";
+        }
+    }
+
+    public static String abbreviateResult(String result) {
+        // Abbreviate exception names
+        result = result.replaceAll("java.lang.NullPointerException", "NPE");
+        result = result.replaceAll("java.lang.IllegalAccessError", "IAE");
+        result = result.replaceAll("java.lang.IllegalAccessException", "IAExc");
+        result = result.replaceAll("java.lang.NoSuchMethodError", "NSME");
+        result = result.replaceAll("java.lang.AbstractMethodError", "AME");
+        result = result.replaceAll("java.lang.IncompatibleClassChangeError", "ICCE");
+        result = result.replaceAll("java.lang.VerifyError", "VE");
+        result = result.replaceAll("java.lang.ClassFormatError", "CFE");
+
+        return result;
+    }
+
+    // Check access possibility from particular call site
+    protected boolean checkAccess(Class klass, Class callerClass) {
+        int modifiers = klass.getModifiers();
+
+        return checkAccess(modifiers, klass, callerClass);
+    }
+
+    protected boolean checkAccess(Method m, Class callerClass) {
+        int modifiers = m.getModifiers();
+        Class declaringClass = m.getDeclaringClass();
+
+        return checkAccess(modifiers, declaringClass, callerClass);
+    }
+
+    protected boolean checkAccess(int modifiers, Class klass, Class callerClass) {
+        if ( Modifier.isPublic(modifiers) ) {
+            return true;
+        } else if ( Modifier.isProtected(modifiers) ) {
+            if (klass.isAssignableFrom(callerClass)) {
+                return true;
+            } else if (getClassPackageName(klass).equals(getClassPackageName(callerClass))) {
+                return true;
+            }
+        } else if ( Modifier.isPrivate(modifiers)) {
+            if (klass == callerClass) {
+                return true;
+            }
+        } else if (getClassPackageName(klass).equals(getClassPackageName(callerClass))) {
+            return true;
+        } else {
+            // if method isn't accessible, IllegalAccessException is thrown
+            return false;
+        }
+
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/InvocationTests/shared/ExecutorGenerator.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,259 @@
+/*
+ * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package shared;
+
+import static jdk.internal.org.objectweb.asm.ClassWriter.*;
+import jdk.internal.org.objectweb.asm.Label;
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.Opcodes;
+import jdk.internal.org.objectweb.asm.ClassWriter;
+import static jdk.internal.org.objectweb.asm.Opcodes.*;
+
+public class ExecutorGenerator {
+    public static final String className = Utils.getInternalName("Test");
+    private String caseDescription;
+    private String staticTargetName;
+    private String dynamicTargetName;
+
+    private String callerSignature;
+
+    public ExecutorGenerator(String caseDescription,
+                             String staticTargetName,
+                             String dynamicTargetName) {
+        this.caseDescription = caseDescription;
+        this.staticTargetName = Utils.getInternalName(staticTargetName);
+        this.dynamicTargetName = Utils.getInternalName(dynamicTargetName);
+        callerSignature = String.format("(L%s;)Ljava/lang/String;", this.staticTargetName);
+    }
+
+    public byte[] generateExecutor(String[] callSites) {
+        ClassWriter cw = new ClassWriter(COMPUTE_MAXS);
+
+        cw.visit(Utils.version, ACC_PUBLIC | (Utils.isACC_SUPER ? ACC_SUPER : 0), className, null, "java/lang/Object", null);
+
+        // Generate constructor
+        {
+            MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+            mv.visitCode();
+            mv.visitVarInsn(ALOAD, 0);
+            mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
+            mv.visitInsn(RETURN);
+            mv.visitEnd();
+            mv.visitMaxs(0, 0);
+        }
+
+        // public static void main(String[] args) {
+        //      new Test().run();
+        // }
+        {
+            MethodVisitor mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);
+            mv.visitCode();
+            mv.visitTypeInsn(NEW, className);
+            mv.visitInsn(DUP);
+            mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", "()V");
+            mv.visitMethodInsn(INVOKEVIRTUAL, className, "run", "()V");
+            mv.visitInsn(RETURN);
+            mv.visitEnd();
+            mv.visitMaxs(0, 0);
+        }
+
+        //    private String indent(String result) {
+        //        while (result.length() < 8) {
+        //            result = " "+result;
+        //        }
+        //        return result;
+        //    }
+        {
+            MethodVisitor mv = cw.visitMethod(ACC_PRIVATE, "indent", "(Ljava/lang/String;)Ljava/lang/String;", null, null);
+            mv.visitCode();
+            Label l0 = new Label();
+            mv.visitLabel(l0);
+            mv.visitVarInsn(ALOAD, 1);
+            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "length", "()I");
+            mv.visitIntInsn(BIPUSH, 8);
+            Label l1 = new Label();
+            mv.visitJumpInsn(IF_ICMPGE, l1);
+            mv.visitTypeInsn(NEW, "java/lang/StringBuffer");
+            mv.visitInsn(DUP);
+            mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuffer", "<init>", "()V");
+            mv.visitLdcInsn(" ");
+            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuffer", "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
+            mv.visitVarInsn(ALOAD, 1);
+            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuffer", "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
+            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;");
+            mv.visitVarInsn(ASTORE, 1);
+            mv.visitJumpInsn(GOTO, l0);
+            mv.visitLabel(l1);
+            mv.visitVarInsn(ALOAD, 1);
+            mv.visitInsn(ARETURN);
+            mv.visitEnd();
+            mv.visitMaxs(0, 0);
+        }
+
+        //private String abbr(String result) {
+        //      result = result.replaceAll("java.lang.NullPointerException", "NPE");
+        //      result = result.replaceAll("java.lang.IllegalAccessError", "IAE");
+        //      result = result.replaceAll("java.lang.IllegalAccessException", "IAExc");
+        //      result = result.replaceAll("java.lang.NoSuchMethodError", "NSME");
+        //      result = result.replaceAll("java.lang.AbstractMethodError", "AME");
+        //      result = result.replaceAll("java.lang.IncompatibleClassChangeError", "ICCE");
+        //
+        //      return result;
+        //}
+        {
+            MethodVisitor mv = cw.visitMethod(ACC_PRIVATE, "abbr", "(Ljava/lang/String;)Ljava/lang/String;", null, null);
+            mv.visitCode();
+            mv.visitVarInsn(ALOAD, 1);
+            mv.visitLdcInsn("java.lang.NullPointerException");
+            mv.visitLdcInsn("NPE");
+            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "replaceAll", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
+            mv.visitVarInsn(ASTORE, 1);
+            mv.visitVarInsn(ALOAD, 1);
+            mv.visitLdcInsn("java.lang.IllegalAccessError");
+            mv.visitLdcInsn("IAE");
+            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "replaceAll", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
+            mv.visitVarInsn(ASTORE, 1);
+            mv.visitVarInsn(ALOAD, 1);
+            mv.visitLdcInsn("java.lang.IllegalAccessException");
+            mv.visitLdcInsn("IAExc");
+            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "replaceAll", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
+            mv.visitVarInsn(ASTORE, 1);
+            mv.visitVarInsn(ALOAD, 1);
+            mv.visitLdcInsn("java.lang.NoSuchMethodError");
+            mv.visitLdcInsn("NSME");
+            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "replaceAll", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
+            mv.visitVarInsn(ASTORE, 1);
+            mv.visitVarInsn(ALOAD, 1);
+            mv.visitLdcInsn("java.lang.AbstractMethodError");
+            mv.visitLdcInsn("AME");
+            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "replaceAll", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
+            mv.visitVarInsn(ASTORE, 1);
+            mv.visitVarInsn(ALOAD, 1);
+            mv.visitLdcInsn("java.lang.IncompatibleClassChangeError");
+            mv.visitLdcInsn("ICCE");
+            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "replaceAll", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
+            mv.visitVarInsn(ASTORE, 1);
+            mv.visitVarInsn(ALOAD, 1);
+            mv.visitInsn(ARETURN);
+            mv.visitEnd();
+            mv.visitMaxs(0, 0);
+        }
+
+        // Generate execution method
+        //        public void run() {
+        //            System.out.print("2048| ! a.A PUB    ! b.B PP     a.C PROT    |");
+        //
+        //            C object = new C();
+        //
+        //            try {
+        //              System.out.print(indent(A.call(object)));
+        //            } catch (Throwable e) {
+        //              System.out.print(indent(abbr(e.getClass().getName())));
+        //            }
+        //
+        //            ...
+        //
+        //            System.out.println();
+        //        }
+        {
+            MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "run", "()V", null, null);
+            mv.visitCode();
+
+            // Generate try/catch blocks
+            Label[][] tryCatchLabels = new Label[callSites.length][3];
+            for (int I = 0; I < tryCatchLabels.length; I++) {
+                Label[] labels = tryCatchLabels[I];
+                for (int K = 0; K < labels.length; K++) {
+                    labels[K] = new Label();
+                }
+
+                mv.visitTryCatchBlock(labels[0], labels[1], labels[2], "java/lang/Throwable");
+            }
+
+            // System.out.print("2048| ! a.A PUB    ! b.B PP     a.C PROT    |");
+            mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+            mv.visitLdcInsn(caseDescription);
+            mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "print", "(Ljava/lang/String;)V");
+
+            // C object = new C();
+            mv.visitTypeInsn(NEW, dynamicTargetName);
+            mv.visitInsn(DUP);
+            mv.visitMethodInsn(INVOKESPECIAL, dynamicTargetName, "<init>", "()V");
+            mv.visitVarInsn(ASTORE, 1);
+
+//            for (String site: callSites) {
+            // System.out.print(indent(A.call(object)));
+//                mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+//                mv.visitVarInsn(ALOAD, 0);
+//                mv.visitVarInsn(ALOAD, 1);
+//                mv.visitMethodInsn(INVOKESTATIC, AbstractGenerator.getInternalName(site), "call", callerSignature);
+//                mv.visitMethodInsn(INVOKESPECIAL, className, "indent", "(Ljava/lang/String;)Ljava/lang/String;");
+//                mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "print", "(Ljava/lang/String;)V");
+//        }
+
+            Label returnLabel = new Label();
+            for (int I = 0; I < callSites.length; I++) {
+                String site = callSites[I];
+                Label[] l = tryCatchLabels[I];
+
+                Label nextBlock = (I+1 < callSites.length ? tryCatchLabels[I+1][0] : returnLabel);
+
+                mv.visitLabel(l[0]);
+                mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitVarInsn(ALOAD, 1);
+                mv.visitMethodInsn(INVOKESTATIC, Utils.getInternalName(site), "call", callerSignature);
+                mv.visitMethodInsn(INVOKESPECIAL, className, "indent", "(Ljava/lang/String;)Ljava/lang/String;");
+                mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "print", "(Ljava/lang/String;)V");
+                mv.visitLabel(l[1]);
+                mv.visitJumpInsn(GOTO, nextBlock);
+                mv.visitLabel(l[2]);
+                mv.visitVarInsn(ASTORE, 2);
+                mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitVarInsn(ALOAD, 2);
+                mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;");
+                mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getName", "()Ljava/lang/String;");
+                mv.visitMethodInsn(INVOKESPECIAL, className, "abbr", "(Ljava/lang/String;)Ljava/lang/String;");
+                mv.visitMethodInsn(INVOKESPECIAL, className, "indent", "(Ljava/lang/String;)Ljava/lang/String;");
+                mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "print", "(Ljava/lang/String;)V");
+            }
+            mv.visitLabel(returnLabel);
+
+            // System.out.println();
+            mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+            mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "()V");
+            mv.visitInsn(RETURN);
+
+            mv.visitEnd();
+            mv.visitMaxs(0, 0);
+        }
+
+        cw.visitEnd();
+
+        return cw.toByteArray();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/InvocationTests/shared/GenericClassGenerator.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package shared;
+
+import jdk.internal.org.objectweb.asm.ClassWriter;
+import static jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES;
+import static jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_MAXS;
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+import static jdk.internal.org.objectweb.asm.Opcodes.*;
+import static shared.AccessCheck.*;
+
+public class GenericClassGenerator<T extends GenericClassGenerator> {
+    private static final String targetMethodName = Utils.TARGET_METHOD_NAME;
+
+    private int flags = 0;
+    private ClassWriter writer;
+    private String fullClassName = null;
+    private String parentClassName = null;
+
+    /*******************************************************************/
+    public GenericClassGenerator(String fullClassName) {
+        this(fullClassName, "java/lang/Object");
+    }
+
+    /*******************************************************************/
+    public GenericClassGenerator(String fullClassName, String parentClassName ) {
+        this(fullClassName, parentClassName, ACC_PUBLIC);
+    }
+
+    /*******************************************************************/
+    public GenericClassGenerator(String fullClassName, String parentClassName, int flags) {
+        this(fullClassName, parentClassName, flags, new String[0]);
+    }
+
+    /*******************************************************************/
+    public GenericClassGenerator(String fullClassName, String parentClassName, int flags, String[] implementedInterfaces) {
+        writer = new ClassWriter(COMPUTE_FRAMES | COMPUTE_MAXS);
+
+        this.fullClassName = fullClassName;
+        this.flags = flags;
+
+        // Construct simple class
+        if (parentClassName != null) {
+            this.parentClassName = getInternalName(parentClassName);
+        } else {
+            this.parentClassName = "java/lang/Object";
+        }
+
+        String parent = this.parentClassName;
+        String name = getInternalName(fullClassName);
+
+        if (Utils.isACC_SUPER) {
+            flags = flags | ACC_SUPER;
+        }
+
+        writer.visit(Utils.version, flags, name, null, parent, implementedInterfaces);
+
+        // Add constructor
+        if ( !isInterface(flags) ) {
+            MethodVisitor m =
+                    writer.visitMethod(
+                            ACC_PUBLIC
+                            , "<init>"
+                            , "()V"
+                            , null
+                            , null
+                    );
+
+            m.visitCode();
+            m.visitVarInsn(ALOAD, 0);
+            m.visitMethodInsn(
+                      INVOKESPECIAL
+                    , getInternalName(parent)
+                    , "<init>"
+                    , "()V"
+            );
+            m.visitInsn(RETURN);
+            m.visitEnd();
+            m.visitMaxs(0,0);
+        }
+    }
+
+    /*******************************************************************/
+    protected static String getInternalName(String fullClassName) {
+        return fullClassName.replaceAll("\\.", "/");
+    }
+
+    /*******************************************************************/
+    public T addTargetConstructor(AccessType access) {
+        // AccessType.UNDEF means that the target method isn't defined, so do nothing
+        if (access == AccessType.UNDEF || isInterface(flags) ) {
+            return (T)this;
+        }
+
+        // Add target constructor
+        int methodAccessType = access.value();
+
+        MethodVisitor m =
+                writer.visitMethod(
+                        methodAccessType
+                        , "<init>"
+                        , "(I)V"
+                        , null
+                        , null
+                );
+
+        // Add a call to parent constructor
+        m.visitCode();
+        m.visitVarInsn(ALOAD, 0);
+        m.visitMethodInsn(
+                  INVOKESPECIAL
+                , getInternalName(parentClassName)
+                , "<init>"
+                , "()V"
+        );
+
+        // Add result reporting
+        String shortName = fullClassName.substring(fullClassName.lastIndexOf('.') + 1);
+        m.visitLdcInsn(shortName+".<init>");
+        m.visitFieldInsn(
+                  PUTSTATIC
+                , "Result"
+                , "value"
+                , "Ljava/lang/String;"
+        );
+
+        m.visitInsn(RETURN);
+        m.visitEnd();
+        m.visitMaxs(0,0);
+
+        return (T)this;
+
+    }
+
+    /*******************************************************************/
+    public T addTargetMethod(AccessType access) {
+        return addTargetMethod(access, 0);
+    }
+
+    /*******************************************************************/
+    public T addTargetMethod(AccessType access, int additionalFlags) {
+        // AccessType.UNDEF means that the target method isn't defined, so do nothing
+        if (access == AccessType.UNDEF) {
+            return (T)this;
+        }
+
+        // Add target method
+        int methodAccessType = access.value();
+        if ( isInterface(flags) || isAbstract(flags) ) {
+            methodAccessType |= ACC_ABSTRACT;
+        }
+
+        // Skip method declaration for abstract private case, which doesn't pass
+        // classfile verification stage
+        if ( isPrivate(methodAccessType) && isAbstract(methodAccessType) ) {
+            return (T)this;
+        }
+
+        MethodVisitor m =
+                writer.visitMethod(
+                        methodAccessType | additionalFlags
+                        , targetMethodName
+                        , "()Ljava/lang/String;"
+                        , null
+                        , null
+                );
+
+        // Don't generate body if the method is abstract
+        if ( (methodAccessType & ACC_ABSTRACT) == 0 ) {
+            String shortName = fullClassName.substring(fullClassName.lastIndexOf('.') + 1);
+
+            // Simply returns info about itself
+            m.visitCode();
+            m.visitLdcInsn(shortName+"."+targetMethodName);
+            m.visitInsn(ARETURN);
+            m.visitEnd();
+            m.visitMaxs(0,0);
+        }
+
+        return (T)this;
+    }
+
+    /*******************************************************************/
+    public T addField(int access, String name, String type) {
+        writer.visitField(
+                access
+                , name
+                , getInternalName(type)
+                , null
+                , null
+        )
+                .visitEnd();
+
+        return (T)this;
+    }
+
+    /*******************************************************************/
+    // Add target method call site into current class
+    public T addCaller(String targetClass, int callType) {
+        MethodVisitor m = writer.visitMethod(
+                ACC_PUBLIC | ACC_STATIC
+                , "call"
+                , String.format( "(L%s;)Ljava/lang/String;" , getInternalName(targetClass))
+                , null
+                , null
+        );
+
+        m.visitCode();
+        m.visitVarInsn(ALOAD, 0);
+        m.visitMethodInsn(
+                  callType
+                , getInternalName(targetClass)
+                , targetMethodName
+                , "()Ljava/lang/String;"
+        );
+        m.visitInsn(ARETURN);
+        m.visitEnd();
+        m.visitMaxs(0,0);
+
+        return (T)this;
+    }
+
+    /*******************************************************************/
+    public byte[] getClassFile() {
+        writer.visitEnd();
+        return writer.toByteArray();
+    }
+
+    /*******************************************************************/
+    public String getFullClassName() {
+        return fullClassName;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/InvocationTests/shared/Utils.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package shared;
+
+import java.util.List;
+
+/**
+ * Just a set of constants
+ */
+public class Utils {
+    public static final String TARGET_METHOD_NAME = "m";
+    public static int version = 50;
+
+    public static boolean isACC_SUPER = false;
+
+    public static void init(List<String> args) {
+        for (String param : args) {
+            String name = "classfile_version";
+            String pattern = "--"+name+"=";
+            if (param.startsWith(pattern)) {
+                String value = param.substring(pattern.length());
+                int majorVersion = 50;
+                int minorVersion = 0;
+
+                try {
+                    String[] versions = value.split(":");
+                    if (versions.length > 2) {
+                        throw new RuntimeException(String.format("Unknown %s value: %s", name, value));
+                    }
+
+                    try {
+                        majorVersion = Integer.parseInt(versions[0]);
+                        if (versions.length > 1) {
+                            minorVersion = Integer.parseInt(versions[1]);
+                        }
+                    } catch(Exception e) {
+                        throw new RuntimeException(String.format("Can't parse %s value: '%s'", name, value));
+                    }
+                } catch (Exception e) {
+                    System.out.println("ERROR: "+e.getMessage());
+                }
+
+                version = majorVersion + (minorVersion << 16);
+
+                System.out.printf("INFO: Class file version: major: %d; minor: %d\n", majorVersion, minorVersion);
+
+                if (majorVersion < 49 && !args.contains("--no_acc_super")) {
+                    isACC_SUPER = true;
+                    System.out.printf("INFO: Enabling ACC_SUPER flag for major: %d\nTo disable it, specify --no_acc_super option.\n", majorVersion, minorVersion);
+                }
+            } else if (param.equals("--no_acc_super")){
+                System.out.println("INFO: ACC_SUPER flag is disabled");
+                isACC_SUPER = false;
+            } else if (param.equals("--acc_super")){
+                isACC_SUPER = true;
+            } else {
+                System.out.println("ERROR: Unknown option: "+param);
+                printHelp();
+                System.exit(1);
+            }
+        }
+    }
+
+    public static void printHelp() {
+        System.out.println(
+                 "Supported parameters:\n"
+               + "\t--classfile_version=major_version[:minor_version]\n"
+               + "\t\t- specify class file version for generated classes\n"
+               + "\t--no_acc_super\n"
+               + "\t\t- don't add ACC_SUPER flag into generated classes\n"
+               + "\t--acc_super\n"
+               + "\t\t- force ACC_SUPER flag in generated classes\n"
+               + "\t--dump\n"
+               + "\t\t- dump generated classes\n"
+               + "\t--noexecute\n"
+               + "\t\t- print only expected results, don't execute tests\n"
+        );
+    }
+
+    /*******************************************************************/
+    public static String getInternalName(String s) {
+        return s.replaceAll("\\.", "/");
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/Unsafe/InternalErrorTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8191278
+ * @requires os.family != "windows"
+ * @summary Check that SIGBUS errors caused by memory accesses in Unsafe_CopyMemory()
+ * and UnsafeCopySwapMemory() get converted to java.lang.InternalError exceptions.
+ * @modules java.base/jdk.internal.misc
+ *
+ * @library /test/lib
+ * @build sun.hotspot.WhiteBox
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *      sun.hotspot.WhiteBox$WhiteBoxPermission
+ *
+ * @run main/othervm -XX:CompileCommand=exclude,*InternalErrorTest.main -XX:CompileCommand=inline,*.get -XX:CompileCommand=inline,*Unsafe.* -Xbootclasspath/a:.  -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI InternalErrorTest
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.file.Files;
+import jdk.internal.misc.Unsafe;
+import sun.hotspot.WhiteBox;
+
+// Test that illegal memory access errors in Unsafe_CopyMemory0() and
+// UnsafeCopySwapMemory() that cause SIGBUS errors result in
+// java.lang.InternalError exceptions, not JVM crashes.
+public class InternalErrorTest {
+
+    private static final Unsafe unsafe = Unsafe.getUnsafe();
+    private static final int pageSize = WhiteBox.getWhiteBox().getVMPageSize();
+    private static final String expectedErrorMsg = "fault occurred in a recent unsafe memory access";
+    private static final String failureMsg1 = "InternalError not thrown";
+    private static final String failureMsg2 = "Wrong InternalError: ";
+
+    public static void main(String[] args) throws Throwable {
+        Unsafe unsafe = Unsafe.getUnsafe();
+
+        String currentDir = System.getProperty("test.classes");
+        File file = new File(currentDir, "tmpFile.txt");
+
+        StringBuilder s = new StringBuilder();
+        for (int i = 1; i < pageSize + 1000; i++) {
+            s.append("1");
+        }
+        Files.write(file.toPath(), s.toString().getBytes());
+        FileChannel fileChannel = new RandomAccessFile(file, "r").getChannel();
+        MappedByteBuffer buffer =
+            fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fileChannel.size());
+
+        // Get address of mapped memory.
+        long mapAddr = 0;
+        try {
+            Field af = java.nio.Buffer.class.getDeclaredField("address");
+            af.setAccessible(true);
+            mapAddr = af.getLong(buffer);
+        } catch (Exception f) {
+            throw f;
+        }
+        long allocMem = unsafe.allocateMemory(4000);
+
+        for (int i = 0; i < 3; i++) {
+            test(buffer, unsafe, mapAddr, allocMem, i);
+        }
+
+        Files.write(file.toPath(), "2".getBytes());
+        buffer.position(buffer.position() + pageSize);
+        for (int i = 0; i < 3; i++) {
+            try {
+                test(buffer, unsafe, mapAddr, allocMem, i);
+                WhiteBox.getWhiteBox().forceSafepoint();
+                throw new RuntimeException(failureMsg1);
+            } catch (InternalError e) {
+                if (!e.getMessage().contains(expectedErrorMsg)) {
+                    throw new RuntimeException(failureMsg2 + e.getMessage());
+                }
+            }
+        }
+
+        Method m = InternalErrorTest.class.getMethod("test", MappedByteBuffer.class, Unsafe.class, long.class, long.class, int.class);
+        WhiteBox.getWhiteBox().enqueueMethodForCompilation(m, 3);
+
+        for (int i = 0; i < 3; i++) {
+            try {
+                test(buffer, unsafe, mapAddr, allocMem, i);
+                WhiteBox.getWhiteBox().forceSafepoint();
+                throw new RuntimeException(failureMsg1);
+            } catch (InternalError e) {
+                if (!e.getMessage().contains(expectedErrorMsg)) {
+                    throw new RuntimeException(failureMsg2 + e.getMessage());
+                }
+            }
+        }
+
+        WhiteBox.getWhiteBox().enqueueMethodForCompilation(m, 4);
+
+        for (int i = 0; i < 3; i++) {
+            try {
+                test(buffer, unsafe, mapAddr, allocMem, i);
+                WhiteBox.getWhiteBox().forceSafepoint();
+                throw new RuntimeException(failureMsg1);
+            } catch (InternalError e) {
+                if (!e.getMessage().contains(expectedErrorMsg)) {
+                    throw new RuntimeException(failureMsg2 + e.getMessage());
+                }
+            }
+        }
+
+        System.out.println("Success");
+    }
+
+    public static void test(MappedByteBuffer buffer, Unsafe unsafe, long mapAddr, long allocMem, int type) {
+        switch (type) {
+            case 0:
+                // testing Unsafe.copyMemory, trying to access a word from next page after truncation.
+                buffer.get(new byte[8]);
+                break;
+            case 1:
+                // testing Unsafe.copySwapMemory, trying to access next  page after truncation.
+                unsafe.copySwapMemory(null, mapAddr + pageSize, new byte[4000], 16, 2000, 2);
+                break;
+            case 2:
+                // testing Unsafe.copySwapMemory, trying to access next  page after truncation.
+                unsafe.copySwapMemory(null, mapAddr + pageSize, null, allocMem, 2000, 2);
+                break;
+        }
+    }
+
+}
--- a/test/hotspot/jtreg/runtime/appcds/AppCDSOptions.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/hotspot/jtreg/runtime/appcds/AppCDSOptions.java	Mon Jul 01 14:57:02 2019 -0700
@@ -28,9 +28,15 @@
 
 public class AppCDSOptions extends CDSOptions {
     public String appJar;
+    public String appJarDir;
 
     public AppCDSOptions setAppJar(String appJar) {
         this.appJar = appJar;
         return this;
     }
+
+    public AppCDSOptions setAppJarDir(String appJarDir) {
+        this.appJarDir = appJarDir;
+        return this;
+    }
 }
--- a/test/hotspot/jtreg/runtime/appcds/AppendClasspath.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/hotspot/jtreg/runtime/appcds/AppendClasspath.java	Mon Jul 01 14:57:02 2019 -0700
@@ -36,6 +36,9 @@
  */
 
 import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
 import jdk.test.lib.process.OutputAnalyzer;
 
 public class AppendClasspath {
@@ -53,9 +56,24 @@
         "HelloMore")
       .assertNormalExit();
 
+    // PASS: 2) runtime has an non-existing jar in the -cp
+    String classDir = System.getProperty("test.classes");
+    String newFile = "non-exist.jar";
+    String nonExistPath = classDir + File.separator + newFile;
+    String classPath = appJar + File.pathSeparator + nonExistPath;
+    File nonExistJar = new File(classDir, newFile);
+    if (nonExistJar.exists()) {
+        nonExistJar.delete();
+    }
+    TestCommon.run(
+        "-cp", classPath,
+        "-Xlog:class+path=trace",
+        "Hello")
+      .assertNormalExit();
+
     final String errorMessage1 = "Unable to use shared archive";
     final String errorMessage2 = "shared class paths mismatch";
-    // FAIL: 2) runtime with classpath different from the one used in dump time
+    // FAIL: 1) runtime with classpath different from the one used in dump time
     // (runtime has an extra jar file prepended to the class path)
     TestCommon.run(
         "-Xlog:cds",
@@ -63,7 +81,7 @@
         "HelloMore")
         .assertAbnormalExit(errorMessage1, errorMessage2);
 
-    // FAIL: 3) runtime with classpath part of the one used in dump time
+    // FAIL: 2) runtime with classpath part of the one used in dump time
     TestCommon.testDump(appJar + File.pathSeparator + appJar2,
                                       TestCommon.list("Hello"));
     TestCommon.run(
@@ -72,12 +90,26 @@
         "Hello")
         .assertAbnormalExit(errorMessage1, errorMessage2);
 
-    // FAIL: 4) runtime with same set of jar files in the classpath but
+    // FAIL: 3) runtime with same set of jar files in the classpath but
     // with different order
     TestCommon.run(
         "-Xlog:cds",
         "-cp", appJar2 + File.pathSeparator + appJar,
         "HelloMore")
         .assertAbnormalExit(errorMessage1, errorMessage2);
-  }
+
+    // FAIL: 4) non-existing jar during dump time but jar exists during runtime
+    TestCommon.testDump(classPath, TestCommon.list("Hello"));
+
+    Files.copy(Paths.get(classDir, "hello.jar"),
+        Paths.get(classDir, newFile),
+        StandardCopyOption.REPLACE_EXISTING);
+
+    TestCommon.run(
+        "-cp", classPath,
+        "-Xlog:class+path=trace",
+        "Hello")
+        .assertAbnormalExit(errorMessage1, errorMessage2);
+
+    }
 }
--- a/test/hotspot/jtreg/runtime/appcds/BootClassPathMismatch.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/hotspot/jtreg/runtime/appcds/BootClassPathMismatch.java	Mon Jul 01 14:57:02 2019 -0700
@@ -34,6 +34,7 @@
  * @run driver BootClassPathMismatch
  */
 
+import jdk.test.lib.Platform;
 import jdk.test.lib.cds.CDSOptions;
 import jdk.test.lib.cds.CDSTestUtils;
 import jdk.test.lib.process.OutputAnalyzer;
@@ -41,7 +42,9 @@
 import java.nio.file.Files;
 import java.nio.file.FileAlreadyExistsException;
 import java.nio.file.StandardCopyOption;
+import java.nio.file.Path;
 import java.nio.file.Paths;
+import java.nio.file.attribute.FileTime;
 
 
 public class BootClassPathMismatch {
@@ -126,6 +129,55 @@
                 "-cp", appJar, "-verbose:class",
                 "-Xbootclasspath/a:" + appJar, "Hello")
             .assertNormalExit("[class,load] Hello source: shared objects file");
+
+        // test relative path to appJar
+        String newJar = TestCommon.composeRelPath(appJar);
+        TestCommon.run(
+                "-cp", newJar, "-verbose:class",
+                "-Xbootclasspath/a:" + newJar, "Hello")
+            .assertNormalExit("[class,load] Hello source: shared objects file");
+
+        int idx = appJar.lastIndexOf(File.separator);
+        String jarName = appJar.substring(idx + 1);
+        String jarDir = appJar.substring(0, idx);
+        // relative path starting with "."
+        TestCommon.runWithRelativePath(
+            jarDir,
+            "-Xshare:on",
+            "-XX:SharedArchiveFile=" + TestCommon.getCurrentArchiveName(),
+            "-cp", "." + File.separator + jarName,
+            "-Xbootclasspath/a:" + "." + File.separator + jarName,
+            "-Xlog:class+load=trace,class+path=info",
+            "Hello")
+            .assertNormalExit(output -> {
+                output.shouldContain("Hello source: shared objects file")
+                      .shouldHaveExitValue(0);
+                });
+
+        // relative path starting with ".."
+        idx = jarDir.lastIndexOf(File.separator);
+        String jarSubDir = jarDir.substring(idx + 1);
+        TestCommon.runWithRelativePath(
+            jarDir,
+            "-Xshare:on",
+            "-XX:SharedArchiveFile=" + TestCommon.getCurrentArchiveName(),
+            "-cp", ".." + File.separator + jarSubDir + File.separator + jarName,
+            "-Xbootclasspath/a:" + ".." + File.separator + jarSubDir + File.separator + jarName,
+            "-Xlog:class+load=trace,class+path=info",
+            "Hello")
+            .assertNormalExit(output -> {
+                output.shouldContain("Hello source: shared objects file")
+                      .shouldHaveExitValue(0);
+                });
+
+        // test sym link to appJar
+        if (!Platform.isWindows()) {
+            File linkedJar = TestCommon.createSymLink(appJar);
+            TestCommon.run(
+                    "-cp", linkedJar.getPath(), "-verbose:class",
+                    "-Xbootclasspath/a:" + linkedJar.getPath(), "Hello")
+                .assertNormalExit("[class,load] Hello source: shared objects file");
+        }
     }
 
     /* Archive contains boot classes only, runtime add -Xbootclasspath/a path.
@@ -158,6 +210,12 @@
                 "-Xlog:cds",
                 "-cp", appJar, "-Xbootclasspath/a:" + appJar, "Hello")
             .assertAbnormalExit(mismatchMessage);
+
+        // test relative path to appJar
+        String newJar = TestCommon.composeRelPath(appJar);
+        TestCommon.run(
+                "-cp", newJar, "-Xbootclasspath/a:" + newJar, "Hello")
+            .assertAbnormalExit(mismatchMessage);
     }
 
     private static void copyHelloToNewDir() throws Exception {
@@ -168,13 +226,25 @@
         } catch (FileAlreadyExistsException e) { }
 
         // copy as hello.jar
+        Path dstPath = Paths.get(dstDir, "hello.jar");
         Files.copy(Paths.get(classDir, "hello.jar"),
-            Paths.get(dstDir, "hello.jar"),
+            dstPath,
             StandardCopyOption.REPLACE_EXISTING);
 
+        File helloJar = dstPath.toFile();
+        long modTime = helloJar.lastModified();
+
         // copy as hello.jar1
+        Path dstPath2 = Paths.get(dstDir, "hello.jar1");
         Files.copy(Paths.get(classDir, "hello.jar"),
-            Paths.get(dstDir, "hello.jar1"),
+            dstPath2,
             StandardCopyOption.REPLACE_EXISTING);
+
+        // On Windows, we rely on the file size, creation time, and
+        // modification time in order to differentiate between 2 files.
+        // Setting a different modification time on hello.jar1 so that this test
+        // runs more reliably on Windows.
+        modTime += 10000;
+        Files.setAttribute(dstPath2, "lastModifiedTime", FileTime.fromMillis(modTime));
     }
 }
--- a/test/hotspot/jtreg/runtime/appcds/PrintSharedArchiveAndExit.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/hotspot/jtreg/runtime/appcds/PrintSharedArchiveAndExit.java	Mon Jul 01 14:57:02 2019 -0700
@@ -105,12 +105,13 @@
         "-XX:+PrintSharedArchiveAndExit")
       .ifNoMappingFailure(output -> check(output, 1, true, lastCheckMsg, "Run time APP classpath is shorter than the one at dump time: ."));
 
-    log("Use an invalid App CP -- all the JAR paths should be checked");
+    log("Use an invalid App CP -- all the JAR paths should be checked.\n" +
+        "Non-existing jar files will be ignored.");
     String invalidCP = "non-existing-dir" + File.pathSeparator + cp;
     TestCommon.run(
         "-cp", invalidCP,
         "-XX:+PrintSharedArchiveAndExit")
-      .ifNoMappingFailure(output -> check(output, 1, true, lastCheckMsg, "APP classpath mismatch, actual: -Djava.class.path=" + invalidCP));
+      .ifNoMappingFailure(output -> check(output, 0, true, lastCheckMsg));
 
     log("Changed modification time of hello.jar -- all the JAR paths should be checked");
     (new File(appJar)).setLastModified(System.currentTimeMillis() + 2000);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/RelativePath.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ * @test
+ * @summary Test relative paths specified in the -cp.
+ * @requires vm.cds
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile test-classes/Hello.java
+ * @compile test-classes/HelloMore.java
+ * @run driver RelativePath
+ */
+
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import static java.nio.file.StandardCopyOption.COPY_ATTRIBUTES;
+import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
+import java.util.Arrays;
+import jdk.test.lib.Platform;
+
+public class RelativePath {
+
+  private static final Path USER_DIR = Paths.get(System.getProperty("user.dir"));
+
+  public static void main(String[] args) throws Exception {
+    String appJar = JarBuilder.getOrCreateHelloJar();
+    String appJar2 = JarBuilder.build("AppendClasspath_HelloMore", "HelloMore");
+
+    // dump an archive with only the jar name in the -cp
+    int idx = appJar.lastIndexOf(File.separator);
+    String jarName = appJar.substring(idx + 1);
+    String jarDir = appJar.substring(0, idx);
+    TestCommon.testDump(jarDir, jarName, TestCommon.list("Hello"));
+
+    // copy the jar file to another dir. Specify the jar file without
+    // a directory path.
+    Path srcPath = Paths.get(appJar);
+    Path destDir = Files.createTempDirectory(USER_DIR, "deploy");
+    Path destPath = destDir.resolve(jarName);
+    Files.copy(srcPath, destPath, REPLACE_EXISTING, COPY_ATTRIBUTES);
+    TestCommon.runWithRelativePath(
+        destDir.toString(),
+        "-Xshare:on",
+        "-XX:SharedArchiveFile=" + TestCommon.getCurrentArchiveName(),
+        "-cp", jarName + File.pathSeparator + appJar2,
+        "-Xlog:class+load=trace,class+path=info",
+        "HelloMore")
+        .assertNormalExit(output -> {
+                output.shouldContain("Hello source: shared objects file")
+                      .shouldHaveExitValue(0);
+            });
+
+    // Long path test
+    // Create a long directory path and copy the appJar there.
+    final int MAX_PATH = 260;
+    destDir = Paths.get(jarDir);
+    int subDirLen = MAX_PATH - jarDir.length() - 3;
+    if (subDirLen > 0) {
+        char[] chars = new char[subDirLen];
+        Arrays.fill(chars, 'x');
+        String subPath = new String(chars);
+        destDir = Paths.get(jarDir, subPath);
+    }
+    File longDir = destDir.toFile();
+    longDir.mkdir();
+    String destJar = longDir.getPath() + File.separator + jarName;
+    Files.copy(Paths.get(appJar), Paths.get(destJar), REPLACE_EXISTING);
+    // Create an archive with the appJar in the long directory path.
+    TestCommon.testDump(destJar, TestCommon.list("Hello"));
+
+    // Run with -cp containing the appJar and another jar appended.
+    TestCommon.run(
+        "-cp", destJar + File.pathSeparator + appJar2,
+        "-Xlog:class+load=trace,class+path=info",
+        "HelloMore")
+        .assertNormalExit(output -> {
+                output.shouldContain("Hello source: shared objects file")
+                      .shouldHaveExitValue(0);
+            });
+
+    // Dump an archive with a specified JAR file in -classpath
+    TestCommon.testDump(appJar, TestCommon.list("Hello"));
+
+    // compose a relative path to the hello.jar
+    String newHello = TestCommon.composeRelPath(appJar);
+
+    // create a sym link to the original hello.jar
+    File linkedHello = null;
+    if (!Platform.isWindows()) {
+        linkedHello = TestCommon.createSymLink(appJar);
+    }
+
+    // PASS:1) same appJar but referred to via a relative path
+    TestCommon.run(
+        "-cp", newHello + File.pathSeparator + appJar2,
+        "-Xlog:class+load=trace,class+path=info",
+        "HelloMore")
+      .assertNormalExit();
+
+    // PASS:2) relative path starting with "."
+    TestCommon.runWithRelativePath(
+        jarDir,
+        "-Xshare:on",
+        "-XX:SharedArchiveFile=" + TestCommon.getCurrentArchiveName(),
+        "-cp", "." + File.separator + jarName + File.pathSeparator + appJar2,
+        "-Xlog:class+load=trace,class+path=info",
+        "HelloMore")
+        .assertNormalExit(output -> {
+                output.shouldContain("Hello source: shared objects file")
+                      .shouldHaveExitValue(0);
+            });
+
+    // PASS:3) relative path starting with ".."
+    idx = jarDir.lastIndexOf(File.separator);
+    String jarSubDir = jarDir.substring(idx + 1);
+    TestCommon.runWithRelativePath(
+        jarDir,
+        "-Xshare:on",
+        "-XX:SharedArchiveFile=" + TestCommon.getCurrentArchiveName(),
+        "-cp", ".." + File.separator + jarSubDir + File.separator + jarName
+               + File.pathSeparator + appJar2,
+        "-Xlog:class+load=trace,class+path=info",
+        "HelloMore")
+        .assertNormalExit(output -> {
+                output.shouldContain("Hello source: shared objects file")
+                      .shouldHaveExitValue(0);
+            });
+
+    // PASS:4) a jar linked to the original hello.jar
+    if (!Platform.isWindows()) {
+        TestCommon.run(
+            "-cp", linkedHello.getPath() + File.pathSeparator + appJar2,
+            "HelloMore")
+          .assertNormalExit();
+    }
+
+    final String errorMessage1 = "Unable to use shared archive";
+    final String errorMessage2 = "shared class paths mismatch";
+    // FAIL: 1) runtime with classpath different from the one used in dump time
+    // (runtime has an extra jar file prepended to the class path)
+    TestCommon.run(
+        "-cp", appJar2 + File.pathSeparator + newHello,
+        "HelloMore")
+        .assertAbnormalExit(errorMessage1, errorMessage2);
+
+    }
+}
--- a/test/hotspot/jtreg/runtime/appcds/TestCommon.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/hotspot/jtreg/runtime/appcds/TestCommon.java	Mon Jul 01 14:57:02 2019 -0700
@@ -128,6 +128,10 @@
         return createArchive(appJar, classList, suffix);
     }
 
+    public static OutputAnalyzer dump(String appJarDir, String appJar, String classList[],
+                                               String... suffix) throws Exception {
+        return createArchive(appJarDir, appJar, classList, suffix);
+    }
 
     // Create AppCDS archive using most common args - convenience method
     public static OutputAnalyzer createArchive(String appJar, String classList[],
@@ -138,6 +142,15 @@
         return createArchive(opts);
     }
 
+    public static OutputAnalyzer createArchive(String appJarDir, String appJar, String classList[],
+                                               String... suffix) throws Exception {
+        AppCDSOptions opts = (new AppCDSOptions()).setAppJar(appJar);
+        opts.setAppJarDir(appJarDir);
+        opts.setClassList(classList);
+        opts.addSuffix(suffix);
+        return createArchive(opts);
+    }
+
     // Simulate -Xshare:dump with -XX:ArchiveClassesAtExit. See comments around patchJarForDynamicDump()
     private static final Class tmp = DynamicDumpHelper.class;
 
@@ -222,6 +235,9 @@
 
         String[] cmdLine = cmd.toArray(new String[cmd.size()]);
         ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, cmdLine);
+        if (opts.appJarDir != null) {
+            pb.directory(new File(opts.appJarDir));
+        }
         return executeAndLog(pb, "dump");
     }
 
@@ -360,6 +376,9 @@
 
         String[] cmdLine = cmd.toArray(new String[cmd.size()]);
         ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, cmdLine);
+        if (opts.appJarDir != null) {
+            pb.directory(new File(opts.appJarDir));
+        }
         return executeAndLog(pb, "exec");
     }
 
@@ -378,6 +397,13 @@
         return new Result(opts, runWithArchive(opts));
     }
 
+    public static Result runWithRelativePath(String jarDir, String... suffix) throws Exception {
+        AppCDSOptions opts = (new AppCDSOptions());
+        opts.setAppJarDir(jarDir);
+        opts.addSuffix(suffix);
+        return new Result(opts, runWithArchive(opts));
+    }
+
     public static OutputAnalyzer exec(String appJar, String... suffix) throws Exception {
         AppCDSOptions opts = (new AppCDSOptions()).setAppJar(appJar);
         opts.addSuffix(suffix);
@@ -443,6 +469,20 @@
         return output;
     }
 
+    public static OutputAnalyzer testDump(String appJarDir, String appJar, String classList[],
+                                          String... suffix) throws Exception {
+        OutputAnalyzer output = dump(appJarDir, appJar, classList, suffix);
+        if (DYNAMIC_DUMP) {
+            if (isUnableToMap(output)) {
+                throw new SkippedException(UnableToMapMsg);
+            }
+            output.shouldContain("Written dynamic archive");
+        } else {
+            output.shouldContain("Loading classes to share");
+        }
+        output.shouldHaveExitValue(0);
+        return output;
+    }
 
     /**
      * Simple test -- dump and execute appJar with the given classList in classlist.
@@ -590,4 +630,32 @@
             }
         }
     }
+
+    public static String composeRelPath(String appJar) {
+         int idx = appJar.lastIndexOf(File.separator);
+         String jarName = appJar.substring(idx + 1);
+         String jarDir = appJar.substring(0, idx);
+         String lastDir = jarDir.substring(jarDir.lastIndexOf(File.separator));
+         String relPath = jarDir + File.separator + ".." + File.separator + lastDir;
+         String newJar = relPath + File.separator + jarName;
+         return newJar;
+    }
+
+
+    public static File createSymLink(String appJar) throws Exception {
+         int idx = appJar.lastIndexOf(File.separator);
+         String jarName = appJar.substring(idx + 1);
+         String jarDir = appJar.substring(0, idx);
+         File origJar = new File(jarDir, jarName);
+         String linkedJarName = "linked_" + jarName;
+         File linkedJar = null;
+         if (!Platform.isWindows()) {
+             linkedJar = new File(jarDir, linkedJarName);
+             if (linkedJar.exists()) {
+                 linkedJar.delete();
+             }
+             Files.createSymbolicLink(linkedJar.toPath(), origJar.toPath());
+         }
+         return linkedJar;
+    }
 }
--- a/test/hotspot/jtreg/runtime/appcds/dynamicArchive/DynamicArchiveTestBase.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/hotspot/jtreg/runtime/appcds/dynamicArchive/DynamicArchiveTestBase.java	Mon Jul 01 14:57:02 2019 -0700
@@ -108,7 +108,7 @@
             cmdLine = TestCommon.concat(cmdLine, "-XX:SharedArchiveFile=" + baseArchiveName);
         }
         cmdLine = TestCommon.concat(cmdLine, cmdLineSuffix);
-        return execProcess("dump", cmdLine);
+        return execProcess("dump", null, cmdLine);
     }
 
     public static Result dump2_WB(String baseArchiveName, String topArchiveName, String ... cmdLineSuffix)
@@ -188,7 +188,23 @@
             "-Xshare:on",
             "-XX:SharedArchiveFile=" + archiveFiles);
         cmdLine = TestCommon.concat(cmdLine, cmdLineSuffix);
-        return execProcess("exec", cmdLine);
+        return execProcess("exec", null, cmdLine);
+    }
+
+    public static Result runWithRelativePath(String baseArchiveName, String topArchiveName,
+                              String jarDir, String ... cmdLineSuffix)
+        throws Exception {
+        if (baseArchiveName == null && topArchiveName == null) {
+            throw new RuntimeException("Both baseArchiveName and topArchiveName cannot be null at the same time.");
+        }
+        String archiveFiles = (baseArchiveName == null) ? topArchiveName :
+            (topArchiveName == null) ? baseArchiveName :
+            baseArchiveName + File.pathSeparator + topArchiveName;
+        String[] cmdLine = TestCommon.concat(
+            "-Xshare:on",
+            "-XX:SharedArchiveFile=" + archiveFiles);
+        cmdLine = TestCommon.concat(cmdLine, cmdLineSuffix);
+        return execProcess("exec", jarDir, cmdLine);
     }
 
     public static Result run2_WB(String baseArchiveName, String topArchiveName, String ... cmdLineSuffix)
@@ -221,11 +237,14 @@
    }
 
 
-    private static Result execProcess(String mode, String[] cmdLine) throws Exception {
+    private static Result execProcess(String mode, String jarDir, String[] cmdLine) throws Exception {
         if (!executedIn_run) {
             throw new Exception("Test error: dynamic archive tests must be executed via DynamicArchiveTestBase.run()");
         }
         ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, cmdLine);
+        if (jarDir != null) {
+            pb.directory(new File(jarDir));
+        }
         OutputAnalyzer output = TestCommon.executeAndLog(pb, mode);
         CDSOptions opts = new CDSOptions();
         String xShareMode = getXshareMode(cmdLine);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/dynamicArchive/RelativePath.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ * @test
+ * @summary Test relative paths specified in the -cp.
+ * @requires vm.cds
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *          jdk.jartool/sun.tools.jar
+ * @compile ../test-classes/Hello.java
+ * @compile ../test-classes/HelloMore.java
+ * @run driver RelativePath
+ */
+
+import java.io.File;
+
+public class RelativePath extends DynamicArchiveTestBase {
+
+    public static void main(String[] args) throws Exception {
+        runTest(AppendClasspath::testDefaultBase);
+    }
+
+    static void testDefaultBase() throws Exception {
+        String topArchiveName = getNewArchiveName("top");
+        doTest(topArchiveName);
+    }
+
+    private static void doTest(String topArchiveName) throws Exception {
+        String appJar = JarBuilder.getOrCreateHelloJar();
+        String appJar2 = JarBuilder.build("AppendClasspath_HelloMore", "HelloMore");
+
+        int idx = appJar.lastIndexOf(File.separator);
+        String jarName = appJar.substring(idx + 1);
+        String jarDir = appJar.substring(0, idx);
+        // relative path starting with "."
+        runWithRelativePath(null, topArchiveName, jarDir,
+            "-Xlog:class+load",
+            "-Xlog:cds+dynamic=debug,cds=debug",
+            "-cp", "." + File.separator + "hello.jar" + File.pathSeparator + appJar2,
+            "HelloMore")
+            .assertNormalExit(output -> {
+                    output.shouldContain("Hello source: shared objects file")
+                          .shouldContain("Hello World ... More")
+                          .shouldHaveExitValue(0);
+                });
+
+        // relative path starting with ".."
+        idx = jarDir.lastIndexOf(File.separator);
+        String jarSubDir = jarDir.substring(idx + 1);
+        runWithRelativePath(null, topArchiveName, jarDir,
+            "-Xlog:class+load",
+            "-Xlog:cds+dynamic=debug,cds=debug",
+            "-cp",
+            ".." + File.separator + jarSubDir + File.separator + "hello.jar" + File.pathSeparator + appJar2,
+            "HelloMore")
+            .assertNormalExit(output -> {
+                    output.shouldContain("Hello source: shared objects file")
+                          .shouldContain("Hello World ... More")
+                          .shouldHaveExitValue(0);
+                });
+
+    }
+}
--- a/test/hotspot/jtreg/runtime/appcds/sharedStrings/SysDictCrash.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/SysDictCrash.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -53,7 +53,22 @@
             "-Xshare:dump",
             "-showversion", "-Xlog:cds,cds+hashtables"));
 
-        TestCommon.checkDump(TestCommon.executeAndLog(dumpPb, "dump"));
+        boolean continueTest = true;
+        OutputAnalyzer output = TestCommon.executeAndLog(dumpPb, "dump");
+        try {
+            TestCommon.checkDump(output);
+        } catch (java.lang.RuntimeException re) {
+            if (!output.getStdout().contains("UseCompressedOops and UseCompressedClassPointers have been disabled due to")) {
+                throw re;
+            } else {
+                System.out.println("Shared archive was not created due to UseCompressedOops and UseCompressedClassPointers have been disabled.");
+                continueTest = false;
+            }
+        }
+
+        if (!continueTest) {
+            return;
+        }
 
         ProcessBuilder runPb = ProcessTools.createJavaProcessBuilder(true,
           TestCommon.concat(vmOptionsPrefix,
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/contention/TC02/tc02t001.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/contention/TC02/tc02t001.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,86 +28,7 @@
 import nsk.share.*;
 import nsk.share.jvmti.*;
 
-//    THIS TEST IS LINE NUMBER SENSITIVE
-
-public class tc02t001 extends DebugeeClass {
-
-    // run test from command line
-    public static void main(String argv[]) {
-        argv = nsk.share.jvmti.JVMTITest.commonInit(argv);
-
-        // JCK-compatible exit
-        System.exit(run(argv, System.out) + Consts.JCK_STATUS_BASE);
-    }
-
-    // run test from JCK-compatible environment
-    public static int run(String argv[], PrintStream out) {
-        return new tc02t001().runIt(argv, out);
-    }
-
-    /* =================================================================== */
-
-    // scaffold objects
-    ArgumentHandler argHandler = null;
-    Log log = null;
-    int status = Consts.TEST_PASSED;
-    static long timeout = 0;
-
-    // tested thread
-    tc02t001Thread thread = null;
-
-    // run debuggee
-    public int runIt(String argv[], PrintStream out) {
-        argHandler = new ArgumentHandler(argv);
-        log = new Log(out, argHandler);
-        timeout = argHandler.getWaitTime() * 60 * 1000;
-        log.display("Timeout = " + timeout + " msc.");
-
-        thread = new tc02t001Thread("Debuggee Thread");
-        synchronized (thread.M) {
-            thread.start();
-            thread.startingBarrier.waitFor();
-            status = checkStatus(status);
-
-            thread.waitingBarrier1.unlock();
-            try {
-                Thread.sleep(1000); // Wait for contended "synchronized (M)"
-                thread.M.wait(timeout);
-            } catch (InterruptedException e) {
-                throw new Failure(e);
-            }
-
-            thread.waitingBarrier2.unlock();
-            try {
-                Thread.sleep(1000); // Wait for contended "synchronized (M)"
-                thread.M.wait(timeout);
-            } catch (InterruptedException e) {
-                throw new Failure(e);
-            }
-
-            thread.waitingBarrier3.unlock();
-            try {
-                Thread.sleep(1000); // Wait for contended "synchronized (M)"
-                thread.M.wait(timeout);
-            } catch (InterruptedException e) {
-                throw new Failure(e);
-            }
-        }
-
-        try {
-            thread.join(timeout);
-        } catch (InterruptedException e) {
-            throw new Failure(e);
-        }
-
-        log.display("Debugee finished");
-        status = checkStatus(status);
-
-        return status;
-    }
-}
-
-/* =================================================================== */
+//    THIS CLASS IS LINE NUMBER SENSITIVE
 
 class tc02t001Thread extends Thread {
     public Wicket startingBarrier = new Wicket();
@@ -139,3 +60,97 @@
         }
     }
 }
+
+/* =================================================================== */
+
+public class tc02t001 extends DebugeeClass {
+
+    // run test from command line
+    public static void main(String argv[]) {
+        argv = nsk.share.jvmti.JVMTITest.commonInit(argv);
+
+        // JCK-compatible exit
+        System.exit(run(argv, System.out) + Consts.JCK_STATUS_BASE);
+    }
+
+    // run test from JCK-compatible environment
+    public static int run(String argv[], PrintStream out) {
+        return new tc02t001().runIt(argv, out);
+    }
+
+    /* =================================================================== */
+
+    // scaffold objects
+    ArgumentHandler argHandler = null;
+    Log log = null;
+    int status = Consts.TEST_PASSED;
+    static long timeout = 0;
+
+    private static volatile int lastEnterEventsCount;
+    private static native   int enterEventsCount();
+
+    // tested thread
+    tc02t001Thread thread = null;
+
+    static void log (String msg) { System.out.println(msg); }
+
+    private void waitForContendedEnterEvent() {
+        try {
+            for (int j = 0; j < (timeout / 20); j++) {
+                Thread.sleep(20);
+                if (enterEventsCount() > lastEnterEventsCount) {
+                    log("Got expected MonitorContendedEnter event\n");
+                    break;
+                }
+            }
+            if (enterEventsCount() == lastEnterEventsCount) {
+                String msg = "Timeout in waiting for a MonitorContendedEnter event";
+                throw new RuntimeException(msg);
+            }
+            thread.M.wait(timeout);
+        } catch (InterruptedException e) {
+            throw new Failure(e);
+        }
+    }
+
+    // run debuggee
+    public int runIt(String argv[], PrintStream out) {
+        argHandler = new ArgumentHandler(argv);
+        log = new Log(out, argHandler);
+        timeout = argHandler.getWaitTime() * 60 * 1000;
+        log.display("Timeout = " + timeout + " msc.");
+
+        thread = new tc02t001Thread("Debuggee Thread");
+        synchronized (thread.M) {
+            thread.start();
+            thread.startingBarrier.waitFor();
+            status = checkStatus(status);
+
+            lastEnterEventsCount = enterEventsCount();
+            thread.waitingBarrier1.unlock();
+            log("Waiting for MonitorEnterEvent #1");
+            waitForContendedEnterEvent();
+
+            lastEnterEventsCount = enterEventsCount();
+            thread.waitingBarrier2.unlock();
+            log("Waiting for MonitorEnterEvent #2");
+            waitForContendedEnterEvent();
+
+            lastEnterEventsCount = enterEventsCount();
+            thread.waitingBarrier3.unlock();
+            log("Waiting for MonitorEnterEvent #3");
+            waitForContendedEnterEvent();
+        }
+
+        try {
+            thread.join(timeout);
+        } catch (InterruptedException e) {
+            throw new Failure(e);
+        }
+
+        log.display("Debugee finished");
+        status = checkStatus(status);
+
+        return status;
+    }
+}
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/contention/TC02/tc02t001/tc02t001.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/contention/TC02/tc02t001/tc02t001.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -38,7 +38,7 @@
 static jthread thread = NULL;
 static jobject object_M = NULL;
 /* line numbers of "synchronized (M)" clauses in java part of the test */
-static jint lines[] = { 127, 132, 137 };
+static jint lines[] = { 48, 53, 58 };
 static volatile int enterEventsCount = 0;
 static volatile int enteredEventsCount = 0;
 
@@ -370,6 +370,11 @@
     return JNI_OK;
 }
 
+JNIEXPORT jint JNICALL
+Java_nsk_jvmti_scenarios_contention_TC02_tc02t001_enterEventsCount(JNIEnv* jni, jclass klass) {
+    return enterEventsCount;
+}
+
 /* ========================================================================== */
 
 }
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/contention/TC04/tc04t001.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/contention/TC04/tc04t001.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
 package nsk.jvmti.scenarios.contention.TC04;
 
 import java.io.PrintStream;
+import java.util.concurrent.*;
 
 import nsk.share.*;
 import nsk.share.jvmti.*;
@@ -31,6 +32,7 @@
 public class tc04t001 extends DebugeeClass {
 
     final static int THREADS_LIMIT = 2;
+    final static CountDownLatch threadsDoneSignal = new CountDownLatch(THREADS_LIMIT);
 
     // run test from command line
     public static void main(String argv[]) {
@@ -68,8 +70,8 @@
         }
 
         try {
-            for (int i = 0; i < THREADS_LIMIT; i++) {
-                threads[i].join(timeout/THREADS_LIMIT);
+            if (!threadsDoneSignal.await(timeout, TimeUnit.MILLISECONDS)) {
+                throw new RuntimeException("Threads timeout");
             }
         } catch (InterruptedException e) {
             throw new Failure(e);
@@ -84,23 +86,6 @@
                 ", expected: " + THREADS_LIMIT*tc04t001Thread.INCREMENT_LIMIT);
             status = Consts.TEST_FAILED;
         }
-
-/* DEBUG -- to check if the threads taking turns in right order
-        boolean race = false;
-        for (int i = 1; i < 2*tc04t001Thread.INCREMENT_LIMIT; i++) {
-             if (tc04t001Thread.passOrder[i] == tc04t001Thread.passOrder[i-1]) {
-                race = true;
-                System.out.println("Race condition in the test:");
-                System.out.println("passOrder[" + (i-1) + "]:"
-                    + tc04t001Thread.passOrder[i-1]);
-                System.out.println("passOrder[" + (i) + "]:"
-                    + tc04t001Thread.passOrder[i]);
-             }
-        }
-        if (race)
-            System.out.println("There was a race condition in the test.");
-*/
-
         return status;
     }
 }
@@ -115,13 +100,10 @@
     static volatile int value = 0;
 
     static Flicker flicker = new Flicker();
-/* DEBUG -- to check if the threads taking turns in right order
-    static volatile int iter = 0;
-    static volatile int passOrder[] =
-        new int[INCREMENT_LIMIT*tc04t001.THREADS_LIMIT];
-*/
 
     private int id;
+    private static volatile int lastEnterEventsCount;
+    private static native   int enterEventsCount();
 
     public tc04t001Thread(int i) {
         super("Debuggee Thread " + i);
@@ -136,19 +118,37 @@
                 wait(1);
             } catch (InterruptedException e) {}
         }
+        tc04t001.threadsDoneSignal.countDown();
     }
 
     static synchronized void increment(int i) {
-/* DEBUG -- to check if the threads taking turns in right order
-        passOrder[iter++] = i;
-*/
         flicker.unlock(i);
         int temp = value;
-        for (int j = 0; j < DELAY; j++) ;
-        try {
-            sleep(500);
-        } catch (InterruptedException e) {}
+        boolean done = false;
+
+        // Wait in a loop for a MonitorContendedEnter event.
+        // Timeout is: 20ms * DELAY.
+        for (int j = 0; j < DELAY; j++) {
+            try {
+                sleep(20);
+            } catch (InterruptedException e) {}
+
+            done = (tc04t001.threadsDoneSignal.getCount() == 1);
+            if (done) {
+                break; // This thread is the only remaining thread, no more contention
+            }
+            if (enterEventsCount() > lastEnterEventsCount) {
+                System.out.println("Thread-" + i + ": increment event: " + enterEventsCount());
+                break; // Got an expected MonitorContendedEnter event
+            }
+        }
+
+        if (!done && enterEventsCount() == lastEnterEventsCount) {
+            String msg = "Timeout in waiting for a MonitorContendedEnter event";
+            throw new RuntimeException(msg);
+        }
         value = temp + 1;
+        lastEnterEventsCount = enterEventsCount();
     }
 }
 
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/contention/TC04/tc04t001/tc04t001.cpp	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/contention/TC04/tc04t001/tc04t001.cpp	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -119,19 +119,10 @@
 
     /* check if event is for tested object */
     if (jni->IsSameObject(object_M, obj)) {
-        jvmtiMonitorUsage usageInfo;
-
         if (lockSyncLock(jvmti)) {
             enterEventsCount++;
             unlockSyncLock(jvmti);
         }
-
-        if (!NSK_JVMTI_VERIFY(jvmti->GetObjectMonitorUsage(obj, &usageInfo))) {
-            nsk_jvmti_setFailStatus();
-        } else if (usageInfo.owner != NULL) {
-            if (!NSK_JVMTI_VERIFY(jvmti->InterruptThread(usageInfo.owner)))
-                nsk_jvmti_setFailStatus();
-        }
     }
 }
 
@@ -344,6 +335,11 @@
     return JNI_OK;
 }
 
+JNIEXPORT jint JNICALL
+Java_nsk_jvmti_scenarios_contention_TC04_tc04t001Thread_enterEventsCount(JNIEnv* jni, jclass klass) {
+    return enterEventsCount;
+}
+
 /* ========================================================================== */
 
 }
--- a/test/hotspot/jtreg/vmTestbase/nsk/share/gc/gp/GarbageUtils.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/hotspot/jtreg/vmTestbase/nsk/share/gc/gp/GarbageUtils.java	Mon Jul 01 14:57:02 2019 -0700
@@ -57,10 +57,10 @@
             }
 
             /**
-                         * Returns true if the given error message matches
-                         * one of expected strings.
-                         */
-                        public boolean accept(String errorMessage) {
+             * Returns true if the given error message matches
+             * one of expected strings.
+             */
+            public boolean accept(String errorMessage) {
                 if (expectedStrings == null || expectedStrings.length == 0 || errorMessage == null) {
                     return true;
                 }
@@ -81,7 +81,6 @@
         public static final StringWriter preloadStringWriter = new StringWriter(1);
         public static final PrintWriter preloadPrintWriter = new PrintWriter(preloadStringWriter);
         public static final Throwable preloadThrowable = new Throwable("preload");
-        public static final StackTraceElement[] preloadStackTraceElement = preloadThrowable.getStackTrace();
 
         private GarbageUtils() {
         }
@@ -215,8 +214,6 @@
         public static int eatMemory(ExecutionController stresser, GarbageProducer gp, long initialFactor, long minMemoryChunk, long factor, OOM_TYPE type) {
                 int numberOfOOMEs = 0;
                 try {
-                        StringWriter sw = new StringWriter(10000);
-                        PrintWriter pw = new PrintWriter(sw);
                         byte[] someMemory = new byte[200000]; //200 Kb
                         try {
                                 Runtime runtime = Runtime.getRuntime();
@@ -243,13 +240,11 @@
                                         } catch (OutOfMemoryError e) {
                                             someMemory = null;
                                             if (type != OOM_TYPE.ANY) {
-                                                e.printStackTrace(pw);
-                                                pw.close();
-                                                if (type.accept(sw.toString())) {
+                                                if (type.accept(e.toString())) {
                                                     numberOfOOMEs++;
                                                 } else {
                                                     // Trying to catch situation when Java generates OOM different type that test trying to catch
-                                                    throw new TestBug("Test throw OOM of unexpected type." + sw.toString());
+                                                    throw new TestBug("Test throw OOM of unexpected type." + e.toString());
                                                 }
                                             } else {
                                                numberOfOOMEs++;
@@ -265,13 +260,11 @@
                         } catch (OutOfMemoryError e) {
                             someMemory = null;
                             if (type != OOM_TYPE.ANY) {
-                                e.printStackTrace(pw);
-                                pw.close();
-                                if (type.accept(sw.toString())) {
+                                if (type.accept(e.toString())) {
                                     numberOfOOMEs++;
                                 } else {
                                     // Trying to catch situation when Java generates OOM different type that test trying to catch
-                                    throw new TestBug("Test throw OOM of unexpected type." + sw.toString());
+                                    throw new TestBug("Test throw OOM of unexpected type." + e.toString());
                                 }
                             } else {
                                 numberOfOOMEs++;
--- a/test/jdk/ProblemList-graal.txt	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/ProblemList-graal.txt	Mon Jul 01 14:57:02 2019 -0700
@@ -27,48 +27,8 @@
 #
 #############################################################################
 
-java/lang/Class/getDeclaredField/ClassDeclaredFieldsTest.java           8185139   generic-all
-java/lang/Class/getDeclaredField/FieldSetAccessibleTest.java            8185139   generic-all
-java/lang/invoke/InvokeDynamicPrintArgs.java                            8185139   generic-all
-java/lang/invoke/MethodHandleConstants.java                             8185139   generic-all
-java/lang/ProcessBuilder/Basic.java#id0                                 8185139   generic-all
-java/lang/ProcessBuilder/Basic.java#id1                                 8185139   generic-all
-java/lang/ProcessBuilder/SecurityManagerClinit.java                     8185139   generic-all
-java/lang/ProcessHandle/PermissionTest.java                             8185139   generic-all
-java/lang/reflect/Proxy/nonPublicProxy/NonPublicProxyClass.java         8185139   generic-all
-java/lang/StackWalker/CallerSensitiveMethod/Main.java                   8185139   generic-all
-java/lang/StackWalker/GetCallerClassTest.java                           8185139   generic-all
-java/lang/String/concat/WithSecurityManager.java                        8185139   generic-all
-java/lang/System/Logger/custom/CustomLoggerTest.java                    8185139   generic-all
-java/lang/System/Logger/default/DefaultLoggerTest.java                  8185139   generic-all
-java/lang/System/LoggerFinder/BaseLoggerFinderTest/BaseLoggerFinderTest.java                        8185139   generic-all
-java/lang/System/LoggerFinder/DefaultLoggerFinderTest/DefaultLoggerFinderTest.java                  8185139   generic-all
-java/lang/System/LoggerFinder/internal/BaseDefaultLoggerFinderTest/BaseDefaultLoggerFinderTest.java 8185139   generic-all
-java/lang/System/LoggerFinder/internal/BaseLoggerBridgeTest/BaseLoggerBridgeTest.java               8185139   generic-all
-java/lang/System/LoggerFinder/internal/BasePlatformLoggerTest/BasePlatformLoggerTest.java           8185139   generic-all
-java/lang/System/LoggerFinder/internal/BootstrapLogger/BootstrapLoggerTest.java                     8185139   generic-all
-java/lang/System/LoggerFinder/internal/LoggerBridgeTest/LoggerBridgeTest.java                       8185139   generic-all
-java/lang/System/LoggerFinder/internal/LoggerFinderLoaderTest/LoggerFinderLoaderTest.java           8185139   generic-all
-java/lang/System/LoggerFinder/internal/PlatformLoggerBridgeTest/PlatformLoggerBridgeTest.java       8185139   generic-all
-java/lang/System/LoggerFinder/jdk/DefaultLoggerBridgeTest/DefaultLoggerBridgeTest.java              8185139   generic-all
-java/lang/System/LoggerFinder/jdk/DefaultPlatformLoggerTest/DefaultPlatformLoggerTest.java          8185139   generic-all
-java/lang/System/LoggerFinder/LoggerFinderAPI/LoggerFinderAPI.java      8185139   generic-all
-java/util/concurrent/atomic/AtomicUpdaters.java                         8185139   generic-all
-java/util/concurrent/Executors/PrivilegedCallables.java                 8185139   generic-all
-java/util/logging/FileHandlerPath.java                                  8185139   generic-all
-java/util/logging/FileHandlerPatternExceptions.java                     8185139   generic-all
-java/util/logging/Logger/setResourceBundle/TestSetResourceBundle.java   8185139   generic-all
-java/util/logging/LogManagerAppContextDeadlock.java                     8185139   generic-all
-java/util/logging/LogManager/Configuration/updateConfiguration/HandlersOnComplexResetUpdate.java    8185139   generic-all
-java/util/logging/LogManager/Configuration/updateConfiguration/HandlersOnComplexUpdate.java         8185139   generic-all
-java/util/logging/LogManager/Configuration/updateConfiguration/SimpleUpdateConfigurationTest.java   8185139   generic-all
-java/util/logging/LogManager/Configuration/updateConfiguration/SimpleUpdateConfigWithInputStreamTest.java   8185139   generic-all
-java/util/logging/LogManager/RootLogger/setLevel/TestRootLoggerLevel.java   8185139   generic-all
-java/util/logging/RootLogger/RootLevelInConfigFile.java                 8185139   generic-all
-java/util/logging/TestAppletLoggerContext.java                          8185139   generic-all
-java/util/logging/TestConfigurationListeners.java                       8185139   generic-all
-java/util/logging/LogManager/Configuration/ParentLoggerWithHandlerGC.java 8185139 generic-all
-java/util/logging/FileHandlerLongLimit.java                             8185139   generic-all
+java/lang/String/concat/WithSecurityManager.java                        8207267   generic-all
+java/lang/System/LoggerFinder/LoggerFinderAPI/LoggerFinderAPI.java      8207267   generic-all
 
 java/util/concurrent/tck/JSR166TestCase.java                            8187486   generic-all
 
--- a/test/jdk/ProblemList.txt	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/ProblemList.txt	Mon Jul 01 14:57:02 2019 -0700
@@ -871,7 +871,3 @@
 
 ############################################################################
 
-# jdk/internal/docker
-
-jdk/internal/platform/docker/TestDockerMemoryMetrics.java       8224506    generic-all
-jdk/internal/platform/docker/TestSystemMetrics.java             8224502    generic-all
--- a/test/jdk/java/lang/Class/getDeclaredField/ClassDeclaredFieldsTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/java/lang/Class/getDeclaredField/ClassDeclaredFieldsTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -166,6 +166,7 @@
     // Policy for the test...
     public static class SimplePolicy extends Policy {
 
+        static final Policy DEFAULT_POLICY = Policy.getPolicy();
         final Permissions permissions;
         final Permissions allPermissions;
         final ThreadLocal<AtomicBoolean> allowAll; // actually: this should be in a thread locale
@@ -187,7 +188,7 @@
         @Override
         public boolean implies(ProtectionDomain domain, Permission permission) {
             if (allowAll.get().get()) return allPermissions.implies(permission);
-            return permissions.implies(permission);
+            return permissions.implies(permission) || DEFAULT_POLICY.implies(domain, permission);
         }
 
         @Override
--- a/test/jdk/java/lang/Class/getDeclaredField/FieldSetAccessibleTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/java/lang/Class/getDeclaredField/FieldSetAccessibleTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -385,6 +385,8 @@
     // Policy for the test...
     public static class SimplePolicy extends Policy {
 
+        static final Policy DEFAULT_POLICY = Policy.getPolicy();
+
         final Permissions permissions;
         final Permissions allPermissions;
         final ThreadLocal<AtomicBoolean> allowAll;
@@ -420,6 +422,7 @@
                     return true;
                 }
             }
+            if (DEFAULT_POLICY.implies(domain, permission)) return true;
             return false;
         }
 
--- a/test/jdk/java/lang/ProcessBuilder/Basic.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/java/lang/ProcessBuilder/Basic.java	Mon Jul 01 14:57:02 2019 -0700
@@ -2602,6 +2602,8 @@
     // A Policy class designed to make permissions fiddling very easy.
     //----------------------------------------------------------------
     private static class Policy extends java.security.Policy {
+        static final java.security.Policy DEFAULT_POLICY = java.security.Policy.getPolicy();
+
         private Permissions perms;
 
         public void setPermissions(Permission...permissions) {
@@ -2621,7 +2623,7 @@
         }
 
         public boolean implies(ProtectionDomain pd, Permission p) {
-            return perms.implies(p);
+            return perms.implies(p) || DEFAULT_POLICY.implies(pd, p);
         }
 
         public void refresh() {}
--- a/test/jdk/java/lang/ProcessBuilder/SecurityManagerClinit.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/java/lang/ProcessBuilder/SecurityManagerClinit.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,6 @@
 /*
  * Copyright 2010 Google Inc.  All Rights Reserved.
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -35,17 +36,19 @@
 import java.security.*;
 
 public class SecurityManagerClinit {
-    private static class Policy extends java.security.Policy {
+    private static class SimplePolicy extends Policy {
+        static final Policy DEFAULT_POLICY = Policy.getPolicy();
+
         private Permissions perms;
 
-        public Policy(Permission... permissions) {
+        public SimplePolicy(Permission... permissions) {
             perms = new Permissions();
             for (Permission permission : permissions)
                 perms.add(permission);
         }
 
         public boolean implies(ProtectionDomain pd, Permission p) {
-            return perms.implies(p);
+            return perms.implies(p) || DEFAULT_POLICY.implies(pd, p);
         }
     }
 
@@ -54,8 +57,8 @@
             System.getProperty("java.home") +
             File.separator + "bin" + File.separator + "java";
 
-        final Policy policy =
-            new Policy
+        final SimplePolicy policy =
+            new SimplePolicy
             (new FilePermission("<<ALL FILES>>", "execute"),
              new RuntimePermission("setSecurityManager"));
         Policy.setPolicy(policy);
--- a/test/jdk/java/lang/ProcessHandle/PermissionTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/java/lang/ProcessHandle/PermissionTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -178,6 +178,9 @@
 }
 
 class TestPolicy extends Policy {
+
+    static final Policy DEFAULT_POLICY = Policy.getPolicy();
+
     private final PermissionCollection permissions = new Permissions();
 
     public TestPolicy() {
@@ -222,6 +225,6 @@
 
     @Override
     public boolean implies(ProtectionDomain domain, Permission perm) {
-        return permissions.implies(perm);
+        return permissions.implies(perm) || DEFAULT_POLICY.implies(domain, perm);
     }
 }
--- a/test/jdk/java/lang/System/Logger/custom/CustomLoggerTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/java/lang/System/Logger/custom/CustomLoggerTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -704,6 +704,8 @@
 
     public static class SimplePolicy extends Policy {
 
+        static final Policy DEFAULT_POLICY = Policy.getPolicy();
+
         static final RuntimePermission LOGGERFINDER_PERMISSION =
                 new RuntimePermission("loggerFinder");
         final Permissions permissions;
@@ -736,7 +738,7 @@
 
         @Override
         public boolean implies(ProtectionDomain domain, Permission permission) {
-            return permissions().implies(permission);
+            return permissions().implies(permission) || DEFAULT_POLICY.implies(domain, permission);
         }
 
         @Override
--- a/test/jdk/java/lang/System/Logger/default/DefaultLoggerTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/java/lang/System/Logger/default/DefaultLoggerTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -884,6 +884,9 @@
     }
 
     public static class SimplePolicy extends Policy {
+
+        static final Policy DEFAULT_POLICY = Policy.getPolicy();
+
         static final RuntimePermission LOGGERFINDER_PERMISSION =
                 new RuntimePermission("loggerFinder");
         final Permissions permissions;
@@ -908,7 +911,7 @@
         public boolean implies(ProtectionDomain domain, Permission permission) {
             if (allowAll.get().get()) return allPermissions.implies(permission);
             if (allowControl.get().get()) return controlPermissions.implies(permission);
-            return permissions.implies(permission);
+            return permissions.implies(permission) || DEFAULT_POLICY.implies(domain, permission);
         }
 
         @Override
--- a/test/jdk/java/lang/System/LoggerFinder/BaseLoggerFinderTest/BaseLoggerFinderTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/java/lang/System/LoggerFinder/BaseLoggerFinderTest/BaseLoggerFinderTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -652,6 +652,8 @@
         final static RuntimePermission CONTROL = LOGGERFINDER_PERMISSION;
         final static RuntimePermission ACCESS = new RuntimePermission("accessClassInPackage.jdk.internal.logger");
 
+        static final Policy DEFAULT_POLICY = Policy.getPolicy();
+
         final Permissions permissions;
         final ThreadLocal<AtomicBoolean> allowControl;
         final ThreadLocal<AtomicBoolean> allowAccess;
@@ -678,7 +680,7 @@
 
         @Override
         public boolean implies(ProtectionDomain domain, Permission permission) {
-            return getPermissions().implies(permission);
+            return getPermissions().implies(permission) || DEFAULT_POLICY.implies(domain, permission);
         }
 
         @Override
--- a/test/jdk/java/lang/System/LoggerFinder/DefaultLoggerFinderTest/DefaultLoggerFinderTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/java/lang/System/LoggerFinder/DefaultLoggerFinderTest/DefaultLoggerFinderTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -842,6 +842,8 @@
 
     public static class SimplePolicy extends Policy {
 
+        static final Policy DEFAULT_POLICY = Policy.getPolicy();
+
         final Permissions permissions;
         final Permissions withControlPermissions;
         final Permissions allPermissions;
@@ -865,7 +867,7 @@
         public boolean implies(ProtectionDomain domain, Permission permission) {
             if (allowAll.get().get()) return allPermissions.implies(permission);
             if (allowControl.get().get()) return withControlPermissions.implies(permission);
-            return permissions.implies(permission);
+            return permissions.implies(permission) || DEFAULT_POLICY.implies(domain, permission);
         }
 
         @Override
--- a/test/jdk/java/lang/System/LoggerFinder/internal/BaseLoggerBridgeTest/BaseLoggerBridgeTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/java/lang/System/LoggerFinder/internal/BaseLoggerBridgeTest/BaseLoggerBridgeTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -981,6 +981,8 @@
         final static RuntimePermission ACCESS_LOGGER = new RuntimePermission("accessClassInPackage.jdk.internal.logger");
         final static RuntimePermission ACCESS_LOGGING = new RuntimePermission("accessClassInPackage.sun.util.logging");
 
+        static final Policy DEFAULT_POLICY = Policy.getPolicy();
+
         final Permissions permissions;
         final Permissions allPermissions;
         final ThreadLocal<AtomicBoolean> allowControl;
@@ -1019,7 +1021,7 @@
 
         @Override
         public boolean implies(ProtectionDomain domain, Permission permission) {
-            return getPermissions().implies(permission);
+            return getPermissions().implies(permission) || DEFAULT_POLICY.implies(domain, permission);
         }
 
         @Override
--- a/test/jdk/java/lang/System/LoggerFinder/internal/BasePlatformLoggerTest/BasePlatformLoggerTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/java/lang/System/LoggerFinder/internal/BasePlatformLoggerTest/BasePlatformLoggerTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -663,6 +663,8 @@
         final static RuntimePermission CONTROL = LOGGERFINDER_PERMISSION;
         final static RuntimePermission ACCESS_LOGGING = new RuntimePermission("accessClassInPackage.sun.util.logging");
 
+        static final Policy DEFAULT_POLICY = Policy.getPolicy();
+
         final Permissions permissions;
         final Permissions allPermissions;
         final ThreadLocal<AtomicBoolean> allowControl;
@@ -700,7 +702,7 @@
 
         @Override
         public boolean implies(ProtectionDomain domain, Permission permission) {
-            return getPermissions().implies(permission);
+            return getPermissions().implies(permission) || DEFAULT_POLICY.implies(domain, permission);
         }
 
         @Override
--- a/test/jdk/java/lang/System/LoggerFinder/internal/LoggerBridgeTest/LoggerBridgeTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/java/lang/System/LoggerFinder/internal/LoggerBridgeTest/LoggerBridgeTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1026,6 +1026,8 @@
         final static RuntimePermission ACCESS_LOGGER = new RuntimePermission("accessClassInPackage.jdk.internal.logger");
         final static RuntimePermission ACCESS_LOGGING = new RuntimePermission("accessClassInPackage.sun.util.logging");
 
+        static final Policy DEFAULT_POLICY = Policy.getPolicy();
+
         final Permissions permissions;
         final Permissions allPermissions;
         final ThreadLocal<AtomicBoolean> allowControl;
@@ -1064,7 +1066,7 @@
 
         @Override
         public boolean implies(ProtectionDomain domain, Permission permission) {
-            return getPermissions().implies(permission);
+            return getPermissions().implies(permission) || DEFAULT_POLICY.implies(domain, permission);
         }
 
         @Override
--- a/test/jdk/java/lang/System/LoggerFinder/internal/PlatformLoggerBridgeTest/PlatformLoggerBridgeTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/java/lang/System/LoggerFinder/internal/PlatformLoggerBridgeTest/PlatformLoggerBridgeTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -805,6 +805,8 @@
         final static RuntimePermission ACCESS_LOGGER = new RuntimePermission("accessClassInPackage.jdk.internal.logger");
         final static RuntimePermission ACCESS_LOGGING = new RuntimePermission("accessClassInPackage.sun.util.logging");
 
+        static final Policy DEFAULT_POLICY = Policy.getPolicy();
+
         final Permissions permissions;
         final Permissions allPermissions;
         final ThreadLocal<AtomicBoolean> allowControl;
@@ -843,7 +845,7 @@
 
         @Override
         public boolean implies(ProtectionDomain domain, Permission permission) {
-            return getPermissions().implies(permission);
+            return getPermissions().implies(permission) || DEFAULT_POLICY.implies(domain, permission);
         }
 
         @Override
--- a/test/jdk/java/lang/System/LoggerFinder/jdk/DefaultLoggerBridgeTest/DefaultLoggerBridgeTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/java/lang/System/LoggerFinder/jdk/DefaultLoggerBridgeTest/DefaultLoggerBridgeTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -801,6 +801,8 @@
         final static RuntimePermission ACCESS_LOGGER = new RuntimePermission("accessClassInPackage.jdk.internal.logger");
         final static RuntimePermission ACCESS_LOGGING = new RuntimePermission("accessClassInPackage.sun.util.logging");
 
+        static final Policy DEFAULT_POLICY = Policy.getPolicy();
+
         final Permissions permissions;
         final Permissions allPermissions;
         final ThreadLocal<AtomicBoolean> allowControl;
@@ -839,7 +841,7 @@
 
         @Override
         public boolean implies(ProtectionDomain domain, Permission permission) {
-            return getPermissions().implies(permission);
+            return getPermissions().implies(permission) || DEFAULT_POLICY.implies(domain, permission);
         }
 
         @Override
--- a/test/jdk/java/lang/System/LoggerFinder/jdk/DefaultPlatformLoggerTest/DefaultPlatformLoggerTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/java/lang/System/LoggerFinder/jdk/DefaultPlatformLoggerTest/DefaultPlatformLoggerTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -499,6 +499,8 @@
         public static final RuntimePermission LOGGERFINDER_PERMISSION =
                 new RuntimePermission("loggerFinder");
 
+        static final Policy DEFAULT_POLICY = Policy.getPolicy();
+
         final Permissions permissions;
         final Permissions withControlPermissions;
         final Permissions allPermissions;
@@ -522,7 +524,7 @@
         public boolean implies(ProtectionDomain domain, Permission permission) {
             if (allowAll.get().get()) return allPermissions.implies(permission);
             if (allowControl.get().get()) return withControlPermissions.implies(permission);
-            return permissions.implies(permission);
+            return permissions.implies(permission) || DEFAULT_POLICY.implies(domain, permission);
         }
 
         @Override
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/constant/access_test/pkg1/MethodTypeDescriptorAccessTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8226709
+ * @summary MethodTypeDesc::resolveConstantDesc needs access check per the specification
+ * @compile ../pkg2/PublicClass.java ../pkg2/NonPublicClass.java
+ * @run main pkg1.MethodTypeDescriptorAccessTest
+ */
+
+package pkg1;
+
+import java.lang.invoke.*;
+import java.lang.invoke.MethodType;
+import java.lang.constant.*;
+
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodHandles.Lookup.*;
+import static java.lang.invoke.MethodType.*;
+
+public class MethodTypeDescriptorAccessTest {
+    public static void main(String... args) throws Throwable {
+        new MethodTypeDescriptorAccessTest().test();
+    }
+
+    void test() {
+        Lookup selfLookup = MethodHandles.lookup();
+        //first test PublicClass
+        String descriptorpub = "(Lpkg2/PublicClass;)Lpkg2/PublicClass;";
+        MethodTypeDesc mtdpub = MethodTypeDesc.ofDescriptor(descriptorpub);
+        checkValidAccess(mtdpub, selfLookup);
+
+        // test NonPublicClass in the return type
+        String descriptornp = "()Lpkg2/NonPublicClass;";
+        MethodTypeDesc mtdnp = MethodTypeDesc.ofDescriptor(descriptornp);
+        checkInvalidAccess(mtdnp, selfLookup);
+
+        // test NonPublicClass in the parameters
+        descriptornp = "(Lpkg2/NonPublicClass;)I";
+        mtdnp = MethodTypeDesc.ofDescriptor(descriptornp);
+        checkInvalidAccess(mtdnp, selfLookup);
+
+        MethodType mt = MethodType.fromMethodDescriptorString("(Lpkg2/NonPublicClass;)I", selfLookup.lookupClass().getClassLoader());
+    }
+
+    private void checkValidAccess(MethodTypeDesc mtd, Lookup lookup) {
+        try {
+            MethodType mt = (MethodType)mtd.resolveConstantDesc(lookup);
+        } catch (ReflectiveOperationException unexpected) {
+            throw new Error("resolveConstantDesc() threw ReflectiveOperationException unexpectedly with cause " +
+                    unexpected.getCause() + " for " + mtd);
+        }
+    }
+
+    private void checkInvalidAccess(MethodTypeDesc mtd, Lookup lookup) {
+        try {
+            MethodType mt = (MethodType)mtd.resolveConstantDesc(lookup);
+            throw new Error("resolveConstantDesc() succeeded unexpectedly " + mtd);
+        } catch (ReflectiveOperationException expected) {
+            if (expected.getClass() != IllegalAccessException.class) {
+                throw new Error("resolveConstantDesc() threw unexpected ReflectiveOperationException with cause " +
+                        expected.getCause() + " for " + mtd);
+            }
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/constant/access_test/pkg2/NonPublicClass.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg2;
+
+class NonPublicClass {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/constant/access_test/pkg2/PublicClass.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg2;
+
+public class PublicClass {}
--- a/test/jdk/java/lang/invoke/InvokeDynamicPrintArgs.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/java/lang/invoke/InvokeDynamicPrintArgs.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -234,6 +234,8 @@
     }
 
     static class TestPolicy extends Policy {
+        static final Policy DEFAULT_POLICY = Policy.getPolicy();
+
         final PermissionCollection permissions = new Permissions();
         TestPolicy() {
             permissions.add(new java.io.FilePermission("<<ALL FILES>>", "read"));
@@ -247,7 +249,7 @@
         }
 
         public boolean implies(ProtectionDomain domain, Permission perm) {
-            return permissions.implies(perm);
+            return permissions.implies(perm) || DEFAULT_POLICY.implies(domain, perm);
         }
     }
 }
--- a/test/jdk/java/lang/invoke/MethodHandleConstants.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/java/lang/invoke/MethodHandleConstants.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -169,6 +169,8 @@
     }
 
     static class TestPolicy extends Policy {
+        static final Policy DEFAULT_POLICY = Policy.getPolicy();
+
         final PermissionCollection permissions = new Permissions();
         TestPolicy() {
             permissions.add(new java.io.FilePermission("<<ALL FILES>>", "read"));
@@ -182,7 +184,7 @@
         }
 
         public boolean implies(ProtectionDomain domain, Permission perm) {
-            return permissions.implies(perm);
+            return permissions.implies(perm) || DEFAULT_POLICY.implies(domain, perm);
         }
     }
 }
--- a/test/jdk/java/net/HttpCookie/IllegalCookieNameTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/java/net/HttpCookie/IllegalCookieNameTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,25 +23,35 @@
 
 /* @test
  * @bug 7183292
+ * @library /test/lib
  * @modules jdk.httpserver
+ * @run main IllegalCookieNameTest
+ * @run main/othervm -Djava.net.preferIPv6Addresses=true IllegalCookieNameTest
  */
 import java.net.*;
 import java.util.*;
 import java.io.*;
 import com.sun.net.httpserver.*;
+import jdk.test.lib.net.URIBuilder;
 
 public class IllegalCookieNameTest {
-    public static void main(String[] args) throws IOException {
+    public static void main(String[] args) throws Exception {
         HttpServer s = null;
         try {
-            InetSocketAddress addr = new InetSocketAddress(0);
+            InetAddress loopback = InetAddress.getLoopbackAddress();
+            InetSocketAddress addr = new InetSocketAddress(loopback, 0);
             s = HttpServer.create(addr, 10);
             s.createContext("/", new HHandler());
             s.start();
-            String u = "http://127.0.0.1:" + s.getAddress().getPort() + "/";
+            String u = URIBuilder.newBuilder()
+                .scheme("http")
+                .loopback()
+                .port(s.getAddress().getPort())
+                .path("/")
+                .build().toString();
             CookieHandler.setDefault(new TestCookieHandler());
             URL url = new URL(u);
-            HttpURLConnection c = (HttpURLConnection) url.openConnection();
+            HttpURLConnection c = (HttpURLConnection) url.openConnection(Proxy.NO_PROXY);
             c.getHeaderFields();
             System.out.println ("OK");
         } finally {
--- a/test/jdk/java/net/HttpURLConnection/SetAuthenticator/HTTPTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/java/net/HttpURLConnection/SetAuthenticator/HTTPTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -258,14 +258,27 @@
     public static URL url(HttpProtocolType protocol, InetSocketAddress address,
                           String path) throws MalformedURLException {
         return new URL(protocol(protocol),
-                       address.getHostString(),
+                       address.getAddress().getHostAddress(),
                        address.getPort(), path);
     }
 
     public static Proxy proxy(HTTPTestServer server, HttpAuthType authType) {
-        return (authType == HttpAuthType.PROXY)
-               ? new Proxy(Proxy.Type.HTTP, server.getAddress())
-               : null;
+        if (authType != HttpAuthType.PROXY) return null;
+
+        InetSocketAddress proxyAddress = server.getProxyAddress();
+        if (!proxyAddress.isUnresolved()) {
+            // Forces the proxy to use an unresolved address created
+            // from the actual IP address to avoid using the proxy
+            // address hostname which would result in resolving to
+            // a posibly different address. For instance we want to
+            // avoid cases such as:
+            //    ::1 => "localhost" => 127.0.0.1
+            proxyAddress = InetSocketAddress.
+                createUnresolved(proxyAddress.getAddress().getHostAddress(),
+                                 proxyAddress.getPort());
+        }
+
+        return new Proxy(Proxy.Type.HTTP, proxyAddress);
     }
 
     public static HttpURLConnection openConnection(URL url,
--- a/test/jdk/java/net/HttpURLConnection/SetAuthenticator/HTTPTestServer.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/java/net/HttpURLConnection/SetAuthenticator/HTTPTestServer.java	Mon Jul 01 14:57:02 2019 -0700
@@ -391,6 +391,10 @@
         return serverImpl.getAddress();
     }
 
+    public InetSocketAddress getProxyAddress() {
+        return serverImpl.getAddress();
+    }
+
     public void stop() {
         serverImpl.stop(0);
         if (redirect != null) {
@@ -1019,7 +1023,7 @@
         }
 
         @Override
-        public InetSocketAddress getAddress() {
+        public InetSocketAddress getProxyAddress() {
             return new InetSocketAddress(ss.getInetAddress(), ss.getLocalPort());
         }
 
@@ -1047,7 +1051,7 @@
             Socket clientConnection = null;
             try {
                 while (true) {
-                    System.out.println("Tunnel: Waiting for client");
+                    System.out.println("Tunnel: Waiting for client at: " + ss);
                     Socket previous = clientConnection;
                     try {
                         clientConnection = ss.accept();
--- a/test/jdk/java/net/MulticastSocket/Promiscuous.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/java/net/MulticastSocket/Promiscuous.java	Mon Jul 01 14:57:02 2019 -0700
@@ -22,7 +22,7 @@
  *
 
 /* @test
- * @bug 8014499
+ * @bug 8014499 8219804
  * @library /test/lib
  * @summary Test for interference when two sockets are bound to the same
  *          port but joined to different multicast groups
@@ -44,11 +44,20 @@
         throws IOException
     {
         byte[] ba = new byte[100];
-        DatagramPacket p = new DatagramPacket(ba, ba.length);
+        DatagramPacket p;
         try {
-            mc.receive(p);
-            int recvId = Integer.parseInt(
-                    new String(p.getData(), 0, p.getLength(), "UTF-8"));
+            String data = null;
+            while (true) {
+                p = new DatagramPacket(ba, ba.length);
+                mc.receive(p);
+                data = new String(p.getData(), 0, p.getLength(), "UTF-8");
+                if (data.length() > UUID.length() && data.startsWith(UUID)) {
+                    data = data.substring(UUID.length());
+                    break;
+                }
+                logUnexpected(p);
+            }
+            int recvId = Integer.parseInt(data);
             if (datagramExpected) {
                 if (recvId != id)
                     throw new RuntimeException("Unexpected id, got " + recvId
@@ -67,6 +76,20 @@
         }
     }
 
+    static void logUnexpected(DatagramPacket p) {
+        byte[] ba = p.getData();
+        System.out.printf("Unexpected packet: length: %d. First three bytes: %d, %d, %d\n",
+                          p.getLength(), ba[0], ba[1], ba[2]);
+    }
+
+    static final String UUID; // process-id : currentTimeMillis
+
+    static {
+        String s1 = Long.toString(ProcessHandle.current().pid());
+        String s2 = Long.toString(System.currentTimeMillis());
+        UUID = "<" + s1 + s2 + ">";
+    }
+
     static void test(InetAddress group1, InetAddress group2)
         throws IOException
     {
@@ -79,7 +102,7 @@
             mc1.setSoTimeout(TIMEOUT);
             mc2.setSoTimeout(TIMEOUT);
             int nextId = id;
-            byte[] msg = Integer.toString(nextId).getBytes("UTF-8");
+            byte[] msg = (UUID + Integer.toString(nextId)).getBytes("UTF-8");
             DatagramPacket p = new DatagramPacket(msg, msg.length);
             p.setAddress(group1);
             p.setPort(port);
@@ -97,7 +120,7 @@
             receive(mc2, false, 0);
 
             nextId = ++id;
-            msg = Integer.toString(nextId).getBytes("UTF-8");
+            msg = (UUID + Integer.toString(nextId)).getBytes("UTF-8");
             p = new DatagramPacket(msg, msg.length);
             p.setAddress(group2);
             p.setPort(port);
@@ -116,7 +139,6 @@
 
     public static void main(String args[]) throws IOException {
         IPSupport.throwSkippedExceptionIfNonOperational();
-
         String os = System.getProperty("os.name");
 
         // Requires IP_MULTICAST_ALL on Linux (new since 2.6.31) so skip
@@ -133,8 +155,8 @@
         }
 
         // multicast groups used for the test
-        InetAddress ip4Group1 = InetAddress.getByName("224.7.8.9");
-        InetAddress ip4Group2 = InetAddress.getByName("225.4.5.6");
+        InetAddress ip4Group1 = InetAddress.getByName("224.0.0.120");
+        InetAddress ip4Group2 = InetAddress.getByName("224.0.0.121");
 
         test(ip4Group1, ip4Group2);
     }
--- a/test/jdk/java/net/Socket/SetSoLinger.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/java/net/Socket/SetSoLinger.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@
  * @summary Test Socket.setSoLinger
  * @run main SetSoLinger
  * @run main/othervm -Djava.net.preferIPv4Stack=true SetSoLinger
+ * @run main/othervm -Djava.net.preferIPv6Addresses=true SetSoLinger
  */
 
 import java.net.*;
@@ -41,7 +42,10 @@
 
         int value;
         InetAddress addr = InetAddress.getLocalHost();
-        ServerSocket ss = new ServerSocket(0);
+        ServerSocket ss = new ServerSocket();
+
+        InetSocketAddress socketAddress = new InetSocketAddress(addr, 0);
+        ss.bind(socketAddress);
         int port = ss.getLocalPort();
 
         Socket s = new Socket(addr, port);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/httpclient/ByteArrayPublishers.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8222968
+ * @summary ByteArrayPublisher is not thread-safe resulting in broken re-use of HttpRequests
+ * @run main/othervm ByteArrayPublishers
+ */
+
+import java.net.InetAddress;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
+import java.util.ArrayList;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.CompletableFuture;
+
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpServer;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.nio.charset.StandardCharsets;
+import static java.net.http.HttpRequest.BodyPublisher;
+import static java.net.http.HttpRequest.BodyPublishers;
+
+public class ByteArrayPublishers {
+    private static final BodyPublisher BODY_PUBLISHER =
+        BodyPublishers.ofByteArray("abcdefghijklmnopqrstuvwxyz".getBytes());
+
+    static int LOOPS = 100;
+
+    public static void main(String[] args) throws Exception {
+        HttpServer server = null;
+        try {
+            InetAddress loopBack = InetAddress.getLoopbackAddress();
+            String lpBackStr = loopBack.getHostAddress();
+            InetSocketAddress serverAddr = new InetSocketAddress(loopBack, 0);
+            server = HttpServer.create(serverAddr, 500);
+            server.createContext("/", (HttpExchange e) -> {
+                    e.getRequestBody().readAllBytes();
+                    String response = "Hello world";
+                    e.sendResponseHeaders(200, response.length());
+                    e.getResponseBody().write(response.getBytes(StandardCharsets.ISO_8859_1));
+                    e.close();
+            });
+            server.start();
+            var address = server.getAddress();
+            URI dest = new URI("http://" + lpBackStr + ":"
+                + Integer.toString(address.getPort()) + "/");
+
+            HttpClient client = createClient();
+
+            ArrayList<CompletableFuture<HttpResponse<Void>>> futures = new ArrayList<>(LOOPS);
+            LinkedBlockingQueue<Object> results = new LinkedBlockingQueue<Object>();
+            for (int i=0;i<LOOPS;i++) {
+                futures.add(
+                    client.sendAsync(createRequest(dest), HttpResponse.BodyHandlers.discarding())
+                          .handle((v, t) -> {
+                                if (t != null)
+                                    results.add(t);
+                                else
+                                    results.add(v);
+                                return null;
+                          }));
+            }
+
+            for (int i=0; i<LOOPS; i++) {
+                Object o = results.take();
+                if (o instanceof Exception) {
+                    throw new RuntimeException((Exception)o);
+                }
+            }
+        } finally {
+            server.stop(1);
+        }
+    }
+
+    private static HttpRequest createRequest(URI uri) throws URISyntaxException {
+        HttpRequest.Builder builder = HttpRequest.newBuilder(uri)
+                .method("POST", BODY_PUBLISHER)
+                .version(HttpClient.Version.HTTP_1_1);
+        builder.header("content-type", "text/plain");
+        return builder.build();
+    }
+
+    private static HttpClient createClient() {
+        return HttpClient.newBuilder()
+                .version(HttpClient.Version.HTTP_1_1)
+                .build();
+
+    }
+}
--- a/test/jdk/java/nio/channels/Selector/RacyDeregister.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/java/nio/channels/Selector/RacyDeregister.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -41,11 +41,6 @@
  */
 public class RacyDeregister {
 
-    // FIXME: NUM_OUTER_LOOP_ITERATIONS should be reverted to the hard-coded
-    // value 15 when JDK-8161083 is resolved as either a bug or a non-issue.
-    static final int NUM_OUTER_LOOP_ITERATIONS =
-        System.getProperty("os.name").startsWith("Windows") ? 150 : 15;
-
     // 90% of 1200 second timeout as milliseconds
     static final int TIMEOUT_THRESHOLD_MILLIS = 1200*900;
 
@@ -90,7 +85,7 @@
 
             public void run() {
                 try {
-                    for (int k = 0; k < NUM_OUTER_LOOP_ITERATIONS; k++) {
+                    for (int k = 0; k < 15; k++) {
                         System.out.format("outer loop %3d at %7d ms%n", k,
                             System.currentTimeMillis() - t0);
                         System.out.flush();
--- a/test/jdk/java/security/Policy/Dynamic/DynamicPolicy.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/java/security/Policy/Dynamic/DynamicPolicy.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@
 
 public class DynamicPolicy extends Policy{
 
+    static final Policy DEFAULT_POLICY = Policy.getPolicy(); // do this early before setPolicy is called
     static int refresher = 0;
 
 
@@ -48,7 +49,7 @@
     }
 
     public boolean implies(ProtectionDomain pd, Permission p) {
-        return getPermissions(pd).implies(p);
+        return getPermissions(pd).implies(p) || DEFAULT_POLICY.implies(pd, p);
     }
 
     public PermissionCollection getPermissions(ProtectionDomain pd) {
--- a/test/jdk/java/util/Locale/LocaleProvidersRun.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/java/util/Locale/LocaleProvidersRun.java	Mon Jul 01 14:57:02 2019 -0700
@@ -159,7 +159,9 @@
     private static void testRun(String prefList, String methodName,
             String param1, String param2, String param3) throws Throwable{
         JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("java");
-        launcher.addToolArg("-cp")
+        launcher.addToolArg("-ea")
+                .addToolArg("-esa")
+                .addToolArg("-cp")
                 .addToolArg(Utils.TEST_CLASS_PATH)
                 .addToolArg("-Djava.locale.providers=" + prefList)
                 .addToolArg("--add-exports=java.base/sun.util.locale.provider=ALL-UNNAMED")
--- a/test/jdk/java/util/concurrent/Executors/PrivilegedCallables.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/java/util/concurrent/Executors/PrivilegedCallables.java	Mon Jul 01 14:57:02 2019 -0700
@@ -70,6 +70,8 @@
     // A Policy class designed to make permissions fiddling very easy.
     //----------------------------------------------------------------
     static class Policy extends java.security.Policy {
+        static final java.security.Policy DEFAULT_POLICY = java.security.Policy.getPolicy();
+
         private Permissions perms;
 
         public void setPermissions(Permission...permissions) {
@@ -89,7 +91,7 @@
         }
 
         public boolean implies(ProtectionDomain pd, Permission p) {
-            return perms.implies(p);
+            return perms.implies(p) || DEFAULT_POLICY.implies(pd, p);
         }
 
         public void refresh() {}
--- a/test/jdk/java/util/logging/FileHandlerLongLimit.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/java/util/logging/FileHandlerLongLimit.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -471,6 +471,8 @@
 
     public static class SimplePolicy extends Policy {
 
+        static final Policy DEFAULT_POLICY = Policy.getPolicy();
+
         final Permissions permissions;
         final Permissions allPermissions;
         final AtomicBoolean allowAll;
@@ -490,7 +492,7 @@
         @Override
         public boolean implies(ProtectionDomain domain, Permission permission) {
             if (allowAll.get()) return allPermissions.implies(permission);
-            return permissions.implies(permission);
+            return permissions.implies(permission) || DEFAULT_POLICY.implies(domain, permission);
         }
 
         @Override
--- a/test/jdk/java/util/logging/FileHandlerPath.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/java/util/logging/FileHandlerPath.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -270,6 +270,8 @@
 
     public static class SimplePolicy extends Policy {
 
+        static final Policy DEFAULT_POLICY = Policy.getPolicy();
+
         final Permissions permissions;
         final Permissions allPermissions;
         final AtomicBoolean allowAll;
@@ -297,7 +299,7 @@
         @Override
         public boolean implies(ProtectionDomain domain, Permission permission) {
             if (allowAll.get()) return allPermissions.implies(permission);
-            return permissions.implies(permission);
+            return permissions.implies(permission) || DEFAULT_POLICY.implies(domain, permission);
         }
 
         @Override
--- a/test/jdk/java/util/logging/FileHandlerPatternExceptions.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/java/util/logging/FileHandlerPatternExceptions.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -294,6 +294,8 @@
 
     public static class SimplePolicy extends Policy {
 
+        static final Policy DEFAULT_POLICY = Policy.getPolicy();
+
         final Permissions permissions;
         final Permissions allPermissions;
         final AtomicBoolean allowAll;
@@ -313,7 +315,7 @@
         @Override
         public boolean implies(ProtectionDomain domain, Permission permission) {
             if (allowAll.get()) return allPermissions.implies(permission);
-            return permissions.implies(permission);
+            return permissions.implies(permission) || DEFAULT_POLICY.implies(domain, permission);
         }
 
         @Override
--- a/test/jdk/java/util/logging/LogManager/Configuration/ParentLoggerWithHandlerGC.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/java/util/logging/LogManager/Configuration/ParentLoggerWithHandlerGC.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -480,6 +480,8 @@
 
     public static class SimplePolicy extends Policy {
 
+        static final Policy DEFAULT_POLICY = Policy.getPolicy();
+
         final Permissions permissions;
         final Permissions allPermissions;
         final AtomicBoolean allowAll;
@@ -499,7 +501,7 @@
         @Override
         public boolean implies(ProtectionDomain domain, Permission permission) {
             if (allowAll.get()) return allPermissions.implies(permission);
-            return permissions.implies(permission);
+            return permissions.implies(permission) || DEFAULT_POLICY.implies(domain, permission);
         }
 
         @Override
--- a/test/jdk/java/util/logging/LogManager/Configuration/updateConfiguration/HandlersOnComplexResetUpdate.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/java/util/logging/LogManager/Configuration/updateConfiguration/HandlersOnComplexResetUpdate.java	Mon Jul 01 14:57:02 2019 -0700
@@ -522,6 +522,8 @@
 
     public static class SimplePolicy extends Policy {
 
+        static final Policy DEFAULT_POLICY = Policy.getPolicy();
+
         final Permissions permissions;
         final Permissions allPermissions;
         final ThreadLocal<AtomicBoolean> allowAll; // actually: this should be in a thread locale
@@ -541,7 +543,7 @@
         @Override
         public boolean implies(ProtectionDomain domain, Permission permission) {
             if (allowAll.get().get()) return allPermissions.implies(permission);
-            return permissions.implies(permission);
+            return permissions.implies(permission) || DEFAULT_POLICY.implies(domain, permission);
         }
 
         @Override
--- a/test/jdk/java/util/logging/LogManager/Configuration/updateConfiguration/HandlersOnComplexUpdate.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/java/util/logging/LogManager/Configuration/updateConfiguration/HandlersOnComplexUpdate.java	Mon Jul 01 14:57:02 2019 -0700
@@ -521,6 +521,8 @@
 
     public static class SimplePolicy extends Policy {
 
+        static final Policy DEFAULT_POLICY = Policy.getPolicy();
+
         final Permissions permissions;
         final Permissions allPermissions;
         final ThreadLocal<AtomicBoolean> allowAll; // actually: this should be in a thread locale
@@ -540,7 +542,7 @@
         @Override
         public boolean implies(ProtectionDomain domain, Permission permission) {
             if (allowAll.get().get()) return allPermissions.implies(permission);
-            return permissions.implies(permission);
+            return permissions.implies(permission) || DEFAULT_POLICY.implies(domain, permission);
         }
 
         @Override
--- a/test/jdk/java/util/logging/LogManager/Configuration/updateConfiguration/SimpleUpdateConfigurationTest.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/java/util/logging/LogManager/Configuration/updateConfiguration/SimpleUpdateConfigurationTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -652,6 +652,8 @@
 
     public static class SimplePolicy extends Policy {
 
+        static final Policy DEFAULT_POLICY = Policy.getPolicy();
+
         final Permissions basic;
         final Permissions control;
         final Permissions all;
@@ -690,7 +692,7 @@
 
         @Override
         public boolean implies(ProtectionDomain domain, Permission permission) {
-            return getPermissions(domain).implies(permission);
+            return getPermissions(domain).implies(permission) || DEFAULT_POLICY.implies(domain, permission);
         }
 
         public PermissionCollection permissions() {
--- a/test/jdk/java/util/logging/LogManager/RootLogger/setLevel/TestRootLoggerLevel.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/java/util/logging/LogManager/RootLogger/setLevel/TestRootLoggerLevel.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -119,6 +119,9 @@
      }
 
     private static final class SimplePolicy extends Policy {
+
+        static final Policy DEFAULT_POLICY = Policy.getPolicy();
+
         private final Permissions perms;
 
         private static final Permissions permissions(Permission... perms) {
@@ -141,7 +144,7 @@
 
         @Override
         public boolean implies(ProtectionDomain domain, Permission permission) {
-            return perms.implies(permission);
+            return perms.implies(permission) || DEFAULT_POLICY.implies(domain, permission);
         }
 
     }
--- a/test/jdk/java/util/logging/LogManagerAppContextDeadlock.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/java/util/logging/LogManagerAppContextDeadlock.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -340,6 +340,8 @@
     // Policy for the test...
     public static class SimplePolicy extends Policy {
 
+        static final Policy DEFAULT_POLICY = Policy.getPolicy();
+
         final Permissions permissions;
         final Permissions allPermissions;
         final ThreadLocal<AtomicBoolean> allowAll; // actually: this should be in a thread locale
@@ -360,7 +362,7 @@
         @Override
         public boolean implies(ProtectionDomain domain, Permission permission) {
             if (allowAll.get().get()) return allPermissions.implies(permission);
-            return permissions.implies(permission);
+            return permissions.implies(permission) || DEFAULT_POLICY.implies(domain, permission);
         }
 
         @Override
--- a/test/jdk/java/util/logging/RootLogger/RootLevelInConfigFile.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/java/util/logging/RootLogger/RootLevelInConfigFile.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -176,6 +176,8 @@
 
     static final class SimplePolicy extends Policy {
 
+        static final Policy DEFAULT_POLICY = Policy.getPolicy();
+
         final PermissionCollection perms = new Permissions();
         public SimplePolicy(String configFile) {
             perms.add(new LoggingPermission("control", null));
@@ -187,7 +189,7 @@
 
         @Override
         public boolean implies(ProtectionDomain domain, Permission permission) {
-            return perms.implies(permission);
+            return perms.implies(permission) || DEFAULT_POLICY.implies(domain, permission);
         }
     }
 
--- a/test/jdk/java/util/logging/TestAppletLoggerContext.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/java/util/logging/TestAppletLoggerContext.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -72,6 +72,9 @@
 
     // Avoids the hassle of dealing with files and system props...
     static class SimplePolicy extends Policy {
+
+        static final Policy DEFAULT_POLICY = Policy.getPolicy();
+
         private final Permissions perms;
         public SimplePolicy(Permission... permissions) {
             perms = new Permissions();
@@ -89,7 +92,7 @@
         }
         @Override
         public boolean implies(ProtectionDomain pd, Permission p) {
-           return perms.implies(p);
+           return perms.implies(p) || DEFAULT_POLICY.implies(pd, p);
         }
     }
 
--- a/test/jdk/java/util/logging/TestConfigurationListeners.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/java/util/logging/TestConfigurationListeners.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -458,6 +458,8 @@
 
     public static class SimplePolicy extends Policy {
 
+        static final Policy DEFAULT_POLICY = Policy.getPolicy();
+
         final Permissions permissions;
         public SimplePolicy(TestCase test) {
             permissions = new Permissions();
@@ -472,7 +474,7 @@
 
         @Override
         public boolean implies(ProtectionDomain domain, Permission permission) {
-            return permissions.implies(permission);
+            return permissions.implies(permission) || DEFAULT_POLICY.implies(domain, permission);
         }
 
         @Override
--- a/test/jdk/javax/net/ssl/templates/SSLSocketTemplate.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/javax/net/ssl/templates/SSLSocketTemplate.java	Mon Jul 01 14:57:02 2019 -0700
@@ -131,10 +131,7 @@
      * Create an instance of SSLContext for client use.
      */
     protected SSLContext createClientSSLContext() throws Exception {
-        return createSSLContext(trustedCertStrs,
-                endEntityCertStrs, endEntityPrivateKeys,
-                endEntityPrivateKeyAlgs,
-                endEntityPrivateKeyNames,
+        return createSSLContext(TRUSTED_CERTS, END_ENTITY_CERTS,
                 getClientContextParameters());
     }
 
@@ -142,10 +139,7 @@
      * Create an instance of SSLContext for server use.
      */
     protected SSLContext createServerSSLContext() throws Exception {
-        return createSSLContext(trustedCertStrs,
-                endEntityCertStrs, endEntityPrivateKeys,
-                endEntityPrivateKeyAlgs,
-                endEntityPrivateKeyNames,
+        return createSSLContext(TRUSTED_CERTS, END_ENTITY_CERTS,
                 getServerContextParameters());
     }
 
@@ -362,330 +356,24 @@
      * Certificates and keys used in the test.
      */
     // Trusted certificates.
-    private final static String[] trustedCertStrs = {
-        // SHA256withECDSA, curve prime256v1
-        // Validity
-        //     Not Before: May 22 07:18:16 2018 GMT
-        //     Not After : May 17 07:18:16 2038 GMT
-        // Subject Key Identifier:
-        //     60:CF:BD:73:FF:FA:1A:30:D2:A4:EC:D3:49:71:46:EF:1A:35:A0:86
-        "-----BEGIN CERTIFICATE-----\n" +
-        "MIIBvjCCAWOgAwIBAgIJAIvFG6GbTroCMAoGCCqGSM49BAMCMDsxCzAJBgNVBAYT\n" +
-        "AlVTMQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2VyaXZj\n" +
-        "ZTAeFw0xODA1MjIwNzE4MTZaFw0zODA1MTcwNzE4MTZaMDsxCzAJBgNVBAYTAlVT\n" +
-        "MQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2VyaXZjZTBZ\n" +
-        "MBMGByqGSM49AgEGCCqGSM49AwEHA0IABBz1WeVb6gM2mh85z3QlvaB/l11b5h0v\n" +
-        "LIzmkC3DKlVukZT+ltH2Eq1oEkpXuf7QmbM0ibrUgtjsWH3mULfmcWmjUDBOMB0G\n" +
-        "A1UdDgQWBBRgz71z//oaMNKk7NNJcUbvGjWghjAfBgNVHSMEGDAWgBRgz71z//oa\n" +
-        "MNKk7NNJcUbvGjWghjAMBgNVHRMEBTADAQH/MAoGCCqGSM49BAMCA0kAMEYCIQCG\n" +
-        "6wluh1r2/T6L31mZXRKf9JxeSf9pIzoLj+8xQeUChQIhAJ09wAi1kV8yePLh2FD9\n" +
-        "2YEHlSQUAbwwqCDEVB5KxaqP\n" +
-        "-----END CERTIFICATE-----",
-        // -----BEGIN PRIVATE KEY-----
-        // MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg/HcHdoLJCdq3haVd
-        // XZTSKP00YzM3xX97l98vGL/RI1KhRANCAAQc9VnlW+oDNpofOc90Jb2gf5ddW+Yd
-        // LyyM5pAtwypVbpGU/pbR9hKtaBJKV7n+0JmzNIm61ILY7Fh95lC35nFp
-        // -----END PRIVATE KEY-----
-
-        // SHA256withRSA, 2048 bits
-        // Validity
-        //     Not Before: May 22 07:18:16 2018 GMT
-        //     Not After : May 17 07:18:16 2038 GMT
-        // Subject Key Identifier:
-        //     0D:DD:93:C9:FE:4B:BD:35:B7:E8:99:78:90:FB:DB:5A:3D:DB:15:4C
-        "-----BEGIN CERTIFICATE-----\n" +
-        "MIIDSTCCAjGgAwIBAgIJAI4ZF3iy8zG+MA0GCSqGSIb3DQEBCwUAMDsxCzAJBgNV\n" +
-        "BAYTAlVTMQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2Vy\n" +
-        "aXZjZTAeFw0xODA1MjIwNzE4MTZaFw0zODA1MTcwNzE4MTZaMDsxCzAJBgNVBAYT\n" +
-        "AlVTMQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2VyaXZj\n" +
-        "ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALpMcY7aWieXDEM1/YJf\n" +
-        "JW27b4nRIFZyEYhEloyGsKTuQiiQjc8cqRZFNXe2vwziDB4IyTEl0Hjl5QF6ZaQE\n" +
-        "huPzzwvQm1pv64KrRXrmj3FisQK8B5OWLty9xp6xDqsaMRoyObLK+oIb20T5fSlE\n" +
-        "evmo1vYjnh8CX0Yzx5Gr5ye6YSEHQvYOWEws8ad17OlyToR2KMeC8w4qo6rs59pW\n" +
-        "g7Mxn9vo22ImDzrtAbTbXbCias3xlE0Bp0h5luyf+5U4UgksoL9B9r2oP4GrLNEV\n" +
-        "oJk57t8lwaR0upiv3CnS8LcJELpegZub5ggqLY8ZPYFQPjlK6IzLOm6rXPgZiZ3m\n" +
-        "RL0CAwEAAaNQME4wHQYDVR0OBBYEFA3dk8n+S701t+iZeJD721o92xVMMB8GA1Ud\n" +
-        "IwQYMBaAFA3dk8n+S701t+iZeJD721o92xVMMAwGA1UdEwQFMAMBAf8wDQYJKoZI\n" +
-        "hvcNAQELBQADggEBAJTRC3rKUUhVH07/1+stUungSYgpM08dY4utJq0BDk36BbmO\n" +
-        "0AnLDMbkwFdHEoqF6hQIfpm7SQTmXk0Fss6Eejm8ynYr6+EXiRAsaXOGOBCzF918\n" +
-        "/RuKOzqABfgSU4UBKECLM5bMfQTL60qx+HdbdVIpnikHZOFfmjCDVxoHsGyXc1LW\n" +
-        "Jhkht8IGOgc4PMGvyzTtRFjz01kvrVQZ75aN2E0GQv6dCxaEY0i3ypSzjUWAKqDh\n" +
-        "3e2OLwUSvumcdaxyCdZAOUsN6pDBQ+8VRG7KxnlRlY1SMEk46QgQYLbPDe/+W/yH\n" +
-        "ca4PejicPeh+9xRAwoTpiE2gulfT7Lm+fVM7Ruc=\n" +
-        "-----END CERTIFICATE-----",
-        // -----BEGIN PRIVATE KEY-----
-        // MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC6THGO2lonlwxD
-        // Nf2CXyVtu2+J0SBWchGIRJaMhrCk7kIokI3PHKkWRTV3tr8M4gweCMkxJdB45eUB
-        // emWkBIbj888L0Jtab+uCq0V65o9xYrECvAeTli7cvcaesQ6rGjEaMjmyyvqCG9tE
-        // +X0pRHr5qNb2I54fAl9GM8eRq+cnumEhB0L2DlhMLPGndezpck6EdijHgvMOKqOq
-        // 7OfaVoOzMZ/b6NtiJg867QG0212womrN8ZRNAadIeZbsn/uVOFIJLKC/Qfa9qD+B
-        // qyzRFaCZOe7fJcGkdLqYr9wp0vC3CRC6XoGbm+YIKi2PGT2BUD45SuiMyzpuq1z4
-        // GYmd5kS9AgMBAAECggEAFHSoU2MuWwJ+2jJnb5U66t2V1bAcuOE1g5zkWvG/G5z9
-        // rq6Qo5kmB8f5ovdx6tw3MGUOklLwnRXBG3RxDJ1iokz3AvkY1clMNsDPlDsUrQKF
-        // JSO4QUBQTPSZhnsyfR8XHSU+qJ8Y+ohMfzpVv95BEoCzebtXdVgxVegBlcEmVHo2
-        // kMmkRN+bYNsr8eb2r+b0EpyumS39ZgKYh09+cFb78y3T6IFMGcVJTP6nlGBFkmA/
-        // 25pYeCF2tSki08qtMJZQAvKfw0Kviibk7ZxRbJqmc7B1yfnOEHP6ftjuvKl2+RP/
-        // +5P5f8CfIP6gtA0LwSzAqQX/hfIKrGV5j0pCqrD0kQKBgQDeNR6Xi4sXVq79lihO
-        // a1bSeV7r8yoQrS8x951uO+ox+UIZ1MsAULadl7zB/P0er92p198I9M/0Jth3KBuS
-        // zj45mucvpiiGvmQlMKMEfNq4nN7WHOu55kufPswQB2mR4J3xmwI+4fM/nl1zc82h
-        // De8JSazRldJXNhfx0RGFPmgzbwKBgQDWoVXrXLbCAn41oVnWB8vwY9wjt92ztDqJ
-        // HMFA/SUohjePep9UDq6ooHyAf/Lz6oE5NgeVpPfTDkgvrCFVKnaWdwALbYoKXT2W
-        // 9FlyJox6eQzrtHAacj3HJooXWuXlphKSizntfxj3LtMR9BmrmRJOfK+SxNOVJzW2
-        // +MowT20EkwKBgHmpB8jdZBgxI7o//m2BI5Y1UZ1KE5vx1kc7VXzHXSBjYqeV9FeF
-        // 2ZZLP9POWh/1Fh4pzTmwIDODGT2UPhSQy0zq3O0fwkyT7WzXRknsuiwd53u/dejg
-        // iEL2NPAJvulZ2+AuiHo5Z99LK8tMeidV46xoJDDUIMgTG+UQHNGhK5gNAoGAZn/S
-        // Cn7SgMC0CWSvBHnguULXZO9wH1wZAFYNLL44OqwuaIUFBh2k578M9kkke7woTmwx
-        // HxQTjmWpr6qimIuY6q6WBN8hJ2Xz/d1fwhYKzIp20zHuv5KDUlJjbFfqpsuy3u1C
-        // kts5zwI7pr1ObRbDGVyOdKcu7HI3QtR5qqyjwaUCgYABo7Wq6oHva/9V34+G3Goh
-        // 63bYGUnRw2l5BD11yhQv8XzGGZFqZVincD8gltNThB0Dc/BI+qu3ky4YdgdZJZ7K
-        // z51GQGtaHEbrHS5caV79yQ8QGY5mUVH3E+VXSxuIqb6pZq2DH4sTAEFHyncddmOH
-        // zoXBInYwRG9KE/Bw5elhUw==
-        // -----END PRIVATE KEY-----
-
-        // SHA256withDSA, 2048 bits
-        // Validity
-        //     Not Before: May 22 07:18:18 2018 GMT
-        //     Not After : May 17 07:18:18 2038 GMT
-        // Subject Key Identifier:
-        //     76:66:9E:F7:3B:DD:45:E5:3B:D9:72:3C:3F:F0:54:39:86:31:26:53
-        "-----BEGIN CERTIFICATE-----\n" +
-        "MIIErjCCBFSgAwIBAgIJAOktYLNCbr02MAsGCWCGSAFlAwQDAjA7MQswCQYDVQQG\n" +
-        "EwJVUzENMAsGA1UECgwESmF2YTEdMBsGA1UECwwUU3VuSlNTRSBUZXN0IFNlcml2\n" +
-        "Y2UwHhcNMTgwNTIyMDcxODE4WhcNMzgwNTE3MDcxODE4WjA7MQswCQYDVQQGEwJV\n" +
-        "UzENMAsGA1UECgwESmF2YTEdMBsGA1UECwwUU3VuSlNTRSBUZXN0IFNlcml2Y2Uw\n" +
-        "ggNHMIICOQYHKoZIzjgEATCCAiwCggEBAO5GyPhSm0ze3LSu+gicdULLj05iOfTL\n" +
-        "UvZQ29sYz41zmqrLBQbdKiHqgJu2Re9sgTb5suLNjF047TOLPnU3jhPtWm2X8Xzi\n" +
-        "VGIcHym/Q/MeZxStt/88seqroI3WOKzIML2GcrishT+lcGrtH36Tf1+ue2Snn3PS\n" +
-        "WyxygNqPjllP5uUjYmFLvAf4QLMldkd/D2VxcwsHjB8y5iUZsXezc/LEhRZS/02m\n" +
-        "ivqlRw3AMkq/OVe/ZtxFWsP0nsfxEGdZuaUFpppGfixxFvymrB3+J51cTt+pZBDq\n" +
-        "D2y0DYfc+88iCs4jwHTfcDIpLb538HBjBj2rEgtQESQmB0ooD/+wsPsCIQC1bYch\n" +
-        "gElNtDYL3FgpLgNSUYp7gIWv9ehaC7LO2z7biQKCAQBitvFOnDkUja8NAF7lDpOV\n" +
-        "b5ipQ8SicBLW3kQamxhyuyxgZyy/PojZ/oPorkqW/T/A0rhnG6MssEpAtdiwVB+c\n" +
-        "rBYGo3bcwmExJhdOJ6dYuKFppPWhCwKMHs9npK+lqBMl8l5j58xlcFeC7ZfGf8GY\n" +
-        "GkhFW0c44vEQhMMbac6ZTTP4mw+1t7xJfmDMlLEyIpTXaAAk8uoVLWzQWnR40sHi\n" +
-        "ybvS0u3JxQkb7/y8tOOZu8qlz/YOS7lQ6UxUGX27Ce1E0+agfPphetoRAlS1cezq\n" +
-        "Wa7r64Ga0nkj1kwkcRqjgTiJx0NwnUXr78VAXFhVF95+O3lfqhvdtEGtkhDGPg7N\n" +
-        "A4IBBgACggEBAMmSHQK0w2i+iqUjOPzn0yNEZrzepLlLeQ1tqtn0xnlv5vBAeefD\n" +
-        "Pm9dd3tZOjufVWP7hhEz8xPobb1CS4e3vuQiv5UBfhdPL3f3l9T7JMAKPH6C9Vve\n" +
-        "OQXE5eGqbjsySbcmseHoYUt1WCSnSda1opX8zchX04e7DhGfE2/L9flpYEoSt8lI\n" +
-        "vMNjgOwvKdW3yvPt1/eBBHYNFG5gWPv/Q5KoyCtHS03uqGm4rNc/wZTIEEfd66C+\n" +
-        "QRaUltjOaHmtwOdDHaNqwhYZSVOip+Mo+TfyzHFREcdHLapo7ZXqbdYkRGxRR3d+\n" +
-        "3DfHaraJO0OKoYlPkr3JMvM/MSGR9AnZOcejUDBOMB0GA1UdDgQWBBR2Zp73O91F\n" +
-        "5TvZcjw/8FQ5hjEmUzAfBgNVHSMEGDAWgBR2Zp73O91F5TvZcjw/8FQ5hjEmUzAM\n" +
-        "BgNVHRMEBTADAQH/MAsGCWCGSAFlAwQDAgNHADBEAiBzriYE41M2y9Hy5ppkL0Qn\n" +
-        "dIlNc8JhXT/PHW7GDtViagIgMko8Qoj9gDGPK3+O9E8DC3wGiiF9CObM4LN387ok\n" +
-        "J+g=\n" +
-        "-----END CERTIFICATE-----"
-        // -----BEGIN PRIVATE KEY-----
-        // MIICZQIBADCCAjkGByqGSM44BAEwggIsAoIBAQDuRsj4UptM3ty0rvoInHVCy49O
-        // Yjn0y1L2UNvbGM+Nc5qqywUG3Soh6oCbtkXvbIE2+bLizYxdOO0ziz51N44T7Vpt
-        // l/F84lRiHB8pv0PzHmcUrbf/PLHqq6CN1jisyDC9hnK4rIU/pXBq7R9+k39frntk
-        // p59z0lsscoDaj45ZT+blI2JhS7wH+ECzJXZHfw9lcXMLB4wfMuYlGbF3s3PyxIUW
-        // Uv9Npor6pUcNwDJKvzlXv2bcRVrD9J7H8RBnWbmlBaaaRn4scRb8pqwd/iedXE7f
-        // qWQQ6g9stA2H3PvPIgrOI8B033AyKS2+d/BwYwY9qxILUBEkJgdKKA//sLD7AiEA
-        // tW2HIYBJTbQ2C9xYKS4DUlGKe4CFr/XoWguyzts+24kCggEAYrbxTpw5FI2vDQBe
-        // 5Q6TlW+YqUPEonAS1t5EGpsYcrssYGcsvz6I2f6D6K5Klv0/wNK4ZxujLLBKQLXY
-        // sFQfnKwWBqN23MJhMSYXTienWLihaaT1oQsCjB7PZ6SvpagTJfJeY+fMZXBXgu2X
-        // xn/BmBpIRVtHOOLxEITDG2nOmU0z+JsPtbe8SX5gzJSxMiKU12gAJPLqFS1s0Fp0
-        // eNLB4sm70tLtycUJG+/8vLTjmbvKpc/2Dku5UOlMVBl9uwntRNPmoHz6YXraEQJU
-        // tXHs6lmu6+uBmtJ5I9ZMJHEao4E4icdDcJ1F6+/FQFxYVRfefjt5X6ob3bRBrZIQ
-        // xj4OzQQjAiEAsceWOM8do4etxp2zgnoNXV8PUUyqWhz1+0srcKV7FR4=
-        // -----END PRIVATE KEY-----
-        };
+    protected final static Cert[] TRUSTED_CERTS = {
+            Cert.CA_ECDSA_SECP256R1,
+            Cert.CA_RSA_2048,
+            Cert.CA_DSA_2048 };
 
     // End entity certificate.
-    private final static String[] endEntityCertStrs = {
-        // SHA256withECDSA, curve prime256v1
-        // Validity
-        //     Not Before: May 22 07:18:16 2018 GMT
-        //     Not After : May 17 07:18:16 2038 GMT
-        // Authority Key Identifier:
-        //     60:CF:BD:73:FF:FA:1A:30:D2:A4:EC:D3:49:71:46:EF:1A:35:A0:86
-        "-----BEGIN CERTIFICATE-----\n" +
-        "MIIBqjCCAVCgAwIBAgIJAPLY8qZjgNRAMAoGCCqGSM49BAMCMDsxCzAJBgNVBAYT\n" +
-        "AlVTMQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2VyaXZj\n" +
-        "ZTAeFw0xODA1MjIwNzE4MTZaFw0zODA1MTcwNzE4MTZaMFUxCzAJBgNVBAYTAlVT\n" +
-        "MQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2VyaXZjZTEY\n" +
-        "MBYGA1UEAwwPUmVncmVzc2lvbiBUZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcD\n" +
-        "QgAEb+9n05qfXnfHUb0xtQJNS4JeSi6IjOfW5NqchvKnfJey9VkJzR7QHLuOESdf\n" +
-        "xlR7q8YIWgih3iWLGfB+wxHiOqMjMCEwHwYDVR0jBBgwFoAUYM+9c//6GjDSpOzT\n" +
-        "SXFG7xo1oIYwCgYIKoZIzj0EAwIDSAAwRQIgWpRegWXMheiD3qFdd8kMdrkLxRbq\n" +
-        "1zj8nQMEwFTUjjQCIQDRIrAjZX+YXHN9b0SoWWLPUq0HmiFIi8RwMnO//wJIGQ==\n" +
-        "-----END CERTIFICATE-----",
-
-        // SHA256withRSA, 2048 bits
-        // Validity
-        //     Not Before: May 22 07:18:16 2018 GMT
-        //     Not After : May 17 07:18:16 2038 GMT
-        // Authority Key Identifier:
-        //     0D:DD:93:C9:FE:4B:BD:35:B7:E8:99:78:90:FB:DB:5A:3D:DB:15:4C
-        "-----BEGIN CERTIFICATE-----\n" +
-        "MIIDNjCCAh6gAwIBAgIJAO2+yPcFryUTMA0GCSqGSIb3DQEBCwUAMDsxCzAJBgNV\n" +
-        "BAYTAlVTMQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2Vy\n" +
-        "aXZjZTAeFw0xODA1MjIwNzE4MTZaFw0zODA1MTcwNzE4MTZaMFUxCzAJBgNVBAYT\n" +
-        "AlVTMQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2VyaXZj\n" +
-        "ZTEYMBYGA1UEAwwPUmVncmVzc2lvbiBUZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOC\n" +
-        "AQ8AMIIBCgKCAQEAszfBobWfZIp8AgC6PiWDDavP65mSvgCXUGxACbxVNAfkLhNR\n" +
-        "QOsHriRB3X1Q3nvO9PetC6wKlvE9jlnDDj7D+1j1r1CHO7ms1fq8rfcQYdkanDtu\n" +
-        "4AlHo8v+SSWX16MIXFRYDj2VVHmyPtgbltcg4zGAuwT746FdLI94uXjJjq1IOr/v\n" +
-        "0VIlwE5ORWH5Xc+5Tj+oFWK0E4a4GHDgtKKhn2m72hN56/GkPKGkguP5NRS1qYYV\n" +
-        "/EFkdyQMOV8J1M7HaicSft4OL6eKjTrgo93+kHk+tv0Dc6cpVBnalX3TorG8QI6B\n" +
-        "cHj1XQd78oAlAC+/jF4pc0mwi0un49kdK9gRfQIDAQABoyMwITAfBgNVHSMEGDAW\n" +
-        "gBQN3ZPJ/ku9NbfomXiQ+9taPdsVTDANBgkqhkiG9w0BAQsFAAOCAQEApXS0nKwm\n" +
-        "Kp8gpmO2yG1rpd1+2wBABiMU4JZaTqmma24DQ3RzyS+V2TeRb29dl5oTUEm98uc0\n" +
-        "GPZvhK8z5RFr4YE17dc04nI/VaNDCw4y1NALXGs+AHkjoPjLyGbWpi1S+gfq2sNB\n" +
-        "Ekkjp6COb/cb9yiFXOGVls7UOIjnVZVd0r7KaPFjZhYh82/f4PA/A1SnIKd1+nfH\n" +
-        "2yk7mSJNC7Z3qIVDL8MM/jBVwiC3uNe5GPB2uwhd7k5LGAVN3j4HQQGB0Sz+VC1h\n" +
-        "92oi6xDa+YBva2fvHuCd8P50DDjxmp9CemC7rnZ5j8egj88w14X44Xjb/Fd/ApG9\n" +
-        "e57NnbT7KM+Grw==\n" +
-        "-----END CERTIFICATE-----",
-
-        // SHA256withRSA, curv prime256v1
-        // Validity
-        //     Not Before: May 22 07:18:16 2018 GMT
-        //     Not After : May 21 07:18:16 2028 GMT
-        // Authority Key Identifier:
-        //     0D:DD:93:C9:FE:4B:BD:35:B7:E8:99:78:90:FB:DB:5A:3D:DB:15:4C
-        "-----BEGIN CERTIFICATE-----\n" +
-        "MIICazCCAVOgAwIBAgIJAO2+yPcFryUUMA0GCSqGSIb3DQEBCwUAMDsxCzAJBgNV\n" +
-        "BAYTAlVTMQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2Vy\n" +
-        "aXZjZTAeFw0xODA1MjIwNzE4MTZaFw0yODA1MjEwNzE4MTZaMFUxCzAJBgNVBAYT\n" +
-        "AlVTMQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2VyaXZj\n" +
-        "ZTEYMBYGA1UEAwwPUmVncmVzc2lvbiBUZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0D\n" +
-        "AQcDQgAE59MERNTlVZ1eeps8Z3Oue5ZkgQdPtD+WIE6tj3PbIKpxGPDxvfNP959A\n" +
-        "yQjEK/ehWQVrCMmNoEkIzY+IIBgB06MjMCEwHwYDVR0jBBgwFoAUDd2Tyf5LvTW3\n" +
-        "6Jl4kPvbWj3bFUwwDQYJKoZIhvcNAQELBQADggEBAFOTVEqs70ykhZiIdrEsF1Ra\n" +
-        "I3B2rLvwXZk52uSltk2/bzVvewA577ZCoxQ1pL7ynkisPfBN1uVYtHjM1VA3RC+4\n" +
-        "+TAK78dnI7otYjWoHp5rvs4l6c/IbOspS290IlNuDUxMErEm5wxIwj+Aukx/1y68\n" +
-        "hOyCvHBLMY2c1LskH1MMBbDuS1aI+lnGpToi+MoYObxGcV458vxuT8+wwV8Fkpvd\n" +
-        "ll8IIFmeNPRv+1E+lXbES6CSNCVaZ/lFhPgdgYKleN7sfspiz50DG4dqafuEAaX5\n" +
-        "xaK1NWXJxTRz0ROH/IUziyuDW6jphrlgit4+3NCzp6vP9hAJQ8Vhcj0n15BKHIQ=\n" +
-        "-----END CERTIFICATE-----",
-
-        // SHA256withDSA, 2048 bits
-        // Validity
-        //     Not Before: May 22 07:18:20 2018 GMT
-        //     Not After : May 17 07:18:20 2038 GMT
-        // Authority Key Identifier:
-        //     76:66:9E:F7:3B:DD:45:E5:3B:D9:72:3C:3F:F0:54:39:86:31:26:53
-        "-----BEGIN CERTIFICATE-----\n" +
-        "MIIEnDCCBEGgAwIBAgIJAP/jh1qVhNVjMAsGCWCGSAFlAwQDAjA7MQswCQYDVQQG\n" +
-        "EwJVUzENMAsGA1UECgwESmF2YTEdMBsGA1UECwwUU3VuSlNTRSBUZXN0IFNlcml2\n" +
-        "Y2UwHhcNMTgwNTIyMDcxODIwWhcNMzgwNTE3MDcxODIwWjBVMQswCQYDVQQGEwJV\n" +
-        "UzENMAsGA1UECgwESmF2YTEdMBsGA1UECwwUU3VuSlNTRSBUZXN0IFNlcml2Y2Ux\n" +
-        "GDAWBgNVBAMMD1JlZ3Jlc3Npb24gVGVzdDCCA0cwggI6BgcqhkjOOAQBMIICLQKC\n" +
-        "AQEAmlavgoJrMcjqWRVcDE2dmWAPREgnzQvneEDef68cprDzjSwvOs5QeFyx75ib\n" +
-        "ado1e6jO/rW1prCGWHDD1oA/Tn4Pk3vu0nUxzvl1qATc+aJbpUU5Op0bvp6LbCsQ\n" +
-        "QslV9FeRh7Eb7bP6gpc/kHCBzEgC1VCK7prccXWy+t6SMOHbND3h+UbckfSaUuaV\n" +
-        "sVJNTD1D6GElfRj4Nmz1BGPfSYvKorwNZEU3gXwFgtDoAcGx7tcyClLpDHfqRfw/\n" +
-        "7yiqLyeiP7D4hl5lMNouJWDlAdMFp0FMgS3s9VDFinIcr6VtBWMTG7+4+czHAB+3\n" +
-        "fvrwlqNzhBn3uFHrekN/w8fNxwIhAJo7Sae1za7IMW0Q6hE5B4b+s2B/FaKPoA4E\n" +
-        "jtZu13B9AoIBAQCOZqLMKfvqZWUgT0PQ3QjR7dAFdd06I9Y3+TOQzZk1+j+vw/6E\n" +
-        "X4vFItX4gihb/u5Q9CdmpwhVGi7bvo+7+/IKeTgoQ6f5+PSug7SrWWUQ5sPwaZui\n" +
-        "zXZJ5nTeZDucFc2yFx0wgnjbPwiUxZklOT7xGiOMtzOTa2koCz5KuIBL+/wPKKxm\n" +
-        "ypo9VoY9xfbdU6LMXZv/lpD5XTM9rYHr/vUTNkukvV6Hpm0YMEWhVZKUJiqCqTqG\n" +
-        "XHaleOxSw6uQWB/+TznifcC7gB48UOQjCqOKf5VuwQneJLhlhU/jhRV3xtr+hLZa\n" +
-        "hW1wYhVi8cjLDrZFKlgEQqhB4crnJU0mJY+tA4IBBQACggEAID0ezl00/X8mv7eb\n" +
-        "bzovum1+DEEP7FM57k6HZEG2N3ve4CW+0m9Cd+cWPz8wkZ+M0j/Eqa6F0IdbkXEc\n" +
-        "Q7CuzvUyJ57xQ3L/WCgXsiS+Bh8O4Mz7GwW22CGmHqafbVv+hKBfr8MkskO6GJUt\n" +
-        "SUF/CVLzB4gMIvZMH26tBP2xK+i7FeEK9kT+nGdzQSZBAhFYpEVCBplHZO24/OYq\n" +
-        "1DNoU327nUuXIhmsfA8N0PjiWbIZIjTPwBGr9H0LpATI7DIDNcvRRvtROP+pBU9y\n" +
-        "fuykPkptg9C0rCM9t06bukpOSaEz/2VIQdLE8fHYFA6pHZ6CIc2+5cfvMgTPhcjz\n" +
-        "W2jCt6MjMCEwHwYDVR0jBBgwFoAUdmae9zvdReU72XI8P/BUOYYxJlMwCwYJYIZI\n" +
-        "AWUDBAMCA0gAMEUCIQCeI5fN08b9BpOaHdc3zQNGjp24FOL/RxlBLeBAorswJgIg\n" +
-        "JEZ8DhYxQy1O7mmZ2UIT7op6epWMB4dENjs0qWPmcKo=\n" +
-        "-----END CERTIFICATE-----"
-        };
-
-    // Private key in the format of PKCS#8.
-    private final static String[] endEntityPrivateKeys = {
-        //
-        // EC private key related to cert endEntityCertStrs[0].
-        //
-        "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgn5K03bpTLjEtFQRa\n" +
-        "JUtx22gtmGEvvSUSQdimhGthdtihRANCAARv72fTmp9ed8dRvTG1Ak1Lgl5KLoiM\n" +
-        "59bk2pyG8qd8l7L1WQnNHtAcu44RJ1/GVHurxghaCKHeJYsZ8H7DEeI6",
-
-        //
-        // RSA private key related to cert endEntityCertStrs[1].
-        //
-        "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCzN8GhtZ9kinwC\n" +
-        "ALo+JYMNq8/rmZK+AJdQbEAJvFU0B+QuE1FA6weuJEHdfVDee870960LrAqW8T2O\n" +
-        "WcMOPsP7WPWvUIc7uazV+ryt9xBh2RqcO27gCUejy/5JJZfXowhcVFgOPZVUebI+\n" +
-        "2BuW1yDjMYC7BPvjoV0sj3i5eMmOrUg6v+/RUiXATk5FYfldz7lOP6gVYrQThrgY\n" +
-        "cOC0oqGfabvaE3nr8aQ8oaSC4/k1FLWphhX8QWR3JAw5XwnUzsdqJxJ+3g4vp4qN\n" +
-        "OuCj3f6QeT62/QNzpylUGdqVfdOisbxAjoFwePVdB3vygCUAL7+MXilzSbCLS6fj\n" +
-        "2R0r2BF9AgMBAAECggEASIkPkMCuw4WdTT44IwERus3IOIYOs2IP3BgEDyyvm4B6\n" +
-        "JP/iihDWKfA4zEl1Gqcni1RXMHswSglXra682J4kui02Ov+vzEeJIY37Ibn2YnP5\n" +
-        "ZjRT2s9GtI/S2o4hl8A/mQb2IMViFC+xKehTukhV4j5d6NPKk0XzLR7gcMjnYxwn\n" +
-        "l21fS6D2oM1xRG/di7sL+uLF8EXLRzfiWDNi12uQv4nwtxPKvuKhH6yzHt7YqMH0\n" +
-        "46pmDKDaxV4w1JdycjCb6NrCJOYZygoQobuZqOQ30UZoZsPJrtovkncFr1e+lNcO\n" +
-        "+aWDfOLCtTH046dEQh5oCShyXMybNlry/QHsOtHOwQKBgQDh2iIjs+FPpQy7Z3EX\n" +
-        "DGEvHYqPjrYO9an2KSRr1m9gzRlWYxKY46WmPKwjMerYtra0GP+TBHrgxsfO8tD2\n" +
-        "wUAII6sd1qup0a/Sutgf2JxVilLykd0+Ge4/Cs51tCdJ8EqDV2B6WhTewOY2EGvg\n" +
-        "JiKYkeNwgRX/9M9CFSAMAk0hUQKBgQDLJAartL3DoGUPjYtpJnfgGM23yAGl6G5r\n" +
-        "NSXDn80BiYIC1p0bG3N0xm3yAjqOtJAUj9jZbvDNbCe3GJfLARMr23legX4tRrgZ\n" +
-        "nEdKnAFKAKL01oM+A5/lHdkwaZI9yyv+hgSVdYzUjB8rDmzeVQzo1BT7vXypt2yV\n" +
-        "6O1OnUpCbQKBgA/0rzDChopv6KRcvHqaX0tK1P0rYeVQqb9ATNhpf9jg5Idb3HZ8\n" +
-        "rrk91BNwdVz2G5ZBpdynFl9G69rNAMJOCM4KZw5mmh4XOEq09Ivba8AHU7DbaTv3\n" +
-        "7QL7KnbaUWRB26HHzIMYVh0el6T+KADf8NXCiMTr+bfpfbL3dxoiF3zhAoGAbCJD\n" +
-        "Qse1dBs/cKYCHfkSOsI5T6kx52Tw0jS6Y4X/FOBjyqr/elyEexbdk8PH9Ar931Qr\n" +
-        "NKMvn8oA4iA/PRrXX7M2yi3YQrWwbkGYWYjtzrzEAdzmg+5eARKAeJrZ8/bg9l3U\n" +
-        "ttKaItJsDPlizn8rngy3FsJpR9aSAMK6/+wOiYkCgYEA1tZkI1rD1W9NYZtbI9BE\n" +
-        "qlJVFi2PBOJMKNuWdouPX3HLQ72GJSQff2BFzLTELjweVVJ0SvY4IipzpQOHQOBy\n" +
-        "5qh/p6izXJZh3IHtvwVBjHoEVplg1b2+I5e3jDCfqnwcQw82dW5SxOJMg1h/BD0I\n" +
-        "qAL3go42DYeYhu/WnECMeis=",
-
-        //
-        // EC private key related to cert endEntityCertStrs[2].
-        //
-        "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgGVc7hICpmp91jbYe\n" +
-        "nrr8nYHD37RZP3VENY+szuA7WjuhRANCAATn0wRE1OVVnV56mzxnc657lmSBB0+0\n" +
-        "P5YgTq2Pc9sgqnEY8PG980/3n0DJCMQr96FZBWsIyY2gSQjNj4ggGAHT",
-
-        //
-        // DSA private key related to cert endEntityCertStrs[3].
-        //
-        "MIICZQIBADCCAjoGByqGSM44BAEwggItAoIBAQCaVq+CgmsxyOpZFVwMTZ2ZYA9E\n" +
-        "SCfNC+d4QN5/rxymsPONLC86zlB4XLHvmJtp2jV7qM7+tbWmsIZYcMPWgD9Ofg+T\n" +
-        "e+7SdTHO+XWoBNz5olulRTk6nRu+notsKxBCyVX0V5GHsRvts/qClz+QcIHMSALV\n" +
-        "UIrumtxxdbL63pIw4ds0PeH5RtyR9JpS5pWxUk1MPUPoYSV9GPg2bPUEY99Ji8qi\n" +
-        "vA1kRTeBfAWC0OgBwbHu1zIKUukMd+pF/D/vKKovJ6I/sPiGXmUw2i4lYOUB0wWn\n" +
-        "QUyBLez1UMWKchyvpW0FYxMbv7j5zMcAH7d++vCWo3OEGfe4Uet6Q3/Dx83HAiEA\n" +
-        "mjtJp7XNrsgxbRDqETkHhv6zYH8Voo+gDgSO1m7XcH0CggEBAI5moswp++plZSBP\n" +
-        "Q9DdCNHt0AV13Toj1jf5M5DNmTX6P6/D/oRfi8Ui1fiCKFv+7lD0J2anCFUaLtu+\n" +
-        "j7v78gp5OChDp/n49K6DtKtZZRDmw/Bpm6LNdknmdN5kO5wVzbIXHTCCeNs/CJTF\n" +
-        "mSU5PvEaI4y3M5NraSgLPkq4gEv7/A8orGbKmj1Whj3F9t1Tosxdm/+WkPldMz2t\n" +
-        "gev+9RM2S6S9XoembRgwRaFVkpQmKoKpOoZcdqV47FLDq5BYH/5POeJ9wLuAHjxQ\n" +
-        "5CMKo4p/lW7BCd4kuGWFT+OFFXfG2v6EtlqFbXBiFWLxyMsOtkUqWARCqEHhyucl\n" +
-        "TSYlj60EIgIgLfA75+8KcKxdN8mr6gzGjQe7jPFGG42Ejhd7Q2F4wuw="
-        };
-
-    // Private key algorithm of endEntityPrivateKeys.
-    private final static String[] endEntityPrivateKeyAlgs = {
-        "EC",
-        "RSA",
-        "EC",
-        "DSA",
-        };
-
-    // Private key names of endEntityPrivateKeys.
-    private final static String[] endEntityPrivateKeyNames = {
-        "ecdsa",
-        "rsa",
-        "ec-rsa",
-        "dsa",
-        };
+    protected final static Cert[] END_ENTITY_CERTS = {
+            Cert.EE_ECDSA_SECP256R1,
+            Cert.EE_RSA_2048,
+            Cert.EE_EC_RSA_SECP256R1,
+            Cert.EE_DSA_2048 };
 
     /*
      * Create an instance of SSLContext with the specified trust/key materials.
      */
-    private SSLContext createSSLContext(
-            String[] trustedMaterials,
-            String[] keyMaterialCerts,
-            String[] keyMaterialKeys,
-            String[] keyMaterialKeyAlgs,
-            String[] keyMaterialKeyNames,
+    public static SSLContext createSSLContext(
+            Cert[] trustedCerts,
+            Cert[] endEntityCerts,
             ContextParameters params) throws Exception {
 
         KeyStore ts = null;     // trust store
@@ -697,51 +385,41 @@
 
         // Import the trused certs.
         ByteArrayInputStream is;
-        if (trustedMaterials != null && trustedMaterials.length != 0) {
+        if (trustedCerts != null && trustedCerts.length != 0) {
             ts = KeyStore.getInstance("JKS");
             ts.load(null, null);
 
-            Certificate[] trustedCert =
-                    new Certificate[trustedMaterials.length];
-            for (int i = 0; i < trustedMaterials.length; i++) {
-                String trustedCertStr = trustedMaterials[i];
-
-                is = new ByteArrayInputStream(trustedCertStr.getBytes());
+            Certificate[] trustedCert = new Certificate[trustedCerts.length];
+            for (int i = 0; i < trustedCerts.length; i++) {
+                is = new ByteArrayInputStream(trustedCerts[i].certStr.getBytes());
                 try {
                     trustedCert[i] = cf.generateCertificate(is);
                 } finally {
                     is.close();
                 }
 
-                ts.setCertificateEntry("trusted-cert-" + i, trustedCert[i]);
+                ts.setCertificateEntry(
+                        "trusted-cert-" + trustedCerts[i].name(), trustedCert[i]);
             }
         }
 
         // Import the key materials.
-        //
-        // Note that certification pathes bigger than one are not supported yet.
-        boolean hasKeyMaterials =
-            (keyMaterialCerts != null) && (keyMaterialCerts.length != 0) &&
-            (keyMaterialKeys != null) && (keyMaterialKeys.length != 0) &&
-            (keyMaterialKeyAlgs != null) && (keyMaterialKeyAlgs.length != 0) &&
-            (keyMaterialCerts.length == keyMaterialKeys.length) &&
-            (keyMaterialCerts.length == keyMaterialKeyAlgs.length);
-        if (hasKeyMaterials) {
+        if (endEntityCerts != null && endEntityCerts.length != 0) {
             ks = KeyStore.getInstance("JKS");
             ks.load(null, null);
 
-            for (int i = 0; i < keyMaterialCerts.length; i++) {
-                String keyCertStr = keyMaterialCerts[i];
-
+            for (int i = 0; i < endEntityCerts.length; i++) {
                 // generate the private key.
                 PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec(
-                    Base64.getMimeDecoder().decode(keyMaterialKeys[i]));
+                    Base64.getMimeDecoder().decode(endEntityCerts[i].privKeyStr));
                 KeyFactory kf =
-                    KeyFactory.getInstance(keyMaterialKeyAlgs[i]);
+                    KeyFactory.getInstance(
+                            endEntityCerts[i].keyAlgo);
                 PrivateKey priKey = kf.generatePrivate(priKeySpec);
 
                 // generate certificate chain
-                is = new ByteArrayInputStream(keyCertStr.getBytes());
+                is = new ByteArrayInputStream(
+                        endEntityCerts[i].certStr.getBytes());
                 Certificate keyCert = null;
                 try {
                     keyCert = cf.generateCertificate(is);
@@ -752,7 +430,7 @@
                 Certificate[] chain = new Certificate[] { keyCert };
 
                 // import the key entry.
-                ks.setKeyEntry("cert-" + keyMaterialKeyNames[i],
+                ks.setKeyEntry("cert-" + endEntityCerts[i].name(),
                         priKey, passphrase, chain);
             }
         }
@@ -763,7 +441,7 @@
         tmf.init(ts);
 
         SSLContext context = SSLContext.getInstance(params.contextProtocol);
-        if (hasKeyMaterials && ks != null) {
+        if (endEntityCerts != null && endEntityCerts.length != 0 && ks != null) {
             KeyManagerFactory kmf =
                     KeyManagerFactory.getInstance(params.kmAlgorithm);
             kmf.init(ks, passphrase);
@@ -928,4 +606,413 @@
         System.out.println(prefix + ": " + cause);
         cause.printStackTrace(System.out);
     }
+
+    public static enum Cert {
+
+        CA_ECDSA_SECP256R1(
+                "EC",
+                // SHA256withECDSA, curve secp256r1
+                // Validity
+                //     Not Before: May 22 07:18:16 2018 GMT
+                //     Not After : May 17 07:18:16 2038 GMT
+                // Subject Key Identifier:
+                //     60:CF:BD:73:FF:FA:1A:30:D2:A4:EC:D3:49:71:46:EF:1A:35:A0:86
+                "-----BEGIN CERTIFICATE-----\n" +
+                "MIIBvjCCAWOgAwIBAgIJAIvFG6GbTroCMAoGCCqGSM49BAMCMDsxCzAJBgNVBAYT\n" +
+                "AlVTMQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2VyaXZj\n" +
+                "ZTAeFw0xODA1MjIwNzE4MTZaFw0zODA1MTcwNzE4MTZaMDsxCzAJBgNVBAYTAlVT\n" +
+                "MQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2VyaXZjZTBZ\n" +
+                "MBMGByqGSM49AgEGCCqGSM49AwEHA0IABBz1WeVb6gM2mh85z3QlvaB/l11b5h0v\n" +
+                "LIzmkC3DKlVukZT+ltH2Eq1oEkpXuf7QmbM0ibrUgtjsWH3mULfmcWmjUDBOMB0G\n" +
+                "A1UdDgQWBBRgz71z//oaMNKk7NNJcUbvGjWghjAfBgNVHSMEGDAWgBRgz71z//oa\n" +
+                "MNKk7NNJcUbvGjWghjAMBgNVHRMEBTADAQH/MAoGCCqGSM49BAMCA0kAMEYCIQCG\n" +
+                "6wluh1r2/T6L31mZXRKf9JxeSf9pIzoLj+8xQeUChQIhAJ09wAi1kV8yePLh2FD9\n" +
+                "2YEHlSQUAbwwqCDEVB5KxaqP\n" +
+                "-----END CERTIFICATE-----",
+                "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg/HcHdoLJCdq3haVd\n" +
+                "XZTSKP00YzM3xX97l98vGL/RI1KhRANCAAQc9VnlW+oDNpofOc90Jb2gf5ddW+Yd\n" +
+                "LyyM5pAtwypVbpGU/pbR9hKtaBJKV7n+0JmzNIm61ILY7Fh95lC35nFp"),
+
+        CA_ECDSA_SECP384R1(
+                "EC",
+                // SHA384withECDSA, curve secp384r1
+                // Validity
+                //     Not Before: Jun 24 08:15:06 2019 GMT
+                //     Not After : Jun 19 08:15:06 2039 GMT
+                // Subject Key Identifier:
+                //     0a:93:a9:a0:bf:e7:d5:48:9d:4f:89:15:c6:51:98:80:05:51:4e:4e
+                "-----BEGIN CERTIFICATE-----\n" +
+                "MIICCDCCAY6gAwIBAgIUCpOpoL/n1UidT4kVxlGYgAVRTk4wCgYIKoZIzj0EAwMw\n" +
+                "OzELMAkGA1UEBhMCVVMxDTALBgNVBAoMBEphdmExHTAbBgNVBAsMFFN1bkpTU0Ug\n" +
+                "VGVzdCBTZXJpdmNlMB4XDTE5MDYyNDA4MTUwNloXDTM5MDYxOTA4MTUwNlowOzEL\n" +
+                "MAkGA1UEBhMCVVMxDTALBgNVBAoMBEphdmExHTAbBgNVBAsMFFN1bkpTU0UgVGVz\n" +
+                "dCBTZXJpdmNlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAENVQN1wXWFdgC6u/dDdiC\n" +
+                "y+WtMTF66oL/0BSm+1ZqsogamzCryawOcHgiuXgWzx5CQ3LuOC+tDFyXpGfHuCvb\n" +
+                "dkzxPrP5n9NrR8/uRPe5l1KOUbchviU8z9cTP+LZxnZDo1MwUTAdBgNVHQ4EFgQU\n" +
+                "SktSFArR1p/5mXV0kyo0RxIVa/UwHwYDVR0jBBgwFoAUSktSFArR1p/5mXV0kyo0\n" +
+                "RxIVa/UwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjBZvoNmq3/v\n" +
+                "RD2gBTyvxjS9h0rsMRLHDnvul/KWngytwGPTOBo0Y8ixQXSjdKoc3rkCMQDkiNgx\n" +
+                "IDxuHedmrLQKIPnVcthTmwv7//jHiqGoKofwChMo2a1P+DQdhszmeHD/ARQ=\n" +
+                "-----END CERTIFICATE-----",
+                "MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDChlbt0NF8oIKODSxn2\n" +
+                "WXCXuJm3z78LRkzYQS3Nx5NMjei5ytkFZz4qvD4XXMWlTEyhZANiAAQ1VA3XBdYV\n" +
+                "2ALq790N2ILL5a0xMXrqgv/QFKb7VmqyiBqbMKvJrA5weCK5eBbPHkJDcu44L60M\n" +
+                "XJekZ8e4K9t2TPE+s/mf02tHz+5E97mXUo5RtyG+JTzP1xM/4tnGdkM="),
+
+        CA_ECDSA_SECP521R1(
+                "EC",
+                // SHA512withECDSA, curve secp521r1
+                // Validity
+                //     Not Before: Jun 24 08:15:06 2019 GMT
+                //     Not After : Jun 19 08:15:06 2039 GMT
+                // Subject Key Identifier:
+                //     25:ca:68:76:6d:29:17:9b:71:78:45:2d:d4:c6:e4:5d:fe:25:ff:90
+                "-----BEGIN CERTIFICATE-----\n" +
+                "MIICUzCCAbSgAwIBAgIUJcpodm0pF5txeEUt1MbkXf4l/5AwCgYIKoZIzj0EAwQw\n" +
+                "OzELMAkGA1UEBhMCVVMxDTALBgNVBAoMBEphdmExHTAbBgNVBAsMFFN1bkpTU0Ug\n" +
+                "VGVzdCBTZXJpdmNlMB4XDTE5MDYyNDA4MTUwNloXDTM5MDYxOTA4MTUwNlowOzEL\n" +
+                "MAkGA1UEBhMCVVMxDTALBgNVBAoMBEphdmExHTAbBgNVBAsMFFN1bkpTU0UgVGVz\n" +
+                "dCBTZXJpdmNlMIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQAmFD5VmB2MdyJ6k+E\n" +
+                "eP4JncrE65ySL07gVmFwnr8otOt3NtRAyzmviMNNXXjo5R5NqNjKP4pr92JjT0sO\n" +
+                "D65yngkBtH151Ev/fiKPLxkXL9GzfKdWHVhDX7Zg6DUydzukzZV2/dIyloAIqwlz\n" +
+                "QVKJqT7RypDufdng8hnE9YfKo6ypZiujUzBRMB0GA1UdDgQWBBRAIrxa7WqtqUCe\n" +
+                "HFuKREDC92spvTAfBgNVHSMEGDAWgBRAIrxa7WqtqUCeHFuKREDC92spvTAPBgNV\n" +
+                "HRMBAf8EBTADAQH/MAoGCCqGSM49BAMEA4GMADCBiAJCAe22iirZnODCmlpxcv57\n" +
+                "3g5BEE60C+dtYmTqR4DtFyDaTRQ5CFf4ZxvQPIbD+SXi5Cbrl6qtrZG0cjUihPkC\n" +
+                "Hi1hAkIAiEcO7nMPgQLny+GrciojfN+bZXME/dPz6KHBm/89f8Me+jawVnv6y+df\n" +
+                "2Sbafh1KV6ntWQtB4bK3MXV8Ym9Eg1I=\n" +
+                "-----END CERTIFICATE-----",
+                "MIHuAgEAMBAGByqGSM49AgEGBSuBBAAjBIHWMIHTAgEBBEIAV8dZszV6+nLw3LeA\n" +
+                "Q+qLJLGaqyjlsQkaopCPcmoRdy1HX6AzB/YnKsPkHp/9DQN6A2JgUhFG5B0XvKSk\n" +
+                "BqNNuSGhgYkDgYYABACYUPlWYHYx3InqT4R4/gmdysTrnJIvTuBWYXCevyi063c2\n" +
+                "1EDLOa+Iw01deOjlHk2o2Mo/imv3YmNPSw4PrnKeCQG0fXnUS/9+Io8vGRcv0bN8\n" +
+                "p1YdWENftmDoNTJ3O6TNlXb90jKWgAirCXNBUompPtHKkO592eDyGcT1h8qjrKlm\n" +
+                "Kw=="),
+
+        CA_RSA_2048(
+                "RSA",
+                // SHA256withRSA, 2048 bits
+                // Validity
+                //     Not Before: May 22 07:18:16 2018 GMT
+                //     Not After : May 17 07:18:16 2038 GMT
+                // Subject Key Identifier:
+                //     0D:DD:93:C9:FE:4B:BD:35:B7:E8:99:78:90:FB:DB:5A:3D:DB:15:4C
+                "-----BEGIN CERTIFICATE-----\n" +
+                "MIIDSTCCAjGgAwIBAgIJAI4ZF3iy8zG+MA0GCSqGSIb3DQEBCwUAMDsxCzAJBgNV\n" +
+                "BAYTAlVTMQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2Vy\n" +
+                "aXZjZTAeFw0xODA1MjIwNzE4MTZaFw0zODA1MTcwNzE4MTZaMDsxCzAJBgNVBAYT\n" +
+                "AlVTMQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2VyaXZj\n" +
+                "ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALpMcY7aWieXDEM1/YJf\n" +
+                "JW27b4nRIFZyEYhEloyGsKTuQiiQjc8cqRZFNXe2vwziDB4IyTEl0Hjl5QF6ZaQE\n" +
+                "huPzzwvQm1pv64KrRXrmj3FisQK8B5OWLty9xp6xDqsaMRoyObLK+oIb20T5fSlE\n" +
+                "evmo1vYjnh8CX0Yzx5Gr5ye6YSEHQvYOWEws8ad17OlyToR2KMeC8w4qo6rs59pW\n" +
+                "g7Mxn9vo22ImDzrtAbTbXbCias3xlE0Bp0h5luyf+5U4UgksoL9B9r2oP4GrLNEV\n" +
+                "oJk57t8lwaR0upiv3CnS8LcJELpegZub5ggqLY8ZPYFQPjlK6IzLOm6rXPgZiZ3m\n" +
+                "RL0CAwEAAaNQME4wHQYDVR0OBBYEFA3dk8n+S701t+iZeJD721o92xVMMB8GA1Ud\n" +
+                "IwQYMBaAFA3dk8n+S701t+iZeJD721o92xVMMAwGA1UdEwQFMAMBAf8wDQYJKoZI\n" +
+                "hvcNAQELBQADggEBAJTRC3rKUUhVH07/1+stUungSYgpM08dY4utJq0BDk36BbmO\n" +
+                "0AnLDMbkwFdHEoqF6hQIfpm7SQTmXk0Fss6Eejm8ynYr6+EXiRAsaXOGOBCzF918\n" +
+                "/RuKOzqABfgSU4UBKECLM5bMfQTL60qx+HdbdVIpnikHZOFfmjCDVxoHsGyXc1LW\n" +
+                "Jhkht8IGOgc4PMGvyzTtRFjz01kvrVQZ75aN2E0GQv6dCxaEY0i3ypSzjUWAKqDh\n" +
+                "3e2OLwUSvumcdaxyCdZAOUsN6pDBQ+8VRG7KxnlRlY1SMEk46QgQYLbPDe/+W/yH\n" +
+                "ca4PejicPeh+9xRAwoTpiE2gulfT7Lm+fVM7Ruc=\n" +
+                "-----END CERTIFICATE-----",
+                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC6THGO2lonlwxD\n" +
+                "Nf2CXyVtu2+J0SBWchGIRJaMhrCk7kIokI3PHKkWRTV3tr8M4gweCMkxJdB45eUB\n" +
+                "emWkBIbj888L0Jtab+uCq0V65o9xYrECvAeTli7cvcaesQ6rGjEaMjmyyvqCG9tE\n" +
+                "+X0pRHr5qNb2I54fAl9GM8eRq+cnumEhB0L2DlhMLPGndezpck6EdijHgvMOKqOq\n" +
+                "7OfaVoOzMZ/b6NtiJg867QG0212womrN8ZRNAadIeZbsn/uVOFIJLKC/Qfa9qD+B\n" +
+                "qyzRFaCZOe7fJcGkdLqYr9wp0vC3CRC6XoGbm+YIKi2PGT2BUD45SuiMyzpuq1z4\n" +
+                "GYmd5kS9AgMBAAECggEAFHSoU2MuWwJ+2jJnb5U66t2V1bAcuOE1g5zkWvG/G5z9\n" +
+                "rq6Qo5kmB8f5ovdx6tw3MGUOklLwnRXBG3RxDJ1iokz3AvkY1clMNsDPlDsUrQKF\n" +
+                "JSO4QUBQTPSZhnsyfR8XHSU+qJ8Y+ohMfzpVv95BEoCzebtXdVgxVegBlcEmVHo2\n" +
+                "kMmkRN+bYNsr8eb2r+b0EpyumS39ZgKYh09+cFb78y3T6IFMGcVJTP6nlGBFkmA/\n" +
+                "25pYeCF2tSki08qtMJZQAvKfw0Kviibk7ZxRbJqmc7B1yfnOEHP6ftjuvKl2+RP/\n" +
+                "+5P5f8CfIP6gtA0LwSzAqQX/hfIKrGV5j0pCqrD0kQKBgQDeNR6Xi4sXVq79lihO\n" +
+                "a1bSeV7r8yoQrS8x951uO+ox+UIZ1MsAULadl7zB/P0er92p198I9M/0Jth3KBuS\n" +
+                "zj45mucvpiiGvmQlMKMEfNq4nN7WHOu55kufPswQB2mR4J3xmwI+4fM/nl1zc82h\n" +
+                "De8JSazRldJXNhfx0RGFPmgzbwKBgQDWoVXrXLbCAn41oVnWB8vwY9wjt92ztDqJ\n" +
+                "HMFA/SUohjePep9UDq6ooHyAf/Lz6oE5NgeVpPfTDkgvrCFVKnaWdwALbYoKXT2W\n" +
+                "9FlyJox6eQzrtHAacj3HJooXWuXlphKSizntfxj3LtMR9BmrmRJOfK+SxNOVJzW2\n" +
+                "+MowT20EkwKBgHmpB8jdZBgxI7o//m2BI5Y1UZ1KE5vx1kc7VXzHXSBjYqeV9FeF\n" +
+                "2ZZLP9POWh/1Fh4pzTmwIDODGT2UPhSQy0zq3O0fwkyT7WzXRknsuiwd53u/dejg\n" +
+                "iEL2NPAJvulZ2+AuiHo5Z99LK8tMeidV46xoJDDUIMgTG+UQHNGhK5gNAoGAZn/S\n" +
+                "Cn7SgMC0CWSvBHnguULXZO9wH1wZAFYNLL44OqwuaIUFBh2k578M9kkke7woTmwx\n" +
+                "HxQTjmWpr6qimIuY6q6WBN8hJ2Xz/d1fwhYKzIp20zHuv5KDUlJjbFfqpsuy3u1C\n" +
+                "kts5zwI7pr1ObRbDGVyOdKcu7HI3QtR5qqyjwaUCgYABo7Wq6oHva/9V34+G3Goh\n" +
+                "63bYGUnRw2l5BD11yhQv8XzGGZFqZVincD8gltNThB0Dc/BI+qu3ky4YdgdZJZ7K\n" +
+                "z51GQGtaHEbrHS5caV79yQ8QGY5mUVH3E+VXSxuIqb6pZq2DH4sTAEFHyncddmOH\n" +
+                "zoXBInYwRG9KE/Bw5elhUw=="),
+
+        CA_DSA_2048(
+                "DSA",
+                // SHA256withDSA, 2048 bits
+                // Validity
+                //     Not Before: May 22 07:18:18 2018 GMT
+                //     Not After : May 17 07:18:18 2038 GMT
+                // Subject Key Identifier:
+                //     76:66:9E:F7:3B:DD:45:E5:3B:D9:72:3C:3F:F0:54:39:86:31:26:53
+                "-----BEGIN CERTIFICATE-----\n" +
+                "MIIErjCCBFSgAwIBAgIJAOktYLNCbr02MAsGCWCGSAFlAwQDAjA7MQswCQYDVQQG\n" +
+                "EwJVUzENMAsGA1UECgwESmF2YTEdMBsGA1UECwwUU3VuSlNTRSBUZXN0IFNlcml2\n" +
+                "Y2UwHhcNMTgwNTIyMDcxODE4WhcNMzgwNTE3MDcxODE4WjA7MQswCQYDVQQGEwJV\n" +
+                "UzENMAsGA1UECgwESmF2YTEdMBsGA1UECwwUU3VuSlNTRSBUZXN0IFNlcml2Y2Uw\n" +
+                "ggNHMIICOQYHKoZIzjgEATCCAiwCggEBAO5GyPhSm0ze3LSu+gicdULLj05iOfTL\n" +
+                "UvZQ29sYz41zmqrLBQbdKiHqgJu2Re9sgTb5suLNjF047TOLPnU3jhPtWm2X8Xzi\n" +
+                "VGIcHym/Q/MeZxStt/88seqroI3WOKzIML2GcrishT+lcGrtH36Tf1+ue2Snn3PS\n" +
+                "WyxygNqPjllP5uUjYmFLvAf4QLMldkd/D2VxcwsHjB8y5iUZsXezc/LEhRZS/02m\n" +
+                "ivqlRw3AMkq/OVe/ZtxFWsP0nsfxEGdZuaUFpppGfixxFvymrB3+J51cTt+pZBDq\n" +
+                "D2y0DYfc+88iCs4jwHTfcDIpLb538HBjBj2rEgtQESQmB0ooD/+wsPsCIQC1bYch\n" +
+                "gElNtDYL3FgpLgNSUYp7gIWv9ehaC7LO2z7biQKCAQBitvFOnDkUja8NAF7lDpOV\n" +
+                "b5ipQ8SicBLW3kQamxhyuyxgZyy/PojZ/oPorkqW/T/A0rhnG6MssEpAtdiwVB+c\n" +
+                "rBYGo3bcwmExJhdOJ6dYuKFppPWhCwKMHs9npK+lqBMl8l5j58xlcFeC7ZfGf8GY\n" +
+                "GkhFW0c44vEQhMMbac6ZTTP4mw+1t7xJfmDMlLEyIpTXaAAk8uoVLWzQWnR40sHi\n" +
+                "ybvS0u3JxQkb7/y8tOOZu8qlz/YOS7lQ6UxUGX27Ce1E0+agfPphetoRAlS1cezq\n" +
+                "Wa7r64Ga0nkj1kwkcRqjgTiJx0NwnUXr78VAXFhVF95+O3lfqhvdtEGtkhDGPg7N\n" +
+                "A4IBBgACggEBAMmSHQK0w2i+iqUjOPzn0yNEZrzepLlLeQ1tqtn0xnlv5vBAeefD\n" +
+                "Pm9dd3tZOjufVWP7hhEz8xPobb1CS4e3vuQiv5UBfhdPL3f3l9T7JMAKPH6C9Vve\n" +
+                "OQXE5eGqbjsySbcmseHoYUt1WCSnSda1opX8zchX04e7DhGfE2/L9flpYEoSt8lI\n" +
+                "vMNjgOwvKdW3yvPt1/eBBHYNFG5gWPv/Q5KoyCtHS03uqGm4rNc/wZTIEEfd66C+\n" +
+                "QRaUltjOaHmtwOdDHaNqwhYZSVOip+Mo+TfyzHFREcdHLapo7ZXqbdYkRGxRR3d+\n" +
+                "3DfHaraJO0OKoYlPkr3JMvM/MSGR9AnZOcejUDBOMB0GA1UdDgQWBBR2Zp73O91F\n" +
+                "5TvZcjw/8FQ5hjEmUzAfBgNVHSMEGDAWgBR2Zp73O91F5TvZcjw/8FQ5hjEmUzAM\n" +
+                "BgNVHRMEBTADAQH/MAsGCWCGSAFlAwQDAgNHADBEAiBzriYE41M2y9Hy5ppkL0Qn\n" +
+                "dIlNc8JhXT/PHW7GDtViagIgMko8Qoj9gDGPK3+O9E8DC3wGiiF9CObM4LN387ok\n" +
+                "J+g=\n" +
+                "-----END CERTIFICATE-----",
+                "MIICZQIBADCCAjkGByqGSM44BAEwggIsAoIBAQDuRsj4UptM3ty0rvoInHVCy49O" +
+                "Yjn0y1L2UNvbGM+Nc5qqywUG3Soh6oCbtkXvbIE2+bLizYxdOO0ziz51N44T7Vpt" +
+                "l/F84lRiHB8pv0PzHmcUrbf/PLHqq6CN1jisyDC9hnK4rIU/pXBq7R9+k39frntk" +
+                "p59z0lsscoDaj45ZT+blI2JhS7wH+ECzJXZHfw9lcXMLB4wfMuYlGbF3s3PyxIUW" +
+                "Uv9Npor6pUcNwDJKvzlXv2bcRVrD9J7H8RBnWbmlBaaaRn4scRb8pqwd/iedXE7f" +
+                "qWQQ6g9stA2H3PvPIgrOI8B033AyKS2+d/BwYwY9qxILUBEkJgdKKA//sLD7AiEA" +
+                "tW2HIYBJTbQ2C9xYKS4DUlGKe4CFr/XoWguyzts+24kCggEAYrbxTpw5FI2vDQBe" +
+                "5Q6TlW+YqUPEonAS1t5EGpsYcrssYGcsvz6I2f6D6K5Klv0/wNK4ZxujLLBKQLXY" +
+                "sFQfnKwWBqN23MJhMSYXTienWLihaaT1oQsCjB7PZ6SvpagTJfJeY+fMZXBXgu2X" +
+                "xn/BmBpIRVtHOOLxEITDG2nOmU0z+JsPtbe8SX5gzJSxMiKU12gAJPLqFS1s0Fp0" +
+                "eNLB4sm70tLtycUJG+/8vLTjmbvKpc/2Dku5UOlMVBl9uwntRNPmoHz6YXraEQJU" +
+                "tXHs6lmu6+uBmtJ5I9ZMJHEao4E4icdDcJ1F6+/FQFxYVRfefjt5X6ob3bRBrZIQ" +
+                "xj4OzQQjAiEAsceWOM8do4etxp2zgnoNXV8PUUyqWhz1+0srcKV7FR4="),
+
+        EE_ECDSA_SECP256R1(
+                "EC",
+                // SHA256withECDSA, curve secp256r1
+                // Validity
+                //     Not Before: May 22 07:18:16 2018 GMT
+                //     Not After : May 17 07:18:16 2038 GMT
+                // Authority Key Identifier:
+                //     60:CF:BD:73:FF:FA:1A:30:D2:A4:EC:D3:49:71:46:EF:1A:35:A0:86
+                "-----BEGIN CERTIFICATE-----\n" +
+                "MIIBqjCCAVCgAwIBAgIJAPLY8qZjgNRAMAoGCCqGSM49BAMCMDsxCzAJBgNVBAYT\n" +
+                "AlVTMQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2VyaXZj\n" +
+                "ZTAeFw0xODA1MjIwNzE4MTZaFw0zODA1MTcwNzE4MTZaMFUxCzAJBgNVBAYTAlVT\n" +
+                "MQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2VyaXZjZTEY\n" +
+                "MBYGA1UEAwwPUmVncmVzc2lvbiBUZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcD\n" +
+                "QgAEb+9n05qfXnfHUb0xtQJNS4JeSi6IjOfW5NqchvKnfJey9VkJzR7QHLuOESdf\n" +
+                "xlR7q8YIWgih3iWLGfB+wxHiOqMjMCEwHwYDVR0jBBgwFoAUYM+9c//6GjDSpOzT\n" +
+                "SXFG7xo1oIYwCgYIKoZIzj0EAwIDSAAwRQIgWpRegWXMheiD3qFdd8kMdrkLxRbq\n" +
+                "1zj8nQMEwFTUjjQCIQDRIrAjZX+YXHN9b0SoWWLPUq0HmiFIi8RwMnO//wJIGQ==\n" +
+                "-----END CERTIFICATE-----",
+                "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgn5K03bpTLjEtFQRa\n" +
+                "JUtx22gtmGEvvSUSQdimhGthdtihRANCAARv72fTmp9ed8dRvTG1Ak1Lgl5KLoiM\n" +
+                "59bk2pyG8qd8l7L1WQnNHtAcu44RJ1/GVHurxghaCKHeJYsZ8H7DEeI6"),
+
+        EE_ECDSA_SECP384R1(
+                "EC",
+                // SHA384withECDSA, curve secp384r1
+                // Validity
+                //     Not Before: Jun 24 08:15:06 2019 GMT
+                //     Not After : Jun 19 08:15:06 2039 GMT
+                // Authority Key Identifier:
+                //     40:2D:AA:EE:66:AA:33:27:AD:9B:5D:52:9B:60:67:6A:2B:AD:52:D2
+                "-----BEGIN CERTIFICATE-----\n" +
+                "MIICEjCCAZegAwIBAgIUS3F0AqAXWRg07CnbknJzxofyBQMwCgYIKoZIzj0EAwMw\n" +
+                "OzELMAkGA1UEBhMCVVMxDTALBgNVBAoMBEphdmExHTAbBgNVBAsMFFN1bkpTU0Ug\n" +
+                "VGVzdCBTZXJpdmNlMB4XDTE5MDYyNDA4MTUwNloXDTM5MDYxOTA4MTUwNlowVTEL\n" +
+                "MAkGA1UEBhMCVVMxDTALBgNVBAoMBEphdmExHTAbBgNVBAsMFFN1bkpTU0UgVGVz\n" +
+                "dCBTZXJpdmNlMRgwFgYDVQQDDA9SZWdyZXNzaW9uIFRlc3QwdjAQBgcqhkjOPQIB\n" +
+                "BgUrgQQAIgNiAARqElz8b6T07eyKomIinhztV3/3XBk9bKGtJ0W+JOltjuhMmP/w\n" +
+                "G8ASSevpgqgpi6EzpBZaaJxE3zNfkNnxXOZmQi2Ypd1uK0zRdbEOKg0XOcTTZwEj\n" +
+                "iLjYmt3O0pwpklijQjBAMB0GA1UdDgQWBBRALaruZqozJ62bXVKbYGdqK61S0jAf\n" +
+                "BgNVHSMEGDAWgBRKS1IUCtHWn/mZdXSTKjRHEhVr9TAKBggqhkjOPQQDAwNpADBm\n" +
+                "AjEArVDFKf48xijN6huVUJzKCOP0zlWB5Js+DItIkZmLQuhciPLhLIB/rChf3Y4C\n" +
+                "xuP4AjEAmfLhQRI0O3pifpYzYSVh2G7/jHNG4eO+2dvgAcU+Lh2IIj/cpLaPFSvL\n" +
+                "J8FXY9Nj\n" +
+                "-----END CERTIFICATE-----",
+                "MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDASuI9EtK29APXPipkc\n" +
+                "qDA+qwlewMjv/OcjUJ77kP1Vz62oVF9iY9SRIyFIUju8wt+hZANiAARqElz8b6T0\n" +
+                "7eyKomIinhztV3/3XBk9bKGtJ0W+JOltjuhMmP/wG8ASSevpgqgpi6EzpBZaaJxE\n" +
+                "3zNfkNnxXOZmQi2Ypd1uK0zRdbEOKg0XOcTTZwEjiLjYmt3O0pwpklg="),
+
+        EE_ECDSA_SECP521R1(
+                "EC",
+                // SHA512withECDSA, curve secp521r1
+                // Validity
+                //     Not Before: Jun 24 08:15:06 2019 GMT
+                //     Not After : Jun 19 08:15:06 2039 GMT
+                // Authority Key Identifier:
+                //     7B:AA:79:A4:49:DD:59:34:F0:86:6C:51:C7:30:F4:CE:C5:81:8A:28
+                "-----BEGIN CERTIFICATE-----\n" +
+                "MIICXDCCAb2gAwIBAgIUck4QTsbHNqUfPxfGPJLYbedFPdswCgYIKoZIzj0EAwQw\n" +
+                "OzELMAkGA1UEBhMCVVMxDTALBgNVBAoMBEphdmExHTAbBgNVBAsMFFN1bkpTU0Ug\n" +
+                "VGVzdCBTZXJpdmNlMB4XDTE5MDYyNDA4MTUwNloXDTM5MDYxOTA4MTUwNlowVTEL\n" +
+                "MAkGA1UEBhMCVVMxDTALBgNVBAoMBEphdmExHTAbBgNVBAsMFFN1bkpTU0UgVGVz\n" +
+                "dCBTZXJpdmNlMRgwFgYDVQQDDA9SZWdyZXNzaW9uIFRlc3QwgZswEAYHKoZIzj0C\n" +
+                "AQYFK4EEACMDgYYABAGa2zDLhYQHHCLI3YBqFYJTzrnDIjzwXrxhcRTS8DYkcrjZ\n" +
+                "+Fih1YyNhix0sdjH+3EqElXAHHuVzn3n3hPOtQCWlQCICkErB34S0cvmtRkeW8Fi\n" +
+                "hrR5tvJEzEZjPSgwn81kKyhV2L70je6i7Cw884Va8bODckpgw0vTmbQb7T9dupkv\n" +
+                "1aNCMEAwHQYDVR0OBBYEFHuqeaRJ3Vk08IZsUccw9M7FgYooMB8GA1UdIwQYMBaA\n" +
+                "FEAivFrtaq2pQJ4cW4pEQML3aym9MAoGCCqGSM49BAMEA4GMADCBiAJCAb33KHdY\n" +
+                "WDbusORWoY8Euglpd5zsF15hJsk7wtpD5HST1/NWmdCx405w+TV6a9Gr4VPHeaIQ\n" +
+                "99i/+f237ALL5p6IAkIBbwwFL1vt3c/bx+niyuffQPNjly80rdC9puqAqriSiboS\n" +
+                "efhxjidJ9HLaIRCMEPyd6vAsC8mO8YvL1uCuEQLsiGM=\n" +
+                "-----END CERTIFICATE-----",
+                "MIHuAgEAMBAGByqGSM49AgEGBSuBBAAjBIHWMIHTAgEBBEIB8C/2OX2Dt9vFszzV\n" +
+                "hcAe0CbkMlvu9uQ/L7Vz88heuIj0rUZIPGshvgIJt1hCMT8HZxYHvDa4lbUvqjFB\n" +
+                "+zafvPWhgYkDgYYABAGa2zDLhYQHHCLI3YBqFYJTzrnDIjzwXrxhcRTS8DYkcrjZ\n" +
+                "+Fih1YyNhix0sdjH+3EqElXAHHuVzn3n3hPOtQCWlQCICkErB34S0cvmtRkeW8Fi\n" +
+                "hrR5tvJEzEZjPSgwn81kKyhV2L70je6i7Cw884Va8bODckpgw0vTmbQb7T9dupkv\n" +
+                "1Q=="),
+
+        EE_RSA_2048(
+                "RSA",
+                // SHA256withRSA, 2048 bits
+                // Validity
+                //     Not Before: May 22 07:18:16 2018 GMT
+                //     Not After : May 17 07:18:16 2038 GMT
+                // Authority Key Identifier:
+                //     0D:DD:93:C9:FE:4B:BD:35:B7:E8:99:78:90:FB:DB:5A:3D:DB:15:4C
+                "-----BEGIN CERTIFICATE-----\n" +
+                "MIIDNjCCAh6gAwIBAgIJAO2+yPcFryUTMA0GCSqGSIb3DQEBCwUAMDsxCzAJBgNV\n" +
+                "BAYTAlVTMQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2Vy\n" +
+                "aXZjZTAeFw0xODA1MjIwNzE4MTZaFw0zODA1MTcwNzE4MTZaMFUxCzAJBgNVBAYT\n" +
+                "AlVTMQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2VyaXZj\n" +
+                "ZTEYMBYGA1UEAwwPUmVncmVzc2lvbiBUZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOC\n" +
+                "AQ8AMIIBCgKCAQEAszfBobWfZIp8AgC6PiWDDavP65mSvgCXUGxACbxVNAfkLhNR\n" +
+                "QOsHriRB3X1Q3nvO9PetC6wKlvE9jlnDDj7D+1j1r1CHO7ms1fq8rfcQYdkanDtu\n" +
+                "4AlHo8v+SSWX16MIXFRYDj2VVHmyPtgbltcg4zGAuwT746FdLI94uXjJjq1IOr/v\n" +
+                "0VIlwE5ORWH5Xc+5Tj+oFWK0E4a4GHDgtKKhn2m72hN56/GkPKGkguP5NRS1qYYV\n" +
+                "/EFkdyQMOV8J1M7HaicSft4OL6eKjTrgo93+kHk+tv0Dc6cpVBnalX3TorG8QI6B\n" +
+                "cHj1XQd78oAlAC+/jF4pc0mwi0un49kdK9gRfQIDAQABoyMwITAfBgNVHSMEGDAW\n" +
+                "gBQN3ZPJ/ku9NbfomXiQ+9taPdsVTDANBgkqhkiG9w0BAQsFAAOCAQEApXS0nKwm\n" +
+                "Kp8gpmO2yG1rpd1+2wBABiMU4JZaTqmma24DQ3RzyS+V2TeRb29dl5oTUEm98uc0\n" +
+                "GPZvhK8z5RFr4YE17dc04nI/VaNDCw4y1NALXGs+AHkjoPjLyGbWpi1S+gfq2sNB\n" +
+                "Ekkjp6COb/cb9yiFXOGVls7UOIjnVZVd0r7KaPFjZhYh82/f4PA/A1SnIKd1+nfH\n" +
+                "2yk7mSJNC7Z3qIVDL8MM/jBVwiC3uNe5GPB2uwhd7k5LGAVN3j4HQQGB0Sz+VC1h\n" +
+                "92oi6xDa+YBva2fvHuCd8P50DDjxmp9CemC7rnZ5j8egj88w14X44Xjb/Fd/ApG9\n" +
+                "e57NnbT7KM+Grw==\n" +
+                "-----END CERTIFICATE-----",
+                "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCzN8GhtZ9kinwC\n" +
+                "ALo+JYMNq8/rmZK+AJdQbEAJvFU0B+QuE1FA6weuJEHdfVDee870960LrAqW8T2O\n" +
+                "WcMOPsP7WPWvUIc7uazV+ryt9xBh2RqcO27gCUejy/5JJZfXowhcVFgOPZVUebI+\n" +
+                "2BuW1yDjMYC7BPvjoV0sj3i5eMmOrUg6v+/RUiXATk5FYfldz7lOP6gVYrQThrgY\n" +
+                "cOC0oqGfabvaE3nr8aQ8oaSC4/k1FLWphhX8QWR3JAw5XwnUzsdqJxJ+3g4vp4qN\n" +
+                "OuCj3f6QeT62/QNzpylUGdqVfdOisbxAjoFwePVdB3vygCUAL7+MXilzSbCLS6fj\n" +
+                "2R0r2BF9AgMBAAECggEASIkPkMCuw4WdTT44IwERus3IOIYOs2IP3BgEDyyvm4B6\n" +
+                "JP/iihDWKfA4zEl1Gqcni1RXMHswSglXra682J4kui02Ov+vzEeJIY37Ibn2YnP5\n" +
+                "ZjRT2s9GtI/S2o4hl8A/mQb2IMViFC+xKehTukhV4j5d6NPKk0XzLR7gcMjnYxwn\n" +
+                "l21fS6D2oM1xRG/di7sL+uLF8EXLRzfiWDNi12uQv4nwtxPKvuKhH6yzHt7YqMH0\n" +
+                "46pmDKDaxV4w1JdycjCb6NrCJOYZygoQobuZqOQ30UZoZsPJrtovkncFr1e+lNcO\n" +
+                "+aWDfOLCtTH046dEQh5oCShyXMybNlry/QHsOtHOwQKBgQDh2iIjs+FPpQy7Z3EX\n" +
+                "DGEvHYqPjrYO9an2KSRr1m9gzRlWYxKY46WmPKwjMerYtra0GP+TBHrgxsfO8tD2\n" +
+                "wUAII6sd1qup0a/Sutgf2JxVilLykd0+Ge4/Cs51tCdJ8EqDV2B6WhTewOY2EGvg\n" +
+                "JiKYkeNwgRX/9M9CFSAMAk0hUQKBgQDLJAartL3DoGUPjYtpJnfgGM23yAGl6G5r\n" +
+                "NSXDn80BiYIC1p0bG3N0xm3yAjqOtJAUj9jZbvDNbCe3GJfLARMr23legX4tRrgZ\n" +
+                "nEdKnAFKAKL01oM+A5/lHdkwaZI9yyv+hgSVdYzUjB8rDmzeVQzo1BT7vXypt2yV\n" +
+                "6O1OnUpCbQKBgA/0rzDChopv6KRcvHqaX0tK1P0rYeVQqb9ATNhpf9jg5Idb3HZ8\n" +
+                "rrk91BNwdVz2G5ZBpdynFl9G69rNAMJOCM4KZw5mmh4XOEq09Ivba8AHU7DbaTv3\n" +
+                "7QL7KnbaUWRB26HHzIMYVh0el6T+KADf8NXCiMTr+bfpfbL3dxoiF3zhAoGAbCJD\n" +
+                "Qse1dBs/cKYCHfkSOsI5T6kx52Tw0jS6Y4X/FOBjyqr/elyEexbdk8PH9Ar931Qr\n" +
+                "NKMvn8oA4iA/PRrXX7M2yi3YQrWwbkGYWYjtzrzEAdzmg+5eARKAeJrZ8/bg9l3U\n" +
+                "ttKaItJsDPlizn8rngy3FsJpR9aSAMK6/+wOiYkCgYEA1tZkI1rD1W9NYZtbI9BE\n" +
+                "qlJVFi2PBOJMKNuWdouPX3HLQ72GJSQff2BFzLTELjweVVJ0SvY4IipzpQOHQOBy\n" +
+                "5qh/p6izXJZh3IHtvwVBjHoEVplg1b2+I5e3jDCfqnwcQw82dW5SxOJMg1h/BD0I\n" +
+                "qAL3go42DYeYhu/WnECMeis="),
+
+        EE_EC_RSA_SECP256R1(
+                "EC",
+                // SHA256withRSA, curve secp256r1
+                // Validity
+                //     Not Before: May 22 07:18:16 2018 GMT
+                //     Not After : May 21 07:18:16 2028 GMT
+                // Authority Key Identifier:
+                //     0D:DD:93:C9:FE:4B:BD:35:B7:E8:99:78:90:FB:DB:5A:3D:DB:15:4C
+                "-----BEGIN CERTIFICATE-----\n" +
+                "MIICazCCAVOgAwIBAgIJAO2+yPcFryUUMA0GCSqGSIb3DQEBCwUAMDsxCzAJBgNV\n" +
+                "BAYTAlVTMQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2Vy\n" +
+                "aXZjZTAeFw0xODA1MjIwNzE4MTZaFw0yODA1MjEwNzE4MTZaMFUxCzAJBgNVBAYT\n" +
+                "AlVTMQ0wCwYDVQQKDARKYXZhMR0wGwYDVQQLDBRTdW5KU1NFIFRlc3QgU2VyaXZj\n" +
+                "ZTEYMBYGA1UEAwwPUmVncmVzc2lvbiBUZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0D\n" +
+                "AQcDQgAE59MERNTlVZ1eeps8Z3Oue5ZkgQdPtD+WIE6tj3PbIKpxGPDxvfNP959A\n" +
+                "yQjEK/ehWQVrCMmNoEkIzY+IIBgB06MjMCEwHwYDVR0jBBgwFoAUDd2Tyf5LvTW3\n" +
+                "6Jl4kPvbWj3bFUwwDQYJKoZIhvcNAQELBQADggEBAFOTVEqs70ykhZiIdrEsF1Ra\n" +
+                "I3B2rLvwXZk52uSltk2/bzVvewA577ZCoxQ1pL7ynkisPfBN1uVYtHjM1VA3RC+4\n" +
+                "+TAK78dnI7otYjWoHp5rvs4l6c/IbOspS290IlNuDUxMErEm5wxIwj+Aukx/1y68\n" +
+                "hOyCvHBLMY2c1LskH1MMBbDuS1aI+lnGpToi+MoYObxGcV458vxuT8+wwV8Fkpvd\n" +
+                "ll8IIFmeNPRv+1E+lXbES6CSNCVaZ/lFhPgdgYKleN7sfspiz50DG4dqafuEAaX5\n" +
+                "xaK1NWXJxTRz0ROH/IUziyuDW6jphrlgit4+3NCzp6vP9hAJQ8Vhcj0n15BKHIQ=\n" +
+                "-----END CERTIFICATE-----",
+                "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgGVc7hICpmp91jbYe\n" +
+                "nrr8nYHD37RZP3VENY+szuA7WjuhRANCAATn0wRE1OVVnV56mzxnc657lmSBB0+0\n" +
+                "P5YgTq2Pc9sgqnEY8PG980/3n0DJCMQr96FZBWsIyY2gSQjNj4ggGAHT"),
+
+        EE_DSA_2048(
+                "DSA",
+                // SHA256withDSA, 2048 bits
+                // Validity
+                //     Not Before: May 22 07:18:20 2018 GMT
+                //     Not After : May 17 07:18:20 2038 GMT
+                // Authority Key Identifier:
+                //     76:66:9E:F7:3B:DD:45:E5:3B:D9:72:3C:3F:F0:54:39:86:31:26:53
+                "-----BEGIN CERTIFICATE-----\n" +
+                "MIIEnDCCBEGgAwIBAgIJAP/jh1qVhNVjMAsGCWCGSAFlAwQDAjA7MQswCQYDVQQG\n" +
+                "EwJVUzENMAsGA1UECgwESmF2YTEdMBsGA1UECwwUU3VuSlNTRSBUZXN0IFNlcml2\n" +
+                "Y2UwHhcNMTgwNTIyMDcxODIwWhcNMzgwNTE3MDcxODIwWjBVMQswCQYDVQQGEwJV\n" +
+                "UzENMAsGA1UECgwESmF2YTEdMBsGA1UECwwUU3VuSlNTRSBUZXN0IFNlcml2Y2Ux\n" +
+                "GDAWBgNVBAMMD1JlZ3Jlc3Npb24gVGVzdDCCA0cwggI6BgcqhkjOOAQBMIICLQKC\n" +
+                "AQEAmlavgoJrMcjqWRVcDE2dmWAPREgnzQvneEDef68cprDzjSwvOs5QeFyx75ib\n" +
+                "ado1e6jO/rW1prCGWHDD1oA/Tn4Pk3vu0nUxzvl1qATc+aJbpUU5Op0bvp6LbCsQ\n" +
+                "QslV9FeRh7Eb7bP6gpc/kHCBzEgC1VCK7prccXWy+t6SMOHbND3h+UbckfSaUuaV\n" +
+                "sVJNTD1D6GElfRj4Nmz1BGPfSYvKorwNZEU3gXwFgtDoAcGx7tcyClLpDHfqRfw/\n" +
+                "7yiqLyeiP7D4hl5lMNouJWDlAdMFp0FMgS3s9VDFinIcr6VtBWMTG7+4+czHAB+3\n" +
+                "fvrwlqNzhBn3uFHrekN/w8fNxwIhAJo7Sae1za7IMW0Q6hE5B4b+s2B/FaKPoA4E\n" +
+                "jtZu13B9AoIBAQCOZqLMKfvqZWUgT0PQ3QjR7dAFdd06I9Y3+TOQzZk1+j+vw/6E\n" +
+                "X4vFItX4gihb/u5Q9CdmpwhVGi7bvo+7+/IKeTgoQ6f5+PSug7SrWWUQ5sPwaZui\n" +
+                "zXZJ5nTeZDucFc2yFx0wgnjbPwiUxZklOT7xGiOMtzOTa2koCz5KuIBL+/wPKKxm\n" +
+                "ypo9VoY9xfbdU6LMXZv/lpD5XTM9rYHr/vUTNkukvV6Hpm0YMEWhVZKUJiqCqTqG\n" +
+                "XHaleOxSw6uQWB/+TznifcC7gB48UOQjCqOKf5VuwQneJLhlhU/jhRV3xtr+hLZa\n" +
+                "hW1wYhVi8cjLDrZFKlgEQqhB4crnJU0mJY+tA4IBBQACggEAID0ezl00/X8mv7eb\n" +
+                "bzovum1+DEEP7FM57k6HZEG2N3ve4CW+0m9Cd+cWPz8wkZ+M0j/Eqa6F0IdbkXEc\n" +
+                "Q7CuzvUyJ57xQ3L/WCgXsiS+Bh8O4Mz7GwW22CGmHqafbVv+hKBfr8MkskO6GJUt\n" +
+                "SUF/CVLzB4gMIvZMH26tBP2xK+i7FeEK9kT+nGdzQSZBAhFYpEVCBplHZO24/OYq\n" +
+                "1DNoU327nUuXIhmsfA8N0PjiWbIZIjTPwBGr9H0LpATI7DIDNcvRRvtROP+pBU9y\n" +
+                "fuykPkptg9C0rCM9t06bukpOSaEz/2VIQdLE8fHYFA6pHZ6CIc2+5cfvMgTPhcjz\n" +
+                "W2jCt6MjMCEwHwYDVR0jBBgwFoAUdmae9zvdReU72XI8P/BUOYYxJlMwCwYJYIZI\n" +
+                "AWUDBAMCA0gAMEUCIQCeI5fN08b9BpOaHdc3zQNGjp24FOL/RxlBLeBAorswJgIg\n" +
+                "JEZ8DhYxQy1O7mmZ2UIT7op6epWMB4dENjs0qWPmcKo=\n" +
+                "-----END CERTIFICATE-----",
+                "MIICZQIBADCCAjoGByqGSM44BAEwggItAoIBAQCaVq+CgmsxyOpZFVwMTZ2ZYA9E\n" +
+                "SCfNC+d4QN5/rxymsPONLC86zlB4XLHvmJtp2jV7qM7+tbWmsIZYcMPWgD9Ofg+T\n" +
+                "e+7SdTHO+XWoBNz5olulRTk6nRu+notsKxBCyVX0V5GHsRvts/qClz+QcIHMSALV\n" +
+                "UIrumtxxdbL63pIw4ds0PeH5RtyR9JpS5pWxUk1MPUPoYSV9GPg2bPUEY99Ji8qi\n" +
+                "vA1kRTeBfAWC0OgBwbHu1zIKUukMd+pF/D/vKKovJ6I/sPiGXmUw2i4lYOUB0wWn\n" +
+                "QUyBLez1UMWKchyvpW0FYxMbv7j5zMcAH7d++vCWo3OEGfe4Uet6Q3/Dx83HAiEA\n" +
+                "mjtJp7XNrsgxbRDqETkHhv6zYH8Voo+gDgSO1m7XcH0CggEBAI5moswp++plZSBP\n" +
+                "Q9DdCNHt0AV13Toj1jf5M5DNmTX6P6/D/oRfi8Ui1fiCKFv+7lD0J2anCFUaLtu+\n" +
+                "j7v78gp5OChDp/n49K6DtKtZZRDmw/Bpm6LNdknmdN5kO5wVzbIXHTCCeNs/CJTF\n" +
+                "mSU5PvEaI4y3M5NraSgLPkq4gEv7/A8orGbKmj1Whj3F9t1Tosxdm/+WkPldMz2t\n" +
+                "gev+9RM2S6S9XoembRgwRaFVkpQmKoKpOoZcdqV47FLDq5BYH/5POeJ9wLuAHjxQ\n" +
+                "5CMKo4p/lW7BCd4kuGWFT+OFFXfG2v6EtlqFbXBiFWLxyMsOtkUqWARCqEHhyucl\n" +
+                "TSYlj60EIgIgLfA75+8KcKxdN8mr6gzGjQe7jPFGG42Ejhd7Q2F4wuw=");
+
+        final String keyAlgo;
+        final String certStr;
+        final String privKeyStr;
+
+        Cert(String keyAlgo, String certStr, String privKeyStr) {
+            this.keyAlgo = keyAlgo;
+            this.certStr = certStr;
+            this.privKeyStr = privKeyStr;
+        }
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/swing/LookAndFeel/SystemLookAndFeel/SystemLookAndFeelTest.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ /*
+ * @test
+ * @bug 8226783
+ * @key headful
+ * @summary Verify System L&F
+ */
+
+/*
+ * Verify the System LAF is what we expect based on platform and,
+ * in at least one case, the desktop environment.
+ * Since changes to the system LAF are a once in a blue moon event,
+ * this test is useful to tell us of unexpected problems.
+ * Note: this test must be run in a headful environment
+ * since otherwise a system LAF may not be available.
+ */
+
+public class SystemLookAndFeelTest {
+
+    public static void main(String[] args) {
+
+        String laf = javax.swing.UIManager.getSystemLookAndFeelClassName();
+        String os = System.getProperty("os.name").toLowerCase();
+        System.out.println("OS is " + os);
+        System.out.println("Reported System LAF is " + laf);
+
+        String expLAF = null;
+        if (os.contains("windows")) {
+            expLAF = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
+        } else if (os.contains("macos")) {
+            expLAF = "com.apple.laf.AquaLookAndFeel";
+        } else if (os.contains("linux") || os.contains("sunos")) {
+           /*
+            * The implementation keys off the following desktop setting to
+            * decide if GTK is an appropriate system L&F.
+            * In its absence, there probably isn't support for the GTK L&F
+            * anyway. It does not tell us if the GTK libraries are available
+            * but they really should be if this is a gnome session.
+            * If it proves necessary the test can perhaps be updated to see
+            * if the GTK LAF is listed as installed and can be instantiated.
+            */
+           String gnome = System.getenv("GNOME_DESKTOP_SESSION_ID");
+           System.out.println("Gnome desktop session ID is " + gnome);
+           if (gnome != null) {
+               expLAF = "com.sun.java.swing.plaf.gtk.GTKLookAndFeel";
+           } else if (os.contains("linux")) {
+               expLAF = "javax.swing.plaf.metal.MetalLookAndFeel";
+           } else if (os.contains("sunos")) {
+               expLAF = "com.sun.java.swing.plaf.motif.MotifLookAndFeel";
+           }
+       }
+        System.out.println("Expected System LAF is " + expLAF);
+        if (expLAF == null) {
+            System.out.println("No match for expected LAF, unknown OS ?");
+            return;
+        }
+        if (!(laf.equals(expLAF))) {
+            throw new RuntimeException("LAF not as expected");
+        }
+   }
+}
--- a/test/jdk/jdk/internal/platform/docker/TestDockerMemoryMetrics.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/jdk/internal/platform/docker/TestDockerMemoryMetrics.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -63,7 +63,7 @@
             testOomKillFlag("100m", false);
             testOomKillFlag("100m", true);
 
-            testMemoryFailCount("20m");
+            testMemoryFailCount("64m");
 
             testMemorySoftLimit("500m","200m");
 
--- a/test/jdk/jdk/internal/platform/docker/TestSystemMetrics.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/jdk/internal/platform/docker/TestSystemMetrics.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -51,6 +51,7 @@
             DockerRunOptions opts =
                     new DockerRunOptions(imageName, "/jdk/bin/java", "jdk.test.lib.containers.cgroup.MetricsTester");
             opts.addDockerOpts("--volume", Utils.TEST_CLASSES + ":/test-classes/");
+            opts.addDockerOpts("--memory=256m");
             opts.addJavaOpts("-cp", "/test-classes/");
             opts.addJavaOpts("--add-exports", "java.base/jdk.internal.platform=ALL-UNNAMED");
             DockerTestUtils.dockerRunJava(opts).shouldHaveExitValue(0).shouldContain("TEST PASSED!!!");
--- a/test/jdk/jdk/jfr/event/gc/collection/TestG1ParallelPhases.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/jdk/jfr/event/gc/collection/TestG1ParallelPhases.java	Mon Jul 01 14:57:02 2019 -0700
@@ -100,20 +100,30 @@
             "CMRefRoots",
             "WaitForStrongCLD",
             "WeakCLDRoots",
-            "UpdateRS",
-            "ScanHCC",
-            "ScanRS",
+            "MergeHCC",
+            "MergeRS",
+            "MergeLB",
+            "ScanHR",
             "CodeRoots",
             "ObjCopy",
             "Termination",
             "StringDedupQueueFixup",
             "StringDedupTableFixup",
             "RedirtyCards",
-       //     "PreserveCMReferents",
             "NonYoungFreeCSet",
             "YoungFreeCSet"
         );
 
+        // Some GC phases may or may not occur depending on environment. Filter them out
+        // since we can not reliably guarantee that they occur (or not).
+        Set<String> optPhases = of(
+            "OptScanHR",
+            "OptMergeRS",
+            "OptCodeRoots",
+            "OptObjCopy"
+        );
+        usedPhases.removeAll(optPhases);
+
         assertTrue(usedPhases.equals(allPhases), "Compare events expected and received"
             + ", Not found phases: " + allPhases.stream().filter(p -> !usedPhases.contains(p)).collect(joining(", "))
             + ", Not expected phases: " + usedPhases.stream().filter(p -> !allPhases.contains(p)).collect(joining(", ")));
--- a/test/jdk/sun/net/ftp/FtpURLConnectionLeak.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/sun/net/ftp/FtpURLConnectionLeak.java	Mon Jul 01 14:57:02 2019 -0700
@@ -27,7 +27,7 @@
  * @summary FtpURLConnection doesn't close FTP connection when FileNotFoundException is thrown
  * @library ../www/ftptest/
  * @build FtpServer FtpCommandHandler FtpAuthHandler FtpFileSystemHandler
- * @run main FtpURLConnectionLeak
+ * @run main/othervm FtpURLConnectionLeak
  */
 import java.io.FileNotFoundException;
 import java.io.InputStream;
--- a/test/jdk/sun/net/www/http/HttpClient/RetryPost.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/sun/net/www/http/HttpClient/RetryPost.java	Mon Jul 01 14:57:02 2019 -0700
@@ -54,23 +54,19 @@
     MyHandler httpHandler;
     ExecutorService executorService;
 
-    public static void main(String[] args) {
+    public static void main(String[] args) throws Exception {
         if (args.length == 1 && args[0].equals("noRetry"))
             shouldRetry = false;
 
         new RetryPost();
     }
 
-    public RetryPost() {
-        try {
-            startHttpServer(shouldRetry);
-            doClient();
-        } catch (IOException ioe) {
-            System.err.println(ioe);
-        }
+    public RetryPost() throws Exception {
+        startHttpServer(shouldRetry);
+        doClient();
     }
 
-    void doClient() {
+    void doClient() throws Exception {
         try {
             InetSocketAddress address = httpServer.getAddress();
             URL url = URIBuilder.newBuilder()
@@ -95,8 +91,6 @@
             else if (!shouldRetry && httpHandler.getCallCount() != 1)
                 throw new RuntimeException("Failed: Handler should have only been called once" +
                                            "It was called "+ httpHandler.getCallCount() + " times");
-        } catch (IOException e) {
-            e.printStackTrace();
         } finally {
             httpServer.stop(1);
             executorService.shutdown();
@@ -119,8 +113,8 @@
     }
 
     class MyHandler implements HttpHandler {
-        int callCount = 0;
-        boolean shouldRetry;
+        volatile int callCount = 0;
+        final boolean shouldRetry;
 
         public MyHandler(boolean shouldRetry) {
             this.shouldRetry = shouldRetry;
--- a/test/jdk/sun/net/www/protocol/http/AsyncDisconnect.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/sun/net/www/protocol/http/AsyncDisconnect.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,18 +24,21 @@
 /*
  * @test
  * @bug 6358532
+ * @library /test/lib
  * @modules jdk.httpserver
  * @run main/othervm AsyncDisconnect
+ * @run main/othervm -Djava.net.preferIPv6Addresses=true AsyncDisconnect
  * @summary HttpURLConnection.disconnect doesn't really do the job
  */
 
 import java.net.*;
-import java.util.*;
 import java.io.*;
 import com.sun.net.httpserver.*;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ExecutorService;
 
+import jdk.test.lib.net.URIBuilder;
+
 public class AsyncDisconnect implements Runnable
 {
     com.sun.net.httpserver.HttpServer httpServer;
@@ -43,27 +46,30 @@
     ExecutorService executorService;
     HttpURLConnection uc;
 
-    public static void main(String[] args) {
+    public static void main(String[] args) throws Exception {
         new AsyncDisconnect();
     }
 
-    public AsyncDisconnect() {
-        try {
-            startHttpServer();
-            doClient();
-        } catch (IOException ioe) {
-            System.err.println(ioe);
-        }
+    public AsyncDisconnect() throws Exception {
+        startHttpServer();
+        doClient();
     }
 
-    void doClient() {
+    void doClient() throws Exception {
+        Thread t = new Thread(this);
+
         try {
             InetSocketAddress address = httpServer.getAddress();
-            URL url = new URL("http://" + address.getHostName() + ":" + address.getPort() + "/test/");
-            uc = (HttpURLConnection)url.openConnection();
+            URL url = URIBuilder.newBuilder()
+                    .scheme("http")
+                    .host(address.getAddress())
+                    .port(address.getPort())
+                    .path("/test/")
+                    .toURL();
+            uc = (HttpURLConnection) url.openConnection(Proxy.NO_PROXY);
 
             // create a thread that will disconnect the connection
-            (new Thread(this)).start();
+            t.start();
 
             uc.getInputStream();
 
@@ -73,11 +79,11 @@
         } catch (SocketException se) {
             // this is what we expect to happen and is OK.
             //System.out.println(se);
-        } catch (IOException e) {
-            e.printStackTrace();
         } finally {
             httpServer.stop(1);
+            t.join();
             executorService.shutdown();
+
         }
     }
 
@@ -93,7 +99,9 @@
      * Http Server
      */
     public void startHttpServer() throws IOException {
-        httpServer = com.sun.net.httpserver.HttpServer.create(new InetSocketAddress(0), 0);
+        InetAddress loopback = InetAddress.getLoopbackAddress();
+        InetSocketAddress address = new InetSocketAddress(loopback, 0);
+        httpServer = com.sun.net.httpserver.HttpServer.create(address, 0);
         httpHandler = new MyHandler();
 
         HttpContext ctx = httpServer.createContext("/test/", httpHandler);
--- a/test/jdk/sun/net/www/protocol/http/B5017051.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/sun/net/www/protocol/http/B5017051.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,9 @@
  * @test
  * @bug 5017051 6360774
  * @modules jdk.httpserver
+ * @library /test/lib
  * @run main/othervm B5017051
+ * @run main/othervm -Djava.net.preferIPv6Addresses=true B5017051
  * @summary Tests CR 5017051 & 6360774
  */
 
@@ -35,6 +37,7 @@
 import com.sun.net.httpserver.*;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ExecutorService;
+import jdk.test.lib.net.URIBuilder;
 
 /*
  * Part 1:
@@ -55,42 +58,47 @@
 
 public class B5017051
 {
-    com.sun.net.httpserver.HttpServer httpServer;
+    HttpServer httpServer;
     ExecutorService executorService;
 
-    public static void main(String[] args)
-    {
+    public static void main(String[] args) throws Exception {
         new B5017051();
     }
 
-    public B5017051()
-    {
-        try {
-            startHttpServer();
-            doClient();
-        } catch (IOException ioe) {
-            System.err.println(ioe);
-        }
+    public B5017051() throws Exception {
+        startHttpServer();
+        doClient();
     }
 
-    void doClient() {
+    void doClient() throws Exception {
         java.net.Authenticator.setDefault(new MyAuthenticator());
         CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));
+        ProxySelector.setDefault(ProxySelector.of(null));
 
         try {
             InetSocketAddress address = httpServer.getAddress();
 
             // Part 1
-            URL url = new URL("http://" + address.getHostName() + ":" + address.getPort() + "/test/");
+            URL url = URIBuilder.newBuilder()
+                .scheme("http")
+                .host(address.getAddress())
+                .port(address.getPort())
+                .path("/test/")
+                .toURL();
             HttpURLConnection uc = (HttpURLConnection)url.openConnection();
             int resp = uc.getResponseCode();
             if (resp != 200)
-                throw new RuntimeException("Failed: Part 1, Response code is not 200");
+                throw new RuntimeException("Failed: Part 1, Response code is not 200: " + resp);
 
             System.out.println("Response code from Part 1 = 200 OK");
 
             // Part 2
-            URL url2 = new URL("http://" + address.getHostName() + ":" + address.getPort() + "/test2/");
+            URL url2 = URIBuilder.newBuilder()
+                .scheme("http")
+                .host(address.getAddress())
+                .port(address.getPort())
+                .path("/test2/")
+                .toURL();
 
             // can use the global CookieHandler used for the first test as the URL's are different
             CookieHandler ch = CookieHandler.getDefault();
@@ -106,15 +114,10 @@
             uc = (HttpURLConnection)url2.openConnection();
             resp = uc.getResponseCode();
             if (resp != 200)
-                throw new RuntimeException("Failed: Part 2, Response code is not 200");
+                throw new RuntimeException("Failed: Part 2, Response code is not 200: " + resp);
 
             System.out.println("Response code from Part 2 = 200 OK");
 
-
-        } catch (IOException e) {
-            e.printStackTrace();
-        } catch (URISyntaxException ue) {
-            ue.printStackTrace();
         } finally {
             httpServer.stop(1);
             executorService.shutdown();
@@ -125,7 +128,8 @@
      * Http Server
      */
     public void startHttpServer() throws IOException {
-        httpServer = com.sun.net.httpserver.HttpServer.create(new InetSocketAddress(0), 0);
+        InetAddress loopback = InetAddress.getLoopbackAddress();
+        httpServer = HttpServer.create(new InetSocketAddress(loopback, 0), 0);
 
         // create HttpServer context for Part 1.
         HttpContext ctx = httpServer.createContext("/test/", new MyHandler());
--- a/test/jdk/sun/net/www/protocol/http/B6296310.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/sun/net/www/protocol/http/B6296310.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@
  * @library ../../httptest/
  * @build HttpCallback TestHttpServer HttpTransaction
  * @run main/othervm B6296310
+ * @run main/othervm -Djava.net.preferIPv6Addresses=true B6296310
  * @summary  REGRESSION: AppletClassLoader.getResourceAsStream() behaviour is wrong in some cases
  */
 
@@ -45,32 +46,26 @@
    static SimpleHttpTransaction httpTrans;
    static TestHttpServer server;
 
-   public static void main(String[] args)
+   public static void main(String[] args) throws Exception
    {
       ResponseCache.setDefault(new MyCacheHandler());
       startHttpServer();
-
       makeHttpCall();
    }
 
-   public static void startHttpServer() {
-      try {
-         httpTrans = new SimpleHttpTransaction();
-         server = new TestHttpServer(httpTrans, 1, 10, 0);
-      } catch (IOException e) {
-         e.printStackTrace();
-      }
+   public static void startHttpServer() throws IOException {
+     httpTrans = new SimpleHttpTransaction();
+     InetAddress loopback = InetAddress.getLoopbackAddress();
+     server = new TestHttpServer(httpTrans, 1, 10, loopback, 0);
    }
 
-   public static void makeHttpCall() {
+   public static void makeHttpCall() throws IOException {
       try {
          System.out.println("http server listen on: " + server.getLocalPort());
-         URL url = new URL("http" , InetAddress.getLocalHost().getHostAddress(),
+         URL url = new URL("http" , InetAddress.getLoopbackAddress().getHostAddress(),
                             server.getLocalPort(), "/");
-         HttpURLConnection uc = (HttpURLConnection)url.openConnection();
+         HttpURLConnection uc = (HttpURLConnection)url.openConnection(Proxy.NO_PROXY);
          System.out.println(uc.getResponseCode());
-      } catch (IOException e) {
-         e.printStackTrace();
       } finally {
          server.terminate();
       }
--- a/test/jdk/sun/net/www/protocol/http/B6299712.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/sun/net/www/protocol/http/B6299712.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
  * @bug 6299712 7150552
  * @modules jdk.httpserver
  * @run main/othervm B6299712
+ * @run main/othervm -Djava.net.preferIPv6Addresses=true B6299712
  * @summary  NullPointerException in sun.net.www.protocol.http.HttpURLConnection.followRedirect
  */
 
@@ -54,13 +55,15 @@
 
     public static void main(String[] args) throws Exception {
         ResponseCache.setDefault(new DeployCacheHandler());
+        ProxySelector.setDefault(ProxySelector.of(null)); // no proxy
         startHttpServer();
 
         makeHttpCall();
     }
 
     public static void startHttpServer() throws IOException {
-        server = HttpServer.create(new InetSocketAddress(0), 0);
+        InetAddress address = InetAddress.getLocalHost();
+        server = HttpServer.create(new InetSocketAddress(address, 0), 0);
         server.createContext("/", new DefaultHandler());
         server.createContext("/redirect", new RedirectHandler());
         server.start();
--- a/test/jdk/sun/net/www/protocol/http/B6641309.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/sun/net/www/protocol/http/B6641309.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,10 @@
  * @test
  * @bug 6641309
  * @modules jdk.httpserver
- * @summary Wrong Cookie separator used in HttpURLConnection
+ * @library /test/lib
+ * @run main/othervm B6641309
+ * @run main/othervm -Djava.net.preferIPv6Addresses=true B6641309
+ * @summary Wrong Cookie separator used in HttpURLConnection B6641309
  */
 
 import java.net.*;
@@ -35,65 +38,65 @@
 import java.util.concurrent.Executors;
 import java.util.concurrent.ExecutorService;
 
+import jdk.test.lib.net.URIBuilder;
+
 public class B6641309
 {
     com.sun.net.httpserver.HttpServer httpServer;
     ExecutorService executorService;
 
-    public static void main(String[] args)
-    {
+    public static void main(String[] args) throws Exception {
         new B6641309();
     }
 
-    public B6641309()
-    {
-        try {
-            startHttpServer();
-            doClient();
-        } catch (IOException ioe) {
-            System.err.println(ioe);
-        }
+    public B6641309() throws Exception {
+        startHttpServer();
+        doClient();
     }
 
-    void doClient() {
+    void doClient() throws Exception {
         CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));
-        try {
-            InetSocketAddress address = httpServer.getAddress();
+        ProxySelector.setDefault(ProxySelector.of(null));
+
+        InetSocketAddress address = httpServer.getAddress();
 
-            // GET Request
-            URL url = new URL("http://localhost:" + address.getPort() + "/test/");
-            CookieHandler ch = CookieHandler.getDefault();
-            Map<String,List<String>> header = new HashMap<String,List<String>>();
-            List<String> values = new LinkedList<String>();
-            values.add("Test1Cookie=TEST1; path=/test/");
-            values.add("Test2Cookie=TEST2; path=/test/");
-            header.put("Set-Cookie", values);
+        // GET Request
+        URL url = URIBuilder.newBuilder()
+                .scheme("http")
+                .host(address.getAddress())
+                .port(address.getPort())
+                .path("/test/")
+                .toURL();
 
-            // preload the CookieHandler with a cookie for our URL
-            // so that it will be sent during the first request
-            ch.put(url.toURI(), header);
-            HttpURLConnection uc = (HttpURLConnection)url.openConnection();
-            int resp = uc.getResponseCode();
-            if (resp != 200)
-                throw new RuntimeException("Failed: Response code from GET is not 200");
+        CookieHandler ch = CookieHandler.getDefault();
+        Map<String,List<String>> header = new HashMap<String,List<String>>();
+        List<String> values = new LinkedList<String>();
+        values.add("Test1Cookie=TEST1; path=/test/");
+        values.add("Test2Cookie=TEST2; path=/test/");
+        header.put("Set-Cookie", values);
 
-            System.out.println("Response code from GET = 200 OK");
+        // preload the CookieHandler with a cookie for our URL
+        // so that it will be sent during the first request
+        ch.put(url.toURI(), header);
+        HttpURLConnection uc = (HttpURLConnection)url.openConnection();
+        int resp = uc.getResponseCode();
+        if (resp != 200) {
+            throw new RuntimeException("Failed: Response code from GET is not 200: "
+                    + resp);
+        }
+        System.out.println("Response code from GET = 200 OK");
 
-        } catch (IOException e) {
-            e.printStackTrace();
-        } catch (URISyntaxException e) {
-            e.printStackTrace();
-        } finally {
-            httpServer.stop(1);
-            executorService.shutdown();
-        }
+        httpServer.stop(1);
+        executorService.shutdown();
     }
 
     /**
      * Http Server
      */
     public void startHttpServer() throws IOException {
-        httpServer = com.sun.net.httpserver.HttpServer.create(new InetSocketAddress(0), 0);
+        InetAddress loopback = InetAddress.getLoopbackAddress();
+        InetSocketAddress address = new InetSocketAddress(loopback, 0);
+        httpServer = com.sun.net.httpserver.HttpServer.create(address, 0);
 
         // create HttpServer context
         HttpContext ctx = httpServer.createContext("/test/", new MyHandler());
--- a/test/jdk/sun/net/www/protocol/http/B6660405.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/sun/net/www/protocol/http/B6660405.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,10 @@
  * @test
  * @bug 6660405
  * @modules jdk.httpserver
- * @summary HttpURLConnection returns the wrong InputStream
+ * @library /test/lib
+ * @run main/othervm B6660405
+ * @run main/othervm -Djava.net.preferIPv6Addresses=true B6660405
+ * @summary HttpURLConnection returns the wrong InputStream B6660405
  */
 
 import java.net.*;
@@ -34,6 +37,8 @@
 import com.sun.net.httpserver.*;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ExecutorService;
+import jdk.test.lib.net.URIBuilder;
+
 
 public class B6660405
 {
@@ -72,7 +77,8 @@
         }
 
         @Override
-        public CacheResponse get(URI uri, String rqstMethod, Map<String, List<String>> rqstHeaders) throws IOException
+        public CacheResponse get(URI uri, String rqstMethod, Map<String, List<String>> rqstHeaders)
+                throws IOException
         {
             if (uri.getPath().equals("/redirect/index.html")) {
                 return new MyCacheResponse();
@@ -88,53 +94,61 @@
 
     }
 
-    public static void main(String[] args)
+    public static void main(String[] args) throws Exception
     {
         new B6660405();
     }
 
-    public B6660405()
-    {
-        try {
-            startHttpServer();
-            doClient();
-        } catch (IOException ioe) {
-            System.err.println(ioe);
-        }
+    public B6660405() throws Exception {
+        startHttpServer();
+        doClient();
     }
 
-    void doClient() {
+    void doClient() throws Exception {
         ResponseCache.setDefault(new MyResponseCache());
-        try {
-            InetSocketAddress address = httpServer.getAddress();
+        InetSocketAddress address = httpServer.getAddress();
+
+        // GET Request
+        URL url = URIBuilder.newBuilder()
+                .scheme("http")
+                .host(address.getAddress())
+                .port(address.getPort())
+                .path("/test/index.html")
+                .toURL();
 
-            // GET Request
-            URL url = new URL("http://localhost:" + address.getPort() + "/test/index.html");
-            HttpURLConnection uc = (HttpURLConnection)url.openConnection();
-            int code = uc.getResponseCode();
-            System.err.println("response code = " + code);
-            int l = uc.getContentLength();
-            System.err.println("content-length = " + l);
-            InputStream in = uc.getInputStream();
-            int i = 0;
-            // Read till end of stream
-            do {
-                i = in.read();
-            } while (i != -1);
-            in.close();
-        } catch (IOException e) {
-            throw new RuntimeException("Got the wrong InputStream after checking headers");
-        } finally {
-            httpServer.stop(1);
-            executorService.shutdown();
+        HttpURLConnection uc = (HttpURLConnection)url.openConnection(Proxy.NO_PROXY);
+        int code = uc.getResponseCode();
+        System.err.println("response code = " + code);
+        int l = uc.getContentLength();
+        System.err.println("content-length = " + l);
+        if (l != 1024) {
+            throw new AssertionError("Bad content length: " + l);
         }
+
+        InputStream in = uc.getInputStream();
+        int i = 0;
+        // Read till end of stream
+        do {
+            l--;
+            i = in.read();
+        } while (i != -1);
+        in.close();
+        if (l != -1) {
+            throw new AssertionError("Only " + (1024 - (l + 1))
+                    + " bytes read from stream.");
+        }
+
+        httpServer.stop(1);
+        executorService.shutdown();
     }
 
     /**
      * Http Server
      */
     public void startHttpServer() throws IOException {
-        httpServer = com.sun.net.httpserver.HttpServer.create(new InetSocketAddress(0), 0);
+        InetAddress loopback = InetAddress.getLoopbackAddress();
+        InetSocketAddress address = new InetSocketAddress(loopback,0);
+        httpServer = com.sun.net.httpserver.HttpServer.create(address, 0);
 
         // create HttpServer context
         HttpContext ctx = httpServer.createContext("/test/", new MyHandler());
--- a/test/jdk/sun/net/www/protocol/http/B6890349.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/sun/net/www/protocol/http/B6890349.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,9 @@
 /**
  * @test
  * @bug 6890349
+ * @library /test/lib
  * @run main/othervm B6890349
+ * @run main/othervm -Djava.net.preferIPv6Addresses=true B6890349
  * @summary  Light weight HTTP server
  */
 
@@ -34,7 +36,11 @@
     public static final void main(String[] args) throws Exception {
 
         try {
-            ServerSocket server = new ServerSocket (0);
+            ServerSocket server = new ServerSocket();
+            InetAddress loopback = InetAddress.getLoopbackAddress();
+            InetSocketAddress address = new InetSocketAddress(loopback, 0);
+            server.bind(address);
+
             int port = server.getLocalPort();
             System.out.println ("listening on "  + port);
             B6890349 t = new B6890349 (server);
@@ -44,11 +50,11 @@
                 port,
                 "/foo\nbar");
             System.out.println("URL: " + u);
-            HttpURLConnection urlc = (HttpURLConnection)u.openConnection ();
+            HttpURLConnection urlc = (HttpURLConnection)u.openConnection(Proxy.NO_PROXY);
             InputStream is = urlc.getInputStream();
             throw new RuntimeException ("Test failed");
         } catch (IOException e) {
-            System.out.println ("OK");
+            System.out.println ("Caught expected exception: " + e);
         }
     }
 
--- a/test/jdk/sun/net/www/protocol/http/Modified.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/sun/net/www/protocol/http/Modified.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2001, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,12 +24,16 @@
 /*
  * @test
  * @bug 4092605
+ * @library /test/lib
+ * @run main/othervm Modified
+ * @run main/othervm -Djava.net.preferIPv6Addresses=true Modified
  * @summary Test HttpURLConnection setIfModifiedSince
  *
  */
 
 import java.net.*;
 import java.io.*;
+import jdk.test.lib.net.URIBuilder;
 
 public class Modified implements Runnable {
 
@@ -78,13 +82,22 @@
 
     Modified() throws Exception {
 
-        ss = new ServerSocket(0);
+        InetAddress loopback = InetAddress.getLoopbackAddress();
+        InetSocketAddress address = new InetSocketAddress(loopback, 0);
+        ss = new ServerSocket();
+        ss.bind(address);
+        int port = ss.getLocalPort();
+
         Thread thr = new Thread(this);
         thr.start();
 
-        URL testURL = new URL("http://localhost:" + ss.getLocalPort() +
-                              "/index.html");
-        URLConnection URLConn = testURL.openConnection();
+        URL testURL = URIBuilder.newBuilder()
+                .scheme("http")
+                .host(loopback)
+                .port(port)
+                .path("/index.html")
+                .toURL();
+        URLConnection URLConn = testURL.openConnection(Proxy.NO_PROXY);
         HttpURLConnection httpConn;
 
         if (URLConn instanceof HttpURLConnection) {
--- a/test/jdk/sun/net/www/protocol/http/NoNTLM.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/sun/net/www/protocol/http/NoNTLM.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,7 @@
  * @modules java.base/sun.net.www
  *          java.base/sun.net.www.protocol.http:open
  * @run main/othervm NoNTLM
+ * @run main/othervm -Djava.net.preferIPv6Addresses=true NoNTLM
  */
 
 import java.io.IOException;
@@ -155,8 +156,8 @@
         System.out.println("====================================");
         System.out.println("Expect client to choose: " + expected);
         System.out.println(reply);
-
-        try (ServerSocket ss = new ServerSocket(0)) {
+        InetAddress loopback = InetAddress.getLoopbackAddress();
+        try (ServerSocket ss = new ServerSocket(0, 0, loopback)) {
             Client.start(ss.getLocalPort());
 
             // client ---- GET ---> server
@@ -198,7 +199,8 @@
         System.out.println("Expect client to fail with 401 Unauthorized");
         System.out.println(reply);
 
-        try (ServerSocket ss = new ServerSocket(0)) {
+        InetAddress loopback = InetAddress.getLoopbackAddress();
+        try (ServerSocket ss = new ServerSocket(0, 0, loopback)) {
             Client client = new Client(ss.getLocalPort());
             Thread thr = new Thread(client);
             thr.start();
@@ -225,13 +227,14 @@
     }
 
     public static void main(String[] args) throws Exception {
+        boolean ntlmSupported = false;
         try {
             Class<?> ntlmProxyClass = Class.forName("sun.net.www.protocol.http.NTLMAuthenticationProxy", true, NoNTLM.class.getClassLoader());
             Field ntlmSupportedField = ntlmProxyClass.getDeclaredField("supported");
             ntlmSupportedField.setAccessible(true);
             if (ntlmSupportedField.getBoolean(null)) {
-                System.out.println("NTLM is supported. Nothing to do. Exiting.");
-                return;
+                System.out.println("NTLM is supported.");
+                ntlmSupported = true;
             }
         } catch (ClassNotFoundException okay) { }
 
@@ -247,15 +250,26 @@
         test("Basic");
         test("Digest");
         test("Basic", "Digest");
-        test("Basic", "NTLM");
+
+        if (ntlmSupported) {
+            System.out.println("====================================");
+            System.out.println("NTLM is supported: client would select NTLM: skipping `test(\"Basic\", \"NTLM\")`..");
+        } else {
+            test("Basic", "NTLM");
+        }
+
         test("Digest", "NTLM");
         test("Basic", "Digest", "NTLM");
 
-        // test NTLM only, this should fail with "401 Unauthorized"
-        testNTLM();
+        if (ntlmSupported) {
+            System.out.println("====================================");
+            System.out.println("NTLM is supported: client would select NTLM: skipping `testNTLM()`..");
+        } else {
+            // test NTLM only, this should fail with "401 Unauthorized"
+            testNTLM();
+        }
 
         System.out.println();
         System.out.println("TEST PASSED");
     }
 }
-
--- a/test/jdk/sun/net/www/protocol/http/UserAgent.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/sun/net/www/protocol/http/UserAgent.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2002, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
  * @library /test/lib
  * @modules java.base/sun.net.www
  * @run main/othervm -Dhttp.agent=foo UserAgent
+ * @run main/othervm -Dhttp.agent=foo -Djava.net.preferIPv6Addresses=true UserAgent
  * @summary  HTTP header "User-Agent" format incorrect
  */
 
@@ -87,7 +88,9 @@
 public class UserAgent {
 
     public static void main(String[] args) throws Exception {
-        ServerSocket server = new ServerSocket (0);
+        InetAddress loopback = InetAddress.getLoopbackAddress();
+        ServerSocket server = new ServerSocket ();
+        server.bind(new InetSocketAddress(loopback, 0));
         Server s = new Server (server);
         s.start ();
         int port = server.getLocalPort ();
@@ -97,7 +100,7 @@
             .port(port)
             .toURL();
         System.out.println("URL: " + url);
-        URLConnection urlc = url.openConnection ();
+        URLConnection urlc = url.openConnection (Proxy.NO_PROXY);
         urlc.getInputStream ();
         s.join ();
         if (!s.succeeded()) {
--- a/test/jdk/sun/net/www/protocol/http/ZoneId.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/sun/net/www/protocol/http/ZoneId.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -60,7 +60,7 @@
         out.println("Found an appropriate IPv6 address: " + address);
 
         out.println("Starting http server...");
-        HttpServer server = HttpServer.create(new InetSocketAddress(0), 0);
+        HttpServer server = HttpServer.create(new InetSocketAddress(address, 0), 0);
         CompletableFuture<Headers> headers = new CompletableFuture<>();
         server.createContext("/", createCapturingHandler(headers));
         server.start();
--- a/test/jdk/sun/net/www/protocol/https/NewImpl/JavaxHTTPSConnection.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/sun/net/www/protocol/https/NewImpl/JavaxHTTPSConnection.java	Mon Jul 01 14:57:02 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,9 @@
  * @test
  * @bug 4474255
  * @summary Can no longer obtain a com.sun.net.ssl.HttpsURLConnection
+ * @library /test/lib
  * @run main/othervm JavaxHTTPSConnection
+ * @run main/othervm -Djava.net.preferIPv6Addresses=true JavaxHTTPSConnection
  *
  *     SunJSSE does not support dynamic system properties, no way to re-use
  *     system properties in samevm/agentvm mode.
@@ -36,6 +38,7 @@
 import java.net.*;
 import java.security.cert.*;
 import javax.net.ssl.*;
+import jdk.test.lib.net.URIBuilder;
 
 /**
  * See if we can obtain a javax.net.ssl.HttpsURLConnection,
@@ -138,10 +141,13 @@
      */
     void doServerSide() throws Exception {
 
+        InetAddress loopback = InetAddress.getLoopbackAddress();
+        InetSocketAddress serverAddress = new InetSocketAddress(loopback, serverPort);
         SSLServerSocketFactory sslssf =
           (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
         SSLServerSocket sslServerSocket =
-            (SSLServerSocket) sslssf.createServerSocket(serverPort);
+            (SSLServerSocket) sslssf.createServerSocket();
+        sslServerSocket.bind(serverAddress);
         serverPort = sslServerSocket.getLocalPort();
 
         /*
@@ -204,9 +210,14 @@
             }
 
             HttpsURLConnection.setDefaultHostnameVerifier(new NameVerifier());
-            URL url = new URL("https://" + "localhost:" + serverPort +
-                                    "/etc/hosts");
-            URLConnection urlc = url.openConnection();
+            URL url = URIBuilder.newBuilder()
+                .scheme("https")
+                .loopback()
+                .port(serverPort)
+                .path("/etc/hosts")
+                .toURL();
+            System.out.println("Client opening: " + url);
+            URLConnection urlc = url.openConnection(Proxy.NO_PROXY);
 
             if (!(urlc instanceof javax.net.ssl.HttpsURLConnection)) {
                 throw new Exception("URLConnection ! instanceof " +
--- a/test/jdk/sun/security/pkcs11/Signature/KeyAndParamCheckForPSS.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/sun/security/pkcs11/Signature/KeyAndParamCheckForPSS.java	Mon Jul 01 14:57:02 2019 -0700
@@ -26,7 +26,7 @@
 
 /**
  * @test
- * @bug 8080462
+ * @bug 8080462 8226651
  * @summary Ensure that PSS key and params check are implemented properly
  *         regardless of call sequence
  * @library /test/lib ..
@@ -57,12 +57,19 @@
         }
         // NOTE: key length >= (digest length + 2) in bytes
         // otherwise, even salt length = 0 would not work
-        runTest(p, 1024, "SHA-384");
-        runTest(p, 1040, "SHA-512");
+        runTest(p, 1024, "SHA-256", "SHA-256");
+        runTest(p, 1024, "SHA-256", "SHA-384");
+        runTest(p, 1024, "SHA-256", "SHA-512");
+        runTest(p, 1024, "SHA-384", "SHA-256");
+        runTest(p, 1024, "SHA-384", "SHA-384");
+        runTest(p, 1024, "SHA-384", "SHA-512");
+        runTest(p, 1040, "SHA-512", "SHA-256");
+        runTest(p, 1040, "SHA-512", "SHA-384");
+        runTest(p, 1040, "SHA-512", "SHA-512");
     }
 
-    private void runTest(Provider p, int keySize, String hashAlg)
-            throws Exception {
+    private void runTest(Provider p, int keySize, String hashAlg,
+            String mgfHashAlg) throws Exception {
         System.out.println("Testing [" + keySize + " " + hashAlg + "]");
 
         // create a key pair with the supplied size
@@ -72,9 +79,9 @@
 
         int bigSaltLen = keySize/8 - 14;
         AlgorithmParameterSpec paramsBad = new PSSParameterSpec(hashAlg,
-            "MGF1", new MGF1ParameterSpec(hashAlg), bigSaltLen, 1);
+            "MGF1", new MGF1ParameterSpec(mgfHashAlg), bigSaltLen, 1);
         AlgorithmParameterSpec paramsGood = new PSSParameterSpec(hashAlg,
-            "MGF1", new MGF1ParameterSpec(hashAlg), 0, 1);
+            "MGF1", new MGF1ParameterSpec(mgfHashAlg), 0, 1);
 
         PrivateKey priv = kp.getPrivate();
         PublicKey pub = kp.getPublic();
--- a/test/jdk/sun/security/pkcs11/Signature/SigInteropPSS.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/sun/security/pkcs11/Signature/SigInteropPSS.java	Mon Jul 01 14:57:02 2019 -0700
@@ -27,7 +27,7 @@
 
 /*
  * @test
- * @bug 8080462
+ * @bug 8080462 8226651
  * @summary testing interoperability of PSS signatures of PKCS11 provider
  *         against SunRsaSign provider
  * @library /test/lib ..
@@ -64,42 +64,31 @@
         KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", p);
         kpg.initialize(3072);
         KeyPair kp = kpg.generateKeyPair();
-        boolean status;
-        try {
-            status = runTest(sigSunRsaSign, sigPkcs11, kp);
-            status &= runTest(sigPkcs11, sigSunRsaSign, kp);
-        } catch (Exception e) {
-            System.out.println("Unexpected exception: " + e);
-            e.printStackTrace(System.out);
-            status = false;
-        }
 
-        if (!status) {
-            throw new RuntimeException("One or more test failed");
-        }
+        runTest(sigSunRsaSign, sigPkcs11, kp);
+        runTest(sigPkcs11, sigSunRsaSign, kp);
+
         System.out.println("Test passed");
     }
 
-    static boolean runTest(Signature signer, Signature verifier, KeyPair kp) throws Exception {
+    static void runTest(Signature signer, Signature verifier, KeyPair kp)
+            throws Exception {
         System.out.println("\tSign using " + signer.getProvider().getName());
         System.out.println("\tVerify using " + verifier.getProvider().getName());
 
-        boolean status;
-        for (String digestAlg : DIGESTS) {
-            System.out.println("\tDigest = " + digestAlg);
-            PSSParameterSpec params = new PSSParameterSpec(digestAlg, "MGF1",
-                    new MGF1ParameterSpec(digestAlg), 0, 1);
-            try {
+        for (String hash : DIGESTS) {
+            for (String mgfHash : DIGESTS) {
+                System.out.println("\tDigest = " + hash);
+                System.out.println("\tMGF = MGF1_" + mgfHash);
+
+                PSSParameterSpec params = new PSSParameterSpec(hash, "MGF1",
+                    new MGF1ParameterSpec(mgfHash), 0, 1);
+
                 signer.setParameter(params);
                 signer.initSign(kp.getPrivate());
                 verifier.setParameter(params);
                 verifier.initVerify(kp.getPublic());
-            } catch (Exception e) {
-                System.out.println("\tERROR: unexpected ex during init" + e);
-                status = false;
-                continue;
-            }
-            try {
+
                 signer.update(MSG);
                 byte[] sigBytes = signer.sign();
                 verifier.update(MSG);
@@ -107,15 +96,9 @@
                 if (isValid) {
                     System.out.println("\tPSS Signature verified");
                 } else {
-                    System.out.println("\tERROR verifying PSS Signature");
-                    status = false;
+                    throw new RuntimeException("ERROR verifying PSS Signature");
                 }
-            } catch (Exception e) {
-                System.out.println("\tERROR: unexpected ex" + e);
-                e.printStackTrace();
-                status = false;
             }
         }
-        return true;
     }
 }
--- a/test/jdk/sun/security/pkcs11/Signature/SignatureTestPSS.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/jdk/sun/security/pkcs11/Signature/SignatureTestPSS.java	Mon Jul 01 14:57:02 2019 -0700
@@ -27,7 +27,7 @@
 
 /**
  * @test
- * @bug 8080462
+ * @bug 8080462 8226651
  * @summary Generate a RSASSA-PSS signature and verify it using PKCS11 provider
  * @library /test/lib ..
  * @modules jdk.crypto.cryptoki
@@ -86,17 +86,19 @@
         test(DIGESTS, kpair.getPrivate(), kpair.getPublic(), data);
     }
 
-    private void test(String[] testAlgs, PrivateKey privKey,
+    private void test(String[] digestAlgs, PrivateKey privKey,
             PublicKey pubKey, byte[] data) throws RuntimeException {
         // For signature algorithm, create and verify a signature
-        for (String testAlg : testAlgs) {
-            try {
-                checkSignature(data, pubKey, privKey, testAlg);
-            } catch (NoSuchAlgorithmException | InvalidKeyException |
-                     SignatureException | NoSuchProviderException ex) {
-                throw new RuntimeException(ex);
-            } catch (InvalidAlgorithmParameterException ex2) {
-                System.out.println("Skip test due to " + ex2);
+        for (String hash : digestAlgs) {
+            for (String mgfHash : digestAlgs) {
+                try {
+                    checkSignature(data, pubKey, privKey, hash, mgfHash);
+                } catch (NoSuchAlgorithmException | InvalidKeyException |
+                         SignatureException | NoSuchProviderException ex) {
+                    throw new RuntimeException(ex);
+                } catch (InvalidAlgorithmParameterException ex2) {
+                    System.out.println("Skip test due to " + ex2);
+                }
             }
         };
     }
@@ -109,13 +111,14 @@
     }
 
     private void checkSignature(byte[] data, PublicKey pub,
-            PrivateKey priv, String mdAlg) throws NoSuchAlgorithmException,
-            InvalidKeyException, SignatureException, NoSuchProviderException,
+            PrivateKey priv, String hash, String mgfHash)
+            throws NoSuchAlgorithmException, InvalidKeyException,
+            SignatureException, NoSuchProviderException,
             InvalidAlgorithmParameterException {
-        System.out.println("Testing against " + mdAlg);
+        System.out.println("Testing against " + hash + " and MGF1_" + mgfHash);
         Signature sig = Signature.getInstance(SIGALG, prov);
         AlgorithmParameterSpec params = new PSSParameterSpec(
-            mdAlg, "MGF1", new MGF1ParameterSpec(mdAlg), 0, 1);
+            hash, "MGF1", new MGF1ParameterSpec(mgfHash), 0, 1);
         sig.setParameter(params);
         sig.initSign(priv);
         for (int i = 0; i < UPDATE_TIMES_HUNDRED; i++) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sun/security/ssl/CipherSuite/NamedGroupsWithCipherSuite.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLServerSocket;
+import javax.net.ssl.SSLSocket;
+
+/*
+  * @test
+  * @bug 8224650
+  * @library /javax/net/ssl/templates
+  *          /javax/net/ssl/TLSCommon
+  * @summary Test TLS ciphersuite with each individual supported group
+  * @run main/othervm NamedGroupsWithCipherSuite x25519
+  * @run main/othervm NamedGroupsWithCipherSuite x448
+  * @run main/othervm NamedGroupsWithCipherSuite secp256r1
+  * @run main/othervm NamedGroupsWithCipherSuite secp384r1
+  * @run main/othervm NamedGroupsWithCipherSuite secp521r1
+  * @run main/othervm NamedGroupsWithCipherSuite ffdhe2048
+  * @run main/othervm NamedGroupsWithCipherSuite ffdhe3072
+  * @run main/othervm NamedGroupsWithCipherSuite ffdhe4096
+  * @run main/othervm NamedGroupsWithCipherSuite ffdhe6144
+  * @run main/othervm NamedGroupsWithCipherSuite ffdhe8192
+ */
+public class NamedGroupsWithCipherSuite extends SSLSocketTemplate {
+
+    private static final Protocol[] PROTOCOLS = new Protocol[] {
+            Protocol.TLSV1_3,
+            Protocol.TLSV1_2,
+            Protocol.TLSV1_1,
+            Protocol.TLSV1
+    };
+
+    private static final CipherSuite[] CIPHER_SUITES = new CipherSuite[] {
+            CipherSuite.TLS_AES_128_GCM_SHA256,
+            CipherSuite.TLS_AES_256_GCM_SHA384,
+            CipherSuite.TLS_CHACHA20_POLY1305_SHA256,
+
+            CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+            CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+            CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
+            CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
+
+            CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
+            CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
+            CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
+            CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
+
+            CipherSuite.TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
+            CipherSuite.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256,
+
+            CipherSuite.TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
+            CipherSuite.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
+            CipherSuite.TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
+    };
+
+    private String protocol;
+    private String cipher;
+
+    private SSLSocketTemplate.Cert[] trustedCerts = TRUSTED_CERTS;
+    private SSLSocketTemplate.Cert[] endEntityCerts = END_ENTITY_CERTS;
+
+    NamedGroupsWithCipherSuite(
+            String protocol,
+            String cipher,
+            String namedGroup) {
+        this.protocol = protocol;
+        this.cipher = cipher;
+
+        if (cipher.startsWith("TLS_ECDHE_ECDSA")) {
+            switch (namedGroup) {
+            case "secp256r1":
+                trustedCerts = new SSLSocketTemplate.Cert[] {
+                        SSLSocketTemplate.Cert.CA_ECDSA_SECP256R1 };
+                endEntityCerts = new SSLSocketTemplate.Cert[] {
+                        SSLSocketTemplate.Cert.EE_ECDSA_SECP256R1 };
+                break;
+            case "secp384r1":
+                trustedCerts = new SSLSocketTemplate.Cert[] {
+                        SSLSocketTemplate.Cert.CA_ECDSA_SECP384R1 };
+                endEntityCerts = new SSLSocketTemplate.Cert[] {
+                        SSLSocketTemplate.Cert.EE_ECDSA_SECP384R1 };
+                break;
+            case "secp521r1":
+                trustedCerts = new SSLSocketTemplate.Cert[] {
+                        SSLSocketTemplate.Cert.CA_ECDSA_SECP521R1 };
+                endEntityCerts = new SSLSocketTemplate.Cert[] {
+                        SSLSocketTemplate.Cert.EE_ECDSA_SECP521R1 };
+            }
+        }
+    }
+
+    protected SSLContext createClientSSLContext() throws Exception {
+        return createSSLContext(trustedCerts, endEntityCerts,
+                getClientContextParameters());
+    }
+
+    protected SSLContext createServerSSLContext() throws Exception {
+        return createSSLContext(trustedCerts, endEntityCerts,
+                getServerContextParameters());
+    }
+
+    // Servers are configured before clients, increment test case after.
+    @Override
+    protected void configureClientSocket(SSLSocket socket) {
+        socket.setEnabledProtocols(new String[] { protocol });
+        socket.setEnabledCipherSuites(new String[] { cipher });
+    }
+
+    @Override
+    protected void configureServerSocket(SSLServerSocket serverSocket) {
+        serverSocket.setEnabledProtocols(new String[] { protocol });
+        serverSocket.setEnabledCipherSuites(new String[] { cipher });
+    }
+
+    public static void main(String[] args) throws Exception {
+        String namedGroup = args[0];
+
+        System.setProperty("jdk.tls.namedGroups", namedGroup);
+        System.out.println("NamedGroup: " + namedGroup);
+
+        for (Protocol protocol : PROTOCOLS) {
+            for (CipherSuite cipherSuite : CIPHER_SUITES) {
+                if (cipherSuite.supportedByProtocol(protocol)
+                        && groupSupportdByCipher(namedGroup, cipherSuite)) {
+                    System.out.printf("Protocol: %s, cipher suite: %s%n",
+                            protocol, cipherSuite);
+
+                    new NamedGroupsWithCipherSuite(protocol.name,
+                            cipherSuite.name(), namedGroup).run();
+                }
+            }
+        }
+    }
+
+    private static boolean groupSupportdByCipher(String group,
+            CipherSuite cipherSuite) {
+        return (group.startsWith("x")
+                        && xdhGroupSupportdByCipher(cipherSuite))
+                || (group.startsWith("secp")
+                        && ecdhGroupSupportdByCipher(cipherSuite))
+                || (group.startsWith("ffdhe")
+                        && ffdhGroupSupportdByCipher(cipherSuite));
+    }
+
+    private static boolean xdhGroupSupportdByCipher(
+            CipherSuite cipherSuite) {
+        return cipherSuite.keyExAlgorithm == null
+                || cipherSuite.keyExAlgorithm == KeyExAlgorithm.ECDHE_RSA;
+    }
+
+    private static boolean ecdhGroupSupportdByCipher(
+            CipherSuite cipherSuite) {
+        return cipherSuite.keyExAlgorithm == null
+                || cipherSuite.keyExAlgorithm == KeyExAlgorithm.ECDHE_RSA
+                || cipherSuite.keyExAlgorithm == KeyExAlgorithm.ECDHE_ECDSA;
+    }
+
+    private static boolean ffdhGroupSupportdByCipher(
+            CipherSuite cipherSuite) {
+        return cipherSuite.keyExAlgorithm == null
+                || cipherSuite.keyExAlgorithm == KeyExAlgorithm.DHE_DSS
+                || cipherSuite.keyExAlgorithm == KeyExAlgorithm.DHE_RSA;
+    }
+}
--- a/test/jdk/sun/security/tools/keytool/PSS.java	Wed Jun 26 15:34:13 2019 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,112 +0,0 @@
-/*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @bug 8215694 8222987
- * @summary keytool cannot generate RSASSA-PSS certificates
- * @library /test/lib
- * @modules java.base/sun.security.util
- *          java.base/sun.security.x509
- * @requires os.family != "solaris"
- * @run main PSS
- */
-
-// This test is excluded from Solaris because the 8192-bit RSA key pair
-// generator is extremely slow there.
-
-import jdk.test.lib.Asserts;
-import jdk.test.lib.SecurityTools;
-import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.security.DerUtils;
-import sun.security.util.ObjectIdentifier;
-import sun.security.x509.AlgorithmId;
-
-import java.io.File;
-import java.security.KeyStore;
-import java.security.cert.X509Certificate;
-
-public class PSS {
-
-    public static void main(String[] args) throws Exception {
-
-        genkeypair("p", "-keyalg RSASSA-PSS -sigalg RSASSA-PSS")
-                .shouldHaveExitValue(0);
-
-        genkeypair("a", "-keyalg RSA -sigalg RSASSA-PSS -keysize 2048")
-                .shouldHaveExitValue(0);
-
-        genkeypair("b", "-keyalg RSA -sigalg RSASSA-PSS -keysize 4096")
-                .shouldHaveExitValue(0);
-
-        genkeypair("c", "-keyalg RSA -sigalg RSASSA-PSS -keysize 8192")
-                .shouldHaveExitValue(0);
-
-        KeyStore ks = KeyStore.getInstance(
-                new File("ks"), "changeit".toCharArray());
-
-        check((X509Certificate)ks.getCertificate("p"), "RSASSA-PSS",
-                AlgorithmId.SHA256_oid);
-
-        check((X509Certificate)ks.getCertificate("a"), "RSA",
-                AlgorithmId.SHA256_oid);
-
-        check((X509Certificate)ks.getCertificate("b"), "RSA",
-                AlgorithmId.SHA384_oid);
-
-        check((X509Certificate)ks.getCertificate("c"), "RSA",
-                AlgorithmId.SHA512_oid);
-
-        // More commands
-        kt("-certreq -alias p -sigalg RSASSA-PSS -file p.req")
-                .shouldHaveExitValue(0);
-
-        kt("-gencert -alias a -sigalg RSASSA-PSS -infile p.req -outfile p.cert")
-                .shouldHaveExitValue(0);
-
-        kt("-importcert -alias p -file p.cert")
-                .shouldHaveExitValue(0);
-
-        kt("-selfcert -alias p -sigalg RSASSA-PSS")
-                .shouldHaveExitValue(0);
-    }
-
-    static OutputAnalyzer genkeypair(String alias, String options)
-            throws Exception {
-        return kt("-genkeypair -alias " + alias
-                + " -dname CN=" + alias + " " + options);
-    }
-
-    static OutputAnalyzer kt(String cmd)
-            throws Exception {
-        return SecurityTools.keytool("-storepass changeit -keypass changeit "
-                + "-keystore ks " + cmd);
-    }
-
-    static void check(X509Certificate cert, String expectedKeyAlg,
-            ObjectIdentifier expectedMdAlg) throws Exception {
-        Asserts.assertEQ(cert.getPublicKey().getAlgorithm(), expectedKeyAlg);
-        Asserts.assertEQ(cert.getSigAlgName(), "RSASSA-PSS");
-        DerUtils.checkAlg(cert.getSigAlgParams(), "000", expectedMdAlg);
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sun/security/tools/keytool/pss/PSS.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8215694 8222987 8225257
+ * @summary keytool cannot generate RSASSA-PSS certificates
+ * @library /test/lib
+ * @build java.base/sun.security.rsa.RSAKeyPairGenerator
+ * @modules java.base/sun.security.util
+ *          java.base/sun.security.x509
+ * @requires os.family != "solaris"
+ * @run main PSS
+ */
+
+// This test is excluded from Solaris because the 8192-bit RSA key pair
+// generator is extremely slow there.
+
+import jdk.test.lib.Asserts;
+import jdk.test.lib.SecurityTools;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.security.DerUtils;
+import sun.security.util.ObjectIdentifier;
+import sun.security.x509.AlgorithmId;
+
+import java.io.File;
+import java.security.KeyStore;
+import java.security.cert.X509Certificate;
+
+public class PSS {
+
+    public static void main(String[] args) throws Exception {
+
+        genkeypair("p", "-keyalg RSASSA-PSS -sigalg RSASSA-PSS")
+                .shouldHaveExitValue(0);
+
+        genkeypair("a", "-keyalg RSA -sigalg RSASSA-PSS -keysize 2048")
+                .shouldHaveExitValue(0);
+
+        genkeypair("b", "-keyalg RSA -sigalg RSASSA-PSS -keysize 4096")
+                .shouldHaveExitValue(0);
+
+        genkeypair("c", "-keyalg RSA -sigalg RSASSA-PSS -keysize 8192")
+                .shouldHaveExitValue(0);
+
+        KeyStore ks = KeyStore.getInstance(
+                new File("ks"), "changeit".toCharArray());
+
+        check((X509Certificate)ks.getCertificate("p"), "RSASSA-PSS",
+                AlgorithmId.SHA256_oid);
+
+        check((X509Certificate)ks.getCertificate("a"), "RSA",
+                AlgorithmId.SHA256_oid);
+
+        check((X509Certificate)ks.getCertificate("b"), "RSA",
+                AlgorithmId.SHA384_oid);
+
+        check((X509Certificate)ks.getCertificate("c"), "RSA",
+                AlgorithmId.SHA512_oid);
+
+        // More commands
+        kt("-certreq -alias p -sigalg RSASSA-PSS -file p.req")
+                .shouldHaveExitValue(0);
+
+        kt("-gencert -alias a -sigalg RSASSA-PSS -infile p.req -outfile p.cert")
+                .shouldHaveExitValue(0);
+
+        kt("-importcert -alias p -file p.cert")
+                .shouldHaveExitValue(0);
+
+        kt("-selfcert -alias p -sigalg RSASSA-PSS")
+                .shouldHaveExitValue(0);
+    }
+
+    static OutputAnalyzer genkeypair(String alias, String options)
+            throws Exception {
+        String patchArg = "-J--patch-module=java.base=" + System.getProperty("test.classes")
+                + File.separator + "patches" + File.separator + "java.base";
+        return kt(patchArg + " -genkeypair -alias " + alias
+                + " -dname CN=" + alias + " " + options);
+    }
+
+    static OutputAnalyzer kt(String cmd)
+            throws Exception {
+        return SecurityTools.keytool("-storepass changeit -keypass changeit "
+                + "-keystore ks " + cmd);
+    }
+
+    static void check(X509Certificate cert, String expectedKeyAlg,
+            ObjectIdentifier expectedMdAlg) throws Exception {
+        Asserts.assertEQ(cert.getPublicKey().getAlgorithm(), expectedKeyAlg);
+        Asserts.assertEQ(cert.getSigAlgName(), "RSASSA-PSS");
+        DerUtils.checkAlg(cert.getSigAlgParams(), "000", expectedMdAlg);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sun/security/tools/keytool/pss/java.base/sun/security/rsa/RSAKeyPairGenerator.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,273 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.rsa;
+
+import java.math.BigInteger;
+
+import java.security.*;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.RSAKeyGenParameterSpec;
+
+import sun.security.jca.JCAUtil;
+import sun.security.x509.AlgorithmId;
+import static sun.security.rsa.RSAUtil.KeyType;
+
+/**
+ * Fake RSA keypair generation.
+ */
+public abstract class RSAKeyPairGenerator extends KeyPairGeneratorSpi {
+
+    // public exponent to use
+    private BigInteger publicExponent;
+
+    // size of the key to generate, >= RSAKeyFactory.MIN_MODLEN
+    private int keySize;
+
+    private final KeyType type;
+    private AlgorithmId rsaId;
+
+    RSAKeyPairGenerator(KeyType type, int defKeySize) {
+        this.type = type;
+        // initialize to default in case the app does not call initialize()
+        initialize(defKeySize, null);
+    }
+
+    // initialize the generator. See JCA doc
+    public void initialize(int keySize, SecureRandom random) {
+        try {
+            initialize(new RSAKeyGenParameterSpec(keySize,
+                    RSAKeyGenParameterSpec.F4), random);
+        } catch (InvalidAlgorithmParameterException iape) {
+            throw new InvalidParameterException(iape.getMessage());
+        }
+    }
+
+    // second initialize method. See JCA doc.
+    public void initialize(AlgorithmParameterSpec params, SecureRandom random)
+            throws InvalidAlgorithmParameterException {
+        if (params instanceof RSAKeyGenParameterSpec == false) {
+            throw new InvalidAlgorithmParameterException
+                ("Params must be instance of RSAKeyGenParameterSpec");
+        }
+
+        RSAKeyGenParameterSpec rsaSpec = (RSAKeyGenParameterSpec)params;
+        int tmpKeySize = rsaSpec.getKeysize();
+        BigInteger tmpPublicExponent = rsaSpec.getPublicExponent();
+        AlgorithmParameterSpec tmpParams = rsaSpec.getKeyParams();
+
+        if (tmpPublicExponent == null) {
+            tmpPublicExponent = RSAKeyGenParameterSpec.F4;
+        } else {
+            if (tmpPublicExponent.compareTo(RSAKeyGenParameterSpec.F0) < 0) {
+                throw new InvalidAlgorithmParameterException
+                        ("Public exponent must be 3 or larger");
+            }
+            if (tmpPublicExponent.bitLength() > tmpKeySize) {
+                throw new InvalidAlgorithmParameterException
+                        ("Public exponent must be smaller than key size");
+            }
+        }
+
+        // do not allow unreasonably large key sizes, probably user error
+        try {
+            RSAKeyFactory.checkKeyLengths(tmpKeySize, tmpPublicExponent,
+                512, 64 * 1024);
+        } catch (InvalidKeyException e) {
+            throw new InvalidAlgorithmParameterException(
+                "Invalid key sizes", e);
+        }
+
+        try {
+            this.rsaId = RSAUtil.createAlgorithmId(type, tmpParams);
+        } catch (ProviderException e) {
+            throw new InvalidAlgorithmParameterException(
+                "Invalid key parameters", e);
+        }
+
+        this.keySize = tmpKeySize;
+        this.publicExponent = tmpPublicExponent;
+    }
+
+    // generate the keypair. See JCA doc
+    public KeyPair generateKeyPair() {
+
+        // accommodate odd key sizes in case anybody wants to use them
+        BigInteger e = publicExponent;
+        if (!e.equals(RSAKeyGenParameterSpec.F4)) {
+            throw new AssertionError("Only support F4 now");
+        }
+        BigInteger p, q, n;
+
+        // Pre-calculated p and q for e == RSAKeyGenParameterSpec.F4
+        switch (keySize) {
+            case 2048:
+                p = new BigInteger("1600840041787354447543653385760927"
+                        + "2642568308955833364523274045522752644800599"
+                        + "8669541532595690224703734511692014533312515"
+                        + "1867029838883431415692353449578487671384896"
+                        + "6611685764860941767986520897595108597563035"
+                        + "4023785639802607792535812062420427283857665"
+                        + "9883578590844700707106157871508280052743363"
+                        + "65749456332400771");
+                q = new BigInteger("1303880717101677622201474394769850"
+                        + "7257196073324816341282215626935164930077468"
+                        + "5999131251387556761167658937349436378464220"
+                        + "4831804147777472146628148336776639855791417"
+                        + "3849903041999943901924899580268176393595653"
+                        + "7357080543898614581363167420619163047562600"
+                        + "6155574020606891195960345238780709194499010"
+                        + "43652862954645301");
+                break;
+            case 4096:
+                p = new BigInteger("2985635754414679487171962796211911"
+                        + "1563710734938215274736352092606404045130913"
+                        + "2477365484439939846705721840432140066578525"
+                        + "0762327458086280430118434094733412377416194"
+                        + "8736124795243564050755767519346747209606612"
+                        + "5835460937739428885308798309679495432910469"
+                        + "0294757621321446003970767164933974474924664"
+                        + "1513767092845098947552598109657871041666676"
+                        + "2945573325433283821164032766425479703026349"
+                        + "9433641551427112483593214628620450175257586"
+                        + "4350119143877183562692754400346175237007314"
+                        + "7121580349193179272551363894896336921717843"
+                        + "3734726842184251708799134654802475890197293"
+                        + "9094908310578403843742664173424031260840446"
+                        + "591633359364559754200663");
+                q = new BigInteger("2279248439141087793789384816271625"
+                        + "1304008816573950275844533962181244003563987"
+                        + "6638461665174020058827698592331066726709304"
+                        + "9231319346136709972639455506783245161859951"
+                        + "6191872757335765533547033659834427437142631"
+                        + "3801232751161907082392011429712327250253948"
+                        + "6012497852063361866175243227579880020724881"
+                        + "9393797645220239009219998518884396282407710"
+                        + "7199202450846395844337846503427790307364624"
+                        + "5124871273035872938616425951596065309519651"
+                        + "1519189356431513094684173807318945903212527"
+                        + "7712469749366620048658571121822171067675915"
+                        + "5479178304648399924549334007222294762969503"
+                        + "5341584429803583589276956979963609078497238"
+                        + "760757619468018224491053");
+                break;
+            case 8192:
+                p = new BigInteger("9821669838446774374944535804569858"
+                        + "0553278885576950130485823829973470553571905"
+                        + "3014418421996241500307589880457361653957913"
+                        + "9176499436767288125182942994089196450118944"
+                        + "8701794862752733776161684616570463744619126"
+                        + "4981622564763630694110472008409561205704867"
+                        + "0221819623405201369630462487520858670679048"
+                        + "5854008441429858453634949980424333056803703"
+                        + "1205609490778445762604050796894221725977551"
+                        + "1428887194691696420765173256600200430067305"
+                        + "4364524177041858044598166859757042904625691"
+                        + "4292728453597609683799189454690202563236931"
+                        + "8171122071288244573793276051041975005528757"
+                        + "0228306442708182141334279133965507583927772"
+                        + "9244311696220253059281524393613278272067808"
+                        + "7017494446447670799055720358621918361716353"
+                        + "5018317015764698318012095108914870478138809"
+                        + "8204738169777192718869484177321870413838036"
+                        + "8149216482968887382371881239714335470844573"
+                        + "1862934371951394070111726593305334971041399"
+                        + "5517260339034138718517336990212463882142363"
+                        + "9154412320743552301967162100734381046548816"
+                        + "3883737645359595416600487444018399886391071"
+                        + "3777667222706059170707223589163679915863781"
+                        + "4662302526078720977228426750718207481384357"
+                        + "7918717041190413457052439016978578217755022"
+                        + "7370720979516554707297685239584071755267452"
+                        + "6021894842754355160100506065457679069228273"
+                        + "95209345267367982516553449135291473361");
+                q = new BigInteger("7902448465953646210110784092684896"
+                        + "0265474424590294110174550047938700740921014"
+                        + "1981650823416127449143596912363210790070524"
+                        + "2903784112701128957948996730263815210531364"
+                        + "0489145287401377007608600217628773627723381"
+                        + "1194123533939872283952535576847014977682278"
+                        + "9332064706645169741712060131540562788886577"
+                        + "3762235020990267901959745687867018811088495"
+                        + "3716021011509120447248882358515954471433808"
+                        + "2782236662758287959413069553620728137831579"
+                        + "2321174813204514354999978428741310035945405"
+                        + "0226661395731921098764192439072425262100813"
+                        + "9732949866553839713092238096261034339815187"
+                        + "2832617055364163276140160068136296115910569"
+                        + "9466440903693740716929166334256441926903849"
+                        + "1082968246155177124035336609654226388424434"
+                        + "5775783323612758615407928446164631651292743"
+                        + "8428509642959278732826297890909454571009075"
+                        + "7836191622138731918099379467912681177757761"
+                        + "6141378131042432093843778753846726589215845"
+                        + "7402160146427434508515156204064224022904659"
+                        + "8645441448874409852211668374267341177082462"
+                        + "7341410218867175406105046487057429530801973"
+                        + "0931082058719258230993681115780999537424968"
+                        + "2385515792331573549935317407789344892257264"
+                        + "7464569110078675090194686816764429827739815"
+                        + "0566036514181547634372488184242167294602000"
+                        + "8232780963578241583529875079397308150506597"
+                        + "37190564909892937290776929541076192569");
+                break;
+            default:
+                throw new AssertionError("Unknown keySize " + keySize);
+        }
+
+        n = p.multiply(q);
+
+        // phi = (p - 1) * (q - 1) must be relative prime to e
+        // otherwise RSA just won't work ;-)
+        BigInteger p1 = p.subtract(BigInteger.ONE);
+        BigInteger q1 = q.subtract(BigInteger.ONE);
+        BigInteger phi = p1.multiply(q1);
+        // generate new p and q until they work. typically
+        // the first try will succeed when using F4
+        if (e.gcd(phi).equals(BigInteger.ONE) == false) {
+            throw new AssertionError("Should not happen");
+        }
+
+        // private exponent d is the inverse of e mod phi
+        BigInteger d = e.modInverse(phi);
+
+        // 1st prime exponent pe = d mod (p - 1)
+        BigInteger pe = d.mod(p1);
+        // 2nd prime exponent qe = d mod (q - 1)
+        BigInteger qe = d.mod(q1);
+
+        // crt coefficient coeff is the inverse of q mod p
+        BigInteger coeff = q.modInverse(p);
+
+        try {
+            PublicKey publicKey = new RSAPublicKeyImpl(rsaId, n, e);
+            PrivateKey privateKey = new RSAPrivateCrtKeyImpl(
+                    rsaId, n, e, d, p, q, pe, qe, coeff);
+            return new KeyPair(publicKey, privateKey);
+        } catch (InvalidKeyException exc) {
+            // invalid key exception only thrown for keys < 512 bit,
+            // will not happen here
+            throw new RuntimeException(exc);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sun/util/locale/provider/CalendarDataRegression.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8226876
+ * @summary Test CalendarDataUtility class not throwing AssertionError
+ * @run main/othervm -ea -esa -Djava.locale.providers=HOST CalendarDataRegression
+ */
+
+import java.text.DateFormat;
+import java.util.Locale;
+
+public class CalendarDataRegression {
+    public static void main(String[] args) {
+        // Host locale provider on Windows returns 0 for
+        // firstDayOfWeek/minimalDaysInFirstWeek, which should
+        // default to non-zero value. Otherwise AssertionError
+        // will be thrown.
+        DateFormat.getDateInstance(DateFormat.FULL, Locale.US);
+    }
+}
--- a/test/langtools/tools/javac/diags/examples/BreakOutsideSwitchExpression.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/langtools/tools/javac/diags/examples/BreakOutsideSwitchExpression.java	Mon Jul 01 14:57:02 2019 -0700
@@ -30,7 +30,8 @@
     int t(int i) {
         OUT: while (true) {
             return switch (i) {
-                default: break OUT;
+                case 0: break OUT;
+                default: yield 0;
             };
         }
         return -1;
--- a/test/langtools/tools/javac/diags/examples/ContinueOutsideSwitchExpression.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/langtools/tools/javac/diags/examples/ContinueOutsideSwitchExpression.java	Mon Jul 01 14:57:02 2019 -0700
@@ -30,7 +30,8 @@
     int t(int i) {
         OUT: while (true) {
             return switch (i) {
-                default: continue OUT;
+                case 0: continue OUT;
+                default: yield 0;
             };
         }
     }
--- a/test/langtools/tools/javac/diags/examples/ReturnOutsideSwitchExpression.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/langtools/tools/javac/diags/examples/ReturnOutsideSwitchExpression.java	Mon Jul 01 14:57:02 2019 -0700
@@ -29,7 +29,8 @@
 class ReturnOutsideSwitchExpression {
     int t(int i) {
         return switch (i) {
-            default: return -1;
+            case 0: return -1;
+            default: yield 0;
         };
     }
 }
--- a/test/langtools/tools/javac/diags/examples/RuleCompletesNormally.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/langtools/tools/javac/diags/examples/RuleCompletesNormally.java	Mon Jul 01 14:57:02 2019 -0700
@@ -29,7 +29,8 @@
 class RuleCompletesNormally {
     public String convert(int i) {
         return switch (i) {
-            default -> {}
+            case 0 -> {}
+            default -> "";
         };
     }
 }
--- a/test/langtools/tools/javac/diags/examples/SwitchExpressionCompletesNormally.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/langtools/tools/javac/diags/examples/SwitchExpressionCompletesNormally.java	Mon Jul 01 14:57:02 2019 -0700
@@ -29,6 +29,7 @@
 class SwitchExpressionCompletesNormally {
     public String convert(int i) {
         return switch (i) {
+            case 0: yield "";
             default:
         };
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/diags/examples/SwitchExpressionNoResultExpressions.java	Mon Jul 01 14:57:02 2019 -0700
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.switch.expression.no.result.expressions
+// key: compiler.note.preview.filename
+// key: compiler.note.preview.recompile
+// options: --enable-preview -source ${jdk.version}
+
+class SwitchExpressionCompletesNormally {
+    public String convert(int i) {
+        return switch (i) {
+            default -> throw new AssertionError();
+        };
+    }
+}
--- a/test/langtools/tools/javac/switchexpr/EmptySwitch.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/langtools/tools/javac/switchexpr/EmptySwitch.java	Mon Jul 01 14:57:02 2019 -0700
@@ -23,15 +23,29 @@
 
 /*
  * @test
- * @bug 8206986
- * @summary Verify than an empty switch expression is rejected.
- * @compile/fail/ref=EmptySwitch.out --enable-preview -source ${jdk.version} -XDrawDiagnostics EmptySwitch.java
+ * @bug 8206986 8226510
+ * @summary Verify than a switch that does not yield a value is rejected.
+ * @compile/fail/ref=EmptySwitch.out --enable-preview -source ${jdk.version} -XDrawDiagnostics -XDshould-stop.at=FLOW EmptySwitch.java
  */
 
 public class EmptySwitch {
     private void print(EmptySwitchEnum t) {
         (switch (t) {
         }).toString();
+        (switch (t) {
+            default -> throw new IllegalStateException();
+        }).toString();
+        (switch (t) {
+            default: throw new IllegalStateException();
+        }).toString();
+        (switch (0) {
+            case 0: yield "";
+            default:
+        }).toString();
+        (switch (0) {
+            case 0 -> { yield ""; }
+            default -> { }
+        }).toString();
     }
 
     enum EmptySwitchEnum {
--- a/test/langtools/tools/javac/switchexpr/EmptySwitch.out	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/langtools/tools/javac/switchexpr/EmptySwitch.out	Mon Jul 01 14:57:02 2019 -0700
@@ -1,4 +1,8 @@
 EmptySwitch.java:33:10: compiler.err.switch.expression.empty
+EmptySwitch.java:35:10: compiler.err.switch.expression.no.result.expressions
+EmptySwitch.java:38:10: compiler.err.switch.expression.no.result.expressions
+EmptySwitch.java:44:9: compiler.err.switch.expression.completes.normally
+EmptySwitch.java:47:26: compiler.err.rule.completes.normally
 - compiler.note.preview.filename: EmptySwitch.java
 - compiler.note.preview.recompile
-1 error
+5 errors
--- a/test/langtools/tools/javac/switchexpr/ExpressionSwitchBreaks2.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/langtools/tools/javac/switchexpr/ExpressionSwitchBreaks2.java	Mon Jul 01 14:57:02 2019 -0700
@@ -41,9 +41,11 @@
         }
         }
         j: print(switch (i) {
+            case 0: yield 0;
             default: break j;
         }, 0);
         j2: print(switch (i) {
+            case 0: yield 0;
             default: break j2;
         }, 0);
         return null;
--- a/test/langtools/tools/javac/switchexpr/ExpressionSwitchBreaks2.out	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/langtools/tools/javac/switchexpr/ExpressionSwitchBreaks2.out	Mon Jul 01 14:57:02 2019 -0700
@@ -5,8 +5,8 @@
 ExpressionSwitchBreaks2.java:30:29: compiler.err.undef.label: UNKNOWN
 ExpressionSwitchBreaks2.java:40:17: compiler.err.no.switch.expression
 ExpressionSwitchBreaks2.java:40:29: compiler.err.cant.resolve.location: kindname.variable, undef, , , (compiler.misc.location: kindname.class, ExpressionSwitchBreaks2, null)
-ExpressionSwitchBreaks2.java:44:22: compiler.err.break.outside.switch.expression
-ExpressionSwitchBreaks2.java:47:22: compiler.err.break.outside.switch.expression
+ExpressionSwitchBreaks2.java:45:22: compiler.err.break.outside.switch.expression
+ExpressionSwitchBreaks2.java:49:22: compiler.err.break.outside.switch.expression
 - compiler.note.preview.filename: ExpressionSwitchBreaks2.java
 - compiler.note.preview.recompile
-9 errors
+9 errors
\ No newline at end of file
--- a/test/langtools/tools/javac/switchexpr/ExpressionSwitchFlow.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/langtools/tools/javac/switchexpr/ExpressionSwitchFlow.java	Mon Jul 01 14:57:02 2019 -0700
@@ -22,6 +22,7 @@
     private String test3(int i) {
         return switch (i) {
             case 0 -> {}
+            case 1 -> "";
             default -> throw new IllegalStateException();
         };
     }
@@ -40,17 +41,20 @@
     private String test6(int i) {
         return switch (i) {
             case 0 -> throw new IllegalStateException();
+            case 1 -> "";
             default -> {}
         };
     }
     private String test7(int i) {
         return switch (i) {
             case 0: throw new IllegalStateException();
+            case 1: yield "";
             default:
         };
     }
     private String test8(int i) {
         return switch (i) {
+            case 1: yield "";
             case 0: i++;
             default: {
             }
@@ -58,6 +62,7 @@
     }
     private String test9(int i) {
         return switch (i) {
+            case 1: yield "";
             case 0:
             default:
                 System.err.println();
--- a/test/langtools/tools/javac/switchexpr/ExpressionSwitchFlow.out	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/langtools/tools/javac/switchexpr/ExpressionSwitchFlow.out	Mon Jul 01 14:57:02 2019 -0700
@@ -1,12 +1,12 @@
 ExpressionSwitchFlow.java:11:24: compiler.err.rule.completes.normally
 ExpressionSwitchFlow.java:18:13: compiler.err.rule.completes.normally
 ExpressionSwitchFlow.java:24:24: compiler.err.rule.completes.normally
-ExpressionSwitchFlow.java:31:25: compiler.err.rule.completes.normally
-ExpressionSwitchFlow.java:37:25: compiler.err.rule.completes.normally
-ExpressionSwitchFlow.java:43:25: compiler.err.rule.completes.normally
-ExpressionSwitchFlow.java:50:9: compiler.err.switch.expression.completes.normally
-ExpressionSwitchFlow.java:57:9: compiler.err.switch.expression.completes.normally
-ExpressionSwitchFlow.java:64:9: compiler.err.switch.expression.completes.normally
+ExpressionSwitchFlow.java:32:25: compiler.err.rule.completes.normally
+ExpressionSwitchFlow.java:38:25: compiler.err.rule.completes.normally
+ExpressionSwitchFlow.java:45:25: compiler.err.rule.completes.normally
+ExpressionSwitchFlow.java:53:9: compiler.err.switch.expression.completes.normally
+ExpressionSwitchFlow.java:61:9: compiler.err.switch.expression.completes.normally
+ExpressionSwitchFlow.java:69:9: compiler.err.switch.expression.completes.normally
 - compiler.note.preview.filename: ExpressionSwitchFlow.java
 - compiler.note.preview.recompile
 9 errors
--- a/test/langtools/tools/javac/switchexpr/WrongBreakTest.out	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/langtools/tools/javac/switchexpr/WrongBreakTest.out	Mon Jul 01 14:57:02 2019 -0700
@@ -1,8 +1,9 @@
 WrongBreakTest.java:36:41: compiler.err.illegal.start.of.expr
 WrongBreakTest.java:35:39: compiler.err.break.outside.switch.expression
+WrongBreakTest.java:35:17: compiler.err.switch.expression.no.result.expressions
 WrongBreakTest.java:36:9: compiler.err.ref.ambiguous: test, kindname.method, test(int), WrongBreakTest, kindname.method, test(java.lang.Object), WrongBreakTest
 WrongBreakTest.java:38:13: compiler.err.no.switch.expression
 WrongBreakTest.java:41:13: compiler.err.no.switch.expression
 - compiler.note.preview.filename: WrongBreakTest.java
 - compiler.note.preview.recompile
-5 errors
+6 errors
--- a/test/lib/jdk/test/lib/containers/cgroup/MetricsTester.java	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/lib/jdk/test/lib/containers/cgroup/MetricsTester.java	Mon Jul 01 14:57:02 2019 -0700
@@ -560,7 +560,7 @@
         long memoryMaxUsage = metrics.getMemoryMaxUsage();
         long memoryUsage = metrics.getMemoryUsage();
 
-        long[] ll = new long[64*1024*1024]; // 64M
+        byte[] bb = new byte[64*1024*1024]; // 64M
 
         long newMemoryMaxUsage = metrics.getMemoryMaxUsage();
         long newMemoryUsage = metrics.getMemoryUsage();
--- a/test/make/TestMake.gmk	Wed Jun 26 15:34:13 2019 -0700
+++ b/test/make/TestMake.gmk	Mon Jul 01 14:57:02 2019 -0700
@@ -46,7 +46,8 @@
 
 all: $(TARGETS)
 
+# Prints targets to TARGETS_FILE which must be set when calling this target.
 print-targets:
-	$(ECHO) "$(TARGETS)"
+	$(ECHO) "$(TARGETS)" >> $(TARGETS_FILE)
 
 .PHONY: default all $(TARGETS)