Merge
authorjwilhelm
Sun, 25 Feb 2018 04:59:43 +0100
changeset 49067 c153e9daadce
parent 49003 64fafabcdb21 (current diff)
parent 49066 4aa67aba6c85 (diff)
child 49068 3e0cdbf86d2c
Merge
make/common/MakeBase.gmk
src/hotspot/share/classfile/vmSymbols.hpp
src/hotspot/share/logging/logSelectionList.cpp
src/hotspot/share/logging/logSelectionList.hpp
src/hotspot/share/logging/logTagLevelExpression.cpp
src/hotspot/share/logging/logTagLevelExpression.hpp
src/hotspot/share/memory/universe.cpp
src/hotspot/share/memory/universe.hpp
src/hotspot/share/oops/arrayOop.inline.hpp
src/hotspot/share/runtime/thread.cpp
src/hotspot/share/services/allocationContextService.hpp
src/java.base/share/classes/java/lang/ClassLoader.java
test/hotspot/gtest/logging/test_logSelectionList.cpp
test/hotspot/gtest/logging/test_logTagLevelExpression.cpp
test/jdk/com/sun/jdi/JDIScaffold.java
--- a/make/common/MakeBase.gmk	Wed Feb 28 15:28:46 2018 +0100
+++ b/make/common/MakeBase.gmk	Sun Feb 25 04:59:43 2018 +0100
@@ -423,7 +423,7 @@
 
 ################################################################################
 
-MAX_PARAMS := 35
+MAX_PARAMS := 36
 PARAM_SEQUENCE := $(call sequence, 2, $(MAX_PARAMS))
 
 # Template for creating a macro taking named parameters. To use it, assign the
--- a/make/hotspot/lib/CompileGtest.gmk	Wed Feb 28 15:28:46 2018 +0100
+++ b/make/hotspot/lib/CompileGtest.gmk	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+# 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
@@ -87,6 +87,7 @@
     DISABLED_WARNINGS_clang := undef switch format-nonliteral \
         tautological-undefined-compare $(BUILD_LIBJVM_DISABLED_WARNINGS_clang), \
     DISABLED_WARNINGS_solstudio := identexpected, \
+    DISABLED_WARNINGS_CXX_microsoft := 4996, \
     LDFLAGS := $(JVM_LDFLAGS), \
     LDFLAGS_solaris := -library=stlport4 $(call SET_SHARED_LIBRARY_ORIGIN), \
     LDFLAGS_aix := -bbigtoc, \
--- a/make/lib/Lib-jdk.jdwp.agent.gmk	Wed Feb 28 15:28:46 2018 +0100
+++ b/make/lib/Lib-jdk.jdwp.agent.gmk	Sun Feb 25 04:59:43 2018 +0100
@@ -43,7 +43,6 @@
     OPTIMIZATION := LOW, \
     CFLAGS := $(CFLAGS_JDKLIB) -DUSE_MMAP \
         $(LIBDT_SOCKET_CPPFLAGS), \
-    DISABLED_WARNINGS_gcc := shift-negative-value, \
     MAPFILE := $(TOPDIR)/make/mapfiles/libdt_socket/mapfile-vers, \
     LDFLAGS := $(LDFLAGS_JDKLIB) \
         $(call SET_SHARED_LIBRARY_ORIGIN), \
--- a/make/nashorn/package-list	Wed Feb 28 15:28:46 2018 +0100
+++ b/make/nashorn/package-list	Sun Feb 25 04:59:43 2018 +0100
@@ -261,7 +261,6 @@
 jdk.jshell.execution
 jdk.jshell.spi
 jdk.jshell.tool
-jdk.management.cmm
 jdk.management.jfr
 jdk.management.resource
 jdk.nashorn.api.scripting
--- a/src/hotspot/cpu/aarch64/c1_Runtime1_aarch64.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/cpu/aarch64/c1_Runtime1_aarch64.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -684,14 +684,14 @@
         }
 
         if ((id == fast_new_instance_id || id == fast_new_instance_init_check_id) &&
-            UseTLAB && FastTLABRefill) {
+            UseTLAB && Universe::heap()->supports_inline_contig_alloc()) {
           Label slow_path;
           Register obj_size = r2;
           Register t1       = r19;
           Register t2       = r4;
           assert_different_registers(klass, obj, obj_size, t1, t2);
 
-          __ stp(r5, r19, Address(__ pre(sp, -2 * wordSize)));
+          __ stp(r19, zr, Address(__ pre(sp, -2 * wordSize)));
 
           if (id == fast_new_instance_init_check_id) {
             // make sure the klass is initialized
@@ -716,24 +716,6 @@
           }
 #endif // ASSERT
 
-          // if we got here then the TLAB allocation failed, so try
-          // refilling the TLAB or allocating directly from eden.
-          Label retry_tlab, try_eden;
-          __ tlab_refill(retry_tlab, try_eden, slow_path); // does not destroy r3 (klass), returns r5
-
-          __ bind(retry_tlab);
-
-          // get the instance size (size is postive so movl is fine for 64bit)
-          __ ldrw(obj_size, Address(klass, Klass::layout_helper_offset()));
-
-          __ tlab_allocate(obj, obj_size, 0, t1, t2, slow_path);
-
-          __ initialize_object(obj, klass, obj_size, 0, t1, t2, /* is_tlab_allocated */ true);
-          __ verify_oop(obj);
-          __ ldp(r5, r19, Address(__ post(sp, 2 * wordSize)));
-          __ ret(lr);
-
-          __ bind(try_eden);
           // get the instance size (size is postive so movl is fine for 64bit)
           __ ldrw(obj_size, Address(klass, Klass::layout_helper_offset()));
 
@@ -742,11 +724,11 @@
 
           __ initialize_object(obj, klass, obj_size, 0, t1, t2, /* is_tlab_allocated */ false);
           __ verify_oop(obj);
-          __ ldp(r5, r19, Address(__ post(sp, 2 * wordSize)));
+          __ ldp(r19, zr, Address(__ post(sp, 2 * wordSize)));
           __ ret(lr);
 
           __ bind(slow_path);
-          __ ldp(r5, r19, Address(__ post(sp, 2 * wordSize)));
+          __ ldp(r19, zr, Address(__ post(sp, 2 * wordSize)));
         }
 
         __ enter();
@@ -814,7 +796,7 @@
         }
 #endif // ASSERT
 
-        if (UseTLAB && FastTLABRefill) {
+        if (UseTLAB && Universe::heap()->supports_inline_contig_alloc()) {
           Register arr_size = r4;
           Register t1       = r2;
           Register t2       = r5;
@@ -826,45 +808,10 @@
           __ cmpw(length, rscratch1);
           __ br(Assembler::HI, slow_path);
 
-          // if we got here then the TLAB allocation failed, so try
-          // refilling the TLAB or allocating directly from eden.
-          Label retry_tlab, try_eden;
-          const Register thread =
-            __ tlab_refill(retry_tlab, try_eden, slow_path); // preserves r19 & r3, returns rthread
-
-          __ bind(retry_tlab);
-
           // get the allocation size: round_up(hdr + length << (layout_helper & 0x1F))
           // since size is positive ldrw does right thing on 64bit
           __ ldrw(t1, Address(klass, Klass::layout_helper_offset()));
-          __ lslvw(arr_size, length, t1);
-          __ ubfx(t1, t1, Klass::_lh_header_size_shift,
-                  exact_log2(Klass::_lh_header_size_mask + 1));
-          __ add(arr_size, arr_size, t1);
-          __ add(arr_size, arr_size, MinObjAlignmentInBytesMask); // align up
-          __ andr(arr_size, arr_size, ~MinObjAlignmentInBytesMask);
-
-          __ tlab_allocate(obj, arr_size, 0, t1, t2, slow_path);  // preserves arr_size
-
-          __ initialize_header(obj, klass, length, t1, t2);
-          __ ldrb(t1, Address(klass, in_bytes(Klass::layout_helper_offset()) + (Klass::_lh_header_size_shift / BitsPerByte)));
-          assert(Klass::_lh_header_size_shift % BitsPerByte == 0, "bytewise");
-          assert(Klass::_lh_header_size_mask <= 0xFF, "bytewise");
-          __ andr(t1, t1, Klass::_lh_header_size_mask);
-          __ sub(arr_size, arr_size, t1);  // body length
-          __ add(t1, t1, obj);       // body start
-          if (!ZeroTLAB) {
-           __ initialize_body(t1, arr_size, 0, t2);
-          }
-          __ verify_oop(obj);
-
-          __ ret(lr);
-
-          __ bind(try_eden);
-          // get the allocation size: round_up(hdr + length << (layout_helper & 0x1F))
-          // since size is positive ldrw does right thing on 64bit
-          __ ldrw(t1, Address(klass, Klass::layout_helper_offset()));
-          // since size is postive movw does right thing on 64bit
+          // since size is positive movw does right thing on 64bit
           __ movw(arr_size, length);
           __ lslvw(arr_size, length, t1);
           __ ubfx(t1, t1, Klass::_lh_header_size_shift,
@@ -874,7 +821,7 @@
           __ andr(arr_size, arr_size, ~MinObjAlignmentInBytesMask);
 
           __ eden_allocate(obj, arr_size, 0, t1, slow_path);  // preserves arr_size
-          __ incr_allocated_bytes(thread, arr_size, 0, rscratch1);
+          __ incr_allocated_bytes(rthread, arr_size, 0, rscratch1);
 
           __ initialize_header(obj, klass, length, t1, t2);
           __ ldrb(t1, Address(klass, in_bytes(Klass::layout_helper_offset()) + (Klass::_lh_header_size_shift / BitsPerByte)));
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -4096,131 +4096,6 @@
   // verify_tlab();
 }
 
-// Preserves r19, and r3.
-Register MacroAssembler::tlab_refill(Label& retry,
-                                     Label& try_eden,
-                                     Label& slow_case) {
-  Register top = r0;
-  Register t1  = r2;
-  Register t2  = r4;
-  assert_different_registers(top, rthread, t1, t2, /* preserve: */ r19, r3);
-  Label do_refill, discard_tlab;
-
-  if (!Universe::heap()->supports_inline_contig_alloc()) {
-    // No allocation in the shared eden.
-    b(slow_case);
-  }
-
-  ldr(top, Address(rthread, in_bytes(JavaThread::tlab_top_offset())));
-  ldr(t1,  Address(rthread, in_bytes(JavaThread::tlab_end_offset())));
-
-  // calculate amount of free space
-  sub(t1, t1, top);
-  lsr(t1, t1, LogHeapWordSize);
-
-  // Retain tlab and allocate object in shared space if
-  // the amount free in the tlab is too large to discard.
-
-  ldr(rscratch1, Address(rthread, in_bytes(JavaThread::tlab_refill_waste_limit_offset())));
-  cmp(t1, rscratch1);
-  br(Assembler::LE, discard_tlab);
-
-  // Retain
-  // ldr(rscratch1, Address(rthread, in_bytes(JavaThread::tlab_refill_waste_limit_offset())));
-  mov(t2, (int32_t) ThreadLocalAllocBuffer::refill_waste_limit_increment());
-  add(rscratch1, rscratch1, t2);
-  str(rscratch1, Address(rthread, in_bytes(JavaThread::tlab_refill_waste_limit_offset())));
-
-  if (TLABStats) {
-    // increment number of slow_allocations
-    addmw(Address(rthread, in_bytes(JavaThread::tlab_slow_allocations_offset())),
-         1, rscratch1);
-  }
-  b(try_eden);
-
-  bind(discard_tlab);
-  if (TLABStats) {
-    // increment number of refills
-    addmw(Address(rthread, in_bytes(JavaThread::tlab_number_of_refills_offset())), 1,
-         rscratch1);
-    // accumulate wastage -- t1 is amount free in tlab
-    addmw(Address(rthread, in_bytes(JavaThread::tlab_fast_refill_waste_offset())), t1,
-         rscratch1);
-  }
-
-  // if tlab is currently allocated (top or end != null) then
-  // fill [top, end + alignment_reserve) with array object
-  cbz(top, do_refill);
-
-  // set up the mark word
-  mov(rscratch1, (intptr_t)markOopDesc::prototype()->copy_set_hash(0x2));
-  str(rscratch1, Address(top, oopDesc::mark_offset_in_bytes()));
-  // set the length to the remaining space
-  sub(t1, t1, typeArrayOopDesc::header_size(T_INT));
-  add(t1, t1, (int32_t)ThreadLocalAllocBuffer::alignment_reserve());
-  lsl(t1, t1, log2_intptr(HeapWordSize/sizeof(jint)));
-  strw(t1, Address(top, arrayOopDesc::length_offset_in_bytes()));
-  // set klass to intArrayKlass
-  {
-    unsigned long offset;
-    // dubious reloc why not an oop reloc?
-    adrp(rscratch1, ExternalAddress((address)Universe::intArrayKlassObj_addr()),
-         offset);
-    ldr(t1, Address(rscratch1, offset));
-  }
-  // store klass last.  concurrent gcs assumes klass length is valid if
-  // klass field is not null.
-  store_klass(top, t1);
-
-  mov(t1, top);
-  ldr(rscratch1, Address(rthread, in_bytes(JavaThread::tlab_start_offset())));
-  sub(t1, t1, rscratch1);
-  incr_allocated_bytes(rthread, t1, 0, rscratch1);
-
-  // refill the tlab with an eden allocation
-  bind(do_refill);
-  ldr(t1, Address(rthread, in_bytes(JavaThread::tlab_size_offset())));
-  lsl(t1, t1, LogHeapWordSize);
-  // allocate new tlab, address returned in top
-  eden_allocate(top, t1, 0, t2, slow_case);
-
-  // Check that t1 was preserved in eden_allocate.
-#ifdef ASSERT
-  if (UseTLAB) {
-    Label ok;
-    Register tsize = r4;
-    assert_different_registers(tsize, rthread, t1);
-    str(tsize, Address(pre(sp, -16)));
-    ldr(tsize, Address(rthread, in_bytes(JavaThread::tlab_size_offset())));
-    lsl(tsize, tsize, LogHeapWordSize);
-    cmp(t1, tsize);
-    br(Assembler::EQ, ok);
-    STOP("assert(t1 != tlab size)");
-    should_not_reach_here();
-
-    bind(ok);
-    ldr(tsize, Address(post(sp, 16)));
-  }
-#endif
-  str(top, Address(rthread, in_bytes(JavaThread::tlab_start_offset())));
-  str(top, Address(rthread, in_bytes(JavaThread::tlab_top_offset())));
-  add(top, top, t1);
-  sub(top, top, (int32_t)ThreadLocalAllocBuffer::alignment_reserve_in_bytes());
-  str(top, Address(rthread, in_bytes(JavaThread::tlab_end_offset())));
-
-  if (ZeroTLAB) {
-    // This is a fast TLAB refill, therefore the GC is not notified of it.
-    // So compiled code must fill the new TLAB with zeroes.
-    ldr(top, Address(rthread, in_bytes(JavaThread::tlab_start_offset())));
-    zero_memory(top,t1,t2);
-  }
-
-  verify_tlab();
-  b(retry);
-
-  return rthread; // for use by caller
-}
-
 // Zero words; len is in bytes
 // Destroys all registers except addr
 // len must be a nonzero multiple of wordSize
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -861,7 +861,6 @@
     Register t2,                       // temp register
     Label&   slow_case                 // continuation point if fast allocation fails
   );
-  Register tlab_refill(Label& retry_tlab, Label& try_eden, Label& slow_case); // returns TLS address
   void zero_memory(Register addr, Register len, Register t1);
   void verify_tlab();
 
--- a/src/hotspot/cpu/arm/c1_Runtime1_arm.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/cpu/arm/c1_Runtime1_arm.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -722,10 +722,10 @@
         const Register result = R0;
         const Register klass  = R1;
 
-        if (UseTLAB && FastTLABRefill && id != new_instance_id) {
+        if (UseTLAB && Universe::heap()->supports_inline_contig_alloc() && id != new_instance_id) {
           // We come here when TLAB allocation failed.
-          // In this case we either refill TLAB or allocate directly from eden.
-          Label retry_tlab, try_eden, slow_case, slow_case_no_pop;
+          // In this case we try to allocate directly from eden.
+          Label slow_case, slow_case_no_pop;
 
           // Make sure the class is fully initialized
           if (id == fast_new_instance_init_check_id) {
@@ -742,17 +742,6 @@
 
           __ raw_push(R4, R5, LR);
 
-          __ tlab_refill(result, obj_size, tmp1, tmp2, obj_end, try_eden, slow_case);
-
-          __ bind(retry_tlab);
-          __ ldr_u32(obj_size, Address(klass, Klass::layout_helper_offset()));
-          __ tlab_allocate(result, obj_end, tmp1, obj_size, slow_case);              // initializes result and obj_end
-          __ initialize_object(result, obj_end, klass, noreg /* len */, tmp1, tmp2,
-                               instanceOopDesc::header_size() * HeapWordSize, -1,
-                               /* is_tlab_allocated */ true);
-          __ raw_pop_and_ret(R4, R5);
-
-          __ bind(try_eden);
           __ ldr_u32(obj_size, Address(klass, Klass::layout_helper_offset()));
           __ eden_allocate(result, obj_end, tmp1, tmp2, obj_size, slow_case);        // initializes result and obj_end
           __ incr_allocated_bytes(obj_size, tmp2);
@@ -803,10 +792,10 @@
         const Register klass  = R1;
         const Register length = R2;
 
-        if (UseTLAB && FastTLABRefill) {
+        if (UseTLAB && Universe::heap()->supports_inline_contig_alloc()) {
           // We come here when TLAB allocation failed.
-          // In this case we either refill TLAB or allocate directly from eden.
-          Label retry_tlab, try_eden, slow_case, slow_case_no_pop;
+          // In this case we try to allocate directly from eden.
+          Label slow_case, slow_case_no_pop;
 
 #ifdef AARCH64
           __ mov_slow(Rtemp, C1_MacroAssembler::max_array_allocation_length);
@@ -825,40 +814,6 @@
 
           __ raw_push(R4, R5, LR);
 
-          __ tlab_refill(result, arr_size, tmp1, tmp2, tmp3, try_eden, slow_case);
-
-          __ bind(retry_tlab);
-          // Get the allocation size: round_up((length << (layout_helper & 0xff)) + header_size)
-          __ ldr_u32(tmp1, Address(klass, Klass::layout_helper_offset()));
-          __ mov(arr_size, MinObjAlignmentInBytesMask);
-          __ and_32(tmp2, tmp1, (unsigned int)(Klass::_lh_header_size_mask << Klass::_lh_header_size_shift));
-
-#ifdef AARCH64
-          __ lslv_w(tmp3, length, tmp1);
-          __ add(arr_size, arr_size, tmp3);
-#else
-          __ add(arr_size, arr_size, AsmOperand(length, lsl, tmp1));
-#endif // AARCH64
-
-          __ add(arr_size, arr_size, AsmOperand(tmp2, lsr, Klass::_lh_header_size_shift));
-          __ align_reg(arr_size, arr_size, MinObjAlignmentInBytes);
-
-          // tlab_allocate initializes result and obj_end, and preserves tmp2 which contains header_size
-          __ tlab_allocate(result, obj_end, tmp1, arr_size, slow_case);
-
-          assert_different_registers(result, obj_end, klass, length, tmp1, tmp2);
-          __ initialize_header(result, klass, length, tmp1);
-
-          __ add(tmp2, result, AsmOperand(tmp2, lsr, Klass::_lh_header_size_shift));
-          if (!ZeroTLAB) {
-            __ initialize_body(tmp2, obj_end, tmp1);
-          }
-
-          __ membar(MacroAssembler::StoreStore, tmp1);
-
-          __ raw_pop_and_ret(R4, R5);
-
-          __ bind(try_eden);
           // Get the allocation size: round_up((length << (layout_helper & 0xff)) + header_size)
           __ ldr_u32(tmp1, Address(klass, Klass::layout_helper_offset()));
           __ mov(arr_size, MinObjAlignmentInBytesMask);
--- a/src/hotspot/cpu/arm/macroAssembler_arm.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/cpu/arm/macroAssembler_arm.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1316,98 +1316,6 @@
   str(obj_end, Address(Rthread, JavaThread::tlab_top_offset()));
 }
 
-void MacroAssembler::tlab_refill(Register top, Register tmp1, Register tmp2,
-                                 Register tmp3, Register tmp4,
-                               Label& try_eden, Label& slow_case) {
-  if (!Universe::heap()->supports_inline_contig_alloc()) {
-    b(slow_case);
-    return;
-  }
-
-  InlinedAddress intArrayKlass_addr((address)Universe::intArrayKlassObj_addr());
-  Label discard_tlab, do_refill;
-  ldr(top,  Address(Rthread, JavaThread::tlab_top_offset()));
-  ldr(tmp1, Address(Rthread, JavaThread::tlab_end_offset()));
-  ldr(tmp2, Address(Rthread, JavaThread::tlab_refill_waste_limit_offset()));
-
-  // Calculate amount of free space
-  sub(tmp1, tmp1, top);
-  // Retain tlab and allocate in shared space
-  // if the amount of free space in tlab is too large to discard
-  cmp(tmp2, AsmOperand(tmp1, lsr, LogHeapWordSize));
-  b(discard_tlab, ge);
-
-  // Increment waste limit to prevent getting stuck on this slow path
-  mov_slow(tmp3, ThreadLocalAllocBuffer::refill_waste_limit_increment());
-  add(tmp2, tmp2, tmp3);
-  str(tmp2, Address(Rthread, JavaThread::tlab_refill_waste_limit_offset()));
-  if (TLABStats) {
-    ldr_u32(tmp2, Address(Rthread, JavaThread::tlab_slow_allocations_offset()));
-    add_32(tmp2, tmp2, 1);
-    str_32(tmp2, Address(Rthread, JavaThread::tlab_slow_allocations_offset()));
-  }
-  b(try_eden);
-  bind_literal(intArrayKlass_addr);
-
-  bind(discard_tlab);
-  if (TLABStats) {
-    ldr_u32(tmp2, Address(Rthread, JavaThread::tlab_number_of_refills_offset()));
-    ldr_u32(tmp3, Address(Rthread, JavaThread::tlab_fast_refill_waste_offset()));
-    add_32(tmp2, tmp2, 1);
-    add_32(tmp3, tmp3, AsmOperand(tmp1, lsr, LogHeapWordSize));
-    str_32(tmp2, Address(Rthread, JavaThread::tlab_number_of_refills_offset()));
-    str_32(tmp3, Address(Rthread, JavaThread::tlab_fast_refill_waste_offset()));
-  }
-  // If tlab is currently allocated (top or end != null)
-  // then fill [top, end + alignment_reserve) with array object
-  cbz(top, do_refill);
-
-  // Set up the mark word
-  mov_slow(tmp2, (intptr_t)markOopDesc::prototype()->copy_set_hash(0x2));
-  str(tmp2, Address(top, oopDesc::mark_offset_in_bytes()));
-  // Set klass to intArrayKlass and the length to the remaining space
-  ldr_literal(tmp2, intArrayKlass_addr);
-  add(tmp1, tmp1, ThreadLocalAllocBuffer::alignment_reserve_in_bytes() -
-      typeArrayOopDesc::header_size(T_INT) * HeapWordSize);
-  Register klass = tmp2;
-  ldr(klass, Address(tmp2));
-  logical_shift_right(tmp1, tmp1, LogBytesPerInt); // divide by sizeof(jint)
-  str_32(tmp1, Address(top, arrayOopDesc::length_offset_in_bytes()));
-  store_klass(klass, top); // blows klass:
-  klass = noreg;
-
-  ldr(tmp1, Address(Rthread, JavaThread::tlab_start_offset()));
-  sub(tmp1, top, tmp1); // size of tlab's allocated portion
-  incr_allocated_bytes(tmp1, tmp2);
-
-  bind(do_refill);
-  // Refill the tlab with an eden allocation
-  ldr(tmp1, Address(Rthread, JavaThread::tlab_size_offset()));
-  logical_shift_left(tmp4, tmp1, LogHeapWordSize);
-  eden_allocate(top, tmp1, tmp2, tmp3, tmp4, slow_case);
-  str(top, Address(Rthread, JavaThread::tlab_start_offset()));
-  str(top, Address(Rthread, JavaThread::tlab_top_offset()));
-
-#ifdef ASSERT
-  // Verify that tmp1 contains tlab_end
-  ldr(tmp2, Address(Rthread, JavaThread::tlab_size_offset()));
-  add(tmp2, top, AsmOperand(tmp2, lsl, LogHeapWordSize));
-  cmp(tmp1, tmp2);
-  breakpoint(ne);
-#endif
-
-  sub(tmp1, tmp1, ThreadLocalAllocBuffer::alignment_reserve_in_bytes());
-  str(tmp1, Address(Rthread, JavaThread::tlab_end_offset()));
-
-  if (ZeroTLAB) {
-    // clobbers start and tmp
-    // top must be preserved!
-    add(tmp1, tmp1, ThreadLocalAllocBuffer::alignment_reserve_in_bytes());
-    ldr(tmp2, Address(Rthread, JavaThread::tlab_start_offset()));
-    zero_memory(tmp2, tmp1, tmp3);
-  }
-}
-
 // Fills memory regions [start..end] with zeroes. Clobbers `start` and `tmp` registers.
 void MacroAssembler::zero_memory(Register start, Register end, Register tmp) {
   Label loop;
--- a/src/hotspot/cpu/arm/macroAssembler_arm.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/cpu/arm/macroAssembler_arm.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -359,8 +359,6 @@
   void tlab_allocate(Register obj, Register obj_end, Register tmp1,
                      RegisterOrConstant size_expression, Label& slow_case);
 
-  void tlab_refill(Register top, Register tmp1, Register tmp2, Register tmp3, Register tmp4,
-                   Label& try_eden, Label& slow_case);
   void zero_memory(Register start, Register end, Register tmp);
 
   void incr_allocated_bytes(RegisterOrConstant size_in_bytes, Register tmp);
--- a/src/hotspot/cpu/ppc/c1_Runtime1_ppc.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/cpu/ppc/c1_Runtime1_ppc.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -413,34 +413,9 @@
           assert(id == fast_new_instance_init_check_id, "bad StubID");
           __ set_info("fast new_instance init check", dont_gc_arguments);
         }
+
         // We don't support eden allocation.
-//        if ((id == fast_new_instance_id || id == fast_new_instance_init_check_id) &&
-//            UseTLAB && FastTLABRefill) {
-//          if (id == fast_new_instance_init_check_id) {
-//            // make sure the klass is initialized
-//            __ lbz(R0, in_bytes(InstanceKlass::init_state_offset()), R3_ARG1);
-//            __ cmpwi(CCR0, R0, InstanceKlass::fully_initialized);
-//            __ bne(CCR0, slow_path);
-//          }
-//#ifdef ASSERT
-//          // assert object can be fast path allocated
-//          {
-//            Label ok, not_ok;
-//          __ lwz(R0, in_bytes(Klass::layout_helper_offset()), R3_ARG1);
-//          // make sure it's an instance (LH > 0)
-//          __ cmpwi(CCR0, R0, 0);
-//          __ ble(CCR0, not_ok);
-//          __ testbitdi(CCR0, R0, R0, Klass::_lh_instance_slow_path_bit);
-//          __ beq(CCR0, ok);
-//
-//          __ bind(not_ok);
-//          __ stop("assert(can be fast path allocated)");
-//          __ bind(ok);
-//          }
-//#endif // ASSERT
-//          // We don't support eden allocation.
-//          __ bind(slow_path);
-//        }
+
         oop_maps = generate_stub_call(sasm, R3_RET, CAST_FROM_FN_PTR(address, new_instance), R4_ARG2);
       }
       break;
--- a/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -2336,9 +2336,6 @@
   std(new_top, in_bytes(JavaThread::tlab_top_offset()), R16_thread);
   //verify_tlab(); not implemented
 }
-void MacroAssembler::tlab_refill(Label& retry_tlab, Label& try_eden, Label& slow_case) {
-  unimplemented("tlab_refill");
-}
 void MacroAssembler::incr_allocated_bytes(RegisterOrConstant size_in_bytes, Register t1, Register t2) {
   unimplemented("incr_allocated_bytes");
 }
--- a/src/hotspot/cpu/ppc/macroAssembler_ppc.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/cpu/ppc/macroAssembler_ppc.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -602,7 +602,6 @@
     Register t1,                       // temp register
     Label&   slow_case                 // continuation point if fast allocation fails
   );
-  void tlab_refill(Label& retry_tlab, Label& try_eden, Label& slow_case);
   void incr_allocated_bytes(RegisterOrConstant size_in_bytes, Register t1, Register t2);
 
   enum { trampoline_stub_size = 6 * 4 };
--- a/src/hotspot/cpu/s390/c1_Runtime1_s390.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/cpu/s390/c1_Runtime1_s390.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -346,11 +346,6 @@
           __ set_info("fast new_instance init check", dont_gc_arguments);
         }
 
-        if ((id == fast_new_instance_id || id == fast_new_instance_init_check_id) &&
-            UseTLAB && FastTLABRefill) {
-          // Sapjvm: must call RT to generate allocation events.
-        }
-
         OopMap* map = save_live_registers_except_r2(sasm);
         int call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_instance), klass);
         oop_maps = new OopMapSet();
@@ -411,10 +406,6 @@
         }
 #endif // ASSERT
 
-        if (UseTLAB && FastTLABRefill) {
-          // sapjvm: must call RT to generate allocation events.
-        }
-
         OopMap* map = save_live_registers_except_r2(sasm);
         int call_offset;
         if (id == new_type_array_id) {
--- a/src/hotspot/cpu/sparc/c1_Runtime1_sparc.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/cpu/sparc/c1_Runtime1_sparc.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -389,7 +389,7 @@
         }
 
         if ((id == fast_new_instance_id || id == fast_new_instance_init_check_id) &&
-            UseTLAB && FastTLABRefill) {
+            UseTLAB && Universe::heap()->supports_inline_contig_alloc()) {
           Label slow_path;
           Register G1_obj_size = G1;
           Register G3_t1 = G3;
@@ -424,25 +424,8 @@
           __ bind(ok);
           }
 #endif // ASSERT
-          // if we got here then the TLAB allocation failed, so try
-          // refilling the TLAB or allocating directly from eden.
-          Label retry_tlab, try_eden;
-          __ tlab_refill(retry_tlab, try_eden, slow_path); // preserves G5_klass
 
-          __ bind(retry_tlab);
-
-          // get the instance size
-          __ ld(G5_klass, in_bytes(Klass::layout_helper_offset()), G1_obj_size);
-
-          __ tlab_allocate(O0_obj, G1_obj_size, 0, G3_t1, slow_path);
-
-          __ initialize_object(O0_obj, G5_klass, G1_obj_size, 0, G3_t1, G4_t2, /* is_tlab_allocated */ true);
-          __ verify_oop(O0_obj);
-          __ mov(O0, I0);
-          __ ret();
-          __ delayed()->restore();
-
-          __ bind(try_eden);
+          // If we got here then the TLAB allocation failed, so try allocating directly from eden.
           // get the instance size
           __ ld(G5_klass, in_bytes(Klass::layout_helper_offset()), G1_obj_size);
           __ eden_allocate(O0_obj, G1_obj_size, 0, G3_t1, G4_t2, slow_path);
@@ -508,73 +491,6 @@
         }
 #endif // ASSERT
 
-        if (UseTLAB && FastTLABRefill) {
-          Label slow_path;
-          Register G1_arr_size = G1;
-          Register G3_t1 = G3;
-          Register O1_t2 = O1;
-          assert_different_registers(G5_klass, G4_length, G1_arr_size, G3_t1, O1_t2);
-
-          // check that array length is small enough for fast path
-          __ set(C1_MacroAssembler::max_array_allocation_length, G3_t1);
-          __ cmp(G4_length, G3_t1);
-          __ br(Assembler::greaterUnsigned, false, Assembler::pn, slow_path);
-          __ delayed()->nop();
-
-          // if we got here then the TLAB allocation failed, so try
-          // refilling the TLAB or allocating directly from eden.
-          Label retry_tlab, try_eden;
-          __ tlab_refill(retry_tlab, try_eden, slow_path); // preserves G4_length and G5_klass
-
-          __ bind(retry_tlab);
-
-          // get the allocation size: (length << (layout_helper & 0x1F)) + header_size
-          __ ld(klass_lh, G3_t1);
-          __ sll(G4_length, G3_t1, G1_arr_size);
-          __ srl(G3_t1, Klass::_lh_header_size_shift, G3_t1);
-          __ and3(G3_t1, Klass::_lh_header_size_mask, G3_t1);
-          __ add(G1_arr_size, G3_t1, G1_arr_size);
-          __ add(G1_arr_size, MinObjAlignmentInBytesMask, G1_arr_size);  // align up
-          __ and3(G1_arr_size, ~MinObjAlignmentInBytesMask, G1_arr_size);
-
-          __ tlab_allocate(O0_obj, G1_arr_size, 0, G3_t1, slow_path);  // preserves G1_arr_size
-
-          __ initialize_header(O0_obj, G5_klass, G4_length, G3_t1, O1_t2);
-          __ ldub(klass_lh, G3_t1, klass_lh_header_size_offset);
-          __ sub(G1_arr_size, G3_t1, O1_t2);  // body length
-          __ add(O0_obj, G3_t1, G3_t1);       // body start
-          if (!ZeroTLAB) {
-            __ initialize_body(G3_t1, O1_t2);
-          }
-          __ verify_oop(O0_obj);
-          __ retl();
-          __ delayed()->nop();
-
-          __ bind(try_eden);
-          // get the allocation size: (length << (layout_helper & 0x1F)) + header_size
-          __ ld(klass_lh, G3_t1);
-          __ sll(G4_length, G3_t1, G1_arr_size);
-          __ srl(G3_t1, Klass::_lh_header_size_shift, G3_t1);
-          __ and3(G3_t1, Klass::_lh_header_size_mask, G3_t1);
-          __ add(G1_arr_size, G3_t1, G1_arr_size);
-          __ add(G1_arr_size, MinObjAlignmentInBytesMask, G1_arr_size);
-          __ and3(G1_arr_size, ~MinObjAlignmentInBytesMask, G1_arr_size);
-
-          __ eden_allocate(O0_obj, G1_arr_size, 0, G3_t1, O1_t2, slow_path);  // preserves G1_arr_size
-          __ incr_allocated_bytes(G1_arr_size, G3_t1, O1_t2);
-
-          __ initialize_header(O0_obj, G5_klass, G4_length, G3_t1, O1_t2);
-          __ ldub(klass_lh, G3_t1, klass_lh_header_size_offset);
-          __ sub(G1_arr_size, G3_t1, O1_t2);  // body length
-          __ add(O0_obj, G3_t1, G3_t1);       // body start
-          __ initialize_body(G3_t1, O1_t2);
-          __ verify_oop(O0_obj);
-          __ retl();
-          __ delayed()->nop();
-
-          __ bind(slow_path);
-        }
-
         if (id == new_type_array_id) {
           oop_maps = generate_stub_call(sasm, I0, CAST_FROM_FN_PTR(address, new_type_array), G5_klass, G4_length);
         } else {
--- a/src/hotspot/cpu/sparc/macroAssembler_sparc.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/cpu/sparc/macroAssembler_sparc.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -3242,127 +3242,6 @@
   verify_tlab();
 }
 
-
-void MacroAssembler::tlab_refill(Label& retry, Label& try_eden, Label& slow_case) {
-  Register top = O0;
-  Register t1 = G1;
-  Register t2 = G3;
-  Register t3 = O1;
-  assert_different_registers(top, t1, t2, t3, G4, G5 /* preserve G4 and G5 */);
-  Label do_refill, discard_tlab;
-
-  if (!Universe::heap()->supports_inline_contig_alloc()) {
-    // No allocation in the shared eden.
-    ba(slow_case);
-    delayed()->nop();
-  }
-
-  ld_ptr(G2_thread, in_bytes(JavaThread::tlab_top_offset()), top);
-  ld_ptr(G2_thread, in_bytes(JavaThread::tlab_end_offset()), t1);
-  ld_ptr(G2_thread, in_bytes(JavaThread::tlab_refill_waste_limit_offset()), t2);
-
-  // calculate amount of free space
-  sub(t1, top, t1);
-  srl_ptr(t1, LogHeapWordSize, t1);
-
-  // Retain tlab and allocate object in shared space if
-  // the amount free in the tlab is too large to discard.
-  cmp(t1, t2);
-
-  brx(Assembler::lessEqual, false, Assembler::pt, discard_tlab);
-  // increment waste limit to prevent getting stuck on this slow path
-  if (Assembler::is_simm13(ThreadLocalAllocBuffer::refill_waste_limit_increment())) {
-    delayed()->add(t2, ThreadLocalAllocBuffer::refill_waste_limit_increment(), t2);
-  } else {
-    delayed()->nop();
-    // set64 does not use the temp register if the given constant is 32 bit. So
-    // we can just use any register; using G0 results in ignoring of the upper 32 bit
-    // of that value.
-    set64(ThreadLocalAllocBuffer::refill_waste_limit_increment(), t3, G0);
-    add(t2, t3, t2);
-  }
-
-  st_ptr(t2, G2_thread, in_bytes(JavaThread::tlab_refill_waste_limit_offset()));
-  if (TLABStats) {
-    // increment number of slow_allocations
-    ld(G2_thread, in_bytes(JavaThread::tlab_slow_allocations_offset()), t2);
-    add(t2, 1, t2);
-    stw(t2, G2_thread, in_bytes(JavaThread::tlab_slow_allocations_offset()));
-  }
-  ba(try_eden);
-  delayed()->nop();
-
-  bind(discard_tlab);
-  if (TLABStats) {
-    // increment number of refills
-    ld(G2_thread, in_bytes(JavaThread::tlab_number_of_refills_offset()), t2);
-    add(t2, 1, t2);
-    stw(t2, G2_thread, in_bytes(JavaThread::tlab_number_of_refills_offset()));
-    // accumulate wastage
-    ld(G2_thread, in_bytes(JavaThread::tlab_fast_refill_waste_offset()), t2);
-    add(t2, t1, t2);
-    stw(t2, G2_thread, in_bytes(JavaThread::tlab_fast_refill_waste_offset()));
-  }
-
-  // if tlab is currently allocated (top or end != null) then
-  // fill [top, end + alignment_reserve) with array object
-  br_null_short(top, Assembler::pn, do_refill);
-
-  set((intptr_t)markOopDesc::prototype()->copy_set_hash(0x2), t2);
-  st_ptr(t2, top, oopDesc::mark_offset_in_bytes()); // set up the mark word
-  // set klass to intArrayKlass
-  sub(t1, typeArrayOopDesc::header_size(T_INT), t1);
-  add(t1, ThreadLocalAllocBuffer::alignment_reserve(), t1);
-  sll_ptr(t1, log2_intptr(HeapWordSize/sizeof(jint)), t1);
-  st(t1, top, arrayOopDesc::length_offset_in_bytes());
-  set((intptr_t)Universe::intArrayKlassObj_addr(), t2);
-  ld_ptr(t2, 0, t2);
-  // store klass last.  concurrent gcs assumes klass length is valid if
-  // klass field is not null.
-  store_klass(t2, top);
-  verify_oop(top);
-
-  ld_ptr(G2_thread, in_bytes(JavaThread::tlab_start_offset()), t1);
-  sub(top, t1, t1); // size of tlab's allocated portion
-  incr_allocated_bytes(t1, t2, t3);
-
-  // refill the tlab with an eden allocation
-  bind(do_refill);
-  ld_ptr(G2_thread, in_bytes(JavaThread::tlab_size_offset()), t1);
-  sll_ptr(t1, LogHeapWordSize, t1);
-  // allocate new tlab, address returned in top
-  eden_allocate(top, t1, 0, t2, t3, slow_case);
-
-  st_ptr(top, G2_thread, in_bytes(JavaThread::tlab_start_offset()));
-  st_ptr(top, G2_thread, in_bytes(JavaThread::tlab_top_offset()));
-#ifdef ASSERT
-  // check that tlab_size (t1) is still valid
-  {
-    Label ok;
-    ld_ptr(G2_thread, in_bytes(JavaThread::tlab_size_offset()), t2);
-    sll_ptr(t2, LogHeapWordSize, t2);
-    cmp_and_br_short(t1, t2, Assembler::equal, Assembler::pt, ok);
-    STOP("assert(t1 == tlab_size)");
-    should_not_reach_here();
-
-    bind(ok);
-  }
-#endif // ASSERT
-  add(top, t1, top); // t1 is tlab_size
-  sub(top, ThreadLocalAllocBuffer::alignment_reserve_in_bytes(), top);
-  st_ptr(top, G2_thread, in_bytes(JavaThread::tlab_end_offset()));
-
-  if (ZeroTLAB) {
-    // This is a fast TLAB refill, therefore the GC is not notified of it.
-    // So compiled code must fill the new TLAB with zeroes.
-    ld_ptr(G2_thread, in_bytes(JavaThread::tlab_start_offset()), t2);
-    zero_memory(t2, t1);
-  }
-  verify_tlab();
-  ba(retry);
-  delayed()->nop();
-}
-
 void MacroAssembler::zero_memory(Register base, Register index) {
   assert_different_registers(base, index);
   Label loop;
--- a/src/hotspot/cpu/sparc/macroAssembler_sparc.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/cpu/sparc/macroAssembler_sparc.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1266,7 +1266,6 @@
     Register t1,                       // temp register
     Label&   slow_case                 // continuation point if fast allocation fails
   );
-  void tlab_refill(Label& retry_tlab, Label& try_eden, Label& slow_case);
   void zero_memory(Register base, Register index);
   void incr_allocated_bytes(RegisterOrConstant size_in_bytes,
                             Register t1, Register t2);
--- a/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -529,12 +529,16 @@
 
   if (SafepointMechanism::uses_thread_local_poll()) {
 #ifdef _LP64
-    __ movptr(rscratch1, Address(r15_thread, Thread::polling_page_offset()));
+    const Register poll_addr = rscratch1;
+    __ movptr(poll_addr, Address(r15_thread, Thread::polling_page_offset()));
+#else
+    const Register poll_addr = rbx;
+    assert(FrameMap::is_caller_save_register(poll_addr), "will overwrite");
+    __ get_thread(poll_addr);
+    __ movptr(poll_addr, Address(poll_addr, Thread::polling_page_offset()));
+#endif
     __ relocate(relocInfo::poll_return_type);
-    __ testl(rax, Address(rscratch1, 0));
-#else
-    ShouldNotReachHere();
-#endif
+    __ testl(rax, Address(poll_addr, 0));
   } else {
     AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type);
 
@@ -555,16 +559,20 @@
   int offset = __ offset();
   if (SafepointMechanism::uses_thread_local_poll()) {
 #ifdef _LP64
-    __ movptr(rscratch1, Address(r15_thread, Thread::polling_page_offset()));
+    const Register poll_addr = rscratch1;
+    __ movptr(poll_addr, Address(r15_thread, Thread::polling_page_offset()));
+#else
+    assert(tmp->is_cpu_register(), "needed");
+    const Register poll_addr = tmp->as_register();
+    __ get_thread(poll_addr);
+    __ movptr(poll_addr, Address(poll_addr, in_bytes(Thread::polling_page_offset())));
+#endif
     add_debug_info_for_branch(info);
     __ relocate(relocInfo::poll_type);
     address pre_pc = __ pc();
-    __ testl(rax, Address(rscratch1, 0));
+    __ testl(rax, Address(poll_addr, 0));
     address post_pc = __ pc();
-    guarantee(pointer_delta(post_pc, pre_pc, 1) == 3, "must be exact length");
-#else
-    ShouldNotReachHere();
-#endif
+    guarantee(pointer_delta(post_pc, pre_pc, 1) == 2 LP64_ONLY(+1), "must be exact length");
   } else {
     AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_type);
     if (Assembler::is_polling_page_far()) {
--- a/src/hotspot/cpu/x86/c1_LIRGenerator_x86.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/cpu/x86/c1_LIRGenerator_x86.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -143,6 +143,7 @@
 
 
 LIR_Opr LIRGenerator::safepoint_poll_register() {
+  NOT_LP64( if (SafepointMechanism::uses_thread_local_poll()) { return new_register(T_ADDRESS); } )
   return LIR_OprFact::illegalOpr;
 }
 
@@ -1515,7 +1516,7 @@
   if (x->is_safepoint()) {
     // increment backedge counter if needed
     increment_backedge_counter(state_for(x, x->state_before()), x->profiled_bci());
-    __ safepoint(LIR_OprFact::illegalOpr, state_for(x, x->state_before()));
+    __ safepoint(safepoint_poll_register(), state_for(x, x->state_before()));
   }
   set_no_result(x);
 
--- a/src/hotspot/cpu/x86/c1_Runtime1_x86.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/cpu/x86/c1_Runtime1_x86.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -994,8 +994,8 @@
           __ set_info("fast new_instance init check", dont_gc_arguments);
         }
 
-        if ((id == fast_new_instance_id || id == fast_new_instance_init_check_id) &&
-            UseTLAB && FastTLABRefill) {
+        if ((id == fast_new_instance_id || id == fast_new_instance_init_check_id) && UseTLAB
+            && Universe::heap()->supports_inline_contig_alloc()) {
           Label slow_path;
           Register obj_size = rcx;
           Register t1       = rbx;
@@ -1030,21 +1030,8 @@
           // if we got here then the TLAB allocation failed, so try
           // refilling the TLAB or allocating directly from eden.
           Label retry_tlab, try_eden;
-          const Register thread =
-            __ tlab_refill(retry_tlab, try_eden, slow_path); // does not destroy rdx (klass), returns rdi
-
-          __ bind(retry_tlab);
-
-          // get the instance size (size is postive so movl is fine for 64bit)
-          __ movl(obj_size, Address(klass, Klass::layout_helper_offset()));
-
-          __ tlab_allocate(obj, obj_size, 0, t1, t2, slow_path);
-
-          __ initialize_object(obj, klass, obj_size, 0, t1, t2, /* is_tlab_allocated */ true);
-          __ verify_oop(obj);
-          __ pop(rbx);
-          __ pop(rdi);
-          __ ret(0);
+          const Register thread = NOT_LP64(rdi) LP64_ONLY(r15_thread);
+          NOT_LP64(__ get_thread(thread));
 
           __ bind(try_eden);
           // get the instance size (size is postive so movl is fine for 64bit)
@@ -1128,24 +1115,13 @@
         }
 #endif // ASSERT
 
-        if (UseTLAB && FastTLABRefill) {
+        // If we got here, the TLAB allocation failed, so try allocating from
+        // eden if inline contiguous allocations are supported.
+        if (UseTLAB && Universe::heap()->supports_inline_contig_alloc()) {
           Register arr_size = rsi;
           Register t1       = rcx;  // must be rcx for use as shift count
           Register t2       = rdi;
           Label slow_path;
-          assert_different_registers(length, klass, obj, arr_size, t1, t2);
-
-          // check that array length is small enough for fast path.
-          __ cmpl(length, C1_MacroAssembler::max_array_allocation_length);
-          __ jcc(Assembler::above, slow_path);
-
-          // if we got here then the TLAB allocation failed, so try
-          // refilling the TLAB or allocating directly from eden.
-          Label retry_tlab, try_eden;
-          const Register thread =
-            __ tlab_refill(retry_tlab, try_eden, slow_path); // preserves rbx & rdx, returns rdi
-
-          __ bind(retry_tlab);
 
           // get the allocation size: round_up(hdr + length << (layout_helper & 0x1F))
           // since size is positive movl does right thing on 64bit
@@ -1160,36 +1136,11 @@
           __ addptr(arr_size, MinObjAlignmentInBytesMask); // align up
           __ andptr(arr_size, ~MinObjAlignmentInBytesMask);
 
-          __ tlab_allocate(obj, arr_size, 0, t1, t2, slow_path);  // preserves arr_size
-
-          __ initialize_header(obj, klass, length, t1, t2);
-          __ movb(t1, Address(klass, in_bytes(Klass::layout_helper_offset()) + (Klass::_lh_header_size_shift / BitsPerByte)));
-          assert(Klass::_lh_header_size_shift % BitsPerByte == 0, "bytewise");
-          assert(Klass::_lh_header_size_mask <= 0xFF, "bytewise");
-          __ andptr(t1, Klass::_lh_header_size_mask);
-          __ subptr(arr_size, t1);  // body length
-          __ addptr(t1, obj);       // body start
-          if (!ZeroTLAB) {
-            __ initialize_body(t1, arr_size, 0, t2);
-          }
-          __ verify_oop(obj);
-          __ ret(0);
+          __ eden_allocate(obj, arr_size, 0, t1, slow_path);  // preserves arr_size
 
-          __ bind(try_eden);
-          // get the allocation size: round_up(hdr + length << (layout_helper & 0x1F))
-          // since size is positive movl does right thing on 64bit
-          __ movl(t1, Address(klass, Klass::layout_helper_offset()));
-          // since size is postive movl does right thing on 64bit
-          __ movl(arr_size, length);
-          assert(t1 == rcx, "fixed register usage");
-          __ shlptr(arr_size /* by t1=rcx, mod 32 */);
-          __ shrptr(t1, Klass::_lh_header_size_shift);
-          __ andptr(t1, Klass::_lh_header_size_mask);
-          __ addptr(arr_size, t1);
-          __ addptr(arr_size, MinObjAlignmentInBytesMask); // align up
-          __ andptr(arr_size, ~MinObjAlignmentInBytesMask);
-
-          __ eden_allocate(obj, arr_size, 0, t1, slow_path);  // preserves arr_size
+          // Using t2 for non 64-bit.
+          const Register thread = NOT_LP64(t2) LP64_ONLY(r15_thread);
+          NOT_LP64(__ get_thread(thread));
           __ incr_allocated_bytes(thread, arr_size, 0);
 
           __ initialize_header(obj, klass, length, t1, t2);
--- a/src/hotspot/cpu/x86/globalDefinitions_x86.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/cpu/x86/globalDefinitions_x86.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -65,9 +65,6 @@
 #define SUPPORT_RESERVED_STACK_AREA
 #endif
 
-#ifdef _LP64
-// X64 have implemented the local polling
 #define THREAD_LOCAL_POLL
-#endif
 
 #endif // CPU_X86_VM_GLOBALDEFINITIONS_X86_HPP
--- a/src/hotspot/cpu/x86/globals_x86.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/cpu/x86/globals_x86.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -97,9 +97,10 @@
 
 define_pd_global(intx, InitArrayShortSize, 8*BytesPerLong);
 
-#ifdef _LP64
+#if defined(_LP64) || defined(_WINDOWS)
 define_pd_global(bool, ThreadLocalHandshakes, true);
 #else
+// get_thread() is slow on linux 32 bit, therefore off by default
 define_pd_global(bool, ThreadLocalHandshakes, false);
 #endif
 
--- a/src/hotspot/cpu/x86/interp_masm_x86.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/cpu/x86/interp_masm_x86.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -830,13 +830,12 @@
   if (verifyoop) {
     verify_oop(rax, state);
   }
+
+  address* const safepoint_table = Interpreter::safept_table(state);
 #ifdef _LP64
-
   Label no_safepoint, dispatch;
-  address* const safepoint_table = Interpreter::safept_table(state);
   if (SafepointMechanism::uses_thread_local_poll() && table != safepoint_table && generate_poll) {
     NOT_PRODUCT(block_comment("Thread-local Safepoint poll"));
-
     testb(Address(r15_thread, Thread::polling_page_offset()), SafepointMechanism::poll_bit());
 
     jccb(Assembler::zero, no_safepoint);
@@ -851,9 +850,23 @@
 
 #else
   Address index(noreg, rbx, Address::times_ptr);
-  ExternalAddress tbl((address)table);
-  ArrayAddress dispatch(tbl, index);
-  jump(dispatch);
+  if (SafepointMechanism::uses_thread_local_poll() && table != safepoint_table && generate_poll) {
+    NOT_PRODUCT(block_comment("Thread-local Safepoint poll"));
+    Label no_safepoint;
+    const Register thread = rcx;
+    get_thread(thread);
+    testb(Address(thread, Thread::polling_page_offset()), SafepointMechanism::poll_bit());
+
+    jccb(Assembler::zero, no_safepoint);
+    ArrayAddress dispatch_addr(ExternalAddress((address)safepoint_table), index);
+    jump(dispatch_addr);
+    bind(no_safepoint);
+  }
+
+  {
+    ArrayAddress dispatch_addr(ExternalAddress((address)table), index);
+    jump(dispatch_addr);
+  }
 #endif // _LP64
 }
 
--- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -3767,10 +3767,17 @@
   movl(as_Address(ArrayAddress(page, index)), tmp);
 }
 
-#ifdef _LP64
 void MacroAssembler::safepoint_poll(Label& slow_path, Register thread_reg, Register temp_reg) {
   if (SafepointMechanism::uses_thread_local_poll()) {
-    testb(Address(r15_thread, Thread::polling_page_offset()), SafepointMechanism::poll_bit());
+#ifdef _LP64
+    assert(thread_reg == r15_thread, "should be");
+#else
+    if (thread_reg == noreg) {
+      thread_reg = temp_reg;
+      get_thread(thread_reg);
+    }
+#endif
+    testb(Address(thread_reg, Thread::polling_page_offset()), SafepointMechanism::poll_bit());
     jcc(Assembler::notZero, slow_path); // handshake bit set implies poll
   } else {
     cmp32(ExternalAddress(SafepointSynchronize::address_of_state()),
@@ -3778,13 +3785,6 @@
     jcc(Assembler::notEqual, slow_path);
   }
 }
-#else
-void MacroAssembler::safepoint_poll(Label& slow_path) {
-  cmp32(ExternalAddress(SafepointSynchronize::address_of_state()),
-      SafepointSynchronize::_not_synchronized);
-  jcc(Assembler::notEqual, slow_path);
-}
-#endif
 
 // Calls to C land
 //
@@ -5604,121 +5604,6 @@
   verify_tlab();
 }
 
-// Preserves rbx, and rdx.
-Register MacroAssembler::tlab_refill(Label& retry,
-                                     Label& try_eden,
-                                     Label& slow_case) {
-  Register top = rax;
-  Register t1  = rcx; // object size
-  Register t2  = rsi;
-  Register thread_reg = NOT_LP64(rdi) LP64_ONLY(r15_thread);
-  assert_different_registers(top, thread_reg, t1, t2, /* preserve: */ rbx, rdx);
-  Label do_refill, discard_tlab;
-
-  if (!Universe::heap()->supports_inline_contig_alloc()) {
-    // No allocation in the shared eden.
-    jmp(slow_case);
-  }
-
-  NOT_LP64(get_thread(thread_reg));
-
-  movptr(top, Address(thread_reg, in_bytes(JavaThread::tlab_top_offset())));
-  movptr(t1,  Address(thread_reg, in_bytes(JavaThread::tlab_end_offset())));
-
-  // calculate amount of free space
-  subptr(t1, top);
-  shrptr(t1, LogHeapWordSize);
-
-  // Retain tlab and allocate object in shared space if
-  // the amount free in the tlab is too large to discard.
-  cmpptr(t1, Address(thread_reg, in_bytes(JavaThread::tlab_refill_waste_limit_offset())));
-  jcc(Assembler::lessEqual, discard_tlab);
-
-  // Retain
-  // %%% yuck as movptr...
-  movptr(t2, (int32_t) ThreadLocalAllocBuffer::refill_waste_limit_increment());
-  addptr(Address(thread_reg, in_bytes(JavaThread::tlab_refill_waste_limit_offset())), t2);
-  if (TLABStats) {
-    // increment number of slow_allocations
-    addl(Address(thread_reg, in_bytes(JavaThread::tlab_slow_allocations_offset())), 1);
-  }
-  jmp(try_eden);
-
-  bind(discard_tlab);
-  if (TLABStats) {
-    // increment number of refills
-    addl(Address(thread_reg, in_bytes(JavaThread::tlab_number_of_refills_offset())), 1);
-    // accumulate wastage -- t1 is amount free in tlab
-    addl(Address(thread_reg, in_bytes(JavaThread::tlab_fast_refill_waste_offset())), t1);
-  }
-
-  // if tlab is currently allocated (top or end != null) then
-  // fill [top, end + alignment_reserve) with array object
-  testptr(top, top);
-  jcc(Assembler::zero, do_refill);
-
-  // set up the mark word
-  movptr(Address(top, oopDesc::mark_offset_in_bytes()), (intptr_t)markOopDesc::prototype()->copy_set_hash(0x2));
-  // set the length to the remaining space
-  subptr(t1, typeArrayOopDesc::header_size(T_INT));
-  addptr(t1, (int32_t)ThreadLocalAllocBuffer::alignment_reserve());
-  shlptr(t1, log2_intptr(HeapWordSize/sizeof(jint)));
-  movl(Address(top, arrayOopDesc::length_offset_in_bytes()), t1);
-  // set klass to intArrayKlass
-  // dubious reloc why not an oop reloc?
-  movptr(t1, ExternalAddress((address)Universe::intArrayKlassObj_addr()));
-  // store klass last.  concurrent gcs assumes klass length is valid if
-  // klass field is not null.
-  store_klass(top, t1);
-
-  movptr(t1, top);
-  subptr(t1, Address(thread_reg, in_bytes(JavaThread::tlab_start_offset())));
-  incr_allocated_bytes(thread_reg, t1, 0);
-
-  // refill the tlab with an eden allocation
-  bind(do_refill);
-  movptr(t1, Address(thread_reg, in_bytes(JavaThread::tlab_size_offset())));
-  shlptr(t1, LogHeapWordSize);
-  // allocate new tlab, address returned in top
-  eden_allocate(top, t1, 0, t2, slow_case);
-
-  // Check that t1 was preserved in eden_allocate.
-#ifdef ASSERT
-  if (UseTLAB) {
-    Label ok;
-    Register tsize = rsi;
-    assert_different_registers(tsize, thread_reg, t1);
-    push(tsize);
-    movptr(tsize, Address(thread_reg, in_bytes(JavaThread::tlab_size_offset())));
-    shlptr(tsize, LogHeapWordSize);
-    cmpptr(t1, tsize);
-    jcc(Assembler::equal, ok);
-    STOP("assert(t1 != tlab size)");
-    should_not_reach_here();
-
-    bind(ok);
-    pop(tsize);
-  }
-#endif
-  movptr(Address(thread_reg, in_bytes(JavaThread::tlab_start_offset())), top);
-  movptr(Address(thread_reg, in_bytes(JavaThread::tlab_top_offset())), top);
-  addptr(top, t1);
-  subptr(top, (int32_t)ThreadLocalAllocBuffer::alignment_reserve_in_bytes());
-  movptr(Address(thread_reg, in_bytes(JavaThread::tlab_end_offset())), top);
-
-  if (ZeroTLAB) {
-    // This is a fast TLAB refill, therefore the GC is not notified of it.
-    // So compiled code must fill the new TLAB with zeroes.
-    movptr(top, Address(thread_reg, in_bytes(JavaThread::tlab_start_offset())));
-    zero_memory(top, t1, 0, t2);
-  }
-
-  verify_tlab();
-  jmp(retry);
-
-  return thread_reg; // for use by caller
-}
-
 // Preserves the contents of address, destroys the contents length_in_bytes and temp.
 void MacroAssembler::zero_memory(Register address, Register length_in_bytes, int offset_in_bytes, Register temp) {
   assert(address != length_in_bytes && address != temp && temp != length_in_bytes, "registers must be different");
--- a/src/hotspot/cpu/x86/macroAssembler_x86.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/cpu/x86/macroAssembler_x86.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -531,7 +531,6 @@
     Register t2,                       // temp register
     Label&   slow_case                 // continuation point if fast allocation fails
   );
-  Register tlab_refill(Label& retry_tlab, Label& try_eden, Label& slow_case); // returns TLS address
   void zero_memory(Register address, Register length_in_bytes, int offset_in_bytes, Register temp);
 
   void incr_allocated_bytes(Register thread,
@@ -657,11 +656,9 @@
   // Support for serializing memory accesses between threads
   void serialize_memory(Register thread, Register tmp);
 
-#ifdef _LP64
+  // If thread_reg is != noreg the code assumes the register passed contains
+  // the thread (required on 64 bit).
   void safepoint_poll(Label& slow_path, Register thread_reg, Register temp_reg);
-#else
-  void safepoint_poll(Label& slow_path);
-#endif
 
   void verify_tlab();
 
--- a/src/hotspot/cpu/x86/nativeInst_x86.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/cpu/x86/nativeInst_x86.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -704,14 +704,18 @@
 inline bool NativeInstruction::is_cond_jump()    { return (int_at(0) & 0xF0FF) == 0x800F /* long jump */ ||
                                                           (ubyte_at(0) & 0xF0) == 0x70;  /* short jump */ }
 inline bool NativeInstruction::is_safepoint_poll() {
+  if (SafepointMechanism::uses_thread_local_poll()) {
 #ifdef AMD64
-  if (SafepointMechanism::uses_thread_local_poll()) {
     const bool has_rex_prefix = ubyte_at(0) == NativeTstRegMem::instruction_rex_b_prefix;
     const int test_offset = has_rex_prefix ? 1 : 0;
+#else
+    const int test_offset = 0;
+#endif
     const bool is_test_opcode = ubyte_at(test_offset) == NativeTstRegMem::instruction_code_memXregl;
     const bool is_rax_target = (ubyte_at(test_offset + 1) & NativeTstRegMem::modrm_mask) == NativeTstRegMem::modrm_reg;
     return is_test_opcode && is_rax_target;
   }
+#ifdef AMD64
   // Try decoding a near safepoint first:
   if (ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl &&
       ubyte_at(1) == 0x05) { // 00 rax 101
--- a/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -2111,16 +2111,13 @@
   Label after_transition;
 
   // check for safepoint operation in progress and/or pending suspend requests
-  { Label Continue;
-
-    __ cmp32(ExternalAddress((address)SafepointSynchronize::address_of_state()),
-             SafepointSynchronize::_not_synchronized);
-
-    Label L;
-    __ jcc(Assembler::notEqual, L);
+  { Label Continue, slow_path;
+
+    __ safepoint_poll(slow_path, thread, noreg);
+
     __ cmpl(Address(thread, JavaThread::suspend_flags_offset()), 0);
     __ jcc(Assembler::equal, Continue);
-    __ bind(L);
+    __ bind(slow_path);
 
     // Don't use call_VM as it will see a possible pending exception and forward it
     // and never return here preventing us from clearing _last_native_pc down below.
@@ -2996,8 +2993,11 @@
 
   // if this was not a poll_return then we need to correct the return address now.
   if (!cause_return) {
-    __ movptr(rax, Address(java_thread, JavaThread::saved_exception_pc_offset()));
-    __ movptr(Address(rbp, wordSize), rax);
+    // Get the return pc saved by the signal handler and stash it in its appropriate place on the stack.
+    // Additionally, rbx is a callee saved register and we can look at it later to determine
+    // if someone changed the return address for us!
+    __ movptr(rbx, Address(java_thread, JavaThread::saved_exception_pc_offset()));
+    __ movptr(Address(rbp, wordSize), rbx);
   }
 
   // do the call
@@ -3029,11 +3029,63 @@
 
   __ bind(noException);
 
+  Label no_adjust, bail, not_special;
+  if (SafepointMechanism::uses_thread_local_poll() && !cause_return) {
+    // If our stashed return pc was modified by the runtime we avoid touching it
+    __ cmpptr(rbx, Address(rbp, wordSize));
+    __ jccb(Assembler::notEqual, no_adjust);
+
+    // Skip over the poll instruction.
+    // See NativeInstruction::is_safepoint_poll()
+    // Possible encodings:
+    //      85 00       test   %eax,(%rax)
+    //      85 01       test   %eax,(%rcx)
+    //      85 02       test   %eax,(%rdx)
+    //      85 03       test   %eax,(%rbx)
+    //      85 06       test   %eax,(%rsi)
+    //      85 07       test   %eax,(%rdi)
+    //
+    //      85 04 24    test   %eax,(%rsp)
+    //      85 45 00    test   %eax,0x0(%rbp)
+
+#ifdef ASSERT
+    __ movptr(rax, rbx); // remember where 0x85 should be, for verification below
+#endif
+    // rsp/rbp base encoding takes 3 bytes with the following register values:
+    // rsp 0x04
+    // rbp 0x05
+    __ movzbl(rcx, Address(rbx, 1));
+    __ andptr(rcx, 0x07); // looking for 0x04 .. 0x05
+    __ subptr(rcx, 4);    // looking for 0x00 .. 0x01
+    __ cmpptr(rcx, 1);
+    __ jcc(Assembler::above, not_special);
+    __ addptr(rbx, 1);
+    __ bind(not_special);
+#ifdef ASSERT
+    // Verify the correct encoding of the poll we're about to skip.
+    __ cmpb(Address(rax, 0), NativeTstRegMem::instruction_code_memXregl);
+    __ jcc(Assembler::notEqual, bail);
+    // Mask out the modrm bits
+    __ testb(Address(rax, 1), NativeTstRegMem::modrm_mask);
+    // rax encodes to 0, so if the bits are nonzero it's incorrect
+    __ jcc(Assembler::notZero, bail);
+#endif
+    // Adjust return pc forward to step over the safepoint poll instruction
+    __ addptr(rbx, 2);
+    __ movptr(Address(rbp, wordSize), rbx);
+  }
+
+  __ bind(no_adjust);
   // Normal exit, register restoring and exit
   RegisterSaver::restore_live_registers(masm, save_vectors);
 
   __ ret(0);
 
+#ifdef ASSERT
+  __ bind(bail);
+  __ stop("Attempting to adjust pc to skip safepoint poll but the return point is not what we expected");
+#endif
+
   // make sure all code is generated
   masm->flush();
 
--- a/src/hotspot/cpu/x86/stubRoutines_x86.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/cpu/x86/stubRoutines_x86.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -303,45 +303,45 @@
 // used in MacroAssembler::sha512_AVX2
 ALIGNED_(64) julong StubRoutines::x86::_k512_W[] =
 {
-    0x428a2f98d728ae22LL, 0x7137449123ef65cdLL,
-    0xb5c0fbcfec4d3b2fLL, 0xe9b5dba58189dbbcLL,
-    0x3956c25bf348b538LL, 0x59f111f1b605d019LL,
-    0x923f82a4af194f9bLL, 0xab1c5ed5da6d8118LL,
-    0xd807aa98a3030242LL, 0x12835b0145706fbeLL,
-    0x243185be4ee4b28cLL, 0x550c7dc3d5ffb4e2LL,
-    0x72be5d74f27b896fLL, 0x80deb1fe3b1696b1LL,
-    0x9bdc06a725c71235LL, 0xc19bf174cf692694LL,
-    0xe49b69c19ef14ad2LL, 0xefbe4786384f25e3LL,
-    0x0fc19dc68b8cd5b5LL, 0x240ca1cc77ac9c65LL,
-    0x2de92c6f592b0275LL, 0x4a7484aa6ea6e483LL,
-    0x5cb0a9dcbd41fbd4LL, 0x76f988da831153b5LL,
-    0x983e5152ee66dfabLL, 0xa831c66d2db43210LL,
-    0xb00327c898fb213fLL, 0xbf597fc7beef0ee4LL,
-    0xc6e00bf33da88fc2LL, 0xd5a79147930aa725LL,
-    0x06ca6351e003826fLL, 0x142929670a0e6e70LL,
-    0x27b70a8546d22ffcLL, 0x2e1b21385c26c926LL,
-    0x4d2c6dfc5ac42aedLL, 0x53380d139d95b3dfLL,
-    0x650a73548baf63deLL, 0x766a0abb3c77b2a8LL,
-    0x81c2c92e47edaee6LL, 0x92722c851482353bLL,
-    0xa2bfe8a14cf10364LL, 0xa81a664bbc423001LL,
-    0xc24b8b70d0f89791LL, 0xc76c51a30654be30LL,
-    0xd192e819d6ef5218LL, 0xd69906245565a910LL,
-    0xf40e35855771202aLL, 0x106aa07032bbd1b8LL,
-    0x19a4c116b8d2d0c8LL, 0x1e376c085141ab53LL,
-    0x2748774cdf8eeb99LL, 0x34b0bcb5e19b48a8LL,
-    0x391c0cb3c5c95a63LL, 0x4ed8aa4ae3418acbLL,
-    0x5b9cca4f7763e373LL, 0x682e6ff3d6b2b8a3LL,
-    0x748f82ee5defb2fcLL, 0x78a5636f43172f60LL,
-    0x84c87814a1f0ab72LL, 0x8cc702081a6439ecLL,
-    0x90befffa23631e28LL, 0xa4506cebde82bde9LL,
-    0xbef9a3f7b2c67915LL, 0xc67178f2e372532bLL,
-    0xca273eceea26619cLL, 0xd186b8c721c0c207LL,
-    0xeada7dd6cde0eb1eLL, 0xf57d4f7fee6ed178LL,
-    0x06f067aa72176fbaLL, 0x0a637dc5a2c898a6LL,
-    0x113f9804bef90daeLL, 0x1b710b35131c471bLL,
-    0x28db77f523047d84LL, 0x32caab7b40c72493LL,
-    0x3c9ebe0a15c9bebcLL, 0x431d67c49c100d4cLL,
-    0x4cc5d4becb3e42b6LL, 0x597f299cfc657e2aLL,
-    0x5fcb6fab3ad6faecLL, 0x6c44198c4a475817LL,
+    0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
+    0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
+    0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
+    0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
+    0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
+    0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
+    0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
+    0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
+    0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
+    0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
+    0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
+    0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
+    0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
+    0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
+    0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
+    0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
+    0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
+    0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
+    0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
+    0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
+    0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
+    0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
+    0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
+    0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
+    0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
+    0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
+    0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
+    0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
+    0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
+    0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
+    0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
+    0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
+    0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
+    0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
+    0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
+    0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
+    0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
+    0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
+    0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
+    0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL,
 };
 #endif
--- a/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -1148,7 +1148,7 @@
     Label slow_path;
 
 #ifndef _LP64
-    __ safepoint_poll(slow_path);
+    __ safepoint_poll(slow_path, thread, noreg);
 #else
     __ safepoint_poll(slow_path, r15_thread, rscratch1);
 #endif
--- a/src/hotspot/cpu/x86/templateInterpreterGenerator_x86_32.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/cpu/x86/templateInterpreterGenerator_x86_32.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -61,10 +61,7 @@
 
     Label slow_path;
     // If we need a safepoint check, generate full interpreter entry.
-    ExternalAddress state(SafepointSynchronize::address_of_state());
-    __ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()),
-             SafepointSynchronize::_not_synchronized);
-    __ jcc(Assembler::notEqual, slow_path);
+    __ safepoint_poll(slow_path, noreg, rdi);
 
     // We don't generate local frame and don't align stack because
     // we call stub code and there is no safepoint on this path.
@@ -113,10 +110,7 @@
 
     Label slow_path;
     // If we need a safepoint check, generate full interpreter entry.
-    ExternalAddress state(SafepointSynchronize::address_of_state());
-    __ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()),
-             SafepointSynchronize::_not_synchronized);
-    __ jcc(Assembler::notEqual, slow_path);
+    __ safepoint_poll(slow_path, noreg, rdi);
 
     // We don't generate local frame and don't align stack because
     // we call stub code and there is no safepoint on this path.
--- a/src/hotspot/cpu/x86/templateTable_x86.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/cpu/x86/templateTable_x86.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -2692,11 +2692,16 @@
     __ bind(skip_register_finalizer);
   }
 
-#ifdef _LP64
   if (SafepointMechanism::uses_thread_local_poll() && _desc->bytecode() != Bytecodes::_return_register_finalizer) {
     Label no_safepoint;
     NOT_PRODUCT(__ block_comment("Thread-local Safepoint poll"));
+#ifdef _LP64
     __ testb(Address(r15_thread, Thread::polling_page_offset()), SafepointMechanism::poll_bit());
+#else
+    const Register thread = rdi;
+    __ get_thread(thread);
+    __ testb(Address(thread, Thread::polling_page_offset()), SafepointMechanism::poll_bit());
+#endif
     __ jcc(Assembler::zero, no_safepoint);
     __ push(state);
     __ call_VM(noreg, CAST_FROM_FN_PTR(address,
@@ -2704,7 +2709,6 @@
     __ pop(state);
     __ bind(no_safepoint);
   }
-#endif
 
   // Narrow result if state is itos but result type is smaller.
   // Need to narrow in the return bytecode rather than in generate_return_entry
--- a/src/hotspot/cpu/x86/x86_32.ad	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/cpu/x86/x86_32.ad	Sun Feb 25 04:59:43 2018 +0100
@@ -317,7 +317,7 @@
 // Indicate if the safepoint node needs the polling page as an input.
 // Since x86 does have absolute addressing, it doesn't.
 bool SafePointNode::needs_polling_address_input() {
-  return false;
+  return SafepointMechanism::uses_thread_local_poll();
 }
 
 //
@@ -706,34 +706,25 @@
   }
 
   if (do_polling() && C->is_method_compilation()) {
-    cbuf.relocate(cbuf.insts_end(), relocInfo::poll_return_type, 0);
-    emit_opcode(cbuf,0x85);
-    emit_rm(cbuf, 0x0, EAX_enc, 0x5); // EAX
-    emit_d32(cbuf, (intptr_t)os::get_polling_page());
+    if (SafepointMechanism::uses_thread_local_poll()) {
+      Register pollReg = as_Register(EBX_enc);
+      MacroAssembler masm(&cbuf);
+      masm.get_thread(pollReg);
+      masm.movl(pollReg, Address(pollReg, in_bytes(Thread::polling_page_offset())));
+      masm.relocate(relocInfo::poll_return_type);
+      masm.testl(rax, Address(pollReg, 0));
+    } else {
+      cbuf.relocate(cbuf.insts_end(), relocInfo::poll_return_type, 0);
+      emit_opcode(cbuf,0x85);
+      emit_rm(cbuf, 0x0, EAX_enc, 0x5); // EAX
+      emit_d32(cbuf, (intptr_t)os::get_polling_page());
+    }
   }
 }
 
 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const {
-  Compile *C = ra_->C;
-  // If method set FPU control word, restore to standard control word
-  int size = C->in_24_bit_fp_mode() ? 6 : 0;
-  if (C->max_vector_size() > 16) size += 3; // vzeroupper
-  if (do_polling() && C->is_method_compilation()) size += 6;
-
-  int framesize = C->frame_size_in_bytes();
-  assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
-  // Remove two words for return addr and rbp,
-  framesize -= 2*wordSize;
-
-  size++; // popl rbp,
-
-  if (framesize >= 128) {
-    size += 6;
-  } else {
-    size += framesize ? 3 : 0;
-  }
-  size += 64; // added to support ReservedStackAccess
-  return size;
+  return MachNode::size(ra_); // too many variables; just compute it
+                              // the hard way
 }
 
 int MachEpilogNode::reloc() const {
@@ -13336,6 +13327,7 @@
 // ============================================================================
 // Safepoint Instruction
 instruct safePoint_poll(eFlagsReg cr) %{
+  predicate(SafepointMechanism::uses_global_page_poll());
   match(SafePoint);
   effect(KILL cr);
 
@@ -13354,6 +13346,25 @@
   ins_pipe( ialu_reg_mem );
 %}
 
+instruct safePoint_poll_tls(eFlagsReg cr, eRegP_no_EBP poll) %{
+  predicate(SafepointMechanism::uses_thread_local_poll());
+  match(SafePoint poll);
+  effect(KILL cr, USE poll);
+
+  format %{ "TSTL   #EAX,[$poll]\t! Safepoint: poll for GC" %}
+  ins_cost(125);
+  // EBP would need size(3)
+  size(2); /* setting an explicit size will cause debug builds to assert if size is incorrect */
+  ins_encode %{
+    __ relocate(relocInfo::poll_type);
+    address pre_pc = __ pc();
+    __ testl(rax, Address($poll$$Register, 0));
+    address post_pc = __ pc();
+    guarantee(pre_pc[0] == 0x85, "must emit test-ax [reg]");
+  %}
+  ins_pipe(ialu_reg_mem);
+%}
+
 
 // ============================================================================
 // This name is KNOWN by the ADLC and cannot be changed.
--- a/src/hotspot/os/bsd/decoder_machO.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/os/bsd/decoder_machO.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -27,6 +27,7 @@
 #ifdef __APPLE__
 #include "jvm.h"
 #include "decoder_machO.hpp"
+#include "memory/allocation.inline.hpp"
 
 #include <cxxabi.h>
 #include <mach-o/loader.h>
--- a/src/hotspot/os/linux/globals_linux.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/os/linux/globals_linux.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -62,6 +62,11 @@
   product(bool, UseContainerSupport, true,                              \
           "Enable detection and runtime container configuration support") \
                                                                         \
+  product(bool, PreferContainerQuotaForCPUCount, true,                  \
+          "Calculate the container CPU availability based on the value" \
+          " of quotas (if set), when true. Otherwise, use the CPU"    \
+          " shares value, provided it is less than quota.")             \
+                                                                        \
   diagnostic(bool, UseCpuAllocPath, false,                              \
              "Use CPU_ALLOC code path in os::active_processor_count ")
 
--- a/src/hotspot/os/linux/osContainer_linux.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/os/linux/osContainer_linux.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 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
@@ -499,11 +499,11 @@
 /* active_processor_count
  *
  * Calculate an appropriate number of active processors for the
- * VM to use based on these three cgroup options.
+ * VM to use based on these three inputs.
  *
  * cpu affinity
- * cpu quota & cpu period
- * cpu shares
+ * cgroup cpu quota & cpu period
+ * cgroup cpu shares
  *
  * Algorithm:
  *
@@ -513,42 +513,61 @@
  * required CPUs by dividing quota by period.
  *
  * If shares are in effect (shares != -1), calculate the number
- * of cpus required for the shares by dividing the share value
+ * of CPUs required for the shares by dividing the share value
  * by PER_CPU_SHARES.
  *
  * All results of division are rounded up to the next whole number.
  *
- * Return the smaller number from the three different settings.
+ * If neither shares or quotas have been specified, return the
+ * number of active processors in the system.
+ *
+ * If both shares and quotas have been specified, the results are
+ * based on the flag PreferContainerQuotaForCPUCount.  If true,
+ * return the quota value.  If false return the smallest value
+ * between shares or quotas.
+ *
+ * If shares and/or quotas have been specified, the resulting number
+ * returned will never exceed the number of active processors.
  *
  * return:
- *    number of cpus
- *    OSCONTAINER_ERROR if failure occured during extract of cpuset info
+ *    number of CPUs
  */
 int OSContainer::active_processor_count() {
-  int cpu_count, share_count, quota_count;
-  int share, quota, period;
+  int quota_count = 0, share_count = 0;
+  int cpu_count, limit_count;
   int result;
 
-  cpu_count = os::Linux::active_processor_count();
+  cpu_count = limit_count = os::Linux::active_processor_count();
+  int quota  = cpu_quota();
+  int period = cpu_period();
+  int share  = cpu_shares();
 
-  share = cpu_shares();
+  if (quota > -1 && period > 0) {
+    quota_count = ceilf((float)quota / (float)period);
+    log_trace(os, container)("CPU Quota count based on quota/period: %d", quota_count);
+  }
   if (share > -1) {
     share_count = ceilf((float)share / (float)PER_CPU_SHARES);
-    log_trace(os, container)("cpu_share count: %d", share_count);
-  } else {
-    share_count = cpu_count;
+    log_trace(os, container)("CPU Share count based on shares: %d", share_count);
   }
 
-  quota = cpu_quota();
-  period = cpu_period();
-  if (quota > -1 && period > 0) {
-    quota_count = ceilf((float)quota / (float)period);
-    log_trace(os, container)("quota_count: %d", quota_count);
-  } else {
-    quota_count = cpu_count;
+  // If both shares and quotas are setup results depend
+  // on flag PreferContainerQuotaForCPUCount.
+  // If true, limit CPU count to quota
+  // If false, use minimum of shares and quotas
+  if (quota_count !=0 && share_count != 0) {
+    if (PreferContainerQuotaForCPUCount) {
+      limit_count = quota_count;
+    } else {
+      limit_count = MIN2(quota_count, share_count);
+    }
+  } else if (quota_count != 0) {
+    limit_count = quota_count;
+  } else if (share_count != 0) {
+    limit_count = share_count;
   }
 
-  result = MIN2(cpu_count, MIN2(share_count, quota_count));
+  result = MIN2(cpu_count, limit_count);
   log_trace(os, container)("OSContainer::active_processor_count: %d", result);
   return result;
 }
--- a/src/hotspot/os/windows/os_windows.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/os/windows/os_windows.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -979,11 +979,6 @@
 }
 
 
-static BOOL (WINAPI *_MiniDumpWriteDump)(HANDLE, DWORD, HANDLE, MINIDUMP_TYPE,
-                                         PMINIDUMP_EXCEPTION_INFORMATION,
-                                         PMINIDUMP_USER_STREAM_INFORMATION,
-                                         PMINIDUMP_CALLBACK_INFORMATION);
-
 static HANDLE dumpFile = NULL;
 
 // Check if dump file can be created.
--- a/src/hotspot/os/windows/semaphore_windows.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/os/windows/semaphore_windows.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -27,7 +27,7 @@
 
 #include "memory/allocation.hpp"
 
-#include <windef.h>
+#include <windows.h>
 
 class WindowsSemaphore : public CHeapObj<mtInternal> {
   HANDLE _semaphore;
--- a/src/hotspot/os/windows/sharedRuntimeRem.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/os/windows/sharedRuntimeRem.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+* Copyright (c) 2015, 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
@@ -23,6 +23,7 @@
 */
 
 #include "precompiled.hpp"
+#include "runtime/sharedRuntime.hpp"
 
 #ifdef _WIN64
 // These are copied defines from fdlibm.h, this allows us to keep the code
--- a/src/hotspot/os/windows/symbolengine.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/os/windows/symbolengine.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 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
@@ -26,6 +26,7 @@
 #include "utilities/globalDefinitions.hpp"
 #include "symbolengine.hpp"
 #include "utilities/debug.hpp"
+#include "utilities/ostream.hpp"
 #include "windbghelp.hpp"
 
 #include <windows.h>
--- a/src/hotspot/os/windows/windbghelp.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/os/windows/windbghelp.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 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
@@ -22,8 +22,8 @@
  *
  */
 
-#ifndef OS_WINDOWS_VM_DBGHELPLOADER_HPP
-#define OS_WINDOWS_VM_DBGHELPLOADER_HPP
+#ifndef OS_WINDOWS_WINDBGHELP_HPP
+#define OS_WINDOWS_WINDBGHELP_HPP
 
 #include <windows.h>
 #include <imagehlp.h>
@@ -71,6 +71,5 @@
 
 };
 
+#endif // OS_WINDOWS_WINDBGHELP_HPP
 
-#endif // OS_WINDOWS_VM_DBGHELPLOADER_HPP
-
--- a/src/hotspot/share/adlc/arena.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/adlc/arena.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -69,6 +69,11 @@
 //------------------------------Chunk------------------------------------------
 // Linked list of raw memory chunks
 class Chunk: public CHeapObj {
+ private:
+  // This ordinary operator delete is needed even though not used, so the
+  // below two-argument operator delete will be treated as a placement
+  // delete rather than an ordinary sized delete; see C++14 3.7.4.2/p2.
+  void operator delete(void* p);
  public:
   void* operator new(size_t size, size_t length) throw();
   void  operator delete(void* p, size_t length);
--- a/src/hotspot/share/aot/aotCodeHeap.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/aot/aotCodeHeap.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -194,7 +194,7 @@
 }
 
 AOTLib::~AOTLib() {
-  free((void*) _name);
+  os::free((void*) _name);
 }
 
 AOTCodeHeap::~AOTCodeHeap() {
@@ -207,7 +207,7 @@
 }
 
 AOTLib::AOTLib(void* handle, const char* name, int dso_id) : _valid(true), _dl_handle(handle), _dso_id(dso_id) {
-  _name = (const char*) strdup(name);
+  _name = (const char*) os::strdup(name);
 
   // Verify that VM runs with the same parameters as AOT tool.
   _config = (AOTConfiguration*) load_symbol("A.config");
--- a/src/hotspot/share/c1/c1_Runtime1.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/c1/c1_Runtime1.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -47,6 +47,7 @@
 #include "memory/oopFactory.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/access.inline.hpp"
+#include "oops/objArrayOop.inline.hpp"
 #include "oops/objArrayKlass.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/atomic.hpp"
--- a/src/hotspot/share/ci/ciArray.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/ci/ciArray.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -30,7 +30,7 @@
 #include "ci/ciUtilities.hpp"
 #include "oops/objArrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
-#include "oops/typeArrayOop.hpp"
+#include "oops/typeArrayOop.inline.hpp"
 
 // ciArray
 //
--- a/src/hotspot/share/ci/ciTypeArray.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/ci/ciTypeArray.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -25,6 +25,7 @@
 #include "precompiled.hpp"
 #include "ci/ciTypeArray.hpp"
 #include "ci/ciUtilities.hpp"
+#include "oops/typeArrayOop.inline.hpp"
 
 // ciTypeArray
 //
--- a/src/hotspot/share/classfile/classLoader.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/classfile/classLoader.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -137,7 +137,6 @@
 PerfCounter*    ClassLoader::_sync_JVMDefineClassLockFreeCounter = NULL;
 PerfCounter*    ClassLoader::_sync_JNIDefineClassLockFreeCounter = NULL;
 PerfCounter*    ClassLoader::_unsafe_defineClassCallCounter = NULL;
-PerfCounter*    ClassLoader::_isUnsyncloadClass = NULL;
 PerfCounter*    ClassLoader::_load_instance_class_failCounter = NULL;
 
 GrowableArray<ModuleClassPathList*>* ClassLoader::_patch_mod_entries = NULL;
@@ -1642,9 +1641,6 @@
     // of the bug fix of 6365597. They are mainly focused on finding out
     // the behavior of system & user-defined classloader lock, whether
     // ClassLoader.loadClass/findClass is being called synchronized or not.
-    // Also two additional counters are created to see whether 'UnsyncloadClass'
-    // flag is being set or not and how many times load_instance_class call
-    // fails with linkageError etc.
     NEWPERFEVENTCOUNTER(_sync_systemLoaderLockContentionRate, SUN_CLS,
                         "systemLoaderLockContentionRate");
     NEWPERFEVENTCOUNTER(_sync_nonSystemLoaderLockContentionRate, SUN_CLS,
@@ -1660,14 +1656,8 @@
     NEWPERFEVENTCOUNTER(_unsafe_defineClassCallCounter, SUN_CLS,
                         "unsafeDefineClassCalls");
 
-    NEWPERFEVENTCOUNTER(_isUnsyncloadClass, SUN_CLS, "isUnsyncloadClassSet");
     NEWPERFEVENTCOUNTER(_load_instance_class_failCounter, SUN_CLS,
                         "loadInstanceClassFailRate");
-
-    // increment the isUnsyncloadClass counter if UnsyncloadClass is set.
-    if (UnsyncloadClass) {
-      _isUnsyncloadClass->inc();
-    }
   }
 
   // lookup zip library entry points
--- a/src/hotspot/share/classfile/classLoader.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/classfile/classLoader.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -207,7 +207,6 @@
   static PerfCounter* _sync_JNIDefineClassLockFreeCounter;
 
   static PerfCounter* _unsafe_defineClassCallCounter;
-  static PerfCounter* _isUnsyncloadClass;
   static PerfCounter* _load_instance_class_failCounter;
 
   // The boot class path consists of 3 ordered pieces:
--- a/src/hotspot/share/classfile/classLoaderData.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/classfile/classLoaderData.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1001,9 +1001,8 @@
 
 
   if (!is_anonymous) {
-    ClassLoaderData** cld_addr = java_lang_ClassLoader::loader_data_addr(loader());
     // First, Atomically set it
-    ClassLoaderData* old = Atomic::cmpxchg(cld, cld_addr, (ClassLoaderData*)NULL);
+    ClassLoaderData* old = java_lang_ClassLoader::cmpxchg_loader_data(cld, loader(), NULL);
     if (old != NULL) {
       delete cld;
       // Returns the data.
--- a/src/hotspot/share/classfile/javaAssertions.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/classfile/javaAssertions.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -31,6 +31,7 @@
 #include "memory/oopFactory.hpp"
 #include "oops/objArrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
+#include "oops/typeArrayOop.inline.hpp"
 #include "runtime/handles.inline.hpp"
 
 bool                            JavaAssertions::_userDefault = false;
--- a/src/hotspot/share/classfile/javaClasses.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/classfile/javaClasses.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -46,7 +46,7 @@
 #include "oops/objArrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "oops/symbol.hpp"
-#include "oops/typeArrayOop.hpp"
+#include "oops/typeArrayOop.inline.hpp"
 #include "prims/resolvedMethodTable.hpp"
 #include "runtime/fieldDescriptor.hpp"
 #include "runtime/handles.inline.hpp"
@@ -3403,7 +3403,7 @@
 
 DependencyContext java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(oop call_site) {
   assert(java_lang_invoke_MethodHandleNatives_CallSiteContext::is_instance(call_site), "");
-  intptr_t* vmdeps_addr = (intptr_t*)call_site->address_field_addr(_vmdependencies_offset);
+  intptr_t* vmdeps_addr = (intptr_t*)call_site->field_addr(_vmdependencies_offset);
   DependencyContext dep_ctx(vmdeps_addr);
   return dep_ctx;
 }
@@ -3458,13 +3458,14 @@
 int  java_lang_ClassLoader::name_offset = -1;
 int  java_lang_ClassLoader::unnamedModule_offset = -1;
 
-ClassLoaderData** java_lang_ClassLoader::loader_data_addr(oop loader) {
-    assert(loader != NULL && oopDesc::is_oop(loader), "loader must be oop");
-    return (ClassLoaderData**) loader->address_field_addr(_loader_data_offset);
-}
-
 ClassLoaderData* java_lang_ClassLoader::loader_data(oop loader) {
-  return *java_lang_ClassLoader::loader_data_addr(loader);
+  assert(loader != NULL && oopDesc::is_oop(loader), "loader must be oop");
+  return HeapAccess<>::load_at(loader, _loader_data_offset);
+}
+
+ClassLoaderData* java_lang_ClassLoader::cmpxchg_loader_data(ClassLoaderData* new_data, oop loader, ClassLoaderData* expected_data) {
+  assert(loader != NULL && oopDesc::is_oop(loader), "loader must be oop");
+  return HeapAccess<>::atomic_cmpxchg_at(new_data, loader, _loader_data_offset, expected_data);
 }
 
 void java_lang_ClassLoader::compute_offsets() {
--- a/src/hotspot/share/classfile/javaClasses.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/classfile/javaClasses.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -881,15 +881,15 @@
   static inline oop referent(oop ref);
   static inline void set_referent(oop ref, oop value);
   static inline void set_referent_raw(oop ref, oop value);
-  static inline HeapWord* referent_addr(oop ref);
+  static inline HeapWord* referent_addr_raw(oop ref);
   static inline oop next(oop ref);
   static inline void set_next(oop ref, oop value);
   static inline void set_next_raw(oop ref, oop value);
-  static inline HeapWord* next_addr(oop ref);
+  static inline HeapWord* next_addr_raw(oop ref);
   static inline oop discovered(oop ref);
   static inline void set_discovered(oop ref, oop value);
   static inline void set_discovered_raw(oop ref, oop value);
-  static inline HeapWord* discovered_addr(oop ref);
+  static inline HeapWord* discovered_addr_raw(oop ref);
   static bool is_referent_field(oop obj, ptrdiff_t offset);
   static inline bool is_phantom(oop ref);
 };
@@ -1229,8 +1229,8 @@
  public:
   static void compute_offsets();
 
-  static ClassLoaderData** loader_data_addr(oop loader);
   static ClassLoaderData* loader_data(oop loader);
+  static ClassLoaderData* cmpxchg_loader_data(ClassLoaderData* new_data, oop loader, ClassLoaderData* expected_data);
 
   static oop parent(oop loader);
   static oop name(oop loader);
--- a/src/hotspot/share/classfile/javaClasses.inline.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/classfile/javaClasses.inline.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -100,8 +100,8 @@
 void java_lang_ref_Reference::set_referent_raw(oop ref, oop value) {
   ref->obj_field_put_raw(referent_offset, value);
 }
-HeapWord* java_lang_ref_Reference::referent_addr(oop ref) {
-  return ref->obj_field_addr<HeapWord>(referent_offset);
+HeapWord* java_lang_ref_Reference::referent_addr_raw(oop ref) {
+  return ref->obj_field_addr_raw<HeapWord>(referent_offset);
 }
 oop java_lang_ref_Reference::next(oop ref) {
   return ref->obj_field(next_offset);
@@ -112,8 +112,8 @@
 void java_lang_ref_Reference::set_next_raw(oop ref, oop value) {
   ref->obj_field_put_raw(next_offset, value);
 }
-HeapWord* java_lang_ref_Reference::next_addr(oop ref) {
-  return ref->obj_field_addr<HeapWord>(next_offset);
+HeapWord* java_lang_ref_Reference::next_addr_raw(oop ref) {
+  return ref->obj_field_addr_raw<HeapWord>(next_offset);
 }
 oop java_lang_ref_Reference::discovered(oop ref) {
   return ref->obj_field(discovered_offset);
@@ -124,8 +124,8 @@
 void java_lang_ref_Reference::set_discovered_raw(oop ref, oop value) {
   ref->obj_field_put_raw(discovered_offset, value);
 }
-HeapWord* java_lang_ref_Reference::discovered_addr(oop ref) {
-  return ref->obj_field_addr<HeapWord>(discovered_offset);
+HeapWord* java_lang_ref_Reference::discovered_addr_raw(oop ref) {
+  return ref->obj_field_addr_raw<HeapWord>(discovered_offset);
 }
 bool java_lang_ref_Reference::is_phantom(oop ref) {
   return InstanceKlass::cast(ref->klass())->reference_type() == REF_PHANTOM;
--- a/src/hotspot/share/classfile/stringTable.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/classfile/stringTable.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -37,6 +37,7 @@
 #include "memory/resourceArea.hpp"
 #include "oops/access.inline.hpp"
 #include "oops/oop.inline.hpp"
+#include "oops/typeArrayOop.inline.hpp"
 #include "runtime/atomic.hpp"
 #include "runtime/mutexLocker.hpp"
 #include "services/diagnosticCommand.hpp"
--- a/src/hotspot/share/classfile/systemDictionary.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/classfile/systemDictionary.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -106,7 +106,6 @@
 oop         SystemDictionary::_java_system_loader         =  NULL;
 oop         SystemDictionary::_java_platform_loader       =  NULL;
 
-bool        SystemDictionary::_has_loadClassInternal      =  false;
 bool        SystemDictionary::_has_checkPackageAccess     =  false;
 
 // lazily initialized klass variables
@@ -159,7 +158,7 @@
 // Parallel class loading check
 
 bool SystemDictionary::is_parallelCapable(Handle class_loader) {
-  if (UnsyncloadClass || class_loader.is_null()) return true;
+  if (class_loader.is_null()) return true;
   if (AlwaysLockClassLoader) return false;
   return java_lang_ClassLoader::parallelCapable(class_loader());
 }
@@ -503,8 +502,7 @@
 //
 // We only get here if
 //  1) custom classLoader, i.e. not bootstrap classloader
-//  2) UnsyncloadClass not set
-//  3) custom classLoader has broken the class loader objectLock
+//  2) custom classLoader has broken the class loader objectLock
 //     so another thread got here in parallel
 //
 // lockObject must be held.
@@ -594,7 +592,6 @@
     } else {
       placeholder = placeholders()->get_entry(p_index, p_hash, name, loader_data);
       if (placeholder && placeholder->super_load_in_progress() ){
-        // Before UnsyncloadClass:
         // We only get here if the application has released the
         // classloader lock when another thread was in the middle of loading a
         // superclass/superinterface for this class, and now
@@ -687,9 +684,9 @@
   // defining the class in parallel by accident.
   // This lock must be acquired here so the waiter will find
   // any successful result in the SystemDictionary and not attempt
-  // the define
-  // ParallelCapable Classloaders and the bootstrap classloader,
-  // or all classloaders with UnsyncloadClass do not acquire lock here
+  // the define.
+  // ParallelCapable Classloaders and the bootstrap classloader
+  // do not acquire lock here.
   bool DoObjectLock = true;
   if (is_parallelCapable(class_loader)) {
     DoObjectLock = false;
@@ -765,14 +762,11 @@
     //    and that lock is still held when calling classloader's loadClass.
     //    For these classloaders, we ensure that the first requestor
     //    completes the load and other requestors wait for completion.
-    // case 3. UnsyncloadClass - don't use objectLocker
-    //    With this flag, we allow parallel classloading of a
-    //    class/classloader pair
-    // case4. Bootstrap classloader - don't own objectLocker
+    // case 3. Bootstrap classloader - don't own objectLocker
     //    This classloader supports parallelism at the classloader level,
     //    but only allows a single load of a class/classloader pair.
     //    No performance benefit and no deadlock issues.
-    // case 5. parallelCapable user level classloaders - without objectLocker
+    // case 4. parallelCapable user level classloaders - without objectLocker
     //    Allow parallel classloading of a class/classloader pair
 
     {
@@ -788,7 +782,7 @@
             // case 1: traditional: should never see load_in_progress.
             while (!class_has_been_loaded && oldprobe && oldprobe->instance_load_in_progress()) {
 
-              // case 4: bootstrap classloader: prevent futile classloading,
+              // case 3: bootstrap classloader: prevent futile classloading,
               // wait on first requestor
               if (class_loader.is_null()) {
                 SystemDictionary_lock->wait();
@@ -811,7 +805,7 @@
         }
       }
       // All cases: add LOAD_INSTANCE holding SystemDictionary_lock
-      // case 3: UnsyncloadClass || case 5: parallelCapable: allow competing threads to try
+      // case 4: parallelCapable: allow competing threads to try
       // LOAD_INSTANCE in parallel
 
       if (!throw_circularity_error && !class_has_been_loaded) {
@@ -844,28 +838,6 @@
       // Do actual loading
       k = load_instance_class(name, class_loader, THREAD);
 
-      // For UnsyncloadClass only
-      // If they got a linkageError, check if a parallel class load succeeded.
-      // If it did, then for bytecode resolution the specification requires
-      // that we return the same result we did for the other thread, i.e. the
-      // successfully loaded InstanceKlass
-      // Should not get here for classloaders that support parallelism
-      // with the new cleaner mechanism, even with AllowParallelDefineClass
-      // Bootstrap goes through here to allow for an extra guarantee check
-      if (UnsyncloadClass || (class_loader.is_null())) {
-        if (k == NULL && HAS_PENDING_EXCEPTION
-          && PENDING_EXCEPTION->is_a(SystemDictionary::LinkageError_klass())) {
-          MutexLocker mu(SystemDictionary_lock, THREAD);
-          InstanceKlass* check = find_class(d_hash, name, dictionary);
-          if (check != NULL) {
-            // Klass is already loaded, so just use it
-            k = check;
-            CLEAR_PENDING_EXCEPTION;
-            guarantee((!class_loader.is_null()), "dup definition for bootstrap loader?");
-          }
-        }
-      }
-
       // If everything was OK (no exceptions, no null return value), and
       // class_loader is NOT the defining loader, do a little more bookkeeping.
       if (!HAS_PENDING_EXCEPTION && k != NULL &&
@@ -1097,7 +1069,7 @@
   HandleMark hm(THREAD);
 
   // Classloaders that support parallelism, e.g. bootstrap classloader,
-  // or all classloaders with UnsyncloadClass do not acquire lock here
+  // do not acquire lock here
   bool DoObjectLock = true;
   if (is_parallelCapable(class_loader)) {
     DoObjectLock = false;
@@ -1556,40 +1528,17 @@
 
     InstanceKlass* spec_klass = SystemDictionary::ClassLoader_klass();
 
-    // Call public unsynchronized loadClass(String) directly for all class loaders
-    // for parallelCapable class loaders. JDK >=7, loadClass(String, boolean) will
+    // Call public unsynchronized loadClass(String) directly for all class loaders.
+    // For parallelCapable class loaders, JDK >=7, loadClass(String, boolean) will
     // acquire a class-name based lock rather than the class loader object lock.
-    // JDK < 7 already acquire the class loader lock in loadClass(String, boolean),
-    // so the call to loadClassInternal() was not required.
-    //
-    // UnsyncloadClass flag means both call loadClass(String) and do
-    // not acquire the class loader lock even for class loaders that are
-    // not parallelCapable. This was a risky transitional
-    // flag for diagnostic purposes only. It is risky to call
-    // custom class loaders without synchronization.
-    // WARNING If a custom class loader does NOT synchronizer findClass, or callers of
-    // findClass, the UnsyncloadClass flag risks unexpected timing bugs in the field.
-    // Do NOT assume this will be supported in future releases.
-    //
-    // Added MustCallLoadClassInternal in case we discover in the field
-    // a customer that counts on this call
-    if (MustCallLoadClassInternal && has_loadClassInternal()) {
-      JavaCalls::call_special(&result,
-                              class_loader,
-                              spec_klass,
-                              vmSymbols::loadClassInternal_name(),
-                              vmSymbols::string_class_signature(),
-                              string,
-                              CHECK_NULL);
-    } else {
-      JavaCalls::call_virtual(&result,
-                              class_loader,
-                              spec_klass,
-                              vmSymbols::loadClass_name(),
-                              vmSymbols::string_class_signature(),
-                              string,
-                              CHECK_NULL);
-    }
+    // JDK < 7 already acquire the class loader lock in loadClass(String, boolean).
+    JavaCalls::call_virtual(&result,
+                            class_loader,
+                            spec_klass,
+                            vmSymbols::loadClass_name(),
+                            vmSymbols::string_class_signature(),
+                            string,
+                            CHECK_NULL);
 
     assert(result.get_type() == T_OBJECT, "just checking");
     oop obj = (oop) result.get_jobject();
@@ -1718,7 +1667,7 @@
   {
     MutexLocker mu(SystemDictionary_lock, THREAD);
     // First check if class already defined
-    if (UnsyncloadClass || (is_parallelDefine(class_loader))) {
+    if (is_parallelDefine(class_loader)) {
       InstanceKlass* check = find_class(d_hash, name_h, dictionary);
       if (check != NULL) {
         return check;
@@ -1737,7 +1686,7 @@
     // Only special cases allow parallel defines and can use other thread's results
     // Other cases fall through, and may run into duplicate defines
     // caught by finding an entry in the SystemDictionary
-    if ((UnsyncloadClass || is_parallelDefine(class_loader)) && (probe->instance_klass() != NULL)) {
+    if (is_parallelDefine(class_loader) && (probe->instance_klass() != NULL)) {
         placeholders()->find_and_remove(p_index, p_hash, name_h, loader_data, PlaceholderTable::DEFINE_CLASS, THREAD);
         SystemDictionary_lock->notify_all();
 #ifdef ASSERT
@@ -2174,10 +2123,6 @@
   //_box_klasses[T_OBJECT]  = WK_KLASS(object_klass);
   //_box_klasses[T_ARRAY]   = WK_KLASS(object_klass);
 
-  { // Compute whether we should use loadClass or loadClassInternal when loading classes.
-    Method* method = InstanceKlass::cast(ClassLoader_klass())->find_method(vmSymbols::loadClassInternal_name(), vmSymbols::string_class_signature());
-    _has_loadClassInternal = (method != NULL);
-  }
   { // Compute whether we should use checkPackageAccess or NOT
     Method* method = InstanceKlass::cast(ClassLoader_klass())->find_method(vmSymbols::checkPackageAccess_name(), vmSymbols::class_protectiondomain_signature());
     _has_checkPackageAccess = (method != NULL);
--- a/src/hotspot/share/classfile/systemDictionary.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/classfile/systemDictionary.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -467,9 +467,6 @@
   static void load_abstract_ownable_synchronizer_klass(TRAPS);
 
 protected:
-  // Tells whether ClassLoader.loadClassInternal is present
-  static bool has_loadClassInternal()       { return _has_loadClassInternal; }
-
   // Returns the class loader data to be used when looking up/updating the
   // system dictionary.
   static ClassLoaderData *class_loader_data(Handle class_loader) {
@@ -746,7 +743,6 @@
   static oop  _java_system_loader;
   static oop  _java_platform_loader;
 
-  static bool _has_loadClassInternal;
   static bool _has_checkPackageAccess;
 };
 
--- a/src/hotspot/share/classfile/systemDictionaryShared.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/classfile/systemDictionaryShared.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -48,6 +48,7 @@
 #include "oops/klass.inline.hpp"
 #include "oops/objArrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
+#include "oops/typeArrayOop.inline.hpp"
 #include "runtime/java.hpp"
 #include "runtime/javaCalls.hpp"
 #include "runtime/mutexLocker.hpp"
--- a/src/hotspot/share/classfile/vmSymbols.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/classfile/vmSymbols.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -360,7 +360,6 @@
   template(run_finalization_name,                     "runFinalization")                          \
   template(dispatchUncaughtException_name,            "dispatchUncaughtException")                \
   template(loadClass_name,                            "loadClass")                                \
-  template(loadClassInternal_name,                    "loadClassInternal")                        \
   template(get_name,                                  "get")                                      \
   template(put_name,                                  "put")                                      \
   template(type_name,                                 "type")                                     \
--- a/src/hotspot/share/gc/cms/cmsCollectorPolicy.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/cms/cmsCollectorPolicy.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -51,26 +51,3 @@
   _space_alignment = _gen_alignment = (uintx)Generation::GenGrain;
   _heap_alignment = compute_heap_alignment();
 }
-
-void ConcurrentMarkSweepPolicy::initialize_generations() {
-  _young_gen_spec = new GenerationSpec(Generation::ParNew, _initial_young_size,
-                                       _max_young_size, _gen_alignment);
-  _old_gen_spec   = new GenerationSpec(Generation::ConcurrentMarkSweep,
-                                       _initial_old_size, _max_old_size, _gen_alignment);
-}
-
-void ConcurrentMarkSweepPolicy::initialize_size_policy(size_t init_eden_size,
-                                               size_t init_promo_size,
-                                               size_t init_survivor_size) {
-  double max_gc_pause_sec = ((double) MaxGCPauseMillis)/1000.0;
-  _size_policy = new AdaptiveSizePolicy(init_eden_size,
-                                        init_promo_size,
-                                        init_survivor_size,
-                                        max_gc_pause_sec,
-                                        GCTimeRatio);
-}
-
-void ConcurrentMarkSweepPolicy::initialize_gc_policy_counters() {
-  // initialize the policy counters - 2 collectors, 2 generations
-  _gc_policy_counters = new GCPolicyCounters("ParNew:CMS", 2, 2);
-}
--- a/src/hotspot/share/gc/cms/cmsCollectorPolicy.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/cms/cmsCollectorPolicy.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -30,18 +30,9 @@
 class ConcurrentMarkSweepPolicy : public GenCollectorPolicy {
  protected:
   void initialize_alignments();
-  void initialize_generations();
 
  public:
   ConcurrentMarkSweepPolicy() {}
-
-  ConcurrentMarkSweepPolicy* as_concurrent_mark_sweep_policy() { return this; }
-
-  void initialize_gc_policy_counters();
-
-  virtual void initialize_size_policy(size_t init_eden_size,
-                                      size_t init_promo_size,
-                                      size_t init_survivor_size);
 };
 
 #endif // SHARE_VM_GC_CMS_CMSCOLLECTORPOLICY_HPP
--- a/src/hotspot/share/gc/cms/cmsHeap.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/cms/cmsHeap.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -64,7 +64,13 @@
 };
 
 CMSHeap::CMSHeap(GenCollectorPolicy *policy) :
-  GenCollectedHeap(policy), _eden_pool(NULL), _survivor_pool(NULL), _old_pool(NULL) {
+    GenCollectedHeap(policy,
+                     Generation::ParNew,
+                     Generation::ConcurrentMarkSweep,
+                     "ParNew::CMS"),
+    _eden_pool(NULL),
+    _survivor_pool(NULL),
+    _old_pool(NULL) {
   _workers = new WorkGang("GC Thread", ParallelGCThreads,
                           /* are_GC_task_threads */true,
                           /* are_ConcurrentGC_threads */false);
@@ -77,7 +83,6 @@
 
   // If we are running CMS, create the collector responsible
   // for collecting the CMS generations.
-  assert(collector_policy()->is_concurrent_mark_sweep_policy(), "must be CMS policy");
   if (!create_cms_collector()) {
     return JNI_ENOMEM;
   }
@@ -152,11 +157,10 @@
 bool CMSHeap::create_cms_collector() {
   assert(old_gen()->kind() == Generation::ConcurrentMarkSweep,
          "Unexpected generation kinds");
-  assert(gen_policy()->is_concurrent_mark_sweep_policy(), "Unexpected policy type");
   CMSCollector* collector =
     new CMSCollector((ConcurrentMarkSweepGeneration*) old_gen(),
                      rem_set(),
-                     gen_policy()->as_concurrent_mark_sweep_policy());
+                     (ConcurrentMarkSweepPolicy*) gen_policy());
 
   if (collector == NULL || !collector->completed_initialization()) {
     if (collector) {
--- a/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -300,8 +300,7 @@
 }
 
 AdaptiveSizePolicy* CMSCollector::size_policy() {
-  CMSHeap* heap = CMSHeap::heap();
-  return heap->gen_policy()->size_policy();
+  return CMSHeap::heap()->size_policy();
 }
 
 void ConcurrentMarkSweepGeneration::initialize_performance_counters() {
@@ -1182,8 +1181,6 @@
   // this is not likely to be productive in practice because it's probably too
   // late anyway.
   CMSHeap* heap = CMSHeap::heap();
-  assert(heap->collector_policy()->is_generation_policy(),
-         "You may want to check the correctness of the following");
   if (heap->incremental_collection_will_fail(true /* consult_young */)) {
     log.print("CMSCollector: collect because incremental collection will fail ");
     return true;
@@ -1498,7 +1495,7 @@
                                          max_eden_size,
                                          full,
                                          gc_cause,
-                                         heap->collector_policy());
+                                         heap->soft_ref_policy());
 
   // Reset the expansion cause, now that we just completed
   // a collection cycle.
@@ -1890,7 +1887,7 @@
   }
 
   // Should this be in gc_epilogue?
-  collector_policy()->counters()->update_counters();
+  heap->counters()->update_counters();
 
   {
     // Clear _foregroundGCShouldWait and, in the event that the
@@ -5551,7 +5548,7 @@
   // already have the lock
   assert(_collectorState == Resetting, "just checking");
   assert_lock_strong(bitMapLock());
-  GCIdMarkAndRestore gc_id_mark(_cmsThread->gc_id());
+  GCIdMark gc_id_mark(_cmsThread->gc_id());
   _markBitMap.clear_all();
   _collectorState = Idling;
   register_gc_end();
--- a/src/hotspot/share/gc/cms/parNewGeneration.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/cms/parNewGeneration.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -889,7 +889,7 @@
 
   _gc_timer->register_gc_start();
 
-  AdaptiveSizePolicy* size_policy = gch->gen_policy()->size_policy();
+  AdaptiveSizePolicy* size_policy = gch->size_policy();
   WorkGang* workers = gch->workers();
   assert(workers != NULL, "Need workgang for parallel work");
   uint active_workers =
@@ -1490,4 +1490,3 @@
   SharedRestorePreservedMarksTaskExecutor task_executor(CMSHeap::heap()->workers());
   _preserved_marks_set.restore(&task_executor);
 }
-
--- a/src/hotspot/share/gc/g1/concurrentMarkThread.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/g1/concurrentMarkThread.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -268,8 +268,6 @@
 
     cm()->concurrent_cycle_start();
 
-    assert(GCId::current() != GCId::undefined(), "GC id should have been set up by the initial mark GC.");
-
     GCTraceConcTime(Info, gc) tt("Concurrent Cycle");
     {
       ResourceMark rm;
--- a/src/hotspot/share/gc/g1/g1AllocationContext.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1AllocationContext.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -41,12 +41,4 @@
   }
 };
 
-class AllocationContextStats: public StackObj {
-public:
-  inline void clear() { }
-  inline void update(bool full_gc) { }
-  inline void update_after_mark() { }
-  inline bool available() { return false; }
-};
-
 #endif // SHARE_VM_GC_G1_G1ALLOCATIONCONTEXT_HPP
--- a/src/hotspot/share/gc/g1/g1Arguments.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1Arguments.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -40,9 +40,6 @@
 void G1Arguments::initialize_flags() {
   GCArguments::initialize_flags();
   assert(UseG1GC, "Error");
-#if defined(COMPILER1) || INCLUDE_JVMCI
-  FastTLABRefill = false;
-#endif
   FLAG_SET_DEFAULT(ParallelGCThreads, Abstract_VM_Version::parallel_worker_threads());
   if (ParallelGCThreads == 0) {
     assert(!FLAG_IS_DEFAULT(ParallelGCThreads), "The default value for ParallelGCThreads should not be 0.");
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -59,6 +59,7 @@
 #include "gc/g1/heapRegionRemSet.hpp"
 #include "gc/g1/heapRegionSet.inline.hpp"
 #include "gc/g1/vm_operations_g1.hpp"
+#include "gc/shared/adaptiveSizePolicy.hpp"
 #include "gc/shared/gcHeapSummary.hpp"
 #include "gc/shared/gcId.hpp"
 #include "gc/shared/gcLocker.inline.hpp"
@@ -1168,7 +1169,7 @@
   }
 
   const bool do_clear_all_soft_refs = clear_all_soft_refs ||
-      collector_policy()->should_clear_all_soft_refs();
+      soft_ref_policy()->should_clear_all_soft_refs();
 
   G1FullCollector collector(this, &_full_gc_memory_manager, explicit_gc, do_clear_all_soft_refs);
   GCTraceTime(Info, gc) tm("Pause Full", NULL, gc_cause(), true);
@@ -1343,7 +1344,7 @@
     return result;
   }
 
-  assert(!collector_policy()->should_clear_all_soft_refs(),
+  assert(!soft_ref_policy()->should_clear_all_soft_refs(),
          "Flag should have been handled and cleared prior to this point");
 
   // What else?  We might try synchronous finalization later.  If the total
@@ -1463,6 +1464,7 @@
   CollectedHeap(),
   _young_gen_sampling_thread(NULL),
   _collector_policy(collector_policy),
+  _soft_ref_policy(),
   _memory_manager("G1 Young Generation", "end of minor GC"),
   _full_gc_memory_manager("G1 Old Generation", "end of major GC"),
   _eden_pool(NULL),
@@ -1893,6 +1895,10 @@
   return _collector_policy;
 }
 
+SoftRefPolicy* G1CollectedHeap::soft_ref_policy() {
+  return &_soft_ref_policy;
+}
+
 size_t G1CollectedHeap::capacity() const {
   return _hrm.length() * HeapRegion::GrainBytes;
 }
@@ -1989,7 +1995,6 @@
   switch (cause) {
     case GCCause::_java_lang_system_gc:                 return ExplicitGCInvokesConcurrent;
     case GCCause::_dcmd_gc_run:                         return ExplicitGCInvokesConcurrent;
-    case GCCause::_update_allocation_context_stats_inc: return true;
     case GCCause::_wb_conc_mark:                        return true;
     default :                                           return false;
   }
@@ -2542,8 +2547,6 @@
   resize_all_tlabs();
   g1_policy()->phase_times()->record_resize_tlab_time_ms((os::elapsedTime() - start) * 1000.0);
 
-  allocation_context_stats().update(full);
-
   MemoryService::track_memory_usage();
   // We have just completed a GC. Update the soft reference
   // policy with the new heap occupancy
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -49,6 +49,7 @@
 #include "gc/shared/gcHeapSummary.hpp"
 #include "gc/shared/plab.hpp"
 #include "gc/shared/preservedMarks.hpp"
+#include "gc/shared/softRefPolicy.hpp"
 #include "memory/memRegion.hpp"
 #include "services/memoryManager.hpp"
 #include "utilities/stack.hpp"
@@ -150,6 +151,8 @@
   WorkGang* _workers;
   G1CollectorPolicy* _collector_policy;
 
+  SoftRefPolicy      _soft_ref_policy;
+
   GCMemoryManager _memory_manager;
   GCMemoryManager _full_gc_memory_manager;
 
@@ -222,9 +225,6 @@
   // Class that handles archive allocation ranges.
   G1ArchiveAllocator* _archive_allocator;
 
-  // Statistics for each allocation context
-  AllocationContextStats _allocation_context_stats;
-
   // GC allocation statistics policy for survivors.
   G1EvacStats _survivor_evac_stats;
 
@@ -277,8 +277,7 @@
   // (b) cause == _g1_humongous_allocation
   // (c) cause == _java_lang_system_gc and +ExplicitGCInvokesConcurrent.
   // (d) cause == _dcmd_gc_run and +ExplicitGCInvokesConcurrent.
-  // (e) cause == _update_allocation_context_stats_inc
-  // (f) cause == _wb_conc_mark
+  // (e) cause == _wb_conc_mark
   bool should_do_concurrent_full_gc(GCCause::Cause cause);
 
   // indicates whether we are in young or mixed GC mode
@@ -580,8 +579,6 @@
   // Determines PLAB size for a given destination.
   inline size_t desired_plab_sz(InCSetState dest);
 
-  inline AllocationContextStats& allocation_context_stats();
-
   // Do anything common to GC's.
   void gc_prologue(bool full);
   void gc_epilogue(bool full);
@@ -998,8 +995,7 @@
 
   virtual CollectorPolicy* collector_policy() const;
 
-  // Adaptive size policy.  No such thing for g1.
-  virtual AdaptiveSizePolicy* size_policy() { return NULL; }
+  virtual SoftRefPolicy* soft_ref_policy();
 
   virtual GrowableArray<GCMemoryManager*> memory_managers();
   virtual GrowableArray<MemoryPool*> memory_pools();
@@ -1130,11 +1126,6 @@
   // "CollectedHeap" supports.
   virtual void collect(GCCause::Cause cause);
 
-  virtual bool copy_allocation_context_stats(const jint* contexts,
-                                             jlong* totals,
-                                             jbyte* accuracy,
-                                             jint len);
-
   // True iff an evacuation has failed in the most-recent collection.
   bool evacuation_failed() { return _evacuation_failed; }
 
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -57,10 +57,6 @@
 
 // Inline functions for G1CollectedHeap
 
-inline AllocationContextStats& G1CollectedHeap::allocation_context_stats() {
-  return _allocation_context_stats;
-}
-
 // Return the region with the given index. It assumes the index is valid.
 inline HeapRegion* G1CollectedHeap::region_at(uint index) const { return _hrm.at(index); }
 
--- a/src/hotspot/share/gc/g1/g1CollectedHeap_ext.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap_ext.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -30,13 +30,6 @@
 
 class STWGCTimer;
 
-bool G1CollectedHeap::copy_allocation_context_stats(const jint* contexts,
-                                                    jlong* totals,
-                                                    jbyte* accuracy,
-                                                    jint len) {
-  return false;
-}
-
 G1Policy* G1CollectedHeap::create_g1_policy(STWGCTimer* gc_timer) {
   return new G1DefaultPolicy(gc_timer);
 }
--- a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -38,6 +38,7 @@
 #include "gc/g1/heapRegion.inline.hpp"
 #include "gc/g1/heapRegionRemSet.hpp"
 #include "gc/g1/heapRegionSet.inline.hpp"
+#include "gc/shared/adaptiveSizePolicy.hpp"
 #include "gc/shared/gcId.hpp"
 #include "gc/shared/gcTimer.hpp"
 #include "gc/shared/gcTrace.hpp"
@@ -1275,7 +1276,6 @@
   // We reclaimed old regions so we should calculate the sizes to make
   // sure we update the old gen/space data.
   g1h->g1mm()->update_sizes();
-  g1h->allocation_context_stats().update_after_mark();
 }
 
 void G1ConcurrentMark::complete_cleanup() {
--- a/src/hotspot/share/gc/g1/g1FullGCScope.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1FullGCScope.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -35,7 +35,7 @@
     _tracer(),
     _active(),
     _cpu_time(),
-    _soft_refs(clear_soft, _g1h->collector_policy()),
+    _soft_refs(clear_soft, _g1h->soft_ref_policy()),
     _memory_stats(memory_manager, _g1h->gc_cause()),
     _collector_stats(_g1h->g1mm()->full_collection_counters()),
     _heap_transition(_g1h) {
--- a/src/hotspot/share/gc/g1/g1PageBasedVirtualSpace.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1PageBasedVirtualSpace.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -235,13 +235,7 @@
   size_t const _page_size;
 public:
   G1PretouchTask(char* start_address, char* end_address, size_t page_size) :
-    AbstractGangTask("G1 PreTouch",
-                     Universe::is_fully_initialized() &&
-                     Thread::current()->is_Named_thread() ? GCId::current_raw() :
-                                                            // During VM initialization there is
-                                                            // no GC cycle that this task can be
-                                                            // associated with.
-                                                            GCId::undefined()),
+    AbstractGangTask("G1 PreTouch"),
     _cur_addr(start_address),
     _start_addr(start_address),
     _end_addr(end_address),
--- a/src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -220,8 +220,39 @@
   return *p == g1_young_card_val();
 }
 
-void G1SATBCardTableLoggingModRefBS::flush_deferred_barriers(JavaThread* thread) {
-  CardTableModRefBS::flush_deferred_barriers(thread);
+void G1SATBCardTableLoggingModRefBS::on_thread_attach(JavaThread* thread) {
+  // This method initializes the SATB and dirty card queues before a
+  // JavaThread is added to the Java thread list. Right now, we don't
+  // have to do anything to the dirty card queue (it should have been
+  // activated when the thread was created), but we have to activate
+  // the SATB queue if the thread is created while a marking cycle is
+  // in progress. The activation / de-activation of the SATB queues at
+  // the beginning / end of a marking cycle is done during safepoints
+  // so we have to make sure this method is called outside one to be
+  // able to safely read the active field of the SATB queue set. Right
+  // now, it is called just before the thread is added to the Java
+  // thread list in the Threads::add() method. That method is holding
+  // the Threads_lock which ensures we are outside a safepoint. We
+  // cannot do the obvious and set the active field of the SATB queue
+  // when the thread is created given that, in some cases, safepoints
+  // might happen between the JavaThread constructor being called and the
+  // thread being added to the Java thread list (an example of this is
+  // when the structure for the DestroyJavaVM thread is created).
+  assert(!SafepointSynchronize::is_at_safepoint(), "We should not be at a safepoint");
+  assert(!thread->satb_mark_queue().is_active(), "SATB queue should not be active");
+  assert(thread->satb_mark_queue().is_empty(), "SATB queue should be empty");
+  assert(thread->dirty_card_queue().is_active(), "Dirty card queue should be active");
+
+  // If we are creating the thread during a marking cycle, we should
+  // set the active field of the SATB queue to true.
+  if (thread->satb_mark_queue_set().is_active()) {
+    thread->satb_mark_queue().set_active(true);
+  }
+}
+
+void G1SATBCardTableLoggingModRefBS::on_thread_detach(JavaThread* thread) {
+  // Flush any deferred card marks, SATB buffers and dirty card queue buffers
+  CardTableModRefBS::on_thread_detach(thread);
   thread->satb_mark_queue().flush();
   thread->dirty_card_queue().flush();
 }
--- a/src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1SATBCardTableModRefBS.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -154,7 +154,8 @@
   void write_ref_field_post(T* field, oop new_val);
   void write_ref_field_post_slow(volatile jbyte* byte);
 
-  virtual void flush_deferred_barriers(JavaThread* thread);
+  virtual void on_thread_attach(JavaThread* thread);
+  virtual void on_thread_detach(JavaThread* thread);
 
   virtual bool card_mark_must_follow_store() const {
     return true;
--- a/src/hotspot/share/gc/g1/g1StringDedupTable.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1StringDedupTable.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -32,6 +32,7 @@
 #include "gc/shared/gcLocker.hpp"
 #include "logging/log.hpp"
 #include "memory/padded.inline.hpp"
+#include "oops/arrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "oops/typeArrayOop.hpp"
 #include "runtime/mutexLocker.hpp"
--- a/src/hotspot/share/gc/g1/satbMarkQueue.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/g1/satbMarkQueue.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -40,7 +40,8 @@
   // them with their active field set to false. If a thread is
   // created during a cycle and its SATB queue needs to be activated
   // before the thread starts running, we'll need to set its active
-  // field to true. This is done in JavaThread::initialize_queues().
+  // field to true. This is done in G1SATBCardTableLoggingModRefBS::
+  // on_thread_attach().
   PtrQueue(qset, permanent, false /* active */)
 { }
 
--- a/src/hotspot/share/gc/parallel/generationSizer.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/parallel/generationSizer.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -41,11 +41,5 @@
   void initialize_alignments();
   void initialize_flags();
   void initialize_size_info();
-
- public:
-  // We don't have associated counters and complain if this is invoked.
-  void initialize_gc_policy_counters() {
-    ShouldNotReachHere();
-  }
 };
 #endif // SHARE_VM_GC_PARALLEL_GENERATIONSIZER_HPP
--- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -331,7 +331,7 @@
         // excesses).  Fill op.result() with a filler object so that the
         // heap remains parsable.
         const bool limit_exceeded = size_policy()->gc_overhead_limit_exceeded();
-        const bool softrefs_clear = collector_policy()->all_soft_refs_clear();
+        const bool softrefs_clear = soft_ref_policy()->all_soft_refs_clear();
 
         if (limit_exceeded && softrefs_clear) {
           *gc_overhead_limit_was_exceeded = true;
--- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -34,6 +34,7 @@
 #include "gc/shared/collectorPolicy.hpp"
 #include "gc/shared/gcPolicyCounters.hpp"
 #include "gc/shared/gcWhen.hpp"
+#include "gc/shared/softRefPolicy.hpp"
 #include "gc/shared/strongRootsScope.hpp"
 #include "memory/metaspace.hpp"
 #include "utilities/growableArray.hpp"
@@ -59,6 +60,8 @@
 
   GenerationSizer* _collector_policy;
 
+  SoftRefPolicy _soft_ref_policy;
+
   // Collection of generations that are adjacent in the
   // space reserved for the heap.
   AdjoiningGenerations* _gens;
@@ -106,6 +109,8 @@
 
   virtual CollectorPolicy* collector_policy() const { return _collector_policy; }
 
+  virtual SoftRefPolicy* soft_ref_policy() { return &_soft_ref_policy; }
+
   virtual GrowableArray<GCMemoryManager*> memory_managers();
   virtual GrowableArray<MemoryPool*> memory_pools();
 
--- a/src/hotspot/share/gc/parallel/psCompactionManager.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/parallel/psCompactionManager.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -181,7 +181,7 @@
 
 template <class T>
 static void oop_pc_follow_contents_specialized(InstanceRefKlass* klass, oop obj, ParCompactionManager* cm) {
-  T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
+  T* referent_addr = (T*)java_lang_ref_Reference::referent_addr_raw(obj);
   T heap_oop = oopDesc::load_heap_oop(referent_addr);
   log_develop_trace(gc, ref)("InstanceRefKlass::oop_pc_follow_contents " PTR_FORMAT, p2i(obj));
   if (!oopDesc::is_null(heap_oop)) {
@@ -198,12 +198,12 @@
       cm->mark_and_push(referent_addr);
     }
   }
-  T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
+  T* next_addr = (T*)java_lang_ref_Reference::next_addr_raw(obj);
   // Treat discovered as normal oop, if ref is not "active",
   // i.e. if next is non-NULL.
   T  next_oop = oopDesc::load_heap_oop(next_addr);
   if (!oopDesc::is_null(next_oop)) { // i.e. ref is not "active"
-    T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
+    T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr_raw(obj);
     log_develop_trace(gc, ref)("   Process discovered as normal " PTR_FORMAT, p2i(discovered_addr));
     cm->mark_and_push(discovered_addr);
   }
--- a/src/hotspot/share/gc/parallel/psCompactionManager.inline.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/parallel/psCompactionManager.inline.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -29,7 +29,8 @@
 #include "gc/parallel/psCompactionManager.hpp"
 #include "gc/parallel/psParallelCompact.inline.hpp"
 #include "gc/shared/taskqueue.inline.hpp"
-#include "oops/objArrayOop.hpp"
+#include "oops/arrayOop.inline.hpp"
+#include "oops/objArrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "utilities/debug.hpp"
 #include "utilities/globalDefinitions.hpp"
@@ -117,7 +118,7 @@
 
   const size_t stride = MIN2(len - beg_index, ObjArrayMarkingStride);
   const size_t end_index = beg_index + stride;
-  T* const base = (T*)obj->base();
+  T* const base = (T*)obj->base_raw();
   T* const beg = base + beg_index;
   T* const end = base + end_index;
 
--- a/src/hotspot/share/gc/parallel/psMarkSweep.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/parallel/psMarkSweep.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -98,7 +98,7 @@
   }
 
   const bool clear_all_soft_refs =
-    heap->collector_policy()->should_clear_all_soft_refs();
+    heap->soft_ref_policy()->should_clear_all_soft_refs();
 
   uint count = maximum_heap_compaction ? 1 : MarkSweepAlwaysCompactCount;
   UIntFlagSetting flag_setting(MarkSweepAlwaysCompactCount, count);
@@ -126,7 +126,7 @@
 
   // The scope of casr should end after code that can change
   // CollectorPolicy::_should_clear_all_soft_refs.
-  ClearedAllSoftRefs casr(clear_all_softrefs, heap->collector_policy());
+  ClearedAllSoftRefs casr(clear_all_softrefs, heap->soft_ref_policy());
 
   PSYoungGen* young_gen = heap->young_gen();
   PSOldGen* old_gen = heap->old_gen();
@@ -320,7 +320,7 @@
                                              max_eden_size,
                                              true /* full gc*/,
                                              gc_cause,
-                                             heap->collector_policy());
+                                             heap->soft_ref_policy());
 
         size_policy->decay_supplemental_growth(true /* full gc*/);
 
--- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -1707,7 +1707,7 @@
   }
 
   const bool clear_all_soft_refs =
-    heap->collector_policy()->should_clear_all_soft_refs();
+    heap->soft_ref_policy()->should_clear_all_soft_refs();
 
   PSParallelCompact::invoke_no_policy(clear_all_soft_refs ||
                                       maximum_heap_compaction);
@@ -1741,7 +1741,7 @@
   // The scope of casr should end after code that can change
   // CollectorPolicy::_should_clear_all_soft_refs.
   ClearedAllSoftRefs casr(maximum_heap_compaction,
-                          heap->collector_policy());
+                          heap->soft_ref_policy());
 
   if (ZapUnusedHeapArea) {
     // Save information needed to minimize mangling
@@ -1869,7 +1869,7 @@
                                              max_eden_size,
                                              true /* full gc*/,
                                              gc_cause,
-                                             heap->collector_policy());
+                                             heap->soft_ref_policy());
 
         size_policy->decay_supplemental_growth(true /* full gc*/);
 
@@ -3087,11 +3087,11 @@
 
 template <class T>
 static void oop_pc_update_pointers_specialized(oop obj, ParCompactionManager* cm) {
-  T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
+  T* referent_addr = (T*)java_lang_ref_Reference::referent_addr_raw(obj);
   PSParallelCompact::adjust_pointer(referent_addr, cm);
-  T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
+  T* next_addr = (T*)java_lang_ref_Reference::next_addr_raw(obj);
   PSParallelCompact::adjust_pointer(next_addr, cm);
-  T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
+  T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr_raw(obj);
   PSParallelCompact::adjust_pointer(discovered_addr, cm);
   debug_only(trace_reference_gc("InstanceRefKlass::oop_update_ptrs", obj,
                                 referent_addr, next_addr, discovered_addr);)
--- a/src/hotspot/share/gc/parallel/psPromotionManager.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/parallel/psPromotionManager.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -38,9 +38,11 @@
 #include "memory/memRegion.hpp"
 #include "memory/padded.inline.hpp"
 #include "memory/resourceArea.hpp"
+#include "oops/arrayOop.inline.hpp"
 #include "oops/instanceKlass.inline.hpp"
 #include "oops/instanceMirrorKlass.inline.hpp"
 #include "oops/objArrayKlass.inline.hpp"
+#include "oops/objArrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
 
 PaddedEnd<PSPromotionManager>* PSPromotionManager::_manager_array = NULL;
@@ -434,7 +436,7 @@
 
 template <class T>
 static void oop_ps_push_contents_specialized(oop obj, InstanceRefKlass *klass, PSPromotionManager* pm) {
-  T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
+  T* referent_addr = (T*)java_lang_ref_Reference::referent_addr_raw(obj);
   if (PSScavenge::should_scavenge(referent_addr)) {
     ReferenceProcessor* rp = PSScavenge::reference_processor();
     if (rp->discover_reference(obj, klass->reference_type())) {
@@ -448,10 +450,10 @@
   }
   // Treat discovered as normal oop, if ref is not "active",
   // i.e. if next is non-NULL.
-  T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
+  T* next_addr = (T*)java_lang_ref_Reference::next_addr_raw(obj);
   T  next_oop = oopDesc::load_heap_oop(next_addr);
   if (!oopDesc::is_null(next_oop)) { // i.e. ref is not "active"
-    T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
+    T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr_raw(obj);
     log_develop_trace(gc, ref)("   Process discovered as normal " PTR_FORMAT, p2i(discovered_addr));
     if (PSScavenge::should_scavenge(discovered_addr)) {
       pm->claim_or_forward_depth(discovered_addr);
--- a/src/hotspot/share/gc/parallel/psScavenge.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/parallel/psScavenge.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -228,8 +228,8 @@
 
   if (need_full_gc) {
     GCCauseSetter gccs(heap, GCCause::_adaptive_size_policy);
-    CollectorPolicy* cp = heap->collector_policy();
-    const bool clear_all_softrefs = cp->should_clear_all_soft_refs();
+    SoftRefPolicy* srp = heap->soft_ref_policy();
+    const bool clear_all_softrefs = srp->should_clear_all_soft_refs();
 
     if (UseParallelOldGC) {
       full_gc_done = PSParallelCompact::invoke_no_policy(clear_all_softrefs);
@@ -569,7 +569,7 @@
                                                max_eden_size,
                                                false /* not full gc*/,
                                                gc_cause,
-                                               heap->collector_policy());
+                                               heap->soft_ref_policy());
 
           size_policy->decay_supplemental_growth(false /* not full gc*/);
         }
--- a/src/hotspot/share/gc/serial/defNewGeneration.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/serial/defNewGeneration.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -24,6 +24,7 @@
 
 #include "precompiled.hpp"
 #include "gc/serial/defNewGeneration.inline.hpp"
+#include "gc/shared/adaptiveSizePolicy.hpp"
 #include "gc/shared/ageTable.inline.hpp"
 #include "gc/shared/cardTableRS.hpp"
 #include "gc/shared/collectorCounters.hpp"
@@ -564,7 +565,7 @@
   _tenuring_threshold = age_table()->compute_tenuring_threshold(desired_survivor_size);
 
   if (UsePerfData) {
-    GCPolicyCounters* gc_counters = GenCollectedHeap::heap()->gen_policy()->counters();
+    GCPolicyCounters* gc_counters = GenCollectedHeap::heap()->counters();
     gc_counters->tenuring_threshold()->set_value(_tenuring_threshold);
     gc_counters->desired_survivor_size()->set_value(desired_survivor_size * oopSize);
   }
@@ -616,9 +617,6 @@
   assert(gch->no_allocs_since_save_marks(),
          "save marks have not been newly set.");
 
-  // Not very pretty.
-  CollectorPolicy* cp = gch->collector_policy();
-
   FastScanClosure fsc_with_no_gc_barrier(this, false);
   FastScanClosure fsc_with_gc_barrier(this, true);
 
@@ -688,7 +686,7 @@
 
     // A successful scavenge should restart the GC time limit count which is
     // for full GC's.
-    AdaptiveSizePolicy* size_policy = gch->gen_policy()->size_policy();
+    AdaptiveSizePolicy* size_policy = gch->size_policy();
     size_policy->reset_gc_overhead_limit_count();
     assert(!gch->incremental_collection_failed(), "Should be clear");
   } else {
@@ -953,7 +951,7 @@
 
   // update the generation and space performance counters
   update_counters();
-  gch->gen_policy()->counters()->update_counters();
+  gch->counters()->update_counters();
 }
 
 void DefNewGeneration::record_spaces_top() {
--- a/src/hotspot/share/gc/serial/genMarkSweep.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/serial/genMarkSweep.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -60,7 +60,7 @@
 
   GenCollectedHeap* gch = GenCollectedHeap::heap();
 #ifdef ASSERT
-  if (gch->collector_policy()->should_clear_all_soft_refs()) {
+  if (gch->soft_ref_policy()->should_clear_all_soft_refs()) {
     assert(clear_all_softrefs, "Policy should have been checked earlier");
   }
 #endif
--- a/src/hotspot/share/gc/serial/serialHeap.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/serial/serialHeap.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -29,7 +29,13 @@
 #include "services/memoryManager.hpp"
 
 SerialHeap::SerialHeap(GenCollectorPolicy* policy) :
-  GenCollectedHeap(policy), _eden_pool(NULL), _survivor_pool(NULL), _old_pool(NULL) {
+    GenCollectedHeap(policy,
+                     Generation::DefNew,
+                     Generation::MarkSweepCompact,
+                     "Copy:MSC"),
+    _eden_pool(NULL),
+    _survivor_pool(NULL),
+    _old_pool(NULL) {
   _young_manager = new GCMemoryManager("Copy", "end of minor GC");
   _old_manager = new GCMemoryManager("MarkSweepCompact", "end of major GC");
 }
--- a/src/hotspot/share/gc/shared/adaptiveSizePolicy.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/shared/adaptiveSizePolicy.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -27,10 +27,12 @@
 #include "gc/shared/collectorPolicy.hpp"
 #include "gc/shared/gcCause.hpp"
 #include "gc/shared/gcUtil.inline.hpp"
+#include "gc/shared/softRefPolicy.hpp"
 #include "gc/shared/workgroup.hpp"
 #include "logging/log.hpp"
 #include "runtime/timer.hpp"
 #include "utilities/ostream.hpp"
+
 elapsedTimer AdaptiveSizePolicy::_minor_timer;
 elapsedTimer AdaptiveSizePolicy::_major_timer;
 bool AdaptiveSizePolicy::_debug_perturbation = false;
@@ -409,7 +411,7 @@
                                           size_t max_eden_size,
                                           bool   is_full_gc,
                                           GCCause::Cause gc_cause,
-                                          CollectorPolicy* collector_policy) {
+                                          SoftRefPolicy* soft_ref_policy) {
 
   // Ignore explicit GC's.  Exiting here does not set the flag and
   // does not reset the count.  Updating of the averages for system
@@ -506,7 +508,7 @@
           // The clearing will be done on the next GC.
           bool near_limit = gc_overhead_limit_near();
           if (near_limit) {
-            collector_policy->set_should_clear_all_soft_refs(true);
+            soft_ref_policy->set_should_clear_all_soft_refs(true);
             log_trace(gc, ergo)("Nearing GC overhead limit, will be clearing all SoftReference");
           }
         }
--- a/src/hotspot/share/gc/shared/adaptiveSizePolicy.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/shared/adaptiveSizePolicy.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -37,7 +37,7 @@
 
 // Forward decls
 class elapsedTimer;
-class CollectorPolicy;
+class SoftRefPolicy;
 
 class AdaptiveSizePolicy : public CHeapObj<mtGC> {
  friend class GCAdaptivePolicyCounters;
@@ -486,7 +486,7 @@
                                size_t max_eden_size,
                                bool   is_full_gc,
                                GCCause::Cause gc_cause,
-                               CollectorPolicy* collector_policy);
+                               SoftRefPolicy* soft_ref_policy);
 
   static bool should_update_promo_stats(GCCause::Cause cause) {
     return ((GCCause::is_user_requested_gc(cause)  &&
--- a/src/hotspot/share/gc/shared/barrierSet.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/shared/barrierSet.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -115,7 +115,8 @@
   // is redone until it succeeds. This can e.g. prevent allocations from the slow path
   // to be in old.
   virtual void on_slowpath_allocation_exit(JavaThread* thread, oop new_obj) {}
-  virtual void flush_deferred_barriers(JavaThread* thread) {}
+  virtual void on_thread_attach(JavaThread* thread) {}
+  virtual void on_thread_detach(JavaThread* thread) {}
   virtual void make_parsable(JavaThread* thread) {}
 
 protected:
@@ -272,6 +273,10 @@
     static void clone_in_heap(oop src, oop dst, size_t size) {
       Raw::clone(src, dst, size);
     }
+
+    static oop resolve(oop obj) {
+      return Raw::resolve(obj);
+    }
   };
 };
 
--- a/src/hotspot/share/gc/shared/barrierSetConfig.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/shared/barrierSetConfig.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 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
@@ -52,9 +52,17 @@
 // To enable runtime-resolution of GC barriers on primitives, please
 // define SUPPORT_BARRIER_ON_PRIMITIVES.
 #ifdef SUPPORT_BARRIER_ON_PRIMITIVES
-#define BT_BUILDTIME_DECORATORS INTERNAL_BT_BARRIER_ON_PRIMITIVES
+#define ACCESS_PRIMITIVE_SUPPORT INTERNAL_BT_BARRIER_ON_PRIMITIVES
 #else
-#define BT_BUILDTIME_DECORATORS INTERNAL_EMPTY
+#define ACCESS_PRIMITIVE_SUPPORT INTERNAL_EMPTY
 #endif
 
+#ifdef SUPPORT_NOT_TO_SPACE_INVARIANT
+#define ACCESS_TO_SPACE_INVARIANT_SUPPORT INTERNAL_EMPTY
+#else
+#define ACCESS_TO_SPACE_INVARIANT_SUPPORT INTERNAL_BT_TO_SPACE_INVARIANT
+#endif
+
+#define BT_BUILDTIME_DECORATORS (ACCESS_PRIMITIVE_SUPPORT | ACCESS_TO_SPACE_INVARIANT_SUPPORT)
+
 #endif // SHARE_VM_GC_SHARED_BARRIERSETCONFIG_HPP
--- a/src/hotspot/share/gc/shared/cardTableModRefBS.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/shared/cardTableModRefBS.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -627,7 +627,7 @@
 #endif
 }
 
-void CardTableModRefBS::flush_deferred_barriers(JavaThread* thread) {
+void CardTableModRefBS::on_thread_detach(JavaThread* thread) {
   // The deferred store barriers must all have been flushed to the
   // card-table (or other remembered set structure) before GC starts
   // processing the card-table (or other remembered set).
--- a/src/hotspot/share/gc/shared/cardTableModRefBS.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/shared/cardTableModRefBS.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -357,7 +357,7 @@
   virtual bool is_in_young(oop obj) const = 0;
 
   virtual void on_slowpath_allocation_exit(JavaThread* thread, oop new_obj);
-  virtual void flush_deferred_barriers(JavaThread* thread);
+  virtual void on_thread_detach(JavaThread* thread);
 
   virtual void make_parsable(JavaThread* thread) { flush_deferred_card_mark_barrier(thread); }
 
--- a/src/hotspot/share/gc/shared/collectedHeap.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/shared/collectedHeap.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -28,6 +28,7 @@
 #include "gc/shared/barrierSet.inline.hpp"
 #include "gc/shared/collectedHeap.hpp"
 #include "gc/shared/collectedHeap.inline.hpp"
+#include "gc/shared/gcLocker.inline.hpp"
 #include "gc/shared/gcHeapSummary.hpp"
 #include "gc/shared/gcTrace.hpp"
 #include "gc/shared/gcTraceTime.inline.hpp"
@@ -41,9 +42,11 @@
 #include "runtime/init.hpp"
 #include "runtime/thread.inline.hpp"
 #include "runtime/threadSMR.hpp"
+#include "runtime/vmThread.hpp"
 #include "services/heapDumper.hpp"
 #include "utilities/align.hpp"
 
+class ClassLoaderData;
 
 #ifdef ASSERT
 int CollectedHeap::_fire_out_of_memory_count = 0;
@@ -233,6 +236,80 @@
   }
 }
 
+MetaWord* CollectedHeap::satisfy_failed_metadata_allocation(ClassLoaderData* loader_data,
+                                                            size_t word_size,
+                                                            Metaspace::MetadataType mdtype) {
+  uint loop_count = 0;
+  uint gc_count = 0;
+  uint full_gc_count = 0;
+
+  assert(!Heap_lock->owned_by_self(), "Should not be holding the Heap_lock");
+
+  do {
+    MetaWord* result = loader_data->metaspace_non_null()->allocate(word_size, mdtype);
+    if (result != NULL) {
+      return result;
+    }
+
+    if (GCLocker::is_active_and_needs_gc()) {
+      // If the GCLocker is active, just expand and allocate.
+      // If that does not succeed, wait if this thread is not
+      // in a critical section itself.
+      result = loader_data->metaspace_non_null()->expand_and_allocate(word_size, mdtype);
+      if (result != NULL) {
+        return result;
+      }
+      JavaThread* jthr = JavaThread::current();
+      if (!jthr->in_critical()) {
+        // Wait for JNI critical section to be exited
+        GCLocker::stall_until_clear();
+        // The GC invoked by the last thread leaving the critical
+        // section will be a young collection and a full collection
+        // is (currently) needed for unloading classes so continue
+        // to the next iteration to get a full GC.
+        continue;
+      } else {
+        if (CheckJNICalls) {
+          fatal("Possible deadlock due to allocating while"
+                " in jni critical section");
+        }
+        return NULL;
+      }
+    }
+
+    {  // Need lock to get self consistent gc_count's
+      MutexLocker ml(Heap_lock);
+      gc_count      = Universe::heap()->total_collections();
+      full_gc_count = Universe::heap()->total_full_collections();
+    }
+
+    // Generate a VM operation
+    VM_CollectForMetadataAllocation op(loader_data,
+                                       word_size,
+                                       mdtype,
+                                       gc_count,
+                                       full_gc_count,
+                                       GCCause::_metadata_GC_threshold);
+    VMThread::execute(&op);
+
+    // If GC was locked out, try again. Check before checking success because the
+    // prologue could have succeeded and the GC still have been locked out.
+    if (op.gc_locked()) {
+      continue;
+    }
+
+    if (op.prologue_succeeded()) {
+      return op.result();
+    }
+    loop_count++;
+    if ((QueuedAllocationWarningCount > 0) &&
+        (loop_count % QueuedAllocationWarningCount == 0)) {
+      log_warning(gc, ergo)("satisfy_failed_metadata_allocation() retries %d times,"
+                            " size=" SIZE_FORMAT, loop_count, word_size);
+    }
+  } while (true);  // Until a GC is done
+}
+
 void CollectedHeap::set_barrier_set(BarrierSet* barrier_set) {
   _barrier_set = barrier_set;
   BarrierSet::set_bs(barrier_set);
--- a/src/hotspot/share/gc/shared/collectedHeap.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/shared/collectedHeap.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -50,6 +50,7 @@
 class GCMemoryManager;
 class MemoryPool;
 class MetaspaceSummary;
+class SoftRefPolicy;
 class Thread;
 class ThreadClosure;
 class VirtualSpaceSummary;
@@ -411,6 +412,10 @@
   // the context of the vm thread.
   virtual void collect_as_vm_thread(GCCause::Cause cause);
 
+  virtual MetaWord* satisfy_failed_metadata_allocation(ClassLoaderData* loader_data,
+                                                       size_t size,
+                                                       Metaspace::MetadataType mdtype);
+
   // Returns the barrier set for this heap
   BarrierSet* barrier_set() { return _barrier_set; }
   void set_barrier_set(BarrierSet* barrier_set);
@@ -438,6 +443,9 @@
   // Return the CollectorPolicy for the heap
   virtual CollectorPolicy* collector_policy() const = 0;
 
+  // Return the SoftRefPolicy for the heap;
+  virtual SoftRefPolicy* soft_ref_policy() = 0;
+
   virtual GrowableArray<GCMemoryManager*> memory_managers() = 0;
   virtual GrowableArray<MemoryPool*> memory_pools() = 0;
 
@@ -492,7 +500,7 @@
   void pre_full_gc_dump(GCTimer* timer);
   void post_full_gc_dump(GCTimer* timer);
 
-  VirtualSpaceSummary create_heap_space_summary();
+  virtual VirtualSpaceSummary create_heap_space_summary();
   GCHeapSummary create_heap_summary();
 
   MetaspaceSummary create_metaspace_summary();
@@ -599,20 +607,6 @@
     return (CIFireOOMAt > 1 && _fire_out_of_memory_count >= CIFireOOMAt);
   }
 #endif
-
- public:
-  // Copy the current allocation context statistics for the specified contexts.
-  // For each context in contexts, set the corresponding entries in the totals
-  // and accuracy arrays to the current values held by the statistics.  Each
-  // array should be of length len.
-  // Returns true if there are more stats available.
-  virtual bool copy_allocation_context_stats(const jint* contexts,
-                                             jlong* totals,
-                                             jbyte* accuracy,
-                                             jint len) {
-    return false;
-  }
-
 };
 
 // Class to set and reset the GC cause for a CollectedHeap.
@@ -622,16 +616,12 @@
   GCCause::Cause _previous_cause;
  public:
   GCCauseSetter(CollectedHeap* heap, GCCause::Cause cause) {
-    assert(SafepointSynchronize::is_at_safepoint(),
-           "This method manipulates heap state without locking");
     _heap = heap;
     _previous_cause = _heap->gc_cause();
     _heap->set_gc_cause(cause);
   }
 
   ~GCCauseSetter() {
-    assert(SafepointSynchronize::is_at_safepoint(),
-          "This method manipulates heap state without locking");
     _heap->set_gc_cause(_previous_cause);
   }
 };
--- a/src/hotspot/share/gc/shared/collectorPolicy.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/shared/collectorPolicy.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -50,9 +50,7 @@
     _heap_alignment(0),
     _initial_heap_byte_size(InitialHeapSize),
     _max_heap_byte_size(MaxHeapSize),
-    _min_heap_byte_size(Arguments::min_heap_size()),
-    _should_clear_all_soft_refs(false),
-    _all_soft_refs_clear(false)
+    _min_heap_byte_size(Arguments::min_heap_size())
 {}
 
 #ifdef ASSERT
@@ -145,20 +143,6 @@
   DEBUG_ONLY(CollectorPolicy::assert_size_info();)
 }
 
-bool CollectorPolicy::use_should_clear_all_soft_refs(bool v) {
-  bool result = _should_clear_all_soft_refs;
-  set_should_clear_all_soft_refs(false);
-  return result;
-}
-
-CardTableRS* CollectorPolicy::create_rem_set(MemRegion whole_heap) {
-  return new CardTableRS(whole_heap);
-}
-
-void CollectorPolicy::cleared_all_soft_refs() {
-  _all_soft_refs_clear = true;
-}
-
 size_t CollectorPolicy::compute_heap_alignment() {
   // The card marking array and the offset arrays for old generations are
   // committed in os pages as well. Make sure they are entirely full (to
@@ -186,10 +170,7 @@
     _min_old_size(0),
     _initial_old_size(0),
     _max_old_size(0),
-    _gen_alignment(0),
-    _young_gen_spec(NULL),
-    _old_gen_spec(NULL),
-    _size_policy(NULL)
+    _gen_alignment(0)
 {}
 
 size_t GenCollectorPolicy::scale_by_NewRatio_aligned(size_t base_size) {
@@ -202,29 +183,6 @@
   return desired_size < max_minus ? desired_size : max_minus;
 }
 
-
-void GenCollectorPolicy::initialize_size_policy(size_t init_eden_size,
-                                                size_t init_promo_size,
-                                                size_t init_survivor_size) {
-  const double max_gc_pause_sec = ((double) MaxGCPauseMillis) / 1000.0;
-  _size_policy = new AdaptiveSizePolicy(init_eden_size,
-                                        init_promo_size,
-                                        init_survivor_size,
-                                        max_gc_pause_sec,
-                                        GCTimeRatio);
-}
-
-void GenCollectorPolicy::cleared_all_soft_refs() {
-  // If near gc overhear limit, continue to clear SoftRefs.  SoftRefs may
-  // have been cleared in the last collection but if the gc overhear
-  // limit continues to be near, SoftRefs should still be cleared.
-  if (size_policy() != NULL) {
-    _should_clear_all_soft_refs = size_policy()->gc_overhead_limit_near();
-  }
-
-  CollectorPolicy::cleared_all_soft_refs();
-}
-
 size_t GenCollectorPolicy::young_gen_size_lower_bound() {
   // The young generation must be aligned and have room for eden + two survivors
   return align_up(3 * _space_alignment, _gen_alignment);
@@ -580,322 +538,6 @@
   DEBUG_ONLY(GenCollectorPolicy::assert_size_info();)
 }
 
-HeapWord* GenCollectorPolicy::mem_allocate_work(size_t size,
-                                        bool is_tlab,
-                                        bool* gc_overhead_limit_was_exceeded) {
-  GenCollectedHeap *gch = GenCollectedHeap::heap();
-
-  debug_only(gch->check_for_valid_allocation_state());
-  assert(gch->no_gc_in_progress(), "Allocation during gc not allowed");
-
-  // In general gc_overhead_limit_was_exceeded should be false so
-  // set it so here and reset it to true only if the gc time
-  // limit is being exceeded as checked below.
-  *gc_overhead_limit_was_exceeded = false;
-
-  HeapWord* result = NULL;
-
-  // Loop until the allocation is satisfied, or unsatisfied after GC.
-  for (uint try_count = 1, gclocker_stalled_count = 0; /* return or throw */; try_count += 1) {
-    HandleMark hm; // Discard any handles allocated in each iteration.
-
-    // First allocation attempt is lock-free.
-    Generation *young = gch->young_gen();
-    assert(young->supports_inline_contig_alloc(),
-      "Otherwise, must do alloc within heap lock");
-    if (young->should_allocate(size, is_tlab)) {
-      result = young->par_allocate(size, is_tlab);
-      if (result != NULL) {
-        assert(gch->is_in_reserved(result), "result not in heap");
-        return result;
-      }
-    }
-    uint gc_count_before;  // Read inside the Heap_lock locked region.
-    {
-      MutexLocker ml(Heap_lock);
-      log_trace(gc, alloc)("GenCollectorPolicy::mem_allocate_work: attempting locked slow path allocation");
-      // Note that only large objects get a shot at being
-      // allocated in later generations.
-      bool first_only = ! should_try_older_generation_allocation(size);
-
-      result = gch->attempt_allocation(size, is_tlab, first_only);
-      if (result != NULL) {
-        assert(gch->is_in_reserved(result), "result not in heap");
-        return result;
-      }
-
-      if (GCLocker::is_active_and_needs_gc()) {
-        if (is_tlab) {
-          return NULL;  // Caller will retry allocating individual object.
-        }
-        if (!gch->is_maximal_no_gc()) {
-          // Try and expand heap to satisfy request.
-          result = expand_heap_and_allocate(size, is_tlab);
-          // Result could be null if we are out of space.
-          if (result != NULL) {
-            return result;
-          }
-        }
-
-        if (gclocker_stalled_count > GCLockerRetryAllocationCount) {
-          return NULL; // We didn't get to do a GC and we didn't get any memory.
-        }
-
-        // If this thread is not in a jni critical section, we stall
-        // the requestor until the critical section has cleared and
-        // GC allowed. When the critical section clears, a GC is
-        // initiated by the last thread exiting the critical section; so
-        // we retry the allocation sequence from the beginning of the loop,
-        // rather than causing more, now probably unnecessary, GC attempts.
-        JavaThread* jthr = JavaThread::current();
-        if (!jthr->in_critical()) {
-          MutexUnlocker mul(Heap_lock);
-          // Wait for JNI critical section to be exited
-          GCLocker::stall_until_clear();
-          gclocker_stalled_count += 1;
-          continue;
-        } else {
-          if (CheckJNICalls) {
-            fatal("Possible deadlock due to allocating while"
-                  " in jni critical section");
-          }
-          return NULL;
-        }
-      }
-
-      // Read the gc count while the heap lock is held.
-      gc_count_before = gch->total_collections();
-    }
-
-    VM_GenCollectForAllocation op(size, is_tlab, gc_count_before);
-    VMThread::execute(&op);
-    if (op.prologue_succeeded()) {
-      result = op.result();
-      if (op.gc_locked()) {
-         assert(result == NULL, "must be NULL if gc_locked() is true");
-         continue;  // Retry and/or stall as necessary.
-      }
-
-      // Allocation has failed and a collection
-      // has been done.  If the gc time limit was exceeded the
-      // this time, return NULL so that an out-of-memory
-      // will be thrown.  Clear gc_overhead_limit_exceeded
-      // so that the overhead exceeded does not persist.
-
-      const bool limit_exceeded = size_policy()->gc_overhead_limit_exceeded();
-      const bool softrefs_clear = all_soft_refs_clear();
-
-      if (limit_exceeded && softrefs_clear) {
-        *gc_overhead_limit_was_exceeded = true;
-        size_policy()->set_gc_overhead_limit_exceeded(false);
-        if (op.result() != NULL) {
-          CollectedHeap::fill_with_object(op.result(), size);
-        }
-        return NULL;
-      }
-      assert(result == NULL || gch->is_in_reserved(result),
-             "result not in heap");
-      return result;
-    }
-
-    // Give a warning if we seem to be looping forever.
-    if ((QueuedAllocationWarningCount > 0) &&
-        (try_count % QueuedAllocationWarningCount == 0)) {
-          log_warning(gc, ergo)("GenCollectorPolicy::mem_allocate_work retries %d times,"
-                                " size=" SIZE_FORMAT " %s", try_count, size, is_tlab ? "(TLAB)" : "");
-    }
-  }
-}
-
-HeapWord* GenCollectorPolicy::expand_heap_and_allocate(size_t size,
-                                                       bool   is_tlab) {
-  GenCollectedHeap *gch = GenCollectedHeap::heap();
-  HeapWord* result = NULL;
-  Generation *old = gch->old_gen();
-  if (old->should_allocate(size, is_tlab)) {
-    result = old->expand_and_allocate(size, is_tlab);
-  }
-  if (result == NULL) {
-    Generation *young = gch->young_gen();
-    if (young->should_allocate(size, is_tlab)) {
-      result = young->expand_and_allocate(size, is_tlab);
-    }
-  }
-  assert(result == NULL || gch->is_in_reserved(result), "result not in heap");
-  return result;
-}
-
-HeapWord* GenCollectorPolicy::satisfy_failed_allocation(size_t size,
-                                                        bool   is_tlab) {
-  GenCollectedHeap *gch = GenCollectedHeap::heap();
-  GCCauseSetter x(gch, GCCause::_allocation_failure);
-  HeapWord* result = NULL;
-
-  assert(size != 0, "Precondition violated");
-  if (GCLocker::is_active_and_needs_gc()) {
-    // GC locker is active; instead of a collection we will attempt
-    // to expand the heap, if there's room for expansion.
-    if (!gch->is_maximal_no_gc()) {
-      result = expand_heap_and_allocate(size, is_tlab);
-    }
-    return result;   // Could be null if we are out of space.
-  } else if (!gch->incremental_collection_will_fail(false /* don't consult_young */)) {
-    // Do an incremental collection.
-    gch->do_collection(false,                     // full
-                       false,                     // clear_all_soft_refs
-                       size,                      // size
-                       is_tlab,                   // is_tlab
-                       GenCollectedHeap::OldGen); // max_generation
-  } else {
-    log_trace(gc)(" :: Trying full because partial may fail :: ");
-    // Try a full collection; see delta for bug id 6266275
-    // for the original code and why this has been simplified
-    // with from-space allocation criteria modified and
-    // such allocation moved out of the safepoint path.
-    gch->do_collection(true,                      // full
-                       false,                     // clear_all_soft_refs
-                       size,                      // size
-                       is_tlab,                   // is_tlab
-                       GenCollectedHeap::OldGen); // max_generation
-  }
-
-  result = gch->attempt_allocation(size, is_tlab, false /*first_only*/);
-
-  if (result != NULL) {
-    assert(gch->is_in_reserved(result), "result not in heap");
-    return result;
-  }
-
-  // OK, collection failed, try expansion.
-  result = expand_heap_and_allocate(size, is_tlab);
-  if (result != NULL) {
-    return result;
-  }
-
-  // If we reach this point, we're really out of memory. Try every trick
-  // we can to reclaim memory. Force collection of soft references. Force
-  // a complete compaction of the heap. Any additional methods for finding
-  // free memory should be here, especially if they are expensive. If this
-  // attempt fails, an OOM exception will be thrown.
-  {
-    UIntFlagSetting flag_change(MarkSweepAlwaysCompactCount, 1); // Make sure the heap is fully compacted
-
-    gch->do_collection(true,                      // full
-                       true,                      // clear_all_soft_refs
-                       size,                      // size
-                       is_tlab,                   // is_tlab
-                       GenCollectedHeap::OldGen); // max_generation
-  }
-
-  result = gch->attempt_allocation(size, is_tlab, false /* first_only */);
-  if (result != NULL) {
-    assert(gch->is_in_reserved(result), "result not in heap");
-    return result;
-  }
-
-  assert(!should_clear_all_soft_refs(),
-    "Flag should have been handled and cleared prior to this point");
-
-  // What else?  We might try synchronous finalization later.  If the total
-  // space available is large enough for the allocation, then a more
-  // complete compaction phase than we've tried so far might be
-  // appropriate.
-  return NULL;
-}
-
-MetaWord* CollectorPolicy::satisfy_failed_metadata_allocation(
-                                                 ClassLoaderData* loader_data,
-                                                 size_t word_size,
-                                                 Metaspace::MetadataType mdtype) {
-  uint loop_count = 0;
-  uint gc_count = 0;
-  uint full_gc_count = 0;
-
-  assert(!Heap_lock->owned_by_self(), "Should not be holding the Heap_lock");
-
-  do {
-    MetaWord* result = loader_data->metaspace_non_null()->allocate(word_size, mdtype);
-    if (result != NULL) {
-      return result;
-    }
-
-    if (GCLocker::is_active_and_needs_gc()) {
-      // If the GCLocker is active, just expand and allocate.
-      // If that does not succeed, wait if this thread is not
-      // in a critical section itself.
-      result =
-        loader_data->metaspace_non_null()->expand_and_allocate(word_size,
-                                                               mdtype);
-      if (result != NULL) {
-        return result;
-      }
-      JavaThread* jthr = JavaThread::current();
-      if (!jthr->in_critical()) {
-        // Wait for JNI critical section to be exited
-        GCLocker::stall_until_clear();
-        // The GC invoked by the last thread leaving the critical
-        // section will be a young collection and a full collection
-        // is (currently) needed for unloading classes so continue
-        // to the next iteration to get a full GC.
-        continue;
-      } else {
-        if (CheckJNICalls) {
-          fatal("Possible deadlock due to allocating while"
-                " in jni critical section");
-        }
-        return NULL;
-      }
-    }
-
-    {  // Need lock to get self consistent gc_count's
-      MutexLocker ml(Heap_lock);
-      gc_count      = Universe::heap()->total_collections();
-      full_gc_count = Universe::heap()->total_full_collections();
-    }
-
-    // Generate a VM operation
-    VM_CollectForMetadataAllocation op(loader_data,
-                                       word_size,
-                                       mdtype,
-                                       gc_count,
-                                       full_gc_count,
-                                       GCCause::_metadata_GC_threshold);
-    VMThread::execute(&op);
-
-    // If GC was locked out, try again. Check before checking success because the
-    // prologue could have succeeded and the GC still have been locked out.
-    if (op.gc_locked()) {
-      continue;
-    }
-
-    if (op.prologue_succeeded()) {
-      return op.result();
-    }
-    loop_count++;
-    if ((QueuedAllocationWarningCount > 0) &&
-        (loop_count % QueuedAllocationWarningCount == 0)) {
-      log_warning(gc, ergo)("satisfy_failed_metadata_allocation() retries %d times,"
-                            " size=" SIZE_FORMAT, loop_count, word_size);
-    }
-  } while (true);  // Until a GC is done
-}
-
-// Return true if any of the following is true:
-// . the allocation won't fit into the current young gen heap
-// . gc locker is occupied (jni critical section)
-// . heap memory is tight -- the most recent previous collection
-//   was a full collection because a partial collection (would
-//   have) failed and is likely to fail again
-bool GenCollectorPolicy::should_try_older_generation_allocation(
-        size_t word_size) const {
-  GenCollectedHeap* gch = GenCollectedHeap::heap();
-  size_t young_capacity = gch->young_gen()->capacity_before_gc();
-  return    (word_size > heap_word_size(young_capacity))
-         || GCLocker::is_active_and_needs_gc()
-         || gch->incremental_collection_failed();
-}
-
-
 //
 // MarkSweepPolicy methods
 //
@@ -904,14 +546,3 @@
   _space_alignment = _gen_alignment = (size_t)Generation::GenGrain;
   _heap_alignment = compute_heap_alignment();
 }
-
-void MarkSweepPolicy::initialize_generations() {
-  _young_gen_spec = new GenerationSpec(Generation::DefNew, _initial_young_size, _max_young_size, _gen_alignment);
-  _old_gen_spec   = new GenerationSpec(Generation::MarkSweepCompact, _initial_old_size, _max_old_size, _gen_alignment);
-}
-
-void MarkSweepPolicy::initialize_gc_policy_counters() {
-  // Initialize the policy counters - 2 collectors, 2 generations.
-  _gc_policy_counters = new GCPolicyCounters("Copy:MSC", 2, 2);
-}
-
--- a/src/hotspot/share/gc/shared/collectorPolicy.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/shared/collectorPolicy.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -53,7 +53,6 @@
 class G1CollectorPolicy;
 #endif // INCLUDE_ALL_GCS
 
-class GCPolicyCounters;
 class MarkSweepPolicy;
 
 class CollectorPolicy : public CHeapObj<mtGC> {
@@ -72,21 +71,10 @@
   size_t _space_alignment;
   size_t _heap_alignment;
 
-  // Set to true when policy wants soft refs cleared.
-  // Reset to false by gc after it clears all soft refs.
-  bool _should_clear_all_soft_refs;
-
-  // Set to true by the GC if the just-completed gc cleared all
-  // softrefs.  This is set to true whenever a gc clears all softrefs, and
-  // set to false each time gc returns to the mutator.  For example, in the
-  // ParallelScavengeHeap case the latter would be done toward the end of
-  // mem_allocate() where it returns op.result()
-  bool _all_soft_refs_clear;
-
   CollectorPolicy();
 
  public:
-  virtual void initialize_all() {
+  void initialize_all() {
     initialize_alignments();
     initialize_flags();
     initialize_size_info();
@@ -101,58 +89,6 @@
   size_t initial_heap_byte_size() { return _initial_heap_byte_size; }
   size_t max_heap_byte_size()     { return _max_heap_byte_size; }
   size_t min_heap_byte_size()     { return _min_heap_byte_size; }
-
-  bool should_clear_all_soft_refs() { return _should_clear_all_soft_refs; }
-  void set_should_clear_all_soft_refs(bool v) { _should_clear_all_soft_refs = v; }
-  // Returns the current value of _should_clear_all_soft_refs.
-  // _should_clear_all_soft_refs is set to false as a side effect.
-  bool use_should_clear_all_soft_refs(bool v);
-  bool all_soft_refs_clear() { return _all_soft_refs_clear; }
-  void set_all_soft_refs_clear(bool v) { _all_soft_refs_clear = v; }
-
-  // Called by the GC after Soft Refs have been cleared to indicate
-  // that the request in _should_clear_all_soft_refs has been fulfilled.
-  virtual void cleared_all_soft_refs();
-
-  // Identification methods.
-  virtual GenCollectorPolicy*           as_generation_policy()            { return NULL; }
-  virtual MarkSweepPolicy*              as_mark_sweep_policy()            { return NULL; }
-#if INCLUDE_ALL_GCS
-  virtual ConcurrentMarkSweepPolicy*    as_concurrent_mark_sweep_policy() { return NULL; }
-#endif // INCLUDE_ALL_GCS
-  // Note that these are not virtual.
-  bool is_generation_policy()            { return as_generation_policy() != NULL; }
-  bool is_mark_sweep_policy()            { return as_mark_sweep_policy() != NULL; }
-#if INCLUDE_ALL_GCS
-  bool is_concurrent_mark_sweep_policy() { return as_concurrent_mark_sweep_policy() != NULL; }
-#else  // INCLUDE_ALL_GCS
-  bool is_concurrent_mark_sweep_policy() { return false; }
-#endif // INCLUDE_ALL_GCS
-
-
-  virtual CardTableRS* create_rem_set(MemRegion reserved);
-
-  MetaWord* satisfy_failed_metadata_allocation(ClassLoaderData* loader_data,
-                                               size_t size,
-                                               Metaspace::MetadataType mdtype);
-};
-
-class ClearedAllSoftRefs : public StackObj {
-  bool _clear_all_soft_refs;
-  CollectorPolicy* _collector_policy;
- public:
-  ClearedAllSoftRefs(bool clear_all_soft_refs,
-                     CollectorPolicy* collector_policy) :
-    _clear_all_soft_refs(clear_all_soft_refs),
-    _collector_policy(collector_policy) {}
-
-  ~ClearedAllSoftRefs() {
-    if (_clear_all_soft_refs) {
-      _collector_policy->cleared_all_soft_refs();
-    }
-  }
-
-  bool should_clear() { return _clear_all_soft_refs; }
 };
 
 class GenCollectorPolicy : public CollectorPolicy {
@@ -171,27 +107,12 @@
   // time. When using large pages they can differ.
   size_t _gen_alignment;
 
-  GenerationSpec* _young_gen_spec;
-  GenerationSpec* _old_gen_spec;
-
-  GCPolicyCounters* _gc_policy_counters;
-
-  // The sizing of the heap is controlled by a sizing policy.
-  AdaptiveSizePolicy* _size_policy;
-
-  // Return true if an allocation should be attempted in the older generation
-  // if it fails in the younger generation.  Return false, otherwise.
-  virtual bool should_try_older_generation_allocation(size_t word_size) const;
-
   void initialize_flags();
   void initialize_size_info();
 
   DEBUG_ONLY(void assert_flags();)
   DEBUG_ONLY(void assert_size_info();)
 
-  // Try to allocate space by expanding the heap.
-  virtual HeapWord* expand_heap_and_allocate(size_t size, bool is_tlab);
-
   // Compute max heap alignment.
   size_t compute_max_alignment();
 
@@ -215,63 +136,17 @@
   size_t initial_old_size()   { return _initial_old_size; }
   size_t max_old_size()       { return _max_old_size; }
 
-  GenerationSpec* young_gen_spec() const {
-    assert(_young_gen_spec != NULL, "_young_gen_spec should have been initialized");
-    return _young_gen_spec;
-  }
-
-  GenerationSpec* old_gen_spec() const {
-    assert(_old_gen_spec != NULL, "_old_gen_spec should have been initialized");
-    return _old_gen_spec;
-  }
-
-  // Performance Counter support
-  GCPolicyCounters* counters()     { return _gc_policy_counters; }
-
-  // Create the jstat counters for the GC policy.
-  virtual void initialize_gc_policy_counters() = 0;
-
-  virtual GenCollectorPolicy* as_generation_policy() { return this; }
-
-  virtual void initialize_generations() { };
-
-  virtual void initialize_all() {
-    CollectorPolicy::initialize_all();
-    initialize_generations();
-  }
-
   size_t young_gen_size_lower_bound();
 
   size_t old_gen_size_lower_bound();
-
-  HeapWord* mem_allocate_work(size_t size,
-                              bool is_tlab,
-                              bool* gc_overhead_limit_was_exceeded);
-
-  HeapWord *satisfy_failed_allocation(size_t size, bool is_tlab);
-
-  // Adaptive size policy
-  AdaptiveSizePolicy* size_policy() { return _size_policy; }
-
-  virtual void initialize_size_policy(size_t init_eden_size,
-                                      size_t init_promo_size,
-                                      size_t init_survivor_size);
-
-  virtual void cleared_all_soft_refs();
-
 };
 
 class MarkSweepPolicy : public GenCollectorPolicy {
  protected:
   void initialize_alignments();
-  void initialize_generations();
 
  public:
   MarkSweepPolicy() {}
-
-  MarkSweepPolicy* as_mark_sweep_policy() { return this; }
-
-  void initialize_gc_policy_counters();
 };
 
 #endif // SHARE_VM_GC_SHARED_COLLECTORPOLICY_HPP
--- a/src/hotspot/share/gc/shared/gcCause.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/shared/gcCause.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -60,10 +60,6 @@
     case _wb_full_gc:
       return "WhiteBox Initiated Full GC";
 
-    case _update_allocation_context_stats_inc:
-    case _update_allocation_context_stats_full:
-      return "Update Allocation Context Stats";
-
     case _no_gc:
       return "No GC";
 
--- a/src/hotspot/share/gc/shared/gcCause.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/shared/gcCause.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -52,8 +52,6 @@
     _wb_young_gc,
     _wb_conc_mark,
     _wb_full_gc,
-    _update_allocation_context_stats_inc,
-    _update_allocation_context_stats_full,
 
     /* implementation independent, but reserved for GC use */
     _no_gc,
--- a/src/hotspot/share/gc/shared/gcId.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/shared/gcId.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -35,27 +35,28 @@
   return (NamedThread*)Thread::current();
 }
 
-const uint GCId::create() {
+uint GCId::create() {
   return _next_id++;
 }
 
-const uint GCId::peek() {
+uint GCId::peek() {
   return _next_id;
 }
 
-const uint GCId::current() {
-  assert(currentNamedthread()->gc_id() != undefined(), "Using undefined GC id.");
-  return current_raw();
+uint GCId::current() {
+  const uint gc_id = currentNamedthread()->gc_id();
+  assert(gc_id != undefined(), "Using undefined GC id.");
+  return gc_id;
 }
 
-const uint GCId::current_raw() {
-  return currentNamedthread()->gc_id();
+uint GCId::current_or_undefined() {
+  return Thread::current()->is_Named_thread() ? currentNamedthread()->gc_id() : undefined();
 }
 
 size_t GCId::print_prefix(char* buf, size_t len) {
   Thread* thread = Thread::current_or_null();
-  if (thread != NULL && thread->is_Named_thread()) {
-    uint gc_id = current_raw();
+  if (thread != NULL) {
+    uint gc_id = current_or_undefined();
     if (gc_id != undefined()) {
       int ret = jio_snprintf(buf, len, "GC(%u) ", gc_id);
       assert(ret > 0, "Failed to print prefix. Log buffer too small?");
@@ -65,28 +66,14 @@
   return 0;
 }
 
-GCIdMark::GCIdMark() : _gc_id(GCId::create()) {
-  currentNamedthread()->set_gc_id(_gc_id);
+GCIdMark::GCIdMark() : _previous_gc_id(currentNamedthread()->gc_id()) {
+  currentNamedthread()->set_gc_id(GCId::create());
 }
 
-GCIdMark::GCIdMark(uint gc_id) : _gc_id(gc_id) {
-  currentNamedthread()->set_gc_id(_gc_id);
+GCIdMark::GCIdMark(uint gc_id) : _previous_gc_id(currentNamedthread()->gc_id()) {
+  currentNamedthread()->set_gc_id(gc_id);
 }
 
 GCIdMark::~GCIdMark() {
-  currentNamedthread()->set_gc_id(GCId::undefined());
-}
-
-GCIdMarkAndRestore::GCIdMarkAndRestore() : _gc_id(GCId::create()) {
-  _previous_gc_id = GCId::current_raw();
-  currentNamedthread()->set_gc_id(_gc_id);
-}
-
-GCIdMarkAndRestore::GCIdMarkAndRestore(uint gc_id) : _gc_id(gc_id) {
-  _previous_gc_id = GCId::current_raw();
-  currentNamedthread()->set_gc_id(_gc_id);
-}
-
-GCIdMarkAndRestore::~GCIdMarkAndRestore() {
   currentNamedthread()->set_gc_id(_previous_gc_id);
 }
--- a/src/hotspot/share/gc/shared/gcId.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/shared/gcId.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -28,38 +28,32 @@
 #include "memory/allocation.hpp"
 
 class GCId : public AllStatic {
+private:
   friend class GCIdMark;
-  friend class GCIdMarkAndRestore;
+
   static uint _next_id;
   static const uint UNDEFINED = (uint)-1;
-  static const uint create();
+  static uint create();
 
- public:
+public:
   // Returns the currently active GC id. Asserts that there is an active GC id.
-  static const uint current();
+  static uint current();
   // Same as current() but can return undefined() if no GC id is currently active
-  static const uint current_raw();
+  static uint current_or_undefined();
   // Returns the next expected GCId.
-  static const uint peek();
-  static const uint undefined() { return UNDEFINED; }
+  static uint peek();
+  static uint undefined() { return UNDEFINED; }
   static size_t print_prefix(char* buf, size_t len);
 };
 
 class GCIdMark : public StackObj {
-  uint _gc_id;
- public:
+private:
+  const uint _previous_gc_id;
+
+public:
   GCIdMark();
   GCIdMark(uint gc_id);
   ~GCIdMark();
 };
 
-class GCIdMarkAndRestore : public StackObj {
-  uint _gc_id;
-  uint _previous_gc_id;
- public:
-  GCIdMarkAndRestore();
-  GCIdMarkAndRestore(uint gc_id);
-  ~GCIdMarkAndRestore();
-};
-
 #endif // SHARE_VM_GC_SHARED_GCID_HPP
--- a/src/hotspot/share/gc/shared/gcTimer.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/shared/gcTimer.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -68,14 +68,14 @@
   GCTimer::register_gc_end(time);
 }
 
-void ConcurrentGCTimer::register_gc_pause_start(const char* name) {
+void ConcurrentGCTimer::register_gc_pause_start(const char* name, const Ticks& time) {
   assert(!_is_concurrent_phase_active, "A pause phase can't be started while a concurrent phase is active.");
-  GCTimer::register_gc_pause_start(name);
+  GCTimer::register_gc_pause_start(name, time);
 }
 
-void ConcurrentGCTimer::register_gc_pause_end() {
+void ConcurrentGCTimer::register_gc_pause_end(const Ticks& time) {
   assert(!_is_concurrent_phase_active, "A pause phase can't be ended while a concurrent phase is active.");
-  GCTimer::register_gc_pause_end();
+  GCTimer::register_gc_pause_end(time);
 }
 
 void ConcurrentGCTimer::register_gc_concurrent_start(const char* name, const Ticks& time) {
--- a/src/hotspot/share/gc/shared/gcTimer.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/shared/gcTimer.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -166,8 +166,8 @@
  public:
   ConcurrentGCTimer(): GCTimer(), _is_concurrent_phase_active(false) {};
 
-  void register_gc_pause_start(const char* name);
-  void register_gc_pause_end();
+  void register_gc_pause_start(const char* name, const Ticks& time = Ticks::now());
+  void register_gc_pause_end(const Ticks& time = Ticks::now());
 
   void register_gc_concurrent_start(const char* name, const Ticks& time = Ticks::now());
   void register_gc_concurrent_end(const Ticks& time = Ticks::now());
--- a/src/hotspot/share/gc/shared/genCollectedHeap.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/shared/genCollectedHeap.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -30,10 +30,13 @@
 #include "classfile/vmSymbols.hpp"
 #include "code/codeCache.hpp"
 #include "code/icBuffer.hpp"
+#include "gc/shared/adaptiveSizePolicy.hpp"
+#include "gc/shared/cardTableRS.hpp"
 #include "gc/shared/collectedHeap.inline.hpp"
 #include "gc/shared/collectorCounters.hpp"
 #include "gc/shared/gcId.hpp"
 #include "gc/shared/gcLocker.inline.hpp"
+#include "gc/shared/gcPolicyCounters.hpp"
 #include "gc/shared/gcTrace.hpp"
 #include "gc/shared/gcTraceTime.inline.hpp"
 #include "gc/shared/genCollectedHeap.hpp"
@@ -60,14 +63,25 @@
 #include "utilities/stack.inline.hpp"
 #include "utilities/vmError.hpp"
 
-GenCollectedHeap::GenCollectedHeap(GenCollectorPolicy *policy) :
+GenCollectedHeap::GenCollectedHeap(GenCollectorPolicy *policy,
+                                   Generation::Name young,
+                                   Generation::Name old,
+                                   const char* policy_counters_name) :
   CollectedHeap(),
   _rem_set(NULL),
+  _young_gen_spec(new GenerationSpec(young,
+                                     policy->initial_young_size(),
+                                     policy->max_young_size(),
+                                     policy->gen_alignment())),
+  _old_gen_spec(new GenerationSpec(old,
+                                   policy->initial_old_size(),
+                                   policy->max_old_size(),
+                                   policy->gen_alignment())),
   _gen_policy(policy),
+  _soft_ref_gen_policy(),
+  _gc_policy_counters(new GCPolicyCounters(policy_counters_name, 2, 2)),
   _process_strong_tasks(new SubTasksDone(GCH_PS_NumElements)),
-  _full_collections_completed(0)
-{
-  assert(policy != NULL, "Sanity check");
+  _full_collections_completed(0) {
 }
 
 jint GenCollectedHeap::initialize() {
@@ -95,32 +109,40 @@
 
   initialize_reserved_region((HeapWord*)heap_rs.base(), (HeapWord*)(heap_rs.base() + heap_rs.size()));
 
-  _rem_set = collector_policy()->create_rem_set(reserved_region());
+  _rem_set = new CardTableRS(reserved_region());
   set_barrier_set(rem_set()->bs());
 
-  ReservedSpace young_rs = heap_rs.first_part(gen_policy()->young_gen_spec()->max_size(), false, false);
-  _young_gen = gen_policy()->young_gen_spec()->init(young_rs, rem_set());
-  heap_rs = heap_rs.last_part(gen_policy()->young_gen_spec()->max_size());
+  ReservedSpace young_rs = heap_rs.first_part(_young_gen_spec->max_size(), false, false);
+  _young_gen = _young_gen_spec->init(young_rs, rem_set());
+  heap_rs = heap_rs.last_part(_young_gen_spec->max_size());
 
-  ReservedSpace old_rs = heap_rs.first_part(gen_policy()->old_gen_spec()->max_size(), false, false);
-  _old_gen = gen_policy()->old_gen_spec()->init(old_rs, rem_set());
+  ReservedSpace old_rs = heap_rs.first_part(_old_gen_spec->max_size(), false, false);
+  _old_gen = _old_gen_spec->init(old_rs, rem_set());
   clear_incremental_collection_failed();
 
   return JNI_OK;
 }
 
+void GenCollectedHeap::initialize_size_policy(size_t init_eden_size,
+                                              size_t init_promo_size,
+                                              size_t init_survivor_size) {
+  const double max_gc_pause_sec = ((double) MaxGCPauseMillis) / 1000.0;
+  _size_policy = new AdaptiveSizePolicy(init_eden_size,
+                                        init_promo_size,
+                                        init_survivor_size,
+                                        max_gc_pause_sec,
+                                        GCTimeRatio);
+}
+
 char* GenCollectedHeap::allocate(size_t alignment,
                                  ReservedSpace* heap_rs){
   // Now figure out the total size.
   const size_t pageSize = UseLargePages ? os::large_page_size() : os::vm_page_size();
   assert(alignment % pageSize == 0, "Must be");
 
-  GenerationSpec* young_spec = gen_policy()->young_gen_spec();
-  GenerationSpec* old_spec = gen_policy()->old_gen_spec();
-
   // Check for overflow.
-  size_t total_reserved = young_spec->max_size() + old_spec->max_size();
-  if (total_reserved < young_spec->max_size()) {
+  size_t total_reserved = _young_gen_spec->max_size() + _old_gen_spec->max_size();
+  if (total_reserved < _young_gen_spec->max_size()) {
     vm_exit_during_initialization("The size of the object heap + VM data exceeds "
                                   "the maximum representable size");
   }
@@ -146,10 +168,9 @@
   check_gen_kinds();
   DefNewGeneration* def_new_gen = (DefNewGeneration*)_young_gen;
 
-  _gen_policy->initialize_size_policy(def_new_gen->eden()->capacity(),
-                                      _old_gen->capacity(),
-                                      def_new_gen->from()->capacity());
-  _gen_policy->initialize_gc_policy_counters();
+  initialize_size_policy(def_new_gen->eden()->capacity(),
+                         _old_gen->capacity(),
+                         def_new_gen->from()->capacity());
 }
 
 void GenCollectedHeap::ref_processing_init() {
@@ -157,6 +178,14 @@
   _old_gen->ref_processor_init();
 }
 
+GenerationSpec* GenCollectedHeap::young_gen_spec() const {
+  return _young_gen_spec;
+}
+
+GenerationSpec* GenCollectedHeap::old_gen_spec() const {
+  return _old_gen_spec;
+}
+
 size_t GenCollectedHeap::capacity() const {
   return _young_gen->capacity() + _old_gen->capacity();
 }
@@ -202,6 +231,157 @@
   return _full_collections_completed;
 }
 
+// Return true if any of the following is true:
+// . the allocation won't fit into the current young gen heap
+// . gc locker is occupied (jni critical section)
+// . heap memory is tight -- the most recent previous collection
+//   was a full collection because a partial collection (would
+//   have) failed and is likely to fail again
+bool GenCollectedHeap::should_try_older_generation_allocation(size_t word_size) const {
+  size_t young_capacity = young_gen()->capacity_before_gc();
+  return    (word_size > heap_word_size(young_capacity))
+         || GCLocker::is_active_and_needs_gc()
+         || incremental_collection_failed();
+}
+
+HeapWord* GenCollectedHeap::expand_heap_and_allocate(size_t size, bool   is_tlab) {
+  HeapWord* result = NULL;
+  if (old_gen()->should_allocate(size, is_tlab)) {
+    result = old_gen()->expand_and_allocate(size, is_tlab);
+  }
+  if (result == NULL) {
+    if (young_gen()->should_allocate(size, is_tlab)) {
+      result = young_gen()->expand_and_allocate(size, is_tlab);
+    }
+  }
+  assert(result == NULL || is_in_reserved(result), "result not in heap");
+  return result;
+}
+
+HeapWord* GenCollectedHeap::mem_allocate_work(size_t size,
+                                              bool is_tlab,
+                                              bool* gc_overhead_limit_was_exceeded) {
+  debug_only(check_for_valid_allocation_state());
+  assert(no_gc_in_progress(), "Allocation during gc not allowed");
+
+  // In general gc_overhead_limit_was_exceeded should be false so
+  // set it so here and reset it to true only if the gc time
+  // limit is being exceeded as checked below.
+  *gc_overhead_limit_was_exceeded = false;
+
+  HeapWord* result = NULL;
+
+  // Loop until the allocation is satisfied, or unsatisfied after GC.
+  for (uint try_count = 1, gclocker_stalled_count = 0; /* return or throw */; try_count += 1) {
+    HandleMark hm; // Discard any handles allocated in each iteration.
+
+    // First allocation attempt is lock-free.
+    Generation *young = young_gen();
+    assert(young->supports_inline_contig_alloc(),
+      "Otherwise, must do alloc within heap lock");
+    if (young->should_allocate(size, is_tlab)) {
+      result = young->par_allocate(size, is_tlab);
+      if (result != NULL) {
+        assert(is_in_reserved(result), "result not in heap");
+        return result;
+      }
+    }
+    uint gc_count_before;  // Read inside the Heap_lock locked region.
+    {
+      MutexLocker ml(Heap_lock);
+      log_trace(gc, alloc)("GenCollectedHeap::mem_allocate_work: attempting locked slow path allocation");
+      // Note that only large objects get a shot at being
+      // allocated in later generations.
+      bool first_only = !should_try_older_generation_allocation(size);
+
+      result = attempt_allocation(size, is_tlab, first_only);
+      if (result != NULL) {
+        assert(is_in_reserved(result), "result not in heap");
+        return result;
+      }
+
+      if (GCLocker::is_active_and_needs_gc()) {
+        if (is_tlab) {
+          return NULL;  // Caller will retry allocating individual object.
+        }
+        if (!is_maximal_no_gc()) {
+          // Try and expand heap to satisfy request.
+          result = expand_heap_and_allocate(size, is_tlab);
+          // Result could be null if we are out of space.
+          if (result != NULL) {
+            return result;
+          }
+        }
+
+        if (gclocker_stalled_count > GCLockerRetryAllocationCount) {
+          return NULL; // We didn't get to do a GC and we didn't get any memory.
+        }
+
+        // If this thread is not in a jni critical section, we stall
+        // the requestor until the critical section has cleared and
+        // GC allowed. When the critical section clears, a GC is
+        // initiated by the last thread exiting the critical section; so
+        // we retry the allocation sequence from the beginning of the loop,
+        // rather than causing more, now probably unnecessary, GC attempts.
+        JavaThread* jthr = JavaThread::current();
+        if (!jthr->in_critical()) {
+          MutexUnlocker mul(Heap_lock);
+          // Wait for JNI critical section to be exited
+          GCLocker::stall_until_clear();
+          gclocker_stalled_count += 1;
+          continue;
+        } else {
+          if (CheckJNICalls) {
+            fatal("Possible deadlock due to allocating while"
+                  " in jni critical section");
+          }
+          return NULL;
+        }
+      }
+
+      // Read the gc count while the heap lock is held.
+      gc_count_before = total_collections();
+    }
+
+    VM_GenCollectForAllocation op(size, is_tlab, gc_count_before);
+    VMThread::execute(&op);
+    if (op.prologue_succeeded()) {
+      result = op.result();
+      if (op.gc_locked()) {
+         assert(result == NULL, "must be NULL if gc_locked() is true");
+         continue;  // Retry and/or stall as necessary.
+      }
+
+      // Allocation has failed and a collection
+      // has been done.  If the gc time limit was exceeded the
+      // this time, return NULL so that an out-of-memory
+      // will be thrown.  Clear gc_overhead_limit_exceeded
+      // so that the overhead exceeded does not persist.
+
+      const bool limit_exceeded = size_policy()->gc_overhead_limit_exceeded();
+      const bool softrefs_clear = soft_ref_policy()->all_soft_refs_clear();
+
+      if (limit_exceeded && softrefs_clear) {
+        *gc_overhead_limit_was_exceeded = true;
+        size_policy()->set_gc_overhead_limit_exceeded(false);
+        if (op.result() != NULL) {
+          CollectedHeap::fill_with_object(op.result(), size);
+        }
+        return NULL;
+      }
+      assert(result == NULL || is_in_reserved(result),
+             "result not in heap");
+      return result;
+    }
+
+    // Give a warning if we seem to be looping forever.
+    if ((QueuedAllocationWarningCount > 0) &&
+        (try_count % QueuedAllocationWarningCount == 0)) {
+          log_warning(gc, ergo)("GenCollectedHeap::mem_allocate_work retries %d times,"
+                                " size=" SIZE_FORMAT " %s", try_count, size, is_tlab ? "(TLAB)" : "");
+    }
+  }
+}
 
 #ifndef PRODUCT
 // Override of memory state checking method in CollectedHeap:
@@ -253,9 +433,9 @@
 
 HeapWord* GenCollectedHeap::mem_allocate(size_t size,
                                          bool* gc_overhead_limit_was_exceeded) {
-  return gen_policy()->mem_allocate_work(size,
-                                         false /* is_tlab */,
-                                         gc_overhead_limit_was_exceeded);
+  return mem_allocate_work(size,
+                           false /* is_tlab */,
+                           gc_overhead_limit_was_exceeded);
 }
 
 bool GenCollectedHeap::must_clear_all_soft_refs() {
@@ -367,12 +547,12 @@
     return; // GC is disabled (e.g. JNI GetXXXCritical operation)
   }
 
-  GCIdMarkAndRestore gc_id_mark;
+  GCIdMark gc_id_mark;
 
   const bool do_clear_all_soft_refs = clear_all_soft_refs ||
-                          collector_policy()->should_clear_all_soft_refs();
+                          soft_ref_policy()->should_clear_all_soft_refs();
 
-  ClearedAllSoftRefs casr(do_clear_all_soft_refs, collector_policy());
+  ClearedAllSoftRefs casr(do_clear_all_soft_refs, soft_ref_policy());
 
   const size_t metadata_prev_used = MetaspaceAux::used_bytes();
 
@@ -442,7 +622,7 @@
 
       if (do_young_collection) {
         // We did a young GC. Need a new GC id for the old GC.
-        GCIdMarkAndRestore gc_id_mark;
+        GCIdMark gc_id_mark;
         GCTraceTime(Info, gc) t("Pause Full", NULL, gc_cause(), true);
         collect_generation(_old_gen, full, size, is_tlab, run_verification && VerifyGCLevel <= 1, do_clear_all_soft_refs, true);
       } else {
@@ -503,7 +683,79 @@
 }
 
 HeapWord* GenCollectedHeap::satisfy_failed_allocation(size_t size, bool is_tlab) {
-  return gen_policy()->satisfy_failed_allocation(size, is_tlab);
+  GCCauseSetter x(this, GCCause::_allocation_failure);
+  HeapWord* result = NULL;
+
+  assert(size != 0, "Precondition violated");
+  if (GCLocker::is_active_and_needs_gc()) {
+    // GC locker is active; instead of a collection we will attempt
+    // to expand the heap, if there's room for expansion.
+    if (!is_maximal_no_gc()) {
+      result = expand_heap_and_allocate(size, is_tlab);
+    }
+    return result;   // Could be null if we are out of space.
+  } else if (!incremental_collection_will_fail(false /* don't consult_young */)) {
+    // Do an incremental collection.
+    do_collection(false,                     // full
+                  false,                     // clear_all_soft_refs
+                  size,                      // size
+                  is_tlab,                   // is_tlab
+                  GenCollectedHeap::OldGen); // max_generation
+  } else {
+    log_trace(gc)(" :: Trying full because partial may fail :: ");
+    // Try a full collection; see delta for bug id 6266275
+    // for the original code and why this has been simplified
+    // with from-space allocation criteria modified and
+    // such allocation moved out of the safepoint path.
+    do_collection(true,                      // full
+                  false,                     // clear_all_soft_refs
+                  size,                      // size
+                  is_tlab,                   // is_tlab
+                  GenCollectedHeap::OldGen); // max_generation
+  }
+
+  result = attempt_allocation(size, is_tlab, false /*first_only*/);
+
+  if (result != NULL) {
+    assert(is_in_reserved(result), "result not in heap");
+    return result;
+  }
+
+  // OK, collection failed, try expansion.
+  result = expand_heap_and_allocate(size, is_tlab);
+  if (result != NULL) {
+    return result;
+  }
+
+  // If we reach this point, we're really out of memory. Try every trick
+  // we can to reclaim memory. Force collection of soft references. Force
+  // a complete compaction of the heap. Any additional methods for finding
+  // free memory should be here, especially if they are expensive. If this
+  // attempt fails, an OOM exception will be thrown.
+  {
+    UIntFlagSetting flag_change(MarkSweepAlwaysCompactCount, 1); // Make sure the heap is fully compacted
+
+    do_collection(true,                      // full
+                  true,                      // clear_all_soft_refs
+                  size,                      // size
+                  is_tlab,                   // is_tlab
+                  GenCollectedHeap::OldGen); // max_generation
+  }
+
+  result = attempt_allocation(size, is_tlab, false /* first_only */);
+  if (result != NULL) {
+    assert(is_in_reserved(result), "result not in heap");
+    return result;
+  }
+
+  assert(!soft_ref_policy()->should_clear_all_soft_refs(),
+    "Flag should have been handled and cleared prior to this point");
+
+  // What else?  We might try synchronous finalization later.  If the total
+  // space available is large enough for the allocation, then a more
+  // complete compaction phase than we've tried so far might be
+  // appropriate.
+  return NULL;
 }
 
 #ifdef ASSERT
@@ -886,9 +1138,9 @@
 
 HeapWord* GenCollectedHeap::allocate_new_tlab(size_t size) {
   bool gc_overhead_limit_was_exceeded;
-  return gen_policy()->mem_allocate_work(size /* size */,
-                                         true /* is_tlab */,
-                                         &gc_overhead_limit_was_exceeded);
+  return mem_allocate_work(size /* size */,
+                           true /* is_tlab */,
+                           &gc_overhead_limit_was_exceeded);
 }
 
 // Requires "*prev_ptr" to be non-NULL.  Deletes and a block of minimal size
--- a/src/hotspot/share/gc/shared/genCollectedHeap.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/shared/genCollectedHeap.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -25,11 +25,14 @@
 #ifndef SHARE_VM_GC_SHARED_GENCOLLECTEDHEAP_HPP
 #define SHARE_VM_GC_SHARED_GENCOLLECTEDHEAP_HPP
 
-#include "gc/shared/adaptiveSizePolicy.hpp"
 #include "gc/shared/collectedHeap.hpp"
 #include "gc/shared/collectorPolicy.hpp"
 #include "gc/shared/generation.hpp"
+#include "gc/shared/softRefGenPolicy.hpp"
 
+class AdaptiveSizePolicy;
+class GCPolicyCounters;
+class GenerationSpec;
 class StrongRootsScope;
 class SubTasksDone;
 class WorkGang;
@@ -64,12 +67,22 @@
   Generation* _young_gen;
   Generation* _old_gen;
 
+  GenerationSpec* _young_gen_spec;
+  GenerationSpec* _old_gen_spec;
+
   // The singleton CardTable Remembered Set.
   CardTableRS* _rem_set;
 
   // The generational collector policy.
   GenCollectorPolicy* _gen_policy;
 
+  SoftRefGenPolicy _soft_ref_gen_policy;
+
+  // The sizing of the heap is controlled by a sizing policy.
+  AdaptiveSizePolicy* _size_policy;
+
+  GCPolicyCounters* _gc_policy_counters;
+
   // Indicates that the most recent previous incremental collection failed.
   // The flag is cleared when an action is taken that might clear the
   // condition that caused that incremental collection to fail.
@@ -143,7 +156,10 @@
   // we absolutely __must__ clear soft refs?
   bool must_clear_all_soft_refs();
 
-  GenCollectedHeap(GenCollectorPolicy *policy);
+  GenCollectedHeap(GenCollectorPolicy *policy,
+                   Generation::Name young,
+                   Generation::Name old,
+                   const char* policy_counters_name);
 
   virtual void check_gen_kinds() = 0;
 
@@ -152,6 +168,10 @@
   // Returns JNI_OK on success
   virtual jint initialize();
 
+  void initialize_size_policy(size_t init_eden_size,
+                              size_t init_promo_size,
+                              size_t init_survivor_size);
+
   // Does operations required after initialization has been done.
   void post_initialize();
 
@@ -161,16 +181,24 @@
   bool is_young_gen(const Generation* gen) const { return gen == _young_gen; }
   bool is_old_gen(const Generation* gen) const { return gen == _old_gen; }
 
+  GenerationSpec* young_gen_spec() const;
+  GenerationSpec* old_gen_spec() const;
+
   // The generational collector policy.
   GenCollectorPolicy* gen_policy() const { return _gen_policy; }
 
   virtual CollectorPolicy* collector_policy() const { return gen_policy(); }
 
+  virtual SoftRefPolicy* soft_ref_policy() { return &_soft_ref_gen_policy; }
+
   // Adaptive size policy
   virtual AdaptiveSizePolicy* size_policy() {
-    return gen_policy()->size_policy();
+    return _size_policy;
   }
 
+  // Performance Counter support
+  GCPolicyCounters* counters()     { return _gc_policy_counters; }
+
   // Return the (conservative) maximum heap alignment
   static size_t conservative_max_heap_alignment() {
     return Generation::GenGrain;
@@ -456,6 +484,17 @@
 
 
 private:
+  // Return true if an allocation should be attempted in the older generation
+  // if it fails in the younger generation.  Return false, otherwise.
+  bool should_try_older_generation_allocation(size_t word_size) const;
+
+  // Try to allocate space by expanding the heap.
+  HeapWord* expand_heap_and_allocate(size_t size, bool is_tlab);
+
+  HeapWord* mem_allocate_work(size_t size,
+                              bool is_tlab,
+                              bool* gc_overhead_limit_was_exceeded);
+
   // Override
   void check_for_non_bad_heap_word_value(HeapWord* addr,
     size_t size) PRODUCT_RETURN;
--- a/src/hotspot/share/gc/shared/generation.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/shared/generation.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -63,9 +63,9 @@
 size_t Generation::initial_size() {
   GenCollectedHeap* gch = GenCollectedHeap::heap();
   if (gch->is_young_gen(this)) {
-    return gch->gen_policy()->young_gen_spec()->init_size();
+    return gch->young_gen_spec()->init_size();
   }
-  return gch->gen_policy()->old_gen_spec()->init_size();
+  return gch->old_gen_spec()->init_size();
 }
 
 size_t Generation::max_capacity() const {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shared/oopStorageParState.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -0,0 +1,198 @@
+/*
+ * 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
+ * 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_GC_SHARED_OOPSTORAGEPARSTATE_HPP
+#define SHARE_GC_SHARED_OOPSTORAGEPARSTATE_HPP
+
+#include "gc/shared/oopStorage.hpp"
+#include "memory/allocation.hpp"
+#include "utilities/macros.hpp"
+
+#if INCLUDE_ALL_GCS
+
+//////////////////////////////////////////////////////////////////////////////
+// Support for parallel and optionally concurrent state iteration.
+//
+// Parallel iteration is for the exclusive use of the GC.  Other iteration
+// clients must use serial iteration.
+//
+// Concurrent Iteration
+//
+// Iteration involves the _active_list, which contains all of the blocks owned
+// by a storage object.  This is a doubly-linked list, linked through
+// dedicated fields in the blocks.
+//
+// At most one concurrent ParState can exist at a time for a given storage
+// object.
+//
+// A concurrent ParState sets the associated storage's
+// _concurrent_iteration_active flag true when the state is constructed, and
+// sets it false when the state is destroyed.  These assignments are made with
+// _active_mutex locked.  Meanwhile, empty block deletion is not done while
+// _concurrent_iteration_active is true.  The flag check and the dependent
+// removal of a block from the _active_list is performed with _active_mutex
+// locked.  This prevents concurrent iteration and empty block deletion from
+// interfering with with each other.
+//
+// Both allocate() and delete_empty_blocks_concurrent() lock the
+// _allocate_mutex while performing their respective list manipulations,
+// preventing them from interfering with each other.
+//
+// When allocate() creates a new block, it is added to the front of the
+// _active_list.  Then _active_head is set to the new block.  When concurrent
+// iteration is started (by a parallel worker thread calling the state's
+// iterate() function), the current _active_head is used as the initial block
+// for the iteration, with iteration proceeding down the list headed by that
+// block.
+//
+// As a result, the list over which concurrent iteration operates is stable.
+// However, once the iteration is started, later allocations may add blocks to
+// the front of the list that won't be examined by the iteration.  And while
+// the list is stable, concurrent allocate() and release() operations may
+// change the set of allocated entries in a block at any time during the
+// iteration.
+//
+// As a result, a concurrent iteration handler must accept that some
+// allocations and releases that occur after the iteration started will not be
+// seen by the iteration.  Further, some may overlap examination by the
+// iteration.  To help with this, allocate() and release() have an invariant
+// that an entry's value must be NULL when it is not in use.
+//
+// An in-progress delete_empty_blocks_concurrent() operation can contend with
+// the start of a concurrent iteration over the _active_mutex.  Since both are
+// under GC control, that potential contention can be eliminated by never
+// scheduling both operations to run at the same time.
+//
+// ParState<concurrent, is_const>
+//   concurrent must be true if iteration is concurrent with the
+//   mutator, false if iteration is at a safepoint.
+//
+//   is_const must be true if the iteration is over a constant storage
+//   object, false if the iteration may modify the storage object.
+//
+// ParState([const] OopStorage* storage)
+//   Construct an object for managing an iteration over storage.  For a
+//   concurrent ParState, empty block deletion for the associated storage
+//   is inhibited for the life of the ParState.  There can be no more
+//   than one live concurrent ParState at a time for a given storage object.
+//
+// template<typename F> void iterate(F f)
+//   Repeatedly claims a block from the associated storage that has
+//   not been processed by this iteration (possibly by other threads),
+//   and applies f to each entry in the claimed block. Assume p is of
+//   type const oop* or oop*, according to is_const. Then f(p) must be
+//   a valid expression whose value is ignored.  Concurrent uses must
+//   be prepared for an entry's value to change at any time, due to
+//   mutator activity.
+//
+// template<typename Closure> void oops_do(Closure* cl)
+//   Wrapper around iterate, providing an adaptation layer allowing
+//   the use of OopClosures and similar objects for iteration.  Assume
+//   p is of type const oop* or oop*, according to is_const.  Then
+//   cl->do_oop(p) must be a valid expression whose value is ignored.
+//   Concurrent uses must be prepared for the entry's value to change
+//   at any time, due to mutator activity.
+//
+// Optional operations, provided only if !concurrent && !is_const.
+// These are not provided when is_const, because the storage object
+// may be modified by the iteration infrastructure, even if the
+// provided closure doesn't modify the storage object.  These are not
+// provided when concurrent because any pre-filtering behavior by the
+// iteration infrastructure is inappropriate for concurrent iteration;
+// modifications of the storage by the mutator could result in the
+// pre-filtering being applied (successfully or not) to objects that
+// are unrelated to what the closure finds in the entry.
+//
+// template<typename Closure> void weak_oops_do(Closure* cl)
+// template<typename IsAliveClosure, typename Closure>
+// void weak_oops_do(IsAliveClosure* is_alive, Closure* cl)
+//   Wrappers around iterate, providing an adaptation layer allowing
+//   the use of is-alive closures and OopClosures for iteration.
+//   Assume p is of type oop*.  Then
+//
+//   - cl->do_oop(p) must be a valid expression whose value is ignored.
+//
+//   - is_alive->do_object_b(*p) must be a valid expression whose value
+//   is convertible to bool.
+//
+//   If *p == NULL then neither is_alive nor cl will be invoked for p.
+//   If is_alive->do_object_b(*p) is false, then cl will not be
+//   invoked on p.
+
+class OopStorage::BasicParState VALUE_OBJ_CLASS_SPEC {
+  OopStorage* _storage;
+  void* volatile _next_block;
+  bool _concurrent;
+
+  // Noncopyable.
+  BasicParState(const BasicParState&);
+  BasicParState& operator=(const BasicParState&);
+
+  void update_iteration_state(bool value);
+  void ensure_iteration_started();
+  Block* claim_next_block();
+
+  // Wrapper for iteration handler; ignore handler result and return true.
+  template<typename F> class AlwaysTrueFn;
+
+public:
+  BasicParState(OopStorage* storage, bool concurrent);
+  ~BasicParState();
+
+  template<bool is_const, typename F> void iterate(F f);
+};
+
+template<bool concurrent, bool is_const>
+class OopStorage::ParState VALUE_OBJ_CLASS_SPEC {
+  BasicParState _basic_state;
+
+public:
+  ParState(const OopStorage* storage) :
+    // For simplicity, always recorded as non-const.
+    _basic_state(const_cast<OopStorage*>(storage), concurrent)
+  {}
+
+  template<typename F> void iterate(F f);
+  template<typename Closure> void oops_do(Closure* cl);
+};
+
+template<>
+class OopStorage::ParState<false, false> VALUE_OBJ_CLASS_SPEC {
+  BasicParState _basic_state;
+
+public:
+  ParState(OopStorage* storage) :
+    _basic_state(storage, false)
+  {}
+
+  template<typename F> void iterate(F f);
+  template<typename Closure> void oops_do(Closure* cl);
+  template<typename Closure> void weak_oops_do(Closure* cl);
+  template<typename IsAliveClosure, typename Closure>
+  void weak_oops_do(IsAliveClosure* is_alive, Closure* cl);
+};
+
+#endif // INCLUDE_ALL_GCS
+
+#endif // SHARE_GC_SHARED_OOPSTORAGEPARSTATE_HPP
--- a/src/hotspot/share/gc/shared/oopStorageParState.inline.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/shared/oopStorageParState.inline.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -26,152 +26,13 @@
 #define SHARE_GC_SHARED_OOPSTORAGEPARSTATE_INLINE_HPP
 
 #include "gc/shared/oopStorage.inline.hpp"
+#include "gc/shared/oopStorageParState.hpp"
 #include "memory/allocation.hpp"
 #include "metaprogramming/conditional.hpp"
 #include "utilities/macros.hpp"
 
 #if INCLUDE_ALL_GCS
 
-//////////////////////////////////////////////////////////////////////////////
-// Support for parallel and optionally concurrent state iteration.
-//
-// Parallel iteration is for the exclusive use of the GC.  Other iteration
-// clients must use serial iteration.
-//
-// Concurrent Iteration
-//
-// Iteration involves the _active_list, which contains all of the blocks owned
-// by a storage object.  This is a doubly-linked list, linked through
-// dedicated fields in the blocks.
-//
-// At most one concurrent ParState can exist at a time for a given storage
-// object.
-//
-// A concurrent ParState sets the associated storage's
-// _concurrent_iteration_active flag true when the state is constructed, and
-// sets it false when the state is destroyed.  These assignments are made with
-// _active_mutex locked.  Meanwhile, empty block deletion is not done while
-// _concurrent_iteration_active is true.  The flag check and the dependent
-// removal of a block from the _active_list is performed with _active_mutex
-// locked.  This prevents concurrent iteration and empty block deletion from
-// interfering with with each other.
-//
-// Both allocate() and delete_empty_blocks_concurrent() lock the
-// _allocate_mutex while performing their respective list manipulations,
-// preventing them from interfering with each other.
-//
-// When allocate() creates a new block, it is added to the front of the
-// _active_list.  Then _active_head is set to the new block.  When concurrent
-// iteration is started (by a parallel worker thread calling the state's
-// iterate() function), the current _active_head is used as the initial block
-// for the iteration, with iteration proceeding down the list headed by that
-// block.
-//
-// As a result, the list over which concurrent iteration operates is stable.
-// However, once the iteration is started, later allocations may add blocks to
-// the front of the list that won't be examined by the iteration.  And while
-// the list is stable, concurrent allocate() and release() operations may
-// change the set of allocated entries in a block at any time during the
-// iteration.
-//
-// As a result, a concurrent iteration handler must accept that some
-// allocations and releases that occur after the iteration started will not be
-// seen by the iteration.  Further, some may overlap examination by the
-// iteration.  To help with this, allocate() and release() have an invariant
-// that an entry's value must be NULL when it is not in use.
-//
-// An in-progress delete_empty_blocks_concurrent() operation can contend with
-// the start of a concurrent iteration over the _active_mutex.  Since both are
-// under GC control, that potential contention can be eliminated by never
-// scheduling both operations to run at the same time.
-//
-// ParState<concurrent, is_const>
-//   concurrent must be true if iteration is concurrent with the
-//   mutator, false if iteration is at a safepoint.
-//
-//   is_const must be true if the iteration is over a constant storage
-//   object, false if the iteration may modify the storage object.
-//
-// ParState([const] OopStorage* storage)
-//   Construct an object for managing an iteration over storage.  For a
-//   concurrent ParState, empty block deletion for the associated storage
-//   is inhibited for the life of the ParState.  There can be no more
-//   than one live concurrent ParState at a time for a given storage object.
-//
-// template<typename F> void iterate(F f)
-//   Repeatedly claims a block from the associated storage that has
-//   not been processed by this iteration (possibly by other threads),
-//   and applies f to each entry in the claimed block. Assume p is of
-//   type const oop* or oop*, according to is_const. Then f(p) must be
-//   a valid expression whose value is ignored.  Concurrent uses must
-//   be prepared for an entry's value to change at any time, due to
-//   mutator activity.
-//
-// template<typename Closure> void oops_do(Closure* cl)
-//   Wrapper around iterate, providing an adaptation layer allowing
-//   the use of OopClosures and similar objects for iteration.  Assume
-//   p is of type const oop* or oop*, according to is_const.  Then
-//   cl->do_oop(p) must be a valid expression whose value is ignored.
-//   Concurrent uses must be prepared for the entry's value to change
-//   at any time, due to mutator activity.
-//
-// Optional operations, provided only if !concurrent && !is_const.
-// These are not provided when is_const, because the storage object
-// may be modified by the iteration infrastructure, even if the
-// provided closure doesn't modify the storage object.  These are not
-// provided when concurrent because any pre-filtering behavior by the
-// iteration infrastructure is inappropriate for concurrent iteration;
-// modifications of the storage by the mutator could result in the
-// pre-filtering being applied (successfully or not) to objects that
-// are unrelated to what the closure finds in the entry.
-//
-// template<typename Closure> void weak_oops_do(Closure* cl)
-// template<typename IsAliveClosure, typename Closure>
-// void weak_oops_do(IsAliveClosure* is_alive, Closure* cl)
-//   Wrappers around iterate, providing an adaptation layer allowing
-//   the use of is-alive closures and OopClosures for iteration.
-//   Assume p is of type oop*.  Then
-//
-//   - cl->do_oop(p) must be a valid expression whose value is ignored.
-//
-//   - is_alive->do_object_b(*p) must be a valid expression whose value
-//   is convertible to bool.
-//
-//   If *p == NULL then neither is_alive nor cl will be invoked for p.
-//   If is_alive->do_object_b(*p) is false, then cl will not be
-//   invoked on p.
-
-class OopStorage::BasicParState VALUE_OBJ_CLASS_SPEC {
-  OopStorage* _storage;
-  void* volatile _next_block;
-  bool _concurrent;
-
-  // Noncopyable.
-  BasicParState(const BasicParState&);
-  BasicParState& operator=(const BasicParState&);
-
-  void update_iteration_state(bool value);
-  void ensure_iteration_started();
-  Block* claim_next_block();
-
-  // Wrapper for iteration handler; ignore handler result and return true.
-  template<typename F> class AlwaysTrueFn;
-
-public:
-  BasicParState(OopStorage* storage, bool concurrent);
-  ~BasicParState();
-
-  template<bool is_const, typename F> void iterate(F f) {
-    // Wrap f in ATF so we can use Block::iterate.
-    AlwaysTrueFn<F> atf_f(f);
-    ensure_iteration_started();
-    typename Conditional<is_const, const Block*, Block*>::type block;
-    while ((block = claim_next_block()) != NULL) {
-      block->iterate(atf_f);
-    }
-  }
-};
-
 template<typename F>
 class OopStorage::BasicParState::AlwaysTrueFn VALUE_OBJ_CLASS_SPEC {
   F _f;
@@ -183,57 +44,49 @@
   bool operator()(OopPtr ptr) const { _f(ptr); return true; }
 };
 
-template<bool concurrent, bool is_const>
-class OopStorage::ParState VALUE_OBJ_CLASS_SPEC {
-  BasicParState _basic_state;
-
-public:
-  ParState(const OopStorage* storage) :
-    // For simplicity, always recorded as non-const.
-    _basic_state(const_cast<OopStorage*>(storage), concurrent)
-  {}
+template<bool is_const, typename F>
+inline void OopStorage::BasicParState::iterate(F f) {
+  // Wrap f in ATF so we can use Block::iterate.
+  AlwaysTrueFn<F> atf_f(f);
+  ensure_iteration_started();
+  typename Conditional<is_const, const Block*, Block*>::type block;
+  while ((block = claim_next_block()) != NULL) {
+    block->iterate(atf_f);
+  }
+}
 
-  template<typename F>
-  void iterate(F f) {
-    _basic_state.template iterate<is_const>(f);
-  }
-
-  template<typename Closure>
-  void oops_do(Closure* cl) {
-    this->iterate(oop_fn(cl));
-  }
-};
-
-template<>
-class OopStorage::ParState<false, false> VALUE_OBJ_CLASS_SPEC {
-  BasicParState _basic_state;
+template<bool concurrent, bool is_const>
+template<typename F>
+inline void OopStorage::ParState<concurrent, is_const>::iterate(F f) {
+  _basic_state.template iterate<is_const>(f);
+}
 
-public:
-  ParState(OopStorage* storage) :
-    _basic_state(storage, false)
-  {}
+template<bool concurrent, bool is_const>
+template<typename Closure>
+inline void OopStorage::ParState<concurrent, is_const>::oops_do(Closure* cl) {
+  this->iterate(oop_fn(cl));
+}
 
-  template<typename F>
-  void iterate(F f) {
-    _basic_state.template iterate<false>(f);
-  }
+template<typename F>
+inline void OopStorage::ParState<false, false>::iterate(F f) {
+  _basic_state.template iterate<false>(f);
+}
 
-  template<typename Closure>
-  void oops_do(Closure* cl) {
-    this->iterate(oop_fn(cl));
-  }
+template<typename Closure>
+inline void OopStorage::ParState<false, false>::oops_do(Closure* cl) {
+  this->iterate(oop_fn(cl));
+}
 
-  template<typename Closure>
-  void weak_oops_do(Closure* cl) {
-    this->iterate(skip_null_fn(oop_fn(cl)));
-  }
+template<typename Closure>
+inline void OopStorage::ParState<false, false>::weak_oops_do(Closure* cl) {
+  this->iterate(skip_null_fn(oop_fn(cl)));
+}
 
-  template<typename IsAliveClosure, typename Closure>
-  void weak_oops_do(IsAliveClosure* is_alive, Closure* cl) {
-    this->iterate(if_alive_fn(is_alive, oop_fn(cl)));
-  }
-};
+template<typename IsAliveClosure, typename Closure>
+inline void OopStorage::ParState<false, false>::weak_oops_do(IsAliveClosure* is_alive, Closure* cl) {
+  this->iterate(if_alive_fn(is_alive, oop_fn(cl)));
+}
 
 #endif // INCLUDE_ALL_GCS
 
-#endif // include guard
+#endif // SHARE_GC_SHARED_OOPSTORAGEPARSTATE_INLINE_HPP
--- a/src/hotspot/share/gc/shared/referenceProcessor.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/shared/referenceProcessor.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -363,12 +363,12 @@
 }
 
 void DiscoveredListIterator::load_ptrs(DEBUG_ONLY(bool allow_null_referent)) {
-  _discovered_addr = java_lang_ref_Reference::discovered_addr(_ref);
+  _discovered_addr = java_lang_ref_Reference::discovered_addr_raw(_ref);
   oop discovered = java_lang_ref_Reference::discovered(_ref);
   assert(_discovered_addr && oopDesc::is_oop_or_null(discovered),
          "Expected an oop or NULL for discovered field at " PTR_FORMAT, p2i(discovered));
   _next = discovered;
-  _referent_addr = java_lang_ref_Reference::referent_addr(_ref);
+  _referent_addr = java_lang_ref_Reference::referent_addr_raw(_ref);
   _referent = java_lang_ref_Reference::referent(_ref);
   assert(Universe::heap()->is_in_reserved_or_null(_referent),
          "Wrong oop found in java.lang.Reference object");
@@ -494,7 +494,7 @@
   DiscoveredListIterator iter(refs_list, keep_alive, is_alive);
   while (iter.has_next()) {
     iter.load_ptrs(DEBUG_ONLY(true /* allow_null_referent */));
-    HeapWord* next_addr = java_lang_ref_Reference::next_addr(iter.obj());
+    HeapWord* next_addr = java_lang_ref_Reference::next_addr_raw(iter.obj());
     oop next = java_lang_ref_Reference::next(iter.obj());
     if ((iter.referent() == NULL || iter.is_referent_alive() ||
          next != NULL)) {
@@ -1019,7 +1019,7 @@
 
   ResourceMark rm;      // Needed for tracing.
 
-  HeapWord* const discovered_addr = java_lang_ref_Reference::discovered_addr(obj);
+  HeapWord* const discovered_addr = java_lang_ref_Reference::discovered_addr_raw(obj);
   const oop  discovered = java_lang_ref_Reference::discovered(obj);
   assert(oopDesc::is_oop_or_null(discovered), "Expected an oop or NULL for discovered field at " PTR_FORMAT, p2i(discovered));
   if (discovered != NULL) {
@@ -1186,10 +1186,10 @@
       // Keep alive its cohort.
       iter.make_referent_alive();
       if (UseCompressedOops) {
-        narrowOop* next_addr = (narrowOop*)java_lang_ref_Reference::next_addr(obj);
+        narrowOop* next_addr = (narrowOop*)java_lang_ref_Reference::next_addr_raw(obj);
         keep_alive->do_oop(next_addr);
       } else {
-        oop* next_addr = (oop*)java_lang_ref_Reference::next_addr(obj);
+        oop* next_addr = (oop*)java_lang_ref_Reference::next_addr_raw(obj);
         keep_alive->do_oop(next_addr);
       }
       iter.move_to_next();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shared/softRefGenPolicy.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2001, 2016, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/shared/adaptiveSizePolicy.hpp"
+#include "gc/shared/genCollectedHeap.hpp"
+#include "gc/shared/softRefGenPolicy.hpp"
+
+void SoftRefGenPolicy::cleared_all_soft_refs() {
+  // If near gc overhear limit, continue to clear SoftRefs.  SoftRefs may
+  // have been cleared in the last collection but if the gc overhear
+  // limit continues to be near, SoftRefs should still be cleared.
+  AdaptiveSizePolicy* size_policy = GenCollectedHeap::heap()->size_policy();
+  if (size_policy != NULL) {
+    set_should_clear_all_soft_refs(size_policy->gc_overhead_limit_near());
+  }
+
+  SoftRefPolicy::cleared_all_soft_refs();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shared/softRefGenPolicy.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2001, 2016, 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_SHARED_SOFTREFGENPOLICY_HPP
+#define SHARE_VM_GC_SHARED_SOFTREFGENPOLICY_HPP
+
+#include "gc/shared/softRefPolicy.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+class AdaptiveSizePolicy;
+
+class SoftRefGenPolicy : public SoftRefPolicy {
+public:
+  virtual void cleared_all_soft_refs();
+};
+
+#endif // SHARE_VM_GC_SHARED_SOFTREFGENPOLICY_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shared/softRefPolicy.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2001, 2016, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/shared/softRefPolicy.hpp"
+
+SoftRefPolicy::SoftRefPolicy() :
+    _should_clear_all_soft_refs(false),
+    _all_soft_refs_clear(false) {
+}
+
+bool SoftRefPolicy::use_should_clear_all_soft_refs(bool v) {
+  bool result = _should_clear_all_soft_refs;
+  set_should_clear_all_soft_refs(false);
+  return result;
+}
+
+void SoftRefPolicy::cleared_all_soft_refs() {
+  _all_soft_refs_clear = true;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shared/softRefPolicy.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2001, 2016, 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_SHARED_SOFTREFPOLICY_HPP
+#define SHARE_VM_GC_SHARED_SOFTREFPOLICY_HPP
+
+#include "memory/allocation.hpp"
+
+class SoftRefPolicy {
+ private:
+  // Set to true when policy wants soft refs cleared.
+  // Reset to false by gc after it clears all soft refs.
+  bool _should_clear_all_soft_refs;
+
+  // Set to true by the GC if the just-completed gc cleared all
+  // softrefs.  This is set to true whenever a gc clears all softrefs, and
+  // set to false each time gc returns to the mutator.  For example, in the
+  // ParallelScavengeHeap case the latter would be done toward the end of
+  // mem_allocate() where it returns op.result()
+  bool _all_soft_refs_clear;
+
+ public:
+  SoftRefPolicy();
+
+  bool should_clear_all_soft_refs() { return _should_clear_all_soft_refs; }
+  void set_should_clear_all_soft_refs(bool v) { _should_clear_all_soft_refs = v; }
+  // Returns the current value of _should_clear_all_soft_refs.
+  // _should_clear_all_soft_refs is set to false as a side effect.
+  bool use_should_clear_all_soft_refs(bool v);
+  bool all_soft_refs_clear() { return _all_soft_refs_clear; }
+  void set_all_soft_refs_clear(bool v) { _all_soft_refs_clear = v; }
+
+  // Called by the GC after Soft Refs have been cleared to indicate
+  // that the request in _should_clear_all_soft_refs has been fulfilled.
+  virtual void cleared_all_soft_refs();
+};
+
+class ClearedAllSoftRefs : public StackObj {
+  bool           _clear_all_soft_refs;
+  SoftRefPolicy* _soft_ref_policy;
+ public:
+  ClearedAllSoftRefs(bool clear_all_soft_refs, SoftRefPolicy* soft_ref_policy) :
+    _clear_all_soft_refs(clear_all_soft_refs),
+    _soft_ref_policy(soft_ref_policy) {}
+
+  ~ClearedAllSoftRefs() {
+    if (_clear_all_soft_refs) {
+      _soft_ref_policy->cleared_all_soft_refs();
+    }
+  }
+
+  bool should_clear() { return _clear_all_soft_refs; }
+};
+
+#endif // SHARE_VM_GC_SHARED_SOFTREFPOLICY_HPP
--- a/src/hotspot/share/gc/shared/vmGCOperations.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/shared/vmGCOperations.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -46,7 +46,7 @@
 
 VM_GC_Operation::~VM_GC_Operation() {
   CollectedHeap* ch = Universe::heap();
-  ch->collector_policy()->set_all_soft_refs_clear(false);
+  ch->soft_ref_policy()->set_all_soft_refs_clear(false);
 }
 
 // The same dtrace probe can't be inserted in two different files, so we
--- a/src/hotspot/share/gc/shared/workgroup.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/gc/shared/workgroup.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -59,14 +59,9 @@
   const uint _gc_id;
 
  public:
-  AbstractGangTask(const char* name) :
+  explicit AbstractGangTask(const char* name) :
     _name(name),
-    _gc_id(GCId::current_raw())
-  {}
-
-  AbstractGangTask(const char* name, const uint gc_id) :
-    _name(name),
-    _gc_id(gc_id)
+    _gc_id(GCId::current_or_undefined())
   {}
 
   // The abstract work method.
--- a/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -34,8 +34,10 @@
 #include "jvmci/jvmciJavaClasses.hpp"
 #include "jvmci/jvmciCompilerToVM.hpp"
 #include "jvmci/jvmciRuntime.hpp"
+#include "oops/arrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "oops/objArrayOop.inline.hpp"
+#include "oops/typeArrayOop.inline.hpp"
 #include "runtime/javaCalls.hpp"
 #include "runtime/safepointMechanism.inline.hpp"
 #include "utilities/align.hpp"
--- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -32,6 +32,7 @@
 #include "oops/fieldStreams.hpp"
 #include "oops/oop.inline.hpp"
 #include "oops/objArrayOop.inline.hpp"
+#include "oops/typeArrayOop.inline.hpp"
 #include "runtime/fieldDescriptor.hpp"
 #include "runtime/javaCalls.hpp"
 #include "jvmci/jvmciRuntime.hpp"
--- a/src/hotspot/share/logging/logConfiguration.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/logging/logConfiguration.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -30,8 +30,8 @@
 #include "logging/logDiagnosticCommand.hpp"
 #include "logging/logFileOutput.hpp"
 #include "logging/logOutput.hpp"
+#include "logging/logSelectionList.hpp"
 #include "logging/logStream.hpp"
-#include "logging/logTagLevelExpression.hpp"
 #include "logging/logTagSet.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/resourceArea.hpp"
@@ -207,7 +207,7 @@
   delete output;
 }
 
-void LogConfiguration::configure_output(size_t idx, const LogTagLevelExpression& tag_level_expression, const LogDecorators& decorators) {
+void LogConfiguration::configure_output(size_t idx, const LogSelectionList& selections, const LogDecorators& decorators) {
   assert(ConfigurationLock::current_thread_has_lock(), "Must hold configuration lock to call this function.");
   assert(idx < _n_outputs, "Invalid index, idx = " SIZE_FORMAT " and _n_outputs = " SIZE_FORMAT, idx, _n_outputs);
   LogOutput* output = _outputs[idx];
@@ -217,7 +217,7 @@
 
   bool enabled = false;
   for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
-    LogLevelType level = tag_level_expression.level_for(*ts);
+    LogLevelType level = selections.level_for(*ts);
 
     // Ignore tagsets that do not, and will not log on the output
     if (!ts->has_output(output) && (level == LogLevel::NotMentioned || level == LogLevel::Off)) {
@@ -299,11 +299,11 @@
 void LogConfiguration::configure_stdout(LogLevelType level, int exact_match, ...) {
   size_t i;
   va_list ap;
-  LogTagLevelExpression expr;
+  LogTagType tags[LogTag::MaxTags];
   va_start(ap, exact_match);
   for (i = 0; i < LogTag::MaxTags; i++) {
     LogTagType tag = static_cast<LogTagType>(va_arg(ap, int));
-    expr.add_tag(tag);
+    tags[i] = tag;
     if (tag == LogTag::__NO_TAG) {
       assert(i > 0, "Must specify at least one tag!");
       break;
@@ -313,17 +313,14 @@
          "Too many tags specified! Can only have up to " SIZE_FORMAT " tags in a tag set.", LogTag::MaxTags);
   va_end(ap);
 
-  if (!exact_match) {
-    expr.set_allow_other_tags();
-  }
-  expr.set_level(level);
-  expr.new_combination();
-  assert(expr.verify_tagsets(),
-         "configure_stdout() called with invalid/non-existing tag set");
+  LogSelection selection(tags, !exact_match, level);
+  assert(selection.tag_sets_selected() > 0,
+         "configure_stdout() called with invalid/non-existing log selection");
+  LogSelectionList list(selection);
 
   // Apply configuration to stdout (output #0), with the same decorators as before.
   ConfigurationLock cl;
-  configure_output(0, expr, _outputs[0]->decorators());
+  configure_output(0, list, _outputs[0]->decorators());
   notify_update_listeners();
 }
 
@@ -382,7 +379,7 @@
 }
 
 bool LogConfiguration::parse_log_arguments(const char* outputstr,
-                                           const char* what,
+                                           const char* selectionstr,
                                            const char* decoratorstr,
                                            const char* output_options,
                                            outputStream* errstream) {
@@ -391,8 +388,8 @@
     outputstr = "stdout";
   }
 
-  LogTagLevelExpression expr;
-  if (!expr.parse(what, errstream)) {
+  LogSelectionList selections;
+  if (!selections.parse(selectionstr, errstream)) {
     return false;
   }
 
@@ -433,9 +430,9 @@
       return false;
     }
   }
-  configure_output(idx, expr, decorators);
+  configure_output(idx, selections, decorators);
   notify_update_listeners();
-  expr.verify_tagsets(errstream);
+  selections.verify_selections(errstream);
   return true;
 }
 
@@ -454,10 +451,7 @@
   out->cr();
 
   out->print("Available log tags:");
-  for (size_t i = 1; i < LogTag::Count; i++) {
-    out->print("%s %s", (i == 1 ? "" : ","), LogTag::name(static_cast<LogTagType>(i)));
-  }
-  out->cr();
+  LogTag::list_tags(out);
 
   LogTagSet::describe_tagsets(out);
 }
@@ -494,13 +488,12 @@
   }
   jio_fprintf(out, "\n Decorators can also be specified as 'none' for no decoration.\n\n");
 
-  jio_fprintf(out, "Available log tags:\n");
-  for (size_t i = 1; i < LogTag::Count; i++) {
-    jio_fprintf(out, "%s %s", (i == 1 ? "" : ","), LogTag::name(static_cast<LogTagType>(i)));
-  }
-  jio_fprintf(out, "\n Specifying 'all' instead of a tag combination matches all tag combinations.\n\n");
+  fileStream stream(out, false);
+  stream.print_cr("Available log tags:");
+  LogTag::list_tags(&stream);
+  stream.print_cr(" Specifying 'all' instead of a tag combination matches all tag combinations.");
+  stream.cr();
 
-  fileStream stream(out, false);
   LogTagSet::describe_tagsets(&stream);
 
   jio_fprintf(out, "\nAvailable log outputs:\n"
--- a/src/hotspot/share/logging/logConfiguration.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/logging/logConfiguration.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -30,7 +30,7 @@
 
 class LogOutput;
 class LogDecorators;
-class LogTagLevelExpression;
+class LogSelectionList;
 
 // Global configuration of logging. Handles parsing and configuration of the logging framework,
 // and manages the list of configured log outputs. The actual tag and level configuration is
@@ -75,7 +75,7 @@
   static size_t find_output(const char* name);
 
   // Configure output (add or update existing configuration) to log on tag-level combination using specified decorators.
-  static void configure_output(size_t idx, const LogTagLevelExpression& tag_level_expression, const LogDecorators& decorators);
+  static void configure_output(size_t idx, const LogSelectionList& tag_level_expression, const LogDecorators& decorators);
 
   // This should be called after any configuration change while still holding ConfigurationLock
   static void notify_update_listeners();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/logging/logSelection.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -0,0 +1,202 @@
+/*
+ * 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
+ * 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.
+ *
+ */
+#include "precompiled.hpp"
+#include "utilities/ostream.hpp"
+#include "logging/logSelection.hpp"
+#include "logging/logTagSet.hpp"
+#include "runtime/os.inline.hpp"
+#include "utilities/globalDefinitions.hpp"
+#include "utilities/ostream.hpp"
+
+const LogSelection LogSelection::Invalid;
+
+LogSelection::LogSelection() : _ntags(0), _wildcard(false), _level(LogLevel::Invalid), _tag_sets_selected(0) {
+}
+
+LogSelection::LogSelection(const LogTagType tags[LogTag::MaxTags], bool wildcard, LogLevelType level)
+    : _ntags(0), _wildcard(wildcard), _level(level), _tag_sets_selected(0) {
+  while (_ntags < LogTag::MaxTags && tags[_ntags] != LogTag::__NO_TAG) {
+    _tags[_ntags] = tags[_ntags];
+    _ntags++;
+  }
+
+  for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
+    if (selects(*ts)) {
+      _tag_sets_selected++;
+    }
+  }
+}
+
+bool LogSelection::operator==(const LogSelection& ref) const {
+  if (_ntags != ref._ntags ||
+      _wildcard != ref._wildcard ||
+      _level != ref._level ||
+      _tag_sets_selected != ref._tag_sets_selected) {
+    return false;
+  }
+  for (size_t i = 0; i < _ntags; i++) {
+    if (_tags[i] != ref._tags[i]) {
+      return false;
+    }
+  }
+  return true;
+}
+
+bool LogSelection::operator!=(const LogSelection& ref) const {
+  return !operator==(ref);
+}
+
+static LogSelection parse_internal(char *str, outputStream* errstream) {
+  // Parse the level, if specified
+  LogLevelType level = LogLevel::Unspecified;
+  char* equals = strchr(str, '=');
+  if (equals != NULL) {
+    level = LogLevel::from_string(equals + 1);
+    if (level == LogLevel::Invalid) {
+      if (errstream != NULL) {
+        errstream->print_cr("Invalid level '%s' in log selection.", equals + 1);
+      }
+      return LogSelection::Invalid;
+    }
+    *equals = '\0';
+  }
+
+  size_t ntags = 0;
+  LogTagType tags[LogTag::MaxTags] = { LogTag::__NO_TAG };
+
+  // Parse special tags such as 'all'
+  if (strcmp(str, "all") == 0) {
+    return LogSelection(tags, true, level);
+  }
+
+  // Check for '*' suffix
+  bool wildcard = false;
+  char* asterisk_pos = strchr(str, '*');
+  if (asterisk_pos != NULL && asterisk_pos[1] == '\0') {
+    wildcard = true;
+    *asterisk_pos = '\0';
+  }
+
+  // Parse the tag expression (t1+t2+...+tn)
+  char* plus_pos;
+  char* cur_tag = str;
+  do {
+    plus_pos = strchr(cur_tag, '+');
+    if (plus_pos != NULL) {
+      *plus_pos = '\0';
+    }
+    LogTagType tag = LogTag::from_string(cur_tag);
+    if (tag == LogTag::__NO_TAG) {
+      if (errstream != NULL) {
+        errstream->print_cr("Invalid tag '%s' in log selection.", cur_tag);
+      }
+      return LogSelection::Invalid;
+    }
+    if (ntags == LogTag::MaxTags) {
+      if (errstream != NULL) {
+        errstream->print_cr("Too many tags in log selection '%s' (can only have up to " SIZE_FORMAT " tags).",
+                               str, LogTag::MaxTags);
+      }
+      return LogSelection::Invalid;
+    }
+    tags[ntags++] = tag;
+    cur_tag = plus_pos + 1;
+  } while (plus_pos != NULL);
+
+  for (size_t i = 0; i < ntags; i++) {
+    for (size_t j = 0; j < ntags; j++) {
+      if (i != j && tags[i] == tags[j]) {
+        if (errstream != NULL) {
+          errstream->print_cr("Log selection contains duplicates of tag %s.", LogTag::name(tags[i]));
+        }
+        return LogSelection::Invalid;
+      }
+    }
+  }
+
+  return LogSelection(tags, wildcard, level);
+}
+
+LogSelection LogSelection::parse(const char* str, outputStream* error_stream) {
+  char* copy = os::strdup_check_oom(str, mtLogging);
+  LogSelection s = parse_internal(copy, error_stream);
+  os::free(copy);
+  return s;
+}
+
+bool LogSelection::selects(const LogTagSet& ts) const {
+  if (!_wildcard && _ntags != ts.ntags()) {
+    return false;
+  }
+  for (size_t i = 0; i < _ntags; i++) {
+    if (!ts.contains(_tags[i])) {
+      return false;
+    }
+  }
+  return true;
+}
+
+size_t LogSelection::ntags() const {
+  return _ntags;
+}
+
+LogLevelType LogSelection::level() const {
+  return _level;
+}
+
+size_t LogSelection::tag_sets_selected() const {
+  return _tag_sets_selected;
+}
+
+int LogSelection::describe_tags(char* buf, size_t bufsize) const {
+  int tot_written = 0;
+  for (size_t i = 0; i < _ntags; i++) {
+    int written = jio_snprintf(buf + tot_written, bufsize - tot_written,
+                               "%s%s", (i == 0 ? "" : "+"), LogTag::name(_tags[i]));
+    if (written == -1) {
+      return written;
+    }
+    tot_written += written;
+  }
+
+  if (_wildcard) {
+    int written = jio_snprintf(buf + tot_written, bufsize - tot_written, "*");
+    if (written == -1) {
+      return written;
+    }
+    tot_written += written;
+  }
+  return tot_written;
+}
+
+int LogSelection::describe(char* buf, size_t bufsize) const {
+  int tot_written = describe_tags(buf, bufsize);
+
+  int written = jio_snprintf(buf + tot_written, bufsize - tot_written, "=%s", LogLevel::name(_level));
+  if (written == -1) {
+    return -1;
+  }
+  tot_written += written;
+  return tot_written;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/logging/logSelection.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -0,0 +1,67 @@
+/*
+ * 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
+ * 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_LOGGING_LOGSELECTION_HPP
+#define SHARE_VM_LOGGING_LOGSELECTION_HPP
+
+#include "logging/logLevel.hpp"
+#include "logging/logTag.hpp"
+#include "memory/allocation.hpp"
+
+class LogTagSet;
+
+// Class representing a selection of tags with for a given level.
+// Consists of a set of tags, an optional wildcard flag, and a level, e.g. "tag1+tag2*=level".
+class LogSelection : public StackObj {
+  friend class LogSelectionList;
+
+ private:
+  size_t _ntags;
+  LogTagType _tags[LogTag::MaxTags];
+  bool _wildcard;
+  LogLevelType _level;
+  size_t _tag_sets_selected;
+
+  LogSelection();
+
+ public:
+  static const LogSelection Invalid;
+
+  static LogSelection parse(const char* str, outputStream* error_stream = NULL);
+
+  LogSelection(const LogTagType tags[LogTag::MaxTags], bool wildcard, LogLevelType level);
+
+  bool operator==(const LogSelection& ref) const;
+  bool operator!=(const LogSelection& ref) const;
+
+  size_t ntags() const;
+  LogLevelType level() const;
+  size_t tag_sets_selected() const;
+
+  bool selects(const LogTagSet& ts) const;
+
+  int describe_tags(char* buf, size_t bufsize) const;
+  int describe(char* buf, size_t bufsize) const;
+};
+
+#endif // SHARE_VM_LOGGING_LOGSELECTION_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/logging/logSelectionList.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2015, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "logging/logSelectionList.hpp"
+#include "logging/logTagSet.hpp"
+#include "runtime/arguments.hpp"
+#include "runtime/os.inline.hpp"
+
+static const char* DefaultExpressionString = "all";
+
+bool LogSelectionList::verify_selections(outputStream* out) const {
+  bool valid = true;
+
+  for (size_t i = 0; i < _nselections; i++) {
+    if (_selections[i].tag_sets_selected() == 0) {
+      // Return immediately unless all invalid selections should be listed
+      if (out == NULL) {
+        return false;
+      }
+
+      if (valid) {
+        out->print("No tag set matches selection(s):");
+      }
+      valid = false;
+
+      char buf[256];
+      _selections[i].describe_tags(buf, sizeof(buf));
+      out->print(" %s", buf);
+    }
+  }
+  if (!valid && out != NULL) {
+    out->cr();
+  }
+  return valid;
+}
+
+
+bool LogSelectionList::parse(const char* str, outputStream* errstream) {
+  bool success = true;
+  if (str == NULL || strcmp(str, "") == 0) {
+    str = DefaultExpressionString;
+  }
+  char* copy = os::strdup_check_oom(str, mtLogging);
+  // Split string on commas
+  for (char *comma_pos = copy, *cur = copy; success && comma_pos != NULL; cur = comma_pos + 1) {
+    if (_nselections == MaxSelections) {
+      if (errstream != NULL) {
+        errstream->print_cr("Can not have more than " SIZE_FORMAT " log selections in a single configuration.",
+                            MaxSelections);
+      }
+      success = false;
+      break;
+    }
+
+    comma_pos = strchr(cur, ',');
+    if (comma_pos != NULL) {
+      *comma_pos = '\0';
+    }
+
+    LogSelection selection = LogSelection::parse(cur, errstream);
+    if (selection == LogSelection::Invalid) {
+      success = false;
+      break;
+    }
+    _selections[_nselections++] = selection;
+  }
+
+  os::free(copy);
+  return success;
+}
+
+LogLevelType LogSelectionList::level_for(const LogTagSet& ts) const {
+  // Return NotMentioned if the given tagset isn't covered by this expression.
+  LogLevelType level = LogLevel::NotMentioned;
+  for (size_t i= 0; i < _nselections; i++) {
+    if (_selections[i].selects(ts)) {
+      level = _selections[i].level();
+    }
+  }
+  return level;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/logging/logSelectionList.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2015, 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.
+ *
+ */
+#ifndef SHARE_VM_LOGGING_LOGSELECTIONLIST_HPP
+#define SHARE_VM_LOGGING_LOGSELECTIONLIST_HPP
+
+#include "logging/logConfiguration.hpp"
+#include "logging/logSelection.hpp"
+#include "logging/logTag.hpp"
+#include "memory/allocation.hpp"
+#include "utilities/debug.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+class LogTagSet;
+
+// Class used to temporary encode a series of log selections during log configuration.
+// Consists of ordered LogSelections, i.e. "tag1+tag2=level1,tag3*=level2".
+class LogSelectionList : public StackObj {
+ public:
+  static const size_t MaxSelections = 256;
+
+ private:
+  friend void LogConfiguration::configure_stdout(LogLevelType, int, ...);
+
+  size_t _nselections;
+  LogSelection _selections[MaxSelections];
+
+ public:
+  LogSelectionList() : _nselections(0) {
+  }
+
+  LogSelectionList(const LogSelection& selection) : _nselections(1) {
+    _selections[0] = selection;
+  }
+
+  bool parse(const char* str, outputStream* errstream = NULL);
+  LogLevelType level_for(const LogTagSet& ts) const;
+
+  // Verify that each selection actually selects something.
+  // Returns false if some invalid selection was found. If given an outputstream,
+  // this function will list all the invalid selections on the stream.
+  bool verify_selections(outputStream* out = NULL) const;
+};
+
+#endif // SHARE_VM_LOGGING_LOGSELECTIONLIST_HPP
--- a/src/hotspot/share/logging/logTag.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/logging/logTag.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -24,6 +24,8 @@
 #include "precompiled.hpp"
 #include "logging/logTag.hpp"
 #include "utilities/globalDefinitions.hpp"
+#include "utilities/ostream.hpp"
+#include "utilities/quickSort.hpp"
 
 const char* LogTag::_name[] = {
   "", // __NO_TAG
@@ -40,3 +42,29 @@
   }
   return __NO_TAG;
 }
+
+static int cmp_logtag(LogTagType a, LogTagType b) {
+  return strcmp(LogTag::name(a), LogTag::name(b));
+}
+
+static const size_t sorted_tagcount = LogTag::Count - 1; // Not counting _NO_TAG
+static LogTagType sorted_tags[sorted_tagcount];
+
+class TagSorter {
+ public:
+  TagSorter() {
+    for (size_t i = 1; i < LogTag::Count; i++) {
+      sorted_tags[i - 1] = static_cast<LogTagType>(i);
+    }
+    QuickSort::sort(sorted_tags, sorted_tagcount, cmp_logtag, true);
+  }
+};
+
+static TagSorter tagsorter; // Sorts tags during static initialization
+
+void LogTag::list_tags(outputStream* out) {
+  for (size_t i = 0; i < sorted_tagcount; i++) {
+    out->print("%s %s", (i == 0 ? "" : ","), _name[sorted_tags[i]]);
+  }
+  out->cr();
+}
--- a/src/hotspot/share/logging/logTag.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/logging/logTag.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -192,6 +192,7 @@
   }
 
   static LogTag::type from_string(const char *str);
+  static void list_tags(outputStream* out);
 
  private:
   static const char* _name[];
--- a/src/hotspot/share/logging/logTagLevelExpression.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,195 +0,0 @@
-/*
- * Copyright (c) 2015, 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.
- *
- */
-#include "precompiled.hpp"
-#include "logging/logTagLevelExpression.hpp"
-#include "logging/logTagSet.hpp"
-#include "runtime/arguments.hpp"
-#include "runtime/os.inline.hpp"
-
-const char* LogTagLevelExpression::DefaultExpressionString = "all";
-
-static bool matches_tagset(const LogTagType tags[],
-                           bool allow_other_tags,
-                           const LogTagSet& ts) {
-  bool contains_all = true;
-  size_t tag_idx;
-  for (tag_idx = 0; tag_idx < LogTag::MaxTags && tags[tag_idx] != LogTag::__NO_TAG; tag_idx++) {
-    if (!ts.contains(tags[tag_idx])) {
-      contains_all = false;
-      break;
-    }
-  }
-  // All tags in the expression must be part of the tagset,
-  // and either the expression allows other tags (has a wildcard),
-  // or the number of tags in the expression and tagset must match.
-  return contains_all && (allow_other_tags || tag_idx == ts.ntags());
-}
-
-bool LogTagLevelExpression::verify_tagsets(outputStream* out) const {
-  bool valid = true;
-
-  for (size_t i = 0; i < _ncombinations; i++) {
-    bool matched = false;
-    for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
-      if (matches_tagset(_tags[i], _allow_other_tags[i], *ts)) {
-        matched = true;
-        break;
-      }
-    }
-
-    if (!matched) {
-      // If this was the first invalid combination, write the message header
-      if (valid && out != NULL) {
-        out->print("No tag set matches selection(s): ");
-      }
-      valid = false;
-
-      // Break as soon as possible unless listing all invalid combinations
-      if (out == NULL) {
-        break;
-      }
-
-      // List the combination on the outputStream
-      for (size_t t = 0; t < LogTag::MaxTags && _tags[i][t] != LogTag::__NO_TAG; t++) {
-        out->print("%s%s", (t == 0 ? "" : "+"), LogTag::name(_tags[i][t]));
-      }
-      if (_allow_other_tags[i]) {
-        out->print("*");
-      }
-      out->print(" ");
-    }
-  }
-
-  if (!valid && out != NULL) {
-    out->cr();
-  }
-
-  return valid;
-}
-
-bool LogTagLevelExpression::parse(const char* str, outputStream* errstream) {
-  bool success = true;
-  if (str == NULL || strcmp(str, "") == 0) {
-    str = DefaultExpressionString;
-  }
-  char* copy = os::strdup_check_oom(str, mtLogging);
-  // Split string on commas
-  for (char *comma_pos = copy, *cur = copy; success && comma_pos != NULL; cur = comma_pos + 1) {
-    if (_ncombinations == MaxCombinations) {
-      if (errstream != NULL) {
-        errstream->print_cr("Can not have more than " SIZE_FORMAT " tag combinations in a what-expression.",
-                            MaxCombinations);
-      }
-      success = false;
-      break;
-    }
-
-    comma_pos = strchr(cur, ',');
-    if (comma_pos != NULL) {
-      *comma_pos = '\0';
-    }
-
-    // Parse the level, if specified
-    LogLevelType level = LogLevel::Unspecified;
-    char* equals = strchr(cur, '=');
-    if (equals != NULL) {
-      level = LogLevel::from_string(equals + 1);
-      if (level == LogLevel::Invalid) {
-        if (errstream != NULL) {
-          errstream->print_cr("Invalid level '%s' in what-expression.", equals + 1);
-        }
-        success = false;
-        break;
-      }
-      *equals = '\0'; // now ignore "=level" part of substr
-    }
-    set_level(level);
-
-    // Parse special tags such as 'all'
-    if (strcmp(cur, "all") == 0) {
-      set_allow_other_tags();
-      new_combination();
-      continue;
-    }
-
-    // Check for '*' suffix
-    char* asterisk_pos = strchr(cur, '*');
-    if (asterisk_pos != NULL && asterisk_pos[1] == '\0') {
-      set_allow_other_tags();
-      *asterisk_pos = '\0';
-    }
-
-    // Parse the tag expression (t1+t2+...+tn)
-    char* plus_pos;
-    char* cur_tag = cur;
-    do {
-      plus_pos = strchr(cur_tag, '+');
-      if (plus_pos != NULL) {
-        *plus_pos = '\0';
-      }
-      LogTagType tag = LogTag::from_string(cur_tag);
-      if (tag == LogTag::__NO_TAG) {
-        if (errstream != NULL) {
-          errstream->print_cr("Invalid tag '%s' in what-expression.", cur_tag);
-        }
-        success = false;
-        break;
-      }
-      if (_ntags == LogTag::MaxTags) {
-        if (errstream != NULL) {
-          errstream->print_cr("Tag combination exceeds the maximum of " SIZE_FORMAT " tags.",
-                              LogTag::MaxTags);
-        }
-        success = false;
-        break;
-      }
-      if (!add_tag(tag)) {
-        if (errstream != NULL) {
-          errstream->print_cr("Tag combination have duplicate tag '%s' in what-expression.",
-                              cur_tag);
-        }
-        success = false;
-        break;
-      }
-      cur_tag = plus_pos + 1;
-    } while (plus_pos != NULL);
-
-    new_combination();
-  }
-
-  os::free(copy);
-  return success;
-}
-
-LogLevelType LogTagLevelExpression::level_for(const LogTagSet& ts) const {
-  // Return NotMentioned if the given tagset isn't covered by this expression.
-  LogLevelType level = LogLevel::NotMentioned;
-  for (size_t combination = 0; combination < _ncombinations; combination++) {
-    if (matches_tagset(_tags[combination], _allow_other_tags[combination], ts)) {
-      level = _level[combination];
-    }
-  }
-  return level;
-}
-
--- a/src/hotspot/share/logging/logTagLevelExpression.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,99 +0,0 @@
-/*
- * Copyright (c) 2015, 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_LOGGING_LOGTAGLEVELEXPRESSION_HPP
-#define SHARE_VM_LOGGING_LOGTAGLEVELEXPRESSION_HPP
-
-#include "logging/logConfiguration.hpp"
-#include "logging/logLevel.hpp"
-#include "logging/logTag.hpp"
-#include "memory/allocation.hpp"
-#include "utilities/debug.hpp"
-#include "utilities/globalDefinitions.hpp"
-
-class LogTagSet;
-
-// Class used to temporary encode a 'what'-expression during log configuration.
-// Consists of a combination of tags and levels, e.g. "tag1+tag2=level1,tag3*=level2".
-class LogTagLevelExpression : public StackObj {
- public:
-  static const size_t MaxCombinations = 256;
-
- private:
-  friend void LogConfiguration::configure_stdout(LogLevelType, int, ...);
-
-  static const char* DefaultExpressionString;
-
-  size_t        _ntags, _ncombinations;
-  LogTagType    _tags[MaxCombinations][LogTag::MaxTags];
-  LogLevelType  _level[MaxCombinations];
-  bool          _allow_other_tags[MaxCombinations];
-
-  void new_combination() {
-    // Make sure either all tags are set or the last tag is __NO_TAG
-    if (_ntags < LogTag::MaxTags) {
-      _tags[_ncombinations][_ntags] = LogTag::__NO_TAG;
-    }
-
-    _ncombinations++;
-    _ntags = 0;
-  }
-
-  bool add_tag(LogTagType tag) {
-    assert(_ntags < LogTag::MaxTags, "Can't have more tags than MaxTags!");
-    for (size_t i = 0; i < _ntags; i++) {
-      if (_tags[_ncombinations][i] == tag) {
-        return false;
-      }
-    }
-    _tags[_ncombinations][_ntags++] = tag;
-    return true;
-  }
-
-  void set_level(LogLevelType level) {
-    _level[_ncombinations] = level;
-  }
-
-  void set_allow_other_tags() {
-    _allow_other_tags[_ncombinations] = true;
-  }
-
- public:
-  LogTagLevelExpression() : _ntags(0), _ncombinations(0) {
-    for (size_t combination = 0; combination < MaxCombinations; combination++) {
-      _level[combination] = LogLevel::Invalid;
-      _allow_other_tags[combination] = false;
-      _tags[combination][0] = LogTag::__NO_TAG;
-    }
-  }
-
-  bool parse(const char* str, outputStream* errstream = NULL);
-  LogLevelType level_for(const LogTagSet& ts) const;
-
-  // Verify the tagsets/selections mentioned in this expression.
-  // Returns false if some invalid tagset was found. If given an outputstream,
-  // this function will list all the invalid selections on the stream.
-  bool verify_tagsets(outputStream* out = NULL) const;
-};
-
-#endif // SHARE_VM_LOGGING_LOGTAGLEVELEXPRESSION_HPP
--- a/src/hotspot/share/memory/metaspace.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/memory/metaspace.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -3952,8 +3952,7 @@
       // Only start a GC if the bootstrapping has completed.
 
       // Try to clean out some memory and retry.
-      result = Universe::heap()->collector_policy()->satisfy_failed_metadata_allocation(
-          loader_data, word_size, mdtype);
+      result = Universe::heap()->satisfy_failed_metadata_allocation(loader_data, word_size, mdtype);
     }
   }
 
--- a/src/hotspot/share/memory/metaspace.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/memory/metaspace.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -87,7 +87,7 @@
   friend class MetaspaceGC;
   friend class MetaspaceAux;
   friend class MetaspaceShared;
-  friend class CollectorPolicy;
+  friend class CollectedHeap;
   friend class PrintCLDMetaspaceInfoClosure;
 
  public:
--- a/src/hotspot/share/memory/oopFactory.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/memory/oopFactory.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -35,6 +35,7 @@
 #include "oops/instanceOop.hpp"
 #include "oops/objArrayOop.hpp"
 #include "oops/oop.inline.hpp"
+#include "oops/typeArrayOop.inline.hpp"
 
 
 typeArrayOop oopFactory::new_charArray(const char* utf8_str, TRAPS) {
--- a/src/hotspot/share/memory/universe.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/memory/universe.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -134,7 +134,6 @@
 oop Universe::_arithmetic_exception_instance          = NULL;
 oop Universe::_virtual_machine_error_instance         = NULL;
 oop Universe::_vm_exception                           = NULL;
-oop Universe::_allocation_context_notification_obj    = NULL;
 oop Universe::_reference_pending_list                 = NULL;
 
 Array<int>* Universe::_the_empty_int_array            = NULL;
@@ -213,7 +212,6 @@
   f->do_oop((oop*)&_main_thread_group);
   f->do_oop((oop*)&_system_thread_group);
   f->do_oop((oop*)&_vm_exception);
-  f->do_oop((oop*)&_allocation_context_notification_obj);
   f->do_oop((oop*)&_reference_pending_list);
   debug_only(f->do_oop((oop*)&_fullgc_alot_dummy_array);)
 }
--- a/src/hotspot/share/memory/universe.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/memory/universe.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -181,8 +181,6 @@
   // the vm thread.
   static oop          _vm_exception;
 
-  static oop          _allocation_context_notification_obj;
-
   // References waiting to be transferred to the ReferenceHandler
   static oop          _reference_pending_list;
 
@@ -334,9 +332,6 @@
   static oop          virtual_machine_error_instance() { return _virtual_machine_error_instance; }
   static oop          vm_exception()                  { return _vm_exception; }
 
-  static inline oop   allocation_context_notification_obj();
-  static inline void  set_allocation_context_notification_obj(oop obj);
-
   // Reference pending list manipulation.  Access is protected by
   // Heap_lock.  The getter, setter and predicate require the caller
   // owns the lock.  Swap is used by parallel non-concurrent reference
--- a/src/hotspot/share/memory/universe.inline.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/memory/universe.inline.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -41,12 +41,4 @@
   return type == T_DOUBLE || type == T_LONG;
 }
 
-inline oop Universe::allocation_context_notification_obj() {
-  return _allocation_context_notification_obj;
-}
-
-inline void Universe::set_allocation_context_notification_obj(oop obj) {
-  _allocation_context_notification_obj = obj;
-}
-
 #endif // SHARE_VM_MEMORY_UNIVERSE_INLINE_HPP
--- a/src/hotspot/share/oops/access.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/oops/access.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -55,6 +55,7 @@
 // * atomic_xchg_at: Atomically swap a new value at an internal pointer address if previous value matched the compared value.
 // * arraycopy: Copy data from one heap array to another heap array.
 // * clone: Clone the contents of an object to a newly allocated object.
+// * resolve: Resolve a stable to-space invariant oop that is guaranteed not to relocate its payload until a subsequent thread transition.
 
 typedef uint64_t DecoratorSet;
 
@@ -69,12 +70,15 @@
 
 // == Internal build-time Decorators ==
 // * INTERNAL_BT_BARRIER_ON_PRIMITIVES: This is set in the barrierSetConfig.hpp file.
+// * INTERNAL_BT_TO_SPACE_INVARIANT: This is set in the barrierSetConfig.hpp file iff
+//   no GC is bundled in the build that is to-space invariant.
 const DecoratorSet INTERNAL_BT_BARRIER_ON_PRIMITIVES = UCONST64(1) << 3;
+const DecoratorSet INTERNAL_BT_TO_SPACE_INVARIANT    = UCONST64(1) << 4;
 
 // == Internal run-time Decorators ==
 // * INTERNAL_RT_USE_COMPRESSED_OOPS: This decorator will be set in runtime resolved
 //   access backends iff UseCompressedOops is true.
-const DecoratorSet INTERNAL_RT_USE_COMPRESSED_OOPS   = UCONST64(1) << 4;
+const DecoratorSet INTERNAL_RT_USE_COMPRESSED_OOPS   = UCONST64(1) << 5;
 
 const DecoratorSet INTERNAL_DECORATOR_MASK           = INTERNAL_CONVERT_COMPRESSED_OOP | INTERNAL_VALUE_IS_OOP |
                                                        INTERNAL_BT_BARRIER_ON_PRIMITIVES | INTERNAL_RT_USE_COMPRESSED_OOPS;
@@ -138,12 +142,12 @@
 //    - Guarantees from MO_RELAXED loads and MO_RELAXED stores hold.
 //  * MO_SEQ_CST: Sequentially consistent xchg.
 //    - Guarantees from MO_SEQ_CST loads and MO_SEQ_CST stores hold.
-const DecoratorSet MO_UNORDERED      = UCONST64(1) << 5;
-const DecoratorSet MO_VOLATILE       = UCONST64(1) << 6;
-const DecoratorSet MO_RELAXED        = UCONST64(1) << 7;
-const DecoratorSet MO_ACQUIRE        = UCONST64(1) << 8;
-const DecoratorSet MO_RELEASE        = UCONST64(1) << 9;
-const DecoratorSet MO_SEQ_CST        = UCONST64(1) << 10;
+const DecoratorSet MO_UNORDERED      = UCONST64(1) << 6;
+const DecoratorSet MO_VOLATILE       = UCONST64(1) << 7;
+const DecoratorSet MO_RELAXED        = UCONST64(1) << 8;
+const DecoratorSet MO_ACQUIRE        = UCONST64(1) << 9;
+const DecoratorSet MO_RELEASE        = UCONST64(1) << 10;
+const DecoratorSet MO_SEQ_CST        = UCONST64(1) << 11;
 const DecoratorSet MO_DECORATOR_MASK = MO_UNORDERED | MO_VOLATILE | MO_RELAXED |
                                        MO_ACQUIRE | MO_RELEASE | MO_SEQ_CST;
 
@@ -166,10 +170,10 @@
 //   responsibility of performing the access and what barriers to be performed to the GC. This is the default.
 //   Note that primitive accesses will only be resolved on the barrier set if the appropriate build-time
 //   decorator for enabling primitive barriers is enabled for the build.
-const DecoratorSet AS_RAW                  = UCONST64(1) << 11;
-const DecoratorSet AS_DEST_NOT_INITIALIZED = UCONST64(1) << 12;
-const DecoratorSet AS_NO_KEEPALIVE         = UCONST64(1) << 13;
-const DecoratorSet AS_NORMAL               = UCONST64(1) << 14;
+const DecoratorSet AS_RAW                  = UCONST64(1) << 12;
+const DecoratorSet AS_DEST_NOT_INITIALIZED = UCONST64(1) << 13;
+const DecoratorSet AS_NO_KEEPALIVE         = UCONST64(1) << 14;
+const DecoratorSet AS_NORMAL               = UCONST64(1) << 15;
 const DecoratorSet AS_DECORATOR_MASK       = AS_RAW | AS_DEST_NOT_INITIALIZED |
                                              AS_NO_KEEPALIVE | AS_NORMAL;
 
@@ -182,10 +186,10 @@
 // * ON_UNKNOWN_OOP_REF: The memory access is performed on a reference of unknown strength.
 //   This could for example come from the unsafe API.
 // * Default (no explicit reference strength specified): ON_STRONG_OOP_REF
-const DecoratorSet ON_STRONG_OOP_REF  = UCONST64(1) << 15;
-const DecoratorSet ON_WEAK_OOP_REF    = UCONST64(1) << 16;
-const DecoratorSet ON_PHANTOM_OOP_REF = UCONST64(1) << 17;
-const DecoratorSet ON_UNKNOWN_OOP_REF = UCONST64(1) << 18;
+const DecoratorSet ON_STRONG_OOP_REF  = UCONST64(1) << 16;
+const DecoratorSet ON_WEAK_OOP_REF    = UCONST64(1) << 17;
+const DecoratorSet ON_PHANTOM_OOP_REF = UCONST64(1) << 18;
+const DecoratorSet ON_UNKNOWN_OOP_REF = UCONST64(1) << 19;
 const DecoratorSet ON_DECORATOR_MASK  = ON_STRONG_OOP_REF | ON_WEAK_OOP_REF |
                                         ON_PHANTOM_OOP_REF | ON_UNKNOWN_OOP_REF;
 
@@ -200,18 +204,18 @@
 // * IN_CONCURRENT_ROOT: The access is performed in an off-heap data structure pointing into the Java heap,
 //   but is notably not scanned during safepoints. This is sometimes a special case for some GCs and
 //   implies that it is also an IN_ROOT.
-const DecoratorSet IN_HEAP            = UCONST64(1) << 19;
-const DecoratorSet IN_HEAP_ARRAY      = UCONST64(1) << 20;
-const DecoratorSet IN_ROOT            = UCONST64(1) << 21;
-const DecoratorSet IN_CONCURRENT_ROOT = UCONST64(1) << 22;
-const DecoratorSet IN_ARCHIVE_ROOT    = UCONST64(1) << 23;
+const DecoratorSet IN_HEAP            = UCONST64(1) << 20;
+const DecoratorSet IN_HEAP_ARRAY      = UCONST64(1) << 21;
+const DecoratorSet IN_ROOT            = UCONST64(1) << 22;
+const DecoratorSet IN_CONCURRENT_ROOT = UCONST64(1) << 23;
+const DecoratorSet IN_ARCHIVE_ROOT    = UCONST64(1) << 24;
 const DecoratorSet IN_DECORATOR_MASK  = IN_HEAP | IN_HEAP_ARRAY |
                                         IN_ROOT | IN_CONCURRENT_ROOT |
                                         IN_ARCHIVE_ROOT;
 
 // == Value Decorators ==
 // * OOP_NOT_NULL: This property can make certain barriers faster such as compressing oops.
-const DecoratorSet OOP_NOT_NULL       = UCONST64(1) << 24;
+const DecoratorSet OOP_NOT_NULL       = UCONST64(1) << 25;
 const DecoratorSet OOP_DECORATOR_MASK = OOP_NOT_NULL;
 
 // == Arraycopy Decorators ==
@@ -224,11 +228,11 @@
 // * ARRAYCOPY_ARRAYOF: The copy is in the arrayof form.
 // * ARRAYCOPY_ATOMIC: The accesses have to be atomic over the size of its elements.
 // * ARRAYCOPY_ALIGNED: The accesses have to be aligned on a HeapWord.
-const DecoratorSet ARRAYCOPY_CHECKCAST            = UCONST64(1) << 25;
-const DecoratorSet ARRAYCOPY_DISJOINT             = UCONST64(1) << 26;
-const DecoratorSet ARRAYCOPY_ARRAYOF              = UCONST64(1) << 27;
-const DecoratorSet ARRAYCOPY_ATOMIC               = UCONST64(1) << 28;
-const DecoratorSet ARRAYCOPY_ALIGNED              = UCONST64(1) << 29;
+const DecoratorSet ARRAYCOPY_CHECKCAST            = UCONST64(1) << 26;
+const DecoratorSet ARRAYCOPY_DISJOINT             = UCONST64(1) << 27;
+const DecoratorSet ARRAYCOPY_ARRAYOF              = UCONST64(1) << 28;
+const DecoratorSet ARRAYCOPY_ATOMIC               = UCONST64(1) << 29;
+const DecoratorSet ARRAYCOPY_ALIGNED              = UCONST64(1) << 30;
 const DecoratorSet ARRAYCOPY_DECORATOR_MASK       = ARRAYCOPY_CHECKCAST | ARRAYCOPY_DISJOINT |
                                                     ARRAYCOPY_DISJOINT | ARRAYCOPY_ARRAYOF |
                                                     ARRAYCOPY_ATOMIC | ARRAYCOPY_ALIGNED;
@@ -297,6 +301,9 @@
   template <DecoratorSet decorators>
   void clone(oop src, oop dst, size_t size);
 
+  template <DecoratorSet decorators>
+  oop resolve(oop src);
+
   // Infer the type that should be returned from a load.
   template <typename P, DecoratorSet decorators>
   class LoadProxy: public StackObj {
@@ -500,6 +507,11 @@
     OopType new_oop_value = new_value;
     return AccessInternal::atomic_xchg<decorators | INTERNAL_VALUE_IS_OOP>(new_oop_value, addr);
   }
+
+  static oop resolve(oop obj) {
+    verify_decorators<INTERNAL_EMPTY>();
+    return AccessInternal::resolve<decorators>(obj);
+  }
 };
 
 // Helper for performing raw accesses (knows only of memory ordering
--- a/src/hotspot/share/oops/access.inline.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/oops/access.inline.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -206,6 +206,13 @@
     }
   };
 
+  template <class GCBarrierType, DecoratorSet decorators>
+  struct PostRuntimeDispatch<GCBarrierType, BARRIER_RESOLVE, decorators>: public AllStatic {
+    static oop access_barrier(oop obj) {
+      return GCBarrierType::resolve(obj);
+    }
+  };
+
   // Resolving accessors with barriers from the barrier set happens in two steps.
   // 1. Expand paths with runtime-decorators, e.g. is UseCompressedOops on or off.
   // 2. Expand paths for each BarrierSet available in the system.
@@ -443,6 +450,22 @@
     }
   };
 
+  template <DecoratorSet decorators, typename T>
+  struct RuntimeDispatch<decorators, T, BARRIER_RESOLVE>: AllStatic {
+    typedef typename AccessFunction<decorators, T, BARRIER_RESOLVE>::type func_t;
+    static func_t _resolve_func;
+
+    static oop resolve_init(oop obj) {
+      func_t function = BarrierResolver<decorators, func_t, BARRIER_RESOLVE>::resolve_barrier();
+      _resolve_func = function;
+      return function(obj);
+    }
+
+    static inline oop resolve(oop obj) {
+      return _resolve_func(obj);
+    }
+  };
+
   // Initialize the function pointers to point to the resolving function.
   template <DecoratorSet decorators, typename T>
   typename AccessFunction<decorators, T, BARRIER_STORE>::type
@@ -484,6 +507,10 @@
   typename AccessFunction<decorators, T, BARRIER_CLONE>::type
   RuntimeDispatch<decorators, T, BARRIER_CLONE>::_clone_func = &clone_init;
 
+  template <DecoratorSet decorators, typename T>
+  typename AccessFunction<decorators, T, BARRIER_RESOLVE>::type
+  RuntimeDispatch<decorators, T, BARRIER_RESOLVE>::_resolve_func = &resolve_init;
+
   // Step 3: Pre-runtime dispatching.
   // The PreRuntimeDispatch class is responsible for filtering the barrier strength
   // decorators. That is, for AS_RAW, it hardwires the accesses without a runtime
@@ -766,6 +793,21 @@
     clone(oop src, oop dst, size_t size) {
       RuntimeDispatch<decorators, oop, BARRIER_CLONE>::clone(src, dst, size);
     }
+
+    template <DecoratorSet decorators>
+    inline static typename EnableIf<
+      HasDecorator<decorators, INTERNAL_BT_TO_SPACE_INVARIANT>::value, oop>::type
+    resolve(oop obj) {
+      typedef RawAccessBarrier<decorators & RAW_DECORATOR_MASK> Raw;
+      return Raw::resolve(obj);
+    }
+
+    template <DecoratorSet decorators>
+    inline static typename EnableIf<
+      !HasDecorator<decorators, INTERNAL_BT_TO_SPACE_INVARIANT>::value, oop>::type
+    resolve(oop obj) {
+      return RuntimeDispatch<decorators, oop, BARRIER_RESOLVE>::resolve(obj);
+    }
   };
 
   // This class adds implied decorators that follow according to decorator rules.
@@ -1051,6 +1093,12 @@
     const DecoratorSet expanded_decorators = DecoratorFixup<decorators>::value;
     PreRuntimeDispatch::clone<expanded_decorators>(src, dst, size);
   }
+
+  template <DecoratorSet decorators>
+  inline oop resolve(oop obj) {
+    const DecoratorSet expanded_decorators = DecoratorFixup<decorators>::value;
+    return PreRuntimeDispatch::resolve<expanded_decorators>(obj);
+  }
 }
 
 template <DecoratorSet decorators>
--- a/src/hotspot/share/oops/accessBackend.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/oops/accessBackend.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -52,7 +52,8 @@
     BARRIER_ATOMIC_XCHG,
     BARRIER_ATOMIC_XCHG_AT,
     BARRIER_ARRAYCOPY,
-    BARRIER_CLONE
+    BARRIER_CLONE,
+    BARRIER_RESOLVE
   };
 
   template <DecoratorSet decorators, typename T>
@@ -100,6 +101,7 @@
 
     typedef bool (*arraycopy_func_t)(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length);
     typedef void (*clone_func_t)(oop src, oop dst, size_t size);
+    typedef oop (*resolve_func_t)(oop obj);
   };
 
   template <DecoratorSet decorators, typename T, BarrierType barrier> struct AccessFunction {};
@@ -119,6 +121,7 @@
   ACCESS_GENERATE_ACCESS_FUNCTION(BARRIER_ATOMIC_XCHG_AT, atomic_xchg_at_func_t);
   ACCESS_GENERATE_ACCESS_FUNCTION(BARRIER_ARRAYCOPY, arraycopy_func_t);
   ACCESS_GENERATE_ACCESS_FUNCTION(BARRIER_CLONE, clone_func_t);
+  ACCESS_GENERATE_ACCESS_FUNCTION(BARRIER_RESOLVE, resolve_func_t);
 #undef ACCESS_GENERATE_ACCESS_FUNCTION
 
   template <DecoratorSet decorators, typename T, BarrierType barrier_type>
@@ -379,6 +382,8 @@
   static bool oop_arraycopy(arrayOop src_obj, arrayOop dst_obj, HeapWord* src, HeapWord* dst, size_t length);
 
   static void clone(oop src, oop dst, size_t size);
+
+  static oop resolve(oop obj) { return obj; }
 };
 
 #endif // SHARE_VM_RUNTIME_ACCESSBACKEND_HPP
--- a/src/hotspot/share/oops/annotations.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/oops/annotations.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -31,6 +31,7 @@
 #include "memory/oopFactory.hpp"
 #include "oops/annotations.hpp"
 #include "oops/instanceKlass.hpp"
+#include "oops/typeArrayOop.inline.hpp"
 #include "utilities/ostream.hpp"
 
 // Allocate annotations in metadata area
--- a/src/hotspot/share/oops/arrayOop.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/oops/arrayOop.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -76,10 +76,10 @@
     return header_size(type) * HeapWordSize;
   }
 
-  // Returns the address of the first element.
-  void* base(BasicType type) const {
-    return (void*) (((intptr_t) this) + base_offset_in_bytes(type));
-  }
+  // Returns the address of the first element. The elements in the array will not
+  // relocate from this address until a subsequent thread transition.
+  inline void* base(BasicType type) const;
+  inline void* base_raw(BasicType type) const; // GC barrier invariant
 
   // Tells whether index is within bounds.
   bool is_within_bounds(int index) const        { return 0 <= index && index < length(); }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/oops/arrayOop.inline.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -0,0 +1,40 @@
+/*
+ * 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
+ * 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_OOPS_ARRAYOOP_INLINE_HPP
+#define SHARE_OOPS_ARRAYOOP_INLINE_HPP
+
+#include "oops/access.inline.hpp"
+#include "oops/arrayOop.hpp"
+
+void* arrayOopDesc::base(BasicType type) const {
+  oop resolved_obj = Access<>::resolve(as_oop());
+  return arrayOop(resolved_obj)->base_raw(type);
+}
+
+void* arrayOopDesc::base_raw(BasicType type) const {
+  return reinterpret_cast<void*>(cast_from_oop<intptr_t>(as_oop()) + base_offset_in_bytes(type));
+}
+
+#endif // SHARE_OOPS_ARRAYOOP_INLINE_HPP
--- a/src/hotspot/share/oops/constantPool.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/oops/constantPool.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -43,6 +43,7 @@
 #include "oops/objArrayKlass.hpp"
 #include "oops/objArrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
+#include "oops/typeArrayOop.inline.hpp"
 #include "runtime/fieldType.hpp"
 #include "runtime/init.hpp"
 #include "runtime/javaCalls.hpp"
@@ -546,12 +547,6 @@
   }
 }
 
-
-Klass* ConstantPool::klass_ref_at_if_loaded(const constantPoolHandle& this_cp, int which) {
-  return klass_at_if_loaded(this_cp, this_cp->klass_ref_index_at(which));
-}
-
-
 Method* ConstantPool::method_at_if_loaded(const constantPoolHandle& cpool,
                                                    int which) {
   if (cpool->cache() == NULL)  return NULL;  // nothing to load yet
--- a/src/hotspot/share/oops/constantPool.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/oops/constantPool.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -147,7 +147,7 @@
     assert(is_within_bounds(which), "index out of bounds");
     assert(!tag_at(which).is_unresolved_klass() && !tag_at(which).is_unresolved_klass_in_error(), "Corrupted constant pool");
     // Uses volatile because the klass slot changes without a lock.
-    intptr_t adr = OrderAccess::load_acquire(obj_at_addr_raw(which));
+    intptr_t adr = OrderAccess::load_acquire(obj_at_addr(which));
     assert(adr != 0 || which == 0, "cp entry for klass should not be zero");
     return CPSlot(adr);
   }
@@ -157,7 +157,7 @@
     assert(s.value() != 0, "Caught something");
     *(intptr_t*)&base()[which] = s.value();
   }
-  intptr_t* obj_at_addr_raw(int which) const {
+  intptr_t* obj_at_addr(int which) const {
     assert(is_within_bounds(which), "index out of bounds");
     return (intptr_t*) &base()[which];
   }
@@ -824,7 +824,6 @@
   static bool    has_method_type_at_if_loaded      (const constantPoolHandle& this_cp, int which);
   static oop         method_type_at_if_loaded      (const constantPoolHandle& this_cp, int which);
   static Klass*            klass_at_if_loaded      (const constantPoolHandle& this_cp, int which);
-  static Klass*        klass_ref_at_if_loaded      (const constantPoolHandle& this_cp, int which);
 
   // Routines currently used for annotations (only called by jvm.cpp) but which might be used in the
   // future by other Java code. These take constant pool indices rather than
--- a/src/hotspot/share/oops/instanceKlass.inline.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/oops/instanceKlass.inline.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -56,7 +56,7 @@
 
 template <bool nv, typename T, class OopClosureType>
 ALWAYSINLINE void InstanceKlass::oop_oop_iterate_oop_map(OopMapBlock* map, oop obj, OopClosureType* closure) {
-  T* p         = (T*)obj->obj_field_addr<T>(map->offset());
+  T* p         = (T*)obj->obj_field_addr_raw<T>(map->offset());
   T* const end = p + map->count();
 
   for (; p < end; ++p) {
@@ -67,7 +67,7 @@
 #if INCLUDE_ALL_GCS
 template <bool nv, typename T, class OopClosureType>
 ALWAYSINLINE void InstanceKlass::oop_oop_iterate_oop_map_reverse(OopMapBlock* map, oop obj, OopClosureType* closure) {
-  T* const start = (T*)obj->obj_field_addr<T>(map->offset());
+  T* const start = (T*)obj->obj_field_addr_raw<T>(map->offset());
   T*       p     = start + map->count();
 
   while (start < p) {
@@ -79,7 +79,7 @@
 
 template <bool nv, typename T, class OopClosureType>
 ALWAYSINLINE void InstanceKlass::oop_oop_iterate_oop_map_bounded(OopMapBlock* map, oop obj, OopClosureType* closure, MemRegion mr) {
-  T* p   = (T*)obj->obj_field_addr<T>(map->offset());
+  T* p   = (T*)obj->obj_field_addr_raw<T>(map->offset());
   T* end = p + map->count();
 
   T* const l   = (T*)mr.start();
--- a/src/hotspot/share/oops/instanceRefKlass.inline.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/oops/instanceRefKlass.inline.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -37,7 +37,7 @@
 
 template <bool nv, typename T, class OopClosureType, class Contains>
 void InstanceRefKlass::do_referent(oop obj, OopClosureType* closure, Contains& contains) {
-  T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
+  T* referent_addr = (T*)java_lang_ref_Reference::referent_addr_raw(obj);
   if (contains(referent_addr)) {
     Devirtualizer<nv>::do_oop(closure, referent_addr);
   }
@@ -45,7 +45,7 @@
 
 template <bool nv, typename T, class OopClosureType, class Contains>
 void InstanceRefKlass::do_next(oop obj, OopClosureType* closure, Contains& contains) {
-  T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
+  T* next_addr = (T*)java_lang_ref_Reference::next_addr_raw(obj);
   if (contains(next_addr)) {
     Devirtualizer<nv>::do_oop(closure, next_addr);
   }
@@ -53,7 +53,7 @@
 
 template <bool nv, typename T, class OopClosureType, class Contains>
 void InstanceRefKlass::do_discovered(oop obj, OopClosureType* closure, Contains& contains) {
-  T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
+  T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr_raw(obj);
   if (contains(discovered_addr)) {
     Devirtualizer<nv>::do_oop(closure, discovered_addr);
   }
@@ -63,7 +63,7 @@
 bool InstanceRefKlass::try_discover(oop obj, ReferenceType type, OopClosureType* closure) {
   ReferenceProcessor* rp = closure->ref_processor();
   if (rp != NULL) {
-    T referent_oop = oopDesc::load_heap_oop((T*)java_lang_ref_Reference::referent_addr(obj));
+    T referent_oop = oopDesc::load_heap_oop((T*)java_lang_ref_Reference::referent_addr_raw(obj));
     if (!oopDesc::is_null(referent_oop)) {
       oop referent = oopDesc::decode_heap_oop_not_null(referent_oop);
       if (!referent->is_gc_marked()) {
@@ -86,7 +86,7 @@
   do_referent<nv, T>(obj, closure, contains);
 
   // Treat discovered as normal oop, if ref is not "active" (next non-NULL).
-  T next_oop  = oopDesc::load_heap_oop((T*)java_lang_ref_Reference::next_addr(obj));
+  T next_oop  = oopDesc::load_heap_oop((T*)java_lang_ref_Reference::next_addr_raw(obj));
   if (!oopDesc::is_null(next_oop)) {
     do_discovered<nv, T>(obj, closure, contains);
   }
@@ -189,9 +189,9 @@
 #ifdef ASSERT
 template <typename T>
 void InstanceRefKlass::trace_reference_gc(const char *s, oop obj) {
-  T* referent_addr   = (T*) java_lang_ref_Reference::referent_addr(obj);
-  T* next_addr       = (T*) java_lang_ref_Reference::next_addr(obj);
-  T* discovered_addr = (T*) java_lang_ref_Reference::discovered_addr(obj);
+  T* referent_addr   = (T*) java_lang_ref_Reference::referent_addr_raw(obj);
+  T* next_addr       = (T*) java_lang_ref_Reference::next_addr_raw(obj);
+  T* discovered_addr = (T*) java_lang_ref_Reference::discovered_addr_raw(obj);
 
   log_develop_trace(gc, ref)("InstanceRefKlass %s for obj " PTR_FORMAT, s, p2i(obj));
   log_develop_trace(gc, ref)("     referent_addr/* " PTR_FORMAT " / " PTR_FORMAT,
--- a/src/hotspot/share/oops/klass.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/oops/klass.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -577,21 +577,15 @@
   if (is_instance_klass()) {
     const InstanceKlass* ik = static_cast<const InstanceKlass*>(this);
     if (ik->is_anonymous()) {
-      intptr_t hash = 0;
-      if (ik->java_mirror() != NULL) {
-        // java_mirror might not be created yet, return 0 as hash.
-        hash = ik->java_mirror()->identity_hash();
-      }
-      char     hash_buf[40];
-      sprintf(hash_buf, "/" UINTX_FORMAT, (uintx)hash);
-      size_t   hash_len = strlen(hash_buf);
-
-      size_t result_len = name()->utf8_length();
-      char*  result     = NEW_RESOURCE_ARRAY(char, result_len + hash_len + 1);
-      name()->as_klass_external_name(result, (int) result_len + 1);
-      assert(strlen(result) == result_len, "");
-      strcpy(result + result_len, hash_buf);
-      assert(strlen(result) == result_len + hash_len, "");
+      char addr_buf[20];
+      jio_snprintf(addr_buf, 20, "/" INTPTR_FORMAT, p2i(ik));
+      size_t addr_len = strlen(addr_buf);
+      size_t name_len = name()->utf8_length();
+      char*  result   = NEW_RESOURCE_ARRAY(char, name_len + addr_len + 1);
+      name()->as_klass_external_name(result, (int) name_len + 1);
+      assert(strlen(result) == name_len, "");
+      strcpy(result + name_len, addr_buf);
+      assert(strlen(result) == name_len + addr_len, "");
       return result;
     }
   }
@@ -737,4 +731,82 @@
   return true;
 }
 
-#endif
+#endif // PRODUCT
+
+// The caller of class_loader_and_module_name() (or one of its callers)
+// must use a ResourceMark in order to correctly free the result.
+const char* Klass::class_loader_and_module_name() const {
+  const char* delim = "/";
+  size_t delim_len = strlen(delim);
+
+  const char* fqn = external_name();
+  // Length of message to return; always include FQN
+  size_t msglen = strlen(fqn) + 1;
+
+  bool has_cl_name = false;
+  bool has_mod_name = false;
+  bool has_version = false;
+
+  // Use class loader name, if exists and not builtin
+  const char* class_loader_name = "";
+  ClassLoaderData* cld = class_loader_data();
+  assert(cld != NULL, "class_loader_data should not be NULL");
+  if (!cld->is_builtin_class_loader_data()) {
+    // If not builtin, look for name
+    oop loader = class_loader();
+    if (loader != NULL) {
+      oop class_loader_name_oop = java_lang_ClassLoader::name(loader);
+      if (class_loader_name_oop != NULL) {
+        class_loader_name = java_lang_String::as_utf8_string(class_loader_name_oop);
+        if (class_loader_name != NULL && class_loader_name[0] != '\0') {
+          has_cl_name = true;
+          msglen += strlen(class_loader_name) + delim_len;
+        }
+      }
+    }
+  }
+
+  const char* module_name = "";
+  const char* version = "";
+  const Klass* bottom_klass = is_objArray_klass() ?
+    ObjArrayKlass::cast(this)->bottom_klass() : this;
+  if (bottom_klass->is_instance_klass()) {
+    ModuleEntry* module = InstanceKlass::cast(bottom_klass)->module();
+    // Use module name, if exists
+    if (module->is_named()) {
+      has_mod_name = true;
+      module_name = module->name()->as_C_string();
+      msglen += strlen(module_name);
+      // Use version if exists and is not a jdk module
+      if (module->is_non_jdk_module() && module->version() != NULL) {
+        has_version = true;
+        version = module->version()->as_C_string();
+        msglen += strlen("@") + strlen(version);
+      }
+    }
+  } else {
+    // klass is an array of primitives, so its module is java.base
+    module_name = JAVA_BASE_NAME;
+  }
+
+  if (has_cl_name || has_mod_name) {
+    msglen += delim_len;
+  }
+
+  char* message = NEW_RESOURCE_ARRAY_RETURN_NULL(char, msglen);
+
+  // Just return the FQN if error in allocating string
+  if (message == NULL) {
+    return fqn;
+  }
+
+  jio_snprintf(message, msglen, "%s%s%s%s%s%s%s",
+               class_loader_name,
+               (has_cl_name) ? delim : "",
+               (has_mod_name) ? module_name : "",
+               (has_version) ? "@" : "",
+               (has_version) ? version : "",
+               (has_cl_name || has_mod_name) ? delim : "",
+               fqn);
+  return message;
+}
--- a/src/hotspot/share/oops/klass.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/oops/klass.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -506,6 +506,8 @@
   //     and the package separators as '/'.
   virtual const char* signature_name() const;
 
+  const char* class_loader_and_module_name() const;
+
   // type testing operations
 #ifdef ASSERT
  protected:
--- a/src/hotspot/share/oops/objArrayKlass.inline.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/oops/objArrayKlass.inline.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -27,6 +27,7 @@
 
 #include "memory/memRegion.hpp"
 #include "memory/iterator.inline.hpp"
+#include "oops/arrayOop.inline.hpp"
 #include "oops/arrayKlass.hpp"
 #include "oops/klass.hpp"
 #include "oops/objArrayKlass.hpp"
@@ -110,7 +111,7 @@
 
 template <bool nv, typename T, class OopClosureType>
 void ObjArrayKlass::oop_oop_iterate_range_specialized(objArrayOop a, OopClosureType* closure, int start, int end) {
-  T* low = start == 0 ? cast_from_oop<T*>(a) : a->obj_at_addr<T>(start);
+  T* low = start == 0 ? cast_from_oop<T*>(a) : a->obj_at_addr_raw<T>(start);
   T* high = (T*)a->base() + end;
 
   oop_oop_iterate_elements_specialized_bounded<nv, T>(a, closure, low, high);
--- a/src/hotspot/share/oops/objArrayOop.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/oops/objArrayOop.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -26,7 +26,7 @@
 #include "gc/shared/specialized_oop_closures.hpp"
 #include "oops/access.inline.hpp"
 #include "oops/objArrayKlass.hpp"
-#include "oops/objArrayOop.hpp"
+#include "oops/objArrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
 
 oop objArrayOopDesc::atomic_compare_exchange_oop(int index, oop exchange_value,
--- a/src/hotspot/share/oops/objArrayOop.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/oops/objArrayOop.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -41,10 +41,8 @@
   friend class CSetMarkOopClosure;
   friend class G1ParScanPartialArrayClosure;
 
-  template <class T> T* obj_at_addr(int index) const {
-    assert(is_within_bounds(index), "index out of bounds");
-    return &((T*)base())[index];
-  }
+  template <class T> T* obj_at_addr(int index) const;
+  template <class T> T* obj_at_addr_raw(int index) const;
 
   template <class T>
   static ptrdiff_t obj_at_offset(int index) {
@@ -84,7 +82,8 @@
   }
 
   // base is the address following the header.
-  HeapWord* base() const      { return (HeapWord*) arrayOopDesc::base(T_OBJECT); }
+  HeapWord* base() const;
+  HeapWord* base_raw() const;
 
   // Accessing
   oop obj_at(int index) const;
--- a/src/hotspot/share/oops/objArrayOop.inline.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/oops/objArrayOop.inline.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -26,10 +26,24 @@
 #define SHARE_VM_OOPS_OBJARRAYOOP_INLINE_HPP
 
 #include "oops/access.inline.hpp"
+#include "oops/arrayOop.inline.hpp"
 #include "oops/objArrayOop.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/globals.hpp"
 
+inline HeapWord* objArrayOopDesc::base() const { return (HeapWord*) arrayOopDesc::base(T_OBJECT); }
+inline HeapWord* objArrayOopDesc::base_raw() const { return (HeapWord*) arrayOopDesc::base_raw(T_OBJECT); }
+
+template <class T> T* objArrayOopDesc::obj_at_addr(int index) const {
+  assert(is_within_bounds(index), "index out of bounds");
+  return &((T*)base())[index];
+}
+
+template <class T> T* objArrayOopDesc::obj_at_addr_raw(int index) const {
+  assert(is_within_bounds(index), "index out of bounds");
+  return &((T*)base_raw())[index];
+}
+
 inline oop objArrayOopDesc::obj_at(int index) const {
   ptrdiff_t offset = UseCompressedOops ? obj_at_offset<narrowOop>(index) : obj_at_offset<oop>(index);
   return HeapAccess<IN_HEAP_ARRAY>::oop_load_at(as_oop(), offset);
--- a/src/hotspot/share/oops/oop.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/oops/oop.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -119,26 +119,13 @@
  protected:
   inline oop        as_oop() const { return const_cast<oopDesc*>(this); }
 
- private:
+ public:
   // field addresses in oop
-  inline void*      field_base(int offset)          const;
+  inline void* field_addr(int offset)     const;
+  inline void* field_addr_raw(int offset) const;
 
-  inline jbyte*     byte_field_addr(int offset)     const;
-  inline jchar*     char_field_addr(int offset)     const;
-  inline jboolean*  bool_field_addr(int offset)     const;
-  inline jint*      int_field_addr(int offset)      const;
-  inline jshort*    short_field_addr(int offset)    const;
-  inline jlong*     long_field_addr(int offset)     const;
-  inline jfloat*    float_field_addr(int offset)    const;
-  inline jdouble*   double_field_addr(int offset)   const;
-  inline Metadata** metadata_field_addr(int offset) const;
-
- public:
   // Need this as public for garbage collection.
-  template <class T> inline T* obj_field_addr(int offset) const;
-
-  // Needed for javaClasses
-  inline address* address_field_addr(int offset) const;
+  template <class T> inline T* obj_field_addr_raw(int offset) const;
 
   inline static bool is_null(oop obj)       { return obj == NULL; }
   inline static bool is_null(narrowOop obj) { return obj == 0; }
--- a/src/hotspot/share/oops/oop.inline.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/oops/oop.inline.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -233,21 +233,11 @@
 bool oopDesc::is_objArray()  const { return klass()->is_objArray_klass();  }
 bool oopDesc::is_typeArray() const { return klass()->is_typeArray_klass(); }
 
-void*      oopDesc::field_base(int offset)          const { return (void*)&((char*)this)[offset]; }
+void*    oopDesc::field_addr_raw(int offset)     const { return reinterpret_cast<void*>(cast_from_oop<intptr_t>(as_oop()) + offset); }
+void*    oopDesc::field_addr(int offset)         const { return Access<>::resolve(as_oop())->field_addr_raw(offset); }
 
-jbyte*     oopDesc::byte_field_addr(int offset)     const { return (jbyte*)    field_base(offset); }
-jchar*     oopDesc::char_field_addr(int offset)     const { return (jchar*)    field_base(offset); }
-jboolean*  oopDesc::bool_field_addr(int offset)     const { return (jboolean*) field_base(offset); }
-jint*      oopDesc::int_field_addr(int offset)      const { return (jint*)     field_base(offset); }
-jshort*    oopDesc::short_field_addr(int offset)    const { return (jshort*)   field_base(offset); }
-jlong*     oopDesc::long_field_addr(int offset)     const { return (jlong*)    field_base(offset); }
-jfloat*    oopDesc::float_field_addr(int offset)    const { return (jfloat*)   field_base(offset); }
-jdouble*   oopDesc::double_field_addr(int offset)   const { return (jdouble*)  field_base(offset); }
-Metadata** oopDesc::metadata_field_addr(int offset) const { return (Metadata**)field_base(offset); }
-
-template <class T> T* oopDesc::obj_field_addr(int offset) const { return (T*)  field_base(offset); }
-address*   oopDesc::address_field_addr(int offset)  const { return (address*)  field_base(offset); }
-
+template <class T>
+T*       oopDesc::obj_field_addr_raw(int offset) const { return (T*) field_addr_raw(offset); }
 
 // Functions for getting and setting oops within instance objects.
 // If the oops are compressed, the type passed to these overloaded functions
--- a/src/hotspot/share/oops/oopsHierarchy.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/oops/oopsHierarchy.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -125,13 +125,6 @@
 
   // from javaCalls.cpp
   operator jobject () const           { return (jobject)obj(); }
-  // from javaClasses.cpp
-  operator JavaThread* () const       { return (JavaThread*)obj(); }
-
-#ifndef _LP64
-  // from jvm.cpp
-  operator jlong* () const            { return (jlong*)obj(); }
-#endif
 
   // from parNewGeneration and other things that want to get to the end of
   // an oop for stuff (like ObjArrayKlass.cpp)
--- a/src/hotspot/share/oops/typeArrayOop.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/oops/typeArrayOop.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -34,110 +34,67 @@
 #include <limits.h>
 
 class typeArrayOopDesc : public arrayOopDesc {
+private:
+  template <class T>
+  static ptrdiff_t element_offset(BasicType bt, int index) {
+    return arrayOopDesc::base_offset_in_bytes(bt) + sizeof(T) * index;
+  }
+
  protected:
-  jchar*    char_base()   const { return (jchar*)   base(T_CHAR); }
-  jboolean* bool_base()   const { return (jboolean*)base(T_BOOLEAN); }
-  jbyte*    byte_base()   const { return (jbyte*)   base(T_BYTE); }
-  jint*     int_base()    const { return (jint*)    base(T_INT); }
-  jlong*    long_base()   const { return (jlong*)   base(T_LONG); }
-  jshort*   short_base()  const { return (jshort*)  base(T_SHORT); }
-  jfloat*   float_base()  const { return (jfloat*)  base(T_FLOAT); }
-  jdouble*  double_base() const { return (jdouble*) base(T_DOUBLE); }
+  jchar*    char_base()   const;
+  jboolean* bool_base()   const;
+  jbyte*    byte_base()   const;
+  jint*     int_base()    const;
+  jlong*    long_base()   const;
+  jshort*   short_base()  const;
+  jfloat*   float_base()  const;
+  jdouble*  double_base() const;
 
   friend class TypeArrayKlass;
 
  public:
-  jbyte* byte_at_addr(int which) const {
-    assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
-    return &byte_base()[which];
-  }
-
-  jboolean* bool_at_addr(int which) const {
-    assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
-    return &bool_base()[which];
-  }
-
-  jchar* char_at_addr(int which) const {
-    assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
-    return &char_base()[which];
-  }
-
-  jint* int_at_addr(int which) const {
-    assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
-    return &int_base()[which];
-  }
+  jbyte* byte_at_addr(int which) const;
+  jboolean* bool_at_addr(int which) const;
+  jchar* char_at_addr(int which) const;
+  jint* int_at_addr(int which) const;
+  jshort* short_at_addr(int which) const;
+  jushort* ushort_at_addr(int which) const;
+  jlong* long_at_addr(int which) const;
+  jfloat* float_at_addr(int which) const;
+  jdouble* double_at_addr(int which) const;
 
-  jshort* short_at_addr(int which) const {
-    assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
-    return &short_base()[which];
-  }
-
-  jushort* ushort_at_addr(int which) const {  // for field descriptor arrays
-    assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
-    return (jushort*) &short_base()[which];
-  }
+  jbyte byte_at(int which) const;
+  void byte_at_put(int which, jbyte contents);
 
-  jlong* long_at_addr(int which) const {
-    assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
-    return &long_base()[which];
-  }
+  jboolean bool_at(int which) const;
+  void bool_at_put(int which, jboolean contents);
 
-  jfloat* float_at_addr(int which) const {
-    assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
-    return &float_base()[which];
-  }
-
-  jdouble* double_at_addr(int which) const {
-    assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
-    return &double_base()[which];
-  }
+  jchar char_at(int which) const;
+  void char_at_put(int which, jchar contents);
 
-  jbyte byte_at(int which) const                  { return *byte_at_addr(which); }
-  void byte_at_put(int which, jbyte contents)     { *byte_at_addr(which) = contents; }
+  jint int_at(int which) const;
+  void int_at_put(int which, jint contents);
 
-  jboolean bool_at(int which) const               { return *bool_at_addr(which); }
-  void bool_at_put(int which, jboolean contents)  { *bool_at_addr(which) = (((jint)contents) & 1); }
-
-  jchar char_at(int which) const                  { return *char_at_addr(which); }
-  void char_at_put(int which, jchar contents)     { *char_at_addr(which) = contents; }
+  jshort short_at(int which) const;
+  void short_at_put(int which, jshort contents);
 
-  jint int_at(int which) const                    { return *int_at_addr(which); }
-  void int_at_put(int which, jint contents)       { *int_at_addr(which) = contents; }
-
-  jshort short_at(int which) const                { return *short_at_addr(which); }
-  void short_at_put(int which, jshort contents)   { *short_at_addr(which) = contents; }
+  jushort ushort_at(int which) const;
+  void ushort_at_put(int which, jushort contents);
 
-  jushort ushort_at(int which) const              { return *ushort_at_addr(which); }
-  void ushort_at_put(int which, jushort contents) { *ushort_at_addr(which) = contents; }
-
-  jlong long_at(int which) const                  { return *long_at_addr(which); }
-  void long_at_put(int which, jlong contents)     { *long_at_addr(which) = contents; }
+  jlong long_at(int which) const;
+  void long_at_put(int which, jlong contents);
 
-  jfloat float_at(int which) const                { return *float_at_addr(which); }
-  void float_at_put(int which, jfloat contents)   { *float_at_addr(which) = contents; }
+  jfloat float_at(int which) const;
+  void float_at_put(int which, jfloat contents);
 
-  jdouble double_at(int which) const              { return *double_at_addr(which); }
-  void double_at_put(int which, jdouble contents) { *double_at_addr(which) = contents; }
-
-  jbyte byte_at_acquire(int which) const              { return OrderAccess::load_acquire(byte_at_addr(which)); }
-  void release_byte_at_put(int which, jbyte contents) { OrderAccess::release_store(byte_at_addr(which), contents); }
+  jdouble double_at(int which) const;
+  void double_at_put(int which, jdouble contents);
 
-  // Java thinks Symbol arrays are just arrays of either long or int, since
-  // there doesn't seem to be T_ADDRESS, so this is a bit of unfortunate
-  // casting
-#ifdef _LP64
-  Symbol* symbol_at(int which) const {
-    return (Symbol*)*long_at_addr(which); }
-  void symbol_at_put(int which, Symbol* contents) {
-    *long_at_addr(which) = (jlong)contents;
-  }
-#else
-  Symbol* symbol_at(int which) const {
-    return (Symbol*)*int_at_addr(which); }
-  void symbol_at_put(int which, Symbol* contents) {
-    *int_at_addr(which) = (int)contents;
-  }
-#endif // _LP64
+  jbyte byte_at_acquire(int which) const;
+  void release_byte_at_put(int which, jbyte contents);
+
+  Symbol* symbol_at(int which) const;
+  void symbol_at_put(int which, Symbol* contents);
 
   // Sizing
 
--- a/src/hotspot/share/oops/typeArrayOop.inline.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/oops/typeArrayOop.inline.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -25,7 +25,9 @@
 #ifndef SHARE_VM_OOPS_TYPEARRAYOOP_INLINE_HPP
 #define SHARE_VM_OOPS_TYPEARRAYOOP_INLINE_HPP
 
+#include "oops/access.inline.hpp"
 #include "oops/oop.inline.hpp"
+#include "oops/arrayOop.inline.hpp"
 #include "oops/typeArrayOop.hpp"
 
 int typeArrayOopDesc::object_size() {
@@ -33,4 +35,172 @@
   return object_size(tk->layout_helper(), length());
 }
 
+inline jchar*    typeArrayOopDesc::char_base()   const { return (jchar*)   base(T_CHAR); }
+inline jboolean* typeArrayOopDesc::bool_base()   const { return (jboolean*)base(T_BOOLEAN); }
+inline jbyte*    typeArrayOopDesc::byte_base()   const { return (jbyte*)   base(T_BYTE); }
+inline jint*     typeArrayOopDesc::int_base()    const { return (jint*)    base(T_INT); }
+inline jlong*    typeArrayOopDesc::long_base()   const { return (jlong*)   base(T_LONG); }
+inline jshort*   typeArrayOopDesc::short_base()  const { return (jshort*)  base(T_SHORT); }
+inline jfloat*   typeArrayOopDesc::float_base()  const { return (jfloat*)  base(T_FLOAT); }
+inline jdouble*  typeArrayOopDesc::double_base() const { return (jdouble*) base(T_DOUBLE); }
+
+inline jbyte* typeArrayOopDesc::byte_at_addr(int which) const {
+  assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
+  return &byte_base()[which];
+}
+
+inline jboolean* typeArrayOopDesc::bool_at_addr(int which) const {
+  assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
+  return &bool_base()[which];
+}
+
+inline jchar* typeArrayOopDesc::char_at_addr(int which) const {
+  assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
+  return &char_base()[which];
+}
+
+inline jint* typeArrayOopDesc::int_at_addr(int which) const {
+  assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
+  return &int_base()[which];
+}
+
+inline jshort* typeArrayOopDesc::short_at_addr(int which) const {
+  assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
+  return &short_base()[which];
+}
+
+inline jushort* typeArrayOopDesc::ushort_at_addr(int which) const {  // for field descriptor arrays
+  assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
+  return (jushort*) &short_base()[which];
+}
+
+inline jlong* typeArrayOopDesc::long_at_addr(int which) const {
+  assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
+  return &long_base()[which];
+}
+
+inline jfloat* typeArrayOopDesc::float_at_addr(int which) const {
+  assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
+  return &float_base()[which];
+}
+
+inline jdouble* typeArrayOopDesc::double_at_addr(int which) const {
+  assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
+  return &double_base()[which];
+}
+
+inline jbyte typeArrayOopDesc::byte_at(int which) const {
+  ptrdiff_t offset = element_offset<jbyte>(T_BYTE, which);
+  return HeapAccess<IN_HEAP_ARRAY>::load_at(as_oop(), offset);
+}
+inline void typeArrayOopDesc::byte_at_put(int which, jbyte contents) {
+  ptrdiff_t offset = element_offset<jbyte>(T_BYTE, which);
+  HeapAccess<IN_HEAP_ARRAY>::store_at(as_oop(), offset, contents);
+}
+
+inline jboolean typeArrayOopDesc::bool_at(int which) const {
+  ptrdiff_t offset = element_offset<jboolean>(T_BOOLEAN, which);
+  return HeapAccess<IN_HEAP_ARRAY>::load_at(as_oop(), offset);
+}
+inline void typeArrayOopDesc::bool_at_put(int which, jboolean contents) {
+  ptrdiff_t offset = element_offset<jboolean>(T_BOOLEAN, which);
+  HeapAccess<IN_HEAP_ARRAY>::store_at(as_oop(), offset, jboolean(contents & 1));
+}
+
+inline jchar typeArrayOopDesc::char_at(int which) const {
+  ptrdiff_t offset = element_offset<jchar>(T_CHAR, which);
+  return HeapAccess<IN_HEAP_ARRAY>::load_at(as_oop(), offset);
+}
+inline void typeArrayOopDesc::char_at_put(int which, jchar contents) {
+  ptrdiff_t offset = element_offset<jchar>(T_CHAR, which);
+  HeapAccess<IN_HEAP_ARRAY>::store_at(as_oop(), offset, contents);
+}
+
+inline jint typeArrayOopDesc::int_at(int which) const {
+  ptrdiff_t offset = element_offset<jint>(T_INT, which);
+  return HeapAccess<IN_HEAP_ARRAY>::load_at(as_oop(), offset);
+}
+inline void typeArrayOopDesc::int_at_put(int which, jint contents) {
+  ptrdiff_t offset = element_offset<jint>(T_INT, which);
+  HeapAccess<IN_HEAP_ARRAY>::store_at(as_oop(), offset, contents);
+}
+
+inline jshort typeArrayOopDesc::short_at(int which) const {
+  ptrdiff_t offset = element_offset<jshort>(T_SHORT, which);
+  return HeapAccess<IN_HEAP_ARRAY>::load_at(as_oop(), offset);
+}
+inline void typeArrayOopDesc::short_at_put(int which, jshort contents) {
+  ptrdiff_t offset = element_offset<jshort>(T_SHORT, which);
+  HeapAccess<IN_HEAP_ARRAY>::store_at(as_oop(), offset, contents);
+}
+
+inline jushort typeArrayOopDesc::ushort_at(int which) const {
+  ptrdiff_t offset = element_offset<jushort>(T_SHORT, which);
+  return HeapAccess<IN_HEAP_ARRAY>::load_at(as_oop(), offset);
+}
+inline void typeArrayOopDesc::ushort_at_put(int which, jushort contents) {
+  ptrdiff_t offset = element_offset<jushort>(T_SHORT, which);
+  HeapAccess<IN_HEAP_ARRAY>::store_at(as_oop(), offset, contents);
+}
+
+inline jlong typeArrayOopDesc::long_at(int which) const {
+  ptrdiff_t offset = element_offset<jlong>(T_LONG, which);
+  return HeapAccess<IN_HEAP_ARRAY>::load_at(as_oop(), offset);
+}
+inline void typeArrayOopDesc::long_at_put(int which, jlong contents) {
+  ptrdiff_t offset = element_offset<jlong>(T_LONG, which);
+  HeapAccess<IN_HEAP_ARRAY>::store_at(as_oop(), offset, contents);
+}
+
+inline jfloat typeArrayOopDesc::float_at(int which) const {
+  ptrdiff_t offset = element_offset<jfloat>(T_FLOAT, which);
+  return HeapAccess<IN_HEAP_ARRAY>::load_at(as_oop(), offset);
+}
+inline void typeArrayOopDesc::float_at_put(int which, jfloat contents) {
+  ptrdiff_t offset = element_offset<jfloat>(T_FLOAT, which);
+  HeapAccess<IN_HEAP_ARRAY>::store_at(as_oop(), offset, contents);
+}
+
+inline jdouble typeArrayOopDesc::double_at(int which) const {
+  ptrdiff_t offset = element_offset<jdouble>(T_DOUBLE, which);
+  return HeapAccess<IN_HEAP_ARRAY>::load_at(as_oop(), offset);
+}
+inline void typeArrayOopDesc::double_at_put(int which, jdouble contents) {
+  ptrdiff_t offset = element_offset<jdouble>(T_DOUBLE, which);
+  HeapAccess<IN_HEAP_ARRAY>::store_at(as_oop(), offset, contents);
+}
+
+inline jbyte typeArrayOopDesc::byte_at_acquire(int which) const {
+  ptrdiff_t offset = element_offset<jbyte>(T_BYTE, which);
+  return HeapAccess<MO_ACQUIRE | IN_HEAP_ARRAY>::load_at(as_oop(), offset);
+}
+inline void typeArrayOopDesc::release_byte_at_put(int which, jbyte contents) {
+  ptrdiff_t offset = element_offset<jbyte>(T_BYTE, which);
+  HeapAccess<MO_RELEASE | IN_HEAP_ARRAY>::store_at(as_oop(), offset, contents);
+}
+
+// Java thinks Symbol arrays are just arrays of either long or int, since
+// there doesn't seem to be T_ADDRESS, so this is a bit of unfortunate
+// casting
+#ifdef _LP64
+inline Symbol* typeArrayOopDesc::symbol_at(int which) const {
+  ptrdiff_t offset = element_offset<jlong>(T_LONG, which);
+  return (Symbol*)(jlong) HeapAccess<IN_HEAP_ARRAY>::load_at(as_oop(), offset);
+}
+inline void typeArrayOopDesc::symbol_at_put(int which, Symbol* contents) {
+  ptrdiff_t offset = element_offset<jlong>(T_LONG, which);
+  HeapAccess<IN_HEAP_ARRAY>::store_at(as_oop(), offset, (jlong)contents);
+}
+#else
+inline Symbol* typeArrayOopDesc::symbol_at(int which) const {
+  ptrdiff_t offset = element_offset<jint>(T_INT, which);
+  return (Symbol*)(jint) HeapAccess<IN_HEAP_ARRAY>::load_at(as_oop(), offset);
+}
+inline void typeArrayOopDesc::symbol_at_put(int which, Symbol* contents) {
+  ptrdiff_t offset = element_offset<jint>(T_INT, which);
+  HeapAccess<IN_HEAP_ARRAY>::store_at(as_oop(), offset, (jint)contents);
+}
+#endif // _LP64
+
+
 #endif // SHARE_VM_OOPS_TYPEARRAYOOP_INLINE_HPP
--- a/src/hotspot/share/opto/buildOopMap.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/opto/buildOopMap.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -618,7 +618,7 @@
     // last block as his only undone child, we can move the OopFlow from the
     // pred to this block.  Otherwise we have to grab a new OopFlow.
     OopFlow *flow = NULL;       // Flag for finding optimized flow
-    Block *pred = (Block*)0xdeadbeef;
+    Block *pred = (Block*)((intptr_t)0xdeadbeef);
     // Scan this block's preds to find a done predecessor
     for (uint j = 1; j < b->num_preds(); j++) {
       Block* p = _cfg->get_block_for_node(b->pred(j));
--- a/src/hotspot/share/opto/compile.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/opto/compile.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -2449,8 +2449,8 @@
   print_method(PHASE_FINAL_CODE);
 
   // He's dead, Jim.
-  _cfg     = (PhaseCFG*)0xdeadbeef;
-  _regalloc = (PhaseChaitin*)0xdeadbeef;
+  _cfg     = (PhaseCFG*)((intptr_t)0xdeadbeef);
+  _regalloc = (PhaseChaitin*)((intptr_t)0xdeadbeef);
 }
 
 
--- a/src/hotspot/share/opto/gcm.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/opto/gcm.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -1486,7 +1486,7 @@
   }
 #endif
   // Dead.
-  _node_latency = (GrowableArray<uint> *)0xdeadbeef;
+  _node_latency = (GrowableArray<uint> *)((intptr_t)0xdeadbeef);
 }
 
 bool PhaseCFG::do_global_code_motion() {
--- a/src/hotspot/share/opto/idealGraphPrinter.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/opto/idealGraphPrinter.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -602,7 +602,7 @@
     }
 #endif
 
-    if (_chaitin && _chaitin != (PhaseChaitin *)0xdeadbeef) {
+    if (_chaitin && _chaitin != (PhaseChaitin *)((intptr_t)0xdeadbeef)) {
       buffer[0] = 0;
       _chaitin->dump_register(node, buffer);
       print_prop("reg", buffer);
--- a/src/hotspot/share/opto/library_call.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/opto/library_call.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -2408,7 +2408,7 @@
   offset = argument(2);  // type: long
   // We currently rely on the cookies produced by Unsafe.xxxFieldOffset
   // to be plain byte offsets, which are also the same as those accepted
-  // by oopDesc::field_base.
+  // by oopDesc::field_addr.
   assert(Unsafe_field_offset_to_byte_offset(11) == 11,
          "fieldOffset must be byte-scaled");
   // 32-bit machines ignore the high half!
@@ -2838,7 +2838,7 @@
   // Build field offset expression.
   // We currently rely on the cookies produced by Unsafe.xxxFieldOffset
   // to be plain byte offsets, which are also the same as those accepted
-  // by oopDesc::field_base.
+  // by oopDesc::field_addr.
   assert(Unsafe_field_offset_to_byte_offset(11) == 11, "fieldOffset must be byte-scaled");
   // 32-bit machines ignore the high half of long offsets
   offset = ConvL2X(offset);
--- a/src/hotspot/share/opto/output.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/opto/output.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -2575,7 +2575,7 @@
   }
 
   Node *kill = def;             // Rename 'def' to more descriptive 'kill'
-  debug_only( def = (Node*)0xdeadbeef; )
+  debug_only( def = (Node*)((intptr_t)0xdeadbeef); )
 
   // After some number of kills there _may_ be a later def
   Node *later_def = NULL;
--- a/src/hotspot/share/opto/split_if.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/opto/split_if.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -292,7 +292,7 @@
 Node *PhaseIdealLoop::spinup( Node *iff_dom, Node *new_false, Node *new_true, Node *use_blk, Node *def, small_cache *cache ) {
   if (use_blk->is_top())        // Handle dead uses
     return use_blk;
-  Node *prior_n = (Node*)0xdeadbeef;
+  Node *prior_n = (Node*)((intptr_t)0xdeadbeef);
   Node *n = use_blk;            // Get path input
   assert( use_blk != iff_dom, "" );
   // Here's the "spinup" the dominator tree loop.  Do a cache-check
@@ -339,7 +339,7 @@
   }
 
   // Update cache everywhere
-  prior_n = (Node*)0xdeadbeef;  // Reset IDOM walk
+  prior_n = (Node*)((intptr_t)0xdeadbeef);  // Reset IDOM walk
   n = use_blk;                  // Get path input
   // Spin-up the idom tree again, basically doing path-compression.
   // Insert cache entries along the way, so that if we ever hit this
--- a/src/hotspot/share/prims/jni.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/prims/jni.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -44,6 +44,7 @@
 #include "memory/resourceArea.hpp"
 #include "memory/universe.inline.hpp"
 #include "oops/access.inline.hpp"
+#include "oops/arrayOop.inline.hpp"
 #include "oops/instanceKlass.hpp"
 #include "oops/instanceOop.hpp"
 #include "oops/markOop.hpp"
@@ -53,7 +54,7 @@
 #include "oops/oop.inline.hpp"
 #include "oops/symbol.hpp"
 #include "oops/typeArrayKlass.hpp"
-#include "oops/typeArrayOop.hpp"
+#include "oops/typeArrayOop.inline.hpp"
 #include "prims/jniCheck.hpp"
 #include "prims/jniExport.hpp"
 #include "prims/jniFastGetField.hpp"
--- a/src/hotspot/share/prims/jvm.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/prims/jvm.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -166,9 +166,8 @@
       }
     } else if (last_caller != NULL &&
                last_caller->method_holder()->name() ==
-               vmSymbols::java_lang_ClassLoader() &&
-               (last_caller->name() == vmSymbols::loadClassInternal_name() ||
-                last_caller->name() == vmSymbols::loadClass_name())) {
+                 vmSymbols::java_lang_ClassLoader() &&
+               last_caller->name() == vmSymbols::loadClass_name()) {
       found_it = true;
     } else if (!vfst.at_end()) {
       if (vfst.method()->is_native()) {
--- a/src/hotspot/share/prims/jvmtiTagMap.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/prims/jvmtiTagMap.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -31,10 +31,12 @@
 #include "jvmtifiles/jvmtiEnv.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/access.inline.hpp"
+#include "oops/arrayOop.inline.hpp"
 #include "oops/instanceMirrorKlass.hpp"
 #include "oops/objArrayKlass.hpp"
 #include "oops/objArrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
+#include "oops/typeArrayOop.inline.hpp"
 #include "prims/jvmtiEventController.hpp"
 #include "prims/jvmtiEventController.inline.hpp"
 #include "prims/jvmtiExport.hpp"
--- a/src/hotspot/share/prims/methodHandles.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/prims/methodHandles.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -36,6 +36,7 @@
 #include "memory/resourceArea.hpp"
 #include "oops/objArrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
+#include "oops/typeArrayOop.inline.hpp"
 #include "prims/methodHandles.hpp"
 #include "runtime/compilationPolicy.hpp"
 #include "runtime/javaCalls.hpp"
--- a/src/hotspot/share/prims/unsafe.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/prims/unsafe.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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,7 @@
 #include "oops/fieldStreams.hpp"
 #include "oops/objArrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
+#include "oops/typeArrayOop.inline.hpp"
 #include "prims/unsafe.hpp"
 #include "runtime/atomic.hpp"
 #include "runtime/globals.hpp"
@@ -108,8 +109,8 @@
     assert(byte_offset >= 0 && byte_offset <= (jlong)MAX_OBJECT_SIZE, "sane offset");
     if (byte_offset == (jint)byte_offset) {
       void* ptr_plus_disp = (address)p + byte_offset;
-      assert((void*)p->obj_field_addr<oop>((jint)byte_offset) == ptr_plus_disp,
-             "raw [ptr+disp] must be consistent with oop::field_base");
+      assert(p->field_addr_raw((jint)byte_offset) == ptr_plus_disp,
+             "raw [ptr+disp] must be consistent with oop::field_addr_raw");
     }
     jlong p_size = HeapWordSize * (jlong)(p->size());
     assert(byte_offset < p_size, "Unsafe access: offset " INT64_FORMAT " > object's size " INT64_FORMAT, (int64_t)byte_offset, (int64_t)p_size);
--- a/src/hotspot/share/prims/whitebox.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/prims/whitebox.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -44,6 +44,7 @@
 #include "oops/objArrayKlass.hpp"
 #include "oops/objArrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
+#include "oops/typeArrayOop.inline.hpp"
 #include "prims/wbtestmethods/parserTests.hpp"
 #include "prims/whitebox.hpp"
 #include "runtime/arguments.hpp"
@@ -59,8 +60,8 @@
 #include "runtime/vm_version.hpp"
 #include "utilities/align.hpp"
 #include "utilities/debug.hpp"
+#include "utilities/elfFile.hpp"
 #include "utilities/exceptions.hpp"
-#include "utilities/elfFile.hpp"
 #include "utilities/macros.hpp"
 #if INCLUDE_CDS
 #include "prims/cdsoffsets.hpp"
@@ -80,7 +81,6 @@
 #endif // INCLUDE_NMT
 
 #ifdef LINUX
-#include "utilities/elfFile.hpp"
 #include "osContainer_linux.hpp"
 #endif
 
@@ -602,6 +602,13 @@
   return addr;
 WB_END
 
+WB_ENTRY(jlong, WB_NMTAttemptReserveMemoryAt(JNIEnv* env, jobject o, jlong addr, jlong size))
+  addr = (jlong)(uintptr_t)os::attempt_reserve_memory_at((size_t)size, (char*)(uintptr_t)addr);
+  MemTracker::record_virtual_memory_type((address)addr, mtTest);
+
+  return addr;
+WB_END
+
 WB_ENTRY(void, WB_NMTCommitMemory(JNIEnv* env, jobject o, jlong addr, jlong size))
   os::commit_memory((char *)(uintptr_t)addr, size, !ExecMem);
   MemTracker::record_virtual_memory_type((address)(uintptr_t)addr, mtTest);
@@ -1212,12 +1219,12 @@
 WB_END
 
 WB_ENTRY(void, WB_FullGC(JNIEnv* env, jobject o))
-  Universe::heap()->collector_policy()->set_should_clear_all_soft_refs(true);
+  Universe::heap()->soft_ref_policy()->set_should_clear_all_soft_refs(true);
   Universe::heap()->collect(GCCause::_wb_full_gc);
 #if INCLUDE_ALL_GCS
   if (UseG1GC) {
     // Needs to be cleared explicitly for G1
-    Universe::heap()->collector_policy()->set_should_clear_all_soft_refs(false);
+    Universe::heap()->soft_ref_policy()->set_should_clear_all_soft_refs(false);
   }
 #endif // INCLUDE_ALL_GCS
 WB_END
@@ -1740,6 +1747,10 @@
 #endif // INCLUDE_CDS
 WB_END
 
+WB_ENTRY(jboolean, WB_IsJavaHeapArchiveSupported(JNIEnv* env))
+  return MetaspaceShared::is_heap_object_archiving_allowed();
+WB_END
+
 
 #if INCLUDE_CDS
 
@@ -1970,6 +1981,7 @@
   {CC"NMTMallocWithPseudoStack", CC"(JI)J",           (void*)&WB_NMTMallocWithPseudoStack},
   {CC"NMTFree",             CC"(J)V",                 (void*)&WB_NMTFree            },
   {CC"NMTReserveMemory",    CC"(J)J",                 (void*)&WB_NMTReserveMemory   },
+  {CC"NMTAttemptReserveMemoryAt",    CC"(JJ)J",       (void*)&WB_NMTAttemptReserveMemoryAt },
   {CC"NMTCommitMemory",     CC"(JJ)V",                (void*)&WB_NMTCommitMemory    },
   {CC"NMTUncommitMemory",   CC"(JJ)V",                (void*)&WB_NMTUncommitMemory  },
   {CC"NMTReleaseMemory",    CC"(JJ)V",                (void*)&WB_NMTReleaseMemory   },
@@ -2116,6 +2128,8 @@
   {CC"getResolvedReferences", CC"(Ljava/lang/Class;)Ljava/lang/Object;", (void*)&WB_GetResolvedReferences},
   {CC"areOpenArchiveHeapObjectsMapped",   CC"()Z",    (void*)&WB_AreOpenArchiveHeapObjectsMapped},
   {CC"isCDSIncludedInVmBuild",            CC"()Z",    (void*)&WB_IsCDSIncludedInVmBuild },
+  {CC"isJavaHeapArchiveSupported",      CC"()Z",      (void*)&WB_IsJavaHeapArchiveSupported },
+
   {CC"clearInlineCaches0",  CC"(Z)V",                 (void*)&WB_ClearInlineCaches },
   {CC"handshakeWalkStack", CC"(Ljava/lang/Thread;Z)I", (void*)&WB_HandshakeWalkStack },
   {CC"addCompilerDirective",    CC"(Ljava/lang/String;)I",
--- a/src/hotspot/share/runtime/arguments.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/runtime/arguments.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -509,7 +509,6 @@
   { "MinRAMFraction",               JDK_Version::jdk(10),  JDK_Version::undefined(), JDK_Version::undefined() },
   { "InitialRAMFraction",           JDK_Version::jdk(10),  JDK_Version::undefined(), JDK_Version::undefined() },
   { "UseMembar",                    JDK_Version::jdk(10), JDK_Version::undefined(), JDK_Version::undefined() },
-  { "FastTLABRefill",               JDK_Version::jdk(10), JDK_Version::jdk(11), JDK_Version::jdk(12) },
   { "SafepointSpinBeforeYield",     JDK_Version::jdk(10), JDK_Version::jdk(11), JDK_Version::jdk(12) },
   { "DeferThrSuspendLoopCount",     JDK_Version::jdk(10), JDK_Version::jdk(11), JDK_Version::jdk(12) },
   { "DeferPollingPageLoopCount",    JDK_Version::jdk(10), JDK_Version::jdk(11), JDK_Version::jdk(12) },
@@ -521,8 +520,8 @@
   // --- Deprecated alias flags (see also aliased_jvm_flags) - sorted by obsolete_in then expired_in:
   { "DefaultMaxRAMFraction",        JDK_Version::jdk(8),  JDK_Version::undefined(), JDK_Version::undefined() },
   { "CreateMinidumpOnCrash",        JDK_Version::jdk(9),  JDK_Version::undefined(), JDK_Version::undefined() },
-  { "MustCallLoadClassInternal",    JDK_Version::jdk(10), JDK_Version::undefined(), JDK_Version::undefined() },
-  { "UnsyncloadClass",              JDK_Version::jdk(10), JDK_Version::undefined(), JDK_Version::undefined() },
+  { "MustCallLoadClassInternal",    JDK_Version::jdk(10), JDK_Version::jdk(11), JDK_Version::jdk(12) },
+  { "UnsyncloadClass",              JDK_Version::jdk(10), JDK_Version::jdk(11), JDK_Version::jdk(12) },
 
   // -------------- Obsolete Flags - sorted by expired_in --------------
   { "ConvertSleepToYield",           JDK_Version::jdk(9),      JDK_Version::jdk(10), JDK_Version::jdk(11) },
@@ -531,6 +530,8 @@
   { "CheckAssertionStatusDirectives",JDK_Version::undefined(), JDK_Version::jdk(11), JDK_Version::jdk(12) },
   { "PrintMallocFree",               JDK_Version::undefined(), JDK_Version::jdk(11), JDK_Version::jdk(12) },
   { "PrintMalloc",                   JDK_Version::undefined(), JDK_Version::jdk(11), JDK_Version::jdk(12) },
+  { "ShowSafepointMsgs",             JDK_Version::undefined(), JDK_Version::jdk(11), JDK_Version::jdk(12) },
+  { "FastTLABRefill",                JDK_Version::jdk(10),     JDK_Version::jdk(11), JDK_Version::jdk(12) },
   { "PermSize",                      JDK_Version::undefined(), JDK_Version::jdk(8),  JDK_Version::undefined() },
   { "MaxPermSize",                   JDK_Version::undefined(), JDK_Version::jdk(8),  JDK_Version::undefined() },
   { "SharedReadWriteSize",           JDK_Version::undefined(), JDK_Version::jdk(10), JDK_Version::undefined() },
@@ -1826,6 +1827,13 @@
   }
 #endif
 
+#if defined(IA32)
+  // Only server compiler can optimize safepoints well enough.
+  if (!is_server_compilation_mode_vm()) {
+    FLAG_SET_ERGO_IF_DEFAULT(bool, ThreadLocalHandshakes, false);
+  }
+#endif
+
   set_conservative_max_heap_alignment();
 
 #ifndef ZERO
--- a/src/hotspot/share/runtime/atomic.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/runtime/atomic.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -131,6 +131,7 @@
                                      cmpxchg_memory_order order = memory_order_conservative);
 
 private:
+WINDOWS_ONLY(public:) // VS2017 warns (C2027) use of undefined type if IsPointerConvertible is declared private
   // Test whether From is implicitly convertible to To.
   // From and To must be pointer types.
   // Note: Provides the limited subset of C++11 std::is_convertible
--- a/src/hotspot/share/runtime/deoptimization.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/runtime/deoptimization.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -40,6 +40,7 @@
 #include "oops/objArrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "oops/fieldStreams.hpp"
+#include "oops/typeArrayOop.inline.hpp"
 #include "oops/verifyOopClosure.hpp"
 #include "prims/jvmtiThreadState.hpp"
 #include "runtime/biasedLocking.hpp"
--- a/src/hotspot/share/runtime/globals.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/runtime/globals.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -842,9 +842,6 @@
   product(bool, FailOverToOldVerifier, true,                                \
           "Fail over to old verifier when split verifier fails")            \
                                                                             \
-  develop(bool, ShowSafepointMsgs, false,                                   \
-          "Show message about safepoint synchronization")                   \
-                                                                            \
   product(bool, SafepointTimeout, false,                                    \
           "Time out and warn or fail after SafepointTimeoutDelay "          \
           "milliseconds if failed to reach safepoint")                      \
@@ -1142,11 +1139,6 @@
   diagnostic(bool, DynamicallyResizeSystemDictionaries, true,               \
           "Dynamically resize system dictionaries as needed")               \
                                                                             \
-  diagnostic(bool, UnsyncloadClass, false,                                  \
-          "Unstable: VM calls loadClass unsynchronized. Custom "            \
-          "class loader must call VM synchronized for findClass "           \
-          "and defineClass.")                                               \
-                                                                            \
   product(bool, AlwaysLockClassLoader, false,                               \
           "Require the VM to acquire the class loader lock before calling " \
           "loadClass() even for class loaders registering "                 \
@@ -1156,9 +1148,6 @@
           "Allow parallel defineClass requests for class loaders "          \
           "registering as parallel capable")                                \
                                                                             \
-  product(bool, MustCallLoadClassInternal, false,                           \
-          "Call loadClassInternal() rather than loadClass()")               \
-                                                                            \
   product_pd(bool, DontYieldALot,                                           \
           "Throw away obvious excess yield calls")                          \
                                                                             \
@@ -2012,9 +2001,6 @@
   product(bool, ZeroTLAB, false,                                            \
           "Zero out the newly created TLAB")                                \
                                                                             \
-  product(bool, FastTLABRefill, false,                                      \
-          "(Deprecated) Use fast TLAB refill code")                         \
-                                                                            \
   product(bool, TLABStats, true,                                            \
           "Provide more detailed and expensive TLAB statistics.")           \
                                                                             \
--- a/src/hotspot/share/runtime/handles.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/runtime/handles.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -97,10 +97,6 @@
   // during GC phase 3, a handle may be a forward pointer that
   // is not yet valid, so loosen the assertion
   while (bottom < top) {
-    // This test can be moved up but for now check every oop.
-
-    assert(oopDesc::is_oop(*bottom, true), "handle should point to oop");
-
     f->do_oop(bottom++);
   }
   return handles_visited;
--- a/src/hotspot/share/runtime/objectMonitor.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/runtime/objectMonitor.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -102,8 +102,6 @@
 int ObjectMonitor::Knob_VerifyInUse = 0;
 int ObjectMonitor::Knob_VerifyMatch = 0;
 int ObjectMonitor::Knob_SpinLimit   = 5000;    // derived by an external tool -
-static int Knob_LogSpins            = 0;       // enable jvmstat tally for spins
-static int Knob_HandOff             = 0;
 static int Knob_ReportSettings      = 0;
 
 static int Knob_SpinBase            = 0;       // Floor AKA SpinMin
@@ -2229,18 +2227,7 @@
 PerfCounter * ObjectMonitor::_sync_ContendedLockAttempts       = NULL;
 PerfCounter * ObjectMonitor::_sync_FutileWakeups               = NULL;
 PerfCounter * ObjectMonitor::_sync_Parks                       = NULL;
-PerfCounter * ObjectMonitor::_sync_EmptyNotifications          = NULL;
 PerfCounter * ObjectMonitor::_sync_Notifications               = NULL;
-PerfCounter * ObjectMonitor::_sync_PrivateA                    = NULL;
-PerfCounter * ObjectMonitor::_sync_PrivateB                    = NULL;
-PerfCounter * ObjectMonitor::_sync_SlowExit                    = NULL;
-PerfCounter * ObjectMonitor::_sync_SlowEnter                   = NULL;
-PerfCounter * ObjectMonitor::_sync_SlowNotify                  = NULL;
-PerfCounter * ObjectMonitor::_sync_SlowNotifyAll               = NULL;
-PerfCounter * ObjectMonitor::_sync_FailedSpins                 = NULL;
-PerfCounter * ObjectMonitor::_sync_SuccessfulSpins             = NULL;
-PerfCounter * ObjectMonitor::_sync_MonInCirculation            = NULL;
-PerfCounter * ObjectMonitor::_sync_MonScavenged                = NULL;
 PerfCounter * ObjectMonitor::_sync_Inflations                  = NULL;
 PerfCounter * ObjectMonitor::_sync_Deflations                  = NULL;
 PerfLongVariable * ObjectMonitor::_sync_MonExtant              = NULL;
@@ -2271,18 +2258,7 @@
     NEWPERFCOUNTER(_sync_ContendedLockAttempts);
     NEWPERFCOUNTER(_sync_FutileWakeups);
     NEWPERFCOUNTER(_sync_Parks);
-    NEWPERFCOUNTER(_sync_EmptyNotifications);
     NEWPERFCOUNTER(_sync_Notifications);
-    NEWPERFCOUNTER(_sync_SlowEnter);
-    NEWPERFCOUNTER(_sync_SlowExit);
-    NEWPERFCOUNTER(_sync_SlowNotify);
-    NEWPERFCOUNTER(_sync_SlowNotifyAll);
-    NEWPERFCOUNTER(_sync_FailedSpins);
-    NEWPERFCOUNTER(_sync_SuccessfulSpins);
-    NEWPERFCOUNTER(_sync_PrivateA);
-    NEWPERFCOUNTER(_sync_PrivateB);
-    NEWPERFCOUNTER(_sync_MonInCirculation);
-    NEWPERFCOUNTER(_sync_MonScavenged);
     NEWPERFVARIABLE(_sync_MonExtant);
 #undef NEWPERFCOUNTER
 #undef NEWPERFVARIABLE
@@ -2328,7 +2304,7 @@
   if (SyncKnobs == NULL) SyncKnobs = "";
 
   size_t sz = strlen(SyncKnobs);
-  char * knobs = (char *) malloc(sz + 2);
+  char * knobs = (char *) os::malloc(sz + 2, mtInternal);
   if (knobs == NULL) {
     vm_exit_out_of_memory(sz + 2, OOM_MALLOC_ERROR, "Parse SyncKnobs");
     guarantee(0, "invariant");
@@ -2351,7 +2327,6 @@
   SETKNOB(SpinBackOff);
   SETKNOB(CASPenalty);
   SETKNOB(OXPenalty);
-  SETKNOB(LogSpins);
   SETKNOB(SpinSetSucc);
   SETKNOB(SuccEnabled);
   SETKNOB(SuccRestrict);
@@ -2389,11 +2364,7 @@
     Knob_FixedSpin = -1;
   }
 
-  if (Knob_LogSpins == 0) {
-    ObjectMonitor::_sync_FailedSpins = NULL;
-  }
-
-  free(knobs);
+  os::free(knobs);
   OrderAccess::fence();
   InitDone = 1;
 }
--- a/src/hotspot/share/runtime/objectMonitor.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/runtime/objectMonitor.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -191,18 +191,7 @@
   static PerfCounter * _sync_ContendedLockAttempts;
   static PerfCounter * _sync_FutileWakeups;
   static PerfCounter * _sync_Parks;
-  static PerfCounter * _sync_EmptyNotifications;
   static PerfCounter * _sync_Notifications;
-  static PerfCounter * _sync_SlowEnter;
-  static PerfCounter * _sync_SlowExit;
-  static PerfCounter * _sync_SlowNotify;
-  static PerfCounter * _sync_SlowNotifyAll;
-  static PerfCounter * _sync_FailedSpins;
-  static PerfCounter * _sync_SuccessfulSpins;
-  static PerfCounter * _sync_PrivateA;
-  static PerfCounter * _sync_PrivateB;
-  static PerfCounter * _sync_MonInCirculation;
-  static PerfCounter * _sync_MonScavenged;
   static PerfCounter * _sync_Inflations;
   static PerfCounter * _sync_Deflations;
   static PerfLongVariable * _sync_MonExtant;
--- a/src/hotspot/share/runtime/os.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/runtime/os.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -93,6 +93,18 @@
   os::init_globals();
 }
 
+static time_t get_timezone(const struct tm* time_struct) {
+#if defined(_ALLBSD_SOURCE)
+  return time_struct->tm_gmtoff;
+#elif defined(_WINDOWS)
+  long zone;
+  _get_timezone(&zone);
+  return static_cast<time_t>(zone);
+#else
+  return timezone;
+#endif
+}
+
 // Fill in buffer with current local time as an ISO-8601 string.
 // E.g., yyyy-mm-ddThh:mm:ss-zzzz.
 // Returns buffer, or NULL if it failed.
@@ -137,11 +149,7 @@
       return NULL;
     }
   }
-#if defined(_ALLBSD_SOURCE)
-  const time_t zone = (time_t) time_struct.tm_gmtoff;
-#else
-  const time_t zone = timezone;
-#endif
+  const time_t zone = get_timezone(&time_struct);
 
   // If daylight savings time is in effect,
   // we are 1 hour East of our time zone
@@ -1706,7 +1714,7 @@
   } else {
     result = pd_attempt_reserve_memory_at(bytes, addr);
     if (result != NULL) {
-      MemTracker::record_virtual_memory_reserve_and_commit((address)result, bytes, CALLER_PC);
+      MemTracker::record_virtual_memory_reserve((address)result, bytes, CALLER_PC);
     }
   }
   return result;
--- a/src/hotspot/share/runtime/reflection.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/runtime/reflection.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -39,6 +39,7 @@
 #include "oops/objArrayKlass.hpp"
 #include "oops/objArrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
+#include "oops/typeArrayOop.inline.hpp"
 #include "prims/jvmtiExport.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/handles.inline.hpp"
--- a/src/hotspot/share/runtime/safepoint.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/runtime/safepoint.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -893,10 +893,6 @@
     assert(SafepointSynchronize::is_synchronizing(), "polling encountered outside safepoint synchronization");
   }
 
-  if (ShowSafepointMsgs) {
-    tty->print("handle_polling_page_exception: ");
-  }
-
   if (PrintSafepointStatistics) {
     inc_page_trap_count();
   }
@@ -1098,9 +1094,6 @@
          "polling page exception on thread not running state: %u", uint(t));
 
   // Step 1: Find the nmethod from the return address
-  if (ShowSafepointMsgs && Verbose) {
-    tty->print_cr("Polling page exception at " INTPTR_FORMAT, p2i(thread()->saved_exception_pc()));
-  }
   address real_return_addr = thread()->saved_exception_pc();
 
   CodeBlob *cb = CodeCache::find_blob(real_return_addr);
@@ -1421,32 +1414,3 @@
                 INT64_FORMAT_W(5) " ms",
                 (int64_t)(_max_vmop_time / MICROUNITS));
 }
-
-// ------------------------------------------------------------------------------------------------
-// Non-product code
-
-#ifndef PRODUCT
-
-void SafepointSynchronize::print_state() {
-  if (_state == _not_synchronized) {
-    tty->print_cr("not synchronized");
-  } else if (_state == _synchronizing || _state == _synchronized) {
-    tty->print_cr("State: %s", (_state == _synchronizing) ? "synchronizing" :
-                  "synchronized");
-
-    for (JavaThreadIteratorWithHandle jtiwh; JavaThread *cur = jtiwh.next(); ) {
-       cur->safepoint_state()->print();
-    }
-  }
-}
-
-void SafepointSynchronize::safepoint_msg(const char* format, ...) {
-  if (ShowSafepointMsgs) {
-    va_list ap;
-    va_start(ap, format);
-    tty->vprint_cr(format, ap);
-    va_end(ap);
-  }
-}
-
-#endif // !PRODUCT
--- a/src/hotspot/share/runtime/safepoint.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/runtime/safepoint.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -191,10 +191,6 @@
   static bool is_cleanup_needed();
   static void do_cleanup_tasks();
 
-  // Debugging
-  static void print_state()                                PRODUCT_RETURN;
-  static void safepoint_msg(const char* format, ...) ATTRIBUTE_PRINTF(1, 2) PRODUCT_RETURN;
-
   static void deferred_initialize_stat();
   static void print_stat_on_exit();
   inline static void inc_vmop_coalesced_count() { _coalesced_vmop_count++; }
@@ -258,15 +254,6 @@
   // Initialize
   static void create(JavaThread *thread);
   static void destroy(JavaThread *thread);
-
-  void safepoint_msg(const char* format, ...) ATTRIBUTE_PRINTF(2, 3) {
-    if (ShowSafepointMsgs) {
-      va_list ap;
-      va_start(ap, format);
-      tty->vprint_cr(format, ap);
-      va_end(ap);
-    }
-  }
 };
 
 
--- a/src/hotspot/share/runtime/serviceThread.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/runtime/serviceThread.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -29,7 +29,6 @@
 #include "runtime/mutexLocker.hpp"
 #include "runtime/os.hpp"
 #include "prims/jvmtiImpl.hpp"
-#include "services/allocationContextService.hpp"
 #include "services/diagnosticArgument.hpp"
 #include "services/diagnosticFramework.hpp"
 #include "services/gcNotifier.hpp"
@@ -105,8 +104,7 @@
       while (!(sensors_changed = LowMemoryDetector::has_pending_requests()) &&
              !(has_jvmti_events = JvmtiDeferredEventQueue::has_events()) &&
               !(has_gc_notification_event = GCNotifier::has_event()) &&
-              !(has_dcmd_notification_event = DCmdFactory::has_pending_jmx_notification()) &&
-             !(acs_notify = AllocationContextService::should_notify())) {
+              !(has_dcmd_notification_event = DCmdFactory::has_pending_jmx_notification())) {
         // wait until one of the sensors has pending requests, or there is a
         // pending JVMTI event or JMX GC notification to post
         Service_lock->wait(Mutex::_no_safepoint_check_flag);
@@ -132,10 +130,6 @@
     if(has_dcmd_notification_event) {
       DCmdFactory::send_notification(CHECK);
     }
-
-    if (acs_notify) {
-      AllocationContextService::notify(CHECK);
-    }
   }
 }
 
--- a/src/hotspot/share/runtime/sharedRuntime.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/runtime/sharedRuntime.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1922,95 +1922,27 @@
   vframeStream vfst(thread, true);
   assert(!vfst.at_end(), "Java frame must exist");
   Bytecode_checkcast cc(vfst.method(), vfst.method()->bcp_from(vfst.bci()));
-  Klass* target_klass = vfst.method()->constants()->klass_at(
-    cc.index(), thread);
-  return generate_class_cast_message(caster_klass, target_klass);
-}
-
-// The caller of class_loader_and_module_name() (or one of its callers)
-// must use a ResourceMark in order to correctly free the result.
-const char* class_loader_and_module_name(Klass* klass) {
-  const char* delim = "/";
-  size_t delim_len = strlen(delim);
-
-  const char* fqn = klass->external_name();
-  // Length of message to return; always include FQN
-  size_t msglen = strlen(fqn) + 1;
-
-  bool has_cl_name = false;
-  bool has_mod_name = false;
-  bool has_version = false;
-
-  // Use class loader name, if exists and not builtin
-  const char* class_loader_name = "";
-  ClassLoaderData* cld = klass->class_loader_data();
-  assert(cld != NULL, "class_loader_data should not be NULL");
-  if (!cld->is_builtin_class_loader_data()) {
-    // If not builtin, look for name
-    oop loader = klass->class_loader();
-    if (loader != NULL) {
-      oop class_loader_name_oop = java_lang_ClassLoader::name(loader);
-      if (class_loader_name_oop != NULL) {
-        class_loader_name = java_lang_String::as_utf8_string(class_loader_name_oop);
-        if (class_loader_name != NULL && class_loader_name[0] != '\0') {
-          has_cl_name = true;
-          msglen += strlen(class_loader_name) + delim_len;
-        }
-      }
-    }
+  constantPoolHandle cpool(thread, vfst.method()->constants());
+  Klass* target_klass = ConstantPool::klass_at_if_loaded(cpool, cc.index());
+  Symbol* target_klass_name = NULL;
+  if (target_klass == NULL) {
+    // This klass should be resolved, but just in case, get the name in the klass slot.
+    target_klass_name = cpool->klass_name_at(cc.index());
   }
-
-  const char* module_name = "";
-  const char* version = "";
-  Klass* bottom_klass = klass->is_objArray_klass() ?
-    ObjArrayKlass::cast(klass)->bottom_klass() : klass;
-  if (bottom_klass->is_instance_klass()) {
-    ModuleEntry* module = InstanceKlass::cast(bottom_klass)->module();
-    // Use module name, if exists
-    if (module->is_named()) {
-      has_mod_name = true;
-      module_name = module->name()->as_C_string();
-      msglen += strlen(module_name);
-      // Use version if exists and is not a jdk module
-      if (module->is_non_jdk_module() && module->version() != NULL) {
-        has_version = true;
-        version = module->version()->as_C_string();
-        msglen += strlen("@") + strlen(version);
-      }
-    }
-  } else {
-    // klass is an array of primitives, so its module is java.base
-    module_name = JAVA_BASE_NAME;
-  }
-
-  if (has_cl_name || has_mod_name) {
-    msglen += delim_len;
-  }
-
-  char* message = NEW_RESOURCE_ARRAY_RETURN_NULL(char, msglen);
-
-  // Just return the FQN if error in allocating string
-  if (message == NULL) {
-    return fqn;
-  }
-
-  jio_snprintf(message, msglen, "%s%s%s%s%s%s%s",
-               class_loader_name,
-               (has_cl_name) ? delim : "",
-               (has_mod_name) ? module_name : "",
-               (has_version) ? "@" : "",
-               (has_version) ? version : "",
-               (has_cl_name || has_mod_name) ? delim : "",
-               fqn);
-  return message;
+  return generate_class_cast_message(caster_klass, target_klass, target_klass_name);
 }
 
+
+// The caller of generate_class_cast_message() (or one of its callers)
+// must use a ResourceMark in order to correctly free the result.
 char* SharedRuntime::generate_class_cast_message(
-    Klass* caster_klass, Klass* target_klass) {
-
-  const char* caster_name = class_loader_and_module_name(caster_klass);
-
-  const char* target_name = class_loader_and_module_name(target_klass);
+    Klass* caster_klass, Klass* target_klass, Symbol* target_klass_name) {
+
+  const char* caster_name = caster_klass->class_loader_and_module_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() :
+                                                   target_klass->class_loader_and_module_name();
 
   size_t msglen = strlen(caster_name) + strlen(" cannot be cast to ") + strlen(target_name) + 1;
 
--- a/src/hotspot/share/runtime/sharedRuntime.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/runtime/sharedRuntime.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -318,7 +318,7 @@
   // The caller (or one of it's callers) must use a ResourceMark
   // in order to correctly free the result.
   //
-  static char* generate_class_cast_message(Klass* caster_klass, Klass* target_klass);
+  static char* generate_class_cast_message(Klass* caster_klass, Klass* target_klass, Symbol* target_klass_name = NULL);
 
   // Resolves a call site- may patch in the destination of the call into the
   // compiled code.
--- a/src/hotspot/share/runtime/synchronizer.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/runtime/synchronizer.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -184,8 +184,6 @@
 // have to pass through, and we must also be able to deal with
 // asynchronous exceptions. The caller is responsible for checking
 // the threads pending exception if needed.
-// doLock was added to support classloading with UnsyncloadClass which
-// requires flag based choice of locking the classloader lock.
 class ObjectLocker : public StackObj {
  private:
   Thread*   _thread;
--- a/src/hotspot/share/runtime/thread.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/runtime/thread.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -51,6 +51,7 @@
 #include "oops/objArrayOop.hpp"
 #include "oops/oop.inline.hpp"
 #include "oops/symbol.hpp"
+#include "oops/typeArrayOop.inline.hpp"
 #include "oops/verifyOopClosure.hpp"
 #include "prims/jvm_misc.hpp"
 #include "prims/jvmtiExport.hpp"
@@ -1997,7 +1998,7 @@
   // We must flush any deferred card marks and other various GC barrier
   // related buffers (e.g. G1 SATB buffer and G1 dirty card queue buffer)
   // before removing a thread from the list of active threads.
-  BarrierSet::barrier_set()->flush_deferred_barriers(this);
+  BarrierSet::barrier_set()->on_thread_detach(this);
 
   log_info(os, thread)("JavaThread %s (tid: " UINTX_FORMAT ").",
     exit_type == JavaThread::normal_exit ? "exiting" : "detaching",
@@ -2026,36 +2027,6 @@
   }
 }
 
-#if INCLUDE_ALL_GCS
-// Flush G1-related queues.
-void JavaThread::flush_barrier_queues() {
-  satb_mark_queue().flush();
-  dirty_card_queue().flush();
-}
-
-void JavaThread::initialize_queues() {
-  assert(!SafepointSynchronize::is_at_safepoint(),
-         "we should not be at a safepoint");
-
-  SATBMarkQueue& satb_queue = satb_mark_queue();
-  SATBMarkQueueSet& satb_queue_set = satb_mark_queue_set();
-  // The SATB queue should have been constructed with its active
-  // field set to false.
-  assert(!satb_queue.is_active(), "SATB queue should not be active");
-  assert(satb_queue.is_empty(), "SATB queue should be empty");
-  // If we are creating the thread during a marking cycle, we should
-  // set the active field of the SATB queue to true.
-  if (satb_queue_set.is_active()) {
-    satb_queue.set_active(true);
-  }
-
-  DirtyCardQueue& dirty_queue = dirty_card_queue();
-  // The dirty card queue should have been constructed with its
-  // active field set to true.
-  assert(dirty_queue.is_active(), "dirty card queue should be active");
-}
-#endif // INCLUDE_ALL_GCS
-
 void JavaThread::cleanup_failed_attach_current_thread() {
   if (active_handles() != NULL) {
     JNIHandleBlock* block = active_handles();
@@ -2076,19 +2047,12 @@
     tlab().make_parsable(true);  // retire TLAB, if any
   }
 
-#if INCLUDE_ALL_GCS
-  if (UseG1GC) {
-    flush_barrier_queues();
-  }
-#endif // INCLUDE_ALL_GCS
+  BarrierSet::barrier_set()->on_thread_detach(this);
 
   Threads::remove(this);
   this->smr_delete();
 }
 
-
-
-
 JavaThread* JavaThread::active() {
   Thread* thread = Thread::current();
   if (thread->is_Java_thread()) {
@@ -4341,9 +4305,8 @@
   // The threads lock must be owned at this point
   assert_locked_or_safepoint(Threads_lock);
 
-  // See the comment for this method in thread.hpp for its purpose and
-  // why it is called here.
-  p->initialize_queues();
+  BarrierSet::barrier_set()->on_thread_attach(p);
+
   p->set_next(_thread_list);
   _thread_list = p;
 
--- a/src/hotspot/share/runtime/thread.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/runtime/thread.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -1075,8 +1075,6 @@
   DirtyCardQueue _dirty_card_queue;      // Thread-local log for dirty cards.
   // Set of all such queues.
   static DirtyCardQueueSet _dirty_card_queue_set;
-
-  void flush_barrier_queues();
 #endif // INCLUDE_ALL_GCS
 
   friend class VMThread;
@@ -1968,29 +1966,6 @@
   }
 #endif // INCLUDE_ALL_GCS
 
-  // This method initializes the SATB and dirty card queues before a
-  // JavaThread is added to the Java thread list. Right now, we don't
-  // have to do anything to the dirty card queue (it should have been
-  // activated when the thread was created), but we have to activate
-  // the SATB queue if the thread is created while a marking cycle is
-  // in progress. The activation / de-activation of the SATB queues at
-  // the beginning / end of a marking cycle is done during safepoints
-  // so we have to make sure this method is called outside one to be
-  // able to safely read the active field of the SATB queue set. Right
-  // now, it is called just before the thread is added to the Java
-  // thread list in the Threads::add() method. That method is holding
-  // the Threads_lock which ensures we are outside a safepoint. We
-  // cannot do the obvious and set the active field of the SATB queue
-  // when the thread is created given that, in some cases, safepoints
-  // might happen between the JavaThread constructor being called and the
-  // thread being added to the Java thread list (an example of this is
-  // when the structure for the DestroyJavaVM thread is created).
-#if INCLUDE_ALL_GCS
-  void initialize_queues();
-#else  // INCLUDE_ALL_GCS
-  void initialize_queues() { }
-#endif // INCLUDE_ALL_GCS
-
   // Machine dependent stuff
 #include OS_CPU_HEADER(thread)
 
--- a/src/hotspot/share/runtime/vmStructs.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/runtime/vmStructs.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -514,9 +514,8 @@
                                                                                                                                      \
   nonstatic_field(GenCollectedHeap,            _young_gen,                                    Generation*)                           \
   nonstatic_field(GenCollectedHeap,            _old_gen,                                      Generation*)                           \
-                                                                                                                                     \
-  nonstatic_field(GenCollectorPolicy,          _young_gen_spec,                               GenerationSpec*)                       \
-  nonstatic_field(GenCollectorPolicy,          _old_gen_spec,                                 GenerationSpec*)                       \
+  nonstatic_field(GenCollectedHeap,            _young_gen_spec,                               GenerationSpec*)                       \
+  nonstatic_field(GenCollectedHeap,            _old_gen_spec,                                 GenerationSpec*)                       \
                                                                                                                                      \
   nonstatic_field(HeapWord,                    i,                                             char*)                                 \
                                                                                                                                      \
@@ -1470,7 +1469,6 @@
            declare_type(DefNewGeneration,             Generation)         \
            declare_type(CardGeneration,               Generation)         \
            declare_type(TenuredGeneration,            CardGeneration)     \
-  declare_toplevel_type(GenCollectorPolicy)                               \
   declare_toplevel_type(Space)                                            \
            declare_type(CompactibleSpace,             Space)              \
            declare_type(ContiguousSpace,              CompactibleSpace)   \
--- a/src/hotspot/share/services/allocationContextService.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2014, 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_SERVICES_ALLOCATION_CONTEXT_SERVICE_HPP
-#define SHARE_VM_SERVICES_ALLOCATION_CONTEXT_SERVICE_HPP
-
-#include "utilities/exceptions.hpp"
-
-class AllocationContextService: public AllStatic {
-public:
-  static inline bool should_notify();
-  static inline void notify(TRAPS);
-};
-
-bool AllocationContextService::should_notify() { return false; }
-void AllocationContextService::notify(TRAPS) { }
-
-#endif // SHARE_VM_SERVICES_ALLOCATION_CONTEXT_SERVICE_HPP
--- a/src/hotspot/share/services/attachListener.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/services/attachListener.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -28,6 +28,7 @@
 #include "gc/shared/vmGCOperations.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/oop.inline.hpp"
+#include "oops/typeArrayOop.inline.hpp"
 #include "prims/jvmtiExport.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/globals.hpp"
--- a/src/hotspot/share/services/diagnosticCommand.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/services/diagnosticCommand.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -31,6 +31,7 @@
 #include "gc/shared/vmGCOperations.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/oop.inline.hpp"
+#include "oops/typeArrayOop.inline.hpp"
 #include "runtime/globals.hpp"
 #include "runtime/javaCalls.hpp"
 #include "runtime/os.hpp"
@@ -88,6 +89,7 @@
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassHierarchyDCmd>(full_export, true, false));
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<SymboltableDCmd>(full_export, true, false));
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<StringtableDCmd>(full_export, true, false));
+  DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<MetaspaceDCmd>(full_export, true, false));
 #if INCLUDE_JVMTI // Both JVMTI and SERVICES have to be enabled to have this dcmd
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JVMTIAgentLoadDCmd>(full_export, true, false));
 #endif // INCLUDE_JVMTI
--- a/src/hotspot/share/services/diagnosticCommand.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/services/diagnosticCommand.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -839,4 +839,25 @@
   virtual void execute(DCmdSource source, TRAPS);
 };
 
+class MetaspaceDCmd : public DCmd {
+public:
+  MetaspaceDCmd(outputStream* output, bool heap);
+  static const char* name() {
+    return "VM.metaspace";
+  }
+  static const char* description() {
+    return "Prints the statistics for the metaspace";
+  }
+  static const char* impact() {
+      return "Medium: Depends on number of classes loaded.";
+  }
+  static const JavaPermission permission() {
+    JavaPermission p = {"java.lang.management.ManagementPermission",
+                        "monitor", NULL};
+    return p;
+  }
+  static int num_arguments() { return 0; }
+  virtual void execute(DCmdSource source, TRAPS);
+};
+
 #endif // SHARE_VM_SERVICES_DIAGNOSTICCOMMAND_HPP
--- a/src/hotspot/share/services/heapDumper.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/services/heapDumper.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -35,6 +35,7 @@
 #include "oops/objArrayKlass.hpp"
 #include "oops/objArrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
+#include "oops/typeArrayOop.inline.hpp"
 #include "runtime/javaCalls.hpp"
 #include "runtime/jniHandles.hpp"
 #include "runtime/os.hpp"
--- a/src/hotspot/share/services/management.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/services/management.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -33,6 +33,7 @@
 #include "oops/objArrayKlass.hpp"
 #include "oops/objArrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
+#include "oops/typeArrayOop.inline.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/globals.hpp"
 #include "runtime/handles.inline.hpp"
--- a/src/hotspot/share/services/memReporter.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/services/memReporter.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -291,7 +291,7 @@
   outputStream* out = output();
   const char* scale = current_scale();
   const NativeCallStack*  stack = reserved_rgn->call_stack();
-  bool all_committed = reserved_rgn->all_committed();
+  bool all_committed = reserved_rgn->size() == reserved_rgn->committed_size();
   const char* region_type = (all_committed ? "reserved and committed" : "reserved");
   out->print_cr(" ");
   print_virtual_memory_region(region_type, reserved_rgn->base(), reserved_rgn->size());
@@ -303,7 +303,17 @@
     stack->print_on(out, 4);
   }
 
-  if (all_committed) return;
+  if (all_committed) {
+    CommittedRegionIterator itr = reserved_rgn->iterate_committed_regions();
+    const CommittedMemoryRegion* committed_rgn = itr.next();
+    if (committed_rgn->size() == reserved_rgn->size() && committed_rgn->call_stack()->equals(*stack)) {
+      // One region spanning the entire reserved region, with the same stack trace.
+      // Don't print this regions because the "reserved and committed" line above
+      // already indicates that the region is comitted.
+      assert(itr.next() == NULL, "Unexpectedly more than one regions");
+      return;
+    }
+  }
 
   CommittedRegionIterator itr = reserved_rgn->iterate_committed_regions();
   const CommittedMemoryRegion* committed_rgn;
@@ -745,4 +755,3 @@
 
   out->print_cr(")\n");
  }
-
--- a/src/hotspot/share/services/memTracker.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/services/memTracker.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -113,6 +113,8 @@
 };
 
 class MemTracker : AllStatic {
+  friend class VirtualMemoryTrackerTest;
+
  public:
   static inline NMT_TrackingLevel tracking_level() {
     if (_tracking_level == NMT_unknown) {
@@ -215,8 +217,7 @@
     if (addr != NULL) {
       ThreadCritical tc;
       if (tracking_level() < NMT_summary) return;
-      VirtualMemoryTracker::add_reserved_region((address)addr, size,
-        stack, flag, true);
+      VirtualMemoryTracker::add_reserved_region((address)addr, size, stack, flag);
       VirtualMemoryTracker::add_committed_region((address)addr, size, stack);
     }
   }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/services/metaspaceDCmd.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -0,0 +1,36 @@
+/*
+ * 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
+ * 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.
+ *
+ */
+#include "precompiled.hpp"
+#include "memory/metaspace.hpp"
+#include "services/diagnosticCommand.hpp"
+
+MetaspaceDCmd::MetaspaceDCmd(outputStream* output, bool heap): DCmd(output, heap) {
+}
+
+void MetaspaceDCmd::execute(DCmdSource source, TRAPS) {
+  const size_t scale = 1 * K;
+  VM_PrintMetadata op(output(), scale);
+  VMThread::execute(&op);
+}
+
--- a/src/hotspot/share/services/nmtDCmd.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/services/nmtDCmd.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -40,8 +40,6 @@
   _detail("detail", "request runtime to report memory allocation >= "
            "1K by each callsite.",
            "BOOLEAN", false, "false"),
-  _metadata("metadata", "request runtime to report metadata information",
-           "BOOLEAN", false, "false"),
   _baseline("baseline", "request runtime to baseline current memory usage, " \
             "so it can be compared against in later time.",
             "BOOLEAN", false, "false"),
@@ -61,7 +59,6 @@
        "STRING", false, "KB") {
   _dcmdparser.add_dcmd_option(&_summary);
   _dcmdparser.add_dcmd_option(&_detail);
-  _dcmdparser.add_dcmd_option(&_metadata);
   _dcmdparser.add_dcmd_option(&_baseline);
   _dcmdparser.add_dcmd_option(&_summary_diff);
   _dcmdparser.add_dcmd_option(&_detail_diff);
@@ -97,7 +94,6 @@
   int nopt = 0;
   if (_summary.is_set() && _summary.value()) { ++nopt; }
   if (_detail.is_set() && _detail.value()) { ++nopt; }
-  if (_metadata.is_set() && _metadata.value()) { ++nopt; }
   if (_baseline.is_set() && _baseline.value()) { ++nopt; }
   if (_summary_diff.is_set() && _summary_diff.value()) { ++nopt; }
   if (_detail_diff.is_set() && _detail_diff.value()) { ++nopt; }
@@ -127,10 +123,6 @@
       return;
     }
     report(false, scale_unit);
-  } else if (_metadata.value()) {
-      size_t scale = get_scale(_scale.value());
-      VM_PrintMetadata op(output(), scale);
-      VMThread::execute(&op);
   } else if (_baseline.value()) {
     MemBaseline& baseline = MemTracker::get_baseline();
     if (!baseline.baseline(MemTracker::tracking_level() != NMT_detail)) {
--- a/src/hotspot/share/services/nmtDCmd.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/services/nmtDCmd.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -39,7 +39,6 @@
  protected:
   DCmdArgument<bool>  _summary;
   DCmdArgument<bool>  _detail;
-  DCmdArgument<bool>  _metadata;
   DCmdArgument<bool>  _baseline;
   DCmdArgument<bool>  _summary_diff;
   DCmdArgument<bool>  _detail_diff;
--- a/src/hotspot/share/services/serviceUtil.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/services/serviceUtil.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -63,6 +63,7 @@
           return true;
         }
       }
+      fatal("visible_oop: should never reach here #1");
       return false;
     }
     // object arrays are visible if they aren't system object arrays
@@ -74,6 +75,7 @@
       return true;
     }
     // everything else (Method*s, ...) aren't visible
+    fatal("visible_oop: should never reach here #2");
     return false;
   };   // end of visible_oop()
 
--- a/src/hotspot/share/services/virtualMemoryTracker.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/services/virtualMemoryTracker.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -48,57 +48,105 @@
   return r1.compare(r2);
 }
 
+static bool is_mergeable_with(CommittedMemoryRegion* rgn, address addr, size_t size, const NativeCallStack& stack) {
+  return rgn->adjacent_to(addr, size) && rgn->call_stack()->equals(stack);
+}
+
+static bool is_same_as(CommittedMemoryRegion* rgn, address addr, size_t size, const NativeCallStack& stack) {
+  // It would have made sense to use rgn->equals(...), but equals returns true for overlapping regions.
+  return rgn->same_region(addr, size) && rgn->call_stack()->equals(stack);
+}
+
+static LinkedListNode<CommittedMemoryRegion>* find_preceding_node_from(LinkedListNode<CommittedMemoryRegion>* from, address addr) {
+  LinkedListNode<CommittedMemoryRegion>* preceding = NULL;
+
+  for (LinkedListNode<CommittedMemoryRegion>* node = from; node != NULL; node = node->next()) {
+    CommittedMemoryRegion* rgn = node->data();
+
+    // We searched past the region start.
+    if (rgn->end() > addr) {
+      break;
+    }
+
+    preceding = node;
+  }
+
+  return preceding;
+}
+
+static bool try_merge_with(LinkedListNode<CommittedMemoryRegion>* node, address addr, size_t size, const NativeCallStack& stack) {
+  if (node != NULL) {
+    CommittedMemoryRegion* rgn = node->data();
+
+    if (is_mergeable_with(rgn, addr, size, stack)) {
+      rgn->expand_region(addr, size);
+      return true;
+    }
+  }
+
+  return false;
+}
+
+static bool try_merge_with(LinkedListNode<CommittedMemoryRegion>* node, LinkedListNode<CommittedMemoryRegion>* other) {
+  if (other == NULL) {
+    return false;
+  }
+
+  CommittedMemoryRegion* rgn = other->data();
+  return try_merge_with(node, rgn->base(), rgn->size(), *rgn->call_stack());
+}
+
 bool ReservedMemoryRegion::add_committed_region(address addr, size_t size, const NativeCallStack& stack) {
   assert(addr != NULL, "Invalid address");
   assert(size > 0, "Invalid size");
   assert(contain_region(addr, size), "Not contain this region");
 
-  if (all_committed()) return true;
+  // Find the region that fully precedes the [addr, addr + size) region.
+  LinkedListNode<CommittedMemoryRegion>* prev = find_preceding_node_from(_committed_regions.head(), addr);
+  LinkedListNode<CommittedMemoryRegion>* next = (prev != NULL ? prev->next() : _committed_regions.head());
 
-  CommittedMemoryRegion committed_rgn(addr, size, stack);
-  LinkedListNode<CommittedMemoryRegion>* node = _committed_regions.head();
-
-  while (node != NULL) {
-    CommittedMemoryRegion* rgn = node->data();
-    if (rgn->same_region(addr, size)) {
+  if (next != NULL) {
+    // Ignore request if region already exists.
+    if (is_same_as(next->data(), addr, size, stack)) {
       return true;
     }
 
-    if (rgn->adjacent_to(addr, size)) {
-      // special case to expand prior region if there is no next region
-      LinkedListNode<CommittedMemoryRegion>* next = node->next();
-      if (next == NULL && rgn->call_stack()->equals(stack)) {
-        VirtualMemorySummary::record_uncommitted_memory(rgn->size(), flag());
-        // the two adjacent regions have the same call stack, merge them
-        rgn->expand_region(addr, size);
-        VirtualMemorySummary::record_committed_memory(rgn->size(), flag());
-        return true;
-      }
-      }
+    // The new region is after prev, and either overlaps with the
+    // next region (and maybe more regions), or overlaps with no region.
+    if (next->data()->overlap_region(addr, size)) {
+      // Remove _all_ overlapping regions, and parts of regions,
+      // in preparation for the addition of this new region.
+      remove_uncommitted_region(addr, size);
 
-    if (rgn->overlap_region(addr, size)) {
-      // Clear a space for this region in the case it overlaps with any regions.
-      remove_uncommitted_region(addr, size);
-      break;  // commit below
+      // The remove could have split a region into two and created a
+      // new prev region. Need to reset the prev and next pointers.
+      prev = find_preceding_node_from((prev != NULL ? prev : _committed_regions.head()), addr);
+      next = (prev != NULL ? prev->next() : _committed_regions.head());
     }
-    if (rgn->end() >= addr + size){
-      break;
-    }
-    node = node->next();
   }
 
-    // New committed region
-    VirtualMemorySummary::record_committed_memory(size, flag());
-    return add_committed_region(committed_rgn);
+  // At this point the previous overlapping regions have been
+  // cleared, and the full region is guaranteed to be inserted.
+  VirtualMemorySummary::record_committed_memory(size, flag());
+
+  // Try to merge with prev and possibly next.
+  if (try_merge_with(prev, addr, size, stack)) {
+    if (try_merge_with(prev, next)) {
+      // prev was expanded to contain the new region
+      // and next, need to remove next from the list
+      _committed_regions.remove_after(prev);
+    }
+
+    return true;
   }
 
-void ReservedMemoryRegion::set_all_committed(bool b) {
-  if (all_committed() != b) {
-    _all_committed = b;
-    if (b) {
-      VirtualMemorySummary::record_committed_memory(size(), flag());
-    }
+  // Didn't merge with prev, try with next.
+  if (try_merge_with(next, addr, size, stack)) {
+    return true;
   }
+
+  // Couldn't merge with any regions - create a new region.
+  return add_committed_region(CommittedMemoryRegion(addr, size, stack));
 }
 
 bool ReservedMemoryRegion::remove_uncommitted_region(LinkedListNode<CommittedMemoryRegion>* node,
@@ -135,94 +183,57 @@
 }
 
 bool ReservedMemoryRegion::remove_uncommitted_region(address addr, size_t sz) {
-  // uncommit stack guard pages
-  if (flag() == mtThreadStack && !same_region(addr, sz)) {
-    return true;
-  }
-
   assert(addr != NULL, "Invalid address");
   assert(sz > 0, "Invalid size");
 
-  if (all_committed()) {
-    assert(_committed_regions.is_empty(), "Sanity check");
-    assert(contain_region(addr, sz), "Reserved region does not contain this region");
-    set_all_committed(false);
-    VirtualMemorySummary::record_uncommitted_memory(sz, flag());
-    if (same_region(addr, sz)) {
+  CommittedMemoryRegion del_rgn(addr, sz, *call_stack());
+  address end = addr + sz;
+
+  LinkedListNode<CommittedMemoryRegion>* head = _committed_regions.head();
+  LinkedListNode<CommittedMemoryRegion>* prev = NULL;
+  CommittedMemoryRegion* crgn;
+
+  while (head != NULL) {
+    crgn = head->data();
+
+    if (crgn->same_region(addr, sz)) {
+      VirtualMemorySummary::record_uncommitted_memory(crgn->size(), flag());
+      _committed_regions.remove_after(prev);
       return true;
-    } else {
-      CommittedMemoryRegion rgn(base(), size(), *call_stack());
-      if (rgn.base() == addr || rgn.end() == (addr + sz)) {
-        rgn.exclude_region(addr, sz);
-        return add_committed_region(rgn);
+    }
+
+    // del_rgn contains crgn
+    if (del_rgn.contain_region(crgn->base(), crgn->size())) {
+      VirtualMemorySummary::record_uncommitted_memory(crgn->size(), flag());
+      head = head->next();
+      _committed_regions.remove_after(prev);
+      continue;  // don't update head or prev
+    }
+
+    // Found addr in the current crgn. There are 2 subcases:
+    if (crgn->contain_address(addr)) {
+
+      // (1) Found addr+size in current crgn as well. (del_rgn is contained in crgn)
+      if (crgn->contain_address(end - 1)) {
+        VirtualMemorySummary::record_uncommitted_memory(sz, flag());
+        return remove_uncommitted_region(head, addr, sz); // done!
       } else {
-        // split this region
-        // top of the whole region
-        address top =rgn.end();
-        // use this region for lower part
-        size_t exclude_size = rgn.end() - addr;
-        rgn.exclude_region(addr, exclude_size);
-        if (add_committed_region(rgn)) {
-          // higher part
-          address high_base = addr + sz;
-          size_t  high_size = top - high_base;
-          CommittedMemoryRegion high_rgn(high_base, high_size, NativeCallStack::EMPTY_STACK);
-          return add_committed_region(high_rgn);
-        } else {
-          return false;
-        }
-      }
-    }
-  } else {
-    CommittedMemoryRegion del_rgn(addr, sz, *call_stack());
-    address end = addr + sz;
-
-    LinkedListNode<CommittedMemoryRegion>* head = _committed_regions.head();
-    LinkedListNode<CommittedMemoryRegion>* prev = NULL;
-    CommittedMemoryRegion* crgn;
-
-    while (head != NULL) {
-      crgn = head->data();
-
-      if (crgn->same_region(addr, sz)) {
-        VirtualMemorySummary::record_uncommitted_memory(crgn->size(), flag());
-          _committed_regions.remove_after(prev);
-          return true;
+        // (2) Did not find del_rgn's end in crgn.
+        size_t size = crgn->end() - del_rgn.base();
+        crgn->exclude_region(addr, size);
+        VirtualMemorySummary::record_uncommitted_memory(size, flag());
       }
 
-      // del_rgn contains crgn
-      if (del_rgn.contain_region(crgn->base(), crgn->size())) {
-          VirtualMemorySummary::record_uncommitted_memory(crgn->size(), flag());
-          head = head->next();
-          _committed_regions.remove_after(prev);
-        continue;  // don't update head or prev
-        }
-
-      // Found addr in the current crgn. There are 2 subcases:
-      if (crgn->contain_address(addr)) {
+    } else if (crgn->contain_address(end - 1)) {
+      // Found del_rgn's end, but not its base addr.
+      size_t size = del_rgn.end() - crgn->base();
+      crgn->exclude_region(crgn->base(), size);
+      VirtualMemorySummary::record_uncommitted_memory(size, flag());
+      return true;  // should be done if the list is sorted properly!
+    }
 
-        // (1) Found addr+size in current crgn as well. (del_rgn is contained in crgn)
-        if (crgn->contain_address(end - 1)) {
-          VirtualMemorySummary::record_uncommitted_memory(sz, flag());
-          return remove_uncommitted_region(head, addr, sz); // done!
-        } else {
-          // (2) Did not find del_rgn's end in crgn.
-          size_t size = crgn->end() - del_rgn.base();
-          crgn->exclude_region(addr, size);
-          VirtualMemorySummary::record_uncommitted_memory(size, flag());
-      }
-
-      } else if (crgn->contain_address(end - 1)) {
-      // Found del_rgn's end, but not its base addr.
-        size_t size = del_rgn.end() - crgn->base();
-        crgn->exclude_region(crgn->base(), size);
-        VirtualMemorySummary::record_uncommitted_memory(size, flag());
-        return true;  // should be done if the list is sorted properly!
-      }
-
-      prev = head;
-      head = head->next();
-    }
+    prev = head;
+    head = head->next();
   }
 
   return true;
@@ -256,18 +267,14 @@
 }
 
 size_t ReservedMemoryRegion::committed_size() const {
-  if (all_committed()) {
-    return size();
-  } else {
-    size_t committed = 0;
-    LinkedListNode<CommittedMemoryRegion>* head =
-      _committed_regions.head();
-    while (head != NULL) {
-      committed += head->data()->size();
-      head = head->next();
-    }
-    return committed;
+  size_t committed = 0;
+  LinkedListNode<CommittedMemoryRegion>* head =
+    _committed_regions.head();
+  while (head != NULL) {
+    committed += head->data()->size();
+    head = head->next();
   }
+  return committed;
 }
 
 void ReservedMemoryRegion::set_flag(MEMFLAGS f) {
@@ -296,22 +303,16 @@
 }
 
 bool VirtualMemoryTracker::add_reserved_region(address base_addr, size_t size,
-   const NativeCallStack& stack, MEMFLAGS flag, bool all_committed) {
+    const NativeCallStack& stack, MEMFLAGS flag) {
   assert(base_addr != NULL, "Invalid address");
   assert(size > 0, "Invalid size");
   assert(_reserved_regions != NULL, "Sanity check");
   ReservedMemoryRegion  rgn(base_addr, size, stack, flag);
   ReservedMemoryRegion* reserved_rgn = _reserved_regions->find(rgn);
-  LinkedListNode<ReservedMemoryRegion>* node;
+
   if (reserved_rgn == NULL) {
     VirtualMemorySummary::record_reserved_memory(size, flag);
-    node = _reserved_regions->add(rgn);
-    if (node != NULL) {
-      node->data()->set_all_committed(all_committed);
-      return true;
-    } else {
-      return false;
-    }
+    return _reserved_regions->add(rgn) != NULL;
   } else {
     if (reserved_rgn->same_region(base_addr, size)) {
       reserved_rgn->set_call_stack(stack);
--- a/src/hotspot/share/services/virtualMemoryTracker.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/services/virtualMemoryTracker.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -210,6 +210,8 @@
 
 
   inline bool overlap_region(address addr, size_t sz) const {
+    assert(sz > 0, "Invalid size");
+    assert(size() > 0, "Invalid size");
     VirtualMemoryRegion rgn(addr, sz);
     return contain_address(addr) ||
            contain_address(addr + sz - 1) ||
@@ -295,18 +297,14 @@
   NativeCallStack  _stack;
   MEMFLAGS         _flag;
 
-  bool             _all_committed;
-
  public:
   ReservedMemoryRegion(address base, size_t size, const NativeCallStack& stack,
     MEMFLAGS flag = mtNone) :
-    VirtualMemoryRegion(base, size), _stack(stack), _flag(flag),
-    _all_committed(false) { }
+    VirtualMemoryRegion(base, size), _stack(stack), _flag(flag) { }
 
 
   ReservedMemoryRegion(address base, size_t size) :
-    VirtualMemoryRegion(base, size), _stack(NativeCallStack::EMPTY_STACK), _flag(mtNone),
-    _all_committed(false) { }
+    VirtualMemoryRegion(base, size), _stack(NativeCallStack::EMPTY_STACK), _flag(mtNone) { }
 
   // Copy constructor
   ReservedMemoryRegion(const ReservedMemoryRegion& rr) :
@@ -347,9 +345,6 @@
   // the new region
   void    move_committed_regions(address addr, ReservedMemoryRegion& rgn);
 
-  inline bool all_committed() const { return _all_committed; }
-  void        set_all_committed(bool b);
-
   CommittedRegionIterator iterate_committed_regions() const {
     return CommittedRegionIterator(_committed_regions.head());
   }
@@ -360,17 +355,14 @@
 
     _stack =         *other.call_stack();
     _flag  =         other.flag();
-    _all_committed = other.all_committed();
-    if (other.all_committed()) {
-      set_all_committed(true);
-    } else {
-      CommittedRegionIterator itr = other.iterate_committed_regions();
-      const CommittedMemoryRegion* rgn = itr.next();
-      while (rgn != NULL) {
-        _committed_regions.add(*rgn);
-        rgn = itr.next();
-      }
+
+    CommittedRegionIterator itr = other.iterate_committed_regions();
+    const CommittedMemoryRegion* rgn = itr.next();
+    while (rgn != NULL) {
+      _committed_regions.add(*rgn);
+      rgn = itr.next();
     }
+
     return *this;
   }
 
@@ -396,14 +388,15 @@
 
 // Main class called from MemTracker to track virtual memory allocations, commits and releases.
 class VirtualMemoryTracker : AllStatic {
+  friend class VirtualMemoryTrackerTest;
+
  public:
   static bool initialize(NMT_TrackingLevel level);
 
   // Late phase initialization
   static bool late_initialize(NMT_TrackingLevel level);
 
-  static bool add_reserved_region (address base_addr, size_t size, const NativeCallStack& stack,
-    MEMFLAGS flag = mtNone, bool all_committed = false);
+  static bool add_reserved_region (address base_addr, size_t size, const NativeCallStack& stack, MEMFLAGS flag = mtNone);
 
   static bool add_committed_region      (address base_addr, size_t size, const NativeCallStack& stack);
   static bool remove_uncommitted_region (address base_addr, size_t size);
--- a/src/hotspot/share/utilities/copy.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/utilities/copy.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -27,6 +27,7 @@
 
 #include "runtime/stubRoutines.hpp"
 #include "utilities/align.hpp"
+#include "utilities/debug.hpp"
 #include "utilities/macros.hpp"
 
 // Assembly code for platforms that need it.
@@ -88,20 +89,20 @@
 
   // Word-aligned words,    conjoint, not atomic on each word
   static void conjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
-    assert_params_ok(from, to, LogHeapWordSize);
+    assert_params_ok(from, to, HeapWordSize);
     pd_conjoint_words(from, to, count);
   }
 
   // Word-aligned words,    disjoint, not atomic on each word
   static void disjoint_words(const HeapWord* from, HeapWord* to, size_t count) {
-    assert_params_ok(from, to, LogHeapWordSize);
+    assert_params_ok(from, to, HeapWordSize);
     assert_disjoint(from, to, count);
     pd_disjoint_words(from, to, count);
   }
 
   // Word-aligned words,    disjoint, atomic on each word
   static void disjoint_words_atomic(const HeapWord* from, HeapWord* to, size_t count) {
-    assert_params_ok(from, to, LogHeapWordSize);
+    assert_params_ok(from, to, HeapWordSize);
     assert_disjoint(from, to, count);
     pd_disjoint_words_atomic(from, to, count);
   }
@@ -133,32 +134,32 @@
 
   // jshorts,               conjoint, atomic on each jshort
   static void conjoint_jshorts_atomic(const jshort* from, jshort* to, size_t count) {
-    assert_params_ok(from, to, LogBytesPerShort);
+    assert_params_ok(from, to, BytesPerShort);
     pd_conjoint_jshorts_atomic(from, to, count);
   }
 
   // jints,                 conjoint, atomic on each jint
   static void conjoint_jints_atomic(const jint* from, jint* to, size_t count) {
-    assert_params_ok(from, to, LogBytesPerInt);
+    assert_params_ok(from, to, BytesPerInt);
     pd_conjoint_jints_atomic(from, to, count);
   }
 
   // jlongs,                conjoint, atomic on each jlong
   static void conjoint_jlongs_atomic(const jlong* from, jlong* to, size_t count) {
-    assert_params_ok(from, to, LogBytesPerLong);
+    assert_params_ok(from, to, BytesPerLong);
     pd_conjoint_jlongs_atomic(from, to, count);
   }
 
   // oops,                  conjoint, atomic on each oop
   static void conjoint_oops_atomic(const oop* from, oop* to, size_t count) {
-    assert_params_ok(from, to, LogBytesPerHeapOop);
+    assert_params_ok(from, to, BytesPerHeapOop);
     pd_conjoint_oops_atomic(from, to, count);
   }
 
   // overloaded for UseCompressedOops
   static void conjoint_oops_atomic(const narrowOop* from, narrowOop* to, size_t count) {
     assert(sizeof(narrowOop) == sizeof(jint), "this cast is wrong");
-    assert_params_ok(from, to, LogBytesPerInt);
+    assert_params_ok(from, to, BytesPerInt);
     pd_conjoint_jints_atomic((const jint*)from, (jint*)to, count);
   }
 
@@ -175,25 +176,25 @@
 
   // jshorts,               conjoint array, atomic on each jshort
   static void arrayof_conjoint_jshorts(const HeapWord* from, HeapWord* to, size_t count) {
-    assert_params_ok(from, to, LogBytesPerShort);
+    assert_params_ok(from, to, BytesPerShort);
     pd_arrayof_conjoint_jshorts(from, to, count);
   }
 
   // jints,                 conjoint array, atomic on each jint
   static void arrayof_conjoint_jints(const HeapWord* from, HeapWord* to, size_t count) {
-    assert_params_ok(from, to, LogBytesPerInt);
+    assert_params_ok(from, to, BytesPerInt);
     pd_arrayof_conjoint_jints(from, to, count);
   }
 
   // jlongs,                conjoint array, atomic on each jlong
   static void arrayof_conjoint_jlongs(const HeapWord* from, HeapWord* to, size_t count) {
-    assert_params_ok(from, to, LogBytesPerLong);
+    assert_params_ok(from, to, BytesPerLong);
     pd_arrayof_conjoint_jlongs(from, to, count);
   }
 
   // oops,                  conjoint array, atomic on each oop
   static void arrayof_conjoint_oops(const HeapWord* from, HeapWord* to, size_t count) {
-    assert_params_ok(from, to, LogBytesPerHeapOop);
+    assert_params_ok(from, to, BytesPerHeapOop);
     pd_arrayof_conjoint_oops(from, to, count);
   }
 
@@ -202,7 +203,7 @@
   // Copy word-aligned words from higher to lower addresses, not atomic on each word
   inline static void conjoint_words_to_lower(const HeapWord* from, HeapWord* to, size_t byte_count) {
     // byte_count is in bytes to check its alignment
-    assert_params_ok(from, to, LogHeapWordSize);
+    assert_params_ok(from, to, HeapWordSize);
     assert_byte_count_ok(byte_count, HeapWordSize);
 
     size_t count = align_up(byte_count, HeapWordSize) >> LogHeapWordSize;
@@ -216,7 +217,7 @@
   // Copy word-aligned words from lower to higher addresses, not atomic on each word
   inline static void conjoint_words_to_higher(const HeapWord* from, HeapWord* to, size_t byte_count) {
     // byte_count is in bytes to check its alignment
-    assert_params_ok(from, to, LogHeapWordSize);
+    assert_params_ok(from, to, HeapWordSize);
     assert_byte_count_ok(byte_count, HeapWordSize);
 
     size_t count = align_up(byte_count, HeapWordSize) >> LogHeapWordSize;
@@ -271,7 +272,7 @@
   // Fill word-aligned words, not atomic on each word
   // set_words
   static void fill_to_words(HeapWord* to, size_t count, juint value = 0) {
-    assert_params_ok(to, LogHeapWordSize);
+    assert_params_ok(to, HeapWordSize);
     pd_fill_to_words(to, count, value);
   }
 
@@ -295,7 +296,7 @@
 
   // Zero word-aligned words, not atomic on each word
   static void zero_to_words(HeapWord* to, size_t count) {
-    assert_params_ok(to, LogHeapWordSize);
+    assert_params_ok(to, HeapWordSize);
     pd_zero_to_words(to, count);
   }
 
@@ -315,49 +316,29 @@
   // These methods raise a fatal if they detect a problem.
 
   static void assert_disjoint(const HeapWord* from, HeapWord* to, size_t count) {
-#ifdef ASSERT
-    if (!params_disjoint(from, to, count))
-      basic_fatal("source and dest overlap");
-#endif
+    assert(params_disjoint(from, to, count), "source and dest overlap");
+  }
+
+  static void assert_params_ok(const void* from, void* to, intptr_t alignment) {
+    assert(is_aligned(from, alignment), "must be aligned: " INTPTR_FORMAT, p2i(from));
+    assert(is_aligned(to, alignment),   "must be aligned: " INTPTR_FORMAT, p2i(to));
   }
 
-  static void assert_params_ok(const void* from, void* to, intptr_t log_align) {
-#ifdef ASSERT
-    if (mask_bits((uintptr_t)from, right_n_bits(log_align)) != 0)
-      basic_fatal("not aligned");
-    if (mask_bits((uintptr_t)to, right_n_bits(log_align)) != 0)
-      basic_fatal("not aligned");
-#endif
+  static void assert_params_ok(HeapWord* to, intptr_t alignment) {
+    assert(is_aligned(to, alignment), "must be aligned: " INTPTR_FORMAT, p2i(to));
   }
 
-  static void assert_params_ok(HeapWord* to, intptr_t log_align) {
-#ifdef ASSERT
-    if (mask_bits((uintptr_t)to, right_n_bits(log_align)) != 0)
-      basic_fatal("not word aligned");
-#endif
-  }
   static void assert_params_aligned(const HeapWord* from, HeapWord* to) {
-#ifdef ASSERT
-    if (mask_bits((uintptr_t)from, BytesPerLong-1) != 0)
-      basic_fatal("not long aligned");
-    if (mask_bits((uintptr_t)to, BytesPerLong-1) != 0)
-      basic_fatal("not long aligned");
-#endif
+    assert(is_aligned(from, BytesPerLong), "must be aligned: " INTPTR_FORMAT, p2i(from));
+    assert(is_aligned(to, BytesPerLong),   "must be aligned: " INTPTR_FORMAT, p2i(to));
   }
 
   static void assert_params_aligned(HeapWord* to) {
-#ifdef ASSERT
-    if (mask_bits((uintptr_t)to, BytesPerLong-1) != 0)
-      basic_fatal("not long aligned");
-#endif
+    assert(is_aligned(to, BytesPerLong), "must be aligned: " INTPTR_FORMAT, p2i(to));
   }
 
   static void assert_byte_count_ok(size_t byte_count, size_t unit_size) {
-#ifdef ASSERT
-    if (!is_aligned(byte_count, unit_size)) {
-      basic_fatal("byte count must be aligned");
-    }
-#endif
+    assert(is_aligned(byte_count, unit_size), "byte count must be aligned");
   }
 
   // Platform dependent implementations of the above methods.
--- a/src/hotspot/share/utilities/debug.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/utilities/debug.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -503,12 +503,6 @@
   SystemDictionary::print();
 }
 
-
-extern "C" void safepoints() {
-  Command c("safepoints");
-  SafepointSynchronize::print_state();
-}
-
 #endif // !PRODUCT
 
 extern "C" void pss() { // print all stacks
--- a/src/hotspot/share/utilities/globalDefinitions.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/utilities/globalDefinitions.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -48,10 +48,6 @@
 // Oop encoding heap max
 uint64_t OopEncodingHeapMax = 0;
 
-void basic_fatal(const char* msg) {
-  fatal("%s", msg);
-}
-
 // Something to help porters sleep at night
 
 void basic_types_init() {
--- a/src/hotspot/share/utilities/globalDefinitions.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/utilities/globalDefinitions.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -939,15 +939,12 @@
 class methodHandle;
 class JavaCallArguments;
 
-// Basic support for errors.
-extern void basic_fatal(const char* msg);
-
 //----------------------------------------------------------------------------------------------------
 // Special constants for debugging
 
 const jint     badInt           = -3;                       // generic "bad int" value
-const long     badAddressVal    = -2;                       // generic "bad address" value
-const long     badOopVal        = -1;                       // generic "bad oop" value
+const intptr_t badAddressVal    = -2;                       // generic "bad address" value
+const intptr_t badOopVal        = -1;                       // generic "bad oop" value
 const intptr_t badHeapOopVal    = (intptr_t) CONST64(0x2BAD4B0BBAADBABE); // value used to zap heap after GC
 const int      badStackSegVal   = 0xCA;                     // value used to zap stack segments
 const int      badHandleValue   = 0xBC;                     // value used to zap vm handle area
--- a/src/hotspot/share/utilities/globalDefinitions_visCPP.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/hotspot/share/utilities/globalDefinitions_visCPP.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -35,6 +35,7 @@
 # include <string.h>
 # include <stdarg.h>
 # include <stdlib.h>
+# include <stdint.h>
 # include <stddef.h>// for offsetof
 # include <io.h>    // for stream.cpp
 # include <float.h> // for _isnan
@@ -42,6 +43,7 @@
 # include <time.h>
 # include <fcntl.h>
 # include <limits.h>
+# include <inttypes.h>
 // Need this on windows to get the math constants (e.g., M_PI).
 #define _USE_MATH_DEFINES
 # include <math.h>
@@ -77,43 +79,18 @@
 // pointer is stored as integer value.
 #define NULL_WORD NULL
 
-// Compiler-specific primitive types
-typedef unsigned __int8  uint8_t;
-typedef unsigned __int16 uint16_t;
-typedef unsigned __int32 uint32_t;
-typedef unsigned __int64 uint64_t;
-
 #ifdef _WIN64
-typedef unsigned __int64 uintptr_t;
+typedef int64_t ssize_t;
 #else
-typedef unsigned int uintptr_t;
-#endif
-typedef signed   __int8  int8_t;
-typedef signed   __int16 int16_t;
-typedef signed   __int32 int32_t;
-typedef signed   __int64 int64_t;
-#ifdef _WIN64
-typedef signed   __int64 intptr_t;
-typedef signed   __int64 ssize_t;
-#else
-typedef signed   int intptr_t;
-typedef signed   int ssize_t;
-#endif
-
-#ifndef UINTPTR_MAX
-#ifdef _WIN64
-#define UINTPTR_MAX _UI64_MAX
-#else
-#define UINTPTR_MAX _UI32_MAX
-#endif
+typedef int32_t ssize_t;
 #endif
 
 // Additional Java basic types
 
-typedef unsigned char    jubyte;
-typedef unsigned short   jushort;
-typedef unsigned int     juint;
-typedef unsigned __int64 julong;
+typedef uint8_t  jubyte;
+typedef uint16_t jushort;
+typedef uint32_t juint;
+typedef uint64_t julong;
 
 // Non-standard stdlib-like stuff:
 inline int strcasecmp(const char *s1, const char *s2) { return _stricmp(s1,s2); }
@@ -187,26 +164,6 @@
 // Formatting.
 #define FORMAT64_MODIFIER "I64"
 
-// Visual Studio doesn't provide inttypes.h so provide appropriate definitions here.
-// The 32 bits ones might need I32 but seem to work ok without it.
-#define PRId32       "d"
-#define PRIu32       "u"
-#define PRIx32       "x"
-
-#define PRId64       "I64d"
-#define PRIu64       "I64u"
-#define PRIx64       "I64x"
-
-#ifdef _LP64
-#define PRIdPTR       "I64d"
-#define PRIuPTR       "I64u"
-#define PRIxPTR       "I64x"
-#else
-#define PRIdPTR       "d"
-#define PRIuPTR       "u"
-#define PRIxPTR       "x"
-#endif
-
 #define offset_of(klass,field) offsetof(klass,field)
 
 #ifndef USE_LIBRARY_BASED_TLS_ONLY
--- a/src/java.base/share/classes/java/lang/ClassLoader.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/java.base/share/classes/java/lang/ClassLoader.java	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -650,21 +650,6 @@
         return lock;
     }
 
-    // This method is invoked by the virtual machine to load a class.
-    private Class<?> loadClassInternal(String name)
-        throws ClassNotFoundException
-    {
-        // For backward compatibility, explicitly lock on 'this' when
-        // the current class loader is not parallel capable.
-        if (parallelLockMap == null) {
-            synchronized (this) {
-                 return loadClass(name);
-            }
-        } else {
-            return loadClass(name);
-        }
-    }
-
     // Invoked by the VM after loading class with this loader.
     private void checkPackageAccess(Class<?> cls, ProtectionDomain pd) {
         final SecurityManager sm = System.getSecurityManager();
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/GCCause.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/GCCause.java	Sun Feb 25 04:59:43 2018 +0100
@@ -38,8 +38,6 @@
   _wb_young_gc ("WhiteBox Initiated Young GC"),
   _wb_conc_mark ("WhiteBox Initiated Concurrent Mark"),
   _wb_full_gc ("WhiteBox Initiated Full GC"),
-  _update_allocation_context_stats_inc ("Update Allocation Context Stats"),
-  _update_allocation_context_stats_full ("Update Allocation Context Stats"),
 
   _no_gc ("No GC"),
   _no_cause_specified ("Unknown GCCause"),
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/GenCollectedHeap.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/GenCollectedHeap.java	Sun Feb 25 04:59:43 2018 +0100
@@ -54,12 +54,10 @@
 
     youngGenField = type.getAddressField("_young_gen");
     oldGenField = type.getAddressField("_old_gen");
+    youngGenSpecField = type.getAddressField("_young_gen_spec");
+    oldGenSpecField = type.getAddressField("_old_gen_spec");
 
     genFactory = new GenerationFactory();
-
-    Type collectorPolicyType = db.lookupType("GenCollectorPolicy");
-    youngGenSpecField = collectorPolicyType.getAddressField("_young_gen_spec");
-    oldGenSpecField = collectorPolicyType.getAddressField("_old_gen_spec");
   }
 
   public GenCollectedHeap(Address addr) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorld.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CompileTheWorld.java	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -553,7 +553,6 @@
                     classFileCounter++;
 
                     if (className.startsWith("jdk.management.") ||
-                                    className.startsWith("jdk.internal.cmm.*") ||
                                     // GR-5881: The class initializer for
                                     // sun.tools.jconsole.OutputViewer
                                     // spawns non-daemon threads for redirecting sysout and syserr.
--- a/test/hotspot/gtest/gc/shared/test_oopStorage.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/gtest/gc/shared/test_oopStorage.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -896,7 +896,7 @@
 
 public:
   Task(const char* name, Storage* storage, VerifyState* vstate) :
-    AbstractGangTask(name, GCId::undefined()),
+    AbstractGangTask(name),
     _state(storage),
     _vstate(vstate)
   {}
@@ -915,7 +915,7 @@
 class OopStorageTestParIteration::TaskUsingOopsDo : public AbstractGangTask {
 public:
   TaskUsingOopsDo(const char* name, OopStorage* storage, VerifyState* vstate) :
-    AbstractGangTask(name, GCId::undefined()),
+    AbstractGangTask(name),
     _state(storage),
     _vstate(vstate)
   {}
--- a/test/hotspot/gtest/logging/logTestUtils.inline.hpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/gtest/logging/logTestUtils.inline.hpp	Sun Feb 25 04:59:43 2018 +0100
@@ -30,6 +30,12 @@
 
 #define LOG_TEST_STRING_LITERAL "a (hopefully) unique log message for testing"
 
+static const char* invalid_selection_substr[] = {
+  "=", "+", " ", "+=", "+=*", "*+", " +", "**", "++", ".", ",", ",," ",+",
+  " *", "all+", "all*", "+all", "+all=Warning", "==Info", "=InfoWarning",
+  "BadTag+", "logging++", "logging*+", ",=", "gc+gc+"
+};
+
 static inline bool string_contains_substring(const char* haystack, const char* needle) {
   return strstr(haystack, needle) != NULL;
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/gtest/logging/test_logSelection.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -0,0 +1,203 @@
+/*
+ * 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.
+ */
+
+#include "precompiled.hpp"
+#include "jvm.h"
+#include "logging/logLevel.hpp"
+#include "logging/logSelection.hpp"
+#include "logging/logTagSet.hpp"
+#include "utilities/globalDefinitions.hpp"
+#include "logTestUtils.inline.hpp"
+#include "unittest.hpp"
+
+// These tests can only run in debug VMs because they rely on the (debug-only) LogTag::_test
+#ifdef ASSERT
+
+#define NON_EXISTING_TAG_SET "logging+test+start+exit+safepoint"
+
+// let google test know how to print LogSelection nicely for better error messages
+void PrintTo(const LogSelection& sel, ::std::ostream* os) {
+  if (sel == LogSelection::Invalid) {
+    *os << "LogSelection::Invalid";
+    return;
+  }
+  char buf[256];
+  sel.describe(buf, sizeof(buf));
+  *os << buf;
+}
+
+TEST(LogSelection, sanity) {
+  LogTagType tags[LogTag::MaxTags] = { PREFIX_LOG_TAG(logging), PREFIX_LOG_TAG(test), PREFIX_LOG_TAG(_NO_TAG) };
+  LogSelection selection(tags, false, LogLevel::Trace);
+
+  EXPECT_EQ(2u, selection.ntags());
+  EXPECT_EQ(LogLevel::Trace, selection.level());
+
+  // Verify that copying the selection also works as expected
+  LogSelection copy = selection;
+  EXPECT_EQ(2u, copy.ntags());
+  EXPECT_EQ(LogLevel::Trace, copy.level());
+
+  tags[0] = PREFIX_LOG_TAG(gc);
+  tags[1] = PREFIX_LOG_TAG(_NO_TAG);
+  LogSelection copy2(tags, true, LogLevel::Off); // start with a completely different selection
+  copy2 = selection; // and test copy assignment
+  EXPECT_EQ(2u, copy2.ntags());
+  EXPECT_EQ(LogLevel::Trace, copy2.level());
+}
+
+TEST(LogSelection, tag_sets_selected) {
+  LogTagType tags[LogTag::MaxTags] = { PREFIX_LOG_TAG(logging), PREFIX_LOG_TAG(test), PREFIX_LOG_TAG(_NO_TAG) };
+  LogSelection selection(tags, false, LogLevel::Trace);
+
+  EXPECT_EQ(1u, selection.tag_sets_selected()) << "there should be a single (it's not a wildcard selection) "
+                                                  "tag set selected by this (in gtest libjvm)";
+
+  EXPECT_EQ(LogTagSet::ntagsets(), LogSelection::parse("all").tag_sets_selected()) << "all should select every tag set";
+  EXPECT_EQ(0u, LogSelection::parse(NON_EXISTING_TAG_SET).tag_sets_selected()) <<
+      "(assuming the tag set doesn't exist) the selection shouldn't select any tag sets";
+}
+
+static const char* valid_expression[] = {
+  "all", "gc", "gc+logging", "logging+gc", "logging+gc*", "gc=trace",
+  "logging+gc=trace", "logging*", "logging*=info", "gc+logging*=error"
+};
+
+TEST(LogSelection, parse) {
+  LogTagType tags[LogTag::MaxTags] = { PREFIX_LOG_TAG(logging), PREFIX_LOG_TAG(test), PREFIX_LOG_TAG(_NO_TAG) };
+  LogSelection selection(tags, true, LogLevel::Off);
+  LogSelection parsed = LogSelection::parse("logging+test*=off");
+  EXPECT_EQ(selection, parsed) << "parsed selection not equal to programmatically constructed";
+
+  // Verify valid expressions parse without problems
+  for (size_t i = 0; i < ARRAY_SIZE(valid_expression); i++) {
+    EXPECT_NE(LogSelection::Invalid, LogSelection::parse(valid_expression[i])) <<
+        "Valid expression '" << valid_expression[i] << "' did not parse";
+  }
+
+  // Test 'all' with each level
+  for (LogLevelType level = LogLevel::First; level <= LogLevel::Last; level = static_cast<LogLevelType>(level + 1)) {
+    char buf[64];
+    int ret = jio_snprintf(buf, sizeof(buf), "all=%s", LogLevel::name(level));
+    ASSERT_NE(-1, ret);
+
+    LogSelection sel = LogSelection::parse(buf);
+    EXPECT_EQ(LogTagSet::ntagsets(), sel.tag_sets_selected()) << "'all' should select all tag sets";
+    EXPECT_EQ(level, sel.level());
+  }
+
+  // Test with 5 tags
+  LogTagType expected_tags[] = { PREFIX_LOG_TAG(logging), PREFIX_LOG_TAG(test), PREFIX_LOG_TAG(start),
+      PREFIX_LOG_TAG(exit), PREFIX_LOG_TAG(safepoint) };
+  LogSelection expected(expected_tags, false, LogLevel::Debug);
+  LogSelection five_tag_selection = LogSelection::parse("logging+test+start+exit+safepoint=debug");
+  EXPECT_EQ(5u, five_tag_selection.ntags()) << "parsed wrong number of tags";
+  EXPECT_EQ(expected, five_tag_selection);
+  EXPECT_EQ(LogLevel::Debug, five_tag_selection.level());
+
+  // Test implicit level
+  selection = LogSelection::parse("logging");
+  EXPECT_EQ(LogLevel::Unspecified, selection.level()) << "parsed implicit level incorrectly";
+  EXPECT_EQ(1u, selection.ntags());
+}
+
+TEST(LogSelection, parse_invalid) {
+
+  // Attempt to parse an expression with too many tags
+  EXPECT_EQ(LogSelection::Invalid, LogSelection::parse(NON_EXISTING_TAG_SET "+gc"));
+
+  // Construct a bunch of invalid expressions and verify that they don't parse
+  for (size_t i = 0; i < ARRAY_SIZE(valid_expression); i++) {
+    char buf[256];
+    for (size_t j = 0; j < ARRAY_SIZE(invalid_selection_substr); j++) {
+      // Prefix with invalid substr
+      jio_snprintf(buf, sizeof(buf), "%s%s", invalid_selection_substr[j], valid_expression[i]);
+      EXPECT_EQ(LogSelection::Invalid, LogSelection::parse(buf)) << "'" << buf << "'" << " considered legal";
+
+      // Suffix with invalid substr
+      jio_snprintf(buf, sizeof(buf), "%s%s", valid_expression[i], invalid_selection_substr[j]);
+      EXPECT_EQ(LogSelection::Invalid, LogSelection::parse(buf)) << "'" << buf << "'" << " considered legal";
+
+      // Use only the invalid substr
+      EXPECT_EQ(LogSelection::Invalid, LogSelection::parse(invalid_selection_substr[j])) <<
+          "'" << invalid_selection_substr[j] << "'" << " considered legal";
+    }
+
+    // Suffix/prefix with some unique invalid prefixes/suffixes
+    jio_snprintf(buf, sizeof(buf), "*%s", valid_expression[i]);
+    EXPECT_EQ(LogSelection::Invalid, LogSelection::parse(buf)) << "'" << buf << "'" << " considered legal";
+
+    jio_snprintf(buf, sizeof(buf), "logging*%s", valid_expression[i]);
+    EXPECT_EQ(LogSelection::Invalid, LogSelection::parse(buf)) << "'" << buf << "'" << " considered legal";
+  }
+}
+
+TEST(LogSelection, equals) {
+  LogTagType tags[LogTag::MaxTags] = { PREFIX_LOG_TAG(logging), PREFIX_LOG_TAG(test), PREFIX_LOG_TAG(_NO_TAG) };
+  LogSelection selection(tags, true, LogLevel::Info);
+  LogSelection copy(tags, true, LogLevel::Info);
+  EXPECT_EQ(selection, selection);
+  EXPECT_EQ(selection, copy);
+
+  tags[0] = PREFIX_LOG_TAG(gc);
+  LogSelection other_tags(tags, true, LogLevel::Info);
+  EXPECT_NE(selection, other_tags);
+
+  tags[0] = PREFIX_LOG_TAG(test);
+  tags[1] = PREFIX_LOG_TAG(logging);
+  LogSelection reversed(tags, true, LogLevel::Info);
+  EXPECT_NE(selection, reversed);
+
+  LogSelection no_wildcard(tags, false, LogLevel::Info);
+  EXPECT_NE(selection, no_wildcard);
+
+  LogSelection different_level(tags, true, LogLevel::Warning);
+  EXPECT_NE(selection, different_level);
+
+  tags[2] = PREFIX_LOG_TAG(gc);
+  tags[3] = PREFIX_LOG_TAG(_NO_TAG);
+  LogSelection more_tags(tags, true, LogLevel::Info);
+  EXPECT_NE(selection, more_tags);
+
+  tags[1] = PREFIX_LOG_TAG(_NO_TAG);
+  LogSelection fewer_tags(tags, true, LogLevel::Info);
+  EXPECT_NE(selection, fewer_tags);
+}
+
+TEST(LogSelection, describe_tags) {
+  char buf[256];
+  LogTagType tags[LogTag::MaxTags] = { PREFIX_LOG_TAG(logging), PREFIX_LOG_TAG(test), PREFIX_LOG_TAG(_NO_TAG) };
+  LogSelection selection(tags, true, LogLevel::Off);
+  selection.describe_tags(buf, sizeof(buf));
+  EXPECT_STREQ("logging+test*", buf);
+}
+
+TEST(LogSelection, describe) {
+  char buf[256];
+  LogTagType tags[LogTag::MaxTags] = { PREFIX_LOG_TAG(logging), PREFIX_LOG_TAG(test), PREFIX_LOG_TAG(_NO_TAG) };
+  LogSelection selection(tags, true, LogLevel::Off);
+  selection.describe(buf, sizeof(buf));
+  EXPECT_STREQ("logging+test*=off", buf);
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/gtest/logging/test_logSelectionList.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -0,0 +1,146 @@
+/*
+ * 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.
+ */
+
+#include "precompiled.hpp"
+#include "jvm.h"
+#include "logging/logLevel.hpp"
+#include "logging/logSelectionList.hpp"
+#include "logging/logTagSet.hpp"
+#include "utilities/globalDefinitions.hpp"
+#include "logTestUtils.inline.hpp"
+#include "unittest.hpp"
+
+TEST(LogSelectionList, combination_limit) {
+  size_t max_combinations = LogSelectionList::MaxSelections;
+  EXPECT_GT(max_combinations, LogTagSet::ntagsets())
+      << "Combination limit not sufficient for configuring all available tag sets";
+}
+
+TEST(LogSelectionList, parse) {
+  char buf[256];
+  const char* valid_expression[] = {
+    "logging=off,all", "gc,logging", "logging+gc", "logging+gc,gc", "gc=trace,logging=info",
+    "logging+gc=trace,gc+logging=warning,logging", "gc,all=info"
+  };
+
+  // Verify valid expressions parse without problems
+  for (size_t i = 0; i < ARRAY_SIZE(valid_expression); i++) {
+    LogSelectionList expr;
+    EXPECT_TRUE(expr.parse(valid_expression[i])) << "Valid expression '" << valid_expression[i] << "' did not parse";
+  }
+
+  // Verify invalid expressions do not parse
+  for (size_t i = 0; i < ARRAY_SIZE(valid_expression); i++) {
+    for (size_t j = 0; j < ARRAY_SIZE(invalid_selection_substr); j++) {
+      // Prefix with invalid substr
+      LogSelectionList expr;
+      jio_snprintf(buf, sizeof(buf), "%s%s", invalid_selection_substr[j], valid_expression[i]);
+      EXPECT_FALSE(expr.parse(buf)) << "'" << buf << "'" << " considered legal";
+
+      // Suffix with invalid substr
+      LogSelectionList expr1;
+      jio_snprintf(buf, sizeof(buf), "%s%s", valid_expression[i], invalid_selection_substr[j]);
+      EXPECT_FALSE(expr1.parse(buf)) << "'" << buf << "'" << " considered legal";
+
+      // Use only the invalid substr
+      LogSelectionList expr2;
+      EXPECT_FALSE(expr2.parse(invalid_selection_substr[j])) << "'" << invalid_selection_substr[j] << "'" << " considered legal";
+    }
+
+    // Suffix/prefix with some unique invalid prefixes/suffixes
+    LogSelectionList expr;
+    jio_snprintf(buf, sizeof(buf), "*%s", valid_expression[i]);
+    EXPECT_FALSE(expr.parse(buf)) << "'" << buf << "'" << " considered legal";
+
+    LogSelectionList expr1;
+    jio_snprintf(buf, sizeof(buf), "logging*%s", valid_expression[i]);
+    EXPECT_FALSE(expr1.parse(buf)) << "'" << buf << "'" << " considered legal";
+  }
+}
+
+// Test the level_for() function for an empty expression
+TEST(LogSelectionList, level_for_empty) {
+  LogSelectionList emptyexpr;
+  ASSERT_TRUE(emptyexpr.parse(""));
+  // All tagsets should be unspecified since the expression doesn't involve any tagset
+  for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
+    EXPECT_EQ(LogLevel::Unspecified, emptyexpr.level_for(*ts));
+  }
+}
+
+// Test level_for() with an expression that has overlap (last subexpression should be used)
+TEST(LogSelectionList, level_for_overlap) {
+  LogSelectionList overlapexpr;
+  // The all=warning will be overridden with gc=info and/or logging+safepoint*=trace
+  ASSERT_TRUE(overlapexpr.parse("all=warning,gc=info,logging+safepoint*=trace"));
+  for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
+    if (ts->contains(PREFIX_LOG_TAG(gc)) && ts->ntags() == 1) {
+      EXPECT_EQ(LogLevel::Info, overlapexpr.level_for(*ts));
+    } else if (ts->contains(PREFIX_LOG_TAG(logging)) && ts->contains(PREFIX_LOG_TAG(safepoint))) {
+      EXPECT_EQ(LogLevel::Trace, overlapexpr.level_for(*ts));
+    } else {
+      EXPECT_EQ(LogLevel::Warning, overlapexpr.level_for(*ts));
+    }
+  }
+  EXPECT_EQ(LogLevel::Warning, overlapexpr.level_for(LogTagSetMapping<LOG_TAGS(class)>::tagset()));
+  EXPECT_EQ(LogLevel::Info, overlapexpr.level_for(LogTagSetMapping<LOG_TAGS(gc)>::tagset()));
+  EXPECT_EQ(LogLevel::Trace, overlapexpr.level_for(LogTagSetMapping<LOG_TAGS(logging, safepoint)>::tagset()));
+  EXPECT_EQ(LogLevel::Trace,
+            overlapexpr.level_for(LogTagSetMapping<LOG_TAGS(logging, gc, class, safepoint, heap)>::tagset()));
+}
+
+// Test level_for() with an expression containing two independent subexpressions
+TEST(LogSelectionList, level_for_disjoint) {
+  LogSelectionList reducedexpr;
+  ASSERT_TRUE(reducedexpr.parse("gc+logging=trace,class*=error"));
+  EXPECT_EQ(LogLevel::Error, reducedexpr.level_for(LogTagSetMapping<LOG_TAGS(class)>::tagset()));
+  EXPECT_EQ(LogLevel::Error, reducedexpr.level_for(LogTagSetMapping<LOG_TAGS(safepoint, class)>::tagset()));
+  EXPECT_EQ(LogLevel::NotMentioned, reducedexpr.level_for(LogTagSetMapping<LOG_TAGS(safepoint)>::tagset()));
+  EXPECT_EQ(LogLevel::NotMentioned, reducedexpr.level_for(LogTagSetMapping<LOG_TAGS(logging)>::tagset()));
+  EXPECT_EQ(LogLevel::NotMentioned, reducedexpr.level_for(LogTagSetMapping<LOG_TAGS(gc)>::tagset()));
+  EXPECT_EQ(LogLevel::Trace, reducedexpr.level_for(LogTagSetMapping<LOG_TAGS(logging, gc)>::tagset()));
+}
+
+// Test level_for() with an expression that is completely overridden in the last part of the expression
+TEST(LogSelectionList, level_for_override) {
+  LogSelectionList overrideexpr;
+  // No matter what, everything should be set to error level because of the last part
+  ASSERT_TRUE(overrideexpr.parse("logging,gc*=trace,all=error"));
+  EXPECT_EQ(LogLevel::Error, overrideexpr.level_for(LogTagSetMapping<LOG_TAGS(class)>::tagset()));
+  EXPECT_EQ(LogLevel::Error, overrideexpr.level_for(LogTagSetMapping<LOG_TAGS(logging)>::tagset()));
+  EXPECT_EQ(LogLevel::Error, overrideexpr.level_for(LogTagSetMapping<LOG_TAGS(gc)>::tagset()));
+  EXPECT_EQ(LogLevel::Error, overrideexpr.level_for(LogTagSetMapping<LOG_TAGS(logging, gc)>::tagset()));
+}
+
+// Test level_for() with a mixed expression with a bit of everything
+TEST(LogSelectionList, level_for_mixed) {
+  LogSelectionList mixedexpr;
+  ASSERT_TRUE(mixedexpr.parse("all=warning,gc*=debug,gc=trace,safepoint*=off"));
+  EXPECT_EQ(LogLevel::Warning, mixedexpr.level_for(LogTagSetMapping<LOG_TAGS(logging)>::tagset()));
+  EXPECT_EQ(LogLevel::Warning, mixedexpr.level_for(LogTagSetMapping<LOG_TAGS(logging, class)>::tagset()));
+  EXPECT_EQ(LogLevel::Debug, mixedexpr.level_for(LogTagSetMapping<LOG_TAGS(gc, class)>::tagset()));
+  EXPECT_EQ(LogLevel::Off, mixedexpr.level_for(LogTagSetMapping<LOG_TAGS(gc, safepoint, logging)>::tagset()));
+  EXPECT_EQ(LogLevel::Off, mixedexpr.level_for(LogTagSetMapping<LOG_TAGS(safepoint)>::tagset()));
+  EXPECT_EQ(LogLevel::Debug, mixedexpr.level_for(LogTagSetMapping<LOG_TAGS(logging, gc)>::tagset()));
+  EXPECT_EQ(LogLevel::Trace, mixedexpr.level_for(LogTagSetMapping<LOG_TAGS(gc)>::tagset()));
+}
--- a/test/hotspot/gtest/logging/test_logTag.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/gtest/logging/test_logTag.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -23,6 +23,7 @@
 
 #include "precompiled.hpp"
 #include "logging/logTag.hpp"
+#include "utilities/ostream.hpp"
 #include "unittest.hpp"
 
 TEST(LogTag, from_string) {
@@ -51,3 +52,31 @@
   LOG_TAG_LIST
 #undef LOG_TAG
 }
+
+TEST(LogTag, list_tags) {
+  char buf[LogTag::Count * 16] = {0};
+  stringStream ss(buf, sizeof(buf));
+  LogTag::list_tags(&ss);
+
+  bool listed_tags[LogTag::Count] = { false };
+
+  char* last_tag = NULL;
+  for (char* tag = buf; *tag != '\0';) {
+    char* end = strpbrk(tag, ",\n");
+    ASSERT_TRUE(end != NULL) <<  "line should end with newline";
+    *end = '\0';
+    if (*tag == ' ') {
+      tag++;
+    }
+
+    EXPECT_TRUE(last_tag == NULL || strcmp(last_tag, tag) < 0) << tag << " should be listed before " << last_tag;
+    listed_tags[LogTag::from_string(tag)] = true;
+
+    last_tag = tag;
+    tag = end + 1;
+  }
+
+  for (size_t i = 1; i < LogTag::Count; i++) {
+    EXPECT_TRUE(listed_tags[i]) << "tag '" << LogTag::name(static_cast<LogTagType>(i)) << "' not listed!";
+  }
+}
--- a/test/hotspot/gtest/logging/test_logTagLevelExpression.cpp	Wed Feb 28 15:28:46 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,190 +0,0 @@
-/*
- * Copyright (c) 2016, 2017, 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.
- */
-
-#include "precompiled.hpp"
-#include "jvm.h"
-#include "logging/logLevel.hpp"
-#include "logging/logTagLevelExpression.hpp"
-#include "logging/logTagSet.hpp"
-#include "unittest.hpp"
-#include "utilities/globalDefinitions.hpp"
-
-TEST(LogTagLevelExpression, combination_limit) {
-  size_t max_combinations = LogTagLevelExpression::MaxCombinations;
-  EXPECT_GT(max_combinations, LogTagSet::ntagsets())
-      << "Combination limit not sufficient for configuring all available tag sets";
-}
-
-TEST(LogTagLevelExpression, parse) {
-  char buf[256];
-  const char* invalid_substr[] = {
-    "=", "+", " ", "+=", "+=*", "*+", " +", "**", "++", ".", ",", ",," ",+",
-    " *", "all+", "all*", "+all", "+all=Warning", "==Info", "=InfoWarning",
-    "BadTag+", "logging++", "logging*+", ",=", "gc+gc+"
-  };
-  const char* valid_expression[] = {
-    "all", "gc", "gc,logging", "gc+logging", "logging+gc", "logging+gc,gc", "logging+gc*", "gc=trace",
-    "gc=trace,logging=info", "logging+gc=trace", "logging+gc=trace,gc+logging=warning,logging",
-    "gc,all=info", "logging*", "logging*=info", "gc+logging*=error", "logging*,gc=info"
-  };
-
-  // Verify valid expressions parse without problems
-  for (size_t i = 0; i < ARRAY_SIZE(valid_expression); i++) {
-    LogTagLevelExpression expr;
-    EXPECT_TRUE(expr.parse(valid_expression[i])) << "Valid expression '" << valid_expression[i] << "' did not parse";
-  }
-
-  // Verify we can use 'all' with each available level
-  for (uint level = LogLevel::First; level <= LogLevel::Last; level++) {
-    char buf[32];
-    int ret = jio_snprintf(buf, sizeof(buf), "all=%s", LogLevel::name(static_cast<LogLevelType>(level)));
-    ASSERT_NE(ret, -1);
-
-    LogTagLevelExpression expr;
-    EXPECT_TRUE(expr.parse(buf));
-  }
-
-  // Verify invalid expressions do not parse
-  for (size_t i = 0; i < ARRAY_SIZE(valid_expression); i++) {
-    for (size_t j = 0; j < ARRAY_SIZE(invalid_substr); j++) {
-      // Prefix with invalid substr
-      LogTagLevelExpression expr;
-      jio_snprintf(buf, sizeof(buf), "%s%s", invalid_substr[j], valid_expression[i]);
-      EXPECT_FALSE(expr.parse(buf)) << "'" << buf << "'" << " considered legal";
-
-      // Suffix with invalid substr
-      LogTagLevelExpression expr1;
-      jio_snprintf(buf, sizeof(buf), "%s%s", valid_expression[i], invalid_substr[j]);
-      EXPECT_FALSE(expr1.parse(buf)) << "'" << buf << "'" << " considered legal";
-
-      // Use only the invalid substr
-      LogTagLevelExpression expr2;
-      EXPECT_FALSE(expr2.parse(invalid_substr[j])) << "'" << invalid_substr[j] << "'" << " considered legal";
-    }
-
-    // Suffix/prefix with some unique invalid prefixes/suffixes
-    LogTagLevelExpression expr;
-    jio_snprintf(buf, sizeof(buf), "*%s", valid_expression[i]);
-    EXPECT_FALSE(expr.parse(buf)) << "'" << buf << "'" << " considered legal";
-
-    LogTagLevelExpression expr1;
-    jio_snprintf(buf, sizeof(buf), "logging*%s", valid_expression[i]);
-    EXPECT_FALSE(expr1.parse(buf)) << "'" << buf << "'" << " considered legal";
-  }
-}
-
-// Test the level_for() function for an empty expression
-TEST(LogTagLevelExpression, level_for_empty) {
-  LogTagLevelExpression emptyexpr;
-  ASSERT_TRUE(emptyexpr.parse(""));
-  // All tagsets should be unspecified since the expression doesn't involve any tagset
-  for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
-    EXPECT_EQ(LogLevel::Unspecified, emptyexpr.level_for(*ts));
-  }
-}
-
-// Test level_for() with "all" without any specified level
-TEST(LogTagLevelExpression, level_for_all) {
-  LogTagLevelExpression allexpr;
-  ASSERT_TRUE(allexpr.parse("all"));
-  // Level will be unspecified since no level was given
-  for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
-    EXPECT_EQ(LogLevel::Unspecified, allexpr.level_for(*ts));
-  }
-}
-
-// Test level_for() with "all=debug"
-TEST(LogTagLevelExpression, level_for_all_debug) {
-  LogTagLevelExpression alldebugexpr;
-  ASSERT_TRUE(alldebugexpr.parse("all=debug"));
-  // All tagsets should report debug level
-  for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
-    EXPECT_EQ(LogLevel::Debug, alldebugexpr.level_for(*ts));
-  }
-}
-
-// Test level_for() with "all=off"
-TEST(LogTagLevelExpression, level_for_all_off) {
-  LogTagLevelExpression alloffexpr;
-  ASSERT_TRUE(alloffexpr.parse("all=off"));
-  for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
-    EXPECT_EQ(LogLevel::Off, alloffexpr.level_for(*ts));
-  }
-}
-
-// Test level_for() with an expression that has overlap (last subexpression should be used)
-TEST(LogTagLevelExpression, level_for_overlap) {
-  LogTagLevelExpression overlapexpr;
-  // The all=warning will be overridden with gc=info and/or logging+safepoint*=trace
-  ASSERT_TRUE(overlapexpr.parse("all=warning,gc=info,logging+safepoint*=trace"));
-  for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
-    if (ts->contains(PREFIX_LOG_TAG(gc)) && ts->ntags() == 1) {
-      EXPECT_EQ(LogLevel::Info, overlapexpr.level_for(*ts));
-    } else if (ts->contains(PREFIX_LOG_TAG(logging)) && ts->contains(PREFIX_LOG_TAG(safepoint))) {
-      EXPECT_EQ(LogLevel::Trace, overlapexpr.level_for(*ts));
-    } else {
-      EXPECT_EQ(LogLevel::Warning, overlapexpr.level_for(*ts));
-    }
-  }
-  EXPECT_EQ(LogLevel::Warning, overlapexpr.level_for(LogTagSetMapping<LOG_TAGS(class)>::tagset()));
-  EXPECT_EQ(LogLevel::Info, overlapexpr.level_for(LogTagSetMapping<LOG_TAGS(gc)>::tagset()));
-  EXPECT_EQ(LogLevel::Trace, overlapexpr.level_for(LogTagSetMapping<LOG_TAGS(logging, safepoint)>::tagset()));
-  EXPECT_EQ(LogLevel::Trace,
-            overlapexpr.level_for(LogTagSetMapping<LOG_TAGS(logging, gc, class, safepoint, heap)>::tagset()));
-}
-
-// Test level_for() with an expression containing two independent subexpressions
-TEST(LogTagLevelExpression, level_for_disjoint) {
-  LogTagLevelExpression reducedexpr;
-  ASSERT_TRUE(reducedexpr.parse("gc+logging=trace,class*=error"));
-  EXPECT_EQ(LogLevel::Error, reducedexpr.level_for(LogTagSetMapping<LOG_TAGS(class)>::tagset()));
-  EXPECT_EQ(LogLevel::Error, reducedexpr.level_for(LogTagSetMapping<LOG_TAGS(safepoint, class)>::tagset()));
-  EXPECT_EQ(LogLevel::NotMentioned, reducedexpr.level_for(LogTagSetMapping<LOG_TAGS(safepoint)>::tagset()));
-  EXPECT_EQ(LogLevel::NotMentioned, reducedexpr.level_for(LogTagSetMapping<LOG_TAGS(logging)>::tagset()));
-  EXPECT_EQ(LogLevel::NotMentioned, reducedexpr.level_for(LogTagSetMapping<LOG_TAGS(gc)>::tagset()));
-  EXPECT_EQ(LogLevel::Trace, reducedexpr.level_for(LogTagSetMapping<LOG_TAGS(logging, gc)>::tagset()));
-}
-
-// Test level_for() with an expression that is completely overridden in the last part of the expression
-TEST(LogTagLevelExpression, level_for_override) {
-  LogTagLevelExpression overrideexpr;
-  // No matter what, everything should be set to error level because of the last part
-  ASSERT_TRUE(overrideexpr.parse("logging,gc*=trace,all=error"));
-  EXPECT_EQ(LogLevel::Error, overrideexpr.level_for(LogTagSetMapping<LOG_TAGS(class)>::tagset()));
-  EXPECT_EQ(LogLevel::Error, overrideexpr.level_for(LogTagSetMapping<LOG_TAGS(logging)>::tagset()));
-  EXPECT_EQ(LogLevel::Error, overrideexpr.level_for(LogTagSetMapping<LOG_TAGS(gc)>::tagset()));
-  EXPECT_EQ(LogLevel::Error, overrideexpr.level_for(LogTagSetMapping<LOG_TAGS(logging, gc)>::tagset()));
-}
-
-// Test level_for() with a mixed expression with a bit of everything
-TEST(LogTagLevelExpression, level_for_mixed) {
-  LogTagLevelExpression mixedexpr;
-  ASSERT_TRUE(mixedexpr.parse("all=warning,gc*=debug,gc=trace,safepoint*=off"));
-  EXPECT_EQ(LogLevel::Warning, mixedexpr.level_for(LogTagSetMapping<LOG_TAGS(logging)>::tagset()));
-  EXPECT_EQ(LogLevel::Warning, mixedexpr.level_for(LogTagSetMapping<LOG_TAGS(logging, class)>::tagset()));
-  EXPECT_EQ(LogLevel::Debug, mixedexpr.level_for(LogTagSetMapping<LOG_TAGS(gc, class)>::tagset()));
-  EXPECT_EQ(LogLevel::Off, mixedexpr.level_for(LogTagSetMapping<LOG_TAGS(gc, safepoint, logging)>::tagset()));
-  EXPECT_EQ(LogLevel::Off, mixedexpr.level_for(LogTagSetMapping<LOG_TAGS(safepoint)>::tagset()));
-  EXPECT_EQ(LogLevel::Debug, mixedexpr.level_for(LogTagSetMapping<LOG_TAGS(logging, gc)>::tagset()));
-  EXPECT_EQ(LogLevel::Trace, mixedexpr.level_for(LogTagSetMapping<LOG_TAGS(gc)>::tagset()));
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/gtest/oops/test_typeArrayOop.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2017, Red Hat, Inc. and/or its affiliates.
+ * 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "memory/universe.hpp"
+#include "oops/oop.inline.hpp"
+#include "oops/typeArrayOop.inline.hpp"
+#include "unittest.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+TEST_VM(typeArrayOopDesc, bool_at_put) {
+  char mem[100];
+  memset(mem, 0, ARRAY_SIZE(mem));
+
+  char* addr = align_up(mem, 16);
+
+  typeArrayOop o = (typeArrayOop) addr;
+  o->set_klass(Universe::boolArrayKlassObj());
+  o->set_length(10);
+
+
+  ASSERT_EQ((jboolean)0, o->bool_at(0));
+  ASSERT_EQ((jboolean)0, o->bool_at(1));
+  ASSERT_EQ((jboolean)0, o->bool_at(2));
+  ASSERT_EQ((jboolean)0, o->bool_at(3));
+  ASSERT_EQ((jboolean)0, o->bool_at(4));
+  ASSERT_EQ((jboolean)0, o->bool_at(5));
+  ASSERT_EQ((jboolean)0, o->bool_at(6));
+  ASSERT_EQ((jboolean)0, o->bool_at(7));
+
+  o->bool_at_put(3, 255); // Check for masking store.
+  o->bool_at_put(2, 1);
+  o->bool_at_put(1, 1);
+  o->bool_at_put(0, 1);
+
+  ASSERT_EQ((jboolean)1, o->bool_at(0));
+  ASSERT_EQ((jboolean)1, o->bool_at(1));
+  ASSERT_EQ((jboolean)1, o->bool_at(2));
+  ASSERT_EQ((jboolean)1, o->bool_at(3));
+  ASSERT_EQ((jboolean)0, o->bool_at(4));
+  ASSERT_EQ((jboolean)0, o->bool_at(5));
+  ASSERT_EQ((jboolean)0, o->bool_at(6));
+  ASSERT_EQ((jboolean)0, o->bool_at(7));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/gtest/runtime/test_virtualMemoryTracker.cpp	Sun Feb 25 04:59:43 2018 +0100
@@ -0,0 +1,550 @@
+/*
+ * 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
+ * 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.
+ */
+
+#include "precompiled.hpp"
+
+// Included early because the NMT flags don't include it.
+#include "utilities/macros.hpp"
+
+#if INCLUDE_NMT
+
+#include "services/memTracker.hpp"
+#include "services/virtualMemoryTracker.hpp"
+#include "utilities/globalDefinitions.hpp"
+#include "unittest.hpp"
+
+namespace {
+  struct R {
+    address _addr;
+    size_t  _size;
+  };
+}
+
+#define check(rmr, regions) check_inner((rmr), (regions), ARRAY_SIZE(regions), __FILE__, __LINE__)
+
+#define check_empty(rmr)                              \
+  do {                                                \
+    check_inner((rmr), NULL, 0, __FILE__, __LINE__);  \
+  } while (false)
+
+static void check_inner(ReservedMemoryRegion* rmr, R* regions, size_t regions_size, const char* file, int line) {
+  CommittedRegionIterator iter = rmr->iterate_committed_regions();
+  size_t i = 0;
+  size_t size = 0;
+
+#define WHERE " from " << file << ":" << line
+
+  for (const CommittedMemoryRegion* region = iter.next(); region != NULL; region = iter.next()) {
+    EXPECT_LT(i, regions_size) << WHERE;
+    EXPECT_EQ(region->base(), regions[i]._addr) << WHERE;
+    EXPECT_EQ(region->size(), regions[i]._size) << WHERE;
+    size += region->size();
+    i++;
+  }
+
+  EXPECT_EQ(i, regions_size) << WHERE;
+  EXPECT_EQ(size, rmr->committed_size()) << WHERE;
+}
+
+class VirtualMemoryTrackerTest {
+public:
+  static void test_add_committed_region_adjacent() {
+    VirtualMemoryTracker::initialize(NMT_detail);
+    VirtualMemoryTracker::late_initialize(NMT_detail);
+
+    address addr = (address)0x10000000;
+    size_t size  = 0x01000000;
+
+    address frame1 = (address)0x1234;
+    address frame2 = (address)0x1235;
+
+    NativeCallStack stack(&frame1, 1);
+    NativeCallStack stack2(&frame2, 1);
+
+    // Add the reserved memory
+    VirtualMemoryTracker::add_reserved_region(addr, size, stack, mtTest);
+
+    // Fetch the added RMR added above
+    ReservedMemoryRegion* rmr = VirtualMemoryTracker::_reserved_regions->find(ReservedMemoryRegion(addr, size));
+
+    ASSERT_EQ(rmr->size(), size);
+    ASSERT_EQ(rmr->base(), addr);
+
+    // Commit Size Granularity
+    const size_t cs = 0x1000;
+
+    // Commit adjacent regions with same stack
+
+    { // Commit one region
+      rmr->add_committed_region(addr + cs, cs, stack);
+      R r[] = { {addr + cs, cs} };
+      check(rmr, r);
+    }
+
+    { // Commit adjacent - lower address
+      rmr->add_committed_region(addr, cs, stack);
+      R r[] = { {addr, 2 * cs} };
+      check(rmr, r);
+    }
+
+    { // Commit adjacent - higher address
+      rmr->add_committed_region(addr + 2 * cs, cs, stack);
+      R r[] = { {addr, 3 * cs} };
+      check(rmr, r);
+    }
+
+    // Cleanup
+    rmr->remove_uncommitted_region(addr, 3 * cs);
+    ASSERT_EQ(rmr->committed_size(), 0u);
+
+
+    // Commit adjacent regions with different stacks
+
+    { // Commit one region
+      rmr->add_committed_region(addr + cs, cs, stack);
+      R r[] = { {addr + cs, cs} };
+      check(rmr, r);
+    }
+
+    { // Commit adjacent - lower address
+      rmr->add_committed_region(addr, cs, stack2);
+      R r[] = { {addr,      cs},
+                {addr + cs, cs} };
+      check(rmr, r);
+    }
+
+    { // Commit adjacent - higher address
+      rmr->add_committed_region(addr + 2 * cs, cs, stack2);
+      R r[] = { {addr,          cs},
+                {addr +     cs, cs},
+                {addr + 2 * cs, cs} };
+      check(rmr, r);
+    }
+
+    // Cleanup
+    rmr->remove_uncommitted_region(addr, 3 * cs);
+    ASSERT_EQ(rmr->committed_size(), 0u);
+  }
+
+  static void test_add_committed_region_adjacent_overlapping() {
+    VirtualMemoryTracker::initialize(NMT_detail);
+    VirtualMemoryTracker::late_initialize(NMT_detail);
+
+    address addr = (address)0x10000000;
+    size_t size  = 0x01000000;
+
+    address frame1 = (address)0x1234;
+    address frame2 = (address)0x1235;
+
+    NativeCallStack stack(&frame1, 1);
+    NativeCallStack stack2(&frame2, 1);
+
+    // Add the reserved memory
+    VirtualMemoryTracker::add_reserved_region(addr, size, stack, mtTest);
+
+    // Fetch the added RMR added above
+    ReservedMemoryRegion* rmr = VirtualMemoryTracker::_reserved_regions->find(ReservedMemoryRegion(addr, size));
+
+    ASSERT_EQ(rmr->size(), size);
+    ASSERT_EQ(rmr->base(), addr);
+
+    // Commit Size Granularity
+    const size_t cs = 0x1000;
+
+    // Commit adjacent and overlapping regions with same stack
+
+    { // Commit two non-adjacent regions
+      rmr->add_committed_region(addr, 2 * cs, stack);
+      rmr->add_committed_region(addr + 3 * cs, 2 * cs, stack);
+      R r[] = { {addr,          2 * cs},
+                {addr + 3 * cs, 2 * cs} };
+      check(rmr, r);
+    }
+
+    { // Commit adjacent and overlapping
+      rmr->add_committed_region(addr + 2 * cs, 2 * cs, stack);
+      R r[] = { {addr, 5 * cs} };
+      check(rmr, r);
+    }
+
+    // revert to two non-adjacent regions
+    rmr->remove_uncommitted_region(addr + 2 * cs, cs);
+    ASSERT_EQ(rmr->committed_size(), 4 * cs);
+
+    { // Commit overlapping and adjacent
+      rmr->add_committed_region(addr + cs, 2 * cs, stack);
+      R r[] = { {addr, 5 * cs} };
+      check(rmr, r);
+    }
+
+    // Cleanup
+    rmr->remove_uncommitted_region(addr, 5 * cs);
+    ASSERT_EQ(rmr->committed_size(), 0u);
+
+
+    // Commit adjacent and overlapping regions with different stacks
+
+    { // Commit two non-adjacent regions
+      rmr->add_committed_region(addr, 2 * cs, stack);
+      rmr->add_committed_region(addr + 3 * cs, 2 * cs, stack);
+      R r[] = { {addr,          2 * cs},
+                {addr + 3 * cs, 2 * cs} };
+      check(rmr, r);
+    }
+
+    { // Commit adjacent and overlapping
+      rmr->add_committed_region(addr + 2 * cs, 2 * cs, stack2);
+      R r[] = { {addr,          2 * cs},
+                {addr + 2 * cs, 2 * cs},
+                {addr + 4 * cs,     cs} };
+      check(rmr, r);
+    }
+
+    // revert to two non-adjacent regions
+    rmr->add_committed_region(addr, 5 * cs, stack);
+    rmr->remove_uncommitted_region(addr + 2 * cs, cs);
+    ASSERT_EQ(rmr->committed_size(), 4 * cs);
+
+    { // Commit overlapping and adjacent
+      rmr->add_committed_region(addr + cs, 2 * cs, stack2);
+      R r[] = { {addr,              cs},
+                {addr +     cs, 2 * cs},
+                {addr + 3 * cs, 2 * cs} };
+      check(rmr, r);
+    }
+  }
+
+  static void test_add_committed_region_overlapping() {
+    VirtualMemoryTracker::initialize(NMT_detail);
+    VirtualMemoryTracker::late_initialize(NMT_detail);
+
+    address addr = (address)0x10000000;
+    size_t size  = 0x01000000;
+
+    address frame1 = (address)0x1234;
+    address frame2 = (address)0x1235;
+
+    NativeCallStack stack(&frame1, 1);
+    NativeCallStack stack2(&frame2, 1);
+
+    // Add the reserved memory
+    VirtualMemoryTracker::add_reserved_region(addr, size, stack, mtTest);
+
+    // Fetch the added RMR added above
+    ReservedMemoryRegion* rmr = VirtualMemoryTracker::_reserved_regions->find(ReservedMemoryRegion(addr, size));
+
+    ASSERT_EQ(rmr->size(), size);
+    ASSERT_EQ(rmr->base(), addr);
+
+    // Commit Size Granularity
+    const size_t cs = 0x1000;
+
+    // With same stack
+
+    { // Commit one region
+      rmr->add_committed_region(addr, cs, stack);
+      R r[] = { {addr, cs} };
+      check(rmr, r);
+    }
+
+    { // Commit the same region
+      rmr->add_committed_region(addr, cs, stack);
+      R r[] = { {addr, cs} };
+      check(rmr, r);
+    }
+
+    { // Commit a succeeding region
+      rmr->add_committed_region(addr + cs, cs, stack);
+      R r[] = { {addr, 2 * cs} };
+      check(rmr, r);
+    }
+
+    { // Commit  over two regions
+      rmr->add_committed_region(addr, 2 * cs, stack);
+      R r[] = { {addr, 2 * cs} };
+      check(rmr, r);
+    }
+
+    {// Commit first part of a region
+      rmr->add_committed_region(addr, cs, stack);
+      R r[] = { {addr, 2 * cs} };
+      check(rmr, r);
+    }
+
+    { // Commit second part of a region
+      rmr->add_committed_region(addr + cs, cs, stack);
+      R r[] = { {addr, 2 * cs} };
+      check(rmr, r);
+    }
+
+    { // Commit a third part
+      rmr->add_committed_region(addr + 2 * cs, cs, stack);
+      R r[] = { {addr, 3 * cs} };
+      check(rmr, r);
+    }
+
+    { // Commit in the middle of a region
+      rmr->add_committed_region(addr + 1 * cs, cs, stack);
+      R r[] = { {addr, 3 * cs} };
+      check(rmr, r);
+    }
+
+    // Cleanup
+    rmr->remove_uncommitted_region(addr, 3 * cs);
+    ASSERT_EQ(rmr->committed_size(), 0u);
+
+    // With preceding region
+
+    rmr->add_committed_region(addr,              cs, stack);
+    rmr->add_committed_region(addr + 2 * cs, 3 * cs, stack);
+
+    rmr->add_committed_region(addr + 2 * cs,     cs, stack);
+    {
+      R r[] = { {addr,              cs},
+                {addr + 2 * cs, 3 * cs} };
+      check(rmr, r);
+    }
+
+    rmr->add_committed_region(addr + 3 * cs,     cs, stack);
+    {
+      R r[] = { {addr,              cs},
+                {addr + 2 * cs, 3 * cs} };
+      check(rmr, r);
+    }
+
+    rmr->add_committed_region(addr + 4 * cs,     cs, stack);
+    {
+      R r[] = { {addr,              cs},
+                {addr + 2 * cs, 3 * cs} };
+      check(rmr, r);
+    }
+
+    // Cleanup
+    rmr->remove_uncommitted_region(addr, 5 * cs);
+    ASSERT_EQ(rmr->committed_size(), 0u);
+
+    // With different stacks
+
+    { // Commit one region
+      rmr->add_committed_region(addr, cs, stack);
+      R r[] = { {addr, cs} };
+      check(rmr, r);
+    }
+
+    { // Commit the same region
+      rmr->add_committed_region(addr, cs, stack2);
+      R r[] = { {addr, cs} };
+      check(rmr, r);
+    }
+
+    { // Commit a succeeding region
+      rmr->add_committed_region(addr + cs, cs, stack);
+      R r[] = { {addr,      cs},
+                {addr + cs, cs} };
+      check(rmr, r);
+    }
+
+    { // Commit  over two regions
+      rmr->add_committed_region(addr, 2 * cs, stack);
+      R r[] = { {addr, 2 * cs} };
+      check(rmr, r);
+    }
+
+    {// Commit first part of a region
+      rmr->add_committed_region(addr, cs, stack2);
+      R r[] = { {addr,      cs},
+                {addr + cs, cs} };
+      check(rmr, r);
+    }
+
+    { // Commit second part of a region
+      rmr->add_committed_region(addr + cs, cs, stack2);
+      R r[] = { {addr, 2 * cs} };
+      check(rmr, r);
+    }
+
+    { // Commit a third part
+      rmr->add_committed_region(addr + 2 * cs, cs, stack2);
+      R r[] = { {addr, 3 * cs} };
+      check(rmr, r);
+    }
+
+    { // Commit in the middle of a region
+      rmr->add_committed_region(addr + 1 * cs, cs, stack);
+      R r[] = { {addr,          cs},
+                {addr +     cs, cs},
+                {addr + 2 * cs, cs} };
+      check(rmr, r);
+    }
+  }
+
+  static void test_add_committed_region() {
+    test_add_committed_region_adjacent();
+    test_add_committed_region_adjacent_overlapping();
+    test_add_committed_region_overlapping();
+  }
+
+  template <size_t S>
+  static void fix(R r[S]) {
+
+  }
+
+  static void test_remove_uncommitted_region() {
+    VirtualMemoryTracker::initialize(NMT_detail);
+    VirtualMemoryTracker::late_initialize(NMT_detail);
+
+    address addr = (address)0x10000000;
+    size_t size  = 0x01000000;
+
+    address frame1 = (address)0x1234;
+    address frame2 = (address)0x1235;
+
+    NativeCallStack stack(&frame1, 1);
+    NativeCallStack stack2(&frame2, 1);
+
+    // Add the reserved memory
+    VirtualMemoryTracker::add_reserved_region(addr, size, stack, mtTest);
+
+    // Fetch the added RMR added above
+    ReservedMemoryRegion* rmr = VirtualMemoryTracker::_reserved_regions->find(ReservedMemoryRegion(addr, size));
+
+    ASSERT_EQ(rmr->size(), size);
+    ASSERT_EQ(rmr->base(), addr);
+
+    // Commit Size Granularity
+    const size_t cs = 0x1000;
+
+    { // Commit regions
+      rmr->add_committed_region(addr, 3 * cs, stack);
+      R r[] = { {addr, 3 * cs} };
+      check(rmr, r);
+
+      // Remove only existing
+      rmr->remove_uncommitted_region(addr, 3 * cs);
+      check_empty(rmr);
+    }
+
+    {
+      rmr->add_committed_region(addr + 0 * cs, cs, stack);
+      rmr->add_committed_region(addr + 2 * cs, cs, stack);
+      rmr->add_committed_region(addr + 4 * cs, cs, stack);
+
+      { // Remove first
+        rmr->remove_uncommitted_region(addr, cs);
+        R r[] = { {addr + 2 * cs, cs},
+                  {addr + 4 * cs, cs} };
+        check(rmr, r);
+      }
+
+      // add back
+      rmr->add_committed_region(addr,          cs, stack);
+
+      { // Remove middle
+        rmr->remove_uncommitted_region(addr + 2 * cs, cs);
+        R r[] = { {addr + 0 * cs, cs},
+                  {addr + 4 * cs, cs} };
+        check(rmr, r);
+      }
+
+      // add back
+      rmr->add_committed_region(addr + 2 * cs, cs, stack);
+
+      { // Remove end
+        rmr->remove_uncommitted_region(addr + 4 * cs, cs);
+        R r[] = { {addr + 0 * cs, cs},
+                  {addr + 2 * cs, cs} };
+        check(rmr, r);
+      }
+
+      rmr->remove_uncommitted_region(addr, 5 * cs);
+      check_empty(rmr);
+    }
+
+    { // Remove larger region
+      rmr->add_committed_region(addr + 1 * cs, cs, stack);
+      rmr->remove_uncommitted_region(addr, 3 * cs);
+      check_empty(rmr);
+    }
+
+    { // Remove smaller region - in the middle
+      rmr->add_committed_region(addr, 3 * cs, stack);
+      rmr->remove_uncommitted_region(addr + 1 * cs, cs);
+      R r[] = { { addr + 0 * cs, cs},
+                { addr + 2 * cs, cs} };
+      check(rmr, r);
+
+      rmr->remove_uncommitted_region(addr, 3 * cs);
+      check_empty(rmr);
+    }
+
+    { // Remove smaller region - at the beginning
+      rmr->add_committed_region(addr, 3 * cs, stack);
+      rmr->remove_uncommitted_region(addr + 0 * cs, cs);
+      R r[] = { { addr + 1 * cs, 2 * cs} };
+      check(rmr, r);
+
+      rmr->remove_uncommitted_region(addr, 3 * cs);
+      check_empty(rmr);
+    }
+
+    { // Remove smaller region - at the end
+      rmr->add_committed_region(addr, 3 * cs, stack);
+      rmr->remove_uncommitted_region(addr + 2 * cs, cs);
+      R r[] = { { addr, 2 * cs} };
+      check(rmr, r);
+
+      rmr->remove_uncommitted_region(addr, 3 * cs);
+      check_empty(rmr);
+    }
+
+    { // Remove smaller, overlapping region - at the beginning
+      rmr->add_committed_region(addr + 1 * cs, 4 * cs, stack);
+      rmr->remove_uncommitted_region(addr, 2 * cs);
+      R r[] = { { addr + 2 * cs, 3 * cs} };
+      check(rmr, r);
+
+      rmr->remove_uncommitted_region(addr + 1 * cs, 4 * cs);
+      check_empty(rmr);
+    }
+
+    { // Remove smaller, overlapping region - at the end
+      rmr->add_committed_region(addr, 3 * cs, stack);
+      rmr->remove_uncommitted_region(addr + 2 * cs, 2 * cs);
+      R r[] = { { addr, 2 * cs} };
+      check(rmr, r);
+
+      rmr->remove_uncommitted_region(addr, 3 * cs);
+      check_empty(rmr);
+    }
+  }
+};
+
+TEST_VM(VirtualMemoryTracker, add_committed_region) {
+  VirtualMemoryTrackerTest::test_add_committed_region();
+}
+
+TEST_VM(VirtualMemoryTracker, remove_uncommitted_region) {
+  VirtualMemoryTrackerTest::test_remove_uncommitted_region();
+}
+
+#endif // INCLUDE_NMT
--- a/test/hotspot/jtreg/ProblemList.txt	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/ProblemList.txt	Sun Feb 25 04:59:43 2018 +0100
@@ -46,16 +46,11 @@
 compiler/compilercontrol/jcmd/ClearDirectivesFileStackTest.java 8140405 generic-all
 compiler/jvmci/compilerToVM/GetResolvedJavaTypeTest.java 8158860 generic-all
 compiler/jvmci/compilerToVM/InvalidateInstalledCodeTest.java 8163894 generic-all
-compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/NativeCallTest.java 8180324 generic-all
-compiler/startup/SmallCodeCacheStartup.java 8134286 generic-all
 compiler/tiered/LevelTransitionTest.java 8067651 generic-all
 compiler/types/correctness/CorrectnessTest.java 8066173 generic-all
 compiler/types/correctness/OffTest.java 8066173 generic-all
 compiler/c2/Test8007294.java 8192992 generic-all
 
-# aot test intermittently failing in jprt 8175791
-compiler/aot/DeoptimizationTest.java 8175791 windows-all
-
 applications/ctw/modules/java_desktop.java 8189604 windows-all
 applications/ctw/modules/jdk_jconsole.java 8189604 windows-all
 
@@ -69,7 +64,7 @@
 gc/g1/humongousObjects/TestHeapCounters.java 8178918 generic-all
 gc/g1/TestVerifyGCType.java 8193067 generic-all
 gc/stress/gclocker/TestGCLockerWithParallel.java 8180622 generic-all
-gc/stress/gclocker/TestGCLockerWithG1.java 8179226 generic-all
+gc/stress/gclocker/TestGCLockerWithG1.java 8180622 generic-all
 gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterMinorGC.java 8177765 generic-all
 gc/stress/TestJNIBlockFullGC/TestJNIBlockFullGC.java 8192647 generic-all
 
@@ -78,8 +73,6 @@
 # :hotspot_runtime
 
 runtime/CompressedOops/UseCompressedOops.java 8079353 generic-all
-# This test is disabled since it will stress NMT and timeout during normal testing
-runtime/NMT/MallocStressTest.java 8166548 generic-all
 runtime/SharedArchiveFile/DefaultUseWithClient.java 8154204 generic-all
 
 #############################################################################
@@ -87,9 +80,8 @@
 # :hotspot_serviceability
 
 serviceability/jdwp/AllModulesCommandTest.java 8170541 generic-all
-serviceability/sa/sadebugd/SADebugDTest.java 8163805 generic-all
-serviceability/jvmti/ModuleAwareAgents/ClassFileLoadHook/MAAClassFileLoadHook.java 8173936 generic-all
 serviceability/sa/TestRevPtrsForInvokeDynamic.java 8191270 generic-all
+
 #############################################################################
 
 # :hotspot_misc
--- a/test/hotspot/jtreg/TEST.ROOT	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/TEST.ROOT	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2005, 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
@@ -54,6 +54,7 @@
     vm.aot \
     vm.cds \
     vm.cds.custom.loaders \
+    vm.cds.archived.java.heap \
     vm.graal.enabled \
     docker.support
 
--- a/test/hotspot/jtreg/TEST.groups	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/TEST.groups	Sun Feb 25 04:59:43 2018 +0100
@@ -54,11 +54,16 @@
 hotspot_native_sanity = \
   native_sanity
 
-hotspot_tier1_common = \
+tier1_common = \
   sanity/BasicVMTest.java \
   gtest/GTestWrapper.java
 
-hotspot_tier1_compiler_1 = \
+tier1_compiler = \
+  :tier1_compiler_1 \
+  :tier1_compiler_2 \
+  :tier1_compiler_3
+
+tier1_compiler_1 = \
   compiler/aot/ \
   compiler/arraycopy/ \
   compiler/c1/ \
@@ -74,7 +79,7 @@
   -compiler/c2/Test6603011.java \
   -compiler/c2/Test6912517.java \
 
-hotspot_tier1_compiler_2 = \
+tier1_compiler_2 = \
   compiler/classUnloading/ \
   compiler/codecache/ \
   compiler/codegen/ \
@@ -93,7 +98,7 @@
   -compiler/codecache/stress \
   -compiler/gcbarriers/PreserveFPRegistersTest.java
 
-hotspot_tier1_compiler_3 = \
+tier1_compiler_3 = \
   compiler/intrinsics/ \
   compiler/jsr292/ \
   compiler/loopopts/ \
@@ -116,14 +121,20 @@
 
 hotspot_not_fast_compiler = \
   :hotspot_compiler \
-  -:hotspot_tier1_compiler_1 \
-  -:hotspot_tier1_compiler_2 \
-  -:hotspot_tier1_compiler_3 \
+  -:tier1_compiler_1 \
+  -:tier1_compiler_2 \
+  -:tier1_compiler_3 \
 
-hotspot_tier1_gc_1 = \
+tier1_gc = \
+  :tier1_gc_1 \
+  :tier1_gc_2 \
+  :tier1_gc_gcold \
+  :tier1_gc_gcbasher 
+
+tier1_gc_1 = \
   gc/g1/
 
-hotspot_tier1_gc_2 = \
+tier1_gc_2 = \
   sanity/ExecuteInternalVMTests.java \
   gc/ \
   -gc/g1/ \
@@ -133,19 +144,19 @@
   -gc/cms/TestMBeanCMS.java \
   -gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java
 
-hotspot_tier1_gc_gcold = \
+tier1_gc_gcold = \
   gc/stress/gcold/TestGCOldWithG1.java
   gc/stress/gcold/TestGCOldWithCMS.java
   gc/stress/gcold/TestGCOldWithSerial.java
   gc/stress/gcold/TestGCOldWithParallel.java
 
-hotspot_tier1_gc_gcbasher = \
+tier1_gc_gcbasher = \
   gc/stress/gcbasher/TestGCBasherWithG1.java \
   gc/stress/gcbasher/TestGCBasherWithCMS.java \
   gc/stress/gcbasher/TestGCBasherWithSerial.java \
   gc/stress/gcbasher/TestGCBasherWithParallel.java
 
-hotspot_tier1_runtime = \
+tier1_runtime = \
   runtime/ \
  -runtime/6626217/Test6626217.sh \
  -runtime/7100935 \
@@ -190,7 +201,7 @@
  -runtime/containers/ \
   sanity/ \
   testlibrary_tests/TestMutuallyExclusivePlatformPredicates.java \
- -:hotspot_tier1_runtime_appcds_exclude
+ -:tier1_runtime_appcds_exclude
 
 hotspot_cds = \
   runtime/SharedArchiveFile/ \
@@ -202,30 +213,26 @@
   runtime/appcds/
 
 # A subset of AppCDS tests to be run in JPRT push
-hotspot_tier1_runtime_appcds = \
+tier1_runtime_appcds = \
   runtime/appcds/HelloTest.java \
   runtime/appcds/sharedStrings/SharedStringsBasic.java \
   runtime/appcds/ClassLoaderTest.java
 
-hotspot_tier1_runtime_appcds_exclude = \
+tier1_runtime_appcds_exclude = \
   runtime/appcds/ \
-  -:hotspot_tier1_runtime_appcds
+  -:tier1_runtime_appcds
 
-hotspot_tier1_serviceability = \
+tier1_serviceability = \
   serviceability/dcmd/compiler \
   serviceability/logging \
   serviceability/sa
 
-hotspot_tier1 = \
-  :hotspot_tier1_common \
-  :hotspot_tier1_compiler_1 \
-  :hotspot_tier1_compiler_2 \
-  :hotspot_tier1_compiler_3 \
-  :hotspot_tier1_gc_1 \
-  :hotspot_tier1_gc_2 \
-  :hotspot_tier1_gc_gcold \
-  :hotspot_tier1_runtime \
-  :hotspot_tier1_serviceability
+tier1 = \
+  :tier1_common \
+  :tier1_compiler \
+  :tier1_gc \
+  :tier1_runtime \
+  :tier1_serviceability
 
 hotspot_tier2_runtime = \
   runtime/ \
@@ -233,20 +240,20 @@
  -runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java \
  -runtime/Thread/TestThreadDumpMonitorContention.java \
  -runtime/containers/ \
- -:hotspot_tier1_runtime \
- -:hotspot_tier1_serviceability \
+ -:tier1_runtime \
+ -:tier1_serviceability \
  -:hotspot_tier2_runtime_platform_agnostic
 
 hotspot_tier2_runtime_platform_agnostic = \
   runtime/SelectionResolution \
- -:hotspot_tier1_runtime
+ -:tier1_runtime
 
 hotspot_tier3_runtime = \
   runtime/ \
   serviceability/ \
  -runtime/containers/ \
- -:hotspot_tier1_runtime \
- -:hotspot_tier1_serviceability \
+ -:tier1_runtime \
+ -:tier1_serviceability \
  -:hotspot_tier2_runtime_platform_agnostic \
  -:hotspot_tier2_runtime
 
--- a/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/AndnTestI.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/AndnTestI.java	Sun Feb 25 04:59:43 2018 +0100
@@ -24,7 +24,7 @@
 /*
  * @test
  * @bug 8031321
- * @requires vm.flavor == "server" & !vm.emulatedClient
+ * @requires vm.flavor == "server" & !vm.emulatedClient & !vm.graal.enabled
  * @library /test/lib /
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/AndnTestL.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/AndnTestL.java	Sun Feb 25 04:59:43 2018 +0100
@@ -24,7 +24,7 @@
 /*
  * @test
  * @bug 8031321
- * @requires vm.flavor == "server" & !vm.emulatedClient
+ * @requires vm.flavor == "server" & !vm.emulatedClient & !vm.graal.enabled
  * @library /test/lib /
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/BlsiTestI.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/BlsiTestI.java	Sun Feb 25 04:59:43 2018 +0100
@@ -24,7 +24,7 @@
 /*
  * @test
  * @bug 8031321
- * @requires vm.flavor == "server" & !vm.emulatedClient
+ * @requires vm.flavor == "server" & !vm.emulatedClient & !vm.graal.enabled
  * @library /test/lib /
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/BlsiTestL.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/BlsiTestL.java	Sun Feb 25 04:59:43 2018 +0100
@@ -24,7 +24,7 @@
 /*
  * @test
  * @bug 8031321
- * @requires vm.flavor == "server" & !vm.emulatedClient
+ * @requires vm.flavor == "server" & !vm.emulatedClient & !vm.graal.enabled
  * @library /test/lib /
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/BlsmskTestI.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/BlsmskTestI.java	Sun Feb 25 04:59:43 2018 +0100
@@ -24,7 +24,7 @@
 /*
  * @test
  * @bug 8031321
- * @requires vm.flavor == "server" & !vm.emulatedClient
+ * @requires vm.flavor == "server" & !vm.emulatedClient & !vm.graal.enabled
  * @library /test/lib /
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/BlsmskTestL.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/BlsmskTestL.java	Sun Feb 25 04:59:43 2018 +0100
@@ -24,7 +24,7 @@
 /*
  * @test
  * @bug 8031321
- * @requires vm.flavor == "server" & !vm.emulatedClient
+ * @requires vm.flavor == "server" & !vm.emulatedClient & !vm.graal.enabled
  * @library /test/lib /
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/BlsrTestI.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/BlsrTestI.java	Sun Feb 25 04:59:43 2018 +0100
@@ -24,7 +24,7 @@
 /*
  * @test
  * @bug 8031321
- * @requires vm.flavor == "server" & !vm.emulatedClient
+ * @requires vm.flavor == "server" & !vm.emulatedClient & !vm.graal.enabled
  * @library /test/lib /
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/BlsrTestL.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/BlsrTestL.java	Sun Feb 25 04:59:43 2018 +0100
@@ -24,7 +24,7 @@
 /*
  * @test
  * @bug 8031321
- * @requires vm.flavor == "server" & !vm.emulatedClient
+ * @requires vm.flavor == "server" & !vm.emulatedClient & !vm.graal.enabled
  * @library /test/lib /
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/LZcntTestI.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/LZcntTestI.java	Sun Feb 25 04:59:43 2018 +0100
@@ -24,7 +24,7 @@
 /*
  * @test
  * @bug 8031321
- * @requires vm.flavor == "server" & !vm.emulatedClient
+ * @requires vm.flavor == "server" & !vm.emulatedClient & !vm.graal.enabled
  * @library /test/lib /
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/LZcntTestL.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/LZcntTestL.java	Sun Feb 25 04:59:43 2018 +0100
@@ -24,7 +24,7 @@
 /*
  * @test
  * @bug 8031321
- * @requires vm.flavor == "server" & !vm.emulatedClient
+ * @requires vm.flavor == "server" & !vm.emulatedClient & !vm.graal.enabled
  * @library /test/lib /
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/TZcntTestI.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/TZcntTestI.java	Sun Feb 25 04:59:43 2018 +0100
@@ -24,7 +24,7 @@
 /*
  * @test
  * @bug 8031321
- * @requires vm.flavor == "server" & !vm.emulatedClient
+ * @requires vm.flavor == "server" & !vm.emulatedClient & !vm.graal.enabled
  * @library /test/lib /
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/TZcntTestL.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/TZcntTestL.java	Sun Feb 25 04:59:43 2018 +0100
@@ -24,7 +24,7 @@
 /*
  * @test
  * @bug 8031321
- * @requires vm.flavor == "server" & !vm.emulatedClient
+ * @requires vm.flavor == "server" & !vm.emulatedClient & !vm.graal.enabled
  * @library /test/lib /
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/test/hotspot/jtreg/runtime/CommandLine/VMDeprecatedOptions.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/runtime/CommandLine/VMDeprecatedOptions.java	Sun Feb 25 04:59:43 2018 +0100
@@ -41,7 +41,6 @@
     public static final String[][] DEPRECATED_OPTIONS = {
         // deprecated non-alias flags:
         {"MaxGCMinorPauseMillis",     "1032"},
-        {"MustCallLoadClassInternal", "false"},
         {"MaxRAMFraction",            "8"},
         {"MinRAMFraction",            "2"},
         {"InitialRAMFraction",        "64"},
@@ -106,7 +105,6 @@
 
     public static void main(String[] args) throws Throwable {
         testDeprecated(DEPRECATED_OPTIONS);  // Make sure that each deprecated option is mentioned in the output.
-        testDeprecatedDiagnostic("UnsyncloadClass", "false");
         testDeprecatedDiagnostic("IgnoreUnverifiableClassesDuringDump", "false");
     }
 }
--- a/test/hotspot/jtreg/runtime/Metaspace/DefineClass.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/runtime/Metaspace/DefineClass.java	Sun Feb 25 04:59:43 2018 +0100
@@ -1,4 +1,5 @@
 /*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2017 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -29,17 +30,9 @@
  * @library /test/lib
  * @run main/othervm test.DefineClass defineClass
  * @run main/othervm test.DefineClass defineSystemClass
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions
-                     -XX:+UnsyncloadClass -XX:+AllowParallelDefineClass
-                     test.DefineClass defineClassParallel
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions
-                     -XX:+UnsyncloadClass -XX:-AllowParallelDefineClass
+ * @run main/othervm -XX:+AllowParallelDefineClass
                      test.DefineClass defineClassParallel
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions
-                     -XX:-UnsyncloadClass -XX:+AllowParallelDefineClass
-                     test.DefineClass defineClassParallel
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions
-                     -XX:-UnsyncloadClass -XX:-AllowParallelDefineClass
+ * @run main/othervm -XX:-AllowParallelDefineClass
                      test.DefineClass defineClassParallel
  * @run main/othervm -Djdk.attach.allowAttachSelf test.DefineClass redefineClass
  * @run main/othervm -Djdk.attach.allowAttachSelf test.DefineClass redefineClassWithError
@@ -126,7 +119,7 @@
             }
             catch (LinkageError jle) {
                 // Expected with a parallel capable class loader and
-                // -XX:+UnsyncloadClass or -XX:+AllowParallelDefineClass
+                // -XX:+AllowParallelDefineClass
                 pcl.incrementLinkageErrors();
             }
 
@@ -320,7 +313,7 @@
             }
             System.out.print("Counted " + pcl.getLinkageErrors() + " LinkageErrors ");
             System.out.println(pcl.getLinkageErrors() == 0 ?
-                    "" : "(use -XX:+UnsyncloadClass and/or -XX:+AllowParallelDefineClass to avoid this)");
+                    "" : "(use -XX:+AllowParallelDefineClass to avoid this)");
             System.gc();
             System.out.println("System.gc()");
             // After System.gc() we expect to remain with two instances: one is the initial version which is
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/NMT/VirtualAllocAttemptReserveMemoryAt.java	Sun Feb 25 04:59:43 2018 +0100
@@ -0,0 +1,84 @@
+/*
+ * 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
+ * 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 that os::attempt_reserve_memory_at doesn't register the memory as committed
+ * @key nmt jcmd
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ * @build sun.hotspot.WhiteBox
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail VirtualAllocAttemptReserveMemoryAt
+ *
+ */
+
+import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.JDKToolFinder;
+
+import sun.hotspot.WhiteBox;
+
+import static jdk.test.lib.Asserts.*;
+
+public class VirtualAllocAttemptReserveMemoryAt {
+
+    public static WhiteBox wb = WhiteBox.getWhiteBox();
+
+    public static void main(String args[]) throws Exception {
+        long reserveSize = 4 * 1024 * 1024; // 4096KB
+
+        String pid = Long.toString(ProcessTools.getProcessId());
+        ProcessBuilder pb = new ProcessBuilder();
+
+        // Find an address
+        long addr = wb.NMTReserveMemory(reserveSize);
+
+        // Release it
+        wb.NMTReleaseMemory(addr, reserveSize);
+
+        long attempt_addr = wb.NMTAttemptReserveMemoryAt(addr, reserveSize);
+
+        if (attempt_addr == 0) {
+            // We didn't manage ot get the requested memory address.
+            // It's not necessarily a bug, so giving up.
+            return;
+        }
+
+        assertEQ(addr, attempt_addr);
+
+        pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid,
+                "VM.native_memory", "detail" });
+
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+
+        output.shouldContain("Test (reserved=4096KB, committed=0KB)");
+
+        wb.NMTReleaseMemory(addr, reserveSize);
+        output = new OutputAnalyzer(pb.start());
+        output.shouldNotContain("Test (reserved=");
+        output.shouldNotMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*"
+                + Long.toHexString(addr + reserveSize) + "\\] reserved 4096KB for Test");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/NMT/VirtualAllocCommitMerge.java	Sun Feb 25 04:59:43 2018 +0100
@@ -0,0 +1,326 @@
+/*
+ * 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
+ * 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 merging of committed virtual memory and that we track it correctly
+ * @key nmt jcmd
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ * @build sun.hotspot.WhiteBox
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail VirtualAllocCommitMerge
+ *
+ */
+
+import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.JDKToolFinder;
+
+import sun.hotspot.WhiteBox;
+
+public class VirtualAllocCommitMerge {
+
+    public static WhiteBox wb = WhiteBox.getWhiteBox();
+
+    public static void main(String args[]) throws Exception {
+        OutputAnalyzer output;
+        long commitSize = 128 * 1024; // 128KB
+        long reserveSize = 4 * 1024 * 1024; // 4096KB
+        long addr;
+
+        String pid = Long.toString(ProcessTools.getProcessId());
+        ProcessBuilder pb = new ProcessBuilder();
+
+        // reserve
+        addr = wb.NMTReserveMemory(reserveSize);
+        pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid,
+                "VM.native_memory", "detail" });
+
+        output = new OutputAnalyzer(pb.start());
+        checkReservedCommittedSummary(output, "4096KB", "0KB");
+        checkReserved(output, addr, reserveSize, "4096KB");
+
+        long addrA = addr + (0 * commitSize);
+        long addrB = addr + (1 * commitSize);
+        long addrC = addr + (2 * commitSize);
+        long addrD = addr + (3 * commitSize);
+        long addrE = addr + (4 * commitSize);
+
+        {
+            // commit overlapping ABC, A, B, C
+            wb.NMTCommitMemory(addrA, 3 * commitSize);
+
+            output = new OutputAnalyzer(pb.start());
+            checkReservedCommittedSummary(output, "4096KB", "384KB");
+            checkReserved(output, addr, reserveSize, "4096KB");
+
+            checkCommitted(output, addrA, 3 * commitSize, "384KB");
+
+
+            wb.NMTCommitMemory(addrA, commitSize);
+
+            output = new OutputAnalyzer(pb.start());
+            checkReservedCommittedSummary(output, "4096KB", "384KB");
+            checkReserved(output, addr, reserveSize, "4096KB");
+
+            checkCommitted(output, addrA, 3 * commitSize, "384KB");
+
+
+            wb.NMTCommitMemory(addrB, commitSize);
+
+            output = new OutputAnalyzer(pb.start());
+            checkReservedCommittedSummary(output, "4096KB", "384KB");
+            checkReserved(output, addr, reserveSize, "4096KB");
+
+            checkCommitted(output, addrA, 3 * commitSize, "384KB");
+
+            wb.NMTCommitMemory(addrC, commitSize);
+
+            output = new OutputAnalyzer(pb.start());
+            checkReservedCommittedSummary(output, "4096KB", "384KB");
+            checkReserved(output, addr, reserveSize, "4096KB");
+
+            checkCommitted(output, addrA, 3 * commitSize, "384KB");
+
+            // uncommit
+            wb.NMTUncommitMemory(addrA, 3 * commitSize);
+
+            output = new OutputAnalyzer(pb.start());
+            checkReservedCommittedSummary(output, "4096KB", "0KB");
+        }
+
+        // Test discontigous areas
+        {
+            // commit ACE
+            wb.NMTCommitMemory(addrA, commitSize);
+            wb.NMTCommitMemory(addrC, commitSize);
+            wb.NMTCommitMemory(addrE, commitSize);
+
+            output = new OutputAnalyzer(pb.start());
+            checkReservedCommittedSummary(output, "4096KB", "384KB");
+            checkReserved(output, addr, reserveSize, "4096KB");
+
+            checkCommitted(output, addrA, commitSize, "128KB");
+            checkCommitted(output, addrC, commitSize, "128KB");
+            checkCommitted(output, addrE, commitSize, "128KB");
+
+            // uncommit ACE
+            wb.NMTUncommitMemory(addrA, commitSize);
+            wb.NMTUncommitMemory(addrC, commitSize);
+            wb.NMTUncommitMemory(addrE, commitSize);
+
+            output = new OutputAnalyzer(pb.start());
+            checkReservedCommittedSummary(output, "4096KB", "0KB");
+        }
+
+        // Test contiguous areas
+        {
+            // commit AB
+            wb.NMTCommitMemory(addrA, commitSize);
+            wb.NMTCommitMemory(addrB, commitSize);
+
+            output = new OutputAnalyzer(pb.start());
+            checkReservedCommittedSummary(output, "4096KB", "256KB");
+            checkReserved(output, addr, reserveSize, "4096KB");
+
+            checkCommitted(output, addrA, 2 * commitSize, "256KB");
+
+            // uncommit AB
+            wb.NMTUncommitMemory(addrA, commitSize);
+            wb.NMTUncommitMemory(addrB, commitSize);
+
+            output = new OutputAnalyzer(pb.start());
+            checkReservedCommittedSummary(output, "4096KB", "0KB");
+        }
+
+        {
+            // commit BA
+            wb.NMTCommitMemory(addrB, commitSize);
+            wb.NMTCommitMemory(addrA, commitSize);
+
+            output = new OutputAnalyzer(pb.start());
+            checkReservedCommittedSummary(output, "4096KB", "256KB");
+            checkReserved(output, addr, reserveSize, "4096KB");
+
+            checkCommitted(output, addrA, 2 * commitSize, "256KB");
+
+            // uncommit AB
+            wb.NMTUncommitMemory(addrB, commitSize);
+            wb.NMTUncommitMemory(addrA, commitSize);
+
+            output = new OutputAnalyzer(pb.start());
+            checkReservedCommittedSummary(output, "4096KB", "0KB");
+        }
+
+        {
+            // commit ABC
+            wb.NMTCommitMemory(addrA, commitSize);
+            wb.NMTCommitMemory(addrB, commitSize);
+            wb.NMTCommitMemory(addrC, commitSize);
+
+            output = new OutputAnalyzer(pb.start());
+            checkReservedCommittedSummary(output, "4096KB", "384KB");
+            checkReserved(output, addr, reserveSize, "4096KB");
+
+            checkCommitted(output, addrA, 3 * commitSize, "384KB");
+
+            // uncommit
+            wb.NMTUncommitMemory(addrA, commitSize);
+            wb.NMTUncommitMemory(addrB, commitSize);
+            wb.NMTUncommitMemory(addrC, commitSize);
+
+            output = new OutputAnalyzer(pb.start());
+            checkReservedCommittedSummary(output, "4096KB", "0KB");
+        }
+
+        {
+            // commit ACB
+            wb.NMTCommitMemory(addrA, commitSize);
+            wb.NMTCommitMemory(addrC, commitSize);
+            wb.NMTCommitMemory(addrB, commitSize);
+
+            output = new OutputAnalyzer(pb.start());
+            checkReservedCommittedSummary(output, "4096KB", "384KB");
+            checkReserved(output, addr, reserveSize, "4096KB");
+
+            checkCommitted(output, addrA, 3 * commitSize, "384KB");
+
+            // uncommit
+            wb.NMTUncommitMemory(addrA, commitSize);
+            wb.NMTUncommitMemory(addrC, commitSize);
+            wb.NMTUncommitMemory(addrB, commitSize);
+
+            output = new OutputAnalyzer(pb.start());
+            checkReservedCommittedSummary(output, "4096KB", "0KB");
+        }
+
+        {
+            // commit BAC
+            wb.NMTCommitMemory(addrB, commitSize);
+            wb.NMTCommitMemory(addrA, commitSize);
+            wb.NMTCommitMemory(addrC, commitSize);
+
+            output = new OutputAnalyzer(pb.start());
+            checkReservedCommittedSummary(output, "4096KB", "384KB");
+            checkReserved(output, addr, reserveSize, "4096KB");
+
+            checkCommitted(output, addrA, 3 * commitSize, "384KB");
+
+            // uncommit
+            wb.NMTUncommitMemory(addrB, commitSize);
+            wb.NMTUncommitMemory(addrA, commitSize);
+            wb.NMTUncommitMemory(addrC, commitSize);
+
+            output = new OutputAnalyzer(pb.start());
+            checkReservedCommittedSummary(output, "4096KB", "0KB");
+        }
+
+        {
+            // commit BCA
+            wb.NMTCommitMemory(addrB, commitSize);
+            wb.NMTCommitMemory(addrC, commitSize);
+            wb.NMTCommitMemory(addrA, commitSize);
+
+            output = new OutputAnalyzer(pb.start());
+            checkReservedCommittedSummary(output, "4096KB", "384KB");
+            checkReserved(output, addr, reserveSize, "4096KB");
+
+            checkCommitted(output, addrA, 3 * commitSize, "384KB");
+
+            // uncommit
+            wb.NMTUncommitMemory(addrB, commitSize);
+            wb.NMTUncommitMemory(addrC, commitSize);
+            wb.NMTUncommitMemory(addrA, commitSize);
+
+            output = new OutputAnalyzer(pb.start());
+            checkReservedCommittedSummary(output, "4096KB", "0KB");
+        }
+
+        {
+            // commit CAB
+            wb.NMTCommitMemory(addrC, commitSize);
+            wb.NMTCommitMemory(addrA, commitSize);
+            wb.NMTCommitMemory(addrB, commitSize);
+
+            output = new OutputAnalyzer(pb.start());
+            checkReservedCommittedSummary(output, "4096KB", "384KB");
+            checkReserved(output, addr, reserveSize, "4096KB");
+
+            checkCommitted(output, addrA, 3 * commitSize, "384KB");
+
+            // uncommit
+            wb.NMTUncommitMemory(addrC, commitSize);
+            wb.NMTUncommitMemory(addrA, commitSize);
+            wb.NMTUncommitMemory(addrB, commitSize);
+
+            output = new OutputAnalyzer(pb.start());
+            checkReservedCommittedSummary(output, "4096KB", "0KB");
+        }
+
+        {
+            // commit CBA
+            wb.NMTCommitMemory(addrC, commitSize);
+            wb.NMTCommitMemory(addrB, commitSize);
+            wb.NMTCommitMemory(addrA, commitSize);
+
+            output = new OutputAnalyzer(pb.start());
+            checkReservedCommittedSummary(output, "4096KB", "384KB");
+            checkReserved(output, addr, reserveSize, "4096KB");
+
+            checkCommitted(output, addrA, 3 * commitSize, "384KB");
+
+            // uncommit
+            wb.NMTUncommitMemory(addrC, commitSize);
+            wb.NMTUncommitMemory(addrB, commitSize);
+            wb.NMTUncommitMemory(addrA, commitSize);
+
+            output = new OutputAnalyzer(pb.start());
+            checkReservedCommittedSummary(output, "4096KB", "0KB");
+        }
+
+        // release
+        wb.NMTReleaseMemory(addr, reserveSize);
+        output = new OutputAnalyzer(pb.start());
+        output.shouldNotContain("Test (reserved=");
+        output.shouldNotMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*"
+                + Long.toHexString(addr + reserveSize) + "\\] reserved 4096KB for Test");
+    }
+
+    public static void checkReservedCommittedSummary(OutputAnalyzer output, String reservedString, String committedString) {
+        output.shouldContain("Test (reserved=" + reservedString + ", committed=" + committedString + ")");
+    }
+
+    public static void checkReserved(OutputAnalyzer output, long addr, long size, String sizeString) {
+        output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*"
+                           + Long.toHexString(addr + size)
+                           + "\\] reserved 4096KB for Test");
+    }
+
+    public static void checkCommitted(OutputAnalyzer output, long addr, long size, String sizeString) {
+        output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*"
+                           + Long.toHexString(addr + size)
+                           + "\\] committed " + sizeString + " from.*");
+    }
+}
--- a/test/hotspot/jtreg/runtime/RedefineTests/RedefineRunningMethods.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/runtime/RedefineTests/RedefineRunningMethods.java	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8055008
+ * @bug 8055008 8197901
  * @summary Redefine EMCP and non-EMCP methods that are running in an infinite loop
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
@@ -31,8 +31,9 @@
  *          java.instrument
  *          jdk.jartool/sun.tools.jar
  * @run main RedefineClassHelper
- * @run main/othervm -javaagent:redefineagent.jar -Xlog:redefine+class+iklass+add=trace,redefine+class+iklass+purge=trace RedefineRunningMethods
+ * @run main/othervm -javaagent:redefineagent.jar -Xlog:redefine+class+iklass+add=trace,redefine+class+iklass+purge=trace,all=trace:file=all.log RedefineRunningMethods
  */
+// Test is executed with full trace logging redirected to a file to ensure there is no crash during logging anonymous classes - see JDK-8197901
 public class RedefineRunningMethods {
 
     public static String newB =
--- a/test/hotspot/jtreg/runtime/SharedArchiveFile/ArchiveDoesNotExist.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/runtime/SharedArchiveFile/ArchiveDoesNotExist.java	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -23,7 +23,6 @@
 
 /**
  * @test ArchiveDoesNotExist
- * @requires vm.cds
  * @summary Test how VM handles "file does not exist" situation while
  *          attempting to use CDS archive. JVM should exit gracefully
  *          when sharing mode is ON, and continue w/o sharing if sharing
--- a/test/hotspot/jtreg/runtime/SharedArchiveFile/CdsDifferentCompactStrings.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/runtime/SharedArchiveFile/CdsDifferentCompactStrings.java	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -23,7 +23,6 @@
 
 /**
  * @test CdsDifferentCompactStrings
- * @requires vm.cds
  * @summary CDS (class data sharing) requires the same -XX:[+-]CompactStrings
  *          setting between archive creation time and load time.
  * @requires vm.cds
--- a/test/hotspot/jtreg/runtime/SharedArchiveFile/CdsDifferentObjectAlignment.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/runtime/SharedArchiveFile/CdsDifferentObjectAlignment.java	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -23,7 +23,6 @@
 
 /**
  * @test CdsDifferentObjectAlignment
- * @requires vm.cds
  * @summary Testing CDS (class data sharing) using varying object alignment.
  *          Using different object alignment for each dump/load pair.
  *          This is a negative test; using  object alignment for loading that
--- a/test/hotspot/jtreg/runtime/SharedArchiveFile/CdsSameObjectAlignment.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/runtime/SharedArchiveFile/CdsSameObjectAlignment.java	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -23,7 +23,6 @@
 
 /**
  * @test CdsSameObjectAlignment
- * @requires vm.cds
  * @summary Testing CDS (class data sharing) using varying object alignment.
  *          Using same object alignment for each dump/load pair
  * @requires vm.cds
--- a/test/hotspot/jtreg/runtime/SharedArchiveFile/DumpSharedDictionary.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/runtime/SharedArchiveFile/DumpSharedDictionary.java	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 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
@@ -25,9 +25,6 @@
  * @test
  * @bug 8130072
  * @summary Check that Shared Dictionary is printed out with jcmd
- * Feature support: compressed oops/kptrs, 64-bit os, not on windows
- * @requires vm.cds
- * @requires (sun.arch.data.model != "32") & (os.family != "windows")
  * @requires vm.cds
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
@@ -47,7 +44,6 @@
             ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
                 "-XX:+UnlockDiagnosticVMOptions",
                 "-XX:SharedArchiveFile=./DumpSharedDictionary.jsa",
-                "-XX:+UseCompressedOops",
                 "-Xshare:dump");
 
             OutputAnalyzer out = CDSTestUtils.executeAndLog(pb, "dump");
@@ -58,7 +54,6 @@
             pb = ProcessTools.createJavaProcessBuilder(
                     "-XX:+UnlockDiagnosticVMOptions",
                     "-XX:SharedArchiveFile=./DumpSharedDictionary.jsa",
-                    "-XX:+UseCompressedOops",
                     "-Dtest.jdk=" + testjdkPath,
                     "-Xshare:on", "DumpSharedDictionary", "test");
 
--- a/test/hotspot/jtreg/runtime/SharedArchiveFile/PrintSharedArchiveAndExit.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/runtime/SharedArchiveFile/PrintSharedArchiveAndExit.java	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -23,7 +23,6 @@
 
 /**
  * @test
- * @requires vm.cds
  * @bug 8066670
  * @summary Testing -XX:+PrintSharedArchiveAndExit option
  * @requires vm.cds
--- a/test/hotspot/jtreg/runtime/SharedArchiveFile/SASymbolTableTest.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/runtime/SharedArchiveFile/SASymbolTableTest.java	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -23,7 +23,6 @@
 
 /**
  * @test SASymbolTableTest
- * @requires vm.cds
  * @summary Walk symbol table using SA, with and without CDS.
  * @requires vm.cds
  * @library /test/lib
--- a/test/hotspot/jtreg/runtime/SharedArchiveFile/SharedArchiveFile.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/runtime/SharedArchiveFile/SharedArchiveFile.java	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -23,7 +23,6 @@
 
 /**
  * @test
- * @requires vm.cds
  * @bug 8014138
  * @summary Testing new -XX:SharedArchiveFile=<file-name> option
  * @requires vm.cds
--- a/test/hotspot/jtreg/runtime/SharedArchiveFile/SharedBaseAddress.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/runtime/SharedArchiveFile/SharedBaseAddress.java	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -23,7 +23,6 @@
 
 /**
  * @test SharedBaseAddress
- * @requires vm.cds
  * @summary Test variety of values for SharedBaseAddress, making sure
  *          VM handles normal values as well as edge values w/o a crash.
  * @requires vm.cds
--- a/test/hotspot/jtreg/runtime/SharedArchiveFile/SharedStrings.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/runtime/SharedArchiveFile/SharedStrings.java	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -23,13 +23,9 @@
 
 /**
  * @test
- * @requires vm.cds
  * @summary Check to make sure that shared strings in the bootstrap CDS archive
  *          are actually shared
- * Feature support: G1GC only, compressed oops/kptrs, 64-bit os, not on windows
- * @requires (sun.arch.data.model != "32") & (os.family != "windows")
- * @requires vm.cds
- * @requires vm.gc.G1
+ * @requires vm.cds.archived.java.heap
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
  *          java.management
@@ -51,8 +47,6 @@
         ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
             "-XX:+UnlockDiagnosticVMOptions",
             "-XX:SharedArchiveFile=./SharedStrings.jsa",
-            "-XX:+UseG1GC",
-            "-XX:+UseCompressedOops",
             "-Xlog:cds,cds+hashtables",
             // Needed for bootclasspath match, for CDS to work with WhiteBox API
             "-Xbootclasspath/a:" + ClassFileInstaller.getJarPath("whitebox.jar"),
@@ -65,8 +59,6 @@
         pb = ProcessTools.createJavaProcessBuilder(
                 "-XX:+UnlockDiagnosticVMOptions",
                 "-XX:SharedArchiveFile=./SharedStrings.jsa",
-                // these are required modes for shared strings
-                "-XX:+UseCompressedOops", "-XX:+UseG1GC",
                 // needed for access to white box test API
                 "-Xbootclasspath/a:" + ClassFileInstaller.getJarPath("whitebox.jar"),
                 "-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI",
--- a/test/hotspot/jtreg/runtime/SharedArchiveFile/SharedStringsDedup.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/runtime/SharedArchiveFile/SharedStringsDedup.java	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -23,12 +23,8 @@
 
 /**
  * @test SharedStringsDedup
- * @requires vm.cds
  * @summary Test -Xshare:auto with shared strings and -XX:+UseStringDeduplication
- * Feature support: G1GC only, compressed oops/kptrs, 64-bit os, not on windows
- * @requires (sun.arch.data.model != "32") & (os.family != "windows")
- * @requires vm.cds
- * @requires vm.gc.G1
+ * @requires vm.cds.archived.java.heap
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
  *          java.management
@@ -46,9 +42,8 @@
 public class SharedStringsDedup {
     public static void main(String[] args) throws Exception {
         OutputAnalyzer out =
-            CDSTestUtils.createArchive("-XX:+UseCompressedOops", "-XX:+UseG1GC");
+            CDSTestUtils.createArchive();
         CDSTestUtils.checkDump(out, "Shared string table stats");
-        CDSTestUtils.runWithArchiveAndCheck("-XX:+UseCompressedOops", "-XX:+UseG1GC",
-                                            "-XX:+UseStringDeduplication");
+        CDSTestUtils.runWithArchiveAndCheck("-XX:+UseStringDeduplication");
     }
 }
--- a/test/hotspot/jtreg/runtime/SharedArchiveFile/SharedStringsRunAuto.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/runtime/SharedArchiveFile/SharedStringsRunAuto.java	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -23,12 +23,8 @@
 
 /**
  * @test SharedStringsAuto
- * @requires vm.cds
  * @summary Test -Xshare:auto with shared strings.
- * Feature support: G1GC only, compressed oops/kptrs, 64-bit os, not on windows
- * @requires (sun.arch.data.model != "32") & (os.family != "windows")
- * @requires vm.cds
- * @requires vm.gc.G1
+ * @requires vm.cds.archived.java.heap
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
  *          java.management
@@ -42,8 +38,8 @@
 public class SharedStringsRunAuto {
     public static void main(String[] args) throws Exception {
         OutputAnalyzer out =
-            CDSTestUtils.createArchive("-XX:+UseCompressedOops", "-XX:+UseG1GC");
+            CDSTestUtils.createArchive();
         CDSTestUtils.checkDump(out, "Shared string table stats");
-        CDSTestUtils.runWithArchiveAndCheck("-XX:+UseCompressedOops", "-XX:+UseG1GC");
+        CDSTestUtils.runWithArchiveAndCheck();
     }
 }
--- a/test/hotspot/jtreg/runtime/SharedArchiveFile/SharedSymbolTableBucketSize.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/runtime/SharedArchiveFile/SharedSymbolTableBucketSize.java	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -23,7 +23,6 @@
 
 /**
  * @test
- * @requires vm.cds
  * @bug 8059510
  * @summary Test SharedSymbolTableBucketSize option
  * @requires vm.cds
--- a/test/hotspot/jtreg/runtime/SharedArchiveFile/SpaceUtilizationCheck.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/runtime/SharedArchiveFile/SpaceUtilizationCheck.java	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -23,7 +23,6 @@
 
 /**
  * @test SpaceUtilizationCheck
- * @requires vm.cds
  * @summary Check if the space utilization for shared spaces is adequate
  * @requires vm.cds
  * @library /test/lib
--- a/test/hotspot/jtreg/runtime/SharedArchiveFile/TestInterpreterMethodEntries.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/runtime/SharedArchiveFile/TestInterpreterMethodEntries.java	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -23,7 +23,6 @@
 
 /**
  * @test InterpreterMethodEntries
- * @requires vm.cds
  * @bug 8169711
  * @summary Test interpreter method entries for intrinsics with CDS (class data sharing)
  *          and different settings of the intrinsic flag during dump/use of the archive.
--- a/test/hotspot/jtreg/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TransformInterfaceAndImplementor.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TransformInterfaceAndImplementor.java	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -23,7 +23,6 @@
 
 /**
  * @test
- * @requires vm.cds
  * @summary Exercise initial transformation (ClassFileLoadHook)
  *  with CDS with Interface/Implementor pair
  * @library /test/lib /runtime/SharedArchiveFile /testlibrary/jvmti
--- a/test/hotspot/jtreg/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TransformSuperAndSubClasses.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TransformSuperAndSubClasses.java	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -24,7 +24,6 @@
 
 /**
  * @test
- * @requires vm.cds
  * @summary Exercise initial transformation (ClassFileLoadHook)
  *  with CDS with SubClass and SuperClass
  * @library /test/lib /runtime/SharedArchiveFile /testlibrary/jvmti
--- a/test/hotspot/jtreg/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TransformSuperSubTwoPckgs.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TransformSuperSubTwoPckgs.java	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -24,7 +24,6 @@
 
 /**
  * @test
- * @requires vm.cds
  * @summary Exercise initial transformation (ClassFileLoadHook)
  *  with CDS with SubClass and SuperClass, each lives in own separate package
  * @library /test/lib /runtime/SharedArchiveFile /testlibrary/jvmti
--- a/test/hotspot/jtreg/runtime/appcds/ProhibitedPackage.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/ProhibitedPackage.java	Sun Feb 25 04:59:43 2018 +0100
@@ -26,7 +26,6 @@
  * @test
  * @summary AppCDS handling of prohibited package.
  * @requires vm.cds
- * @requires vm.cds
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/test/hotspot/jtreg/runtime/appcds/cacheObject/CheckCachedResolvedReferences.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/cacheObject/CheckCachedResolvedReferences.java	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 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
@@ -27,7 +27,6 @@
  * @summary Test resolved_references
  * @requires vm.cds
  * @requires vm.cds.custom.loaders
- * @requires (vm.gc=="null")
  * @library /test/lib /test/hotspot/jtreg/runtime/appcds
  * @modules java.base/jdk.internal.misc
  * @modules java.management
--- a/test/hotspot/jtreg/runtime/appcds/cacheObject/DumpTimeVerifyFailure.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/cacheObject/DumpTimeVerifyFailure.java	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 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
@@ -26,9 +26,7 @@
  * @test
  * @summary Dump time should not crash if any class with shared strings fails verification due to missing dependencies.
  * @bug 8186789
- * @requires vm.cds
- * @requires (sun.arch.data.model != "32") & (os.family != "windows")
- * @requires (vm.gc=="null")
+ * @requires vm.cds.archived.java.heap
  * @library /test/lib /test/hotspot/jtreg/runtime/appcds
  * @modules java.base/jdk.internal.misc
  * @modules java.management
--- a/test/hotspot/jtreg/runtime/appcds/cacheObject/GCStressTest.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/cacheObject/GCStressTest.java	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 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
@@ -25,9 +25,7 @@
 /*
  * @test
  * @summary
- * @requires vm.cds
- * @requires (sun.arch.data.model != "32") & (os.family != "windows")
- * @requires (vm.gc=="null")
+ * @requires vm.cds.archived.java.heap
  * @library /test/lib /test/hotspot/jtreg/runtime/appcds
  * @modules java.base/jdk.internal.misc
  * @modules java.management
--- a/test/hotspot/jtreg/runtime/appcds/cacheObject/OpenArchiveRegion.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/cacheObject/OpenArchiveRegion.java	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 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
@@ -25,8 +25,7 @@
 /*
  * @test
  * @summary Test open archive heap regions
- * @requires vm.cds
- * @requires (sun.arch.data.model != "32") & (os.family != "windows")
+ * @requires vm.cds.archived.java.heap
  * @requires (vm.gc=="null")
  * @library /test/lib /test/hotspot/jtreg/runtime/appcds
  * @modules java.base/jdk.internal.misc
--- a/test/hotspot/jtreg/runtime/appcds/cacheObject/RangeNotWithinHeap.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/cacheObject/RangeNotWithinHeap.java	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 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
@@ -28,9 +28,8 @@
  *          mapped due to out of range, and -Xshare:on should not fail. Test on
  *          linux 64-bit only since the HeapBaseMinAddress value is platform specific.
  *          The value used in the test may cause different behavior on other platforms.
- * @requires vm.cds
- * @requires (os.family == "linux") & (os.arch == "amd64") & (sun.arch.data.model == "64")
- * @requires (vm.gc=="null")
+ * @requires vm.cds.archived.java.heap
+ * @requires os.family == "linux"
  * @library /test/lib /test/hotspot/jtreg/runtime/appcds
  * @modules java.base/jdk.internal.misc
  * @modules java.management
--- a/test/hotspot/jtreg/runtime/appcds/cacheObject/RedefineClassTest.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/cacheObject/RedefineClassTest.java	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 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
@@ -26,10 +26,7 @@
  * @test
  * @summary Redefine shared class. GC should not cause crash with cached resolved_references.
  * @library /test/lib /test/hotspot/jtreg/runtime/appcds /test/hotspot/jtreg/runtime/appcds/test-classes /test/hotspot/jtreg/runtime/appcds/jvmti
- * @requires vm.cds
- * @requires vm.gc.G1
- * @requires vm.flavor != "minimal"
- * @requires (sun.arch.data.model != "32") & (os.family != "windows")
+ * @requires vm.cds.archived.java.heap
  * @modules java.base/jdk.internal.misc
  *          jdk.jartool/sun.tools.jar
  *          java.management
--- a/test/hotspot/jtreg/runtime/appcds/javaldr/GCSharedStringsDuringDump.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/javaldr/GCSharedStringsDuringDump.java	Sun Feb 25 04:59:43 2018 +0100
@@ -27,10 +27,7 @@
  * @summary Similar to GCDuringDumping.java, this test adds the -XX:SharedArchiveConfigFile
  *          option for testing the interaction with GC and shared strings.
  * @library /test/lib /test/hotspot/jtreg/runtime/appcds /test/hotspot/jtreg/runtime/appcds/test-classes
- * @requires (sun.arch.data.model != "32") & (os.family != "windows")
- * @requires vm.cds
- * @requires vm.flavor != "minimal"
- * @requires vm.gc.G1
+ * @requires vm.cds.archived.java.heap
  * @modules java.base/jdk.internal.misc
  *          jdk.jartool/sun.tools.jar
  *          java.management
@@ -94,8 +91,6 @@
             OutputAnalyzer output = TestCommon.dump(
                                 appJar, TestCommon.list("GCSharedStringsDuringDumpWb"),
                                 bootClassPath, extraArg, "-Xmx32m", gcLog,
-                                "-XX:+UseCompressedOops", "-XX:+UseG1GC",
-                                "-XX:SharedReadOnlySize=30m",
                                 "-XX:SharedArchiveConfigFile=" + sharedArchiveCfgFile);
 
             if (output.getStdout().contains("Too many string space regions") ||
@@ -108,8 +103,6 @@
                 TestCommon.testDump(
                     appJar, TestCommon.list("GCSharedStringsDuringDumpWb"),
                     bootClassPath, extraArg, "-Xmx8g", "-XX:NewSize=8m", gcLog,
-                    "-XX:+UseCompressedOops", "-XX:+UseG1GC",
-                    "-XX:SharedReadOnlySize=30m",
                     "-XX:SharedArchiveConfigFile=" + sharedArchiveCfgFile);
             }
 
@@ -118,8 +111,6 @@
                 bootClassPath,
                 "-Xmx32m",
                 "-XX:+PrintSharedSpaces",
-                "-XX:+UseCompressedOops",
-                "-XX:+UseG1GC",
                 "-XX:+UnlockDiagnosticVMOptions",
                 "-XX:+WhiteBoxAPI",
                 "-XX:SharedReadOnlySize=30m",
--- a/test/hotspot/jtreg/runtime/appcds/sharedStrings/ExerciseGC.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/ExerciseGC.java	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -25,9 +25,7 @@
 /*
  * @test
  * @summary Exercise GC with shared strings
- * @requires vm.cds
- * @requires vm.gc.G1
- * @requires (sun.arch.data.model != "32") & (os.family != "windows")
+ * @requires vm.cds.archived.java.heap
  * @library /test/hotspot/jtreg/runtime/appcds /test/lib
  * @modules java.base/jdk.internal.misc
  * @modules java.management
--- a/test/hotspot/jtreg/runtime/appcds/sharedStrings/FlagCombo.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/FlagCombo.java	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -25,9 +25,7 @@
 /*
  * @test
  * @summary Test relevant combinations of command line flags with shared strings
- * @requires vm.cds
- * @requires (sun.arch.data.model != "32") & (os.family != "windows")
- * @requires (vm.gc=="null")
+ * @requires vm.cds.archived.java.heap
  * @library /test/lib /test/hotspot/jtreg/runtime/appcds
  * @modules java.base/jdk.internal.misc
  * @modules java.management
--- a/test/hotspot/jtreg/runtime/appcds/sharedStrings/IncompatibleOptions.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/IncompatibleOptions.java	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -26,9 +26,7 @@
  * @test
  * @summary Test options that are incompatible with use of shared strings
  *          Also test mismatch in oops encoding between dump time and run time
- * Feature support: G1GC only, compressed oops/kptrs, 64-bit os, not on windows
- * @requires (sun.arch.data.model != "32") & (os.family != "windows")
- * @requires vm.cds
+ * @requires vm.cds.archived.java.heap
  * @requires (vm.gc=="null")
  * @library /test/lib /test/hotspot/jtreg/runtime/appcds
  * @modules java.base/jdk.internal.misc
--- a/test/hotspot/jtreg/runtime/appcds/sharedStrings/InternSharedString.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/InternSharedString.java	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -25,10 +25,7 @@
 /*
  * @test
  * @summary Test shared strings together with string intern operation
- * Feature support: G1GC only, compressed oops/kptrs, 64-bit os, not on windows
- * @requires (sun.arch.data.model != "32") & (os.family != "windows")
- * @requires vm.cds
- * @requires vm.gc.G1
+ * @requires vm.cds.archived.java.heap
  * @library /test/hotspot/jtreg/runtime/appcds /test/lib
  * @modules java.base/jdk.internal.misc
  * @modules java.management
--- a/test/hotspot/jtreg/runtime/appcds/sharedStrings/InvalidFileFormat.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/InvalidFileFormat.java	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -25,10 +25,7 @@
 /*
  * @test
  * @summary Check most common errors in file format
- * Feature support: G1GC only, compressed oops/kptrs, 64-bit os, not on windows
- * @requires (sun.arch.data.model != "32") & (os.family != "windows")
- * @requires vm.cds
- * @requires vm.gc.G1
+ * @requires vm.cds.archived.java.heap
  * @library /test/lib /test/hotspot/jtreg/runtime/appcds
  * @modules java.base/jdk.internal.misc
  * @modules java.management
--- a/test/hotspot/jtreg/runtime/appcds/sharedStrings/LargePages.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/LargePages.java	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -25,10 +25,7 @@
 /*
  * @test
  * @summary Basic shared string test with large pages
- * Feature support: G1GC only, compressed oops/kptrs, 64-bit os, not on windows
- * @requires (sun.arch.data.model != "32") & (os.family != "windows")
- * @requires vm.cds
- * @requires vm.gc.G1
+ * @requires vm.cds.archived.java.heap
  * @library /test/lib /test/hotspot/jtreg/runtime/appcds
  * @modules java.base/jdk.internal.misc
  * @modules java.management
--- a/test/hotspot/jtreg/runtime/appcds/sharedStrings/LockSharedStrings.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/LockSharedStrings.java	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -25,10 +25,7 @@
 /*
  * @test
  * @summary Test locking on shared strings
- * Feature support: G1GC only, compressed oops/kptrs, 64-bit os, not on windows
- * @requires (sun.arch.data.model != "32") & (os.family != "windows")
- * @requires vm.cds
- * @requires vm.gc.G1
+ * @requires vm.cds.archived.java.heap
  * @library /test/hotspot/jtreg/runtime/appcds /test/lib
  * @modules java.base/jdk.internal.misc
  * @modules java.management
--- a/test/hotspot/jtreg/runtime/appcds/sharedStrings/SharedStringsBasic.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/SharedStringsBasic.java	Sun Feb 25 04:59:43 2018 +0100
@@ -25,10 +25,7 @@
 /*
  * @test
  * @summary Basic test for shared strings
- * Feature support: G1GC only, compressed oops/kptrs, 64-bit os, not on windows
- * @requires (sun.arch.data.model != "32") & (os.family != "windows")
- * @requires vm.cds
- * @requires vm.gc.G1
+ * @requires vm.cds.archived.java.heap
  * @library /test/hotspot/jtreg/runtime/appcds /test/lib
  * @modules java.base/jdk.internal.misc
  * @modules java.management
@@ -52,8 +49,6 @@
         ProcessBuilder dumpPb = ProcessTools.createJavaProcessBuilder(true,
           TestCommon.makeCommandLineForAppCDS(
             "-XX:+UseAppCDS",
-            "-XX:+UseCompressedOops",
-            "-XX:+UseG1GC",
             "-cp", appJar,
             "-XX:SharedArchiveConfigFile=" + sharedArchiveConfigFile,
             "-XX:SharedArchiveFile=./SharedStringsBasic.jsa",
@@ -67,8 +62,6 @@
         ProcessBuilder runPb = ProcessTools.createJavaProcessBuilder(true,
           TestCommon.makeCommandLineForAppCDS(
             "-XX:+UseAppCDS",
-            "-XX:+UseCompressedOops",
-            "-XX:+UseG1GC",
             "-cp", appJar,
             "-XX:SharedArchiveFile=./SharedStringsBasic.jsa",
             "-Xshare:auto",
--- a/test/hotspot/jtreg/runtime/appcds/sharedStrings/SharedStringsBasicPlus.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/SharedStringsBasicPlus.java	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -25,10 +25,7 @@
 /*
  * @test
  * @summary Basic plus test for shared strings
- * Feature support: G1GC only, compressed oops/kptrs, 64-bit os, not on windows
- * @requires (sun.arch.data.model != "32") & (os.family != "windows")
- * @requires vm.cds
- * @requires vm.gc.G1
+ * @requires vm.cds.archived.java.heap
  * @library /test/hotspot/jtreg/runtime/appcds /test/lib
  * @modules java.base/jdk.internal.misc
  * @modules java.management
--- a/test/hotspot/jtreg/runtime/appcds/sharedStrings/SharedStringsStress.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/SharedStringsStress.java	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 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
@@ -25,10 +25,7 @@
 /*
  * @test
  * @summary Write a lots of shared strings.
- * Feature support: G1GC only, compressed oops/kptrs, 64-bit os, not on windows
- * @requires (sun.arch.data.model != "32") & (os.family != "windows")
- * @requires vm.cds
- * @requires vm.gc.G1
+ * @requires vm.cds.archived.java.heap
  * @library /test/hotspot/jtreg/runtime/appcds /test/lib
  * @modules jdk.jartool/sun.tools.jar
  * @build HelloString
--- a/test/hotspot/jtreg/runtime/appcds/sharedStrings/SharedStringsWbTest.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/SharedStringsWbTest.java	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -25,10 +25,7 @@
 /*
  * @test
  * @summary White box test for shared strings
- * Feature support: G1GC only, compressed oops/kptrs, 64-bit os, not on windows
- * @requires (sun.arch.data.model != "32") & (os.family != "windows")
- * @requires vm.cds
- * @requires vm.gc.G1
+ * @requires vm.cds.archived.java.heap
  * @library /test/lib /test/hotspot/jtreg/runtime/appcds
  * @modules java.base/jdk.internal.misc
  * @modules java.management
--- a/test/hotspot/jtreg/runtime/containers/docker/TestCPUAwareness.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/hotspot/jtreg/runtime/containers/docker/TestCPUAwareness.java	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 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
@@ -94,14 +94,23 @@
             // Test subset of cpuset with one element
             if (cpuSet.size() >= 1) {
                 String testCpuSet = CPUSetsReader.listToString(cpuSet, 1);
-                testAPCCombo(testCpuSet, 200*1000, 100*1000,   4*1024, 1);
+                testAPCCombo(testCpuSet, 200*1000, 100*1000,   4*1024, true, 1);
             }
 
             // Test subset of cpuset with two elements
             if (cpuSet.size() >= 2) {
                 String testCpuSet = CPUSetsReader.listToString(cpuSet, 2);
-                testAPCCombo(testCpuSet, 200*1000, 100*1000, 4*1024, 2);
-                testAPCCombo(testCpuSet, 200*1000, 100*1000, 1*1024, 2);
+                testAPCCombo(testCpuSet, 200*1000, 100*1000, 4*1024, true, 2);
+                testAPCCombo(testCpuSet, 200*1000, 100*1000, 1023,   true, 2);
+                testAPCCombo(testCpuSet, 200*1000, 100*1000, 1023,   false,  1);
+            }
+
+            // Test subset of cpuset with three elements
+            if (cpuSet.size() >= 3) {
+                String testCpuSet = CPUSetsReader.listToString(cpuSet, 3);
+                testAPCCombo(testCpuSet, 100*1000, 100*1000, 2*1024, true, 1);
+                testAPCCombo(testCpuSet, 200*1000, 100*1000, 1023,   true, 2);
+                testAPCCombo(testCpuSet, 200*1000, 100*1000, 1023,   false,  1);
             }
         }
     }
@@ -159,12 +168,14 @@
 
     // Test correctess of automatically selected active processor cound
     private static void testAPCCombo(String cpuset, int quota, int period, int shares,
-                                         int expectedAPC) throws Exception {
+                                     boolean usePreferContainerQuotaForCPUCount,
+                                     int expectedAPC) throws Exception {
         Common.logNewTestCase("test APC Combo");
         System.out.println("cpuset = " + cpuset);
         System.out.println("quota = " + quota);
         System.out.println("period = " + period);
         System.out.println("shares = " + period);
+        System.out.println("usePreferContainerQuotaForCPUCount = " + usePreferContainerQuotaForCPUCount);
         System.out.println("expectedAPC = " + expectedAPC);
 
         expectedAPC = adjustExpectedAPCForAvailableCPUs(expectedAPC);
@@ -174,6 +185,9 @@
             .addDockerOpts("--cpu-period=" + period)
             .addDockerOpts("--cpu-quota=" + quota)
             .addDockerOpts("--cpu-shares=" + shares);
+
+        if (!usePreferContainerQuotaForCPUCount) opts.addJavaOpts("-XX:-PreferContainerQuotaForCPUCount");
+
         Common.run(opts)
             .shouldMatch("active_processor_count.*" + expectedAPC);
     }
--- a/test/jdk/TEST.groups	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/jdk/TEST.groups	Sun Feb 25 04:59:43 2018 +0100
@@ -28,6 +28,7 @@
 tier1 = \
     :jdk_lang \
     :jdk_util \
+    :jdk_svc_sanity \
     sun/nio/cs/ISO8859x.java \
     java/nio/Buffer \
     com/sun/crypto/provider/Cipher \
--- a/test/jdk/com/sun/jdi/JDIScaffold.java	Wed Feb 28 15:28:46 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,595 +0,0 @@
-/*
- * Copyright (c) 1999, 2013, 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 com.sun.jdi.*;
-import com.sun.jdi.request.*;
-import com.sun.jdi.event.*;
-import java.util.*;
-import java.io.*;
-
-
-/**
- * Framework used by all JDI regression tests
- */
-abstract public class JDIScaffold {
-    private boolean shouldTrace = false;
-    private VMConnection connection;
-    private VirtualMachine vm;
-    private EventRequestManager requestManager;
-    private List listeners = Collections.synchronizedList(new LinkedList());
-    ThreadReference vmStartThread = null;
-    boolean vmDied = false;
-    boolean vmDisconnected = false;
-
-    static private class ArgInfo {
-        String targetVMArgs = "";
-        String targetAppCommandLine = "";
-        String connectorSpec = "com.sun.jdi.CommandLineLaunch:";
-        int traceFlags = 0;
-    }
-
-    static public interface TargetListener {
-        boolean eventSetReceived(EventSet set);
-        boolean eventSetComplete(EventSet set);
-        boolean eventReceived(Event event);
-        boolean breakpointReached(BreakpointEvent event);
-        boolean exceptionThrown(ExceptionEvent event);
-        boolean stepCompleted(StepEvent event);
-        boolean classPrepared(ClassPrepareEvent event);
-        boolean classUnloaded(ClassUnloadEvent event);
-        boolean methodEntered(MethodEntryEvent event);
-        boolean methodExited(MethodExitEvent event);
-        boolean fieldAccessed(AccessWatchpointEvent event);
-        boolean fieldModified(ModificationWatchpointEvent event);
-        boolean threadStarted(ThreadStartEvent event);
-        boolean threadDied(ThreadDeathEvent event);
-        boolean vmStarted(VMStartEvent event);
-        boolean vmDied(VMDeathEvent event);
-        boolean vmDisconnected(VMDisconnectEvent event);
-    }
-
-    static public class TargetAdapter implements TargetListener {
-        public boolean eventSetReceived(EventSet set) {
-            return false;
-        }
-        public boolean eventSetComplete(EventSet set) {
-            return false;
-        }
-        public boolean eventReceived(Event event) {
-            return false;
-        }
-        public boolean breakpointReached(BreakpointEvent event) {
-            return false;
-        }
-        public boolean exceptionThrown(ExceptionEvent event) {
-            return false;
-        }
-        public boolean stepCompleted(StepEvent event) {
-            return false;
-        }
-        public boolean classPrepared(ClassPrepareEvent event) {
-            return false;
-        }
-        public boolean classUnloaded(ClassUnloadEvent event) {
-            return false;
-        }
-        public boolean methodEntered(MethodEntryEvent event) {
-            return false;
-        }
-        public boolean methodExited(MethodExitEvent event) {
-            return false;
-        }
-        public boolean fieldAccessed(AccessWatchpointEvent event) {
-            return false;
-        }
-        public boolean fieldModified(ModificationWatchpointEvent event) {
-            return false;
-        }
-        public boolean threadStarted(ThreadStartEvent event) {
-            return false;
-        }
-        public boolean threadDied(ThreadDeathEvent event) {
-            return false;
-        }
-        public boolean vmStarted(VMStartEvent event) {
-            return false;
-        }
-        public boolean vmDied(VMDeathEvent event) {
-            return false;
-        }
-        public boolean vmDisconnected(VMDisconnectEvent event) {
-            return false;
-        }
-    }
-
-    private class EventHandler implements Runnable {
-        EventHandler() {
-            Thread thread = new Thread(this);
-            thread.setDaemon(true);
-            thread.start();
-        }
-
-        private boolean notifyEvent(TargetListener listener, Event event) {
-            if (listener.eventReceived(event) == true) {
-                return true;
-            } else if (event instanceof BreakpointEvent) {
-                return listener.breakpointReached((BreakpointEvent)event);
-            } else if (event instanceof ExceptionEvent) {
-                return listener.exceptionThrown((ExceptionEvent)event);
-            } else if (event instanceof StepEvent) {
-                return listener.stepCompleted((StepEvent)event);
-            } else if (event instanceof ClassPrepareEvent) {
-                return listener.classPrepared((ClassPrepareEvent)event);
-            } else if (event instanceof ClassUnloadEvent) {
-                return listener.classUnloaded((ClassUnloadEvent)event);
-            } else if (event instanceof MethodEntryEvent) {
-                return listener.methodEntered((MethodEntryEvent)event);
-            } else if (event instanceof MethodExitEvent) {
-                return listener.methodExited((MethodExitEvent)event);
-            } else if (event instanceof AccessWatchpointEvent) {
-                return listener.fieldAccessed((AccessWatchpointEvent)event);
-            } else if (event instanceof ModificationWatchpointEvent) {
-                return listener.fieldModified((ModificationWatchpointEvent)event);
-            } else if (event instanceof ThreadStartEvent) {
-                return listener.threadStarted((ThreadStartEvent)event);
-            } else if (event instanceof ThreadDeathEvent) {
-                return listener.threadDied((ThreadDeathEvent)event);
-            } else if (event instanceof VMStartEvent) {
-                return listener.vmStarted((VMStartEvent)event);
-            } else if (event instanceof VMDeathEvent) {
-                return listener.vmDied((VMDeathEvent)event);
-            } else if (event instanceof VMDisconnectEvent) {
-                return listener.vmDisconnected((VMDisconnectEvent)event);
-            } else {
-                throw new InternalError("Unknown event type: " + event.getClass());
-            }
-        }
-
-        private void traceSuspendPolicy(int policy) {
-            if (shouldTrace) {
-                switch (policy) {
-                case EventRequest.SUSPEND_NONE:
-                    traceln("JDI: runloop: suspend = SUSPEND_NONE");
-                    break;
-                case EventRequest.SUSPEND_ALL:
-                    traceln("JDI: runloop: suspend = SUSPEND_ALL");
-                    break;
-                case EventRequest.SUSPEND_EVENT_THREAD:
-                    traceln("JDI: runloop: suspend = SUSPEND_EVENT_THREAD");
-                    break;
-                }
-            }
-        }
-
-        public void run() {
-            boolean connected = true;
-            do {
-                try {
-                    EventSet set = vm.eventQueue().remove();
-                    traceSuspendPolicy(set.suspendPolicy());
-                    synchronized (listeners) {
-                        ListIterator iter = listeners.listIterator();
-                        while (iter.hasNext()) {
-                            TargetListener listener = (TargetListener)iter.next();
-                            traceln("JDI: runloop: listener = " + listener);
-                            if (listener.eventSetReceived(set) == true) {
-                                iter.remove();
-                            } else {
-                                Iterator jter = set.iterator();
-                                while (jter.hasNext()) {
-                                    Event event = (Event)jter.next();
-                                    traceln("JDI: runloop:    event = " + event.getClass());
-                                    if (event instanceof VMDisconnectEvent) {
-                                        connected = false;
-                                    }
-                                    if (notifyEvent(listener, event) == true) {
-                                        iter.remove();
-                                        break;
-                                    }
-                                }
-                                traceln("JDI: runloop:   end of events loop");
-                                if (listener.eventSetComplete(set) == true) {
-                                    iter.remove();
-                                }
-                            }
-                        traceln("JDI: runloop: end of listener");
-                        }
-                    }
-                } catch (InterruptedException e) {
-                }
-                traceln("JDI: runloop: end of outer loop");
-            } while (connected);
-        }
-    }
-
-    /**
-     * Constructor
-     */
-    public JDIScaffold() {
-    }
-
-    public void enableScaffoldTrace() {
-        this.shouldTrace = true;
-    }
-
-    public void disableScaffoldTrace() {
-        this.shouldTrace = false;
-    }
-
-
-    /*
-     * Test cases should implement tests in runTests and should
-     * initiate testing by calling run().
-     */
-    abstract protected void runTests() throws Exception;
-
-    final public void startTests() throws Exception {
-        try {
-            runTests();
-        } finally {
-            shutdown();
-        }
-    }
-
-    protected void println(String str) {
-        System.err.println(str);
-    }
-
-    protected void traceln(String str) {
-        if (shouldTrace) {
-            println(str);
-        }
-    }
-
-    private ArgInfo parseArgs(String args[]) {
-        ArgInfo argInfo = new ArgInfo();
-        for (int i = 0; i < args.length; i++) {
-            if (args[i].equals("-connect")) {
-                i++;
-                argInfo.connectorSpec = args[i];
-            } else if (args[i].equals("-trace")) {
-                i++;
-                argInfo.traceFlags = Integer.decode(args[i]).intValue();
-            } else if (args[i].startsWith("-J")) {
-                argInfo.targetVMArgs += (args[i].substring(2) + ' ');
-
-                /*
-                 * classpath can span two arguments so we need to handle
-                 * it specially.
-                 */
-                if (args[i].equals("-J-classpath")) {
-                    i++;
-                    argInfo.targetVMArgs += (args[i] + ' ');
-                }
-            } else {
-                argInfo.targetAppCommandLine += (args[i] + ' ');
-            }
-        }
-        return argInfo;
-    }
-
-    public void connect(String args[]) {
-        ArgInfo argInfo = parseArgs(args);
-
-        argInfo.targetVMArgs += VMConnection.getDebuggeeVMOptions();
-        connection = new VMConnection(argInfo.connectorSpec,
-                                      argInfo.traceFlags);
-        if (!connection.isLaunch()) {
-            throw new UnsupportedOperationException(
-                                 "Listening and Attaching not yet supported");
-        }
-
-        /*
-         * Add a listener to track VM start/death/disconnection and
-         * to update status fields accordingly.
-         */
-        addListener(new TargetAdapter() {
-                        public boolean vmStarted(VMStartEvent event) {
-                            traceln("JDI: listener1:  got VMStart");
-                            synchronized(JDIScaffold.this) {
-                                vmStartThread = event.thread();
-                                JDIScaffold.this.notifyAll();
-                            }
-                            return false;
-                        }
-
-                        public boolean vmDied(VMDeathEvent event) {
-                            traceln("JDI: listener1:  got VMDeath");
-                            synchronized(JDIScaffold.this) {
-                                vmDied = true;
-                                JDIScaffold.this.notifyAll();
-                            }
-                            return false;
-                        }
-
-                        public boolean vmDisconnected(VMDisconnectEvent event) {
-                            traceln("JDI: listener1:  got VMDisconnectedEvent");
-                            synchronized(JDIScaffold.this) {
-                                vmDisconnected = true;
-                                JDIScaffold.this.notifyAll();
-                            }
-                            return false;
-                        }
-                    });
-
-        if (connection.connector().name().equals("com.sun.jdi.CommandLineLaunch")) {
-            if (argInfo.targetVMArgs.length() > 0) {
-                if (connection.connectorArg("options").length() > 0) {
-                    throw new IllegalArgumentException("VM options in two places");
-                }
-                connection.setConnectorArg("options", argInfo.targetVMArgs);
-            }
-            if (argInfo.targetAppCommandLine.length() > 0) {
-                if (connection.connectorArg("main").length() > 0) {
-                    throw new IllegalArgumentException("Command line in two places");
-                }
-                connection.setConnectorArg("main", argInfo.targetAppCommandLine);
-            }
-        }
-
-        vm = connection.open();
-        requestManager = vm.eventRequestManager();
-        new EventHandler();
-    }
-
-
-    public VirtualMachine vm() {
-        return vm;
-    }
-
-    public EventRequestManager eventRequestManager() {
-        return requestManager;
-    }
-
-    public void addListener(TargetListener listener) {
-        listeners.add(listener);
-    }
-
-    public void removeListener(TargetListener listener) {
-        listeners.remove(listener);
-    }
-
-    public synchronized ThreadReference waitForVMStart() {
-        while ((vmStartThread == null) && !vmDisconnected) {
-            try {
-                wait();
-            } catch (InterruptedException e) {
-            }
-        }
-
-        if (vmStartThread == null) {
-            throw new VMDisconnectedException();
-        }
-
-        return vmStartThread;
-    }
-
-    public synchronized void waitForVMDeath() {
-        while (!vmDied && !vmDisconnected) {
-            try {
-                traceln("JDI: waitForVMDeath:  waiting");
-                wait();
-            } catch (InterruptedException e) {
-            }
-        }
-        traceln("JDI: waitForVMDeath:  done waiting");
-
-        if (!vmDied) {
-            throw new VMDisconnectedException();
-        }
-    }
-
-    public Event waitForRequestedEvent(final EventRequest request) {
-        class EventNotification {
-            Event event;
-            boolean disconnected = false;
-        }
-        final EventNotification en = new EventNotification();
-
-        TargetAdapter adapter = new TargetAdapter() {
-            public boolean eventReceived(Event event) {
-                if (request.equals(event.request())) {
-                    synchronized (en) {
-                        en.event = event;
-                        en.notifyAll();
-                    }
-                    return true;
-                } else if (event instanceof VMDisconnectEvent) {
-                    synchronized (en) {
-                        en.disconnected = true;
-                        en.notifyAll();
-                    }
-                    return true;
-                } else {
-                    return false;
-                }
-            }
-        };
-
-        addListener(adapter);
-
-        try {
-            synchronized (en) {
-                vm.resume();
-                while (!en.disconnected && (en.event == null)) {
-                    en.wait();
-                }
-            }
-        } catch (InterruptedException e) {
-            return null;
-        }
-
-        if (en.disconnected) {
-            throw new RuntimeException("VM Disconnected before requested event occurred");
-        }
-        return en.event;
-    }
-
-    private StepEvent doStep(ThreadReference thread, int gran, int depth) {
-        final StepRequest sr =
-                  requestManager.createStepRequest(thread, gran, depth);
-
-        sr.addClassExclusionFilter("java.*");
-        sr.addClassExclusionFilter("javax.*");
-        sr.addClassExclusionFilter("sun.*");
-        sr.addClassExclusionFilter("com.sun.*");
-        sr.addClassExclusionFilter("com.oracle.*");
-        sr.addClassExclusionFilter("oracle.*");
-        sr.addClassExclusionFilter("jdk.internal.*");
-        sr.addCountFilter(1);
-        sr.enable();
-        StepEvent retEvent = (StepEvent)waitForRequestedEvent(sr);
-        requestManager.deleteEventRequest(sr);
-        return retEvent;
-    }
-
-    public StepEvent stepIntoInstruction(ThreadReference thread) {
-        return doStep(thread, StepRequest.STEP_MIN, StepRequest.STEP_INTO);
-    }
-
-    public StepEvent stepIntoLine(ThreadReference thread) {
-        return doStep(thread, StepRequest.STEP_LINE, StepRequest.STEP_INTO);
-    }
-
-    public StepEvent stepOverInstruction(ThreadReference thread) {
-        return doStep(thread, StepRequest.STEP_MIN, StepRequest.STEP_OVER);
-    }
-
-    public StepEvent stepOverLine(ThreadReference thread) {
-        return doStep(thread, StepRequest.STEP_LINE, StepRequest.STEP_OVER);
-    }
-
-    public StepEvent stepOut(ThreadReference thread) {
-        return doStep(thread, StepRequest.STEP_LINE, StepRequest.STEP_OUT);
-    }
-
-    public BreakpointEvent resumeTo(Location loc) {
-        final BreakpointRequest request =
-            requestManager.createBreakpointRequest(loc);
-        request.addCountFilter(1);
-        request.enable();
-        return (BreakpointEvent)waitForRequestedEvent(request);
-    }
-
-    public ReferenceType findReferenceType(String name) {
-        List rts = vm.classesByName(name);
-        Iterator iter = rts.iterator();
-        while (iter.hasNext()) {
-            ReferenceType rt = (ReferenceType)iter.next();
-            if (rt.name().equals(name)) {
-                return rt;
-            }
-        }
-        return null;
-    }
-
-    public Method findMethod(ReferenceType rt, String name, String signature) {
-        List methods = rt.methods();
-        Iterator iter = methods.iterator();
-        while (iter.hasNext()) {
-            Method method = (Method)iter.next();
-            if (method.name().equals(name) &&
-                method.signature().equals(signature)) {
-                return method;
-            }
-        }
-        return null;
-    }
-
-    public Location findLocation(ReferenceType rt, int lineNumber)
-                         throws AbsentInformationException {
-        List locs = rt.locationsOfLine(lineNumber);
-        if (locs.size() == 0) {
-            throw new IllegalArgumentException("Bad line number");
-        } else if (locs.size() > 1) {
-            throw new IllegalArgumentException("Line number has multiple locations");
-        }
-
-        return (Location)locs.get(0);
-    }
-
-    public BreakpointEvent resumeTo(String clsName, String methodName,
-                                         String methodSignature) {
-        ReferenceType rt = findReferenceType(clsName);
-        if (rt == null) {
-            rt = resumeToPrepareOf(clsName).referenceType();
-        }
-
-        Method method = findMethod(rt, methodName, methodSignature);
-        if (method == null) {
-            throw new IllegalArgumentException("Bad method name/signature");
-        }
-
-        return resumeTo(method.location());
-    }
-
-    public BreakpointEvent resumeTo(String clsName, int lineNumber) throws AbsentInformationException {
-        ReferenceType rt = findReferenceType(clsName);
-        if (rt == null) {
-            rt = resumeToPrepareOf(clsName).referenceType();
-        }
-
-        return resumeTo(findLocation(rt, lineNumber));
-    }
-
-    public ClassPrepareEvent resumeToPrepareOf(String className) {
-        final ClassPrepareRequest request =
-            requestManager.createClassPrepareRequest();
-        request.addClassFilter(className);
-        request.addCountFilter(1);
-        request.enable();
-        return (ClassPrepareEvent)waitForRequestedEvent(request);
-    }
-
-    public void resumeToVMDeath() {
-        // If we are very close to VM death, we might get a VM disconnect
-        // before resume is complete. In that case ignore any VMDisconnectException
-        // and let the waitForVMDeath to clean up.
-        try {
-            traceln("JDI: resumeToVMDeath:  resuming");
-            vm.resume();
-            traceln("JDI: resumeToVMDeath:  resumed");
-        } catch (VMDisconnectedException e) {
-            // clean up below
-        }
-        waitForVMDeath();
-    }
-
-    public void shutdown() {
-        shutdown(null);
-    }
-
-    public void shutdown(String message) {
-        if ((connection != null) && !vmDied) {
-            try {
-                connection.disposeVM();
-            } catch (VMDisconnectedException e) {
-                // Shutting down after the VM has gone away. This is
-                // not an error, and we just ignore it.
-            }
-        }
-        if (message != null) {
-            System.out.println(message);
-        }
-    }
-}
--- a/test/jdk/com/sun/jdi/LaunchCommandLine.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/jdk/com/sun/jdi/LaunchCommandLine.java	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -27,7 +27,7 @@
  * @summary Test launcher command line construction
  * @author Gordon Hirsch
  *
- * @run build JDIScaffold VMConnection
+ * @run build TestScaffold VMConnection
  * @run compile -g HelloWorld.java
  * @run build LaunchCommandLine
  *
@@ -39,14 +39,14 @@
 
 import java.util.List;
 
-public class LaunchCommandLine extends JDIScaffold {
+public class LaunchCommandLine extends TestScaffold {
     public static void main(String args[]) throws Exception {
         new LaunchCommandLine(args).startTests();
     }
 
     LaunchCommandLine(String args[]) {
         // args are set in code below
-        super();
+        super(args);
     }
 
     protected void runTests() throws Exception {
@@ -96,7 +96,7 @@
         }
 
         // Allow application to complete
-        resumeToVMDeath();
+        resumeToVMDisconnect();
     }
 
 }
--- a/test/jdk/com/sun/jdi/ModificationWatchpoints.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/jdk/com/sun/jdi/ModificationWatchpoints.java	Sun Feb 25 04:59:43 2018 +0100
@@ -26,9 +26,9 @@
  * @bug 4409582
  * @summary Test all info returned by modification watchpoints
  * @author Daniel Prusa (or someone in the FFJ group)
- * @author Robert Field (modified to JDIScaffold)
+ * @author Robert Field
  *
- * @run build JDIScaffold VMConnection
+ * @run build TestScaffold VMConnection
  * @run compile -g ModificationWatchpoints.java
  * @run driver ModificationWatchpoints
  */
--- a/test/jdk/com/sun/jdi/NativeInstanceFilter.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/jdk/com/sun/jdi/NativeInstanceFilter.java	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -27,7 +27,7 @@
  * @summary Instance filter doesn't filter event if it occurs in native method
  * @author Keith McGuigan
  *
- * @run build JDIScaffold VMConnection
+ * @run build TestScaffold VMConnection
  * @compile -XDignore.symbol.file NativeInstanceFilterTarg.java
  * @run driver NativeInstanceFilter
  */
@@ -41,56 +41,24 @@
 import com.sun.jdi.event.*;
 import com.sun.jdi.request.*;
 
-public class NativeInstanceFilter extends JDIScaffold {
+public class NativeInstanceFilter extends TestScaffold {
 
     static int unfilteredEvents = 0;
+    EventSet eventSet = null;
+    ObjectReference instance = null;
 
     public static void main(String args[]) throws Exception {
-        new NativeInstanceFilter().startTests();
+        new NativeInstanceFilter(args).startTests();
     }
 
-    public NativeInstanceFilter() {
-        super();
+    public NativeInstanceFilter(String args[]) {
+        super(args);
     }
 
     static EventRequestManager requestManager = null;
     static MethodExitRequest request = null;
     static ThreadReference mainThread = null;
 
-    private void listen() {
-        TargetAdapter adapter = new TargetAdapter() {
-            EventSet set = null;
-            ObjectReference instance = null;
-
-            public boolean eventSetReceived(EventSet set) {
-                this.set = set;
-                return false;
-            }
-
-            public boolean methodExited(MethodExitEvent event) {
-                String name = event.method().name();
-                if (instance == null && name.equals("latch")) {
-                    // Grab the instance (return value) and set up as filter
-                    System.out.println("Setting up instance filter");
-                    instance = (ObjectReference)event.returnValue();
-                    requestManager.deleteEventRequest(request);
-                    request = requestManager.createMethodExitRequest();
-                    request.addInstanceFilter(instance);
-                    request.addThreadFilter(mainThread);
-                    request.enable();
-                } else if (instance != null && name.equals("intern")) {
-                    // If not for the filter, this will be called twice
-                    System.out.println("method exit event (String.intern())");
-                    ++unfilteredEvents;
-                }
-                set.resume();
-                return false;
-            }
-        };
-        addListener(adapter);
-    }
-
-
     protected void runTests() throws Exception {
         String[] args = new String[2];
         args[0] = "-connect";
@@ -99,21 +67,25 @@
         connect(args);
         waitForVMStart();
 
-        // VM has started, but hasn't started running the test program yet.
+        BreakpointEvent bpe = resumeTo("NativeInstanceFilterTarg", "main", "([Ljava/lang/String;)V");
+        mainThread = bpe.thread();
         requestManager = vm().eventRequestManager();
-        ClassPrepareEvent e = resumeToPrepareOf("NativeInstanceFilterTarg");
-        ReferenceType referenceType = e.referenceType();
-        mainThread = e.thread();
 
         request = requestManager.createMethodExitRequest();
         request.addThreadFilter(mainThread);
         request.enable();
 
-        listen();
+        try {
+            addListener(this);
+        } catch (Exception ex) {
+            ex.printStackTrace();
+            failure("failure: Could not add listener");
+            throw new Exception("NativeInstanceFilter: failed");
+        }
 
         vm().resume();
 
-        waitForVMDeath();
+        waitForVMDisconnect();
 
         if (unfilteredEvents != 1) {
             throw new Exception(
@@ -121,4 +93,27 @@
         }
         System.out.println("Passed: Event filtered out.");
     }
+
+    public void eventSetReceived(EventSet set) {
+        this.eventSet = set;
+    }
+
+    public void methodExited(MethodExitEvent event) {
+        String name = event.method().name();
+        if (instance == null && name.equals("latch")) {
+            // Grab the instance (return value) and set up as filter
+            System.out.println("Setting up instance filter");
+            instance = (ObjectReference)event.returnValue();
+            requestManager.deleteEventRequest(request);
+            request = requestManager.createMethodExitRequest();
+            request.addInstanceFilter(instance);
+            request.addThreadFilter(mainThread);
+            request.enable();
+        } else if (instance != null && name.equals("intern")) {
+            // If not for the filter, this will be called twice
+            System.out.println("method exit event (String.intern())");
+            ++unfilteredEvents;
+        }
+        eventSet.resume();
+    }
 }
--- a/test/jdk/com/sun/jdi/UnpreparedByName.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/jdk/com/sun/jdi/UnpreparedByName.java	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -28,7 +28,7 @@
  * won't be returned by classesByName.
  * @author Robert Field
  *
- * @run build JDIScaffold VMConnection
+ * @run build TestScaffold VMConnection
  * @run compile -g InnerTarg.java
  * @run build UnpreparedByName
  *
@@ -41,22 +41,18 @@
 import java.util.List;
 import java.util.Iterator;
 
-public class UnpreparedByName extends JDIScaffold {
-    final String[] args;
+public class UnpreparedByName extends TestScaffold {
 
     public static void main(String args[]) throws Exception {
         new UnpreparedByName(args).startTests();
     }
 
     UnpreparedByName(String args[]) throws Exception {
-        super();
-        this.args = args;
+        super(args);
     }
 
     protected void runTests() throws Exception {
-        connect(args);
-        waitForVMStart();
-        resumeTo("InnerTarg", "go", "()V");
+        startTo("InnerTarg", "go", "()V");
 
         List classes = vm().classesByName("InnerTarg$TheInner");
         if (classes.size() == 0) {
@@ -75,6 +71,6 @@
         }
 
         // Allow application to complete
-        resumeToVMDeath();
+        resumeToVMDisconnect();
     }
 }
--- a/test/jdk/com/sun/jdi/UnpreparedClasses.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/jdk/com/sun/jdi/UnpreparedClasses.java	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -28,7 +28,7 @@
  * loaded class list are prepared classes.
  * @author Robert Field
  *
- * @run build JDIScaffold VMConnection
+ * @run build TestScaffold VMConnection
  * @run compile -g InnerTarg.java
  * @run build UnpreparedClasses
  *
@@ -41,22 +41,18 @@
 import java.util.List;
 import java.util.Iterator;
 
-public class UnpreparedClasses extends JDIScaffold {
-    final String[] args;
+public class UnpreparedClasses extends TestScaffold {
 
     public static void main(String args[]) throws Exception {
         new UnpreparedClasses(args).startTests();
     }
 
     UnpreparedClasses(String args[]) throws Exception {
-        super();
-        this.args = args;
+        super(args);
     }
 
     protected void runTests() throws Exception {
-        connect(args);
-        waitForVMStart();
-        resumeTo("InnerTarg", "go", "()V");
+        startTo("InnerTarg", "go", "()V");
 
         List all = vm().allClasses();
         for (Iterator it = all.iterator(); it.hasNext(); ) {
@@ -73,6 +69,6 @@
         }
 
         // Allow application to complete
-        resumeToVMDeath();
+        resumeToVMDisconnect();
     }
 }
--- a/test/jdk/com/sun/jdi/Vars.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/jdk/com/sun/jdi/Vars.java	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -26,7 +26,7 @@
  * @summary Test Method.variables() and the like.
  * @author Robert Field
  *
- * @run build JDIScaffold VMConnection
+ * @run build TestScaffold VMConnection
  * @run compile -g Vars.java
  * @run driver Vars
  */
@@ -68,14 +68,12 @@
 /*
  * "Vars" test runs TestVars and makes LocalVariable queries
  */
-public class Vars extends JDIScaffold {
-    final String[] args;
+public class Vars extends TestScaffold {
 
     boolean failed = false;
 
     Vars(String args[]) {
-        super();
-        this.args = args;
+        super(args);
     }
 
     public static void main(String[] args) throws Exception {
@@ -144,16 +142,10 @@
     }
 
     protected void runTests() throws Exception {
-        List argList = new ArrayList(Arrays.asList(args));
-        argList.add("TestVars");
-        System.out.println("run args: " + argList);
-        connect((String[])argList.toArray(args));
-        waitForVMStart();
-
         /*
          * Get to a point where the classes are loaded.
          */
-        BreakpointEvent bp = resumeTo("TestVars", "hi", "()V");
+        BreakpointEvent bp = startTo("TestVars", "hi", "()V");
 
         /*
          * These classes should have no line numbers, except for
@@ -196,7 +188,7 @@
         test(method, ARGUMENTS, "normal/arguments", "sh,lo");
 
         // Allow application to complete
-        resumeToVMDeath();
+        resumeToVMDisconnect();
 
         if (failed) {
             throw new Exception("Vars: failed");
--- a/test/jdk/java/lang/StackWalker/VerifyStackTrace.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/jdk/java/lang/StackWalker/VerifyStackTrace.java	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -36,7 +36,7 @@
 
 /**
  * @test
- * @bug 8140450
+ * @bug 8140450 8197901
  * @summary Verify stack trace information obtained with respect to StackWalker
  *          options, when the stack contains lambdas, method handle invoke
  *          virtual calls, and reflection.
@@ -131,10 +131,10 @@
         // test output in here (don't forget the final \n):
         private final String expected =
             "1: VerifyStackTrace.lambda$test$1(VerifyStackTrace.java:213)\n" +
-            "2: VerifyStackTrace$$Lambda$1/662441761.run(Unknown Source)\n" +
+            "2: VerifyStackTrace$$Lambda$1/0x00000007c0089430.run(Unknown Source)\n" +
             "3: VerifyStackTrace$Handle.execute(VerifyStackTrace.java:149)\n" +
-            "4: java.base/java.lang.invoke.LambdaForm$DMH/2008017533.invokeVirtual_LL_V(LambdaForm$DMH)\n" +
-            "5: java.base/java.lang.invoke.LambdaForm$MH/1395089624.invoke_MT(LambdaForm$MH)\n" +
+            "4: java.base/java.lang.invoke.LambdaForm$DMH/0x00000007c008a830.invokeVirtual_LL_V(LambdaForm$DMH)\n" +
+            "5: java.base/java.lang.invoke.LambdaForm$MH/0x00000007c008a830.invoke_MT(LambdaForm$MH)\n" +
             "6: VerifyStackTrace$Handle.run(VerifyStackTrace.java:162)\n" +
             "7: VerifyStackTrace.invoke(VerifyStackTrace.java:192)\n" +
             "8: java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n" +
@@ -201,8 +201,8 @@
             // out before comparing. We also erase the hash-like names of
             // synthetic frames introduced by lambdas & method handles
             return produced.replaceAll(":[1-9][0-9]*\\)", ":00)")
-                    .replaceAll("/[0-9]+\\.run", "/xxxxxxxx.run")
-                    .replaceAll("/[0-9]+\\.invoke", "/xxxxxxxx.invoke")
+                    .replaceAll("/0x[0-9a-f]+\\.run", "/xxxxxxxx.run")
+                    .replaceAll("/0x[0-9a-f]+\\.invoke", "/xxxxxxxx.invoke")
                     // LFs may or may not be pre-generated, making frames differ
                     .replaceAll("DirectMethodHandle\\$Holder", "LambdaForm\\$DMH")
                     .replaceAll("Invokers\\$Holder", "LambdaForm\\$MH")
--- a/test/jtreg-ext/requires/VMProps.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/jtreg-ext/requires/VMProps.java	Sun Feb 25 04:59:43 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -75,6 +75,7 @@
         // vm.cds is true if the VM is compiled with cds support.
         map.put("vm.cds", vmCDS());
         map.put("vm.cds.custom.loaders", vmCDSForCustomLoaders());
+        map.put("vm.cds.archived.java.heap", vmCDSForArchivedJavaHeap());
         // vm.graal.enabled is true if Graal is used as JIT
         map.put("vm.graal.enabled", isGraalEnabled());
         map.put("docker.support", dockerSupport());
@@ -300,7 +301,7 @@
     /**
      * Check for CDS support for custom loaders.
      *
-     * @return true if CDS is supported for customer loader by the VM to be tested.
+     * @return true if CDS provides support for customer loader in the VM to be tested.
      */
     protected String vmCDSForCustomLoaders() {
         if (vmCDS().equals("true") && Platform.areCustomLoadersSupportedForCDS()) {
@@ -311,6 +312,19 @@
     }
 
     /**
+     * Check for CDS support for archived Java heap regions.
+     *
+     * @return true if CDS provides support for archive Java heap regions in the VM to be tested.
+     */
+    protected String vmCDSForArchivedJavaHeap() {
+      if (vmCDS().equals("true") && WB.isJavaHeapArchiveSupported()) {
+            return "true";
+        } else {
+            return "false";
+        }
+    }
+
+    /**
      * Check if Graal is used as JIT compiler.
      *
      * @return true if Graal is used as JIT compiler.
--- a/test/langtools/jdk/javadoc/doclet/testModules/jdk/element-list	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/langtools/jdk/javadoc/doclet/testModules/jdk/element-list	Sun Feb 25 04:59:43 2018 +0100
@@ -310,8 +310,6 @@
 module:jdk.management
 com.sun.management
 module:jdk.management.agent
-module:jdk.management.cmm
-jdk.management.cmm
 module:jdk.management.jfr
 jdk.management.jfr
 module:jdk.management.resource
--- a/test/lib/sun/hotspot/WhiteBox.java	Wed Feb 28 15:28:46 2018 +0100
+++ b/test/lib/sun/hotspot/WhiteBox.java	Sun Feb 25 04:59:43 2018 +0100
@@ -206,6 +206,7 @@
   public native long NMTMalloc(long size);
   public native void NMTFree(long mem);
   public native long NMTReserveMemory(long size);
+  public native long NMTAttemptReserveMemoryAt(long addr, long size);
   public native void NMTCommitMemory(long addr, long size);
   public native void NMTUncommitMemory(long addr, long size);
   public native void NMTReleaseMemory(long addr, long size);
@@ -524,6 +525,7 @@
   public native boolean isSharedClass(Class<?> c);
   public native boolean areSharedStringsIgnored();
   public native boolean isCDSIncludedInVmBuild();
+  public native boolean isJavaHeapArchiveSupported();
   public native Object  getResolvedReferences(Class<?> c);
   public native boolean areOpenArchiveHeapObjectsMapped();