changeset 12030:c6c0b2224e96

Merge
author sspitsyn
date Wed, 21 Sep 2016 08:38:21 +0000
parents c86a798296ae ddb6b697fbd1
children bc4db66d65c3
files
diffstat 223 files changed, 4018 insertions(+), 1261 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Wed Sep 21 01:33:21 2016 -0700
+++ b/.hgtags	Wed Sep 21 08:38:21 2016 +0000
@@ -536,3 +536,6 @@
 943bf73b49c33c2d7cbd796f6a4ae3c7a00ae932 jdk-9+131
 713951c08aa26813375175c2ab6cc99ff2a56903 jdk-9+132
 a25e0fb6033245ab075136e744d362ce765464cd jdk-9+133
+b8b694c6b4d2ab0939aed7adaf0eec1ac321a085 jdk-9+134
+3b1c4562953db47e36b237a500f368d5c9746d47 jdk-9+135
+a20da289f646ee44440695b81abc0548330e4ca7 jdk-9+136
--- a/make/test/JtregNative.gmk	Wed Sep 21 01:33:21 2016 -0700
+++ b/make/test/JtregNative.gmk	Wed Sep 21 08:38:21 2016 +0000
@@ -44,6 +44,7 @@
     $(HOTSPOT_TOPDIR)/test/native_sanity \
     $(HOTSPOT_TOPDIR)/test/runtime/jni/8025979 \
     $(HOTSPOT_TOPDIR)/test/runtime/jni/8033445 \
+    $(HOTSPOT_TOPDIR)/test/runtime/jni/checked \
     $(HOTSPOT_TOPDIR)/test/runtime/jni/ToStringInInterfaceTest \
     $(HOTSPOT_TOPDIR)/test/runtime/modules/getModuleJNI \
     $(HOTSPOT_TOPDIR)/test/runtime/SameObject \
--- a/src/cpu/aarch64/vm/interp_masm_aarch64.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/cpu/aarch64/vm/interp_masm_aarch64.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -326,7 +326,8 @@
 }
 
 void InterpreterMacroAssembler::push_l(Register r) {
-  str(r, pre(esp, 2 * -wordSize));
+  str(zr, pre(esp, -wordSize));
+  str(r, pre(esp, -wordsize));
 }
 
 void InterpreterMacroAssembler::pop_f(FloatRegister r) {
--- a/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -2041,6 +2041,11 @@
       __ verify_oop(r0);
   }
 
+  if (CheckJNICalls) {
+    // clear_pending_jni_exception_check
+    __ str(zr, Address(rthread, JavaThread::pending_jni_exception_check_fn_offset()));
+  }
+
   if (!is_critical_native) {
     // reset handle block
     __ ldr(r2, Address(rthread, JavaThread::active_handles_offset()));
--- a/src/cpu/aarch64/vm/templateInterpreterGenerator_aarch64.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/cpu/aarch64/vm/templateInterpreterGenerator_aarch64.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -1355,6 +1355,11 @@
   // reset_last_Java_frame
   __ reset_last_Java_frame(true);
 
+  if (CheckJNICalls) {
+    // clear_pending_jni_exception_check
+    __ str(zr, Address(rthread, JavaThread::pending_jni_exception_check_fn_offset()));
+  }
+
   // reset handle block
   __ ldr(t, Address(rthread, JavaThread::active_handles_offset()));
   __ str(zr, Address(t, JNIHandleBlock::top_offset_in_bytes()));
--- a/src/cpu/sparc/vm/globals_sparc.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/cpu/sparc/vm/globals_sparc.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -57,10 +57,12 @@
 
 #ifdef _LP64
 // Stack slots are 2X larger in LP64 than in the 32 bit VM.
+define_pd_global(intx, CompilerThreadStackSize, 1024);
 define_pd_global(intx, ThreadStackSize,       1024);
 define_pd_global(intx, VMThreadStackSize,     1024);
 #define DEFAULT_STACK_SHADOW_PAGES (20 DEBUG_ONLY(+2))
 #else
+define_pd_global(intx, CompilerThreadStackSize, 512);
 define_pd_global(intx, ThreadStackSize,       512);
 define_pd_global(intx, VMThreadStackSize,     512);
 #define DEFAULT_STACK_SHADOW_PAGES (6 DEBUG_ONLY(+2))
--- a/src/cpu/sparc/vm/interp_masm_sparc.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/cpu/sparc/vm/interp_masm_sparc.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -359,7 +359,7 @@
 #ifdef _LP64
   stx(l, r1, offset);
   // store something more useful here
-  debug_only(stx(G0, r1, offset+Interpreter::stackElementSize);)
+  stx(G0, r1, offset+Interpreter::stackElementSize);
 #else
   st(l, r1, offset);
   st(l->successor(), r1, offset + Interpreter::stackElementSize);
--- a/src/cpu/sparc/vm/sharedRuntime_sparc.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/cpu/sparc/vm/sharedRuntime_sparc.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -2765,6 +2765,11 @@
       __ verify_oop(I0);
   }
 
+  if (CheckJNICalls) {
+    // clear_pending_jni_exception_check
+    __ st_ptr(G0, G2_thread, JavaThread::pending_jni_exception_check_fn_offset());
+  }
+
   if (!is_critical_native) {
     // reset handle block
     __ ld_ptr(G2_thread, in_bytes(JavaThread::active_handles_offset()), L5);
--- a/src/cpu/sparc/vm/templateInterpreterGenerator_sparc.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/cpu/sparc/vm/templateInterpreterGenerator_sparc.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -1487,6 +1487,11 @@
   __ set(_thread_in_Java, G3_scratch);
   __ st(G3_scratch, thread_state);
 
+  if (CheckJNICalls) {
+    // clear_pending_jni_exception_check
+    __ st_ptr(G0, G2_thread, JavaThread::pending_jni_exception_check_fn_offset());
+  }
+
   // reset handle block
   __ ld_ptr(G2_thread, JavaThread::active_handles_offset(), G3_scratch);
   __ st(G0, G3_scratch, JNIHandleBlock::top_offset_in_bytes());
--- a/src/cpu/x86/vm/interp_masm_x86.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/cpu/x86/vm/interp_masm_x86.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -611,7 +611,8 @@
 
 void InterpreterMacroAssembler::push_l(Register r) {
   subptr(rsp, 2 * wordSize);
-  movq(Address(rsp, 0), r);
+  movptr(Address(rsp, Interpreter::expr_offset_in_bytes(0)), r         );
+  movptr(Address(rsp, Interpreter::expr_offset_in_bytes(1)), NULL_WORD );
 }
 
 void InterpreterMacroAssembler::pop(TosState state) {
--- a/src/cpu/x86/vm/sharedRuntime_x86_32.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/cpu/x86/vm/sharedRuntime_x86_32.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -2236,6 +2236,11 @@
       __ verify_oop(rax);
   }
 
+  if (CheckJNICalls) {
+    // clear_pending_jni_exception_check
+    __ movptr(Address(thread, JavaThread::pending_jni_exception_check_fn_offset()), NULL_WORD);
+  }
+
   if (!is_critical_native) {
     // reset handle block
     __ movptr(rcx, Address(thread, JavaThread::active_handles_offset()));
--- a/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -2589,6 +2589,11 @@
       __ verify_oop(rax);
   }
 
+  if (CheckJNICalls) {
+    // clear_pending_jni_exception_check
+    __ movptr(Address(r15_thread, JavaThread::pending_jni_exception_check_fn_offset()), NULL_WORD);
+  }
+
   if (!is_critical_native) {
     // reset handle block
     __ movptr(rcx, Address(r15_thread, JavaThread::active_handles_offset()));
--- a/src/cpu/x86/vm/templateInterpreterGenerator_x86.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/cpu/x86/vm/templateInterpreterGenerator_x86.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -1169,6 +1169,11 @@
   // reset_last_Java_frame
   __ reset_last_Java_frame(thread, true);
 
+  if (CheckJNICalls) {
+    // clear_pending_jni_exception_check
+    __ movptr(Address(thread, JavaThread::pending_jni_exception_check_fn_offset()), NULL_WORD);
+  }
+
   // reset handle block
   __ movptr(t, Address(thread, JavaThread::active_handles_offset()));
   __ movl(Address(t, JNIHandleBlock::top_offset_in_bytes()), (int32_t)NULL_WORD);
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java	Wed Sep 21 08:38:21 2016 +0000
@@ -68,6 +68,7 @@
     Type type            = db.lookupType("InstanceKlass");
     arrayKlasses         = new MetadataField(type.getAddressField("_array_klasses"), 0);
     methods              = type.getAddressField("_methods");
+    defaultMethods       = type.getAddressField("_default_methods");
     methodOrdering       = type.getAddressField("_method_ordering");
     localInterfaces      = type.getAddressField("_local_interfaces");
     transitiveInterfaces = type.getAddressField("_transitive_interfaces");
@@ -128,6 +129,7 @@
 
   private static MetadataField arrayKlasses;
   private static AddressField  methods;
+  private static AddressField  defaultMethods;
   private static AddressField  methodOrdering;
   private static AddressField  localInterfaces;
   private static AddressField  transitiveInterfaces;
@@ -335,6 +337,20 @@
   // Accessors for declared fields
   public Klass     getArrayKlasses()        { return (Klass)        arrayKlasses.getValue(this); }
   public MethodArray  getMethods()              { return new MethodArray(methods.getValue(getAddress())); }
+
+  public MethodArray  getDefaultMethods() {
+    if (defaultMethods != null) {
+      Address addr = defaultMethods.getValue(getAddress());
+      if ((addr != null) && (addr.getAddressAt(0) != null)) {
+        return new MethodArray(addr);
+      } else {
+        return null;
+      }
+    } else {
+      return null;
+    }
+  }
+
   public KlassArray   getLocalInterfaces()      { return new KlassArray(localInterfaces.getValue(getAddress())); }
   public KlassArray   getTransitiveInterfaces() { return new KlassArray(transitiveInterfaces.getValue(getAddress())); }
   public int       getJavaFieldsCount()     { return                (int) javaFieldsCount.getValue(this); }
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/GrowableArray.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/GrowableArray.java	Wed Sep 21 08:38:21 2016 +0000
@@ -65,4 +65,7 @@
     super(addr);
     virtualConstructor = v;
   }
+  public Address getData() {
+    return dataField.getValue(getAddress());
+  }
 }
--- a/src/os/aix/vm/os_aix.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/os/aix/vm/os_aix.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -847,7 +847,8 @@
   return 0;
 }
 
-bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) {
+bool os::create_thread(Thread* thread, ThreadType thr_type,
+                       size_t req_stack_size) {
 
   assert(thread->osthread() == NULL, "caller responsible");
 
@@ -880,37 +881,12 @@
   guarantee(pthread_attr_setsuspendstate_np(&attr, PTHREAD_CREATE_SUSPENDED_NP) == 0, "???");
 
   // calculate stack size if it's not specified by caller
-  if (stack_size == 0) {
-    stack_size = os::Aix::default_stack_size(thr_type);
-
-    switch (thr_type) {
-    case os::java_thread:
-      // Java threads use ThreadStackSize whose default value can be changed with the flag -Xss.
-      assert(JavaThread::stack_size_at_create() > 0, "this should be set");
-      stack_size = JavaThread::stack_size_at_create();
-      break;
-    case os::compiler_thread:
-      if (CompilerThreadStackSize > 0) {
-        stack_size = (size_t)(CompilerThreadStackSize * K);
-        break;
-      } // else fall through:
-        // use VMThreadStackSize if CompilerThreadStackSize is not defined
-    case os::vm_thread:
-    case os::pgc_thread:
-    case os::cgc_thread:
-    case os::watcher_thread:
-      if (VMThreadStackSize > 0) stack_size = (size_t)(VMThreadStackSize * K);
-      break;
-    }
-  }
-
-  stack_size = MAX2(stack_size, os::Aix::min_stack_allowed);
+  size_t stack_size = os::Posix::get_initial_stack_size(thr_type, req_stack_size);
   pthread_attr_setstacksize(&attr, stack_size);
 
   pthread_t tid;
   int ret = pthread_create(&tid, &attr, (void* (*)(void*)) thread_native_entry, thread);
 
-
   char buf[64];
   if (ret == 0) {
     log_info(os, thread)("Thread started (pthread id: " UINTX_FORMAT ", attributes: %s). ",
@@ -3593,32 +3569,11 @@
   Aix::signal_sets_init();
   Aix::install_signal_handlers();
 
-  // Check minimum allowable stack size for thread creation and to initialize
-  // the java system classes, including StackOverflowError - depends on page
-  // size. Add two 4K pages for compiler2 recursion in main thread.
-  // Add in 4*BytesPerWord 4K pages to account for VM stack during
-  // class initialization depending on 32 or 64 bit VM.
-  os::Aix::min_stack_allowed = MAX2(os::Aix::min_stack_allowed,
-                                    JavaThread::stack_guard_zone_size() +
-                                    JavaThread::stack_shadow_zone_size() +
-                                    (4*BytesPerWord COMPILER2_PRESENT(+2)) * 4 * K);
-
-  os::Aix::min_stack_allowed = align_size_up(os::Aix::min_stack_allowed, os::vm_page_size());
-
-  size_t threadStackSizeInBytes = ThreadStackSize * K;
-  if (threadStackSizeInBytes != 0 &&
-      threadStackSizeInBytes < os::Aix::min_stack_allowed) {
-    tty->print_cr("\nThe stack size specified is too small, "
-                  "Specify at least %dk",
-                  os::Aix::min_stack_allowed / K);
+  // Check and sets minimum stack sizes against command line options
+  if (Posix::set_minimum_stack_sizes() == JNI_ERR) {
     return JNI_ERR;
   }
 
-  // Make the stack size a multiple of the page size so that
-  // the yellow/red zones can be guarded.
-  // Note that this can be 0, if no default stacksize was set.
-  JavaThread::set_stack_size_at_create(round_to(threadStackSizeInBytes, vm_page_size()));
-
   if (UseNUMA) {
     UseNUMA = false;
     warning("NUMA optimizations are not available on this OS.");
--- a/src/os/aix/vm/os_aix.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/os/aix/vm/os_aix.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2013, 2016 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -140,14 +140,6 @@
   // libpthread version string
   static void libpthread_init();
 
-  // Minimum stack size a thread can be created with (allowing
-  // the VM to completely create the thread and enter user code)
-  static size_t min_stack_allowed;
-
-  // Return default stack size or guard size for the specified thread type
-  static size_t default_stack_size(os::ThreadType thr_type);
-  static size_t default_guard_size(os::ThreadType thr_type);
-
   // Function returns true if we run on OS/400 (pase), false if we run
   // on AIX.
   static bool on_pase() {
--- a/src/os/bsd/vm/os_bsd.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/os/bsd/vm/os_bsd.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -734,7 +734,8 @@
   return 0;
 }
 
-bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) {
+bool os::create_thread(Thread* thread, ThreadType thr_type,
+                       size_t req_stack_size) {
   assert(thread->osthread() == NULL, "caller responsible");
 
   // Allocate the OSThread object
@@ -757,32 +758,7 @@
   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
 
   // calculate stack size if it's not specified by caller
-  if (stack_size == 0) {
-    stack_size = os::Bsd::default_stack_size(thr_type);
-
-    switch (thr_type) {
-    case os::java_thread:
-      // Java threads use ThreadStackSize which default value can be
-      // changed with the flag -Xss
-      assert(JavaThread::stack_size_at_create() > 0, "this should be set");
-      stack_size = JavaThread::stack_size_at_create();
-      break;
-    case os::compiler_thread:
-      if (CompilerThreadStackSize > 0) {
-        stack_size = (size_t)(CompilerThreadStackSize * K);
-        break;
-      } // else fall through:
-        // use VMThreadStackSize if CompilerThreadStackSize is not defined
-    case os::vm_thread:
-    case os::pgc_thread:
-    case os::cgc_thread:
-    case os::watcher_thread:
-      if (VMThreadStackSize > 0) stack_size = (size_t)(VMThreadStackSize * K);
-      break;
-    }
-  }
-
-  stack_size = MAX2(stack_size, os::Bsd::min_stack_allowed);
+  size_t stack_size = os::Posix::get_initial_stack_size(thr_type, req_stack_size);
   pthread_attr_setstacksize(&attr, stack_size);
 
   ThreadState state;
@@ -3502,32 +3478,11 @@
   Bsd::signal_sets_init();
   Bsd::install_signal_handlers();
 
-  // Check minimum allowable stack size for thread creation and to initialize
-  // the java system classes, including StackOverflowError - depends on page
-  // size.  Add two 4K pages for compiler2 recursion in main thread.
-  // Add in 4*BytesPerWord 4K pages to account for VM stack during
-  // class initialization depending on 32 or 64 bit VM.
-  os::Bsd::min_stack_allowed = MAX2(os::Bsd::min_stack_allowed,
-                                    JavaThread::stack_guard_zone_size() +
-                                    JavaThread::stack_shadow_zone_size() +
-                                    (4*BytesPerWord COMPILER2_PRESENT(+2)) * 4 * K);
-
-  os::Bsd::min_stack_allowed = align_size_up(os::Bsd::min_stack_allowed, os::vm_page_size());
-
-  size_t threadStackSizeInBytes = ThreadStackSize * K;
-  if (threadStackSizeInBytes != 0 &&
-      threadStackSizeInBytes < os::Bsd::min_stack_allowed) {
-    tty->print_cr("\nThe stack size specified is too small, "
-                  "Specify at least %dk",
-                  os::Bsd::min_stack_allowed/ K);
+  // Check and sets minimum stack sizes against command line options
+  if (Posix::set_minimum_stack_sizes() == JNI_ERR) {
     return JNI_ERR;
   }
 
-  // Make the stack size a multiple of the page size so that
-  // the yellow/red zones can be guarded.
-  JavaThread::set_stack_size_at_create(round_to(threadStackSizeInBytes,
-                                                vm_page_size()));
-
   if (MaxFDLimit) {
     // set the number of file descriptors to max. print out error
     // if getrlimit/setrlimit fails but continue regardless.
--- a/src/os/bsd/vm/os_bsd.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/os/bsd/vm/os_bsd.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -120,14 +120,6 @@
   static struct sigaction *get_chained_signal_action(int sig);
   static bool chained_handler(int sig, siginfo_t* siginfo, void* context);
 
-  // Minimum stack size a thread can be created with (allowing
-  // the VM to completely create the thread and enter user code)
-  static size_t min_stack_allowed;
-
-  // Return default stack size or guard size for the specified thread type
-  static size_t default_stack_size(os::ThreadType thr_type);
-  static size_t default_guard_size(os::ThreadType thr_type);
-
   // Real-time clock functions
   static void clock_init(void);
 
--- a/src/os/linux/vm/os_linux.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/os/linux/vm/os_linux.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -701,7 +701,7 @@
 }
 
 bool os::create_thread(Thread* thread, ThreadType thr_type,
-                       size_t stack_size) {
+                       size_t req_stack_size) {
   assert(thread->osthread() == NULL, "caller responsible");
 
   // Allocate the OSThread object
@@ -723,34 +723,8 @@
   pthread_attr_init(&attr);
   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
 
-  // stack size
   // calculate stack size if it's not specified by caller
-  if (stack_size == 0) {
-    stack_size = os::Linux::default_stack_size(thr_type);
-
-    switch (thr_type) {
-    case os::java_thread:
-      // Java threads use ThreadStackSize which default value can be
-      // changed with the flag -Xss
-      assert(JavaThread::stack_size_at_create() > 0, "this should be set");
-      stack_size = JavaThread::stack_size_at_create();
-      break;
-    case os::compiler_thread:
-      if (CompilerThreadStackSize > 0) {
-        stack_size = (size_t)(CompilerThreadStackSize * K);
-        break;
-      } // else fall through:
-        // use VMThreadStackSize if CompilerThreadStackSize is not defined
-    case os::vm_thread:
-    case os::pgc_thread:
-    case os::cgc_thread:
-    case os::watcher_thread:
-      if (VMThreadStackSize > 0) stack_size = (size_t)(VMThreadStackSize * K);
-      break;
-    }
-  }
-
-  stack_size = MAX2(stack_size, os::Linux::min_stack_allowed);
+  size_t stack_size = os::Posix::get_initial_stack_size(thr_type, req_stack_size);
   pthread_attr_setstacksize(&attr, stack_size);
 
   // glibc guard page
@@ -956,10 +930,9 @@
 // bogus value for initial thread.
 void os::Linux::capture_initial_stack(size_t max_size) {
   // stack size is the easy part, get it from RLIMIT_STACK
-  size_t stack_size;
   struct rlimit rlim;
   getrlimit(RLIMIT_STACK, &rlim);
-  stack_size = rlim.rlim_cur;
+  size_t stack_size = rlim.rlim_cur;
 
   // 6308388: a bug in ld.so will relocate its own .data section to the
   //   lower end of primordial stack; reduce ulimit -s value a little bit
@@ -4793,32 +4766,10 @@
   Linux::signal_sets_init();
   Linux::install_signal_handlers();
 
-  // Check minimum allowable stack size for thread creation and to initialize
-  // the java system classes, including StackOverflowError - depends on page
-  // size.  Add two 4K pages for compiler2 recursion in main thread.
-  // Add in 4*BytesPerWord 4K pages to account for VM stack during
-  // class initialization depending on 32 or 64 bit VM.
-  os::Linux::min_stack_allowed = MAX2(os::Linux::min_stack_allowed,
-                                      JavaThread::stack_guard_zone_size() +
-                                      JavaThread::stack_shadow_zone_size() +
-                                      (4*BytesPerWord COMPILER2_PRESENT(+2)) * 4 * K);
-
-  os::Linux::min_stack_allowed = align_size_up(os::Linux::min_stack_allowed, os::vm_page_size());
-
-  size_t threadStackSizeInBytes = ThreadStackSize * K;
-  if (threadStackSizeInBytes != 0 &&
-      threadStackSizeInBytes < os::Linux::min_stack_allowed) {
-    tty->print_cr("\nThe stack size specified is too small, "
-                  "Specify at least " SIZE_FORMAT "k",
-                  os::Linux::min_stack_allowed/ K);
+  // Check and sets minimum stack sizes against command line options
+  if (Posix::set_minimum_stack_sizes() == JNI_ERR) {
     return JNI_ERR;
   }
-
-  // Make the stack size a multiple of the page size so that
-  // the yellow/red zones can be guarded.
-  JavaThread::set_stack_size_at_create(round_to(threadStackSizeInBytes,
-                                                vm_page_size()));
-
   Linux::capture_initial_stack(JavaThread::stack_size_at_create());
 
 #if defined(IA32)
--- a/src/os/linux/vm/os_linux.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/os/linux/vm/os_linux.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -170,12 +170,8 @@
   static void libpthread_init();
   static bool libnuma_init();
   static void* libnuma_dlsym(void* handle, const char* name);
-  // Minimum stack size a thread can be created with (allowing
-  // the VM to completely create the thread and enter user code)
-  static size_t min_stack_allowed;
 
-  // Return default stack size or guard size for the specified thread type
-  static size_t default_stack_size(os::ThreadType thr_type);
+  // Return default guard size for the specified thread type
   static size_t default_guard_size(os::ThreadType thr_type);
 
   static void capture_initial_stack(size_t max_size);
--- a/src/os/posix/vm/os_posix.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/os/posix/vm/os_posix.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -1099,6 +1099,123 @@
   return buf;
 }
 
+// Check minimum allowable stack sizes for thread creation and to initialize
+// the java system classes, including StackOverflowError - depends on page
+// size.  Add two 4K pages for compiler2 recursion in main thread.
+// Add in 4*BytesPerWord 4K pages to account for VM stack during
+// class initialization depending on 32 or 64 bit VM.
+jint os::Posix::set_minimum_stack_sizes() {
+  _java_thread_min_stack_allowed = MAX2(_java_thread_min_stack_allowed,
+                                        JavaThread::stack_guard_zone_size() +
+                                        JavaThread::stack_shadow_zone_size() +
+                                        (4 * BytesPerWord COMPILER2_PRESENT(+ 2)) * 4 * K);
+
+  _java_thread_min_stack_allowed = align_size_up(_java_thread_min_stack_allowed, vm_page_size());
+
+  size_t stack_size_in_bytes = ThreadStackSize * K;
+  if (stack_size_in_bytes != 0 &&
+      stack_size_in_bytes < _java_thread_min_stack_allowed) {
+    // The '-Xss' and '-XX:ThreadStackSize=N' options both set
+    // ThreadStackSize so we go with "Java thread stack size" instead
+    // of "ThreadStackSize" to be more friendly.
+    tty->print_cr("\nThe Java thread stack size specified is too small. "
+                  "Specify at least " SIZE_FORMAT "k",
+                  _java_thread_min_stack_allowed / K);
+    return JNI_ERR;
+  }
+
+#ifdef SOLARIS
+  // For 64kbps there will be a 64kb page size, which makes
+  // the usable default stack size quite a bit less.  Increase the
+  // stack for 64kb (or any > than 8kb) pages, this increases
+  // virtual memory fragmentation (since we're not creating the
+  // stack on a power of 2 boundary.  The real fix for this
+  // should be to fix the guard page mechanism.
+
+  if (vm_page_size() > 8*K) {
+    stack_size_in_bytes = (stack_size_in_bytes != 0)
+       ? stack_size_in_bytes +
+         JavaThread::stack_red_zone_size() +
+         JavaThread::stack_yellow_zone_size()
+       : 0;
+    ThreadStackSize = stack_size_in_bytes/K;
+  }
+#endif // SOLARIS
+
+  // Make the stack size a multiple of the page size so that
+  // the yellow/red zones can be guarded.
+  JavaThread::set_stack_size_at_create(round_to(stack_size_in_bytes,
+                                                vm_page_size()));
+
+  _compiler_thread_min_stack_allowed = align_size_up(_compiler_thread_min_stack_allowed, vm_page_size());
+
+  stack_size_in_bytes = CompilerThreadStackSize * K;
+  if (stack_size_in_bytes != 0 &&
+      stack_size_in_bytes < _compiler_thread_min_stack_allowed) {
+    tty->print_cr("\nThe CompilerThreadStackSize specified is too small. "
+                  "Specify at least " SIZE_FORMAT "k",
+                  _compiler_thread_min_stack_allowed / K);
+    return JNI_ERR;
+  }
+
+  _vm_internal_thread_min_stack_allowed = align_size_up(_vm_internal_thread_min_stack_allowed, vm_page_size());
+
+  stack_size_in_bytes = VMThreadStackSize * K;
+  if (stack_size_in_bytes != 0 &&
+      stack_size_in_bytes < _vm_internal_thread_min_stack_allowed) {
+    tty->print_cr("\nThe VMThreadStackSize specified is too small. "
+                  "Specify at least " SIZE_FORMAT "k",
+                  _vm_internal_thread_min_stack_allowed / K);
+    return JNI_ERR;
+  }
+  return JNI_OK;
+}
+
+// Called when creating the thread.  The minimum stack sizes have already been calculated
+size_t os::Posix::get_initial_stack_size(ThreadType thr_type, size_t req_stack_size) {
+  size_t stack_size;
+  if (req_stack_size == 0) {
+    stack_size = default_stack_size(thr_type);
+  } else {
+    stack_size = req_stack_size;
+  }
+
+  switch (thr_type) {
+  case os::java_thread:
+    // Java threads use ThreadStackSize which default value can be
+    // changed with the flag -Xss
+    if (req_stack_size == 0 && JavaThread::stack_size_at_create() > 0) {
+      // no requested size and we have a more specific default value
+      stack_size = JavaThread::stack_size_at_create();
+    }
+    stack_size = MAX2(stack_size,
+                      _java_thread_min_stack_allowed);
+    break;
+  case os::compiler_thread:
+    if (req_stack_size == 0 && CompilerThreadStackSize > 0) {
+      // no requested size and we have a more specific default value
+      stack_size = (size_t)(CompilerThreadStackSize * K);
+    }
+    stack_size = MAX2(stack_size,
+                      _compiler_thread_min_stack_allowed);
+    break;
+  case os::vm_thread:
+  case os::pgc_thread:
+  case os::cgc_thread:
+  case os::watcher_thread:
+  default:  // presume the unknown thr_type is a VM internal
+    if (req_stack_size == 0 && VMThreadStackSize > 0) {
+      // no requested size and we have a more specific default value
+      stack_size = (size_t)(VMThreadStackSize * K);
+    }
+
+    stack_size = MAX2(stack_size,
+                      _vm_internal_thread_min_stack_allowed);
+    break;
+  }
+
+  return stack_size;
+}
 
 os::WatcherThreadCrashProtection::WatcherThreadCrashProtection() {
   assert(Thread::current()->is_Watcher_thread(), "Must be WatcherThread");
--- a/src/os/posix/vm/os_posix.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/os/posix/vm/os_posix.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -42,7 +42,18 @@
   static void print_libversion_info(outputStream* st);
   static void print_load_average(outputStream* st);
 
+  // Minimum stack size a thread can be created with (allowing
+  // the VM to completely create the thread and enter user code)
+  static size_t _compiler_thread_min_stack_allowed;
+  static size_t _java_thread_min_stack_allowed;
+  static size_t _vm_internal_thread_min_stack_allowed;
+
 public:
+  // Return default stack size for the specified thread type
+  static size_t default_stack_size(os::ThreadType thr_type);
+  // Check and sets minimum stack sizes
+  static jint set_minimum_stack_sizes();
+  static size_t get_initial_stack_size(ThreadType thr_type, size_t req_stack_size);
 
   // Returns true if signal is valid.
   static bool is_valid_signal(int sig);
--- a/src/os/solaris/vm/os_solaris.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/os/solaris/vm/os_solaris.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -917,8 +917,15 @@
   return buf;
 }
 
+// return default stack size for thr_type
+size_t os::Posix::default_stack_size(os::ThreadType thr_type) {
+  // default stack size when not specified by caller is 1M (2M for LP64)
+  size_t s = (BytesPerWord >> 2) * K * K;
+  return s;
+}
+
 bool os::create_thread(Thread* thread, ThreadType thr_type,
-                       size_t stack_size) {
+                       size_t req_stack_size) {
   // Allocate the OSThread object
   OSThread* osthread = new OSThread(NULL, NULL);
   if (osthread == NULL) {
@@ -953,31 +960,8 @@
     tty->print_cr("In create_thread, creating a %s thread\n", thrtyp);
   }
 
-  // Calculate stack size if it's not specified by caller.
-  if (stack_size == 0) {
-    // The default stack size 1M (2M for LP64).
-    stack_size = (BytesPerWord >> 2) * K * K;
-
-    switch (thr_type) {
-    case os::java_thread:
-      // Java threads use ThreadStackSize which default value can be changed with the flag -Xss
-      if (JavaThread::stack_size_at_create() > 0) stack_size = JavaThread::stack_size_at_create();
-      break;
-    case os::compiler_thread:
-      if (CompilerThreadStackSize > 0) {
-        stack_size = (size_t)(CompilerThreadStackSize * K);
-        break;
-      } // else fall through:
-        // use VMThreadStackSize if CompilerThreadStackSize is not defined
-    case os::vm_thread:
-    case os::pgc_thread:
-    case os::cgc_thread:
-    case os::watcher_thread:
-      if (VMThreadStackSize > 0) stack_size = (size_t)(VMThreadStackSize * K);
-      break;
-    }
-  }
-  stack_size = MAX2(stack_size, os::Solaris::min_stack_allowed);
+  // calculate stack size if it's not specified by caller
+  size_t stack_size = os::Posix::get_initial_stack_size(thr_type, req_stack_size);
 
   // Initial state is ALLOCATED but not INITIALIZED
   osthread->set_state(ALLOCATED);
@@ -4400,7 +4384,12 @@
   // Constant minimum stack size allowed. It must be at least
   // the minimum of what the OS supports (thr_min_stack()), and
   // enough to allow the thread to get to user bytecode execution.
-  Solaris::min_stack_allowed = MAX2(thr_min_stack(), Solaris::min_stack_allowed);
+  Posix::_compiler_thread_min_stack_allowed = MAX2(thr_min_stack(),
+                                                   Posix::_compiler_thread_min_stack_allowed);
+  Posix::_java_thread_min_stack_allowed = MAX2(thr_min_stack(),
+                                               Posix::_java_thread_min_stack_allowed);
+  Posix::_vm_internal_thread_min_stack_allowed = MAX2(thr_min_stack(),
+                                                      Posix::_vm_internal_thread_min_stack_allowed);
 
   // dynamic lookup of functions that may not be available in our lowest
   // supported Solaris release
@@ -4445,47 +4434,11 @@
     log_info(os)("Memory Serialize Page address: " INTPTR_FORMAT, p2i(mem_serialize_page));
   }
 
-  // Check minimum allowable stack size for thread creation and to initialize
-  // the java system classes, including StackOverflowError - depends on page
-  // size.  Add two 4K pages for compiler2 recursion in main thread.
-  // Add in 4*BytesPerWord 4K pages to account for VM stack during
-  // class initialization depending on 32 or 64 bit VM.
-  os::Solaris::min_stack_allowed = MAX2(os::Solaris::min_stack_allowed,
-                                        JavaThread::stack_guard_zone_size() +
-                                        JavaThread::stack_shadow_zone_size() +
-                                        (4*BytesPerWord COMPILER2_PRESENT(+2)) * 4 * K);
-
-  os::Solaris::min_stack_allowed = align_size_up(os::Solaris::min_stack_allowed, os::vm_page_size());
-
-  size_t threadStackSizeInBytes = ThreadStackSize * K;
-  if (threadStackSizeInBytes != 0 &&
-      threadStackSizeInBytes < os::Solaris::min_stack_allowed) {
-    tty->print_cr("\nThe stack size specified is too small, Specify at least %dk",
-                  os::Solaris::min_stack_allowed/K);
+  // Check and sets minimum stack sizes against command line options
+  if (Posix::set_minimum_stack_sizes() == JNI_ERR) {
     return JNI_ERR;
   }
 
-  // For 64kbps there will be a 64kb page size, which makes
-  // the usable default stack size quite a bit less.  Increase the
-  // stack for 64kb (or any > than 8kb) pages, this increases
-  // virtual memory fragmentation (since we're not creating the
-  // stack on a power of 2 boundary.  The real fix for this
-  // should be to fix the guard page mechanism.
-
-  if (vm_page_size() > 8*K) {
-    threadStackSizeInBytes = (threadStackSizeInBytes != 0)
-       ? threadStackSizeInBytes +
-         JavaThread::stack_red_zone_size() +
-         JavaThread::stack_yellow_zone_size()
-       : 0;
-    ThreadStackSize = threadStackSizeInBytes/K;
-  }
-
-  // Make the stack size a multiple of the page size so that
-  // the yellow/red zones can be guarded.
-  JavaThread::set_stack_size_at_create(round_to(threadStackSizeInBytes,
-                                                vm_page_size()));
-
   Solaris::libthread_init();
 
   if (UseNUMA) {
--- a/src/os/solaris/vm/os_solaris.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/os/solaris/vm/os_solaris.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -292,10 +292,6 @@
   static          jint  _os_thread_limit;
   static volatile jint  _os_thread_count;
 
-  // Minimum stack size a thread can be created with (allowing
-  // the VM to completely create the thread and enter user code)
-
-  static size_t min_stack_allowed;
 
   // Stack overflow handling
 
--- a/src/os/windows/vm/os_windows.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/os/windows/vm/os_windows.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -4215,7 +4215,7 @@
   min_stack_allowed = align_size_up(min_stack_allowed, os::vm_page_size());
 
   if (actual_reserve_size < min_stack_allowed) {
-    tty->print_cr("\nThe stack size specified is too small, "
+    tty->print_cr("\nThe Java thread stack size specified is too small. "
                   "Specify at least %dk",
                   min_stack_allowed / K);
     return JNI_ERR;
--- a/src/os_cpu/aix_ppc/vm/globals_aix_ppc.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/os_cpu/aix_ppc/vm/globals_aix_ppc.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2012, 2015 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -33,10 +33,6 @@
 define_pd_global(intx, ThreadStackSize,          2048); // 0 => use system default
 define_pd_global(intx, VMThreadStackSize,        2048);
 
-// if we set CompilerThreadStackSize to a value different than 0, it will
-// be used in os::create_thread(). Otherwise, due the strange logic in os::create_thread(),
-// the stack size for compiler threads will default to VMThreadStackSize, although it
-// is defined to 4M in os::Aix::default_stack_size()!
 define_pd_global(intx, CompilerThreadStackSize,  4096);
 
 // Allow extra space in DEBUG builds for asserts.
--- a/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -192,8 +192,10 @@
   intptr_t* csp = (intptr_t*) *((intptr_t*) os::current_stack_pointer());
   // hack.
   frame topframe(csp, (address)0x8);
-  // return sender of current topframe which hopefully has pc != NULL.
-  return os::get_sender_for_C_frame(&topframe);
+  // Return sender of sender of current topframe which hopefully
+  // both have pc != NULL.
+  frame tmp = os::get_sender_for_C_frame(&topframe);
+  return os::get_sender_for_C_frame(&tmp);
 }
 
 // Utility functions
@@ -533,23 +535,17 @@
 ////////////////////////////////////////////////////////////////////////////////
 // thread stack
 
-size_t os::Aix::min_stack_allowed = 128*K;
+size_t os::Posix::_compiler_thread_min_stack_allowed = 128 * K;
+size_t os::Posix::_java_thread_min_stack_allowed = 128 * K;
+size_t os::Posix::_vm_internal_thread_min_stack_allowed = 128 * K;
 
 // return default stack size for thr_type
-size_t os::Aix::default_stack_size(os::ThreadType thr_type) {
+size_t os::Posix::default_stack_size(os::ThreadType thr_type) {
   // default stack size (compiler thread needs larger stack)
-  // Notice that the setting for compiler threads here have no impact
-  // because of the strange 'fallback logic' in os::create_thread().
-  // Better set CompilerThreadStackSize in globals_<os_cpu>.hpp if you want to
-  // specify a different stack size for compiler threads!
   size_t s = (thr_type == os::compiler_thread ? 4 * M : 1 * M);
   return s;
 }
 
-size_t os::Aix::default_guard_size(os::ThreadType thr_type) {
-  return 2 * page_size();
-}
-
 /////////////////////////////////////////////////////////////////////////////
 // helper functions for fatal error handler
 
--- a/src/os_cpu/bsd_x86/vm/globals_bsd_x86.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/os_cpu/bsd_x86/vm/globals_bsd_x86.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -31,9 +31,11 @@
 //
 define_pd_global(bool, DontYieldALot,            false);
 #ifdef AMD64
+define_pd_global(intx, CompilerThreadStackSize,  1024);
 define_pd_global(intx, ThreadStackSize,          1024); // 0 => use system default
 define_pd_global(intx, VMThreadStackSize,        1024);
 #else
+define_pd_global(intx, CompilerThreadStackSize,  512);
 // ThreadStackSize 320 allows a couple of test cases to run while
 // keeping the number of threads that can be created high.  System
 // default ThreadStackSize appears to be 512 which is too big.
@@ -41,7 +43,6 @@
 define_pd_global(intx, VMThreadStackSize,        512);
 #endif // AMD64
 
-define_pd_global(intx, CompilerThreadStackSize,  0);
 
 define_pd_global(size_t, JVMInvokeMethodSlack,   8192);
 
--- a/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -838,9 +838,13 @@
 // thread stack
 
 #ifdef AMD64
-size_t os::Bsd::min_stack_allowed  = 64 * K;
+size_t os::Posix::_compiler_thread_min_stack_allowed = 64 * K;
+size_t os::Posix::_java_thread_min_stack_allowed = 64 * K;
+size_t os::Posix::_vm_internal_thread_min_stack_allowed = 64 * K;
 #else
-size_t os::Bsd::min_stack_allowed  =  (48 DEBUG_ONLY(+4))*K;
+size_t os::Posix::_compiler_thread_min_stack_allowed = (48 DEBUG_ONLY(+ 4)) * K;
+size_t os::Posix::_java_thread_min_stack_allowed = (48 DEBUG_ONLY(+ 4)) * K;
+size_t os::Posix::_vm_internal_thread_min_stack_allowed = (48 DEBUG_ONLY(+ 4)) * K;
 
 #ifdef __GNUC__
 #define GET_GS() ({int gs; __asm__ volatile("movw %%gs, %w0":"=q"(gs)); gs&0xffff;})
@@ -849,7 +853,7 @@
 #endif // AMD64
 
 // return default stack size for thr_type
-size_t os::Bsd::default_stack_size(os::ThreadType thr_type) {
+size_t os::Posix::default_stack_size(os::ThreadType thr_type) {
   // default stack size (compiler thread needs larger stack)
 #ifdef AMD64
   size_t s = (thr_type == os::compiler_thread ? 4 * M : 1 * M);
@@ -859,11 +863,6 @@
   return s;
 }
 
-size_t os::Bsd::default_guard_size(os::ThreadType thr_type) {
-  // Creating guard page is very expensive. Java thread has HotSpot
-  // guard page, only enable glibc guard page for non-Java threads.
-  return (thr_type == java_thread ? 0 : page_size());
-}
 
 // Java thread:
 //
--- a/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -282,9 +282,11 @@
 ///////////////////////////////////////////////////////////////////////////////
 // thread stack
 
-size_t os::Bsd::min_stack_allowed = 64 * K;
+size_t os::Posix::_compiler_thread_min_stack_allowed = 64 * K;
+size_t os::Posix::_java_thread_min_stack_allowed = 64 * K;
+size_t os::Posix::_vm_internal_thread_min_stack_allowed = 64 * K;
 
-size_t os::Bsd::default_stack_size(os::ThreadType thr_type) {
+size_t os::Posix::default_stack_size(os::ThreadType thr_type) {
 #ifdef _LP64
   size_t s = (thr_type == os::compiler_thread ? 4 * M : 1 * M);
 #else
@@ -293,12 +295,6 @@
   return s;
 }
 
-size_t os::Bsd::default_guard_size(os::ThreadType thr_type) {
-  // Only enable glibc guard pages for non-Java threads
-  // (Java threads have HotSpot guard pages)
-  return (thr_type == java_thread ? 0 : page_size());
-}
-
 static void current_stack_region(address *bottom, size_t *size) {
   address stack_bottom;
   address stack_top;
--- a/src/os_cpu/linux_aarch64/vm/globals_linux_aarch64.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/os_cpu/linux_aarch64/vm/globals_linux_aarch64.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2014, Red Hat Inc. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -33,7 +33,7 @@
 define_pd_global(intx, ThreadStackSize,          2048); // 0 => use system default
 define_pd_global(intx, VMThreadStackSize,        2048);
 
-define_pd_global(intx, CompilerThreadStackSize,  0);
+define_pd_global(intx, CompilerThreadStackSize,  2048);
 
 define_pd_global(uintx,JVMInvokeMethodSlack,     8192);
 
--- a/src/os_cpu/linux_aarch64/vm/os_linux_aarch64.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/os_cpu/linux_aarch64/vm/os_linux_aarch64.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -473,10 +473,12 @@
 ////////////////////////////////////////////////////////////////////////////////
 // thread stack
 
-size_t os::Linux::min_stack_allowed  = 64 * K;
+size_t os::Posix::_compiler_thread_min_stack_allowed = 64 * K;
+size_t os::Posix::_java_thread_min_stack_allowed = 64 * K;
+size_t os::Posix::_vm_internal_thread_min_stack_allowed = 64 * K;
 
 // return default stack size for thr_type
-size_t os::Linux::default_stack_size(os::ThreadType thr_type) {
+size_t os::Posix::default_stack_size(os::ThreadType thr_type) {
   // default stack size (compiler thread needs larger stack)
   size_t s = (thr_type == os::compiler_thread ? 4 * M : 1 * M);
   return s;
--- a/src/os_cpu/linux_ppc/vm/globals_linux_ppc.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/os_cpu/linux_ppc/vm/globals_linux_ppc.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2012, 2015 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -33,10 +33,6 @@
 define_pd_global(intx, ThreadStackSize,          2048); // 0 => use system default
 define_pd_global(intx, VMThreadStackSize,        2048);
 
-// if we set CompilerThreadStackSize to a value different than 0, it will
-// be used in os::create_thread(). Otherwise, due the strange logic in os::create_thread(),
-// the stack size for compiler threads will default to VMThreadStackSize, although it
-// is defined to 4M in os::Linux::default_stack_size()!
 define_pd_global(intx, CompilerThreadStackSize,  4096);
 
 // Allow extra space in DEBUG builds for asserts.
--- a/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -205,8 +205,10 @@
   intptr_t* csp = (intptr_t*) *((intptr_t*) os::current_stack_pointer());
   // hack.
   frame topframe(csp, (address)0x8);
-  // return sender of current topframe which hopefully has pc != NULL.
-  return os::get_sender_for_C_frame(&topframe);
+  // Return sender of sender of current topframe which hopefully
+  // both have pc != NULL.
+  frame tmp = os::get_sender_for_C_frame(&topframe);
+  return os::get_sender_for_C_frame(&tmp);
 }
 
 // Utility functions
@@ -533,15 +535,13 @@
 ////////////////////////////////////////////////////////////////////////////////
 // thread stack
 
-size_t os::Linux::min_stack_allowed = 128*K;
+size_t os::Posix::_compiler_thread_min_stack_allowed = 128 * K;
+size_t os::Posix::_java_thread_min_stack_allowed = 128 * K;
+size_t os::Posix::_vm_internal_thread_min_stack_allowed = 128 * K;
 
 // return default stack size for thr_type
-size_t os::Linux::default_stack_size(os::ThreadType thr_type) {
+size_t os::Posix::default_stack_size(os::ThreadType thr_type) {
   // default stack size (compiler thread needs larger stack)
-  // Notice that the setting for compiler threads here have no impact
-  // because of the strange 'fallback logic' in os::create_thread().
-  // Better set CompilerThreadStackSize in globals_<os_cpu>.hpp if you want to
-  // specify a different stack size for compiler threads!
   size_t s = (thr_type == os::compiler_thread ? 4 * M : 1024 * K);
   return s;
 }
--- a/src/os_cpu/linux_sparc/vm/globals_linux_sparc.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/os_cpu/linux_sparc/vm/globals_linux_sparc.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -31,7 +31,6 @@
 //
 
 define_pd_global(size_t, JVMInvokeMethodSlack,   12288);
-define_pd_global(intx, CompilerThreadStackSize,  0);
 
 // Used on 64 bit platforms for UseCompressedOops base address
 define_pd_global(size_t, HeapBaseMinAddress,     CONST64(4)*G);
--- a/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -726,10 +726,12 @@
 ///////////////////////////////////////////////////////////////////////////////
 // thread stack
 
-size_t os::Linux::min_stack_allowed  = 128 * K;
+size_t os::Posix::_compiler_thread_min_stack_allowed = 128 * K;
+size_t os::Posix::_java_thread_min_stack_allowed = 128 * K;
+size_t os::Posix::_vm_internal_thread_min_stack_allowed = 128 * K;
 
 // return default stack size for thr_type
-size_t os::Linux::default_stack_size(os::ThreadType thr_type) {
+size_t os::Posix::default_stack_size(os::ThreadType thr_type) {
   // default stack size (compiler thread needs larger stack)
   size_t s = (thr_type == os::compiler_thread ? 4 * M : 1 * M);
   return s;
--- a/src/os_cpu/linux_x86/vm/globals_linux_x86.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/os_cpu/linux_x86/vm/globals_linux_x86.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -30,9 +30,11 @@
 
 define_pd_global(bool, DontYieldALot,            false);
 #ifdef AMD64
+define_pd_global(intx, CompilerThreadStackSize,  1024);
 define_pd_global(intx, ThreadStackSize,          1024); // 0 => use system default
 define_pd_global(intx, VMThreadStackSize,        1024);
 #else
+define_pd_global(intx, CompilerThreadStackSize,  512);
 // ThreadStackSize 320 allows a couple of test cases to run while
 // keeping the number of threads that can be created high.  System
 // default ThreadStackSize appears to be 512 which is too big.
@@ -40,8 +42,6 @@
 define_pd_global(intx, VMThreadStackSize,        512);
 #endif // AMD64
 
-define_pd_global(intx, CompilerThreadStackSize,  0);
-
 define_pd_global(size_t, JVMInvokeMethodSlack,   8192);
 
 // Used on 64 bit platforms for UseCompressedOops base address
--- a/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -676,13 +676,17 @@
 // thread stack
 
 #ifdef AMD64
-size_t os::Linux::min_stack_allowed  = 64 * K;
+size_t os::Posix::_compiler_thread_min_stack_allowed = 64 * K;
+size_t os::Posix::_java_thread_min_stack_allowed = 64 * K;
+size_t os::Posix::_vm_internal_thread_min_stack_allowed = 64 * K;
 #else
-size_t os::Linux::min_stack_allowed  =  (48 DEBUG_ONLY(+4))*K;
+size_t os::Posix::_compiler_thread_min_stack_allowed = (48 DEBUG_ONLY(+ 4)) * K;
+size_t os::Posix::_java_thread_min_stack_allowed = (48 DEBUG_ONLY(+ 4)) * K;
+size_t os::Posix::_vm_internal_thread_min_stack_allowed = (48 DEBUG_ONLY(+ 4)) * K;
 #endif // AMD64
 
 // return default stack size for thr_type
-size_t os::Linux::default_stack_size(os::ThreadType thr_type) {
+size_t os::Posix::default_stack_size(os::ThreadType thr_type) {
   // default stack size (compiler thread needs larger stack)
 #ifdef AMD64
   size_t s = (thr_type == os::compiler_thread ? 4 * M : 1 * M);
--- a/src/os_cpu/linux_zero/vm/os_linux_zero.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/os_cpu/linux_zero/vm/os_linux_zero.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -307,9 +307,11 @@
 ///////////////////////////////////////////////////////////////////////////////
 // thread stack
 
-size_t os::Linux::min_stack_allowed = 64 * K;
+size_t os::Posix::_compiler_thread_min_stack_allowed = 64 * K;
+size_t os::Posix::_java_thread_min_stack_allowed = 64 * K;
+size_t os::Posix::_vm_internal_thread_min_stack_allowed = 64 * K;
 
-size_t os::Linux::default_stack_size(os::ThreadType thr_type) {
+size_t os::Posix::default_stack_size(os::ThreadType thr_type) {
 #ifdef _LP64
   size_t s = (thr_type == os::compiler_thread ? 4 * M : 1 * M);
 #else
--- a/src/os_cpu/solaris_sparc/vm/globals_solaris_sparc.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/os_cpu/solaris_sparc/vm/globals_solaris_sparc.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -31,7 +31,6 @@
 //
 
 define_pd_global(size_t, JVMInvokeMethodSlack,   12288);
-define_pd_global(intx, CompilerThreadStackSize,  0);
 
 // Used on 64 bit platforms for UseCompressedOops base address
 #ifdef _LP64
--- a/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -84,9 +84,13 @@
 // Minimum stack size for the VM.  It's easier to document a constant
 // but it's different for x86 and sparc because the page sizes are different.
 #ifdef _LP64
-size_t os::Solaris::min_stack_allowed = 128*K;
+size_t os::Posix::_compiler_thread_min_stack_allowed = 128 * K;
+size_t os::Posix::_java_thread_min_stack_allowed = 128 * K;
+size_t os::Posix::_vm_internal_thread_min_stack_allowed = 128 * K;
 #else
-size_t os::Solaris::min_stack_allowed = 96*K;
+size_t os::Posix::_compiler_thread_min_stack_allowed = 96 * K;
+size_t os::Posix::_java_thread_min_stack_allowed = 96 * K;
+size_t os::Posix::_vm_internal_thread_min_stack_allowed = 96 * K;
 #endif
 
 int os::Solaris::max_register_window_saves_before_flushing() {
--- a/src/os_cpu/solaris_x86/vm/globals_solaris_x86.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/os_cpu/solaris_x86/vm/globals_solaris_x86.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -30,10 +30,12 @@
 
 define_pd_global(bool, DontYieldALot,            true); // Determined in the design center
 #ifdef AMD64
+define_pd_global(intx, CompilerThreadStackSize,  1024);
 define_pd_global(intx, ThreadStackSize,          1024); // 0 => use system default
 define_pd_global(intx, VMThreadStackSize,        1024);
 define_pd_global(size_t, JVMInvokeMethodSlack,   8*K);
 #else
+define_pd_global(intx, CompilerThreadStackSize,  512);
 // ThreadStackSize 320 allows a couple of test cases to run while
 // keeping the number of threads that can be created high.
 define_pd_global(intx, ThreadStackSize,          320);
@@ -41,7 +43,6 @@
 define_pd_global(size_t, JVMInvokeMethodSlack,   10*K);
 #endif // AMD64
 
-define_pd_global(intx, CompilerThreadStackSize,  0);
 
 // Used on 64 bit platforms for UseCompressedOops base address
 define_pd_global(size_t, HeapBaseMinAddress,     2*G);
--- a/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -86,15 +86,19 @@
 
 #define MAX_PATH (2 * K)
 
-// Minimum stack size for the VM.  It's easier to document a constant value
+// Minimum stack sizes for the VM.  It's easier to document a constant value
 // but it's different for x86 and sparc because the page sizes are different.
 #ifdef AMD64
-size_t os::Solaris::min_stack_allowed = 224*K;
+size_t os::Posix::_compiler_thread_min_stack_allowed = 394 * K;
+size_t os::Posix::_java_thread_min_stack_allowed = 224 * K;
+size_t os::Posix::_vm_internal_thread_min_stack_allowed = 224 * K;
 #define REG_SP REG_RSP
 #define REG_PC REG_RIP
 #define REG_FP REG_RBP
 #else
-size_t os::Solaris::min_stack_allowed = 64*K;
+size_t os::Posix::_compiler_thread_min_stack_allowed = 64 * K;
+size_t os::Posix::_java_thread_min_stack_allowed = 64 * K;
+size_t os::Posix::_vm_internal_thread_min_stack_allowed = 64 * K;
 #define REG_SP UESP
 #define REG_PC EIP
 #define REG_FP EBP
--- a/src/share/vm/classfile/classLoader.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/classfile/classLoader.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -85,6 +85,7 @@
 typedef jzentry* (JNICALL *GetNextEntry_t)(jzfile *zip, jint n);
 typedef jboolean (JNICALL *ZipInflateFully_t)(void *inBuf, jlong inLen, void *outBuf, jlong outLen, char **pmsg);
 typedef jint     (JNICALL *Crc32_t)(jint crc, const jbyte *buf, jint len);
+typedef void     (JNICALL *FreeEntry_t)(jzfile *zip, jzentry *entry);
 
 static ZipOpen_t         ZipOpen            = NULL;
 static ZipClose_t        ZipClose           = NULL;
@@ -95,6 +96,7 @@
 static canonicalize_fn_t CanonicalizeEntry  = NULL;
 static ZipInflateFully_t ZipInflateFully    = NULL;
 static Crc32_t           Crc32              = NULL;
+static FreeEntry_t       FreeEntry          = NULL;
 
 // Entry points for jimage.dll for loading jimage file entries
 
@@ -150,6 +152,7 @@
 GrowableArray<char*>* ClassLoader::_boot_modules_array = NULL;
 GrowableArray<char*>* ClassLoader::_platform_modules_array = NULL;
 SharedPathsMiscInfo* ClassLoader::_shared_paths_misc_info = NULL;
+int  ClassLoader::_num_patch_mod_prefixes = 0;
 #endif
 
 // helper routines
@@ -319,6 +322,20 @@
   FREE_C_HEAP_ARRAY(char, _zip_name);
 }
 
+bool ClassPathZipEntry::stream_exists(const char* name) {
+  // enable call to C land
+  JavaThread* thread = JavaThread::current();
+  ThreadToNativeFromVM ttn(thread);
+  // check whether zip archive contains name
+  jint name_len, filesize;
+  jzentry* entry = (*FindEntry)(_zip, name, &filesize, &name_len);
+  if (entry != NULL) {
+    (*FreeEntry)(_zip, entry);
+    return true;
+  }
+  return false;
+}
+
 u1* ClassPathZipEntry::open_entry(const char* name, jint* filesize, bool nul_terminate, TRAPS) {
     // enable call to C land
   JavaThread* thread = JavaThread::current();
@@ -640,7 +657,7 @@
 
   struct stat st;
   if (os::stat(path, &st) == 0) {
-    if ((st.st_mode & S_IFREG) != S_IFREG) { // is directory
+    if ((st.st_mode & S_IFMT) != S_IFREG) { // is not a regular file
       if (!os::dir_is_empty(path)) {
         tty->print_cr("Error: non-empty directory '%s'", path);
         exit_with_path_failure("CDS allows only empty directories in archived classpaths", NULL);
@@ -693,8 +710,6 @@
   GrowableArray<ModulePatchPath*>* patch_mod_args = Arguments::get_patch_mod_prefix();
   int num_of_entries = patch_mod_args->length();
 
-  assert(!DumpSharedSpaces, "DumpSharedSpaces not supported with --patch-module");
-  assert(!UseSharedSpaces, "UseSharedSpaces not supported with --patch-module");
 
   // Set up the boot loader's _patch_mod_entries list
   _patch_mod_entries = new (ResourceObj::C_HEAP, mtModule) GrowableArray<ModuleClassPathList*>(num_of_entries, true);
@@ -851,7 +866,7 @@
                                                      bool is_boot_append, TRAPS) {
   JavaThread* thread = JavaThread::current();
   ClassPathEntry* new_entry = NULL;
-  if ((st->st_mode & S_IFREG) == S_IFREG) {
+  if ((st->st_mode & S_IFMT) == S_IFREG) {
     ResourceMark rm(thread);
     // Regular file, should be a zip or jimage file
     // Canonicalized filename
@@ -914,7 +929,7 @@
   // check for a regular file
   struct stat st;
   if (os::stat(path, &st) == 0) {
-    if ((st.st_mode & S_IFREG) == S_IFREG) {
+    if ((st.st_mode & S_IFMT) == S_IFREG) {
       char canonical_path[JVM_MAXPATHLEN];
       if (get_canonical_path(path, canonical_path, JVM_MAXPATHLEN)) {
         char* error_msg = NULL;
@@ -1068,6 +1083,7 @@
   GetNextEntry = CAST_TO_FN_PTR(GetNextEntry_t, os::dll_lookup(handle, "ZIP_GetNextEntry"));
   ZipInflateFully = CAST_TO_FN_PTR(ZipInflateFully_t, os::dll_lookup(handle, "ZIP_InflateFully"));
   Crc32        = CAST_TO_FN_PTR(Crc32_t, os::dll_lookup(handle, "ZIP_CRC32"));
+  FreeEntry    = CAST_TO_FN_PTR(FreeEntry_t, os::dll_lookup(handle, "ZIP_FreeEntry"));
 
   // ZIP_Close is not exported on Windows in JDK5.0 so don't abort if ZIP_Close is NULL
   if (ZipOpen == NULL || FindEntry == NULL || ReadEntry == NULL ||
@@ -1358,7 +1374,7 @@
   if (!Universe::is_module_initialized() &&
       !ModuleEntryTable::javabase_defined() &&
       mod_entry == NULL) {
-    mod_entry = ModuleEntryTable::javabase_module();
+    mod_entry = ModuleEntryTable::javabase_moduleEntry();
   }
 
   // The module must be a named module
@@ -1395,6 +1411,57 @@
   return NULL;
 }
 
+#if INCLUDE_CDS
+// The following function is only used during CDS dump time.
+// It checks if a class can be found in the jar entries of the _patch_mod_entries.
+// It does not support non-jar entries.
+bool ClassLoader::is_in_patch_module(const char* const file_name) {
+  assert(DumpSharedSpaces, "dump time only");
+  if (_patch_mod_entries == NULL) {
+    return false;
+  }
+
+  int num_of_entries = _patch_mod_entries->length();
+  char* class_module_name = NULL;
+  ResourceMark rm;
+  const char *pkg_name = package_from_name(file_name);
+  // Using the jimage to obtain the class' module name.
+  // The ModuleEntryTable cannot be used at this point during dump time
+  // because the module system hasn't been initialized yet.
+  if (pkg_name != NULL) {
+    JImageFile *jimage = _jrt_entry->jimage();
+    class_module_name = (char*)(*JImagePackageToModule)(jimage, pkg_name);
+  }
+
+  if (class_module_name == NULL) {
+    return false;
+  }
+
+  // Loop through all the patch module entries looking for module
+  for (int i = 0; i < num_of_entries; i++) {
+    ModuleClassPathList* module_cpl = _patch_mod_entries->at(i);
+    Symbol* module_cpl_name = module_cpl->module_name();
+
+    if (strcmp(module_cpl_name->as_C_string(), class_module_name) == 0) {
+      // Class' module has been located, attempt to locate
+      // the class from the module's ClassPathEntry list.
+      ClassPathEntry* e = module_cpl->module_first_entry();
+      while (e != NULL) {
+        if (e->is_jar_file()) {
+          if (e->stream_exists(file_name)) {
+            return true;
+          } else {
+            e = e->next();
+          }
+        }
+      }
+    }
+  }
+
+  return false;
+}
+#endif // INCLUDE_CDS
+
 instanceKlassHandle ClassLoader::load_class(Symbol* name, bool search_append_only, TRAPS) {
   assert(name != NULL, "invariant");
   assert(THREAD->is_Java_thread(), "must be a JavaThread");
@@ -1420,8 +1487,8 @@
 
   // If DumpSharedSpaces is true boot loader visibility boundaries are set to:
   //   - [jimage] + [_first_append_entry to _last_append_entry] (all path entries).
-  // No --patch-module entries or exploded module builds are included since CDS
-  // is not supported if --patch-module or exploded module builds are used.
+  // If a class is found in the --patch-module entries, the class will not be included in the
+  // CDS archive. Also, CDS is not supported if exploded module builds are used.
   //
   // If search_append_only is true, boot loader visibility boundaries are
   // set to be _first_append_entry to the end. This includes:
@@ -1444,8 +1511,17 @@
   // found within its module specification, the search should continue to Load Attempt #2.
   // Note: The --patch-module entries are never searched if the boot loader's
   //       visibility boundary is limited to only searching the append entries.
-  if (_patch_mod_entries != NULL && !search_append_only && !DumpSharedSpaces) {
-    stream = search_module_entries(_patch_mod_entries, class_name, file_name, CHECK_NULL);
+  if (_patch_mod_entries != NULL && !search_append_only) {
+    if (!DumpSharedSpaces) {
+      stream = search_module_entries(_patch_mod_entries, class_name, file_name, CHECK_NULL);
+    } else {
+#if INCLUDE_CDS
+      if (is_in_patch_module(file_name)) {
+        tty->print_cr("Preload Warning: Skip archiving class %s found in --patch-module entry", class_name);
+        return NULL;
+      }
+#endif
+    }
   }
 
   // Load Attempt #2: [jimage | exploded build]
@@ -1596,8 +1672,57 @@
 }
 
 #if INCLUDE_CDS
+// Capture all the --patch-module entries specified during CDS dump time.
+// It also captures the non-existing path(s) and the required file(s) during inspecting
+// the entries.
+void ClassLoader::setup_patch_mod_path() {
+  assert(DumpSharedSpaces, "only used with -Xshare:dump");
+  ResourceMark rm;
+  GrowableArray<ModulePatchPath*>* patch_mod_args = Arguments::get_patch_mod_prefix();
+  if (patch_mod_args != NULL) {
+    int num_of_entries = patch_mod_args->length();
+    for (int i = 0; i < num_of_entries; i++) {
+      const char* module_name = (patch_mod_args->at(i))->module_name();
+      const char* module_path = (patch_mod_args->at(i))->path_string();
+      int path_len = (int)strlen(module_path);
+      int name_len = (int)strlen(module_name);
+      int buf_len = name_len + path_len + 2; // add 2 for the '=' and NULL terminator
+      int end = 0;
+      char* buf = NEW_C_HEAP_ARRAY(char, buf_len, mtInternal);
+      // Iterate over the module's class path entries
+      for (int start = 0; start < path_len; start = end) {
+        while (module_path[end] && module_path[end] != os::path_separator()[0]) {
+          end++;
+        }
+        strncpy(buf, &module_path[start], end - start);
+        buf[end - start] = '\0';
+        struct stat st;
+        if (os::stat(buf, &st) != 0) {
+          // File not found
+          _shared_paths_misc_info->add_nonexist_path(buf);
+        } else {
+          if ((st.st_mode & S_IFMT) != S_IFREG) { // is not a regular file
+            vm_exit_during_initialization(
+              "--patch-module requires a regular file during dumping", buf);
+          } else {
+            _shared_paths_misc_info->add_required_file(buf);
+          }
+        }
+        while (module_path[end] == os::path_separator()[0]) {
+          end++;
+        }
+      };
+      jio_snprintf(buf, buf_len, "%s=%s", module_name, module_path);
+      _shared_paths_misc_info->add_patch_mod_classpath((const char*)buf);
+      _num_patch_mod_prefixes++;
+      FREE_C_HEAP_ARRAY(char, buf);
+    }
+  }
+}
+
 void ClassLoader::initialize_shared_path() {
   if (DumpSharedSpaces) {
+    setup_patch_mod_path();
     ClassLoaderExt::setup_search_paths();
     _shared_paths_misc_info->write_jint(0); // see comments in SharedPathsMiscInfo::check()
   }
@@ -1708,7 +1833,7 @@
     if (jb_module == NULL) {
       vm_exit_during_initialization("Unable to create ModuleEntry for java.base");
     }
-    ModuleEntryTable::set_javabase_module(jb_module);
+    ModuleEntryTable::set_javabase_moduleEntry(jb_module);
   }
 }
 
--- a/src/share/vm/classfile/classLoader.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/classfile/classLoader.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -69,6 +69,7 @@
   // Attempt to locate file_name through this class path entry.
   // Returns a class file parsing stream if successfull.
   virtual ClassFileStream* open_stream(const char* name, TRAPS) = 0;
+  virtual bool stream_exists(const char* name) = 0;
   // Debugging
   NOT_PRODUCT(virtual void compile_the_world(Handle loader, TRAPS) = 0;)
 };
@@ -83,6 +84,7 @@
   JImageFile* jimage() const { return NULL; }
   ClassPathDirEntry(const char* dir);
   ClassFileStream* open_stream(const char* name, TRAPS);
+  bool stream_exists(const char* name) { return false; }
   // Debugging
   NOT_PRODUCT(void compile_the_world(Handle loader, TRAPS);)
 };
@@ -126,6 +128,7 @@
   ClassFileStream* open_stream(const char* name, TRAPS);
   void contents_do(void f(const char* name, void* context), void* context);
   bool is_multiple_versioned(TRAPS) NOT_CDS_RETURN_(false);
+  bool stream_exists(const char* name);
   // Debugging
   NOT_PRODUCT(void compile_the_world(Handle loader, TRAPS);)
 };
@@ -145,6 +148,7 @@
   ClassPathImageEntry(JImageFile* jimage, const char* name);
   ~ClassPathImageEntry();
   ClassFileStream* open_stream(const char* name, TRAPS);
+  bool stream_exists(const char* name) { return false; }
 
   // Debugging
   NOT_PRODUCT(void compile_the_world(Handle loader, TRAPS);)
@@ -255,6 +259,7 @@
 
   // Info used by CDS
   CDS_ONLY(static SharedPathsMiscInfo * _shared_paths_misc_info;)
+  CDS_ONLY(static int _num_patch_mod_prefixes;)
 
   // Initialization:
   //   - setup the boot loader's system class path
@@ -427,6 +432,9 @@
   static void initialize_module_loader_map(JImageFile* jimage);
   static s2 classloader_type(Symbol* class_name, ClassPathEntry* e,
                              int classpath_index, TRAPS);
+  static bool is_in_patch_module(const char* const file_name);
+  static void setup_patch_mod_path(); // Only when -Xshare:dump
+  static int num_patch_mod_prefixes() { return _num_patch_mod_prefixes; }
 #endif
 
   static void  trace_class_path(const char* msg, const char* name = NULL);
--- a/src/share/vm/classfile/javaClasses.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/classfile/javaClasses.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -773,6 +773,41 @@
   InstanceKlass::cast(k())->do_local_static_fields(&initialize_static_field, mirror, CHECK);
 }
 
+// Set the java.lang.reflect.Module module field in the java_lang_Class mirror
+void java_lang_Class::set_mirror_module_field(KlassHandle k, Handle mirror, Handle module, TRAPS) {
+  if (module.is_null()) {
+    // During startup, the module may be NULL only if java.base has not been defined yet.
+    // Put the class on the fixup_module_list to patch later when the java.lang.reflect.Module
+    // for java.base is known.
+    assert(!Universe::is_module_initialized(), "Incorrect java.lang.reflect.Module pre module system initialization");
+    MutexLocker m1(Module_lock, THREAD);
+    // Keep list of classes needing java.base module fixup
+    if (!ModuleEntryTable::javabase_defined()) {
+      if (fixup_module_field_list() == NULL) {
+        GrowableArray<Klass*>* list =
+          new (ResourceObj::C_HEAP, mtModule) GrowableArray<Klass*>(500, true);
+        set_fixup_module_field_list(list);
+      }
+      k->class_loader_data()->inc_keep_alive();
+      fixup_module_field_list()->push(k());
+    } else {
+      // java.base was defined at some point between calling create_mirror()
+      // and obtaining the Module_lock, patch this particular class with java.base.
+      ModuleEntry *javabase_entry = ModuleEntryTable::javabase_moduleEntry();
+      assert(javabase_entry != NULL && javabase_entry->module() != NULL,
+             "Setting class module field, java.base should be defined");
+      Handle javabase_handle(THREAD, JNIHandles::resolve(javabase_entry->module()));
+      set_module(mirror(), javabase_handle());
+    }
+  } else {
+    assert(Universe::is_module_initialized() ||
+           (ModuleEntryTable::javabase_defined() &&
+            (module() == JNIHandles::resolve(ModuleEntryTable::javabase_moduleEntry()->module()))),
+           "Incorrect java.lang.reflect.Module specification while creating mirror");
+    set_module(mirror(), module());
+  }
+}
+
 void java_lang_Class::create_mirror(KlassHandle k, Handle class_loader,
                                     Handle module, Handle protection_domain, TRAPS) {
   assert(k->java_mirror() == NULL, "should only assign mirror once");
@@ -835,25 +870,13 @@
     set_class_loader(mirror(), class_loader());
 
     // set the module field in the java_lang_Class instance
-    // This may be null during bootstrap but will get fixed up later on.
-    set_module(mirror(), module());
+    set_mirror_module_field(k, mirror, module, THREAD);
 
     // Setup indirection from klass->mirror last
     // after any exceptions can happen during allocations.
     if (!k.is_null()) {
       k->set_java_mirror(mirror());
     }
-
-    // Keep list of classes needing java.base module fixup.
-    if (!ModuleEntryTable::javabase_defined()) {
-      if (fixup_module_field_list() == NULL) {
-        GrowableArray<Klass*>* list =
-          new (ResourceObj::C_HEAP, mtModule) GrowableArray<Klass*>(500, true);
-        set_fixup_module_field_list(list);
-      }
-      k->class_loader_data()->inc_keep_alive();
-      fixup_module_field_list()->push(k());
-    }
   } else {
     if (fixup_mirror_list() == NULL) {
       GrowableArray<Klass*>* list =
--- a/src/share/vm/classfile/javaClasses.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/classfile/javaClasses.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -219,6 +219,7 @@
   static void set_class_loader(oop java_class, oop class_loader);
   static void set_component_mirror(oop java_class, oop comp_mirror);
   static void initialize_mirror_fields(KlassHandle k, Handle mirror, Handle protection_domain, TRAPS);
+  static void set_mirror_module_field(KlassHandle K, Handle mirror, Handle module, TRAPS);
  public:
   static void compute_offsets();
 
--- a/src/share/vm/classfile/klassFactory.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/classfile/klassFactory.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -25,12 +25,85 @@
 #include "precompiled.hpp"
 #include "classfile/classFileParser.hpp"
 #include "classfile/classFileStream.hpp"
+#include "classfile/classLoader.hpp"
 #include "classfile/classLoaderData.hpp"
+#include "classfile/classLoaderData.inline.hpp"
 #include "classfile/klassFactory.hpp"
+#include "classfile/sharedClassUtil.hpp"
+#include "memory/metaspaceShared.hpp"
 #include "memory/resourceArea.hpp"
 #include "prims/jvmtiEnvBase.hpp"
+#include "prims/jvmtiRedefineClasses.hpp"
 #include "trace/traceMacros.hpp"
 
+// called during initial loading of a shared class
+instanceKlassHandle KlassFactory::check_shared_class_file_load_hook(
+                                          instanceKlassHandle ik,
+                                          Symbol* class_name,
+                                          Handle class_loader,
+                                          Handle protection_domain, TRAPS) {
+#if INCLUDE_CDS && INCLUDE_JVMTI
+  assert(ik.not_null(), "sanity");
+  assert(ik()->is_shared(), "expecting a shared class");
+
+  if (JvmtiExport::should_post_class_file_load_hook()) {
+    assert(THREAD->is_Java_thread(), "must be JavaThread");
+
+    // Post the CFLH
+    JvmtiCachedClassFileData* cached_class_file = NULL;
+    JvmtiCachedClassFileData* archived_class_data = ik->get_archived_class_data();
+    assert(archived_class_data != NULL, "shared class has no archived class data");
+    unsigned char* ptr =
+        VM_RedefineClasses::get_cached_class_file_bytes(archived_class_data);
+    unsigned char* end_ptr =
+        ptr + VM_RedefineClasses::get_cached_class_file_len(archived_class_data);
+    unsigned char* old_ptr = ptr;
+    JvmtiExport::post_class_file_load_hook(class_name,
+                                           class_loader,
+                                           protection_domain,
+                                           &ptr,
+                                           &end_ptr,
+                                           &cached_class_file);
+    if (old_ptr != ptr) {
+      // JVMTI agent has modified class file data.
+      // Set new class file stream using JVMTI agent modified class file data.
+      ClassLoaderData* loader_data =
+        ClassLoaderData::class_loader_data(class_loader());
+      int path_index = ik->shared_classpath_index();
+      SharedClassPathEntry* ent =
+        (SharedClassPathEntry*)FileMapInfo::shared_classpath(path_index);
+      ClassFileStream* stream = new ClassFileStream(ptr,
+                                                    end_ptr - ptr,
+                                                    ent->_name,
+                                                    ClassFileStream::verify);
+      ClassFileParser parser(stream,
+                             class_name,
+                             loader_data,
+                             protection_domain,
+                             NULL,
+                             NULL,
+                             ClassFileParser::BROADCAST, // publicity level
+                             CHECK_NULL);
+      instanceKlassHandle new_ik = parser.create_instance_klass(true /* changed_by_loadhook */,
+                                                                CHECK_NULL);
+      if (cached_class_file != NULL) {
+        new_ik->set_cached_class_file(cached_class_file);
+      }
+
+      if (class_loader.is_null()) {
+        ResourceMark rm;
+        ClassLoader::add_package(class_name->as_C_string(), path_index, THREAD);
+      }
+
+      return new_ik;
+    }
+  }
+#endif
+
+  return NULL;
+}
+
+
 static ClassFileStream* check_class_file_load_hook(ClassFileStream* stream,
                                                    Symbol* name,
                                                    ClassLoaderData* loader_data,
@@ -97,7 +170,6 @@
                                                      const InstanceKlass* host_klass,
                                                      GrowableArray<Handle>* cp_patches,
                                                      TRAPS) {
-
   assert(stream != NULL, "invariant");
   assert(loader_data != NULL, "invariant");
   assert(THREAD->is_Java_thread(), "must be a JavaThread");
@@ -142,5 +214,27 @@
 
   TRACE_KLASS_CREATION(result, parser, THREAD);
 
+#if INCLUDE_CDS && INCLUDE_JVMTI
+  if (DumpSharedSpaces) {
+    assert(cached_class_file == NULL, "Sanity");
+    // Archive the class stream data into the optional data section
+    JvmtiCachedClassFileData *p;
+    int len;
+    const unsigned char *bytes;
+    // event based tracing might set cached_class_file
+    if ((bytes = result->get_cached_class_file_bytes()) != NULL) {
+      len = result->get_cached_class_file_len();
+    } else {
+      len = stream->length();
+      bytes = stream->buffer();
+    }
+    p = (JvmtiCachedClassFileData*)MetaspaceShared::optional_data_space_alloc(
+                    offset_of(JvmtiCachedClassFileData, data) + len);
+    p->length = len;
+    memcpy(p->data, bytes, len);
+    result->set_archived_class_data(p);
+  }
+#endif
+
   return result;
 }
--- a/src/share/vm/classfile/klassFactory.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/classfile/klassFactory.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -75,6 +75,12 @@
                                                 const InstanceKlass* host_klass,
                                                 GrowableArray<Handle>* cp_patches,
                                                 TRAPS);
+ public:
+  static instanceKlassHandle check_shared_class_file_load_hook(
+                                          instanceKlassHandle ik,
+                                          Symbol* class_name,
+                                          Handle class_loader,
+                                          Handle protection_domain, TRAPS);
 };
 
 #endif // SHARE_VM_CLASSFILE_KLASSFACTORY_HPP
--- a/src/share/vm/classfile/moduleEntry.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/classfile/moduleEntry.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -92,7 +92,7 @@
   // read java.base.  If either of these conditions
   // hold, readability has been established.
   if (!this->is_named() ||
-      (m == ModuleEntryTable::javabase_module())) {
+      (m == ModuleEntryTable::javabase_moduleEntry())) {
     return true;
   }
 
@@ -358,16 +358,27 @@
   }
 
   // Set java.lang.reflect.Module, version and location for java.base
-  ModuleEntry* jb_module = javabase_module();
+  ModuleEntry* jb_module = javabase_moduleEntry();
   assert(jb_module != NULL, "java.base ModuleEntry not defined");
-  jb_module->set_module(boot_loader_data->add_handle(module_handle));
   jb_module->set_version(version);
   jb_module->set_location(location);
+  // Once java.base's ModuleEntry _module field is set with the known
+  // java.lang.reflect.Module, java.base is considered "defined" to the VM.
+  jb_module->set_module(boot_loader_data->add_handle(module_handle));
+
   // Store pointer to the ModuleEntry for java.base in the java.lang.reflect.Module object.
   java_lang_reflect_Module::set_module_entry(module_handle(), jb_module);
+
+  // Patch any previously loaded classes' module field with java.base's java.lang.reflect.Module.
+  patch_javabase_entries(module_handle);
 }
 
+// Within java.lang.Class instances there is a java.lang.reflect.Module field
+// that must be set with the defining module.  During startup, prior to java.base's
+// definition, classes needing their module field set are added to the fixup_module_list.
+// Their module field is set once java.base's java.lang.reflect.Module is known to the VM.
 void ModuleEntryTable::patch_javabase_entries(Handle module_handle) {
+  assert(Module_lock->owned_by_self(), "should have the Module_lock");
   if (module_handle.is_null()) {
     fatal("Unable to patch the module field of classes loaded prior to java.base's definition, invalid java.lang.reflect.Module");
   }
@@ -389,9 +400,7 @@
   for (int i = 0; i < list_length; i++) {
     Klass* k = list->at(i);
     assert(k->is_klass(), "List should only hold classes");
-    Thread* THREAD = Thread::current();
-    KlassHandle kh(THREAD, k);
-    java_lang_Class::fixup_module_field(kh, module_handle);
+    java_lang_Class::fixup_module_field(KlassHandle(k), module_handle);
     k->class_loader_data()->dec_keep_alive();
   }
 
--- a/src/share/vm/classfile/moduleEntry.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/classfile/moduleEntry.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -78,11 +78,11 @@
     _must_walk_reads = false;
   }
 
-  Symbol*          name() const          { return literal(); }
-  void             set_name(Symbol* n)   { set_literal(n); }
+  Symbol*          name() const                        { return literal(); }
+  void             set_name(Symbol* n)                 { set_literal(n); }
 
-  jobject          module() const        { return _module; }
-  void             set_module(jobject j) { _module = j; }
+  jobject          module() const                      { return _module; }
+  void             set_module(jobject j)               { _module = j; }
 
   // The shared ProtectionDomain reference is set once the VM loads a shared class
   // originated from the current Module. The referenced ProtectionDomain object is
@@ -217,13 +217,13 @@
 
   // Special handling for unnamed module, one per class loader's ModuleEntryTable
   void create_unnamed_module(ClassLoaderData* loader_data);
-  ModuleEntry* unnamed_module()                           { return _unnamed_module; }
+  ModuleEntry* unnamed_module()                                { return _unnamed_module; }
 
   // Special handling for java.base
-  static ModuleEntry* javabase_module()                   { return _javabase_module; }
-  static void set_javabase_module(ModuleEntry* java_base) { _javabase_module = java_base; }
-  static bool javabase_defined()                          { return ((_javabase_module != NULL) &&
-                                                                    (_javabase_module->module() != NULL)); }
+  static ModuleEntry* javabase_moduleEntry()                   { return _javabase_module; }
+  static void set_javabase_moduleEntry(ModuleEntry* java_base) { _javabase_module = java_base; }
+  static bool javabase_defined()                               { return ((_javabase_module != NULL) &&
+                                                                         (_javabase_module->module() != NULL)); }
   static void finalize_javabase(Handle module_handle, Symbol* version, Symbol* location);
   static void patch_javabase_entries(Handle module_handle);
 
--- a/src/share/vm/classfile/modules.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/classfile/modules.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -206,7 +206,7 @@
   assert(pkg_list->length() == 0 || package_table != NULL, "Bad package_table");
 
   // Ensure java.base's ModuleEntry has been created
-  assert(ModuleEntryTable::javabase_module() != NULL, "No ModuleEntry for java.base");
+  assert(ModuleEntryTable::javabase_moduleEntry() != NULL, "No ModuleEntry for java.base");
 
   bool duplicate_javabase = false;
   {
@@ -226,7 +226,7 @@
       for (int x = 0; x < pkg_list->length(); x++) {
         // Some of java.base's packages were added early in bootstrapping, ignore duplicates.
         if (package_table->lookup_only(pkg_list->at(x)) == NULL) {
-          pkg = package_table->locked_create_entry_or_null(pkg_list->at(x), ModuleEntryTable::javabase_module());
+          pkg = package_table->locked_create_entry_or_null(pkg_list->at(x), ModuleEntryTable::javabase_moduleEntry());
           assert(pkg != NULL, "Unable to create a java.base package entry");
         }
         // Unable to have a GrowableArray of TempNewSymbol.  Must decrement the refcount of
@@ -255,9 +255,6 @@
     log_trace(modules)("define_javabase_module(): creation of package %s for module java.base",
                        (pkg_list->at(x))->as_C_string());
   }
-
-  // Patch any previously loaded classes' module field with java.base's jlr.Module.
-  ModuleEntryTable::patch_javabase_entries(module_handle);
 }
 
 void Modules::define_module(jobject module, jstring version,
--- a/src/share/vm/classfile/sharedPathsMiscInfo.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/classfile/sharedPathsMiscInfo.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -86,6 +86,9 @@
   case REQUIRED:
     out->print("Expecting that file %s must exist and is not altered", path);
     break;
+  case PATCH_MOD:
+    out->print("Expecting --patch-module=%s", path);
+    break;
   default:
     ShouldNotReachHere();
   }
@@ -146,6 +149,9 @@
           // But we want it to not exist -> fail
           return fail("File must not exist");
         }
+        if ((st.st_mode & S_IFMT) != S_IFREG) {
+          return fail("Did not get a regular file as expected.");
+        }
         time_t    timestamp;
         long      filesize;
 
@@ -161,7 +167,26 @@
       }
     }
     break;
-
+  case PATCH_MOD:
+    {
+      GrowableArray<ModulePatchPath*>* patch_mod_args = Arguments::get_patch_mod_prefix();
+      if (patch_mod_args != NULL) {
+        int num_of_entries = patch_mod_args->length();
+        for (int i = 0; i < num_of_entries; i++) {
+          const char* module_name = (patch_mod_args->at(i))->module_name();
+          const char* path_string = (patch_mod_args->at(i))->path_string();
+          size_t n = strlen(module_name);
+          // path contains the module name, followed by '=', and one or more entries.
+          // E.g.: "java.base=foo" or "java.naming=dir1:dir2:dir3"
+          if ((strncmp(module_name, path, n) != 0) ||
+              (path[n] != '=') ||
+              (strcmp(path + n + 1, path_string) != 0)) {
+            return fail("--patch-module mismatch, path not found in run time: ", path);
+          }
+        }
+      }
+    }
+    break;
   default:
     return fail("Corrupted archive file header");
   }
--- a/src/share/vm/classfile/sharedPathsMiscInfo.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/classfile/sharedPathsMiscInfo.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -104,10 +104,28 @@
     add_path(path, NON_EXIST);
   }
 
+  // The path must exist and have required size and modification time
+  void add_required_file(const char* path) {
+    add_path(path, REQUIRED);
+
+    struct stat st;
+    if (os::stat(path, &st) != 0) {
+      assert(0, "sanity");
+#if INCLUDE_CDS
+      ClassLoader::exit_with_path_failure("failed to os::stat(%s)", path); // should not happen
+#endif
+    }
+    write_time(st.st_mtime);
+    write_long(st.st_size);
+  }
+
   // The path must exist, and must contain exactly <num_entries> files/dirs
   void add_boot_classpath(const char* path) {
     add_path(path, BOOT);
   }
+  void add_patch_mod_classpath(const char* path) {
+    add_path(path, PATCH_MOD);
+  }
   int write_jint(jint num) {
     write(&num, sizeof(num));
     return 0;
@@ -129,7 +147,8 @@
   enum {
     BOOT      = 1,
     NON_EXIST = 2,
-    REQUIRED  = 3
+    REQUIRED  = 3,
+    PATCH_MOD = 4
   };
 
   virtual const char* type_name(int type) {
@@ -137,6 +156,7 @@
     case BOOT:      return "BOOT";
     case NON_EXIST: return "NON_EXIST";
     case REQUIRED:  return "REQUIRED";
+    case PATCH_MOD: return "PATCH_MOD";
     default:        ShouldNotReachHere(); return "?";
     }
   }
--- a/src/share/vm/classfile/systemDictionary.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/classfile/systemDictionary.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -1210,16 +1210,12 @@
 
 instanceKlassHandle SystemDictionary::load_shared_class(
                  Symbol* class_name, Handle class_loader, TRAPS) {
-  // Don't load shared class when JvmtiExport::should_post_class_file_load_hook()
-  // is enabled since posting CFLH is not supported when loading shared class.
-  if (!JvmtiExport::should_post_class_file_load_hook()) {
-    instanceKlassHandle ik (THREAD, find_shared_class(class_name));
-    // Make sure we only return the boot class for the NULL classloader.
-    if (ik.not_null() &&
-        ik->is_shared_boot_class() && class_loader.is_null()) {
-      Handle protection_domain;
-      return load_shared_class(ik, class_loader, protection_domain, THREAD);
-    }
+  instanceKlassHandle ik (THREAD, find_shared_class(class_name));
+  // Make sure we only return the boot class for the NULL classloader.
+  if (ik.not_null() &&
+      ik->is_shared_boot_class() && class_loader.is_null()) {
+    Handle protection_domain;
+    return load_shared_class(ik, class_loader, protection_domain, THREAD);
   }
   return instanceKlassHandle();
 }
@@ -1303,11 +1299,6 @@
                                                         Handle class_loader,
                                                         Handle protection_domain, TRAPS) {
   instanceKlassHandle nh = instanceKlassHandle(); // null Handle
-  if (JvmtiExport::should_post_class_file_load_hook()) {
-    // Don't load shared class when JvmtiExport::should_post_class_file_load_hook()
-    // is enabled since posting CFLH is not supported when loading shared class.
-    return nh;
-  }
 
   if (ik.not_null()) {
     Symbol* class_name = ik->name();
@@ -1358,6 +1349,14 @@
       }
     }
 
+    instanceKlassHandle new_ik = KlassFactory::check_shared_class_file_load_hook(
+        ik, class_name, class_loader, protection_domain, CHECK_(nh));
+    if (new_ik.not_null()) {
+      // The class is changed by CFLH. Return the new class. The shared class is
+      // not used.
+      return new_ik;
+    }
+
     // Adjust methods to recover missing data.  They need addresses for
     // interpreter entry points and their default native method address
     // must be reset.
--- a/src/share/vm/classfile/verificationType.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/classfile/verificationType.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -95,7 +95,8 @@
       Category2_2nd      = (Category2_2ndFlag << 1 * BitsPerByte) | Primitive,
 
       // Primitive values (type descriminator stored in most-signifcant bytes)
-      Bogus              = (ITEM_Bogus      << 2 * BitsPerByte) | Category1,
+      // Bogus needs the " | Primitive".  Else, is_reference(Bogus) returns TRUE.
+      Bogus              = (ITEM_Bogus      << 2 * BitsPerByte) | Primitive,
       Boolean            = (ITEM_Boolean    << 2 * BitsPerByte) | Category1,
       Byte               = (ITEM_Byte       << 2 * BitsPerByte) | Category1,
       Short              = (ITEM_Short      << 2 * BitsPerByte) | Category1,
--- a/src/share/vm/gc/cms/cmsOopClosures.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/gc/cms/cmsOopClosures.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -258,16 +258,15 @@
 // the closure ParMarkFromRootsClosure.
 class ParPushOrMarkClosure: public MetadataAwareOopClosure {
  private:
-  CMSCollector*    _collector;
-  MemRegion        _whole_span;
-  MemRegion        _span;        // local chunk
-  CMSBitMap*       _bit_map;
-  OopTaskQueue*    _work_queue;
-  CMSMarkStack*    _overflow_stack;
-  HeapWord*  const _finger;
-  HeapWord** const _global_finger_addr;
-  ParMarkFromRootsClosure* const
-                   _parent;
+  CMSCollector*                  _collector;
+  MemRegion                      _whole_span;
+  MemRegion                      _span;       // local chunk
+  CMSBitMap*                     _bit_map;
+  OopTaskQueue*                  _work_queue;
+  CMSMarkStack*                  _overflow_stack;
+  HeapWord*  const               _finger;
+  HeapWord* volatile* const      _global_finger_addr;
+  ParMarkFromRootsClosure* const _parent;
  protected:
   DO_OOP_WORK_DEFN
  public:
@@ -277,7 +276,7 @@
                        OopTaskQueue* work_queue,
                        CMSMarkStack* mark_stack,
                        HeapWord* finger,
-                       HeapWord** global_finger_addr,
+                       HeapWord* volatile* global_finger_addr,
                        ParMarkFromRootsClosure* parent);
   virtual void do_oop(oop* p);
   virtual void do_oop(narrowOop* p);
--- a/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -3025,14 +3025,14 @@
 
 // MT Concurrent Marking Task
 class CMSConcMarkingTask: public YieldingFlexibleGangTask {
-  CMSCollector* _collector;
-  uint          _n_workers;       // requested/desired # workers
-  bool          _result;
-  CompactibleFreeListSpace*  _cms_space;
-  char          _pad_front[64];   // padding to ...
-  HeapWord*     _global_finger;   // ... avoid sharing cache line
-  char          _pad_back[64];
-  HeapWord*     _restart_addr;
+  CMSCollector*             _collector;
+  uint                      _n_workers;      // requested/desired # workers
+  bool                      _result;
+  CompactibleFreeListSpace* _cms_space;
+  char                      _pad_front[64];   // padding to ...
+  HeapWord* volatile        _global_finger;   // ... avoid sharing cache line
+  char                      _pad_back[64];
+  HeapWord*                 _restart_addr;
 
   //  Exposed here for yielding support
   Mutex* const _bit_map_lock;
@@ -3068,7 +3068,7 @@
 
   OopTaskQueue* work_queue(int i) { return task_queues()->queue(i); }
 
-  HeapWord** global_finger_addr() { return &_global_finger; }
+  HeapWord* volatile* global_finger_addr() { return &_global_finger; }
 
   CMSConcMarkingTerminator* terminator() { return &_term; }
 
@@ -6554,7 +6554,7 @@
 
   // Note: the local finger doesn't advance while we drain
   // the stack below, but the global finger sure can and will.
-  HeapWord** gfa = _task->global_finger_addr();
+  HeapWord* volatile* gfa = _task->global_finger_addr();
   ParPushOrMarkClosure pushOrMarkClosure(_collector,
                                          _span, _bit_map,
                                          _work_queue,
@@ -6721,7 +6721,7 @@
                                            OopTaskQueue* work_queue,
                                            CMSMarkStack*  overflow_stack,
                                            HeapWord* finger,
-                                           HeapWord** global_finger_addr,
+                                           HeapWord* volatile* global_finger_addr,
                                            ParMarkFromRootsClosure* parent) :
   MetadataAwareOopClosure(collector->ref_processor()),
   _collector(collector),
--- a/src/share/vm/gc/cms/concurrentMarkSweepGeneration.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/gc/cms/concurrentMarkSweepGeneration.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -724,12 +724,12 @@
   // Support for parallelizing young gen rescan in CMS remark phase
   ParNewGeneration* _young_gen;
 
-  HeapWord** _top_addr;    // ... Top of Eden
-  HeapWord** _end_addr;    // ... End of Eden
-  Mutex*     _eden_chunk_lock;
-  HeapWord** _eden_chunk_array; // ... Eden partitioning array
-  size_t     _eden_chunk_index; // ... top (exclusive) of array
-  size_t     _eden_chunk_capacity;  // ... max entries in array
+  HeapWord* volatile* _top_addr;    // ... Top of Eden
+  HeapWord**          _end_addr;    // ... End of Eden
+  Mutex*              _eden_chunk_lock;
+  HeapWord**          _eden_chunk_array; // ... Eden partitioning array
+  size_t              _eden_chunk_index; // ... top (exclusive) of array
+  size_t              _eden_chunk_capacity;  // ... max entries in array
 
   // Support for parallelizing survivor space rescan
   HeapWord** _survivor_chunk_array;
--- a/src/share/vm/gc/cms/parNewGeneration.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/gc/cms/parNewGeneration.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -1366,22 +1366,25 @@
      return false;
   }
   assert(prefix != NULL && prefix != BUSY, "Error");
-  size_t i = 1;
   oop cur = prefix;
-  while (i < objsFromOverflow && cur->klass_or_null() != NULL) {
-    i++; cur = cur->list_ptr_from_klass();
+  for (size_t i = 1; i < objsFromOverflow; ++i) {
+    oop next = cur->list_ptr_from_klass();
+    if (next == NULL) break;
+    cur = next;
   }
+  assert(cur != NULL, "Loop postcondition");
 
   // Reattach remaining (suffix) to overflow list
-  if (cur->klass_or_null() == NULL) {
+  oop suffix = cur->list_ptr_from_klass();
+  if (suffix == NULL) {
     // Write back the NULL in lieu of the BUSY we wrote
     // above and it is still the same value.
     if (_overflow_list == BUSY) {
       (void) Atomic::cmpxchg_ptr(NULL, &_overflow_list, BUSY);
     }
   } else {
-    assert(cur->klass_or_null() != (Klass*)(address)BUSY, "Error");
-    oop suffix = cur->list_ptr_from_klass();       // suffix will be put back on global list
+    assert(suffix != BUSY, "Error");
+    // suffix will be put back on global list
     cur->set_klass_to_list_ptr(NULL);     // break off suffix
     // It's possible that the list is still in the empty(busy) state
     // we left it in a short while ago; in that case we may be
@@ -1401,8 +1404,10 @@
       // Too bad, someone else got in in between; we'll need to do a splice.
       // Find the last item of suffix list
       oop last = suffix;
-      while (last->klass_or_null() != NULL) {
-        last = last->list_ptr_from_klass();
+      while (true) {
+        oop next = last->list_ptr_from_klass();
+        if (next == NULL) break;
+        last = next;
       }
       // Atomically prepend suffix to current overflow list
       observed_overflow_list = _overflow_list;
--- a/src/share/vm/gc/g1/g1CollectedHeap.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/gc/g1/g1CollectedHeap.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -1479,7 +1479,7 @@
                               "Capacity: " SIZE_FORMAT "B occupancy: " SIZE_FORMAT "B min_desired_capacity: " SIZE_FORMAT "B (" UINTX_FORMAT " %%)",
                               capacity_after_gc, used_after_gc, minimum_desired_capacity, MinHeapFreeRatio);
 
-    expand(expand_bytes);
+    expand(expand_bytes, _workers);
 
     // No expansion, now see if we want to shrink
   } else if (capacity_after_gc > maximum_desired_capacity) {
@@ -1599,7 +1599,7 @@
                             word_size * HeapWordSize);
 
 
-  if (expand(expand_bytes)) {
+  if (expand(expand_bytes, _workers)) {
     _hrm.verify_optional();
     _verifier->verify_region_sets_optional();
     return attempt_allocation_at_safepoint(word_size,
@@ -1609,7 +1609,7 @@
   return NULL;
 }
 
-bool G1CollectedHeap::expand(size_t expand_bytes, double* expand_time_ms) {
+bool G1CollectedHeap::expand(size_t expand_bytes, WorkGang* pretouch_workers, double* expand_time_ms) {
   size_t aligned_expand_bytes = ReservedSpace::page_align_size_up(expand_bytes);
   aligned_expand_bytes = align_size_up(aligned_expand_bytes,
                                        HeapRegion::GrainBytes);
@@ -1626,7 +1626,7 @@
   uint regions_to_expand = (uint)(aligned_expand_bytes / HeapRegion::GrainBytes);
   assert(regions_to_expand > 0, "Must expand by at least one region");
 
-  uint expanded_by = _hrm.expand_by(regions_to_expand);
+  uint expanded_by = _hrm.expand_by(regions_to_expand, pretouch_workers);
   if (expand_time_ms != NULL) {
     *expand_time_ms = (os::elapsedTime() - expand_heap_start_time_sec) * MILLIUNITS;
   }
@@ -1927,7 +1927,7 @@
   _cmThread = _cm->cmThread();
 
   // Now expand into the initial heap size.
-  if (!expand(init_byte_size)) {
+  if (!expand(init_byte_size, _workers)) {
     vm_shutdown_during_initialization("Failed to allocate initial heap.");
     return JNI_ENOMEM;
   }
@@ -2474,8 +2474,16 @@
 }
 
 jlong G1CollectedHeap::millis_since_last_gc() {
-  // assert(false, "NYI");
-  return 0;
+  // See the notes in GenCollectedHeap::millis_since_last_gc()
+  // for more information about the implementation.
+  jlong ret_val = (os::javaTimeNanos() / NANOSECS_PER_MILLISEC) -
+    _g1_policy->collection_pause_end_millis();
+  if (ret_val < 0) {
+    log_warning(gc)("millis_since_last_gc() would return : " JLONG_FORMAT
+      ". returning zero instead.", ret_val);
+    return 0;
+  }
+  return ret_val;
 }
 
 void G1CollectedHeap::prepare_for_verify() {
@@ -3165,7 +3173,6 @@
 
         assert(_verifier->check_cset_fast_test(), "Inconsistency in the InCSetState table.");
 
-        _cm->note_start_of_gc();
         // We call this after finalize_cset() to
         // ensure that the CSet has been finalized.
         _cm->verify_no_cset_oops();
@@ -3241,7 +3248,7 @@
             // No need for an ergo logging here,
             // expansion_amount() does this when it returns a value > 0.
             double expand_ms;
-            if (!expand(expand_bytes, &expand_ms)) {
+            if (!expand(expand_bytes, _workers, &expand_ms)) {
               // We failed to expand the heap. Cannot do anything about it.
             }
             g1_policy()->phase_times()->record_expand_heap_time(expand_ms);
@@ -3251,7 +3258,6 @@
         // We redo the verification but now wrt to the new CSet which
         // has just got initialized after the previous CSet was freed.
         _cm->verify_no_cset_oops();
-        _cm->note_end_of_gc();
 
         // This timing is only used by the ergonomics to handle our pause target.
         // It is unclear why this should not include the full pause. We will
--- a/src/share/vm/gc/g1/g1CollectedHeap.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/gc/g1/g1CollectedHeap.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -557,7 +557,7 @@
   // Returns true if the heap was expanded by the requested amount;
   // false otherwise.
   // (Rounds up to a HeapRegion boundary.)
-  bool expand(size_t expand_bytes, double* expand_time_ms = NULL);
+  bool expand(size_t expand_bytes, WorkGang* pretouch_workers = NULL, double* expand_time_ms = NULL);
 
   // Returns the PLAB statistics for a given destination.
   inline G1EvacStats* alloc_buffer_stats(InCSetState dest);
--- a/src/share/vm/gc/g1/g1CollectionSet.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/gc/g1/g1CollectionSet.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -32,6 +32,7 @@
 #include "gc/g1/heapRegionSet.hpp"
 #include "logging/logStream.hpp"
 #include "utilities/debug.hpp"
+#include "utilities/quickSort.hpp"
 
 G1CollectorState* G1CollectionSet::collector_state() {
   return _g1->collector_state();
@@ -396,6 +397,16 @@
   return time_remaining_ms;
 }
 
+static int compare_region_idx(const uint a, const uint b) {
+  if (a > b) {
+    return 1;
+  } else if (a == b) {
+    return 0;
+  } else {
+    return -1;
+  }
+}
+
 void G1CollectionSet::finalize_old_part(double time_remaining_ms) {
   double non_young_start_time_sec = os::elapsedTime();
   double predicted_old_time_ms = 0.0;
@@ -493,6 +504,8 @@
 
   double non_young_end_time_sec = os::elapsedTime();
   phase_times()->record_non_young_cset_choice_time_ms((non_young_end_time_sec - non_young_start_time_sec) * 1000.0);
+
+  QuickSort::sort<uint>(_collection_set_regions, (int)_collection_set_cur_length, compare_region_idx, true);
 }
 
 #ifdef ASSERT
--- a/src/share/vm/gc/g1/g1ConcurrentMark.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/gc/g1/g1ConcurrentMark.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -133,129 +133,184 @@
 }
 
 G1CMMarkStack::G1CMMarkStack() :
-  _reserved_space(),
+  _max_chunk_capacity(0),
   _base(NULL),
-  _capacity(0),
-  _saved_index((size_t)AllBits),
+  _chunk_capacity(0),
+  _out_of_memory(false),
   _should_expand(false) {
   set_empty();
 }
 
 bool G1CMMarkStack::resize(size_t new_capacity) {
   assert(is_empty(), "Only resize when stack is empty.");
-  assert(new_capacity <= MarkStackSizeMax,
-         "Trying to resize stack to " SIZE_FORMAT " elements when the maximum is " SIZE_FORMAT, new_capacity, MarkStackSizeMax);
-
-  size_t reservation_size = ReservedSpace::allocation_align_size_up(new_capacity * sizeof(oop));
-
-  ReservedSpace rs(reservation_size);
-  if (!rs.is_reserved()) {
-    log_warning(gc)("Failed to reserve memory for new overflow mark stack with " SIZE_FORMAT " elements and size " SIZE_FORMAT "B.", new_capacity, reservation_size);
+  assert(new_capacity <= _max_chunk_capacity,
+         "Trying to resize stack to " SIZE_FORMAT " chunks when the maximum is " SIZE_FORMAT, new_capacity, _max_chunk_capacity);
+
+  OopChunk* new_base = MmapArrayAllocator<OopChunk, mtGC>::allocate_or_null(new_capacity);
+
+  if (new_base == NULL) {
+    log_warning(gc)("Failed to reserve memory for new overflow mark stack with " SIZE_FORMAT " chunks and size " SIZE_FORMAT "B.", new_capacity, new_capacity * sizeof(OopChunk));
     return false;
   }
-
-  VirtualSpace vs;
-
-  if (!vs.initialize(rs, rs.size())) {
-    rs.release();
-    log_warning(gc)("Failed to commit memory for new overflow mark stack of size " SIZE_FORMAT "B.", rs.size());
-    return false;
+  // Release old mapping.
+  if (_base != NULL) {
+    MmapArrayAllocator<OopChunk, mtGC>::free(_base, _chunk_capacity);
   }
 
-  assert(vs.committed_size() == rs.size(), "Failed to commit all of the mark stack.");
-
-  // Release old mapping.
-  _reserved_space.release();
-
-  // Save new mapping for future unmapping.
-  _reserved_space = rs;
-
-  MemTracker::record_virtual_memory_type((address)_reserved_space.base(), mtGC);
-
-  _base = (oop*) vs.low();
-  _capacity = new_capacity;
+  _base = new_base;
+  _chunk_capacity = new_capacity;
   set_empty();
   _should_expand = false;
 
   return true;
 }
 
-bool G1CMMarkStack::allocate(size_t capacity) {
-  return resize(capacity);
+size_t G1CMMarkStack::capacity_alignment() {
+  return (size_t)lcm(os::vm_allocation_granularity(), sizeof(OopChunk)) / sizeof(void*);
+}
+
+bool G1CMMarkStack::initialize(size_t initial_capacity, size_t max_capacity) {
+  guarantee(_max_chunk_capacity == 0, "G1CMMarkStack already initialized.");
+
+  size_t const OopChunkSizeInVoidStar = sizeof(OopChunk) / sizeof(void*);
+
+  _max_chunk_capacity = (size_t)align_size_up(max_capacity, capacity_alignment()) / OopChunkSizeInVoidStar;
+  size_t initial_chunk_capacity = (size_t)align_size_up(initial_capacity, capacity_alignment()) / OopChunkSizeInVoidStar;
+
+  guarantee(initial_chunk_capacity <= _max_chunk_capacity,
+            "Maximum chunk capacity " SIZE_FORMAT " smaller than initial capacity " SIZE_FORMAT,
+            _max_chunk_capacity,
+            initial_chunk_capacity);
+
+  log_debug(gc)("Initialize mark stack with " SIZE_FORMAT " chunks, maximum " SIZE_FORMAT,
+                initial_chunk_capacity, _max_chunk_capacity);
+
+  return resize(initial_chunk_capacity);
 }
 
 void G1CMMarkStack::expand() {
   // Clear expansion flag
   _should_expand = false;
 
-  if (_capacity == MarkStackSizeMax) {
-    log_debug(gc)("Can not expand overflow mark stack further, already at maximum capacity of " SIZE_FORMAT " elements.", _capacity);
+  if (_chunk_capacity == _max_chunk_capacity) {
+    log_debug(gc)("Can not expand overflow mark stack further, already at maximum capacity of " SIZE_FORMAT " chunks.", _chunk_capacity);
     return;
   }
-  size_t old_capacity = _capacity;
+  size_t old_capacity = _chunk_capacity;
   // Double capacity if possible
-  size_t new_capacity = MIN2(old_capacity * 2, MarkStackSizeMax);
+  size_t new_capacity = MIN2(old_capacity * 2, _max_chunk_capacity);
 
   if (resize(new_capacity)) {
-    log_debug(gc)("Expanded marking stack capacity from " SIZE_FORMAT " to " SIZE_FORMAT " elements",
+    log_debug(gc)("Expanded mark stack capacity from " SIZE_FORMAT " to " SIZE_FORMAT " chunks",
                   old_capacity, new_capacity);
   } else {
-    log_warning(gc)("Failed to expand marking stack capacity from " SIZE_FORMAT " to " SIZE_FORMAT " elements",
+    log_warning(gc)("Failed to expand mark stack capacity from " SIZE_FORMAT " to " SIZE_FORMAT " chunks",
                     old_capacity, new_capacity);
   }
 }
 
 G1CMMarkStack::~G1CMMarkStack() {
   if (_base != NULL) {
-    _base = NULL;
-    _reserved_space.release();
+    MmapArrayAllocator<OopChunk, mtGC>::free(_base, _chunk_capacity);
   }
 }
 
-void G1CMMarkStack::par_push_arr(oop* buffer, size_t n) {
-  MutexLockerEx x(ParGCRareEvent_lock, Mutex::_no_safepoint_check_flag);
-  size_t start = _index;
-  size_t next_index = start + n;
-  if (next_index > _capacity) {
-    _overflow = true;
-    return;
+void G1CMMarkStack::add_chunk_to_list(OopChunk* volatile* list, OopChunk* elem) {
+  elem->next = *list;
+  *list = elem;
+}
+
+void G1CMMarkStack::add_chunk_to_chunk_list(OopChunk* elem) {
+  MutexLockerEx x(MarkStackChunkList_lock, Mutex::_no_safepoint_check_flag);
+  add_chunk_to_list(&_chunk_list, elem);
+  _chunks_in_chunk_list++;
+}
+
+void G1CMMarkStack::add_chunk_to_free_list(OopChunk* elem) {
+  MutexLockerEx x(MarkStackFreeList_lock, Mutex::_no_safepoint_check_flag);
+  add_chunk_to_list(&_free_list, elem);
+}
+
+G1CMMarkStack::OopChunk* G1CMMarkStack::remove_chunk_from_list(OopChunk* volatile* list) {
+  OopChunk* result = *list;
+  if (result != NULL) {
+    *list = (*list)->next;
   }
-  // Otherwise.
-  _index = next_index;
-  for (size_t i = 0; i < n; i++) {
-    size_t ind = start + i;
-    assert(ind < _capacity, "By overflow test above.");
-    _base[ind] = buffer[i];
+  return result;
+}
+
+G1CMMarkStack::OopChunk* G1CMMarkStack::remove_chunk_from_chunk_list() {
+  MutexLockerEx x(MarkStackChunkList_lock, Mutex::_no_safepoint_check_flag);
+  OopChunk* result = remove_chunk_from_list(&_chunk_list);
+  if (result != NULL) {
+    _chunks_in_chunk_list--;
   }
+  return result;
 }
 
-bool G1CMMarkStack::par_pop_arr(oop* buffer, size_t max, size_t* n) {
-  MutexLockerEx x(ParGCRareEvent_lock, Mutex::_no_safepoint_check_flag);
-  size_t index = _index;
-  if (index == 0) {
-    *n = 0;
+G1CMMarkStack::OopChunk* G1CMMarkStack::remove_chunk_from_free_list() {
+  MutexLockerEx x(MarkStackFreeList_lock, Mutex::_no_safepoint_check_flag);
+  return remove_chunk_from_list(&_free_list);
+}
+
+G1CMMarkStack::OopChunk* G1CMMarkStack::allocate_new_chunk() {
+  // This dirty read of _hwm is okay because we only ever increase the _hwm in parallel code.
+  // Further this limits _hwm to a value of _chunk_capacity + #threads, avoiding
+  // wraparound of _hwm.
+  if (_hwm >= _chunk_capacity) {
+    return NULL;
+  }
+
+  size_t cur_idx = Atomic::add(1, &_hwm) - 1;
+  if (cur_idx >= _chunk_capacity) {
+    return NULL;
+  }
+
+  OopChunk* result = ::new (&_base[cur_idx]) OopChunk;
+  result->next = NULL;
+  return result;
+}
+
+bool G1CMMarkStack::par_push_chunk(oop* ptr_arr) {
+  // Get a new chunk.
+  OopChunk* new_chunk = remove_chunk_from_free_list();
+
+  if (new_chunk == NULL) {
+    // Did not get a chunk from the free list. Allocate from backing memory.
+    new_chunk = allocate_new_chunk();
+  }
+
+  if (new_chunk == NULL) {
+    _out_of_memory = true;
     return false;
-  } else {
-    size_t k = MIN2(max, index);
-    size_t new_ind = index - k;
-    for (size_t j = 0; j < k; j++) {
-      buffer[j] = _base[new_ind + j];
-    }
-    _index = new_ind;
-    *n = k;
-    return true;
   }
+
+  Copy::conjoint_memory_atomic(ptr_arr, new_chunk->data, OopsPerChunk * sizeof(oop));
+
+  add_chunk_to_chunk_list(new_chunk);
+
+  return true;
 }
 
-void G1CMMarkStack::note_start_of_gc() {
-  assert(_saved_index == (size_t)AllBits, "note_start_of_gc()/end_of_gc() calls bracketed incorrectly");
-  _saved_index = _index;
+bool G1CMMarkStack::par_pop_chunk(oop* ptr_arr) {
+  OopChunk* cur = remove_chunk_from_chunk_list();
+
+  if (cur == NULL) {
+    return false;
+  }
+
+  Copy::conjoint_memory_atomic(cur->data, ptr_arr, OopsPerChunk * sizeof(oop));
+
+  add_chunk_to_free_list(cur);
+  return true;
 }
 
-void G1CMMarkStack::note_end_of_gc() {
-  guarantee(!stack_modified(), "Saved index " SIZE_FORMAT " must be the same as " SIZE_FORMAT, _saved_index, _index);
-
-  _saved_index = (size_t)AllBits;
+void G1CMMarkStack::set_empty() {
+  _chunks_in_chunk_list = 0;
+  _hwm = 0;
+  clear_out_of_memory();
+  _chunk_list = NULL;
+  _free_list = NULL;
 }
 
 G1CMRootRegions::G1CMRootRegions() :
@@ -483,9 +538,8 @@
     }
   }
 
-  if (!_global_mark_stack.allocate(MarkStackSize)) {
+  if (!_global_mark_stack.initialize(MarkStackSize, MarkStackSizeMax)) {
     vm_exit_during_initialization("Failed to allocate initial concurrent mark overflow mark stack.");
-    return;
   }
 
   _tasks = NEW_C_HEAP_ARRAY(G1CMTask*, _max_worker_id, mtGC);
@@ -1695,10 +1749,10 @@
     // oop closures will set the has_overflown flag if we overflow the
     // global marking stack.
 
-    assert(_global_mark_stack.overflow() || _global_mark_stack.is_empty(),
-            "mark stack should be empty (unless it overflowed)");
-
-    if (_global_mark_stack.overflow()) {
+    assert(_global_mark_stack.is_out_of_memory() || _global_mark_stack.is_empty(),
+            "Mark stack should be empty (unless it is out of memory)");
+
+    if (_global_mark_stack.is_out_of_memory()) {
       // This should have been done already when we tried to push an
       // entry on to the global mark stack. But let's do it again.
       set_has_overflown();
@@ -1904,7 +1958,8 @@
     assert(_g1h->is_in_g1_reserved(finger), "invariant");
 
     HeapRegion* curr_region = _g1h->heap_region_containing(finger);
-
+    // Make sure that the reads below do not float before loading curr_region.
+    OrderAccess::loadload();
     // Above heap_region_containing may return NULL as we always scan claim
     // until the end of the heap. In this case, just jump to the next region.
     HeapWord* end = curr_region != NULL ? curr_region->end() : finger + HeapRegion::GrainWords;
@@ -2342,49 +2397,54 @@
 }
 
 void G1CMTask::move_entries_to_global_stack() {
-  // local array where we'll store the entries that will be popped
-  // from the local queue
-  oop buffer[global_stack_transfer_size];
-
-  int n = 0;
+  // Local array where we'll store the entries that will be popped
+  // from the local queue.
+  oop buffer[G1CMMarkStack::OopsPerChunk];
+
+  size_t n = 0;
   oop obj;
-  while (n < global_stack_transfer_size && _task_queue->pop_local(obj)) {
+  while (n < G1CMMarkStack::OopsPerChunk && _task_queue->pop_local(obj)) {
     buffer[n] = obj;
     ++n;
   }
+  if (n < G1CMMarkStack::OopsPerChunk) {
+    buffer[n] = NULL;
+  }
 
   if (n > 0) {
-    // we popped at least one entry from the local queue
-
-    if (!_cm->mark_stack_push(buffer, n)) {
+    if (!_cm->mark_stack_push(buffer)) {
       set_has_aborted();
     }
   }
 
-  // this operation was quite expensive, so decrease the limits
+  // This operation was quite expensive, so decrease the limits.
   decrease_limits();
 }
 
-void G1CMTask::get_entries_from_global_stack() {
-  // local array where we'll store the entries that will be popped
+bool G1CMTask::get_entries_from_global_stack() {
+  // Local array where we'll store the entries that will be popped
   // from the global stack.
-  oop buffer[global_stack_transfer_size];
-  size_t n;
-  _cm->mark_stack_pop(buffer, global_stack_transfer_size, &n);
-  assert(n <= global_stack_transfer_size,
-         "we should not pop more than the given limit");
-  if (n > 0) {
-    // yes, we did actually pop at least one entry
-    for (size_t i = 0; i < n; ++i) {
-      bool success = _task_queue->push(buffer[i]);
-      // We only call this when the local queue is empty or under a
-      // given target limit. So, we do not expect this push to fail.
-      assert(success, "invariant");
+  oop buffer[G1CMMarkStack::OopsPerChunk];
+
+  if (!_cm->mark_stack_pop(buffer)) {
+    return false;
+  }
+
+  // We did actually pop at least one entry.
+  for (size_t i = 0; i < G1CMMarkStack::OopsPerChunk; ++i) {
+    oop elem = buffer[i];
+    if (elem == NULL) {
+      break;
     }
+    bool success = _task_queue->push(elem);
+    // We only call this when the local queue is empty or under a
+    // given target limit. So, we do not expect this push to fail.
+    assert(success, "invariant");
   }
 
-  // this operation was quite expensive, so decrease the limits
+  // This operation was quite expensive, so decrease the limits
   decrease_limits();
+  return true;
 }
 
 void G1CMTask::drain_local_queue(bool partially) {
@@ -2428,20 +2488,21 @@
 
   // Decide what the target size is, depending whether we're going to
   // drain it partially (so that other tasks can steal if they run out
-  // of things to do) or totally (at the very end).  Notice that,
-  // because we move entries from the global stack in chunks or
-  // because another task might be doing the same, we might in fact
-  // drop below the target. But, this is not a problem.
-  size_t target_size;
+  // of things to do) or totally (at the very end).
+  // Notice that when draining the global mark stack partially, due to the racyness
+  // of the mark stack size update we might in fact drop below the target. But,
+  // this is not a problem.
+  // In case of total draining, we simply process until the global mark stack is
+  // totally empty, disregarding the size counter.
   if (partially) {
-    target_size = _cm->partial_mark_stack_size_target();
+    size_t const target_size = _cm->partial_mark_stack_size_target();
+    while (!has_aborted() && _cm->mark_stack_size() > target_size) {
+      if (get_entries_from_global_stack()) {
+        drain_local_queue(partially);
+      }
+    }
   } else {
-    target_size = 0;
-  }
-
-  if (_cm->mark_stack_size() > target_size) {
-    while (!has_aborted() && _cm->mark_stack_size() > target_size) {
-      get_entries_from_global_stack();
+    while (!has_aborted() && get_entries_from_global_stack()) {
       drain_local_queue(partially);
     }
   }
--- a/src/share/vm/gc/g1/g1ConcurrentMark.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/gc/g1/g1ConcurrentMark.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -149,42 +149,98 @@
 //
 // Stores oops in a huge buffer in virtual memory that is always fully committed.
 // Resizing may only happen during a STW pause when the stack is empty.
+//
+// Memory is allocated on a "chunk" basis, i.e. a set of oops. For this, the mark
+// stack memory is split into evenly sized chunks of oops. Users can only
+// add or remove entries on that basis.
+// Chunks are filled in increasing address order. Not completely filled chunks
+// have a NULL element as a terminating element.
+//
+// Every chunk has a header containing a single pointer element used for memory
+// management. This wastes some space, but is negligible (< .1% with current sizing).
+//
+// Memory management is done using a mix of tracking a high water-mark indicating
+// that all chunks at a lower address are valid chunks, and a singly linked free
+// list connecting all empty chunks.
 class G1CMMarkStack VALUE_OBJ_CLASS_SPEC {
-  ReservedSpace _reserved_space; // Space currently reserved for the mark stack.
+public:
+  // Number of oops that can fit in a single chunk.
+  static const size_t OopsPerChunk = 1024 - 1 /* One reference for the next pointer */;
+private:
+  struct OopChunk {
+    OopChunk* next;
+    oop data[OopsPerChunk];
+  };
 
-  oop* _base;                    // Bottom address of allocated memory area.
-  size_t _capacity;              // Maximum number of elements.
-  size_t _index;                 // One more than last occupied index.
+  size_t _max_chunk_capacity;    // Maximum number of OopChunk elements on the stack.
 
-  size_t _saved_index;           // Value of _index saved at start of GC to detect mark stack modifications during that time.
+  OopChunk* _base;               // Bottom address of allocated memory area.
+  size_t _chunk_capacity;        // Current maximum number of OopChunk elements.
 
-  bool  _overflow;
+  char _pad0[DEFAULT_CACHE_LINE_SIZE];
+  OopChunk* volatile _free_list;  // Linked list of free chunks that can be allocated by users.
+  char _pad1[DEFAULT_CACHE_LINE_SIZE - sizeof(OopChunk*)];
+  OopChunk* volatile _chunk_list; // List of chunks currently containing data.
+  volatile size_t _chunks_in_chunk_list;
+  char _pad2[DEFAULT_CACHE_LINE_SIZE - sizeof(OopChunk*) - sizeof(size_t)];
+
+  volatile size_t _hwm;          // High water mark within the reserved space.
+  char _pad4[DEFAULT_CACHE_LINE_SIZE - sizeof(size_t)];
+
+  // Allocate a new chunk from the reserved memory, using the high water mark. Returns
+  // NULL if out of memory.
+  OopChunk* allocate_new_chunk();
+
+  volatile bool _out_of_memory;
+
+  // Atomically add the given chunk to the list.
+  void add_chunk_to_list(OopChunk* volatile* list, OopChunk* elem);
+  // Atomically remove and return a chunk from the given list. Returns NULL if the
+  // list is empty.
+  OopChunk* remove_chunk_from_list(OopChunk* volatile* list);
+
+  void add_chunk_to_chunk_list(OopChunk* elem);
+  void add_chunk_to_free_list(OopChunk* elem);
+
+  OopChunk* remove_chunk_from_chunk_list();
+  OopChunk* remove_chunk_from_free_list();
+
   bool  _should_expand;
 
   // Resizes the mark stack to the given new capacity. Releases any previous
   // memory if successful.
   bool resize(size_t new_capacity);
 
-  bool stack_modified() const { return _index != _saved_index; }
  public:
   G1CMMarkStack();
   ~G1CMMarkStack();
 
-  bool allocate(size_t capacity);
+  // Alignment and minimum capacity of this mark stack in number of oops.
+  static size_t capacity_alignment();
 
-  // Pushes the first "n" elements of the given buffer on the stack.
-  void par_push_arr(oop* buffer, size_t n);
+  // Allocate and initialize the mark stack with the given number of oops.
+  bool initialize(size_t initial_capacity, size_t max_capacity);
 
-  // Moves up to max elements from the stack into the given buffer. Returns
-  // the number of elements pushed, and false if the array has been empty.
-  // Returns true if the buffer contains at least one element.
-  bool par_pop_arr(oop* buffer, size_t max, size_t* n);
+  // Pushes the given buffer containing at most OopsPerChunk elements on the mark
+  // stack. If less than OopsPerChunk elements are to be pushed, the array must
+  // be terminated with a NULL.
+  // Returns whether the buffer contents were successfully pushed to the global mark
+  // stack.
+  bool par_push_chunk(oop* buffer);
 
-  bool is_empty() const { return _index == 0; }
-  size_t capacity() const  { return _capacity; }
+  // Pops a chunk from this mark stack, copying them into the given buffer. This
+  // chunk may contain up to OopsPerChunk elements. If there are less, the last
+  // element in the array is a NULL pointer.
+  bool par_pop_chunk(oop* buffer);
 
-  bool overflow() const { return _overflow; }
-  void clear_overflow() { _overflow = false; }
+  // Return whether the chunk list is empty. Racy due to unsynchronized access to
+  // _chunk_list.
+  bool is_empty() const { return _chunk_list == NULL; }
+
+  size_t capacity() const  { return _chunk_capacity; }
+
+  bool is_out_of_memory() const { return _out_of_memory; }
+  void clear_out_of_memory() { _out_of_memory = false; }
 
   bool should_expand() const { return _should_expand; }
   void set_should_expand(bool value) { _should_expand = value; }
@@ -192,20 +248,15 @@
   // Expand the stack, typically in response to an overflow condition
   void expand();
 
-  size_t size() const { return _index; }
+  // Return the approximate number of oops on this mark stack. Racy due to
+  // unsynchronized access to _chunks_in_chunk_list.
+  size_t size() const { return _chunks_in_chunk_list * OopsPerChunk; }
 
-  void set_empty() { _index = 0; clear_overflow(); }
+  void set_empty();
 
-  // Record the current index.
-  void note_start_of_gc();
-
-  // Make sure that we have not added any entries to the stack during GC.
-  void note_end_of_gc();
-
-  // Apply fn to each oop in the mark stack, up to the bound recorded
-  // via one of the above "note" functions.  The mark stack must not
+  // Apply Fn to every oop on the mark stack. The mark stack must not
   // be modified while iterating.
-  template<typename Fn> void iterate(Fn fn);
+  template<typename Fn> void iterate(Fn fn) const PRODUCT_RETURN;
 };
 
 // Root Regions are regions that are not empty at the beginning of a
@@ -278,7 +329,6 @@
   friend class G1CMDrainMarkingStackClosure;
   friend class G1CMBitMapClosure;
   friend class G1CMConcurrentMarkingTask;
-  friend class G1CMMarkStack;
   friend class G1CMRemarkTask;
   friend class G1CMTask;
 
@@ -479,22 +529,20 @@
 public:
   // Manipulation of the global mark stack.
   // The push and pop operations are used by tasks for transfers
-  // between task-local queues and the global mark stack, and use
-  // locking for concurrency safety.
-  bool mark_stack_push(oop* arr, size_t n) {
-    _global_mark_stack.par_push_arr(arr, n);
-    if (_global_mark_stack.overflow()) {
+  // between task-local queues and the global mark stack.
+  bool mark_stack_push(oop* arr) {
+    if (!_global_mark_stack.par_push_chunk(arr)) {
       set_has_overflown();
       return false;
     }
     return true;
   }
-  void mark_stack_pop(oop* arr, size_t max, size_t* n) {
-    _global_mark_stack.par_pop_arr(arr, max, n);
+  bool mark_stack_pop(oop* arr) {
+    return _global_mark_stack.par_pop_chunk(arr);
   }
   size_t mark_stack_size()                { return _global_mark_stack.size(); }
   size_t partial_mark_stack_size_target() { return _global_mark_stack.capacity()/3; }
-  bool mark_stack_overflow()              { return _global_mark_stack.overflow(); }
+  bool mark_stack_overflow()              { return _global_mark_stack.is_out_of_memory(); }
   bool mark_stack_empty()                 { return _global_mark_stack.is_empty(); }
 
   G1CMRootRegions* root_regions() { return &_root_regions; }
@@ -599,16 +647,6 @@
   // read-only, so use this carefully!
   void clearRangePrevBitmap(MemRegion mr);
 
-  // Notify data structures that a GC has started.
-  void note_start_of_gc() {
-    _global_mark_stack.note_start_of_gc();
-  }
-
-  // Notify data structures that a GC is finished.
-  void note_end_of_gc() {
-    _global_mark_stack.note_end_of_gc();
-  }
-
   // Verify that there are no CSet oops on the stacks (taskqueues /
   // global mark stack) and fingers (global / per-task).
   // If marking is not in progress, it's a no-op.
@@ -670,10 +708,7 @@
     // references reaches this limit
     refs_reached_period           = 384,
     // Initial value for the hash seed, used in the work stealing code
-    init_hash_seed                = 17,
-    // How many entries will be transferred between global stack and
-    // local queues at once.
-    global_stack_transfer_size    = 1024
+    init_hash_seed                = 17
   };
 
   uint                        _worker_id;
@@ -858,9 +893,10 @@
   // It pushes an object on the local queue.
   inline void push(oop obj);
 
-  // These two move entries to/from the global stack.
+  // Move entries to the global stack.
   void move_entries_to_global_stack();
-  void get_entries_from_global_stack();
+  // Move entries from the global stack, return true if we were successful to do so.
+  bool get_entries_from_global_stack();
 
   // It pops and scans objects from the local queue. If partially is
   // true, then it stops when the queue size is of a given limit. If
--- a/src/share/vm/gc/g1/g1ConcurrentMark.inline.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/gc/g1/g1ConcurrentMark.inline.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -89,14 +89,28 @@
 
 #undef check_mark
 
+#ifndef PRODUCT
 template<typename Fn>
-inline void G1CMMarkStack::iterate(Fn fn) {
+inline void G1CMMarkStack::iterate(Fn fn) const {
   assert_at_safepoint(true);
-  assert(!stack_modified(), "Saved index " SIZE_FORMAT " must be the same as " SIZE_FORMAT, _saved_index, _index);
-  for (size_t i = 0; i < _index; ++i) {
-    fn(_base[i]);
+
+  size_t num_chunks = 0;
+
+  OopChunk* cur = _chunk_list;
+  while (cur != NULL) {
+    guarantee(num_chunks <= _chunks_in_chunk_list, "Found " SIZE_FORMAT " oop chunks which is more than there should be", num_chunks);
+
+    for (size_t i = 0; i < OopsPerChunk; ++i) {
+      if (cur->data[i] == NULL) {
+        break;
+      }
+      fn(cur->data[i]);
+    }
+    cur = cur->next;
+    num_chunks++;
   }
 }
+#endif
 
 // It scans an object and visits its children.
 inline void G1CMTask::scan_object(oop obj) { process_grey_object<true>(obj); }
--- a/src/share/vm/gc/g1/g1DefaultPolicy.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/gc/g1/g1DefaultPolicy.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -66,7 +66,8 @@
   _phase_times(new G1GCPhaseTimes(ParallelGCThreads)),
   _tenuring_threshold(MaxTenuringThreshold),
   _max_survivor_regions(0),
-  _survivors_age_table(true) { }
+  _survivors_age_table(true),
+  _collection_pause_end_millis(os::javaTimeNanos() / NANOSECS_PER_MILLISEC) { }
 
 G1DefaultPolicy::~G1DefaultPolicy() {
   delete _ihop_control;
@@ -575,6 +576,8 @@
 
   record_pause(young_gc_pause_kind(), end_time_sec - pause_time_ms / 1000.0, end_time_sec);
 
+  _collection_pause_end_millis = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
+
   last_pause_included_initial_mark = collector_state()->during_initial_mark_pause();
   if (last_pause_included_initial_mark) {
     record_concurrent_mark_init_end(0.0);
--- a/src/share/vm/gc/g1/g1DefaultPolicy.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/gc/g1/g1DefaultPolicy.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -64,6 +64,8 @@
 
   double _full_collection_start_sec;
 
+  jlong _collection_pause_end_millis;
+
   uint _young_list_target_length;
   uint _young_list_fixed_length;
 
@@ -237,6 +239,8 @@
 
   double reclaimable_bytes_perc(size_t reclaimable_bytes) const;
 
+  jlong collection_pause_end_millis() { return _collection_pause_end_millis; }
+
 private:
   // Sets up marking if proper conditions are met.
   void maybe_start_marking();
--- a/src/share/vm/gc/g1/g1MarkSweep.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/gc/g1/g1MarkSweep.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -132,9 +132,16 @@
   MarkingCodeBlobClosure follow_code_closure(&GenMarkSweep::follow_root_closure, !CodeBlobToOopClosure::FixRelocations);
   {
     G1RootProcessor root_processor(g1h, 1);
-    root_processor.process_strong_roots(&GenMarkSweep::follow_root_closure,
-                                        &GenMarkSweep::follow_cld_closure,
-                                        &follow_code_closure);
+    if (ClassUnloading) {
+      root_processor.process_strong_roots(&GenMarkSweep::follow_root_closure,
+                                          &GenMarkSweep::follow_cld_closure,
+                                          &follow_code_closure);
+    } else {
+      root_processor.process_all_roots_no_string_table(
+                                          &GenMarkSweep::follow_root_closure,
+                                          &GenMarkSweep::follow_cld_closure,
+                                          &follow_code_closure);
+    }
   }
 
   {
@@ -157,7 +164,7 @@
   // This is the point where the entire marking should have completed.
   assert(GenMarkSweep::_marking_stack.is_empty(), "Marking should have completed");
 
-  {
+  if (ClassUnloading) {
     GCTraceTime(Debug, gc, phases) trace("Class Unloading", gc_timer());
 
     // Unload classes and purge the SystemDictionary.
--- a/src/share/vm/gc/g1/g1OopClosures.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/gc/g1/g1OopClosures.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -34,7 +34,6 @@
 class G1ConcurrentMark;
 class DirtyCardToOopClosure;
 class G1CMBitMap;
-class G1CMMarkStack;
 class G1ParScanThreadState;
 class G1CMTask;
 class ReferenceProcessor;
--- a/src/share/vm/gc/g1/g1PageBasedVirtualSpace.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/gc/g1/g1PageBasedVirtualSpace.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -24,8 +24,10 @@
 
 #include "precompiled.hpp"
 #include "gc/g1/g1PageBasedVirtualSpace.hpp"
+#include "gc/shared/workgroup.hpp"
 #include "oops/markOop.hpp"
 #include "oops/oop.inline.hpp"
+#include "runtime/atomic.hpp"
 #include "runtime/os.inline.hpp"
 #include "services/memTracker.hpp"
 #include "utilities/bitMap.inline.hpp"
@@ -177,7 +179,7 @@
   guarantee(start_page < end_page,
             "Given start page " SIZE_FORMAT " is larger or equal to end page " SIZE_FORMAT, start_page, end_page);
 
-  os::pretouch_memory(page_start(start_page), bounded_end_addr(end_page));
+  os::pretouch_memory(page_start(start_page), bounded_end_addr(end_page), _page_size);
 }
 
 bool G1PageBasedVirtualSpace::commit(size_t start_page, size_t size_in_pages) {
@@ -198,9 +200,6 @@
   }
   _committed.set_range(start_page, end_page);
 
-  if (AlwaysPreTouch) {
-    pretouch_internal(start_page, end_page);
-  }
   return zero_filled;
 }
 
@@ -227,6 +226,53 @@
   _committed.clear_range(start_page, end_page);
 }
 
+class G1PretouchTask : public AbstractGangTask {
+private:
+  char* volatile _cur_addr;
+  char* const _start_addr;
+  char* const _end_addr;
+  size_t const _page_size;
+public:
+  G1PretouchTask(char* start_address, char* end_address, size_t page_size) :
+    AbstractGangTask("G1 PreTouch",
+                     Universe::is_fully_initialized() ? GCId::current_raw() :
+                                                        // During VM initialization there is
+                                                        // no GC cycle that this task can be
+                                                        // associated with.
+                                                        GCId::undefined()),
+    _cur_addr(start_address),
+    _start_addr(start_address),
+    _end_addr(end_address),
+    _page_size(page_size) {
+  }
+
+  virtual void work(uint worker_id) {
+    size_t const actual_chunk_size = MAX2(chunk_size(), _page_size);
+    while (true) {
+      char* touch_addr = (char*)Atomic::add_ptr((intptr_t)actual_chunk_size, (volatile void*) &_cur_addr) - actual_chunk_size;
+      if (touch_addr < _start_addr || touch_addr >= _end_addr) {
+        break;
+      }
+      char* end_addr = touch_addr + MIN2(actual_chunk_size, pointer_delta(_end_addr, touch_addr, sizeof(char)));
+      os::pretouch_memory(touch_addr, end_addr, _page_size);
+    }
+  }
+
+  static size_t chunk_size() { return PreTouchParallelChunkSize; }
+};
+
+void G1PageBasedVirtualSpace::pretouch(size_t start_page, size_t size_in_pages, WorkGang* pretouch_gang) {
+  guarantee(pretouch_gang != NULL, "No pretouch gang specified.");
+
+  size_t num_chunks = MAX2((size_t)1, size_in_pages * _page_size / MAX2(G1PretouchTask::chunk_size(), _page_size));
+
+  uint num_workers = MIN2((uint)num_chunks, pretouch_gang->active_workers());
+  G1PretouchTask cl(page_start(start_page), bounded_end_addr(start_page + size_in_pages), _page_size);
+  log_debug(gc, heap)("Running %s with %u workers for " SIZE_FORMAT " work units pre-touching " SIZE_FORMAT "B.",
+                      cl.name(), num_workers, num_chunks, size_in_pages * _page_size);
+  pretouch_gang->run_task(&cl, num_workers);
+}
+
 bool G1PageBasedVirtualSpace::contains(const void* p) const {
   return _low_boundary <= (const char*) p && (const char*) p < _high_boundary;
 }
--- a/src/share/vm/gc/g1/g1PageBasedVirtualSpace.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/gc/g1/g1PageBasedVirtualSpace.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -30,6 +30,8 @@
 #include "memory/virtualspace.hpp"
 #include "utilities/bitMap.hpp"
 
+class WorkGang;
+
 // Virtual space management helper for a virtual space with an OS page allocation
 // granularity.
 // (De-)Allocation requests are always OS page aligned by passing a page index
@@ -117,6 +119,8 @@
   // Uncommit the given area of pages starting at start being size_in_pages large.
   void uncommit(size_t start_page, size_t size_in_pages);
 
+  void pretouch(size_t start_page, size_t size_in_pages, WorkGang* pretouch_gang = NULL);
+
   // Initialize the given reserved space with the given base address and the size
   // actually used.
   // Prefer to commit in page_size chunks.
--- a/src/share/vm/gc/g1/g1Policy.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/gc/g1/g1Policy.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -119,6 +119,8 @@
   virtual void record_full_collection_start() = 0;
   virtual void record_full_collection_end() = 0;
 
+  virtual jlong collection_pause_end_millis() = 0;
+
   // Must currently be called while the world is stopped.
   virtual void record_concurrent_mark_init_end(double mark_init_elapsed_time_ms) = 0;
 
--- a/src/share/vm/gc/g1/g1RegionToSpaceMapper.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/gc/g1/g1RegionToSpaceMapper.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -66,8 +66,12 @@
     guarantee(alloc_granularity >= page_size, "allocation granularity smaller than commit granularity");
   }
 
-  virtual void commit_regions(uint start_idx, size_t num_regions) {
-    bool zero_filled = _storage.commit((size_t)start_idx * _pages_per_region, num_regions * _pages_per_region);
+  virtual void commit_regions(uint start_idx, size_t num_regions, WorkGang* pretouch_gang) {
+    size_t const start_page = (size_t)start_idx * _pages_per_region;
+    bool zero_filled = _storage.commit(start_page, num_regions * _pages_per_region);
+    if (AlwaysPreTouch) {
+      _storage.pretouch(start_page, num_regions * _pages_per_region, pretouch_gang);
+    }
     _commit_map.set_range(start_idx, start_idx + num_regions);
     fire_on_commit(start_idx, num_regions, zero_filled);
   }
@@ -110,19 +114,38 @@
     _refcounts.initialize((HeapWord*)rs.base(), (HeapWord*)(rs.base() + align_size_up(rs.size(), page_size)), page_size);
   }
 
-  virtual void commit_regions(uint start_idx, size_t num_regions) {
+  virtual void commit_regions(uint start_idx, size_t num_regions, WorkGang* pretouch_gang) {
+    size_t const NoPage = ~(size_t)0;
+
+    size_t first_committed = NoPage;
+    size_t num_committed = 0;
+
+    bool all_zero_filled = true;
+
     for (uint i = start_idx; i < start_idx + num_regions; i++) {
       assert(!_commit_map.at(i), "Trying to commit storage at region %u that is already committed", i);
       size_t idx = region_idx_to_page_idx(i);
       uint old_refcount = _refcounts.get_by_index(idx);
+
       bool zero_filled = false;
       if (old_refcount == 0) {
+        if (first_committed == NoPage) {
+          first_committed = idx;
+          num_committed = 1;
+        } else {
+          num_committed++;
+        }
         zero_filled = _storage.commit(idx, 1);
       }
+      all_zero_filled &= zero_filled;
+
       _refcounts.set_by_index(idx, old_refcount + 1);
       _commit_map.set_bit(i);
-      fire_on_commit(i, 1, zero_filled);
     }
+    if (AlwaysPreTouch && num_committed > 0) {
+      _storage.pretouch(first_committed, num_committed, pretouch_gang);
+    }
+    fire_on_commit(start_idx, num_regions, all_zero_filled);
   }
 
   virtual void uncommit_regions(uint start_idx, size_t num_regions) {
--- a/src/share/vm/gc/g1/g1RegionToSpaceMapper.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/gc/g1/g1RegionToSpaceMapper.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -29,6 +29,8 @@
 #include "memory/allocation.hpp"
 #include "utilities/debug.hpp"
 
+class WorkGang;
+
 class G1MappingChangedListener VALUE_OBJ_CLASS_SPEC {
  public:
   // Fired after commit of the memory, i.e. the memory this listener is registered
@@ -68,7 +70,7 @@
     return _commit_map.at(idx);
   }
 
-  virtual void commit_regions(uint start_idx, size_t num_regions = 1) = 0;
+  virtual void commit_regions(uint start_idx, size_t num_regions = 1, WorkGang* pretouch_workers = NULL) = 0;
   virtual void uncommit_regions(uint start_idx, size_t num_regions = 1) = 0;
 
   // Creates an appropriate G1RegionToSpaceMapper for the given parameters.
--- a/src/share/vm/gc/g1/g1RootProcessor.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/gc/g1/g1RootProcessor.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -83,6 +83,7 @@
   }
 
   process_vm_roots(closures, phase_times, worker_i);
+  process_string_table_roots(closures, phase_times, worker_i);
 
   {
     // Now the CM ref_processor roots.
@@ -191,19 +192,34 @@
 
 void G1RootProcessor::process_all_roots(OopClosure* oops,
                                         CLDClosure* clds,
-                                        CodeBlobClosure* blobs) {
+                                        CodeBlobClosure* blobs,
+                                        bool process_string_table) {
   AllRootsClosures closures(oops, clds);
 
   process_java_roots(&closures, NULL, 0);
   process_vm_roots(&closures, NULL, 0);
 
-  if (!_process_strong_tasks.is_task_claimed(G1RP_PS_CodeCache_oops_do)) {
-    CodeCache::blobs_do(blobs);
+  if (process_string_table) {
+    process_string_table_roots(&closures, NULL, 0);
   }
+  process_code_cache_roots(blobs, NULL, 0);
 
   _process_strong_tasks.all_tasks_completed(n_workers());
 }
 
+void G1RootProcessor::process_all_roots(OopClosure* oops,
+                                        CLDClosure* clds,
+                                        CodeBlobClosure* blobs) {
+  process_all_roots(oops, clds, blobs, true);
+}
+
+void G1RootProcessor::process_all_roots_no_string_table(OopClosure* oops,
+                                                        CLDClosure* clds,
+                                                        CodeBlobClosure* blobs) {
+  assert(!ClassUnloading, "Should only be used when class unloading is disabled");
+  process_all_roots(oops, clds, blobs, false);
+}
+
 void G1RootProcessor::process_java_roots(G1RootClosures* closures,
                                          G1GCPhaseTimes* phase_times,
                                          uint worker_i) {
@@ -280,14 +296,23 @@
       SystemDictionary::roots_oops_do(strong_roots, weak_roots);
     }
   }
+}
 
-  {
-    G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::StringTableRoots, worker_i);
-    // All threads execute the following. A specific chunk of buckets
-    // from the StringTable are the individual tasks.
-    if (weak_roots != NULL) {
-      StringTable::possibly_parallel_oops_do(weak_roots);
-    }
+void G1RootProcessor::process_string_table_roots(G1RootClosures* closures,
+                                                 G1GCPhaseTimes* phase_times,
+                                                 uint worker_i) {
+  assert(closures->weak_oops() != NULL, "Should only be called when all roots are processed");
+  G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::StringTableRoots, worker_i);
+  // All threads execute the following. A specific chunk of buckets
+  // from the StringTable are the individual tasks.
+  StringTable::possibly_parallel_oops_do(closures->weak_oops());
+}
+
+void G1RootProcessor::process_code_cache_roots(CodeBlobClosure* code_closure,
+                                               G1GCPhaseTimes* phase_times,
+                                               uint worker_i) {
+  if (!_process_strong_tasks.is_task_claimed(G1RP_PS_CodeCache_oops_do)) {
+    CodeCache::blobs_do(code_closure);
   }
 }
 
--- a/src/share/vm/gc/g1/g1RootProcessor.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/gc/g1/g1RootProcessor.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -73,6 +73,11 @@
   void worker_has_discovered_all_strong_classes();
   void wait_until_all_strong_classes_discovered();
 
+  void process_all_roots(OopClosure* oops,
+                         CLDClosure* clds,
+                         CodeBlobClosure* blobs,
+                         bool process_string_table);
+
   void process_java_roots(G1RootClosures* closures,
                           G1GCPhaseTimes* phase_times,
                           uint worker_i);
@@ -81,6 +86,14 @@
                         G1GCPhaseTimes* phase_times,
                         uint worker_i);
 
+  void process_string_table_roots(G1RootClosures* closures,
+                                  G1GCPhaseTimes* phase_times,
+                                  uint worker_i);
+
+  void process_code_cache_roots(CodeBlobClosure* code_closure,
+                                G1GCPhaseTimes* phase_times,
+                                uint worker_i);
+
 public:
   G1RootProcessor(G1CollectedHeap* g1h, uint n_workers);
 
@@ -99,6 +112,13 @@
                          CLDClosure* clds,
                          CodeBlobClosure* blobs);
 
+  // Apply oops, clds and blobs to strongly and weakly reachable roots in the system,
+  // the only thing different from process_all_roots is that we skip the string table
+  // to avoid keeping every string live when doing class unloading.
+  void process_all_roots_no_string_table(OopClosure* oops,
+                                         CLDClosure* clds,
+                                         CodeBlobClosure* blobs);
+
   // Number of worker threads used by the root processor.
   uint n_workers() const;
 };
--- a/src/share/vm/gc/g1/heapRegion.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/gc/g1/heapRegion.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -353,35 +353,6 @@
 }
 
 HeapWord*
-HeapRegion::object_iterate_mem_careful(MemRegion mr,
-                                                 ObjectClosure* cl) {
-  G1CollectedHeap* g1h = G1CollectedHeap::heap();
-  // We used to use "block_start_careful" here.  But we're actually happy
-  // to update the BOT while we do this...
-  HeapWord* cur = block_start(mr.start());
-  mr = mr.intersection(used_region());
-  if (mr.is_empty()) return NULL;
-  // Otherwise, find the obj that extends onto mr.start().
-
-  assert(cur <= mr.start()
-         && (oop(cur)->klass_or_null() == NULL ||
-             cur + oop(cur)->size() > mr.start()),
-         "postcondition of block_start");
-  oop obj;
-  while (cur < mr.end()) {
-    obj = oop(cur);
-    if (obj->klass_or_null() == NULL) {
-      // Ran into an unparseable point.
-      return cur;
-    } else if (!g1h->is_obj_dead(obj)) {
-      cl->do_object(obj);
-    }
-    cur += block_size(cur);
-  }
-  return NULL;
-}
-
-HeapWord*
 HeapRegion::
 oops_on_card_seq_iterate_careful(MemRegion mr,
                                  FilterOutOfRegionClosure* cl,
--- a/src/share/vm/gc/g1/heapRegion.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/gc/g1/heapRegion.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -653,17 +653,6 @@
     }
   }
 
-  // Requires that "mr" be entirely within the region.
-  // Apply "cl->do_object" to all objects that intersect with "mr".
-  // If the iteration encounters an unparseable portion of the region,
-  // or if "cl->abort()" is true after a closure application,
-  // terminate the iteration and return the address of the start of the
-  // subregion that isn't done.  (The two can be distinguished by querying
-  // "cl->abort()".)  Return of "NULL" indicates that the iteration
-  // completed.
-  HeapWord*
-  object_iterate_mem_careful(MemRegion mr, ObjectClosure* cl);
-
   // filter_young: if true and the region is a young region then we
   // skip the iteration.
   // card_ptr: if not NULL, and we decide that the card is not young
--- a/src/share/vm/gc/g1/heapRegionManager.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/gc/g1/heapRegionManager.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -72,22 +72,22 @@
   return g1h->new_heap_region(hrm_index, mr);
 }
 
-void HeapRegionManager::commit_regions(uint index, size_t num_regions) {
+void HeapRegionManager::commit_regions(uint index, size_t num_regions, WorkGang* pretouch_gang) {
   guarantee(num_regions > 0, "Must commit more than zero regions");
   guarantee(_num_committed + num_regions <= max_length(), "Cannot commit more than the maximum amount of regions");
 
   _num_committed += (uint)num_regions;
 
-  _heap_mapper->commit_regions(index, num_regions);
+  _heap_mapper->commit_regions(index, num_regions, pretouch_gang);
 
   // Also commit auxiliary data
-  _prev_bitmap_mapper->commit_regions(index, num_regions);
-  _next_bitmap_mapper->commit_regions(index, num_regions);
+  _prev_bitmap_mapper->commit_regions(index, num_regions, pretouch_gang);
+  _next_bitmap_mapper->commit_regions(index, num_regions, pretouch_gang);
 
-  _bot_mapper->commit_regions(index, num_regions);
-  _cardtable_mapper->commit_regions(index, num_regions);
+  _bot_mapper->commit_regions(index, num_regions, pretouch_gang);
+  _cardtable_mapper->commit_regions(index, num_regions, pretouch_gang);
 
-  _card_counts_mapper->commit_regions(index, num_regions);
+  _card_counts_mapper->commit_regions(index, num_regions, pretouch_gang);
 }
 
 void HeapRegionManager::uncommit_regions(uint start, size_t num_regions) {
@@ -117,12 +117,13 @@
   _card_counts_mapper->uncommit_regions(start, num_regions);
 }
 
-void HeapRegionManager::make_regions_available(uint start, uint num_regions) {
+void HeapRegionManager::make_regions_available(uint start, uint num_regions, WorkGang* pretouch_gang) {
   guarantee(num_regions > 0, "No point in calling this for zero regions");
-  commit_regions(start, num_regions);
+  commit_regions(start, num_regions, pretouch_gang);
   for (uint i = start; i < start + num_regions; i++) {
     if (_regions.get_by_index(i) == NULL) {
       HeapRegion* new_hr = new_heap_region(i);
+      OrderAccess::storestore();
       _regions.set_by_index(i, new_hr);
       _allocated_heapregions_length = MAX2(_allocated_heapregions_length, i + 1);
     }
@@ -162,11 +163,11 @@
   return MemoryUsage(0, used_sz, committed_sz, committed_sz);
 }
 
-uint HeapRegionManager::expand_by(uint num_regions) {
-  return expand_at(0, num_regions);
+uint HeapRegionManager::expand_by(uint num_regions, WorkGang* pretouch_workers) {
+  return expand_at(0, num_regions, pretouch_workers);
 }
 
-uint HeapRegionManager::expand_at(uint start, uint num_regions) {
+uint HeapRegionManager::expand_at(uint start, uint num_regions, WorkGang* pretouch_workers) {
   if (num_regions == 0) {
     return 0;
   }
@@ -180,7 +181,7 @@
   while (expanded < num_regions &&
          (num_last_found = find_unavailable_from_idx(cur, &idx_last_found)) > 0) {
     uint to_expand = MIN2(num_regions - expanded, num_last_found);
-    make_regions_available(idx_last_found, to_expand);
+    make_regions_available(idx_last_found, to_expand, pretouch_workers);
     expanded += to_expand;
     cur = idx_last_found + num_last_found + 1;
   }
--- a/src/share/vm/gc/g1/heapRegionManager.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/gc/g1/heapRegionManager.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -34,6 +34,7 @@
 class HeapRegionClosure;
 class HeapRegionClaimer;
 class FreeRegionList;
+class WorkGang;
 
 class G1HeapRegionTable : public G1BiasedMappedArray<HeapRegion*> {
  protected:
@@ -94,10 +95,10 @@
   HeapWord* heap_bottom() const { return _regions.bottom_address_mapped(); }
   HeapWord* heap_end() const {return _regions.end_address_mapped(); }
 
-  void make_regions_available(uint index, uint num_regions = 1);
+  void make_regions_available(uint index, uint num_regions = 1, WorkGang* pretouch_gang = NULL);
 
   // Pass down commit calls to the VirtualSpace.
-  void commit_regions(uint index, size_t num_regions = 1);
+  void commit_regions(uint index, size_t num_regions = 1, WorkGang* pretouch_gang = NULL);
   void uncommit_regions(uint index, size_t num_regions = 1);
 
   // Notify other data structures about change in the heap layout.
@@ -209,12 +210,12 @@
   // HeapRegions, or re-use existing ones. Returns the number of regions the
   // sequence was expanded by. If a HeapRegion allocation fails, the resulting
   // number of regions might be smaller than what's desired.
-  uint expand_by(uint num_regions);
+  uint expand_by(uint num_regions, WorkGang* pretouch_workers = NULL);
 
   // Makes sure that the regions from start to start+num_regions-1 are available
   // for allocation. Returns the number of regions that were committed to achieve
   // this.
-  uint expand_at(uint start, uint num_regions);
+  uint expand_at(uint start, uint num_regions, WorkGang* pretouch_workers = NULL);
 
   // Find a contiguous set of empty regions of length num. Returns the start index of
   // that set, or G1_NO_HRM_INDEX.
--- a/src/share/vm/gc/g1/heapRegionRemSet.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/gc/g1/heapRegionRemSet.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -56,7 +56,7 @@
   PerRegionTable * _collision_list_next;
 
   // Global free list of PRTs
-  static PerRegionTable* _free_list;
+  static PerRegionTable* volatile _free_list;
 
 protected:
   // We need access in order to union things into the base table.
@@ -249,7 +249,7 @@
   static void test_fl_mem_size();
 };
 
-PerRegionTable* PerRegionTable::_free_list = NULL;
+PerRegionTable* volatile PerRegionTable::_free_list = NULL;
 
 size_t OtherRegionsTable::_max_fine_entries = 0;
 size_t OtherRegionsTable::_mod_max_fine_entries_mask = 0;
--- a/src/share/vm/gc/g1/sparsePRT.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/gc/g1/sparsePRT.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -283,7 +283,7 @@
 
 // ----------------------------------------------------------------------
 
-SparsePRT* SparsePRT::_head_expanded_list = NULL;
+SparsePRT* volatile SparsePRT::_head_expanded_list = NULL;
 
 void SparsePRT::add_to_expanded_list(SparsePRT* sprt) {
   // We could expand multiple times in a pause -- only put on list once.
--- a/src/share/vm/gc/g1/sparsePRT.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/gc/g1/sparsePRT.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -250,7 +250,7 @@
 
   bool should_be_on_expanded_list();
 
-  static SparsePRT* _head_expanded_list;
+  static SparsePRT* volatile _head_expanded_list;
 
 public:
   SparsePRT(HeapRegion* hr);
--- a/src/share/vm/gc/parallel/mutableSpace.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/gc/parallel/mutableSpace.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -51,7 +51,7 @@
   MemRegion _last_setup_region;
   size_t _alignment;
  protected:
-  HeapWord* _top;
+  HeapWord* volatile _top;
 
   MutableSpaceMangler* mangler() { return _mangler; }
 
@@ -69,7 +69,7 @@
   HeapWord* top() const                    { return _top;    }
   virtual void set_top(HeapWord* value)    { _top = value;   }
 
-  HeapWord** top_addr()                    { return &_top; }
+  HeapWord* volatile* top_addr()           { return &_top; }
   HeapWord** end_addr()                    { return &_end; }
 
   virtual void set_bottom(HeapWord* value) { _bottom = value; }
--- a/src/share/vm/gc/parallel/parallelScavengeHeap.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/gc/parallel/parallelScavengeHeap.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -175,7 +175,7 @@
 
   bool supports_inline_contig_alloc() const { return !UseNUMA; }
 
-  HeapWord** top_addr() const { return !UseNUMA ? young_gen()->top_addr() : (HeapWord**)-1; }
+  HeapWord* volatile* top_addr() const { return !UseNUMA ? young_gen()->top_addr() : (HeapWord* volatile*)-1; }
   HeapWord** end_addr() const { return !UseNUMA ? young_gen()->end_addr() : (HeapWord**)-1; }
 
   void ensure_parsability(bool retire_tlabs);
--- a/src/share/vm/gc/parallel/psYoungGen.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/gc/parallel/psYoungGen.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -162,7 +162,7 @@
     return result;
   }
 
-  HeapWord** top_addr() const   { return eden_space()->top_addr(); }
+  HeapWord* volatile* top_addr() const   { return eden_space()->top_addr(); }
   HeapWord** end_addr() const   { return eden_space()->end_addr(); }
 
   // Iteration.
--- a/src/share/vm/gc/parallel/vmStructs_parallelgc.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/gc/parallel/vmStructs_parallelgc.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -26,7 +26,8 @@
 #define SHARE_VM_GC_PARALLEL_VMSTRUCTS_PARALLELGC_HPP
 
 #define VM_STRUCTS_PARALLELGC(nonstatic_field, \
-                   static_field) \
+                              volatile_nonstatic_field, \
+                              static_field) \
                                                                                                                                      \
   /**********************/                                                                                                           \
   /* Parallel GC fields */                                                                                                           \
@@ -40,7 +41,7 @@
   nonstatic_field(ImmutableSpace,              _bottom,                                       HeapWord*)                             \
   nonstatic_field(ImmutableSpace,              _end,                                          HeapWord*)                             \
                                                                                                                                      \
-  nonstatic_field(MutableSpace,                _top,                                          HeapWord*)                             \
+  volatile_nonstatic_field(MutableSpace,       _top,                                          HeapWord*)                             \
                                                                                                                                      \
   nonstatic_field(PSYoungGen,                  _reserved,                                     MemRegion)                             \
   nonstatic_field(PSYoungGen,                  _virtual_space,                                PSVirtualSpace*)                       \
--- a/src/share/vm/gc/serial/defNewGeneration.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/gc/serial/defNewGeneration.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -512,7 +512,7 @@
 }
 
 
-HeapWord** DefNewGeneration::top_addr() const { return eden()->top_addr(); }
+HeapWord* volatile* DefNewGeneration::top_addr() const { return eden()->top_addr(); }
 HeapWord** DefNewGeneration::end_addr() const { return eden()->end_addr(); }
 
 void DefNewGeneration::object_iterate(ObjectClosure* blk) {
--- a/src/share/vm/gc/serial/defNewGeneration.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/gc/serial/defNewGeneration.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -225,7 +225,7 @@
   size_t max_survivor_size() const          { return _max_survivor_size; }
 
   bool supports_inline_contig_alloc() const { return true; }
-  HeapWord** top_addr() const;
+  HeapWord* volatile* top_addr() const;
   HeapWord** end_addr() const;
 
   // Thread-local allocation buffers
--- a/src/share/vm/gc/shared/collectedHeap.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/gc/shared/collectedHeap.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -304,9 +304,6 @@
   inline static oop array_allocate_nozero(KlassHandle klass, int size, int length, TRAPS);
   inline static oop class_allocate(KlassHandle klass, int size, TRAPS);
 
-  inline static void post_allocation_install_obj_klass(KlassHandle klass,
-                                                       oop obj);
-
   // Raw memory allocation facilities
   // The obj and array allocate methods are covers for these methods.
   // mem_allocate() should never be
@@ -353,7 +350,7 @@
   // These functions return the addresses of the fields that define the
   // boundaries of the contiguous allocation area.  (These fields should be
   // physically near to one another.)
-  virtual HeapWord** top_addr() const {
+  virtual HeapWord* volatile* top_addr() const {
     guarantee(false, "inline contiguous allocation not supported");
     return NULL;
   }
--- a/src/share/vm/gc/shared/collectedHeap.inline.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/gc/shared/collectedHeap.inline.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -41,14 +41,22 @@
 // Inline allocation implementations.
 
 void CollectedHeap::post_allocation_setup_common(KlassHandle klass,
-                                                 HeapWord* obj) {
-  post_allocation_setup_no_klass_install(klass, obj);
-  post_allocation_install_obj_klass(klass, oop(obj));
+                                                 HeapWord* obj_ptr) {
+  post_allocation_setup_no_klass_install(klass, obj_ptr);
+  oop obj = (oop)obj_ptr;
+#if ! INCLUDE_ALL_GCS
+  obj->set_klass(klass());
+#else
+  // Need a release store to ensure array/class length, mark word, and
+  // object zeroing are visible before setting the klass non-NULL, for
+  // concurrent collectors.
+  obj->release_set_klass(klass());
+#endif
 }
 
 void CollectedHeap::post_allocation_setup_no_klass_install(KlassHandle klass,
-                                                           HeapWord* objPtr) {
-  oop obj = (oop)objPtr;
+                                                           HeapWord* obj_ptr) {
+  oop obj = (oop)obj_ptr;
 
   assert(obj != NULL, "NULL object pointer");
   if (UseBiasedLocking && (klass() != NULL)) {
@@ -59,18 +67,6 @@
   }
 }
 
-void CollectedHeap::post_allocation_install_obj_klass(KlassHandle klass,
-                                                   oop obj) {
-  // These asserts are kind of complicated because of klassKlass
-  // and the beginning of the world.
-  assert(klass() != NULL || !Universe::is_fully_initialized(), "NULL klass");
-  assert(klass() == NULL || klass()->is_klass(), "not a klass");
-  assert(obj != NULL, "NULL object pointer");
-  obj->set_klass(klass());
-  assert(!Universe::is_fully_initialized() || obj->klass() != NULL,
-         "missing klass");
-}
-
 // Support for jvmti and dtrace
 inline void post_allocation_notify(KlassHandle klass, oop obj, int size) {
   // support low memory notifications (no-op if not enabled)
@@ -88,25 +84,26 @@
 }
 
 void CollectedHeap::post_allocation_setup_obj(KlassHandle klass,
-                                              HeapWord* obj,
+                                              HeapWord* obj_ptr,
                                               int size) {
-  post_allocation_setup_common(klass, obj);
+  post_allocation_setup_common(klass, obj_ptr);
+  oop obj = (oop)obj_ptr;
   assert(Universe::is_bootstrapping() ||
-         !((oop)obj)->is_array(), "must not be an array");
+         !obj->is_array(), "must not be an array");
   // notify jvmti and dtrace
-  post_allocation_notify(klass, (oop)obj, size);
+  post_allocation_notify(klass, obj, size);
 }
 
 void CollectedHeap::post_allocation_setup_class(KlassHandle klass,
-                                                HeapWord* obj,
+                                                HeapWord* obj_ptr,
                                                 int size) {
-  // Set oop_size field before setting the _klass field
-  // in post_allocation_setup_common() because the klass field
-  // indicates that the object is parsable by concurrent GC.
-  oop new_cls = (oop)obj;
+  // Set oop_size field before setting the _klass field because a
+  // non-NULL _klass field indicates that the object is parsable by
+  // concurrent GC.
+  oop new_cls = (oop)obj_ptr;
   assert(size > 0, "oop_size must be positive.");
   java_lang_Class::set_oop_size(new_cls, size);
-  post_allocation_setup_common(klass, obj);
+  post_allocation_setup_common(klass, obj_ptr);
   assert(Universe::is_bootstrapping() ||
          !new_cls->is_array(), "must not be an array");
   // notify jvmti and dtrace
@@ -114,15 +111,15 @@
 }
 
 void CollectedHeap::post_allocation_setup_array(KlassHandle klass,
-                                                HeapWord* obj,
+                                                HeapWord* obj_ptr,
                                                 int length) {
-  // Set array length before setting the _klass field
-  // in post_allocation_setup_common() because the klass field
-  // indicates that the object is parsable by concurrent GC.
+  // Set array length before setting the _klass field because a
+  // non-NULL klass field indicates that the object is parsable by
+  // concurrent GC.
   assert(length >= 0, "length should be non-negative");
-  ((arrayOop)obj)->set_length(length);
-  post_allocation_setup_common(klass, obj);
-  oop new_obj = (oop)obj;
+  ((arrayOop)obj_ptr)->set_length(length);
+  post_allocation_setup_common(klass, obj_ptr);
+  oop new_obj = (oop)obj_ptr;
   assert(new_obj->is_array(), "must be an array");
   // notify jvmti and dtrace (must be after length is set for dtrace)
   post_allocation_notify(klass, new_obj, new_obj->size());
--- a/src/share/vm/gc/shared/gcTrace.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/gc/shared/gcTrace.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -185,8 +185,10 @@
 }
 
 #if INCLUDE_ALL_GCS
-void G1MMUTracer::report_mmu(double timeSlice, double gcTime, double maxTime) {
-  send_g1_mmu_event(timeSlice, gcTime, maxTime);
+void G1MMUTracer::report_mmu(double time_slice_sec, double gc_time_sec, double max_time_sec) {
+  send_g1_mmu_event(time_slice_sec * MILLIUNITS,
+                    gc_time_sec * MILLIUNITS,
+                    max_time_sec * MILLIUNITS);
 }
 
 void G1NewTracer::report_yc_type(G1YCType type) {
--- a/src/share/vm/gc/shared/gcTrace.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/gc/shared/gcTrace.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -235,10 +235,10 @@
 
 #if INCLUDE_ALL_GCS
 class G1MMUTracer : public AllStatic {
-  static void send_g1_mmu_event(double timeSlice, double gcTime, double maxTime);
+  static void send_g1_mmu_event(double time_slice_ms, double gc_time_ms, double max_time_ms);
 
  public:
-  static void report_mmu(double timeSlice, double gcTime, double maxTime);
+  static void report_mmu(double time_slice_sec, double gc_time_sec, double max_time_sec);
 };
 
 class G1NewTracer : public YoungGCTracer {
--- a/src/share/vm/gc/shared/gcTraceSend.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/gc/shared/gcTraceSend.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -200,13 +200,13 @@
   }
 }
 
-void G1MMUTracer::send_g1_mmu_event(double timeSlice, double gcTime, double maxTime) {
+void G1MMUTracer::send_g1_mmu_event(double time_slice_ms, double gc_time_ms, double max_time_ms) {
   EventG1MMU e;
   if (e.should_commit()) {
     e.set_gcId(GCId::current());
-    e.set_timeSlice(timeSlice);
-    e.set_gcTime(gcTime);
-    e.set_maxGcTime(maxTime);
+    e.set_timeSlice(time_slice_ms);
+    e.set_gcTime(gc_time_ms);
+    e.set_pauseTarget(max_time_ms);
     e.commit();
   }
 }
@@ -281,10 +281,10 @@
     evt.set_targetOccupancy(target_occupancy);
     evt.set_thresholdPercentage(target_occupancy > 0 ? ((double)threshold / target_occupancy) : 0.0);
     evt.set_currentOccupancy(current_occupancy);
-    evt.set_lastAllocationSize(last_allocation_size);
-    evt.set_lastAllocationDuration(last_allocation_duration);
-    evt.set_lastAllocationRate(last_allocation_duration != 0.0 ? last_allocation_size / last_allocation_duration : 0.0);
-    evt.set_lastMarkingLength(last_marking_length);
+    evt.set_recentMutatorAllocationSize(last_allocation_size);
+    evt.set_recentMutatorDuration(last_allocation_duration * MILLIUNITS);
+    evt.set_recentAllocationRate(last_allocation_duration != 0.0 ? last_allocation_size / last_allocation_duration : 0.0);
+    evt.set_lastMarkingDuration(last_marking_length * MILLIUNITS);
     evt.commit();
   }
 }
@@ -301,11 +301,11 @@
     evt.set_gcId(GCId::current());
     evt.set_threshold(threshold);
     evt.set_thresholdPercentage(internal_target_occupancy > 0 ? ((double)threshold / internal_target_occupancy) : 0.0);
-    evt.set_internalTargetOccupancy(internal_target_occupancy);
+    evt.set_ihopTargetOccupancy(internal_target_occupancy);
     evt.set_currentOccupancy(current_occupancy);
     evt.set_additionalBufferSize(additional_buffer_size);
     evt.set_predictedAllocationRate(predicted_allocation_rate);
-    evt.set_predictedMarkingLength(predicted_marking_length);
+    evt.set_predictedMarkingDuration(predicted_marking_length * MILLIUNITS);
     evt.set_predictionActive(prediction_active);
     evt.commit();
   }
--- a/src/share/vm/gc/shared/genCollectedHeap.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/gc/shared/genCollectedHeap.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -721,7 +721,7 @@
   return _young_gen->supports_inline_contig_alloc();
 }
 
-HeapWord** GenCollectedHeap::top_addr() const {
+HeapWord* volatile* GenCollectedHeap::top_addr() const {
   return _young_gen->top_addr();
 }
 
@@ -1256,21 +1256,20 @@
 };
 
 jlong GenCollectedHeap::millis_since_last_gc() {
-  // We need a monotonically non-decreasing time in ms but
-  // os::javaTimeMillis() does not guarantee monotonicity.
+  // javaTimeNanos() is guaranteed to be monotonically non-decreasing
+  // provided the underlying platform provides such a time source
+  // (and it is bug free). So we still have to guard against getting
+  // back a time later than 'now'.
   jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
   GenTimeOfLastGCClosure tolgc_cl(now);
   // iterate over generations getting the oldest
   // time that a generation was collected
   generation_iterate(&tolgc_cl, false);
 
-  // javaTimeNanos() is guaranteed to be monotonically non-decreasing
-  // provided the underlying platform provides such a time source
-  // (and it is bug free). So we still have to guard against getting
-  // back a time later than 'now'.
   jlong retVal = now - tolgc_cl.time();
   if (retVal < 0) {
-    NOT_PRODUCT(log_warning(gc)("time warp: " JLONG_FORMAT, retVal);)
+    log_warning(gc)("millis_since_last_gc() would return : " JLONG_FORMAT
+       ". returning zero instead.", retVal);
     return 0;
   }
   return retVal;
--- a/src/share/vm/gc/shared/genCollectedHeap.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/gc/shared/genCollectedHeap.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -184,7 +184,7 @@
   // We may support a shared contiguous allocation area, if the youngest
   // generation does.
   bool supports_inline_contig_alloc() const;
-  HeapWord** top_addr() const;
+  HeapWord* volatile* top_addr() const;
   HeapWord** end_addr() const;
 
   // Perform a full collection of the heap; intended for use in implementing
--- a/src/share/vm/gc/shared/generation.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/gc/shared/generation.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -263,7 +263,7 @@
   // These functions return the addresses of the fields that define the
   // boundaries of the contiguous allocation area.  (These fields should be
   // physically near to one another.)
-  virtual HeapWord** top_addr() const { return NULL; }
+  virtual HeapWord* volatile* top_addr() const { return NULL; }
   virtual HeapWord** end_addr() const { return NULL; }
 
   // Thread-local allocation buffers
--- a/src/share/vm/gc/shared/workerManager.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/gc/shared/workerManager.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 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
--- a/src/share/vm/gc/shared/workgroup.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/gc/shared/workgroup.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -472,23 +472,21 @@
 }
 
 bool SequentialSubTasksDone::is_task_claimed(uint& t) {
-  uint* n_claimed_ptr = &_n_claimed;
-  t = *n_claimed_ptr;
+  t = _n_claimed;
   while (t < _n_tasks) {
-    jint res = Atomic::cmpxchg(t+1, n_claimed_ptr, t);
+    jint res = Atomic::cmpxchg(t+1, &_n_claimed, t);
     if (res == (jint)t) {
       return false;
     }
-    t = *n_claimed_ptr;
+    t = res;
   }
   return true;
 }
 
 bool SequentialSubTasksDone::all_tasks_completed() {
-  uint* n_completed_ptr = &_n_completed;
-  uint  complete        = *n_completed_ptr;
+  uint complete = _n_completed;
   while (true) {
-    uint res = Atomic::cmpxchg(complete+1, n_completed_ptr, complete);
+    uint res = Atomic::cmpxchg(complete+1, &_n_completed, complete);
     if (res == complete) {
       break;
     }
--- a/src/share/vm/gc/shared/workgroup.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/gc/shared/workgroup.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -62,7 +62,12 @@
   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)
+  {}
 
   // The abstract work method.
   // The argument tells you which member of the gang you are.
@@ -313,9 +318,9 @@
 // enumeration type.
 
 class SubTasksDone: public CHeapObj<mtInternal> {
-  uint* _tasks;
+  volatile uint* _tasks;
   uint _n_tasks;
-  uint _threads_completed;
+  volatile uint _threads_completed;
 #ifdef ASSERT
   volatile uint _claimed;
 #endif
@@ -358,11 +363,11 @@
 class SequentialSubTasksDone : public StackObj {
 protected:
   uint _n_tasks;     // Total number of tasks available.
-  uint _n_claimed;   // Number of tasks claimed.
+  volatile uint _n_claimed;   // Number of tasks claimed.
   // _n_threads is used to determine when a sub task is done.
   // See comments on SubTasksDone::_n_threads
   uint _n_threads;   // Total number of parallel threads.
-  uint _n_completed; // Number of completed threads.
+  volatile uint _n_completed; // Number of completed threads.
 
   void clear();
 
--- a/src/share/vm/jvmci/jvmciCompilerToVM.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/jvmci/jvmciCompilerToVM.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -112,7 +112,7 @@
 
 bool       CompilerToVM::Data::_supports_inline_contig_alloc;
 HeapWord** CompilerToVM::Data::_heap_end_addr;
-HeapWord** CompilerToVM::Data::_heap_top_addr;
+HeapWord* volatile* CompilerToVM::Data::_heap_top_addr;
 int CompilerToVM::Data::_max_oop_map_stack_offset;
 
 jbyte* CompilerToVM::Data::cardtable_start_address;
@@ -153,7 +153,7 @@
 
   _supports_inline_contig_alloc = Universe::heap()->supports_inline_contig_alloc();
   _heap_end_addr = _supports_inline_contig_alloc ? Universe::heap()->end_addr() : (HeapWord**) -1;
-  _heap_top_addr = _supports_inline_contig_alloc ? Universe::heap()->top_addr() : (HeapWord**) -1;
+  _heap_top_addr = _supports_inline_contig_alloc ? Universe::heap()->top_addr() : (HeapWord* volatile*) -1;
 
   _max_oop_map_stack_offset = (OopMapValue::register_mask - VMRegImpl::stack2reg(0)->value()) * VMRegImpl::stack_slot_size;
   int max_oop_map_stack_index = _max_oop_map_stack_offset / VMRegImpl::stack_slot_size;
@@ -1604,4 +1604,3 @@
 int CompilerToVM::methods_count() {
   return sizeof(methods) / sizeof(JNINativeMethod);
 }
-
--- a/src/share/vm/jvmci/jvmciCompilerToVM.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/jvmci/jvmciCompilerToVM.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -58,7 +58,7 @@
 
     static bool _supports_inline_contig_alloc;
     static HeapWord** _heap_end_addr;
-    static HeapWord** _heap_top_addr;
+    static HeapWord* volatile* _heap_top_addr;
     static int _max_oop_map_stack_offset;
 
     static jbyte* cardtable_start_address;
--- a/src/share/vm/jvmci/vmStructs_jvmci.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/jvmci/vmStructs_jvmci.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -69,7 +69,7 @@
                                                                                                                                      \
   static_field(CompilerToVM::Data,             _supports_inline_contig_alloc,          bool)                                         \
   static_field(CompilerToVM::Data,             _heap_end_addr,                         HeapWord**)                                   \
-  static_field(CompilerToVM::Data,             _heap_top_addr,                         HeapWord**)                                   \
+  static_field(CompilerToVM::Data,             _heap_top_addr,                         HeapWord* volatile*)                          \
                                                                                                                                      \
   static_field(CompilerToVM::Data,             _max_oop_map_stack_offset,              int)                                          \
                                                                                                                                      \
--- a/src/share/vm/memory/allocation.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/memory/allocation.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -738,6 +738,7 @@
   static size_t size_for(size_t length);
 
  public:
+  static E* allocate_or_null(size_t length);
   static E* allocate(size_t length);
   static void free(E* addr, size_t length);
 };
--- a/src/share/vm/memory/allocation.inline.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/memory/allocation.inline.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -153,6 +153,24 @@
 }
 
 template <class E, MEMFLAGS F>
+E* MmapArrayAllocator<E, F>::allocate_or_null(size_t length) {
+  size_t size = size_for(length);
+  int alignment = os::vm_allocation_granularity();
+
+  char* addr = os::reserve_memory(size, NULL, alignment, F);
+  if (addr == NULL) {
+    return NULL;
+  }
+
+  if (os::commit_memory(addr, size, !ExecMem, "Allocator (commit)")) {
+    return (E*)addr;
+  } else {
+    os::release_memory(addr, size);
+    return NULL;
+  }
+}
+
+template <class E, MEMFLAGS F>
 E* MmapArrayAllocator<E, F>::allocate(size_t length) {
   size_t size = size_for(length);
   int alignment = os::vm_allocation_granularity();
--- a/src/share/vm/memory/filemap.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/memory/filemap.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -179,6 +179,7 @@
   _classpath_entry_table_size = mapinfo->_classpath_entry_table_size;
   _classpath_entry_table = mapinfo->_classpath_entry_table;
   _classpath_entry_size = mapinfo->_classpath_entry_size;
+  _num_patch_mod_prefixes = ClassLoader::num_patch_mod_prefixes();
 
   // The following fields are for sanity checks for whether this archive
   // will function correctly with this JVM and the bootclasspath it's
@@ -649,7 +650,7 @@
 
 // Memory map a region in the address space.
 static const char* shared_region_name[] = { "ReadOnly", "ReadWrite", "MiscData", "MiscCode",
-                                            "String1", "String2" };
+                                            "String1", "String2", "OptionalData" };
 
 char* FileMapInfo::map_region(int i) {
   assert(!MetaspaceShared::is_string_region(i), "sanity");
@@ -911,11 +912,6 @@
     return false;
   }
 
-  if (Arguments::get_patch_mod_prefix() != NULL) {
-    FileMapInfo::fail_continue("The shared archive file cannot be used with --patch-module.");
-    return false;
-  }
-
   if (!Arguments::has_jimage()) {
     FileMapInfo::fail_continue("The shared archive file cannot be used with an exploded module build.");
     return false;
@@ -952,6 +948,23 @@
     return false;
   }
 
+  // Check if there is a mismatch in --patch-module entry counts between dump time and run time.
+  // More checks will be performed on individual --patch-module entry in the
+  // SharedPathsMiscInfo::check() function.
+  GrowableArray<ModulePatchPath*>* patch_mod_args = Arguments::get_patch_mod_prefix();
+  if (patch_mod_args != NULL) {
+    if (_num_patch_mod_prefixes == 0) {
+      FileMapInfo::fail_stop("--patch-module found in run time but none was specified in dump time");
+    }
+    if (patch_mod_args->length() != _num_patch_mod_prefixes) {
+      FileMapInfo::fail_stop("mismatched --patch-module entry counts between dump time and run time");
+    }
+  } else {
+    if (_num_patch_mod_prefixes > 0) {
+      FileMapInfo::fail_stop("--patch-module specified in dump time but none was specified in run time");
+    }
+  }
+
   return true;
 }
 
--- a/src/share/vm/memory/filemap.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/memory/filemap.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -155,6 +155,7 @@
     // loading failures during runtime.
     int _classpath_entry_table_size;
     size_t _classpath_entry_size;
+    int    _num_patch_mod_prefixes;   // number of --patch-module entries
     SharedClassPathEntry* _classpath_entry_table;
 
     char* region_addr(int idx);
@@ -252,10 +253,27 @@
   bool is_in_shared_region(const void* p, int idx) NOT_CDS_RETURN_(false);
   void print_shared_spaces() NOT_CDS_RETURN;
 
+  // The ro+rw+md+mc spaces size
+  static size_t core_spaces_size() {
+    return align_size_up((SharedReadOnlySize + SharedReadWriteSize +
+                          SharedMiscDataSize + SharedMiscCodeSize),
+                          os::vm_allocation_granularity());
+  }
+
+  // The estimated optional space size.
+  //
+  // Currently the optional space only has archived class bytes.
+  // The core_spaces_size is the size of all class metadata, which is a good
+  // estimate of the total class bytes to be archived. Only the portion
+  // containing data is written out to the archive and mapped at runtime.
+  // There is no memory waste due to unused portion in optional space.
+  static size_t optional_space_size() {
+    return core_spaces_size();
+  }
+
+  // Total shared_spaces size includes the ro, rw, md, mc and od spaces
   static size_t shared_spaces_size() {
-    return align_size_up(SharedReadOnlySize + SharedReadWriteSize +
-                         SharedMiscDataSize + SharedMiscCodeSize,
-                         os::vm_allocation_granularity());
+    return core_spaces_size() + optional_space_size();
   }
 
   // Stop CDS sharing and unmap CDS regions.
--- a/src/share/vm/memory/metaspace.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/memory/metaspace.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -3172,36 +3172,28 @@
       address cds_address = NULL;
       FileMapInfo* mapinfo = new FileMapInfo();
 
-      if (JvmtiExport::should_post_class_file_load_hook()) {
-        // Currently CDS does not support JVMTI CFLH when loading shared class.
-        // If JvmtiExport::should_post_class_file_load_hook is already enabled,
-        // just disable UseSharedSpaces.
-        FileMapInfo::fail_continue("Tool agent requires sharing to be disabled.");
-        delete mapinfo;
+      // Open the shared archive file, read and validate the header. If
+      // initialization fails, shared spaces [UseSharedSpaces] are
+      // disabled and the file is closed.
+      // Map in spaces now also
+      if (mapinfo->initialize() && MetaspaceShared::map_shared_spaces(mapinfo)) {
+        cds_total = FileMapInfo::shared_spaces_size();
+        cds_address = (address)mapinfo->header()->region_addr(0);
+#ifdef _LP64
+        if (using_class_space()) {
+          char* cds_end = (char*)(cds_address + cds_total);
+          cds_end = (char *)align_ptr_up(cds_end, _reserve_alignment);
+          // If UseCompressedClassPointers is set then allocate the metaspace area
+          // above the heap and above the CDS area (if it exists).
+          allocate_metaspace_compressed_klass_ptrs(cds_end, cds_address);
+          // Map the shared string space after compressed pointers
+          // because it relies on compressed class pointers setting to work
+          mapinfo->map_string_regions();
+        }
+#endif // _LP64
       } else {
-        // Open the shared archive file, read and validate the header. If
-        // initialization fails, shared spaces [UseSharedSpaces] are
-        // disabled and the file is closed.
-        // Map in spaces now also
-        if (mapinfo->initialize() && MetaspaceShared::map_shared_spaces(mapinfo)) {
-          cds_total = FileMapInfo::shared_spaces_size();
-          cds_address = (address)mapinfo->header()->region_addr(0);
-#ifdef _LP64
-          if (using_class_space()) {
-            char* cds_end = (char*)(cds_address + cds_total);
-            cds_end = (char *)align_ptr_up(cds_end, _reserve_alignment);
-            // If UseCompressedClassPointers is set then allocate the metaspace area
-            // above the heap and above the CDS area (if it exists).
-            allocate_metaspace_compressed_klass_ptrs(cds_end, cds_address);
-            // Map the shared string space after compressed pointers
-            // because it relies on compressed class pointers setting to work
-            mapinfo->map_string_regions();
-          }
-#endif // _LP64
-        } else {
-          assert(!mapinfo->is_open() && !UseSharedSpaces,
-                 "archive file not closed or shared spaces not disabled.");
-        }
+        assert(!mapinfo->is_open() && !UseSharedSpaces,
+               "archive file not closed or shared spaces not disabled.");
       }
     }
 #endif // INCLUDE_CDS
--- a/src/share/vm/memory/metaspaceShared.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/memory/metaspaceShared.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -65,6 +65,7 @@
 size_t MetaspaceShared::_cds_i2i_entry_code_buffers_size = 0;
 SharedMiscRegion MetaspaceShared::_mc;
 SharedMiscRegion MetaspaceShared::_md;
+SharedMiscRegion MetaspaceShared::_od;
 
 void SharedMiscRegion::initialize(ReservedSpace rs, size_t committed_byte_size,  SharedSpaceType space_type) {
   _vs.initialize(rs, committed_byte_size);
@@ -93,16 +94,24 @@
   assert(DumpSharedSpaces, "dump time only");
   _shared_rs = rs;
 
-  // Split up and initialize the misc code and data spaces
+  size_t core_spaces_size = FileMapInfo::core_spaces_size();
   size_t metadata_size = SharedReadOnlySize + SharedReadWriteSize;
-  ReservedSpace shared_ro_rw = _shared_rs->first_part(metadata_size);
-  ReservedSpace misc_section = _shared_rs->last_part(metadata_size);
 
-  // Now split into misc sections.
+  // Split into the core and optional sections
+  ReservedSpace core_data = _shared_rs->first_part(core_spaces_size);
+  ReservedSpace optional_data = _shared_rs->last_part(core_spaces_size);
+
+  // The RO/RW and the misc sections
+  ReservedSpace shared_ro_rw = core_data.first_part(metadata_size);
+  ReservedSpace misc_section = core_data.last_part(metadata_size);
+
+  // Now split the misc code and misc data sections.
   ReservedSpace md_rs   = misc_section.first_part(SharedMiscDataSize);
   ReservedSpace mc_rs   = misc_section.last_part(SharedMiscDataSize);
+
   _md.initialize(md_rs, SharedMiscDataSize, SharedMiscData);
-  _mc.initialize(mc_rs, SharedMiscCodeSize, SharedMiscData);
+  _mc.initialize(mc_rs, SharedMiscCodeSize, SharedMiscCode);
+  _od.initialize(optional_data, metadata_size, SharedOptional);
 }
 
 // Read/write a data stream for restoring/preserving metadata pointers and
@@ -521,6 +530,7 @@
   GrowableArray<Klass*> *_class_promote_order;
   VirtualSpace _md_vs;
   VirtualSpace _mc_vs;
+  VirtualSpace _od_vs;
   GrowableArray<MemRegion> *_string_regions;
 
 public:
@@ -598,15 +608,19 @@
   remove_unshareable_in_classes();
   tty->print_cr("done. ");
 
-  // Set up the share data and shared code segments.
+  // Set up the misc data, misc code and optional data segments.
   _md_vs = *MetaspaceShared::misc_data_region()->virtual_space();
   _mc_vs = *MetaspaceShared::misc_code_region()->virtual_space();
+  _od_vs = *MetaspaceShared::optional_data_region()->virtual_space();
   char* md_low = _md_vs.low();
   char* md_top = MetaspaceShared::misc_data_region()->alloc_top();
   char* md_end = _md_vs.high();
   char* mc_low = _mc_vs.low();
   char* mc_top = MetaspaceShared::misc_code_region()->alloc_top();
   char* mc_end = _mc_vs.high();
+  char* od_low = _od_vs.low();
+  char* od_top = MetaspaceShared::optional_data_region()->alloc_top();
+  char* od_end = _od_vs.high();
 
   // Reserve space for the list of Klass*s whose vtables are used
   // for patching others as needed.
@@ -661,28 +675,32 @@
   const size_t rw_alloced = rw_space->capacity_bytes_slow(Metaspace::NonClassType);
   const size_t md_alloced = md_end-md_low;
   const size_t mc_alloced = mc_end-mc_low;
+  const size_t od_alloced = od_end-od_low;
   const size_t total_alloced = ro_alloced + rw_alloced + md_alloced + mc_alloced
-                             + ss_bytes;
+                             + ss_bytes + od_alloced;
 
   // Occupied size of each space.
   const size_t ro_bytes = ro_space->used_bytes_slow(Metaspace::NonClassType);
   const size_t rw_bytes = rw_space->used_bytes_slow(Metaspace::NonClassType);
   const size_t md_bytes = size_t(md_top - md_low);
   const size_t mc_bytes = size_t(mc_top - mc_low);
+  const size_t od_bytes = size_t(od_top - od_low);
 
   // Percent of total size
-  const size_t total_bytes = ro_bytes + rw_bytes + md_bytes + mc_bytes + ss_bytes;
+  const size_t total_bytes = ro_bytes + rw_bytes + md_bytes + mc_bytes + ss_bytes + od_bytes;
   const double ro_t_perc = ro_bytes / double(total_bytes) * 100.0;
   const double rw_t_perc = rw_bytes / double(total_bytes) * 100.0;
   const double md_t_perc = md_bytes / double(total_bytes) * 100.0;
   const double mc_t_perc = mc_bytes / double(total_bytes) * 100.0;
   const double ss_t_perc = ss_bytes / double(total_bytes) * 100.0;
+  const double od_t_perc = od_bytes / double(total_bytes) * 100.0;
 
   // Percent of fullness of each space
   const double ro_u_perc = ro_bytes / double(ro_alloced) * 100.0;
   const double rw_u_perc = rw_bytes / double(rw_alloced) * 100.0;
   const double md_u_perc = md_bytes / double(md_alloced) * 100.0;
   const double mc_u_perc = mc_bytes / double(mc_alloced) * 100.0;
+  const double od_u_perc = od_bytes / double(od_alloced) * 100.0;
   const double total_u_perc = total_bytes / double(total_alloced) * 100.0;
 
 #define fmt_space "%s space: " SIZE_FORMAT_W(9) " [ %4.1f%% of total] out of " SIZE_FORMAT_W(9) " bytes [%5.1f%% used] at " INTPTR_FORMAT
@@ -691,6 +709,7 @@
   tty->print_cr(fmt_space, "md", md_bytes, md_t_perc, md_alloced, md_u_perc, p2i(md_low));
   tty->print_cr(fmt_space, "mc", mc_bytes, mc_t_perc, mc_alloced, mc_u_perc, p2i(mc_low));
   tty->print_cr(fmt_space, "st", ss_bytes, ss_t_perc, ss_bytes,   100.0,     p2i(ss_low));
+  tty->print_cr(fmt_space, "od", od_bytes, od_t_perc, od_alloced, od_u_perc, p2i(od_low));
   tty->print_cr("total   : " SIZE_FORMAT_W(9) " [100.0%% of total] out of " SIZE_FORMAT_W(9) " bytes [%5.1f%% used]",
                  total_bytes, total_alloced, total_u_perc);
 
@@ -734,6 +753,10 @@
                           SharedMiscCodeSize,
                           true, true);
     mapinfo->write_string_regions(_string_regions);
+    mapinfo->write_region(MetaspaceShared::od, _od_vs.low(),
+                          pointer_delta(od_top, _od_vs.low(), sizeof(char)),
+                          pointer_delta(od_end, _od_vs.low(), sizeof(char)),
+                          true, false);
   }
 
   mapinfo->close();
@@ -1049,8 +1072,6 @@
 
 
 // Map shared spaces at requested addresses and return if succeeded.
-// Need to keep the bounds of the ro and rw space for the Metaspace::contains
-// call, or is_in_shared_space.
 bool MetaspaceShared::map_shared_spaces(FileMapInfo* mapinfo) {
   size_t image_alignment = mapinfo->alignment();
 
@@ -1068,6 +1089,7 @@
   char* _rw_base = NULL;
   char* _md_base = NULL;
   char* _mc_base = NULL;
+  char* _od_base = NULL;
 
   // Map each shared region
   if ((_ro_base = mapinfo->map_region(ro)) != NULL &&
@@ -1078,6 +1100,8 @@
       mapinfo->verify_region_checksum(md) &&
       (_mc_base = mapinfo->map_region(mc)) != NULL &&
       mapinfo->verify_region_checksum(mc) &&
+      (_od_base = mapinfo->map_region(od)) != NULL &&
+      mapinfo->verify_region_checksum(od) &&
       (image_alignment == (size_t)max_alignment()) &&
       mapinfo->validate_classpath_entry_table()) {
     // Success (no need to do anything)
@@ -1089,6 +1113,7 @@
     if (_rw_base != NULL) mapinfo->unmap_region(rw);
     if (_md_base != NULL) mapinfo->unmap_region(md);
     if (_mc_base != NULL) mapinfo->unmap_region(mc);
+    if (_od_base != NULL) mapinfo->unmap_region(od);
 #ifndef _WINDOWS
     // Release the entire mapped region
     shared_rs.release();
--- a/src/share/vm/memory/metaspaceShared.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/memory/metaspaceShared.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -132,6 +132,7 @@
   // Used only during dumping.
   static SharedMiscRegion _md;
   static SharedMiscRegion _mc;
+  static SharedMiscRegion _od;
  public:
   enum {
     vtbl_list_size         = DEFAULT_VTBL_LIST_SIZE,
@@ -148,7 +149,10 @@
     max_strings = 2, // max number of string regions in string space
     num_non_strings = 4, // number of non-string regions
     first_string = num_non_strings, // index of first string region
-    n_regions = max_strings + num_non_strings // total number of regions
+    // The optional data region is the last region.
+    // Currently it only contains class file data.
+    od = max_strings + num_non_strings,
+    n_regions = od + 1 // total number of regions
   };
 
   // Accessor functions to save shared space created for metadata, which has
@@ -222,9 +226,10 @@
   static int count_class(const char* classlist_file);
   static void estimate_regions_size() NOT_CDS_RETURN;
 
-  // Allocate a block of memory from the "mc" or "md" regions.
+  // Allocate a block of memory from the "mc", "md", or "od" regions.
   static char* misc_code_space_alloc(size_t num_bytes) {  return _mc.alloc(num_bytes); }
   static char* misc_data_space_alloc(size_t num_bytes) {  return _md.alloc(num_bytes); }
+  static char* optional_data_space_alloc(size_t num_bytes) { return _od.alloc(num_bytes); }
 
   static address cds_i2i_entry_code_buffers(size_t total_size);
 
@@ -243,5 +248,9 @@
     assert(DumpSharedSpaces, "used during dumping only");
     return &_md;
   }
+  static SharedMiscRegion* optional_data_region() {
+    assert(DumpSharedSpaces, "used during dumping only");
+    return &_od;
+  }
 };
 #endif // SHARE_VM_MEMORY_METASPACESHARED_HPP
--- a/src/share/vm/oops/instanceKlass.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/oops/instanceKlass.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -41,6 +41,7 @@
 #include "memory/heapInspection.hpp"
 #include "memory/iterator.inline.hpp"
 #include "memory/metadataFactory.hpp"
+#include "memory/metaspaceShared.hpp"
 #include "memory/oopFactory.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/fieldStreams.hpp"
@@ -1972,11 +1973,6 @@
     m->remove_unshareable_info();
   }
 
-  // cached_class_file might be pointing to a malloc'ed buffer allocated by
-  // event-based tracing code at CDS dump time. It's not usable at runtime
-  // so let's clear it.
-  set_cached_class_file(NULL);
-
   // do array classes also.
   array_klasses_do(remove_unshareable_in_class);
 }
@@ -2070,6 +2066,7 @@
 }
 
 void InstanceKlass::release_C_heap_structures() {
+  assert(!this->is_shared(), "should not be called for a shared class");
 
   // Can't release the constant pool here because the constant pool can be
   // deallocated separately from the InstanceKlass for default methods and
@@ -2250,8 +2247,8 @@
         // the java.base module.  If a non-java.base package is erroneously placed
         // in the java.base module it will be caught later when java.base
         // is defined by ModuleEntryTable::verify_javabase_packages check.
-        assert(ModuleEntryTable::javabase_module() != NULL, "java.base module is NULL");
-        _package_entry = loader_data->packages()->lookup(pkg_name, ModuleEntryTable::javabase_module());
+        assert(ModuleEntryTable::javabase_moduleEntry() != NULL, "java.base module is NULL");
+        _package_entry = loader_data->packages()->lookup(pkg_name, ModuleEntryTable::javabase_moduleEntry());
       } else {
         assert(loader_data->modules()->unnamed_module() != NULL, "unnamed module is NULL");
         _package_entry = loader_data->packages()->lookup(pkg_name,
@@ -3653,6 +3650,15 @@
 }
 
 #if INCLUDE_JVMTI
+JvmtiCachedClassFileData* InstanceKlass::get_cached_class_file() {
+  if (MetaspaceShared::is_in_shared_space(_cached_class_file)) {
+    // Ignore the archived class stream data
+    return NULL;
+  } else {
+    return _cached_class_file;
+  }
+}
+
 jint InstanceKlass::get_cached_class_file_len() {
   return VM_RedefineClasses::get_cached_class_file_len(_cached_class_file);
 }
@@ -3660,4 +3666,15 @@
 unsigned char * InstanceKlass::get_cached_class_file_bytes() {
   return VM_RedefineClasses::get_cached_class_file_bytes(_cached_class_file);
 }
+
+#if INCLUDE_CDS
+JvmtiCachedClassFileData* InstanceKlass::get_archived_class_data() {
+  assert(this->is_shared(), "class should be shared");
+  if (MetaspaceShared::is_in_shared_space(_cached_class_file)) {
+    return _cached_class_file;
+  } else {
+    return NULL;
+  }
+}
 #endif
+#endif
--- a/src/share/vm/oops/instanceKlass.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/oops/instanceKlass.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -783,7 +783,7 @@
   void set_cached_class_file(JvmtiCachedClassFileData *data) {
     _cached_class_file = data;
   }
-  JvmtiCachedClassFileData * get_cached_class_file() { return _cached_class_file; }
+  JvmtiCachedClassFileData * get_cached_class_file();
   jint get_cached_class_file_len();
   unsigned char * get_cached_class_file_bytes();
 
@@ -795,6 +795,13 @@
     return _jvmti_cached_class_field_map;
   }
 
+#if INCLUDE_CDS
+  void set_archived_class_data(JvmtiCachedClassFileData* data) {
+    _cached_class_file = data;
+  }
+
+  JvmtiCachedClassFileData * get_archived_class_data();
+#endif // INCLUDE_CDS
 #else // INCLUDE_JVMTI
 
   static void purge_previous_versions(InstanceKlass* ik) { return; };
--- a/src/share/vm/oops/klass.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/oops/klass.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -530,7 +530,7 @@
       InstanceKlass* ik = (InstanceKlass*) k;
       module_entry = ik->module();
     } else {
-      module_entry = ModuleEntryTable::javabase_module();
+      module_entry = ModuleEntryTable::javabase_moduleEntry();
     }
     // Obtain java.lang.reflect.Module, if available
     Handle module_handle(THREAD, ((module_entry != NULL) ? JNIHandles::resolve(module_entry->module()) : (oop)NULL));
--- a/src/share/vm/oops/oop.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/oops/oop.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -87,6 +87,7 @@
   inline narrowKlass* compressed_klass_addr();
 
   inline void set_klass(Klass* k);
+  inline void release_set_klass(Klass* k);
 
   // For klass field compression
   inline int klass_gap() const;
--- a/src/share/vm/oops/oop.inline.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/oops/oop.inline.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -129,10 +129,14 @@
   return &_metadata._compressed_klass;
 }
 
+#define CHECK_SET_KLASS(k)                                                \
+  do {                                                                    \
+    assert(Universe::is_bootstrapping() || k != NULL, "NULL Klass");      \
+    assert(Universe::is_bootstrapping() || k->is_klass(), "not a Klass"); \
+  } while (0)
+
 void oopDesc::set_klass(Klass* k) {
-  // since klasses are promoted no store check is needed
-  assert(Universe::is_bootstrapping() || k != NULL, "must be a real Klass*");
-  assert(Universe::is_bootstrapping() || k->is_klass(), "not a Klass*");
+  CHECK_SET_KLASS(k);
   if (UseCompressedClassPointers) {
     *compressed_klass_addr() = Klass::encode_klass_not_null(k);
   } else {
@@ -140,6 +144,18 @@
   }
 }
 
+void oopDesc::release_set_klass(Klass* k) {
+  CHECK_SET_KLASS(k);
+  if (UseCompressedClassPointers) {
+    OrderAccess::release_store(compressed_klass_addr(),
+                               Klass::encode_klass_not_null(k));
+  } else {
+    OrderAccess::release_store_ptr(klass_addr(), k);
+  }
+}
+
+#undef CHECK_SET_KLASS
+
 int oopDesc::klass_gap() const {
   return *(int*)(((intptr_t)this) + klass_gap_offset_in_bytes());
 }
--- a/src/share/vm/oops/typeArrayKlass.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/oops/typeArrayKlass.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -72,7 +72,7 @@
   null_loader_data->add_class(ak);
 
   // Call complete_create_array_klass after all instance variables have been initialized.
-  complete_create_array_klass(ak, ak->super(), ModuleEntryTable::javabase_module(), CHECK_NULL);
+  complete_create_array_klass(ak, ak->super(), ModuleEntryTable::javabase_moduleEntry(), CHECK_NULL);
 
   return ak;
 }
@@ -347,7 +347,7 @@
 
 // A TypeArrayKlass is an array of a primitive type, its defining module is java.base
 ModuleEntry* TypeArrayKlass::module() const {
-  return ModuleEntryTable::javabase_module();
+  return ModuleEntryTable::javabase_moduleEntry();
 }
 
 PackageEntry* TypeArrayKlass::package() const {
--- a/src/share/vm/prims/jvm.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/prims/jvm.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -562,8 +562,8 @@
   }
 
   Handle stackStream_h(THREAD, JNIHandles::resolve_non_null(stackStream));
-  return StackWalk::moreFrames(stackStream_h, mode, anchor, frame_count,
-                               start_index, frames_array_h, THREAD);
+  return StackWalk::fetchNextBatch(stackStream_h, mode, anchor, frame_count,
+                                   start_index, frames_array_h, THREAD);
 JVM_END
 
 JVM_ENTRY(void, JVM_ToStackTraceElement(JNIEnv *env, jobject frame, jobject stack))
--- a/src/share/vm/prims/jvm.h	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/prims/jvm.h	Wed Sep 21 08:38:21 2016 +0000
@@ -196,7 +196,8 @@
  * java.lang.StackWalker
  */
 enum {
-  JVM_STACKWALK_FILL_CLASS_REFS_ONLY       = 0x2,
+  JVM_STACKWALK_FILL_CLASS_REFS_ONLY       = 0x02,
+  JVM_STACKWALK_GET_CALLER_CLASS           = 0x04,
   JVM_STACKWALK_SHOW_HIDDEN_FRAMES         = 0x20,
   JVM_STACKWALK_FILL_LIVE_STACK_FRAMES     = 0x100
 };
--- a/src/share/vm/prims/stackwalk.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/prims/stackwalk.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -37,42 +37,47 @@
 #include "utilities/globalDefinitions.hpp"
 
 // setup and cleanup actions
-void JavaFrameStream::setup_magic_on_entry(objArrayHandle frames_array) {
+void BaseFrameStream::setup_magic_on_entry(objArrayHandle frames_array) {
   frames_array->obj_at_put(magic_pos, _thread->threadObj());
   _anchor = address_value();
   assert(check_magic(frames_array), "invalid magic");
 }
 
-bool JavaFrameStream::check_magic(objArrayHandle frames_array) {
+bool BaseFrameStream::check_magic(objArrayHandle frames_array) {
   oop   m1 = frames_array->obj_at(magic_pos);
   jlong m2 = _anchor;
   if (m1 == _thread->threadObj() && m2 == address_value())  return true;
   return false;
 }
 
-bool JavaFrameStream::cleanup_magic_on_exit(objArrayHandle frames_array) {
+bool BaseFrameStream::cleanup_magic_on_exit(objArrayHandle frames_array) {
   bool ok = check_magic(frames_array);
   frames_array->obj_at_put(magic_pos, NULL);
   _anchor = 0L;
   return ok;
 }
 
-// Returns JavaFrameStream for the current stack being traversed.
+JavaFrameStream::JavaFrameStream(JavaThread* thread, int mode)
+  : BaseFrameStream(thread), _vfst(thread) {
+  _need_method_info = StackWalk::need_method_info(mode);
+}
+
+// Returns the BaseFrameStream for the current stack being traversed.
 //
 // Parameters:
 //  thread         Current Java thread.
 //  magic          Magic value used for each stack walking
 //  frames_array   User-supplied buffers.  The 0th element is reserved
-//                 to this JavaFrameStream to use
+//                 for this BaseFrameStream to use
 //
-JavaFrameStream* JavaFrameStream::from_current(JavaThread* thread, jlong magic,
+BaseFrameStream* BaseFrameStream::from_current(JavaThread* thread, jlong magic,
                                                objArrayHandle frames_array)
 {
   assert(thread != NULL && thread->is_Java_thread(), "");
   oop m1 = frames_array->obj_at(magic_pos);
   if (m1 != thread->threadObj())      return NULL;
   if (magic == 0L)                    return NULL;
-  JavaFrameStream* stream = (JavaFrameStream*) (intptr_t) magic;
+  BaseFrameStream* stream = (BaseFrameStream*) (intptr_t) magic;
   if (!stream->is_valid_in(thread, frames_array))   return NULL;
   return stream;
 }
@@ -85,7 +90,7 @@
 //
 // Parameters:
 //   mode             Restrict which frames to be decoded.
-//   JavaFrameStream  stream of javaVFrames
+//   BaseFrameStream  stream of frames
 //   max_nframes      Maximum number of frames to be filled.
 //   start_index      Start index to the user-supplied buffers.
 //   frames_array     Buffer to store Class or StackFrame in, starting at start_index.
@@ -96,7 +101,7 @@
 //
 // Returns the number of frames whose information was transferred into the buffers.
 //
-int StackWalk::fill_in_frames(jlong mode, JavaFrameStream& stream,
+int StackWalk::fill_in_frames(jlong mode, BaseFrameStream& stream,
                               int max_nframes, int start_index,
                               objArrayHandle  frames_array,
                               int& end_index, TRAPS) {
@@ -110,10 +115,12 @@
   int frames_decoded = 0;
   for (; !stream.at_end(); stream.next()) {
     Method* method = stream.method();
-    int bci = stream.bci();
 
     if (method == NULL) continue;
-    if (!ShowHiddenFrames && StackWalk::skip_hidden_frames(mode)) {
+
+    // skip hidden frames for default StackWalker option (i.e. SHOW_HIDDEN_FRAMES
+    // not set) and when StackWalker::getCallerClass is called
+    if (!ShowHiddenFrames && (skip_hidden_frames(mode) || get_caller_class(mode))) {
       if (method->is_hidden()) {
         if (TraceStackWalk) {
           tty->print("  hidden method: "); method->print_short_name();
@@ -126,28 +133,42 @@
     int index = end_index++;
     if (TraceStackWalk) {
       tty->print("  %d: frame method: ", index); method->print_short_name();
-      tty->print_cr(" bci=%d", bci);
+      tty->print_cr(" bci=%d", stream.bci());
     }
 
+    if (!need_method_info(mode) && get_caller_class(mode) &&
+          index == start_index && method->caller_sensitive()) {
+      ResourceMark rm(THREAD);
+      THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(),
+        err_msg("StackWalker::getCallerClass called from @CallerSensitive %s method",
+                method->name_and_sig_as_C_string()));
+    }
     // fill in StackFrameInfo and initialize MemberName
-    if (live_frame_info(mode)) {
-      assert (use_frames_array(mode), "Bad mode for get live frame");
-      Handle stackFrame(frames_array->obj_at(index));
-      fill_live_stackframe(stackFrame, method, bci, stream.java_frame(), CHECK_0);
-    } else if (need_method_info(mode)) {
-      assert (use_frames_array(mode), "Bad mode for get stack frame");
-      Handle stackFrame(frames_array->obj_at(index));
-      fill_stackframe(stackFrame, method, bci);
-    } else {
-      assert (use_frames_array(mode) == false, "Bad mode for get caller class");
-      frames_array->obj_at_put(index, method->method_holder()->java_mirror());
-    }
+    stream.fill_frame(index, frames_array, method, CHECK_0);
     if (++frames_decoded >= max_nframes)  break;
   }
   return frames_decoded;
 }
 
-static oop create_primitive_value_instance(StackValueCollection* values, int i, TRAPS) {
+// Fill in the LiveStackFrameInfo at the given index in frames_array
+void LiveFrameStream::fill_frame(int index, objArrayHandle  frames_array,
+                                 const methodHandle& method, TRAPS) {
+  Handle stackFrame(THREAD, frames_array->obj_at(index));
+  fill_live_stackframe(stackFrame, method, CHECK);
+}
+
+// Fill in the StackFrameInfo at the given index in frames_array
+void JavaFrameStream::fill_frame(int index, objArrayHandle  frames_array,
+                                 const methodHandle& method, TRAPS) {
+  if (_need_method_info) {
+    Handle stackFrame(THREAD, frames_array->obj_at(index));
+    fill_stackframe(stackFrame, method);
+  } else {
+    frames_array->obj_at_put(index, method->method_holder()->java_mirror());
+  }
+}
+
+oop LiveFrameStream::create_primitive_value_instance(StackValueCollection* values, int i, TRAPS) {
   Klass* k = SystemDictionary::resolve_or_null(vmSymbols::java_lang_LiveStackFrameInfo(), CHECK_NULL);
   instanceKlassHandle ik (THREAD, k);
 
@@ -218,7 +239,7 @@
   return (instanceOop) result.get_jobject();
 }
 
-static objArrayHandle values_to_object_array(StackValueCollection* values, TRAPS) {
+objArrayHandle LiveFrameStream::values_to_object_array(StackValueCollection* values, TRAPS) {
   objArrayHandle empty;
   int length = values->size();
   objArrayOop array_oop = oopFactory::new_objArray(SystemDictionary::Object_klass(),
@@ -233,7 +254,7 @@
   return array_h;
 }
 
-static objArrayHandle monitors_to_object_array(GrowableArray<MonitorInfo*>* monitors, TRAPS) {
+objArrayHandle LiveFrameStream::monitors_to_object_array(GrowableArray<MonitorInfo*>* monitors, TRAPS) {
   int length = monitors->length();
   objArrayOop array_oop = oopFactory::new_objArray(SystemDictionary::Object_klass(),
                                                    length, CHECK_(objArrayHandle()));
@@ -246,19 +267,19 @@
 }
 
 // Fill StackFrameInfo with declaringClass and bci and initialize memberName
-void StackWalk::fill_stackframe(Handle stackFrame, const methodHandle& method, int bci) {
+void BaseFrameStream::fill_stackframe(Handle stackFrame, const methodHandle& method) {
   java_lang_StackFrameInfo::set_declaringClass(stackFrame(), method->method_holder()->java_mirror());
-  java_lang_StackFrameInfo::set_method_and_bci(stackFrame(), method, bci);
+  java_lang_StackFrameInfo::set_method_and_bci(stackFrame(), method, bci());
 }
 
 // Fill LiveStackFrameInfo with locals, monitors, and expressions
-void StackWalk::fill_live_stackframe(Handle stackFrame, const methodHandle& method,
-                                     int bci, javaVFrame* jvf, TRAPS) {
-  fill_stackframe(stackFrame, method, bci);
-  if (jvf != NULL) {
-    StackValueCollection* locals = jvf->locals();
-    StackValueCollection* expressions = jvf->expressions();
-    GrowableArray<MonitorInfo*>* monitors = jvf->monitors();
+void LiveFrameStream::fill_live_stackframe(Handle stackFrame,
+                                           const methodHandle& method, TRAPS) {
+  fill_stackframe(stackFrame, method);
+  if (_jvf != NULL) {
+    StackValueCollection* locals = _jvf->locals();
+    StackValueCollection* expressions = _jvf->expressions();
+    GrowableArray<MonitorInfo*>* monitors = _jvf->monitors();
 
     if (!locals->is_empty()) {
       objArrayHandle locals_h = values_to_object_array(locals, CHECK);
@@ -305,15 +326,26 @@
     THROW_MSG_(vmSymbols::java_lang_NullPointerException(), "frames_array is NULL", NULL);
   }
 
-  Klass* stackWalker_klass = SystemDictionary::StackWalker_klass();
-  Klass* abstractStackWalker_klass = SystemDictionary::AbstractStackWalker_klass();
+  // Setup traversal onto my stack.
+  if (live_frame_info(mode)) {
+    assert (use_frames_array(mode), "Bad mode for get live frame");
+    RegisterMap regMap(jt, true);
+    LiveFrameStream stream(jt, &regMap);
+    return fetchFirstBatch(stream, stackStream, mode, skip_frames, frame_count, start_index, frames_array, CHECK_NULL);
+  } else {
+    JavaFrameStream stream(jt, mode);
+    return fetchFirstBatch(stream, stackStream, mode, skip_frames, frame_count, start_index, frames_array, CHECK_NULL);
+  }
+}
 
+oop StackWalk::fetchFirstBatch(BaseFrameStream& stream, Handle stackStream,
+                               jlong mode, int skip_frames, int frame_count,
+                               int start_index, objArrayHandle frames_array, TRAPS) {
   methodHandle m_doStackWalk(THREAD, Universe::do_stack_walk_method());
 
-  // Setup traversal onto my stack.
-  RegisterMap regMap(jt, true);
-  JavaFrameStream stream(jt, &regMap);
   {
+    Klass* stackWalker_klass = SystemDictionary::StackWalker_klass();
+    Klass* abstractStackWalker_klass = SystemDictionary::AbstractStackWalker_klass();
     while (!stream.at_end()) {
       InstanceKlass* ik = stream.method()->method_holder();
       if (ik != stackWalker_klass &&
@@ -331,10 +363,7 @@
     // from the stack frame at depth == skip_frames.
     for (int n=0; n < skip_frames && !stream.at_end(); stream.next(), n++) {
       if (TraceStackWalk) {
-        tty->print("  skip "); stream.method()->print_short_name();
-        tty->print_cr(" frame id: " PTR_FORMAT " pc: " PTR_FORMAT,
-                      p2i(stream.java_frame()->fr().id()),
-                      p2i(stream.java_frame()->fr().pc()));
+        tty->print("  skip "); stream.method()->print_short_name(); tty->cr();
       }
     }
   }
@@ -392,13 +421,13 @@
 //
 // Returns the end index of frame filled in the buffer.
 //
-jint StackWalk::moreFrames(Handle stackStream, jlong mode, jlong magic,
-                           int frame_count, int start_index,
-                           objArrayHandle frames_array,
-                           TRAPS)
+jint StackWalk::fetchNextBatch(Handle stackStream, jlong mode, jlong magic,
+                               int frame_count, int start_index,
+                               objArrayHandle frames_array,
+                               TRAPS)
 {
   JavaThread* jt = (JavaThread*)THREAD;
-  JavaFrameStream* existing_stream = JavaFrameStream::from_current(jt, magic, frames_array);
+  BaseFrameStream* existing_stream = BaseFrameStream::from_current(jt, magic, frames_array);
   if (existing_stream == NULL) {
     THROW_MSG_(vmSymbols::java_lang_InternalError(), "doStackWalk: corrupted buffers", 0L);
   }
@@ -408,7 +437,7 @@
   }
 
   if (TraceStackWalk) {
-    tty->print_cr("StackWalk::moreFrames frame_count %d existing_stream " PTR_FORMAT " start %d frames %d",
+    tty->print_cr("StackWalk::fetchNextBatch frame_count %d existing_stream " PTR_FORMAT " start %d frames %d",
                   frame_count, p2i(existing_stream), start_index, frames_array->length());
   }
   int end_index = start_index;
@@ -419,7 +448,7 @@
   int count = frame_count + start_index;
   assert (frames_array->length() >= count, "not enough space in buffers");
 
-  JavaFrameStream& stream = (*existing_stream);
+  BaseFrameStream& stream = (*existing_stream);
   if (!stream.at_end()) {
     stream.next(); // advance past the last frame decoded in previous batch
     if (!stream.at_end()) {
--- a/src/share/vm/prims/stackwalk.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/prims/stackwalk.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -29,31 +29,34 @@
 #include "oops/oop.hpp"
 #include "runtime/vframe.hpp"
 
-//
-// JavaFrameStream is used by StackWalker to iterate through Java stack frames
-// on the given JavaThread.
-//
-class JavaFrameStream : public StackObj {
+// BaseFrameStream is an abstract base class for encapsulating the VM-side
+// implementation of the StackWalker API.  There are two concrete subclasses:
+// - JavaFrameStream:
+//     -based on vframeStream; used in most instances
+// - LiveFrameStream:
+//     -based on javaVFrame; used for retrieving locals/monitors/operands for
+//      LiveStackFrame
+class BaseFrameStream : public StackObj {
 private:
   enum {
     magic_pos = 0
   };
 
   JavaThread*           _thread;
-  javaVFrame*           _jvf;
   jlong                 _anchor;
+protected:
+  void fill_stackframe(Handle stackFrame, const methodHandle& method);
 public:
-  JavaFrameStream(JavaThread* thread, RegisterMap* rm)
-    : _thread(thread), _anchor(0L) {
-    _jvf = _thread->last_java_vframe(rm);
-  }
+  BaseFrameStream(JavaThread* thread) : _thread(thread), _anchor(0L) {}
 
-  javaVFrame*     java_frame()        { return _jvf; }
-  void            next()              { _jvf = _jvf->java_sender(); }
-  bool            at_end()            { return _jvf == NULL; }
+  virtual void    next()=0;
+  virtual bool    at_end()=0;
 
-  Method* method()                    { return _jvf->method(); }
-  int bci()                           { return _jvf->bci(); }
+  virtual Method* method()=0;
+  virtual int     bci()=0;
+
+  virtual void    fill_frame(int index, objArrayHandle  frames_array,
+                             const methodHandle& method, TRAPS)=0;
 
   void setup_magic_on_entry(objArrayHandle frames_array);
   bool check_magic(objArrayHandle frames_array);
@@ -67,32 +70,72 @@
     return (jlong) castable_address(this);
   }
 
-  static JavaFrameStream* from_current(JavaThread* thread, jlong magic, objArrayHandle frames_array);
+  static BaseFrameStream* from_current(JavaThread* thread, jlong magic, objArrayHandle frames_array);
+};
+
+class JavaFrameStream : public BaseFrameStream {
+private:
+  vframeStream          _vfst;
+  bool                  _need_method_info;
+public:
+  JavaFrameStream(JavaThread* thread, int mode);
+
+  void next()      { _vfst.next();}
+  bool at_end()    { return _vfst.at_end(); }
+
+  Method* method() { return _vfst.method(); }
+  int bci()        { return _vfst.bci(); }
+
+  void fill_frame(int index, objArrayHandle  frames_array,
+                  const methodHandle& method, TRAPS);
+};
+
+class LiveFrameStream : public BaseFrameStream {
+private:
+  javaVFrame*           _jvf;
+
+  void fill_live_stackframe(Handle stackFrame, const methodHandle& method, TRAPS);
+  static oop create_primitive_value_instance(StackValueCollection* values,
+                                             int i, TRAPS);
+  static objArrayHandle monitors_to_object_array(GrowableArray<MonitorInfo*>* monitors,
+                                                 TRAPS);
+  static objArrayHandle values_to_object_array(StackValueCollection* values, TRAPS);
+public:
+  LiveFrameStream(JavaThread* thread, RegisterMap* rm) : BaseFrameStream(thread) {
+    _jvf = thread->last_java_vframe(rm);
+  }
+
+  void next()      { _jvf = _jvf->java_sender(); }
+  bool at_end()    { return _jvf == NULL; }
+
+  Method* method() { return _jvf->method(); }
+  int bci()        { return _jvf->bci(); }
+
+  void fill_frame(int index, objArrayHandle  frames_array,
+                  const methodHandle& method, TRAPS);
 };
 
 class StackWalk : public AllStatic {
 private:
-  static int fill_in_frames(jlong mode, JavaFrameStream& stream,
+  static int fill_in_frames(jlong mode, BaseFrameStream& stream,
                             int max_nframes, int start_index,
                             objArrayHandle frames_array,
                             int& end_index, TRAPS);
 
-  static void fill_stackframe(Handle stackFrame, const methodHandle& method, int bci);
-
-  static void fill_live_stackframe(Handle stackFrame, const methodHandle& method, int bci,
-                                   javaVFrame* jvf, TRAPS);
-
+  static inline bool get_caller_class(int mode) {
+    return (mode & JVM_STACKWALK_GET_CALLER_CLASS) != 0;
+  }
   static inline bool skip_hidden_frames(int mode) {
     return (mode & JVM_STACKWALK_SHOW_HIDDEN_FRAMES) == 0;
   }
-  static inline bool need_method_info(int mode) {
-    return (mode & JVM_STACKWALK_FILL_CLASS_REFS_ONLY) == 0;
-  }
   static inline bool live_frame_info(int mode) {
     return (mode & JVM_STACKWALK_FILL_LIVE_STACK_FRAMES) != 0;
   }
 
 public:
+  static inline bool need_method_info(int mode) {
+    return (mode & JVM_STACKWALK_FILL_CLASS_REFS_ONLY) == 0;
+  }
   static inline bool use_frames_array(int mode) {
     return (mode & JVM_STACKWALK_FILL_CLASS_REFS_ONLY) == 0;
   }
@@ -101,9 +144,12 @@
                   objArrayHandle frames_array,
                   TRAPS);
 
-  static jint moreFrames(Handle stackStream, jlong mode, jlong magic,
-                         int frame_count, int start_index,
-                         objArrayHandle frames_array,
-                         TRAPS);
+  static oop fetchFirstBatch(BaseFrameStream& stream, Handle stackStream,
+                             jlong mode, int skip_frames, int frame_count,
+                             int start_index, objArrayHandle frames_array, TRAPS);
+
+  static jint fetchNextBatch(Handle stackStream, jlong mode, jlong magic,
+                             int frame_count, int start_index,
+                             objArrayHandle frames_array, TRAPS);
 };
 #endif // SHARE_VM_PRIMS_STACKWALK_HPP
--- a/src/share/vm/prims/unsafe.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/prims/unsafe.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -272,6 +272,31 @@
 
 // Get/PutObject must be special-cased, since it works with handles.
 
+// We could be accessing the referent field in a reference
+// object. If G1 is enabled then we need to register non-null
+// referent with the SATB barrier.
+
+#if INCLUDE_ALL_GCS
+static bool is_java_lang_ref_Reference_access(oop o, jlong offset) {
+  if (offset == java_lang_ref_Reference::referent_offset && o != NULL) {
+    Klass* k = o->klass();
+    if (InstanceKlass::cast(k)->reference_type() != REF_NONE) {
+      assert(InstanceKlass::cast(k)->is_subclass_of(SystemDictionary::Reference_klass()), "sanity");
+      return true;
+    }
+  }
+  return false;
+}
+#endif
+
+static void ensure_satb_referent_alive(oop o, jlong offset, oop v) {
+#if INCLUDE_ALL_GCS
+  if (UseG1GC && v != NULL && is_java_lang_ref_Reference_access(o, offset)) {
+    G1SATBCardTableModRefBS::enqueue(v);
+  }
+#endif
+}
+
 // These functions allow a null base pointer with an arbitrary address.
 // But if the base pointer is non-null, the offset should make some sense.
 // That is, it should be in the range [0, MAX_OBJECT_SIZE].
@@ -286,34 +311,9 @@
     v = *(oop*)index_oop_from_field_offset_long(p, offset);
   }
 
-  jobject ret = JNIHandles::make_local(env, v);
+  ensure_satb_referent_alive(p, offset, v);
 
-#if INCLUDE_ALL_GCS
-  // We could be accessing the referent field in a reference
-  // object. If G1 is enabled then we need to register non-null
-  // referent with the SATB barrier.
-  if (UseG1GC) {
-    bool needs_barrier = false;
-
-    if (ret != NULL) {
-      if (offset == java_lang_ref_Reference::referent_offset && obj != NULL) {
-        oop o = JNIHandles::resolve(obj);
-        Klass* k = o->klass();
-        if (InstanceKlass::cast(k)->reference_type() != REF_NONE) {
-          assert(InstanceKlass::cast(k)->is_subclass_of(SystemDictionary::Reference_klass()), "sanity");
-          needs_barrier = true;
-        }
-      }
-    }
-
-    if (needs_barrier) {
-      oop referent = JNIHandles::resolve(ret);
-      G1SATBCardTableModRefBS::enqueue(referent);
-    }
-  }
-#endif // INCLUDE_ALL_GCS
-
-  return ret;
+  return JNIHandles::make_local(env, v);
 } UNSAFE_END
 
 UNSAFE_ENTRY(void, Unsafe_PutObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) {
@@ -344,6 +344,8 @@
     (void)const_cast<oop&>(v = *(volatile oop*) addr);
   }
 
+  ensure_satb_referent_alive(p, offset, v);
+
   OrderAccess::acquire();
   return JNIHandles::make_local(env, v);
 } UNSAFE_END
--- a/src/share/vm/prims/whitebox.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/prims/whitebox.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -894,6 +894,7 @@
   }
   ThreadToNativeFromVM ttnfv(thread);   // can't be in VM when we call JNI
   const char* flag_name = env->GetStringUTFChars(name, NULL);
+  CHECK_JNI_EXCEPTION_(env, false);
   Flag::Error result = (*TAt)(flag_name, value, true, true);
   env->ReleaseStringUTFChars(name, flag_name);
   return (result == Flag::SUCCESS);
@@ -906,6 +907,7 @@
   }
   ThreadToNativeFromVM ttnfv(thread);   // can't be in VM when we call JNI
   const char* flag_name = env->GetStringUTFChars(name, NULL);
+  CHECK_JNI_EXCEPTION_(env, false);
   Flag::Error result = (*TAtPut)(flag_name, value, Flag::INTERNAL);
   env->ReleaseStringUTFChars(name, flag_name);
   return (result == Flag::SUCCESS);
@@ -944,6 +946,7 @@
 static Flag* getVMFlag(JavaThread* thread, JNIEnv* env, jstring name) {
   ThreadToNativeFromVM ttnfv(thread);   // can't be in VM when we call JNI
   const char* flag_name = env->GetStringUTFChars(name, NULL);
+  CHECK_JNI_EXCEPTION_(env, NULL);
   Flag* result = Flag::find_flag(flag_name, strlen(flag_name), true, true);
   env->ReleaseStringUTFChars(name, flag_name);
   return result;
@@ -1084,7 +1087,14 @@
 
 WB_ENTRY(void, WB_SetStringVMFlag(JNIEnv* env, jobject o, jstring name, jstring value))
   ThreadToNativeFromVM ttnfv(thread);   // can't be in VM when we call JNI
-  const char* ccstrValue = (value == NULL) ? NULL : env->GetStringUTFChars(value, NULL);
+  const char* ccstrValue;
+  if (value == NULL) {
+    ccstrValue = NULL;
+  }
+  else {
+    ccstrValue = env->GetStringUTFChars(value, NULL);
+    CHECK_JNI_EXCEPTION(env);
+  }
   ccstr ccstrResult = ccstrValue;
   bool needFree;
   {
@@ -1308,6 +1318,7 @@
   jclass clazz = env->FindClass(vmSymbols::java_lang_Object()->as_C_string());
   CHECK_JNI_EXCEPTION_(env, NULL);
   result = env->NewObjectArray(blobs.length(), clazz, NULL);
+  CHECK_JNI_EXCEPTION_(env, NULL);
   if (result == NULL) {
     return result;
   }
@@ -1317,6 +1328,7 @@
     jobjectArray obj = codeBlob2objectArray(thread, env, *it);
     CHECK_JNI_EXCEPTION_(env, NULL);
     env->SetObjectArrayElement(result, i, obj);
+    CHECK_JNI_EXCEPTION_(env, NULL);
     ++i;
   }
   return result;
@@ -1523,6 +1535,7 @@
   // can't be in VM when we call JNI
   ThreadToNativeFromVM ttnfv(thread);
   const char* flag_name = env->GetStringUTFChars(name, NULL);
+  CHECK_JNI_EXCEPTION_(env, false);
   bool result =  CompilerOracle::has_option_value(mh, flag_name, *value);
   env->ReleaseStringUTFChars(name, flag_name);
   return result;
@@ -1678,6 +1691,7 @@
   // can't be in VM when we call JNI
   ThreadToNativeFromVM ttnfv(thread);
   const char* dir = env->GetStringUTFChars(compDirect, NULL);
+  CHECK_JNI_EXCEPTION_(env, 0);
   int ret;
   {
     ThreadInVMfromNative ttvfn(thread); // back to VM
--- a/src/share/vm/prims/whitebox.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/prims/whitebox.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -33,9 +33,22 @@
 #include "oops/symbol.hpp"
 #include "runtime/interfaceSupport.hpp"
 
+// Unconditionally clear pedantic pending JNI checks
+class ClearPendingJniExcCheck : public StackObj {
+private:
+  JavaThread* _thread;
+public:
+  ClearPendingJniExcCheck(JNIEnv* env) : _thread(JavaThread::thread_from_jni_environment(env)) {}
+  ~ClearPendingJniExcCheck() {
+    _thread->clear_pending_jni_exception_check();
+  }
+};
+
 // Entry macro to transition from JNI to VM state.
 
-#define WB_ENTRY(result_type, header) JNI_ENTRY(result_type, header)
+#define WB_ENTRY(result_type, header) JNI_ENTRY(result_type, header) \
+  ClearPendingJniExcCheck _clearCheck(env);
+
 #define WB_END JNI_END
 #define WB_METHOD_DECLARE(result_type) extern "C" result_type JNICALL
 
--- a/src/share/vm/runtime/arguments.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/runtime/arguments.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -1308,35 +1308,13 @@
   return true;
 }
 
-// sets or adds a module name to the jdk.module.addmods property
-bool Arguments::append_to_addmods_property(const char* module_name) {
-  const char* key = "jdk.module.addmods";
-  const char* old_value = Arguments::get_property(key);
-  size_t buf_len = strlen(key) + strlen(module_name) + 2;
-  if (old_value != NULL) {
-    buf_len += strlen(old_value) + 1;
-  }
-  char* new_value = AllocateHeap(buf_len, mtArguments);
-  if (new_value == NULL) {
-    return false;
-  }
-  if (old_value == NULL) {
-    jio_snprintf(new_value, buf_len, "%s=%s", key, module_name);
-  } else {
-    jio_snprintf(new_value, buf_len, "%s=%s,%s", key, old_value, module_name);
-  }
-  bool added = add_property(new_value, UnwriteableProperty, InternalProperty);
-  FreeHeap(new_value);
-  return added;
-}
-
 #if INCLUDE_CDS
 void Arguments::check_unsupported_dumping_properties() {
   assert(DumpSharedSpaces, "this function is only used with -Xshare:dump");
   const char* unsupported_properties[5] = { "jdk.module.main",
                                            "jdk.module.path",
                                            "jdk.module.upgrade.path",
-                                           "jdk.module.addmods",
+                                           "jdk.module.addmods.0",
                                            "jdk.module.limitmods" };
   const char* unsupported_options[5] = { "-m",
                                         "--module-path",
@@ -1687,11 +1665,6 @@
     CompactibleFreeListSpaceLAB::modify_initialization(OldPLABSize, OldPLABWeight);
   }
 
-  if (!ClassUnloading) {
-    FLAG_SET_CMDLINE(bool, CMSClassUnloadingEnabled, false);
-    FLAG_SET_CMDLINE(bool, ExplicitGCInvokesConcurrentAndUnloadsClasses, false);
-  }
-
   log_trace(gc)("MarkStackSize: %uk  MarkStackSizeMax: %uk", (unsigned int) (MarkStackSize / K), (uint) (MarkStackSizeMax / K));
 }
 #endif // INCLUDE_ALL_GCS
@@ -2019,6 +1992,13 @@
     // Keeping the heap 100% free is hard ;-) so limit it to 99%.
     FLAG_SET_ERGO(uintx, MinHeapFreeRatio, 99);
   }
+
+  // If class unloading is disabled, also disable concurrent class unloading.
+  if (!ClassUnloading) {
+    FLAG_SET_CMDLINE(bool, CMSClassUnloadingEnabled, false);
+    FLAG_SET_CMDLINE(bool, ClassUnloadingWithConcurrentMark, false);
+    FLAG_SET_CMDLINE(bool, ExplicitGCInvokesConcurrentAndUnloadsClasses, false);
+  }
 #endif // INCLUDE_ALL_GCS
 }
 
@@ -2566,8 +2546,8 @@
 
 unsigned int addreads_count = 0;
 unsigned int addexports_count = 0;
+unsigned int addmods_count = 0;
 unsigned int patch_mod_count = 0;
-const char* add_modules_value = NULL;
 
 bool Arguments::create_property(const char* prop_name, const char* prop_value, PropertyInternal internal) {
   size_t prop_len = strlen(prop_name) + strlen(prop_value) + 2;
@@ -2821,7 +2801,9 @@
         return JNI_ENOMEM;
       }
     } else if (match_option(option, "--add-modules=", &tail)) {
-      add_modules_value = tail;
+      if (!create_numbered_property("jdk.module.addmods", tail, addmods_count++)) {
+        return JNI_ENOMEM;
+      }
     } else if (match_option(option, "--limit-modules=", &tail)) {
       if (!create_property("jdk.module.limitmods", tail, InternalProperty)) {
         return JNI_ENOMEM;
@@ -2873,7 +2855,7 @@
         char *options = strcpy(NEW_C_HEAP_ARRAY(char, strlen(tail) + 1, mtArguments), tail);
         add_init_agent("instrument", options, false);
         // java agents need module java.instrument
-        if (!Arguments::append_to_addmods_property("java.instrument")) {
+        if (!create_numbered_property("jdk.module.addmods", "java.instrument", addmods_count++)) {
           return JNI_ENOMEM;
         }
       }
@@ -3149,7 +3131,7 @@
           return JNI_EINVAL;
         }
         // management agent in module java.management
-        if (!Arguments::append_to_addmods_property("java.management")) {
+        if (!create_numbered_property("jdk.module.addmods", "java.management", addmods_count++)) {
           return JNI_ENOMEM;
         }
 #else
@@ -3560,15 +3542,6 @@
     return JNI_ERR;
   }
 
-  // Append the value of the last --add-modules option specified on the command line.
-  // This needs to be done here, to prevent overwriting possible values written
-  // to the jdk.module.addmods property by -javaagent and other options.
-  if (add_modules_value != NULL) {
-    if (!append_to_addmods_property(add_modules_value)) {
-      return JNI_ENOMEM;
-    }
-  }
-
   // This must be done after all arguments have been processed.
   // java_compiler() true means set to "NONE" or empty.
   if (java_compiler() && !xdebug_mode()) {
@@ -3617,7 +3590,8 @@
 #endif
 
 #if INCLUDE_JVMCI
-  if (EnableJVMCI && !append_to_addmods_property("jdk.vm.ci")) {
+  if (EnableJVMCI &&
+      !create_numbered_property("jdk.module.addmods", "jdk.vm.ci", addmods_count++)) {
     return JNI_ENOMEM;
   }
 #endif
@@ -3923,10 +3897,6 @@
 
 void Arguments::set_shared_spaces_flags() {
   if (DumpSharedSpaces) {
-    if (Arguments::get_patch_mod_prefix() != NULL) {
-      vm_exit_during_initialization(
-        "Cannot use the following option when dumping the shared archive: --patch-module");
-    }
 
     if (RequireSharedSpaces) {
       warning("Cannot dump shared archive while using shared archive");
--- a/src/share/vm/runtime/arguments.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/runtime/arguments.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -489,9 +489,6 @@
 
   static int process_patch_mod_option(const char* patch_mod_tail, bool* patch_mod_javabase);
 
-  // Miscellaneous system property setter
-  static bool append_to_addmods_property(const char* module_name);
-
   // Aggressive optimization flags.
   static jint set_aggressive_opts_flags();
 
--- a/src/share/vm/runtime/globals.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/runtime/globals.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -1596,6 +1596,10 @@
   product(bool, AlwaysPreTouch, false,                                      \
           "Force all freshly committed pages to be pre-touched")            \
                                                                             \
+  product(size_t, PreTouchParallelChunkSize, 1 * G,                         \
+          "Per-thread chunk size for parallel memory pre-touch.")           \
+          range(1, SIZE_MAX / 2)                                            \
+                                                                            \
   product_pd(size_t, CMSYoungGenPerWorker,                                  \
           "The maximum size of young gen chosen by default per GC worker "  \
           "thread available")                                               \
--- a/src/share/vm/runtime/interfaceSupport.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/runtime/interfaceSupport.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -280,6 +280,7 @@
 
   ~ThreadToNativeFromVM() {
     trans_from_native(_thread_in_vm);
+    assert(!_thread->is_pending_jni_exception_check(), "Pending JNI Exception Check");
     // We don't need to clear_walkable because it will happen automagically when we return to java
   }
 };
--- a/src/share/vm/runtime/mutexLocker.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/runtime/mutexLocker.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -77,6 +77,8 @@
 Mutex*   DirtyCardQ_FL_lock           = NULL;
 Monitor* DirtyCardQ_CBL_mon           = NULL;
 Mutex*   Shared_DirtyCardQ_lock       = NULL;
+Mutex*   MarkStackFreeList_lock       = NULL;
+Mutex*   MarkStackChunkList_lock      = NULL;
 Mutex*   ParGCRareEvent_lock          = NULL;
 Mutex*   DerivedPointerTableGC_lock   = NULL;
 Mutex*   Compile_lock                 = NULL;
@@ -194,6 +196,9 @@
 
     def(StringDedupQueue_lock      , Monitor, leaf,        true,  Monitor::_safepoint_check_never);
     def(StringDedupTable_lock      , Mutex  , leaf,        true,  Monitor::_safepoint_check_never);
+
+    def(MarkStackFreeList_lock     , Mutex , leaf      ,   true,  Monitor::_safepoint_check_never);
+    def(MarkStackChunkList_lock    , Mutex , leaf      ,   true,  Monitor::_safepoint_check_never);
   }
   def(ParGCRareEvent_lock          , Mutex  , leaf     ,   true,  Monitor::_safepoint_check_sometimes);
   def(DerivedPointerTableGC_lock   , Mutex,   leaf,        true,  Monitor::_safepoint_check_never);
--- a/src/share/vm/runtime/mutexLocker.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/runtime/mutexLocker.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -81,7 +81,8 @@
 extern Mutex*   Shared_DirtyCardQ_lock;          // Lock protecting dirty card
                                                  // queue shared by
                                                  // non-Java threads.
-                                                 // (see option ExplicitGCInvokesConcurrent)
+extern Mutex*   MarkStackFreeList_lock;          // Protects access to the global mark stack free list.
+extern Mutex*   MarkStackChunkList_lock;         // Protects access to the global mark stack chunk list.
 extern Mutex*   ParGCRareEvent_lock;             // Synchronizes various (rare) parallel GC ops.
 extern Mutex*   Compile_lock;                    // a lock held when Compilation is updating code (used to block CodeCache traversal, CHA updates, etc)
 extern Monitor* MethodCompileQueue_lock;         // a lock held when method compilations are enqueued, dequeued
--- a/src/share/vm/runtime/os.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/runtime/os.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -1705,8 +1705,8 @@
   return res;
 }
 
-void os::pretouch_memory(void* start, void* end) {
-  for (volatile char *p = (char*)start; p < (char*)end; p += os::vm_page_size()) {
+void os::pretouch_memory(void* start, void* end, size_t page_size) {
+  for (volatile char *p = (char*)start; p < (char*)end; p += page_size) {
     *p = 0;
   }
 }
--- a/src/share/vm/runtime/os.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/runtime/os.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -324,7 +324,7 @@
   // to make the OS back the memory range with actual memory.
   // Current implementation may not touch the last page if unaligned addresses
   // are passed.
-  static void   pretouch_memory(void* start, void* end);
+  static void   pretouch_memory(void* start, void* end, size_t page_size = vm_page_size());
 
   enum ProtType { MEM_PROT_NONE, MEM_PROT_READ, MEM_PROT_RW, MEM_PROT_RWX };
   static bool   protect_memory(char* addr, size_t bytes, ProtType prot,
@@ -443,7 +443,7 @@
 
   static bool create_thread(Thread* thread,
                             ThreadType thr_type,
-                            size_t stack_size = 0);
+                            size_t req_stack_size = 0);
   static bool create_main_thread(JavaThread* thread);
   static bool create_attached_thread(JavaThread* thread);
   static void pd_start_thread(Thread* thread);
--- a/src/share/vm/runtime/thread.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/runtime/thread.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -1542,6 +1542,9 @@
   static ByteSize jmp_ring_offset()              { return byte_offset_of(JavaThread, _jmp_ring); }
 #endif // PRODUCT
   static ByteSize jni_environment_offset()       { return byte_offset_of(JavaThread, _jni_environment); }
+  static ByteSize pending_jni_exception_check_fn_offset() {
+    return byte_offset_of(JavaThread, _pending_jni_exception_check_fn);
+  }
   static ByteSize last_Java_sp_offset() {
     return byte_offset_of(JavaThread, _anchor) + JavaFrameAnchor::last_Java_sp_offset();
   }
@@ -1615,7 +1618,11 @@
     assert(_jni_active_critical >= 0, "JNI critical nesting problem?");
   }
 
-  // Checked JNI, is the programmer required to check for exceptions, specify which function name
+  // Checked JNI: is the programmer required to check for exceptions, if so specify
+  // which function name. Returning to a Java frame should implicitly clear the
+  // pending check, this is done for Native->Java transitions (i.e. user JNI code).
+  // VM->Java transistions are not cleared, it is expected that JNI code enclosed
+  // within ThreadToNativeFromVM makes proper exception checks (i.e. VM internal).
   bool is_pending_jni_exception_check() const { return _pending_jni_exception_check_fn != NULL; }
   void clear_pending_jni_exception_check() { _pending_jni_exception_check_fn = NULL; }
   const char* get_pending_jni_exception_check() const { return _pending_jni_exception_check_fn; }
--- a/src/share/vm/runtime/vmStructs.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/runtime/vmStructs.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -2970,6 +2970,7 @@
 
 #if INCLUDE_ALL_GCS
   VM_STRUCTS_PARALLELGC(GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
+                        GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
                         GENERATE_STATIC_VM_STRUCT_ENTRY)
 
   VM_STRUCTS_CMS(GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
@@ -2982,7 +2983,7 @@
 
 #if INCLUDE_TRACE
   VM_STRUCTS_TRACE(GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
-                GENERATE_STATIC_VM_STRUCT_ENTRY)
+                   GENERATE_STATIC_VM_STRUCT_ENTRY)
 #endif
 
   VM_STRUCTS_EXT(GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
@@ -3168,11 +3169,12 @@
 
 #if INCLUDE_ALL_GCS
   VM_STRUCTS_PARALLELGC(CHECK_NONSTATIC_VM_STRUCT_ENTRY,
-             CHECK_STATIC_VM_STRUCT_ENTRY);
+                        CHECK_VOLATILE_NONSTATIC_VM_STRUCT_ENTRY,
+                        CHECK_STATIC_VM_STRUCT_ENTRY);
 
   VM_STRUCTS_CMS(CHECK_NONSTATIC_VM_STRUCT_ENTRY,
-             CHECK_VOLATILE_NONSTATIC_VM_STRUCT_ENTRY,
-             CHECK_STATIC_VM_STRUCT_ENTRY);
+                 CHECK_VOLATILE_NONSTATIC_VM_STRUCT_ENTRY,
+                 CHECK_STATIC_VM_STRUCT_ENTRY);
 
   VM_STRUCTS_G1(CHECK_NONSTATIC_VM_STRUCT_ENTRY,
                 CHECK_STATIC_VM_STRUCT_ENTRY);
@@ -3181,7 +3183,7 @@
 
 #if INCLUDE_TRACE
   VM_STRUCTS_TRACE(CHECK_NONSTATIC_VM_STRUCT_ENTRY,
-                CHECK_STATIC_VM_STRUCT_ENTRY);
+                   CHECK_STATIC_VM_STRUCT_ENTRY);
 #endif
 
   VM_STRUCTS_EXT(CHECK_NONSTATIC_VM_STRUCT_ENTRY,
@@ -3293,6 +3295,7 @@
                         CHECK_NO_OP));
 #if INCLUDE_ALL_GCS
   debug_only(VM_STRUCTS_PARALLELGC(ENSURE_FIELD_TYPE_PRESENT,
+                                   ENSURE_FIELD_TYPE_PRESENT,
                                    ENSURE_FIELD_TYPE_PRESENT));
   debug_only(VM_STRUCTS_CMS(ENSURE_FIELD_TYPE_PRESENT,
                             ENSURE_FIELD_TYPE_PRESENT,
--- a/src/share/vm/trace/traceevents.xml	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/trace/traceevents.xml	Wed Sep 21 08:38:21 2016 +0000
@@ -315,9 +315,9 @@
 
   <event id="G1MMU" path="vm/gc/detailed/g1_mmu_info" label="G1 MMU Information" is_instant="true">
     <value type="UINT" field="gcId" label="GC Identifier" relation="GcId"/>
-    <value type="DOUBLE" field="timeSlice" label="Time Slice" description="Time slice used to calculate MMU"/>
-    <value type="DOUBLE" field="gcTime" label="GC Time" description="Time spent on GC during last time slice"/>
-    <value type="DOUBLE" field="maxGcTime" label="Max GC Time" description="Max time allowed to be spent on GC during last time slice"/>
+    <value type="MILLIS" field="timeSlice" label="Time Slice" description="Time slice used to calculate MMU"/>
+    <value type="MILLIS" field="gcTime" label="GC Time" description="Time stopped because of GC during last time slice"/>
+    <value type="MILLIS" field="pauseTarget" label="Pause Target" description="Max time allowed to be spent on GC during last time slice"/>
   </event>
 
   <event id="EvacuationInformation" path="vm/gc/detailed/evacuation_info" label="Evacuation Information" is_instant="true">
@@ -377,29 +377,29 @@
     <structvalue type="G1EvacuationStatistics" field="statistics" label="Evacuation Statistics"/>
   </event>
 
-  <event id="G1BasicIHOP" path="vm/gc/detailed/g1_basic_ihop_status" label="G1 Basic IHOP statistics"
+  <event id="G1BasicIHOP" path="vm/gc/detailed/g1_basic_ihop_status" label="G1 Basic IHOP Statistics"
          is_instant="true" description="Basic statistics related to current IHOP calculation">
     <value type="UINT" field="gcId" label="GC Identifier" relation="GcId"/>
-    <value type="BYTES64" field="threshold" label="Current IHOP threshold" description="Current IHOP threshold in bytes"/>
-    <value type="PERCENTAGE" field="thresholdPercentage" label="Current IHOP threshold in percent" description="Current IHOP threshold in percent of old gen"/>
-    <value type="BYTES64" field="targetOccupancy" label="Target Occupancy" description="Target old gen occupancy to reach at the start of mixed GC in bytes"/>
-    <value type="BYTES64" field="currentOccupancy" label="Current Occupancy" description="Current old generation occupancy in bytes"/>
-    <value type="BYTES64" field="lastAllocationSize" label="Last Mutator Allocation" description="Mutator allocation during mutator operation since last GC in bytes"/>
-    <value type="DOUBLE" field="lastAllocationDuration" label="Last Mutator Operation" description="Time the mutator ran since last GC in seconds"/>
-    <value type="DOUBLE" field="lastAllocationRate" label="Last Mutator Allocation Rate" description="Allocation rate of the mutator since last GC in bytes/second"/>
-    <value type="DOUBLE" field="lastMarkingLength" label="Last Marking Length" description="Last time from the end of the last initial mark to the first mixed GC in seconds"/>
+    <value type="BYTES64" field="threshold" label="Current IHOP Threshold" description="Current IHOP threshold"/>
+    <value type="PERCENTAGE" field="thresholdPercentage" label="Current IHOP Threshold" description="Current IHOP threshold in percent of old generation"/>
+    <value type="BYTES64" field="targetOccupancy" label="Target Occupancy" description="Target old generation occupancy to reach at the start of mixed GC"/>
+    <value type="BYTES64" field="currentOccupancy" label="Current Occupancy" description="Current old generation occupancy"/>
+    <value type="BYTES64" field="recentMutatorAllocationSize" label="Recent Mutator Allocation Size" description="Mutator allocation during mutator operation in the most recent interval"/>
+    <value type="MILLIS" field="recentMutatorDuration" label="Recent Mutator Duration" description="Time the mutator ran in the most recent interval"/>
+    <value type="DOUBLE" field="recentAllocationRate" label="Recent Allocation Rate" description="Allocation rate of the mutator in the most recent interval in bytes/second"/>
+    <value type="MILLIS" field="lastMarkingDuration" label="Last Marking Duration" description="Last time from the end of the last initial mark to the first mixed GC"/>
   </event>
 
-  <event id="G1AdaptiveIHOP" path="vm/gc/detailed/g1_adaptive_ihop_status" label="G1 Adaptive IHOP statistics"
+  <event id="G1AdaptiveIHOP" path="vm/gc/detailed/g1_adaptive_ihop_status" label="G1 Adaptive IHOP Statistics"
          is_instant="true" description="Statistics related to current adaptive IHOP calculation">
     <value type="UINT" field="gcId" label="GC Identifier" relation="GcId"/>
-    <value type="BYTES64" field="threshold" label="Threshold" description="Current IHOP threshold in bytes"/>
-    <value type="PERCENTAGE" field="thresholdPercentage" label="Threshold Percentage" description="Current IHOP threshold in percent of the internal target occupancy"/>
-    <value type="BYTES64" field="internalTargetOccupancy" label="Target Occupancy" description="Internal target old generation occupancy to reach at the start of mixed GC in bytes"/>
-    <value type="BYTES64" field="currentOccupancy" label="Current Occupancy" description="Current old generation occupancy in bytes"/>
-    <value type="BYTES64" field="additionalBufferSize" label="Additional Buffer" description="Additional buffer size in bytes"/>
+    <value type="BYTES64" field="threshold" label="Threshold" description="Current IHOP Threshold"/>
+    <value type="PERCENTAGE" field="thresholdPercentage" label="Threshold" description="Current IHOP threshold in percent of the internal target occupancy"/>
+    <value type="BYTES64" field="ihopTargetOccupancy" label="IHOP Target Occupancy" description="Internal target old generation occupancy to reach at the start of mixed GC"/>
+    <value type="BYTES64" field="currentOccupancy" label="Current Occupancy" description="Current old generation occupancy"/>
+    <value type="BYTES64" field="additionalBufferSize" label="Additional Buffer" description="Additional buffer size" experimental="true"/>
     <value type="DOUBLE" field="predictedAllocationRate" label="Predicted Allocation Rate" description="Current predicted allocation rate for the mutator in bytes/second"/>
-    <value type="DOUBLE" field="predictedMarkingLength" label="Predicted Marking Length" description="Current predicted time from the end of the last initial mark to the first mixed GC in seconds"/>
+    <value type="MILLIS" field="predictedMarkingDuration" label="Predicted Marking Duration" description="Current predicted time from the end of the last initial mark to the first mixed GC"/>
     <value type="BOOLEAN" field="predictionActive" label="Prediction Active" description="Indicates whether the adaptive IHOP prediction is active"/>
   </event>
 
--- a/src/share/vm/utilities/debug.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/utilities/debug.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -282,6 +282,12 @@
 }
 
 void report_out_of_shared_space(SharedSpaceType shared_space) {
+  if (shared_space == SharedOptional) {
+    // The estimated shared_optional_space size is large enough
+    // for all class bytes.  It should not run out of space.
+    ShouldNotReachHere();
+  }
+
   static const char* name[] = {
     "shared read only space",
     "shared read write space",
--- a/src/share/vm/utilities/debug.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/utilities/debug.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -271,7 +271,8 @@
   SharedReadOnly,
   SharedReadWrite,
   SharedMiscData,
-  SharedMiscCode
+  SharedMiscCode,
+  SharedOptional
 };
 
 void report_out_of_shared_space(SharedSpaceType space_type);
--- a/src/share/vm/utilities/exceptions.cpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/utilities/exceptions.cpp	Wed Sep 21 08:38:21 2016 +0000
@@ -80,7 +80,7 @@
   if (h_exception()->klass() == SystemDictionary::StackOverflowError_klass()) {
     InstanceKlass* ik = InstanceKlass::cast(h_exception->klass());
     assert(ik->is_initialized(),
-           "need to increase min_stack_allowed calculation");
+           "need to increase java_thread_min_stack_allowed calculation");
   }
 #endif // ASSERT
 
@@ -227,7 +227,7 @@
     Klass* k = SystemDictionary::StackOverflowError_klass();
     oop e = InstanceKlass::cast(k)->allocate_instance(CHECK);
     exception = Handle(THREAD, e);  // fill_in_stack trace does gc
-    assert(InstanceKlass::cast(k)->is_initialized(), "need to increase min_stack_allowed calculation");
+    assert(InstanceKlass::cast(k)->is_initialized(), "need to increase java_thread_min_stack_allowed calculation");
     if (StackTraceInThrowable) {
       java_lang_Throwable::fill_in_stack_trace(exception, method());
     }
--- a/src/share/vm/utilities/globalDefinitions_xlc.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/utilities/globalDefinitions_xlc.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -186,6 +186,6 @@
 
 // Inlining support
 #define NOINLINE
-#define ALWAYSINLINE __attribute__((always_inline))
+#define ALWAYSINLINE inline __attribute__((always_inline))
 
 #endif // SHARE_VM_UTILITIES_GLOBALDEFINITIONS_XLC_HPP
--- a/src/share/vm/utilities/hashtable.inline.hpp	Wed Sep 21 01:33:21 2016 -0700
+++ b/src/share/vm/utilities/hashtable.inline.hpp	Wed Sep 21 08:38:21 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -79,8 +79,8 @@
 
 
 template <MEMFLAGS F> inline void HashtableBucket<F>::set_entry(BasicHashtableEntry<F>* l) {
-  // Warning: Preserve store ordering.  The SystemDictionary is read
-  //          without locks.  The new SystemDictionaryEntry must be
+  // Warning: Preserve store ordering.  The PackageEntryTable, ModuleEntryTable and
+  //          SystemDictionary are read without locks.  The new entry must be
   //          complete before other threads can be allowed to see it
   //          via a store to _buckets[index].
   OrderAccess::release_store_ptr(&_entry, l);
@@ -88,8 +88,8 @@
 
 
 template <MEMFLAGS F> inline BasicHashtableEntry<F>* HashtableBucket<F>::get_entry() const {
-  // Warning: Preserve load ordering.  The SystemDictionary is read
-  //          without locks.  The new SystemDictionaryEntry must be
+  // Warning: Preserve load ordering.  The PackageEntryTable, ModuleEntryTable and
+  //          SystemDictionary are read without locks.  The new entry must be
   //          complete before other threads can be allowed to see it
   //          via a store to _buckets[index].
   return (BasicHashtableEntry<F>*) OrderAccess::load_ptr_acquire(&_entry);
--- a/test/compiler/c2/Test6968348.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/compiler/c2/Test6968348.java	Wed Sep 21 08:38:21 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -38,15 +38,11 @@
 import java.lang.reflect.Field;
 
 public class Test6968348 {
-    static Unsafe unsafe;
+    static Unsafe unsafe = Unsafe.getUnsafe();
     static final long[] buffer = new long[4096];
     static int array_long_base_offset;
 
     public static void main(String[] args) throws Exception {
-        Class c = Test6968348.class.getClassLoader().loadClass("jdk.internal.misc.Unsafe");
-        Field f = c.getDeclaredField("theUnsafe");
-        f.setAccessible(true);
-        unsafe = (Unsafe)f.get(c);
         array_long_base_offset = unsafe.arrayBaseOffset(long[].class);
 
         for (int n = 0; n < 100000; n++) {
--- a/test/compiler/c2/cr8004867/TestIntUnsafeCAS.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/compiler/c2/cr8004867/TestIntUnsafeCAS.java	Wed Sep 21 08:38:21 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -50,14 +50,10 @@
   private static final int ALIGN_OFF = 8;
   private static final int UNALIGN_OFF = 5;
 
-  private static final Unsafe unsafe;
+  private static final Unsafe unsafe = Unsafe.getUnsafe();
   private static final int BASE;
   static {
     try {
-      Class c = TestIntUnsafeCAS.class.getClassLoader().loadClass("jdk.internal.misc.Unsafe");
-      Field f = c.getDeclaredField("theUnsafe");
-      f.setAccessible(true);
-      unsafe = (Unsafe)f.get(c);
       BASE = unsafe.arrayBaseOffset(int[].class);
     } catch (Exception e) {
       InternalError err = new InternalError();
--- a/test/compiler/c2/cr8004867/TestIntUnsafeOrdered.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/compiler/c2/cr8004867/TestIntUnsafeOrdered.java	Wed Sep 21 08:38:21 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -50,14 +50,10 @@
   private static final int ALIGN_OFF = 8;
   private static final int UNALIGN_OFF = 5;
 
-  private static final Unsafe unsafe;
+  private static final Unsafe unsafe = Unsafe.getUnsafe();
   private static final int BASE;
   static {
     try {
-      Class<?> c = Unsafe.class;
-      Field f = c.getDeclaredField("theUnsafe");
-      f.setAccessible(true);
-      unsafe = (Unsafe) f.get(c);
       BASE = unsafe.arrayBaseOffset(int[].class);
     } catch (Exception e) {
       InternalError err = new InternalError();
--- a/test/compiler/c2/cr8004867/TestIntUnsafeVolatile.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/compiler/c2/cr8004867/TestIntUnsafeVolatile.java	Wed Sep 21 08:38:21 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -50,14 +50,10 @@
   private static final int ALIGN_OFF = 8;
   private static final int UNALIGN_OFF = 5;
 
-  private static final Unsafe unsafe;
+  private static final Unsafe unsafe = Unsafe.getUnsafe();
   private static final int BASE;
   static {
     try {
-      Class c = TestIntUnsafeVolatile.class.getClassLoader().loadClass("jdk.internal.misc.Unsafe");
-      Field f = c.getDeclaredField("theUnsafe");
-      f.setAccessible(true);
-      unsafe = (Unsafe)f.get(c);
       BASE = unsafe.arrayBaseOffset(int[].class);
     } catch (Exception e) {
       InternalError err = new InternalError();
--- a/test/compiler/cpuflags/AESIntrinsicsBase.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/compiler/cpuflags/AESIntrinsicsBase.java	Wed Sep 21 08:38:21 2016 +0000
@@ -48,8 +48,8 @@
             = {"-XX:+UnlockDiagnosticVMOptions", "-XX:+PrintIntrinsics"};
     public static final String[] TEST_AES_CMD
             = {"-XX:+IgnoreUnrecognizedVMOptions", "-XX:+PrintFlagsFinal",
-            "-Xbatch", "-DcheckOutput=true", "-Dmode=CBC",
-            TestAESMain.class.getName()};
+            "-Xbatch", "-XX:CompileThresholdScaling=0.01", "-DcheckOutput=true", "-Dmode=CBC",
+            TestAESMain.class.getName(), "100", "1000"};
 
     protected AESIntrinsicsBase(BooleanSupplier predicate) {
         super(predicate);
--- a/test/compiler/cpuflags/TestAESIntrinsicsOnSupportedConfig.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/compiler/cpuflags/TestAESIntrinsicsOnSupportedConfig.java	Wed Sep 21 08:38:21 2016 +0000
@@ -27,11 +27,11 @@
  * @library /test/lib /
  * @modules java.base/jdk.internal.misc
  *          java.management
- * @ignore 8146128
  * @build sun.hotspot.WhiteBox
  * @run driver ClassFileInstaller sun.hotspot.WhiteBox
  *                                sun.hotspot.WhiteBox$WhiteBoxPermission
- * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * @run main/othervm/timeout=600 -Xbootclasspath/a:.
+ *                   -XX:+UnlockDiagnosticVMOptions
  *                   -XX:+WhiteBoxAPI -Xbatch
  *                   compiler.cpuflags.TestAESIntrinsicsOnSupportedConfig
  */
--- a/test/compiler/intrinsics/unsafe/TestUnsafeMismatchedArrayFieldAccess.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/compiler/intrinsics/unsafe/TestUnsafeMismatchedArrayFieldAccess.java	Wed Sep 21 08:38:21 2016 +0000
@@ -27,7 +27,6 @@
  * @bug 8142386
  * @summary Unsafe access to an array is wrongly marked as mismatched
  * @modules java.base/jdk.internal.misc
- * @library /test/lib
  *
  * @run main/othervm -XX:-UseOnStackReplacement -XX:-BackgroundCompilation -XX:-TieredCompilation
  *      compiler.intrinsics.unsafe.TestUnsafeMismatchedArrayFieldAccess
@@ -36,11 +35,10 @@
 package compiler.intrinsics.unsafe;
 
 import jdk.internal.misc.Unsafe;
-import jdk.test.lib.unsafe.UnsafeHelper;
 
 public class TestUnsafeMismatchedArrayFieldAccess {
 
-    private static final Unsafe UNSAFE = UnsafeHelper.getUnsafe();
+    private static final Unsafe UNSAFE = Unsafe.getUnsafe();
 
     static {
         try {
--- a/test/compiler/jvmci/compilerToVM/GetResolvedJavaMethodTest.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/compiler/jvmci/compilerToVM/GetResolvedJavaMethodTest.java	Wed Sep 21 08:38:21 2016 +0000
@@ -45,7 +45,6 @@
 
 import jdk.internal.misc.Unsafe;
 import jdk.test.lib.Asserts;
-import jdk.test.lib.unsafe.UnsafeHelper;
 import jdk.vm.ci.hotspot.CompilerToVMHelper;
 import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
 import jdk.vm.ci.hotspot.PublicMetaspaceWrapperObject;
@@ -114,7 +113,7 @@
         abstract HotSpotResolvedJavaMethod getResolvedJavaMethod();
     }
 
-    private static final Unsafe UNSAFE = UnsafeHelper.getUnsafe();
+    private static final Unsafe UNSAFE = Unsafe.getUnsafe();
     private static final WhiteBox WB = WhiteBox.getWhiteBox();
     private static final Field METASPACE_METHOD_FIELD;
     private static final Class<?> TEST_CLASS = GetResolvedJavaMethodTest.class;
--- a/test/compiler/jvmci/compilerToVM/GetResolvedJavaTypeTest.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/compiler/jvmci/compilerToVM/GetResolvedJavaTypeTest.java	Wed Sep 21 08:38:21 2016 +0000
@@ -53,7 +53,6 @@
 
 import jdk.internal.misc.Unsafe;
 import jdk.test.lib.Asserts;
-import jdk.test.lib.unsafe.UnsafeHelper;
 import jdk.vm.ci.hotspot.CompilerToVMHelper;
 import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
 import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
@@ -154,7 +153,7 @@
         abstract HotSpotResolvedObjectType getResolvedJavaType();
     }
 
-    private static final Unsafe UNSAFE = UnsafeHelper.getUnsafe();
+    private static final Unsafe UNSAFE = Unsafe.getUnsafe();
     private static final WhiteBox WB = WhiteBox.getWhiteBox();
     private static final Class TEST_CLASS = GetResolvedJavaTypeTest.class;
     /* a compressed parameter for tested method is set to false because
--- a/test/compiler/jvmci/compilerToVM/ResolveFieldInPoolTest.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/compiler/jvmci/compilerToVM/ResolveFieldInPoolTest.java	Wed Sep 21 08:38:21 2016 +0000
@@ -53,7 +53,6 @@
 import jdk.internal.misc.Unsafe;
 import jdk.internal.org.objectweb.asm.Opcodes;
 import jdk.test.lib.Asserts;
-import jdk.test.lib.unsafe.UnsafeHelper;
 import jdk.vm.ci.hotspot.CompilerToVMHelper;
 import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
 import jdk.vm.ci.meta.ConstantPool;
@@ -69,7 +68,7 @@
  */
 public class ResolveFieldInPoolTest {
 
-    private static final Unsafe UNSAFE = UnsafeHelper.getUnsafe();
+    private static final Unsafe UNSAFE = Unsafe.getUnsafe();
 
     public static void main(String[] args) throws Exception {
         Map<ConstantTypes, Validator> typeTests = new HashMap<>();
--- a/test/compiler/jvmci/compilerToVM/ResolveMethodTest.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/compiler/jvmci/compilerToVM/ResolveMethodTest.java	Wed Sep 21 08:38:21 2016 +0000
@@ -52,7 +52,6 @@
 import jdk.internal.misc.Unsafe;
 import jdk.test.lib.Asserts;
 import jdk.test.lib.Utils;
-import jdk.test.lib.unsafe.UnsafeHelper;
 import jdk.vm.ci.hotspot.CompilerToVMHelper;
 import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
 import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
@@ -61,7 +60,7 @@
 import java.util.Set;
 
 public class ResolveMethodTest {
-    private static final Unsafe UNSAFE = UnsafeHelper.getUnsafe();
+    private static final Unsafe UNSAFE = Unsafe.getUnsafe();
 
     public static void main(String args[]) {
         ResolveMethodTest test = new ResolveMethodTest();
--- a/test/compiler/loopopts/superword/TestVectorizationWithInvariant.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/compiler/loopopts/superword/TestVectorizationWithInvariant.java	Wed Sep 21 08:38:21 2016 +0000
@@ -34,7 +34,6 @@
 package compiler.loopopts.superword;
 
 import jdk.internal.misc.Unsafe;
-import jdk.test.lib.unsafe.UnsafeHelper;
 
 public class TestVectorizationWithInvariant {
 
@@ -43,7 +42,7 @@
     private static final long CHAR_ARRAY_OFFSET;
 
     static {
-        unsafe = UnsafeHelper.getUnsafe();
+        unsafe = Unsafe.getUnsafe();
         BYTE_ARRAY_OFFSET = unsafe.arrayBaseOffset(byte[].class);
         CHAR_ARRAY_OFFSET = unsafe.arrayBaseOffset(char[].class);
     }
--- a/test/compiler/rtm/locking/TestRTMAbortRatio.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/compiler/rtm/locking/TestRTMAbortRatio.java	Wed Sep 21 08:38:21 2016 +0000
@@ -49,7 +49,6 @@
 import jdk.internal.misc.Unsafe;
 import jdk.test.lib.Asserts;
 import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.unsafe.UnsafeHelper;
 import jdk.test.lib.cli.CommandLineOptionTest;
 import jdk.test.lib.cli.predicate.AndPredicate;
 
@@ -125,7 +124,7 @@
     public static class Test implements CompilableTest {
         private static final int TOTAL_ITERATIONS = 10000;
         private static final int WARMUP_ITERATIONS = 1000;
-        private static final Unsafe UNSAFE = UnsafeHelper.getUnsafe();
+        private static final Unsafe UNSAFE = Unsafe.getUnsafe();
         private final Object monitor = new Object();
         // Following field have to be static in order to avoid escape analysis.
         @SuppressWarnings("UnsuedDeclaration")
--- a/test/compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java	Wed Sep 21 08:38:21 2016 +0000
@@ -51,7 +51,6 @@
 import jdk.internal.misc.Unsafe;
 import jdk.test.lib.Asserts;
 import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.unsafe.UnsafeHelper;
 import jdk.test.lib.cli.CommandLineOptionTest;
 import jdk.test.lib.cli.predicate.AndPredicate;
 
@@ -158,7 +157,7 @@
         private static int field = 0;
         private static final int ITERATIONS = 10000;
         private static final int RANGE_CHECK_AT = ITERATIONS / 2;
-        private static final Unsafe UNSAFE = UnsafeHelper.getUnsafe();
+        private static final Unsafe UNSAFE = Unsafe.getUnsafe();
         private final Object monitor = new Object();
 
         @Override
--- a/test/compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java	Wed Sep 21 08:38:21 2016 +0000
@@ -48,7 +48,6 @@
 import jdk.internal.misc.Unsafe;
 import jdk.test.lib.Asserts;
 import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.unsafe.UnsafeHelper;
 import jdk.test.lib.cli.CommandLineOptionTest;
 import jdk.test.lib.cli.predicate.AndPredicate;
 
@@ -133,7 +132,7 @@
     }
 
     public static class Test implements CompilableTest {
-        private static final Unsafe UNSAFE = UnsafeHelper.getUnsafe();
+        private static final Unsafe UNSAFE = Unsafe.getUnsafe();
         private final Object monitor = new Object();
 
         @Override
--- a/test/compiler/rtm/locking/TestRTMLockingThreshold.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/compiler/rtm/locking/TestRTMLockingThreshold.java	Wed Sep 21 08:38:21 2016 +0000
@@ -49,7 +49,6 @@
 import jdk.internal.misc.Unsafe;
 import jdk.test.lib.Asserts;
 import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.unsafe.UnsafeHelper;
 import jdk.test.lib.cli.CommandLineOptionTest;
 import jdk.test.lib.cli.predicate.AndPredicate;
 
@@ -142,7 +141,7 @@
         @SuppressWarnings("UnsuedDeclaration")
         private static int field = 0;
         private static final int TOTAL_ITERATIONS = 10000;
-        private static final Unsafe UNSAFE = UnsafeHelper.getUnsafe();
+        private static final Unsafe UNSAFE = Unsafe.getUnsafe();
         private final Object monitor = new Object();
 
 
--- a/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java	Wed Sep 21 08:38:21 2016 +0000
@@ -49,7 +49,6 @@
 import jdk.internal.misc.Unsafe;
 import jdk.test.lib.Asserts;
 import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.unsafe.UnsafeHelper;
 import jdk.test.lib.cli.CommandLineOptionTest;
 import jdk.test.lib.cli.predicate.AndPredicate;
 
@@ -113,7 +112,7 @@
 
     public static class Test implements CompilableTest {
         private static final long TOTAL_ITERATIONS = 10000L;
-        private static final Unsafe UNSAFE = UnsafeHelper.getUnsafe();
+        private static final Unsafe UNSAFE = Unsafe.getUnsafe();
         private final Object monitor = new Object();
         // Following field have to be static in order to avoid escape analysis.
         @SuppressWarnings("UnsuedDeclaration")
--- a/test/compiler/testlibrary/rtm/XAbortProvoker.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/compiler/testlibrary/rtm/XAbortProvoker.java	Wed Sep 21 08:38:21 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -25,7 +25,6 @@
 package compiler.testlibrary.rtm;
 
 import jdk.internal.misc.Unsafe;
-import jdk.test.lib.unsafe.UnsafeHelper;
 
 /**
  * Current RTM locking implementation force transaction abort
@@ -35,7 +34,7 @@
     // Following field have to be static in order to avoid escape analysis.
     @SuppressWarnings("UnsuedDeclaration")
     private static int field = 0;
-    private static final Unsafe UNSAFE = UnsafeHelper.getUnsafe();
+    private static final Unsafe UNSAFE = Unsafe.getUnsafe();
 
     public XAbortProvoker() {
         this(new Object());
--- a/test/compiler/unsafe/UnsafeRaw.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/compiler/unsafe/UnsafeRaw.java	Wed Sep 21 08:38:21 2016 +0000
@@ -35,7 +35,6 @@
 
 import jdk.internal.misc.Unsafe;
 import jdk.test.lib.Utils;
-import jdk.test.lib.unsafe.UnsafeHelper;
 
 import java.util.Random;
 
@@ -82,7 +81,7 @@
   }
 
   public static void main(String[] args) throws Exception {
-    Unsafe unsafe = UnsafeHelper.getUnsafe();
+    Unsafe unsafe = Unsafe.getUnsafe();
     final int array_size = 128;
     final int element_size = 4;
     final int magic = 0x12345678;
--- a/test/gc/arguments/TestMaxMinHeapFreeRatioFlags.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/gc/arguments/TestMaxMinHeapFreeRatioFlags.java	Wed Sep 21 08:38:21 2016 +0000
@@ -37,7 +37,6 @@
 import jdk.test.lib.process.OutputAnalyzer;
 import jdk.test.lib.process.ProcessTools;
 import jdk.test.lib.Utils;
-import jdk.test.lib.unsafe.UnsafeHelper;
 import jdk.internal.misc.Unsafe;
 
 public class TestMaxMinHeapFreeRatioFlags {
@@ -134,7 +133,7 @@
      */
     public static class RatioVerifier {
 
-        private static final Unsafe unsafe = UnsafeHelper.getUnsafe();
+        private static final Unsafe unsafe = Unsafe.getUnsafe();
 
         // Size of byte array that will be allocated
         public static final int CHUNK_SIZE = 1024;
--- a/test/gc/arguments/TestTargetSurvivorRatioFlag.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/gc/arguments/TestTargetSurvivorRatioFlag.java	Wed Sep 21 08:38:21 2016 +0000
@@ -46,7 +46,6 @@
 import jdk.test.lib.process.OutputAnalyzer;
 import jdk.test.lib.process.ProcessTools;
 import jdk.test.lib.Utils;
-import jdk.test.lib.unsafe.UnsafeHelper;
 import sun.hotspot.WhiteBox;
 
 /* In order to test that TargetSurvivorRatio affects survivor space occupancy
@@ -249,7 +248,7 @@
     public static class TargetSurvivorRatioVerifier {
 
         static final WhiteBox wb = WhiteBox.getWhiteBox();
-        static final Unsafe unsafe = UnsafeHelper.getUnsafe();
+        static final Unsafe unsafe = Unsafe.getUnsafe();
 
         // Desired size of memory allocated at once
         public static final int CHUNK_SIZE = 1024;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/gc/class_unloading/TestClassUnloadingDisabled.java	Wed Sep 21 08:38:21 2016 +0000
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reqserved.
+ * 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
+ * @key gc
+ * @bug 8114823
+ * @requires vm.gc == null
+ * @requires vm.opt.ExplicitGCInvokesConcurrent != true
+ * @requires vm.opt.ClassUnloading != true
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ * @build sun.hotspot.WhiteBox
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
+ *
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ *                   -XX:-ClassUnloading -XX:+UseG1GC TestClassUnloadingDisabled
+ *
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ *                   -XX:-ClassUnloading -XX:+UseSerialGC TestClassUnloadingDisabled
+ *
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ *                   -XX:-ClassUnloading -XX:+UseParallelGC TestClassUnloadingDisabled
+ *
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ *                   -XX:-ClassUnloading -XX:+UseConcMarkSweepGC TestClassUnloadingDisabled
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import sun.hotspot.WhiteBox;
+
+import static jdk.test.lib.Asserts.*;
+
+public class TestClassUnloadingDisabled {
+    public static void main(String args[]) throws Exception {
+        final WhiteBox wb = WhiteBox.getWhiteBox();
+        // Fetch the dir where the test class and the class
+        // to be loaded resides.
+        String classDir = TestClassUnloadingDisabled.class.getProtectionDomain().getCodeSource().getLocation().getPath();
+        String className = "ClassToLoadUnload";
+
+        assertFalse(wb.isClassAlive(className), "Should not be loaded yet");
+
+        // The NoPDClassLoader handles loading classes in the test directory
+        // and loads them without a protection domain, which in some cases
+        // keeps the class live regardless of marking state.
+        NoPDClassLoader nopd = new NoPDClassLoader(classDir);
+        nopd.loadClass(className);
+
+        assertTrue(wb.isClassAlive(className), "Class should be loaded");
+
+        // Clear the class-loader, class and object references to make
+        // class unloading possible.
+        nopd = null;
+
+        System.gc();
+        assertTrue(wb.isClassAlive(className), "Class should not have ben unloaded");
+    }
+}
+
+class NoPDClassLoader extends ClassLoader {
+    String path;
+
+    NoPDClassLoader(String path) {
+        this.path = path;
+    }
+
+    public Class<?> loadClass(String name) throws ClassNotFoundException {
+        byte[] cls = null;
+        File f = new File(path,name + ".class");
+
+        // Delegate class loading if class not present in the given
+        // directory.
+        if (!f.exists()) {
+            return super.loadClass(name);
+        }
+
+        try {
+            Path path = Paths.get(f.getAbsolutePath());
+            cls = Files.readAllBytes(path);
+        } catch (IOException e) {
+            throw new ClassNotFoundException(name);
+        }
+
+        // Define class with no protection domain and resolve it.
+        return defineClass(name, cls, 0, cls.length, null);
+    }
+}
+
+class ClassToLoadUnload {
+}
--- a/test/runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java	Wed Sep 21 08:38:21 2016 +0000
@@ -89,20 +89,6 @@
         excludeTestMaxRange("CICompilerCount");
 
         /*
-         * JDK-8136766
-         * Temporarily remove ThreadStackSize from testing because Windows can set it to 0
-         * (for default OS size) but other platforms insist it must be greater than 0
-        */
-        excludeTestRange("ThreadStackSize");
-
-        /*
-         * Remove the flag controlling the size of the stack because the
-         * flag has direct influence on the physical memory usage of
-         * the VM.
-         */
-        allOptionsAsMap.remove("CompilerThreadStackSize");
-
-        /*
          * Exclude MallocMaxTestWords as it is expected to exit VM at small values (>=0)
          */
         excludeTestMinRange("MallocMaxTestWords");
@@ -124,8 +110,6 @@
         excludeTestMaxRange("OldSize");
         excludeTestMaxRange("ParallelGCThreads");
 
-        excludeTestMaxRange("VMThreadStackSize");
-
         /*
          * Remove parameters controlling the code cache. As these
          * parameters have implications on the physical memory
--- a/test/runtime/ErrorHandling/CreateCoredumpOnCrash.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/runtime/ErrorHandling/CreateCoredumpOnCrash.java	Wed Sep 21 08:38:21 2016 +0000
@@ -34,13 +34,12 @@
 import jdk.test.lib.process.ProcessTools;
 import jdk.test.lib.process.OutputAnalyzer;
 import jdk.test.lib.Platform;
-import jdk.test.lib.unsafe.UnsafeHelper;
 import jdk.internal.misc.Unsafe;
 
 public class CreateCoredumpOnCrash {
     private static class Crasher {
         public static void main(String[] args) {
-            UnsafeHelper.getUnsafe().putInt(0L, 0);
+            Unsafe.getUnsafe().putInt(0L, 0);
         }
     }
 
--- a/test/runtime/ErrorHandling/ProblematicFrameTest.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/runtime/ErrorHandling/ProblematicFrameTest.java	Wed Sep 21 08:38:21 2016 +0000
@@ -35,14 +35,13 @@
 
 import jdk.test.lib.process.ProcessTools;
 import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.unsafe.UnsafeHelper;
 
 import jdk.internal.misc.Unsafe;
 
 public class ProblematicFrameTest {
     private static class Crasher {
         public static void main(String[] args) {
-            UnsafeHelper.getUnsafe().getInt(0);
+            Unsafe.getUnsafe().getInt(0);
         }
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/LocalLong/LocalLongHelper.java	Wed Sep 21 08:38:21 2016 +0000
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 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.
+ */
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.lang.StackWalker.StackFrame;
+
+public class LocalLongHelper {
+    static StackWalker sw;
+    static Method intValue;
+    static Method getLocals;
+    static Class<?> primitiveValueClass;
+    static Method primitiveType;
+    static Method getMethodType;
+    static Field memberName;
+    static Field offset;
+
+    public static void main(String[] args) throws Throwable {
+        setupReflectionStatics();
+        new LocalLongHelper().longArg(0xC0FFEE, 0x1234567890ABCDEFL);
+    }
+
+    // locals[2] contains the high byte of the long argument.
+    public long longArg(int i, long l) throws Throwable {
+        List<StackFrame> frames = sw.walk(s -> s.collect(Collectors.toList()));
+        Object[] locals = (Object[]) getLocals.invoke(frames.get(0));
+
+        int locals_2 = (int) intValue.invoke(locals[2]);
+        if (locals_2 != 0){
+            throw new RuntimeException("Expected locals_2 == 0");
+        }
+        return l; // Don't want l to become a dead var
+    }
+
+    private static void setupReflectionStatics() throws Throwable {
+        Class<?> liveStackFrameClass = Class.forName("java.lang.LiveStackFrame");
+        primitiveValueClass = Class.forName("java.lang.LiveStackFrame$PrimitiveValue");
+
+        getLocals = liveStackFrameClass.getDeclaredMethod("getLocals");
+        getLocals.setAccessible(true);
+
+        intValue = primitiveValueClass.getDeclaredMethod("intValue");
+        intValue.setAccessible(true);
+
+        Class<?> stackFrameInfoClass = Class.forName("java.lang.StackFrameInfo");
+        memberName = stackFrameInfoClass.getDeclaredField("memberName");
+        memberName.setAccessible(true);
+        offset = stackFrameInfoClass.getDeclaredField("bci");
+        offset.setAccessible(true);
+        getMethodType = Class.forName("java.lang.invoke.MemberName").getDeclaredMethod("getMethodType");
+        getMethodType.setAccessible(true);
+
+        Class<?> extendedOptionClass = Class.forName("java.lang.StackWalker$ExtendedOption");
+        Method ewsNI = StackWalker.class.getDeclaredMethod("newInstance", Set.class, extendedOptionClass);
+        ewsNI.setAccessible(true);
+        Field f = extendedOptionClass.getDeclaredField("LOCALS_AND_OPERANDS");
+        f.setAccessible(true);
+        Object localsAndOperandsOption = f.get(null);
+
+        primitiveType = primitiveValueClass.getDeclaredMethod("type");
+        primitiveType.setAccessible(true);
+
+        sw = (StackWalker) ewsNI.invoke(null, java.util.Collections.emptySet(), localsAndOperandsOption);
+    }
+
+    private static String type(Object o) throws Throwable {
+        if (primitiveValueClass.isInstance(o)) {
+            final char c = (char) primitiveType.invoke(o);
+            return String.valueOf(c);
+        } else if (o != null) {
+            return o.getClass().getName();
+        } else {
+            return "null";
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/LocalLong/LocalLongTest.java	Wed Sep 21 08:38:21 2016 +0000
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 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.
+ */
+
+
+/*
+ * @test LocalLongTest
+ * @bug 8163014
+ * @modules java.base/jdk.internal.misc
+ * @library /test/lib
+ * @compile LocalLongHelper.java
+ * @run driver LocalLongTest
+ */
+
+import jdk.test.lib.Platform;
+import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class LocalLongTest {
+    public static void main(String... args) throws Exception {
+        if (Platform.is64bit()) {
+            ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xint",
+                                                                      "LocalLongHelper");
+            OutputAnalyzer o = new OutputAnalyzer(pb.start());
+            o.shouldHaveExitValue(0);
+        }
+    };
+}
--- a/test/runtime/NMT/CheckForProperDetailStackTrace.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/runtime/NMT/CheckForProperDetailStackTrace.java	Wed Sep 21 08:38:21 2016 +0000
@@ -57,11 +57,6 @@
     private static String expectedSymbol =
         "locked_create_entry_or_null";
 
-    private static final String jdkDebug = System.getProperty("jdk.debug");
-    private static boolean isSlowDebugBuild() {
-        return (jdkDebug.toLowerCase().equals("slowdebug"));
-    }
-
     public static void main(String args[]) throws Exception {
         ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
             "-XX:+UnlockDiagnosticVMOptions",
@@ -76,11 +71,12 @@
         output.shouldNotContain("NativeCallStack::NativeCallStack");
         output.shouldNotContain("os::get_native_stack");
 
-        // AllocateHeap shouldn't be in the output because it is suppose to always be inlined.
-        // We check for that here, but allow it for Windows and Solaris slowdebug builds because
-        // the compiler ends up not inlining AllocateHeap.
+        // AllocateHeap shouldn't be in the output because it is supposed to always be inlined.
+        // We check for that here, but allow it for Aix, Solaris and Windows slowdebug builds
+        // because the compiler ends up not inlining AllocateHeap.
         Boolean okToHaveAllocateHeap =
-            isSlowDebugBuild() && (Platform.isSolaris() || Platform.isWindows());
+            Platform.isSlowDebugBuild() &&
+            (Platform.isAix() || Platform.isSolaris() || Platform.isWindows());
         if (!okToHaveAllocateHeap) {
             output.shouldNotContain("AllocateHeap");
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/SharedArchiveFile/CDSTestUtils.java	Wed Sep 21 08:38:21 2016 +0000
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 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.
+ */
+
+import java.io.IOException;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.PrintStream;
+import jdk.test.lib.process.OutputAnalyzer;
+
+
+// This class contains common test utilities for CDS testing
+public class CDSTestUtils {
+
+    // check result of 'dump' operation
+    public static void checkDump(OutputAnalyzer output, String... extraMatches)
+        throws Exception {
+
+        output.shouldContain("Loading classes to share");
+        output.shouldHaveExitValue(0);
+
+        for (String match : extraMatches) {
+            output.shouldContain(match);
+        }
+    }
+
+
+    // check the output for indication that mapping of the archive failed
+    public static boolean isUnableToMap(OutputAnalyzer output) {
+        String outStr = output.getOutput();
+        if ((output.getExitValue() == 1) && (
+            outStr.contains("Unable to reserve shared space at required address") ||
+            outStr.contains("Unable to map ReadOnly shared space at required address") ||
+            outStr.contains("Unable to map ReadWrite shared space at required address") ||
+            outStr.contains("Unable to map MiscData shared space at required address") ||
+            outStr.contains("Unable to map MiscCode shared space at required address") ||
+            outStr.contains("Unable to map shared string space at required address") ||
+            outStr.contains("Could not allocate metaspace at a compatible address") ||
+            outStr.contains("Unable to allocate shared string space: range is not within java heap") ))
+        {
+            return true;
+        }
+
+        return false;
+    }
+
+    // check result of 'exec' operation, that is when JVM is run using the archive
+    public static void checkExec(OutputAnalyzer output, String... extraMatches) throws Exception {
+        if (isUnableToMap(output)) {
+            System.out.println("Unable to map shared archive: test did not complete; assumed PASS");
+            return;
+        }
+        output.shouldContain("sharing");
+        output.shouldHaveExitValue(0);
+
+        for (String match : extraMatches) {
+            output.shouldContain(match);
+        }
+    }
+
+
+    // get the file object for the test artifact
+    private static File getTestArtifactFile(String prefix, String name) {
+        File dir = new File(System.getProperty("test.classes", "."));
+        return new File(dir, prefix + name);
+    }
+
+
+    // create file containing the specified class list
+    public static File makeClassList(String testCaseName, String classes[])
+        throws Exception {
+
+        File classList = getTestArtifactFile(testCaseName, "test.classlist");
+        FileOutputStream fos = new FileOutputStream(classList);
+        PrintStream ps = new PrintStream(fos);
+
+        addToClassList(ps, classes);
+
+        ps.close();
+        fos.close();
+
+        return classList;
+    }
+
+
+    private static void addToClassList(PrintStream ps, String classes[])
+        throws IOException
+    {
+        if (classes != null) {
+            for (String s : classes) {
+                ps.println(s);
+            }
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/Implementor.java	Wed Sep 21 08:38:21 2016 +0000
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 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.
+ */
+
+public class Implementor implements Interface {
+    public static void main(String[] args) {
+        System.out.println("Implementor: entering main()");
+        test();
+    }
+
+    public static void test() {
+        // from interface
+        (new Implementor()).printString();
+        // from implementor
+        System.out.println(TransformUtil.ChildCheckPattern +
+                           TransformUtil.BeforePattern);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/Interface.java	Wed Sep 21 08:38:21 2016 +0000
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 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.
+ */
+
+public interface Interface {
+    public static final String stringToBeTransformed =
+        TransformUtil.ParentCheckPattern + TransformUtil.BeforePattern;
+
+    default void printString() {
+        System.out.println(stringToBeTransformed);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/SubClass.java	Wed Sep 21 08:38:21 2016 +0000
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 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.
+ */
+
+public class SubClass extends SuperClazz {
+    public static void main(String[] args) {
+        System.out.println("SubClass: entering main()");
+        test();
+    }
+
+    public static void test() {
+        // The line below will be used to check for successful class transformation
+        System.out.println(TransformUtil.ChildCheckPattern +
+                           TransformUtil.BeforePattern);
+        (new SubClass()).callParent();
+    }
+
+    private void callParent() {
+        super.testParent();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/SuperClazz.java	Wed Sep 21 08:38:21 2016 +0000
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 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.
+ */
+
+
+public class SuperClazz {
+    public static void testParent() {
+        System.out.println("SuperClazz: entering testParent()");
+
+        // The line below will be used to check for successful class transformation
+        System.out.println(TransformUtil.ParentCheckPattern + TransformUtil.BeforePattern);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TestEntry.java	Wed Sep 21 08:38:21 2016 +0000
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 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.
+ */
+
+
+// Test Entry - a single entry in a test table
+// that defines a test case
+// See TransformRelatedClasses.java for more details
+public class TestEntry {
+    int testCaseId;
+    boolean transformParent;
+    boolean transformChild;
+    boolean isParentExpectedShared;
+    boolean isChildExpectedShared;
+
+    public TestEntry(int testCaseId,
+                     boolean transformParent, boolean transformChild,
+                     boolean isParentExpectedShared, boolean isChildExpectedShared) {
+        this.testCaseId = testCaseId;
+        this.transformParent = transformParent;
+        this.transformChild = transformChild;
+        this.isParentExpectedShared = isParentExpectedShared;
+        this.isChildExpectedShared = isChildExpectedShared;
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TransformInterfaceAndImplementor.java	Wed Sep 21 08:38:21 2016 +0000
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 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.
+ */
+
+/*
+ * @test
+ * @summary Exercise initial transformation (ClassFileLoadHook)
+ *  with CDS with Interface/Implementor pair
+ * @library /test/lib /runtime/SharedArchiveFile /testlibrary/jvmti
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @requires vm.flavor != "minimal"
+ * @modules java.base/jdk.internal.misc
+ *          jdk.jartool/sun.tools.jar
+ *          java.management
+ *          java.instrument
+ * @build TransformUtil TransformerAgent Interface Implementor
+ * @run main/othervm TransformRelatedClasses Interface Implementor
+ */
+
+// Clarification on @requires declarations:
+// CDS is not supported w/o the use of Compressed OOPs
+// JVMTI's ClassFileLoadHook is not supported under minimal VM
+
+// This test class uses TransformRelatedClasses to do its work.
+// The goal of this test is to exercise transformation of related interface
+// and its implementor in combination with CDS.
+// The transformation is done via ClassFileLoadHook mechanism.
+// Both superclass and subclass reside in the shared archive.
+// The test consists of 4 test cases where transformation is applied
+// to an interface and an implementor in a combinatorial manner.
+// Please see TransformRelatedClasses.java for details.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TransformRelatedClasses.java	Wed Sep 21 08:38:21 2016 +0000
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 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.
+ */
+
+
+// This is the main test class for testing transformation of related classes
+// in combination with CDS, to ensure these features work well together.
+// The relationships that can be tested using this test class are:
+// superclass/subclass, and interface/implementor relationships.
+//
+// The test uses combinatorial approach.
+// For details on test table and test cases see main() method in this class.
+//
+// This test consists of multiple classes for better flexibility and reuse,
+// and also relies on certain common utility code.
+// Here are the details on the structure of the test
+//
+// Structure of the test:
+// TransformRelatedClasses -- common main test driver
+//     The TransformRelatedClasses is invoked from test driver classes:
+//     TransformInterfaceAndImplementor, TransformSuperAndSubClasses
+//     It is responsible for preparing test artifacts (test jar, agent jar
+//     and the shared archive), running test cases and checking the results.
+// The following test classes below are launched in a sub-process with use
+// of shared archive:
+//     SuperClazz, SubClass -- super/sub class pair under test
+//     Interface, Implementor -- classes under test
+// This test will transform these classes, based on the test case data,
+// by changing a predefined unique string in each class.
+// For more details, see the test classes' code and comments.
+//
+// Other related classes:
+//     TestEntry - a class representing a single test case, as test entry in the table
+//     TransformTestCommon - common methods for transformation test cases
+//
+// Other utility/helper classes and files used in this test:
+//     TransformerAgent - an agent that is used when JVM-under-test is executed
+//         to transform specific strings inside specified classes
+//     TransformerAgent.mf - accompanies transformer agent
+//     CDSTestUtils - Test Utilities common to all CDS tests
+
+import java.io.File;
+import java.util.ArrayList;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+
+public class TransformRelatedClasses {
+    static final String archiveName = "./TransformRelatedClasses.jsa";
+    static String agentClasses[] = {
+        "TransformerAgent",
+        "TransformerAgent$SimpleTransformer",
+        "TransformUtil"
+    };
+
+    String parent;
+    String child;
+    String[] testClasses = new String[2];
+    String[] testNames = new String[2];
+    String testJar;
+    String agentJar;
+
+
+    private static void log(String msg) {
+        System.out.println("TransformRelatedClasses: " + msg);
+    }
+
+
+    // This class is intended to test 2 parent-child relationships:
+    // 1. Base Class (parent) and Derived Class (child)
+    // 2. Interface (parent) and Implementor (child)
+    //    Parameters to main(): parent, child
+    public static void main(String args[]) throws Exception {
+        TransformRelatedClasses test = new TransformRelatedClasses(args[0], args[1]);
+        test.prepare();
+
+        // Test Table
+        // TestEntry:  (testCaseId, transformParent, tranformChild,
+        //             isParentExpectedShared, isChildExpectedShared)
+        ArrayList<TestEntry> testTable = new ArrayList<>();
+
+        // base case - no tranformation - all expected to be shared
+        testTable.add(new TestEntry(0, false, false, true, true));
+
+        // transform parent only - both parent and child should not be shared
+        testTable.add(new TestEntry(1, true, false, false, false));
+
+        // transform parent and child - both parent and child should not be shared
+        testTable.add(new TestEntry(2, true, true, false, false));
+
+        // transform child only - parent should still be shared, but not child
+        testTable.add(new TestEntry(3, false, true, true, false));
+
+        // run the tests
+        for (TestEntry entry : testTable) {
+            test.runTest(entry);
+        }
+    }
+
+
+    public TransformRelatedClasses(String parent, String child) {
+        log("Constructor: parent = " + parent + ", child = " + child);
+        this.parent = parent;
+        this.child = child;
+        testClasses[0] = parent;
+        testClasses[1] = child;
+        testNames[0] = parent.replace('.', '/');
+        testNames[1] = child.replace('.', '/');
+    }
+
+
+    // same test jar and archive can be used for all test cases
+    private void prepare() throws Exception {
+        // create agent jar
+        // Agent is the same for all test cases
+        String pathToManifest = "../../../../testlibrary/jvmti/TransformerAgent.mf";
+        agentJar = ClassFileInstaller.writeJar("TransformerAgent.jar",
+                       ClassFileInstaller.Manifest.fromSourceFile(pathToManifest),
+                                           agentClasses);
+
+        // create a test jar
+        testJar =
+            ClassFileInstaller.writeJar(parent + "-" + child + ".jar",
+                                           testClasses);
+
+        // create an archive
+        File classList = CDSTestUtils.makeClassList("transform-" + parent,
+                                                    testNames);
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true,
+                                        "-Xbootclasspath/a:" + testJar,
+                                        "-XX:+UnlockDiagnosticVMOptions",
+                                        "-XX:ExtraSharedClassListFile=" +
+                                        classList.getPath(),
+                                        "-XX:SharedArchiveFile=" + archiveName,
+                                        "-XX:+PrintSharedSpaces",
+                                        "-Xshare:dump");
+        OutputAnalyzer out = new OutputAnalyzer(pb.start());
+        CDSTestUtils.checkDump(out);
+    }
+
+
+    private void runTest(TestEntry entry) throws Exception {
+        log("runTest(): testCaseId = " + entry.testCaseId);
+
+        // execute with archive
+        String agentParam = "-javaagent:" + agentJar + "=" +
+            TransformTestCommon.getAgentParams(entry, parent, child);
+
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true,
+                                        "-Xbootclasspath/a:" + testJar,
+                                        "-XX:+UnlockDiagnosticVMOptions",
+                                        "-XX:SharedArchiveFile=" + archiveName,
+                                        "-Xlog:class+load=info",
+                                        "-Xshare:on", "-showversion",
+                                        agentParam, child);
+        OutputAnalyzer out = new OutputAnalyzer(pb.start());
+
+        TransformTestCommon.checkResults(entry, out, parent, child);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TransformSuperAndSubClasses.java	Wed Sep 21 08:38:21 2016 +0000
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 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.
+ */
+
+
+/*
+ * @test
+ * @summary Exercise initial transformation (ClassFileLoadHook)
+ *  with CDS with SubClass and SuperClass
+ * @library /test/lib /runtime/SharedArchiveFile /testlibrary/jvmti
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @requires vm.flavor != "minimal"
+ * @modules java.base/jdk.internal.misc
+ *          jdk.jartool/sun.tools.jar
+ *          java.management
+ *          java.instrument
+ * @build TransformUtil TransformerAgent SubClass SuperClazz
+ * @run main/othervm TransformRelatedClasses SuperClazz SubClass
+*/
+
+// Clarification on @requires declarations:
+// CDS is not supported w/o the use of Compressed OOPs
+// JVMTI's ClassFileLoadHook is not supported under minimal VM
+
+// This test class uses TransformRelatedClasses to do its work.
+// The goal of this test is to exercise transformation of related superclass
+// and subclass in combination with CDS.
+// The transformation is done via ClassFileLoadHook mechanism.
+// Both superclass and subclass reside in the shared archive.
+// The test consists of 4 test cases where transformation is applied
+// to a parent and child in combinatorial manner.
+// Please see TransformRelatedClasses.java for details.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TransformSuperSubTwoPckgs.java	Wed Sep 21 08:38:21 2016 +0000
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 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.
+ */
+
+
+/*
+ * @test
+ * @summary Exercise initial transformation (ClassFileLoadHook)
+ *  with CDS with SubClass and SuperClass, each lives in own separate package
+ * @library /test/lib /runtime/SharedArchiveFile /testlibrary/jvmti
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @requires vm.flavor != "minimal"
+ * @modules java.base/jdk.internal.misc
+ *          jdk.jartool/sun.tools.jar
+ *          java.management
+ *          java.instrument
+ * @build TransformUtil TransformerAgent SubClass SuperClazz
+ * @compile myPkg2/SubClass.java myPkg1/SuperClazz.java
+ * @run main/othervm TransformRelatedClasses myPkg1.SuperClazz myPkg2.SubClass
+*/
+
+// Clarification on @requires declarations:
+// CDS is not supported w/o the use of Compressed OOPs
+// JVMTI's ClassFileLoadHook is not supported under minimal VM
+
+// This test class uses TransformRelatedClasses to do its work.
+// The goal of this test is to exercise transformation of related superclass
+// and subclass in combination with CDS; each class lives in its own package.
+// The transformation is done via ClassFileLoadHook mechanism.
+// Both superclass and subclass reside in the shared archive.
+// The test consists of 4 test cases where transformation is applied
+// to a parent and child in combinatorial manner.
+// Please see TransformRelatedClasses.java for details.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TransformTestCommon.java	Wed Sep 21 08:38:21 2016 +0000
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 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.
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+
+
+// This class contains methods common to all transformation test cases
+public class TransformTestCommon {
+
+    // get parameters to an agent depending on the test case
+    // these parameters will instruct the agent which classes should be
+    // transformed
+    public static String getAgentParams(TestEntry entry,
+                                        String parent, String child) {
+
+        if (entry.transformParent && entry.transformChild)
+            return parent + "," + child;
+        if (entry.transformParent)
+            return parent;
+        if (entry.transformChild)
+            return child;
+
+        return "";
+    }
+
+
+    private static void checkTransformationResults(TestEntry entry,
+                                                   OutputAnalyzer out)
+        throws Exception {
+
+        if (entry.transformParent)
+            out.shouldContain(TransformUtil.ParentCheckPattern +
+                              TransformUtil.AfterPattern);
+
+        if (entry.transformChild)
+            out.shouldContain(TransformUtil.ChildCheckPattern +
+                              TransformUtil.AfterPattern);
+    }
+
+
+    private static void checkSharingByClass(TestEntry entry, OutputAnalyzer out,
+                                            String parent, String child)
+        throws Exception {
+
+        String parentSharedMatch = parent + " source: shared objects file";
+        String childSharedMatch =  child +  " source: shared objects file";
+
+        if (entry.isParentExpectedShared)
+            out.shouldContain(parentSharedMatch);
+        else
+            out.shouldNotContain(parentSharedMatch);
+
+        if (entry.isChildExpectedShared)
+            out.shouldContain(childSharedMatch);
+        else
+            out.shouldNotContain(childSharedMatch);
+    }
+
+
+    // Both parent and child classes should be passed to ClassFileTransformer.transform()
+    // exactly once.
+    private static void checkTransformationCounts(TestEntry entry, OutputAnalyzer out,
+                                                  String parent, String child)
+        throws Exception {
+
+        String patternBase = "TransformerAgent: SimpleTransformer called for: ";
+
+        out.shouldContain(patternBase + child + "@1");
+        out.shouldContain(patternBase + parent + "@1");
+
+        out.shouldNotContain(patternBase + child + "@2");
+        out.shouldNotContain(patternBase + parent + "@2");
+    }
+
+
+    public static void checkResults(TestEntry entry, OutputAnalyzer out,
+                                    String parent, String child)
+        throws Exception {
+
+        // If we were not able to map an archive,
+        // then do not perform other checks, since
+        // there was no sharing at all
+        if (CDSTestUtils.isUnableToMap(out))
+            return;
+
+        String childVmName = child.replace('.', '/');
+        String parentVmName = parent.replace('.', '/');
+
+        CDSTestUtils.checkExec(out);
+        checkTransformationCounts(entry, out, parentVmName, childVmName);
+        checkTransformationResults(entry, out);
+        checkSharingByClass(entry, out, parent, child);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/myPkg1/SuperClazz.java	Wed Sep 21 08:38:21 2016 +0000
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 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.
+ */
+
+package myPkg1;
+
+public class SuperClazz {
+    public static void testParent() {
+        System.out.println("SuperClazz: entering testParent()");
+
+        // The line below will be used to check for successful class transformation
+        System.out.println("parent-transform-check: this-should-be-transformed");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/myPkg2/SubClass.java	Wed Sep 21 08:38:21 2016 +0000
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 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.
+ */
+
+package myPkg2;
+
+import myPkg1.SuperClazz;
+
+public class SubClass extends SuperClazz {
+    public static void main(String[] args) {
+        System.out.println("SubClass: entering main()");
+        test();
+    }
+
+    public static void test() {
+        // The line below will be used to check for successful class transformation
+        System.out.println("child-transform-check: this-should-be-transformed");
+        (new SubClass()).callParent();
+
+        // Get the system packages, which should contain myPkg1 and myPkag2
+        Package[] pkgs = Package.getPackages();
+        for (int i = 0; i < pkgs.length; i++) {
+            if (pkgs[i].getName().equals("myPkg1")) {
+                for (int j = 0; j < pkgs.length; j++) {
+                    if (pkgs[j].getName().equals("myPkg2")) {
+                        return; // found myPkg1 & myPkg1
+                    }
+                }
+            }
+        }
+        throw new RuntimeException("Missing system package");
+    }
+
+    private void callParent() {
+        super.testParent();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/Thread/TooSmallStackSize.java	Wed Sep 21 08:38:21 2016 +0000
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 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.
+ */
+
+/*
+ * @test
+ * @bug 8140520
+ * @summary Setting small CompilerThreadStackSize, ThreadStackSize, and
+ * VMThreadStackSize values should result in an error message that shows
+ * the minimum stack size value for each thread type.
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ * @run main TooSmallStackSize
+ */
+
+/*
+ * The primary purpose of this test is to make sure we can run with a
+ * stack smaller than the minimum without crashing. Also this test will
+ * determine the minimum allowed stack size for the platform (as
+ * provided by the JVM error message when a very small stack is used),
+ * and then verify that the JVM can be launched with that stack size
+ * without a crash or any error messages.
+ *
+ * Note: The '-Xss<size>' and '-XX:ThreadStackSize=<k-bytes>' options
+ * both control Java thread stack size. This repo's version of the test
+ * exercises the '-XX:ThreadStackSize' VM option. The jdk repo's version
+ * of the test exercises the '-Xss' option.
+ */
+
+import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class TooSmallStackSize {
+    /* for debugging. Normally false. */
+    static final boolean verbose = false;
+    static final String CompilerThreadStackSizeString = "CompilerThreadStackSize";
+    static final String ThreadStackSizeString = "Java thread stack size";
+    static final String VMThreadStackSizeString = "VMThreadStackSize";
+
+    /*
+     * Returns the minimum stack size this platform will allowed based on the
+     * contents of the error message the JVM outputs when too small of a
+     * stack size was used.
+     *
+     * The testOutput argument must contain the result of having already run
+     * the JVM with too small of a stack size.
+     */
+    static String getMinStackAllowed(String testOutput) {
+        /*
+         * The JVM output will contain in one of the lines:
+         *   "The CompilerThreadStackSize specified is too small. Specify at least 100k"
+         *   "The Java thread stack size specified is too small. Specify at least 100k"
+         *   "The VMThreadStackSize specified is too small. Specify at least 100k"
+         * Although the actual size will vary. We need to extract this size
+         * string from the output and return it.
+         */
+        String matchStr = "Specify at least ";
+        int match_idx = testOutput.indexOf(matchStr);
+        if (match_idx >= 0) {
+            int size_start_idx = match_idx + matchStr.length();
+            int k_start_idx = testOutput.indexOf("k", size_start_idx);
+            // don't include the 'k'; the caller will have to
+            // add it back as needed.
+            return testOutput.substring(size_start_idx, k_start_idx);
+        }
+
+        System.out.println("Expect='" + matchStr + "'");
+        System.out.println("Actual: " + testOutput);
+        System.out.println("FAILED: Could not get the stack size from the output");
+        throw new RuntimeException("test fails");
+    }
+
+    /*
+     * Run the JVM with the specified stack size.
+     *
+     * Returns the minimum allowed stack size gleaned from the error message,
+     * if there is an error message. Otherwise returns the stack size passed in.
+     */
+    static String checkStack(String stackOption, String optionMesg, String stackSize) throws Exception {
+        String min_stack_allowed;
+
+        System.out.println("*** Testing " + stackOption + stackSize);
+
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+            stackOption + stackSize,
+            // Uncomment the following to get log output
+            // that shows actual thread creation sizes.
+            // "-Xlog:os+thread",
+            "-version");
+
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+
+        if (verbose) {
+            System.out.println("stdout: " + output.getStdout());
+        }
+
+        if (output.getExitValue() == 0) {
+            // checkMinStackAllowed() is called with stackSize values
+            // that should be the minimum that works. This method,
+            // checkStack(), is called with stackSize values that
+            // should be too small and result in error messages.
+            // However, some platforms fix up a stackSize value that is
+            // too small into something that works so we have to allow
+            // for checkStack() calls that work.
+            System.out.println("PASSED: got exit_code == 0 with " + stackOption + stackSize);
+            min_stack_allowed = stackSize;
+        } else {
+            String expect = "The " + optionMesg + " specified is too small";
+            if (verbose) {
+                System.out.println("Expect='" + expect + "'");
+            }
+            output.shouldContain(expect);
+            min_stack_allowed = getMinStackAllowed(output.getStdout());
+
+            System.out.println("PASSED: got expected error message with " + stackOption + stackSize);
+        }
+
+        return min_stack_allowed;
+    }
+
+    /*
+     * Run the JVM with the minimum allowed stack size. This should always succeed.
+     */
+    static void checkMinStackAllowed(String stackOption, String optionMesg, String stackSize) throws Exception {
+        System.out.println("*** Testing " + stackOption + stackSize);
+
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+            stackOption + stackSize,
+            // Uncomment the following to get log output
+            // that shows actual thread creation sizes.
+            // "-Xlog:os+thread",
+            "-version");
+
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+        output.shouldHaveExitValue(0);
+
+        System.out.println("PASSED: VM launched with " + stackOption + stackSize);
+    }
+
+    public static void main(String... args) throws Exception {
+        /*
+         * The result of a 16k stack size should be a quick exit with a complaint
+         * that the stack size is too small. However, for some win32 builds, the
+         * stack is always at least 64k, and this also sometimes is the minimum
+         * allowed size, so we won't see an error in this case.
+         *
+         * This test case will also produce a crash on some platforms if the fix
+         * for 6762191 is not yet in place.
+         */
+        checkStack("-XX:ThreadStackSize=", ThreadStackSizeString, "16");
+
+        /*
+         * Try with a 32k stack size, which is the size that the launcher will
+         * set to if you try setting to anything smaller. This should produce the same
+         * result as setting to 16k if the fix for 6762191 is in place.
+         */
+        String min_stack_allowed = checkStack("-XX:ThreadStackSize=", ThreadStackSizeString, "32");
+
+        /*
+         * Try again with a the minimum stack size that was given in the error message
+         */
+        checkMinStackAllowed("-XX:ThreadStackSize=", ThreadStackSizeString, min_stack_allowed);
+
+        /*
+         * Now redo the same tests with the compiler thread stack size:
+         */
+        checkStack("-XX:CompilerThreadStackSize=", CompilerThreadStackSizeString, "16");
+        min_stack_allowed = checkStack("-XX:CompilerThreadStackSize=", CompilerThreadStackSizeString, "32");
+        checkMinStackAllowed("-XX:CompilerThreadStackSize=", CompilerThreadStackSizeString, min_stack_allowed);
+
+        /*
+         * Now redo the same tests with the VM thread stack size:
+         */
+        checkStack("-XX:VMThreadStackSize=", VMThreadStackSizeString, "16");
+        min_stack_allowed = checkStack("-XX:VMThreadStackSize=", VMThreadStackSizeString, "32");
+        checkMinStackAllowed("-XX:VMThreadStackSize=", VMThreadStackSizeString, min_stack_allowed);
+    }
+}
--- a/test/runtime/Unsafe/AllocateInstance.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/runtime/Unsafe/AllocateInstance.java	Wed Sep 21 08:38:21 2016 +0000
@@ -30,12 +30,11 @@
  * @run main AllocateInstance
  */
 
-import jdk.test.lib.unsafe.UnsafeHelper;
 import jdk.internal.misc.Unsafe;
 import static jdk.test.lib.Asserts.*;
 
 public class AllocateInstance {
-    static final Unsafe UNSAFE = UnsafeHelper.getUnsafe();
+    static final Unsafe UNSAFE = Unsafe.getUnsafe();
 
     class TestClass {
         public boolean calledConstructor = false;
--- a/test/runtime/Unsafe/AllocateMemory.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/runtime/Unsafe/AllocateMemory.java	Wed Sep 21 08:38:21 2016 +0000
@@ -31,13 +31,12 @@
  * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:MallocMaxTestWords=100m AllocateMemory
  */
 
-import jdk.test.lib.unsafe.UnsafeHelper;
 import jdk.internal.misc.Unsafe;
 import static jdk.test.lib.Asserts.*;
 
 public class AllocateMemory {
     public static void main(String args[]) throws Exception {
-        Unsafe unsafe = UnsafeHelper.getUnsafe();
+        Unsafe unsafe = Unsafe.getUnsafe();
 
         // Allocate a byte, write to the location and read back the value
         long address = unsafe.allocateMemory(1);
--- a/test/runtime/Unsafe/CopyMemory.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/runtime/Unsafe/CopyMemory.java	Wed Sep 21 08:38:21 2016 +0000
@@ -30,14 +30,13 @@
  * @run main CopyMemory
  */
 
-import jdk.test.lib.unsafe.UnsafeHelper;
 import jdk.internal.misc.Unsafe;
 import static jdk.test.lib.Asserts.*;
 
 public class CopyMemory {
     final static int LENGTH = 8;
     public static void main(String args[]) throws Exception {
-        Unsafe unsafe = UnsafeHelper.getUnsafe();
+        Unsafe unsafe = Unsafe.getUnsafe();
         long src = unsafe.allocateMemory(LENGTH);
         long dst = unsafe.allocateMemory(LENGTH);
         assertNotEquals(src, 0L);
--- a/test/runtime/Unsafe/DefineClass.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/runtime/Unsafe/DefineClass.java	Wed Sep 21 08:38:21 2016 +0000
@@ -34,13 +34,12 @@
 import java.security.ProtectionDomain;
 import java.io.InputStream;
 import jdk.test.lib.InMemoryJavaCompiler;
-import jdk.test.lib.unsafe.UnsafeHelper;
 import jdk.internal.misc.Unsafe;
 import static jdk.test.lib.Asserts.*;
 
 public class DefineClass {
     public static void main(String args[]) throws Exception {
-        Unsafe unsafe = UnsafeHelper.getUnsafe();
+        Unsafe unsafe = Unsafe.getUnsafe();
         TestClassLoader classloader = new TestClassLoader();
         ProtectionDomain pd = new ProtectionDomain(null, null);
 
--- a/test/runtime/Unsafe/FieldOffset.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/runtime/Unsafe/FieldOffset.java	Wed Sep 21 08:38:21 2016 +0000
@@ -31,14 +31,13 @@
  */
 
 import java.lang.reflect.Field;
-import jdk.test.lib.unsafe.UnsafeHelper;
 import jdk.internal.misc.Unsafe;
 import java.lang.reflect.*;
 import static jdk.test.lib.Asserts.*;
 
 public class FieldOffset {
     public static void main(String args[]) throws Exception {
-        Unsafe unsafe = UnsafeHelper.getUnsafe();
+        Unsafe unsafe = Unsafe.getUnsafe();
         Field[] fields = Test.class.getDeclaredFields();
 
         for (int i = 0; i < fields.length; i++) {
--- a/test/runtime/Unsafe/GetField.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/runtime/Unsafe/GetField.java	Wed Sep 21 08:38:21 2016 +0000
@@ -30,14 +30,13 @@
  * @run main GetField
  */
 
-import jdk.test.lib.unsafe.UnsafeHelper;
 import jdk.internal.misc.Unsafe;
 import java.lang.reflect.*;
 import static jdk.test.lib.Asserts.*;
 
 public class GetField {
     public static void main(String args[]) throws Exception {
-        Unsafe unsafe = UnsafeHelper.getUnsafe();
+        Unsafe unsafe = Unsafe.getUnsafe();
         // Unsafe.INVALID_FIELD_OFFSET is a static final int field,
         // make sure getField returns the correct field
         Field field = Unsafe.class.getField("INVALID_FIELD_OFFSET");
--- a/test/runtime/Unsafe/GetPutAddress.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/runtime/Unsafe/GetPutAddress.java	Wed Sep 21 08:38:21 2016 +0000
@@ -31,13 +31,12 @@
  */
 
 import jdk.test.lib.Platform;
-import jdk.test.lib.unsafe.UnsafeHelper;
 import jdk.internal.misc.Unsafe;
 import static jdk.test.lib.Asserts.*;
 
 public class GetPutAddress {
     public static void main(String args[]) throws Exception {
-        Unsafe unsafe = UnsafeHelper.getUnsafe();
+        Unsafe unsafe = Unsafe.getUnsafe();
         int addressSize = unsafe.addressSize();
         // Ensure the size returned from Unsafe.addressSize is correct
         assertEquals(unsafe.addressSize(), Platform.is32bit() ? 4 : 8);
--- a/test/runtime/Unsafe/GetPutBoolean.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/runtime/Unsafe/GetPutBoolean.java	Wed Sep 21 08:38:21 2016 +0000
@@ -31,13 +31,12 @@
  */
 
 import java.lang.reflect.Field;
-import jdk.test.lib.unsafe.UnsafeHelper;
 import jdk.internal.misc.Unsafe;
 import static jdk.test.lib.Asserts.*;
 
 public class GetPutBoolean {
     public static void main(String args[]) throws Exception {
-        Unsafe unsafe = UnsafeHelper.getUnsafe();
+        Unsafe unsafe = Unsafe.getUnsafe();
         Test t = new Test();
         Field field = Test.class.getField("b1");
 
--- a/test/runtime/Unsafe/GetPutByte.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/runtime/Unsafe/GetPutByte.java	Wed Sep 21 08:38:21 2016 +0000
@@ -31,13 +31,12 @@
  */
 
 import java.lang.reflect.Field;
-import jdk.test.lib.unsafe.UnsafeHelper;
 import jdk.internal.misc.Unsafe;
 import static jdk.test.lib.Asserts.*;
 
 public class GetPutByte {
     public static void main(String args[]) throws Exception {
-        Unsafe unsafe = UnsafeHelper.getUnsafe();
+        Unsafe unsafe = Unsafe.getUnsafe();
         Test t = new Test();
         Field field = Test.class.getField("b");
 
--- a/test/runtime/Unsafe/GetPutChar.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/runtime/Unsafe/GetPutChar.java	Wed Sep 21 08:38:21 2016 +0000
@@ -31,13 +31,12 @@
  */
 
 import java.lang.reflect.Field;
-import jdk.test.lib.unsafe.UnsafeHelper;
 import jdk.internal.misc.Unsafe;
 import static jdk.test.lib.Asserts.*;
 
 public class GetPutChar {
     public static void main(String args[]) throws Exception {
-        Unsafe unsafe = UnsafeHelper.getUnsafe();
+        Unsafe unsafe = Unsafe.getUnsafe();
         Test t = new Test();
         Field field = Test.class.getField("c");
 
--- a/test/runtime/Unsafe/GetPutDouble.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/runtime/Unsafe/GetPutDouble.java	Wed Sep 21 08:38:21 2016 +0000
@@ -31,13 +31,12 @@
  */
 
 import java.lang.reflect.Field;
-import jdk.test.lib.unsafe.UnsafeHelper;
 import jdk.internal.misc.Unsafe;
 import static jdk.test.lib.Asserts.*;
 
 public class GetPutDouble {
     public static void main(String args[]) throws Exception {
-        Unsafe unsafe = UnsafeHelper.getUnsafe();
+        Unsafe unsafe = Unsafe.getUnsafe();
         Test t = new Test();
         Field field = Test.class.getField("d");
 
--- a/test/runtime/Unsafe/GetPutFloat.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/runtime/Unsafe/GetPutFloat.java	Wed Sep 21 08:38:21 2016 +0000
@@ -31,13 +31,12 @@
  */
 
 import java.lang.reflect.Field;
-import jdk.test.lib.unsafe.UnsafeHelper;
 import jdk.internal.misc.Unsafe;
 import static jdk.test.lib.Asserts.*;
 
 public class GetPutFloat {
     public static void main(String args[]) throws Exception {
-        Unsafe unsafe = UnsafeHelper.getUnsafe();
+        Unsafe unsafe = Unsafe.getUnsafe();
         Test t = new Test();
         Field field = Test.class.getField("f");
 
--- a/test/runtime/Unsafe/GetPutInt.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/runtime/Unsafe/GetPutInt.java	Wed Sep 21 08:38:21 2016 +0000
@@ -30,13 +30,12 @@
  */
 
 import java.lang.reflect.Field;
-import jdk.test.lib.unsafe.UnsafeHelper;
 import jdk.internal.misc.Unsafe;
 import static jdk.test.lib.Asserts.*;
 
 public class GetPutInt {
     public static void main(String args[]) throws Exception {
-        Unsafe unsafe = UnsafeHelper.getUnsafe();
+        Unsafe unsafe = Unsafe.getUnsafe();
         Test t = new Test();
         Field field = Test.class.getField("i");
 
--- a/test/runtime/Unsafe/GetPutLong.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/runtime/Unsafe/GetPutLong.java	Wed Sep 21 08:38:21 2016 +0000
@@ -31,13 +31,12 @@
  */
 
 import java.lang.reflect.Field;
-import jdk.test.lib.unsafe.UnsafeHelper;
 import jdk.internal.misc.Unsafe;
 import static jdk.test.lib.Asserts.*;
 
 public class GetPutLong {
     public static void main(String args[]) throws Exception {
-        Unsafe unsafe = UnsafeHelper.getUnsafe();
+        Unsafe unsafe = Unsafe.getUnsafe();
         Test t = new Test();
         Field field = Test.class.getField("l");
 
--- a/test/runtime/Unsafe/GetPutObject.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/runtime/Unsafe/GetPutObject.java	Wed Sep 21 08:38:21 2016 +0000
@@ -31,13 +31,12 @@
  */
 
 import java.lang.reflect.Field;
-import jdk.test.lib.unsafe.UnsafeHelper;
 import jdk.internal.misc.Unsafe;
 import static jdk.test.lib.Asserts.*;
 
 public class GetPutObject {
     public static void main(String args[]) throws Exception {
-        Unsafe unsafe = UnsafeHelper.getUnsafe();
+        Unsafe unsafe = Unsafe.getUnsafe();
         Test t = new Test();
         Object o = new Object();
         Field field = Test.class.getField("o");
--- a/test/runtime/Unsafe/GetPutShort.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/runtime/Unsafe/GetPutShort.java	Wed Sep 21 08:38:21 2016 +0000
@@ -31,13 +31,12 @@
  */
 
 import java.lang.reflect.Field;
-import jdk.test.lib.unsafe.UnsafeHelper;
 import jdk.internal.misc.Unsafe;
 import static jdk.test.lib.Asserts.*;
 
 public class GetPutShort {
     public static void main(String args[]) throws Exception {
-        Unsafe unsafe = UnsafeHelper.getUnsafe();
+        Unsafe unsafe = Unsafe.getUnsafe();
         Test t = new Test();
         Field field = Test.class.getField("s");
 
--- a/test/runtime/Unsafe/GetUncompressedObject.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/runtime/Unsafe/GetUncompressedObject.java	Wed Sep 21 08:38:21 2016 +0000
@@ -30,13 +30,12 @@
 
 import static jdk.test.lib.Asserts.*;
 
-import jdk.test.lib.unsafe.UnsafeHelper;
 import jdk.internal.misc.Unsafe;
 
 public class GetUncompressedObject {
 
     public static void main(String args[]) throws Exception {
-        Unsafe unsafe = UnsafeHelper.getUnsafe();
+        Unsafe unsafe = Unsafe.getUnsafe();
 
         // Allocate some memory and fill it with non-zero values.
         final int size = 32;
--- a/test/runtime/Unsafe/NestedUnsafe.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/runtime/Unsafe/NestedUnsafe.java	Wed Sep 21 08:38:21 2016 +0000
@@ -35,7 +35,6 @@
 import java.io.InputStream;
 import java.lang.*;
 import jdk.test.lib.InMemoryJavaCompiler;
-import jdk.test.lib.unsafe.UnsafeHelper;
 import jdk.internal.misc.Unsafe;
 import static jdk.test.lib.Asserts.*;
 
@@ -50,7 +49,7 @@
         " } } ");
 
     public static void main(String args[]) throws Exception {
-        Unsafe unsafe = UnsafeHelper.getUnsafe();
+        Unsafe unsafe = Unsafe.getUnsafe();
 
         Class klass = unsafe.defineAnonymousClass(NestedUnsafe.class, klassbuf, new Object[0]);
         unsafe.ensureClassInitialized(klass);
--- a/test/runtime/Unsafe/PageSize.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/runtime/Unsafe/PageSize.java	Wed Sep 21 08:38:21 2016 +0000
@@ -31,13 +31,12 @@
  */
 
 import java.lang.reflect.Field;
-import jdk.test.lib.unsafe.UnsafeHelper;
 import jdk.internal.misc.Unsafe;
 import static jdk.test.lib.Asserts.*;
 
 public class PageSize {
     public static void main(String args[]) throws Exception {
-        Unsafe unsafe = UnsafeHelper.getUnsafe();
+        Unsafe unsafe = Unsafe.getUnsafe();
         int pageSize = unsafe.pageSize();
 
         for (int n = 1; n != 0; n <<= 1) {
--- a/test/runtime/Unsafe/PrimitiveHostClass.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/runtime/Unsafe/PrimitiveHostClass.java	Wed Sep 21 08:38:21 2016 +0000
@@ -39,16 +39,7 @@
 
 public class PrimitiveHostClass {
 
-    static final Unsafe U;
-    static {
-        try {
-            Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
-            theUnsafe.setAccessible(true);
-            U = (Unsafe) theUnsafe.get(null);
-        } catch (Exception e) {
-            throw new AssertionError(e);
-        }
-    }
+    static final Unsafe U = Unsafe.getUnsafe();
 
     public static void testVMAnonymousClass(Class<?> hostClass) {
 
--- a/test/runtime/Unsafe/RangeCheck.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/runtime/Unsafe/RangeCheck.java	Wed Sep 21 08:38:21 2016 +0000
@@ -33,7 +33,6 @@
 import jdk.test.lib.process.ProcessTools;
 import jdk.test.lib.process.OutputAnalyzer;
 import jdk.test.lib.Platform;
-import jdk.test.lib.unsafe.UnsafeHelper;
 
 import jdk.internal.misc.Unsafe;
 
@@ -60,7 +59,7 @@
 
     public static class DummyClassWithMainRangeCheck {
         public static void main(String args[]) throws Exception {
-            Unsafe unsafe = UnsafeHelper.getUnsafe();
+            Unsafe unsafe = Unsafe.getUnsafe();
             unsafe.getObject(new DummyClassWithMainRangeCheck(), Short.MAX_VALUE);
         }
     }
--- a/test/runtime/Unsafe/Reallocate.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/runtime/Unsafe/Reallocate.java	Wed Sep 21 08:38:21 2016 +0000
@@ -31,13 +31,12 @@
  * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:MallocMaxTestWords=100m Reallocate
  */
 
-import jdk.test.lib.unsafe.UnsafeHelper;
 import jdk.internal.misc.Unsafe;
 import static jdk.test.lib.Asserts.*;
 
 public class Reallocate {
     public static void main(String args[]) throws Exception {
-        Unsafe unsafe = UnsafeHelper.getUnsafe();
+        Unsafe unsafe = Unsafe.getUnsafe();
 
         long address = unsafe.allocateMemory(1);
         assertNotEquals(address, 0L);
--- a/test/runtime/Unsafe/SetMemory.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/runtime/Unsafe/SetMemory.java	Wed Sep 21 08:38:21 2016 +0000
@@ -30,13 +30,12 @@
  * @run main SetMemory
  */
 
-import jdk.test.lib.unsafe.UnsafeHelper;
 import jdk.internal.misc.Unsafe;
 import static jdk.test.lib.Asserts.*;
 
 public class SetMemory {
     public static void main(String args[]) throws Exception {
-        Unsafe unsafe = UnsafeHelper.getUnsafe();
+        Unsafe unsafe = Unsafe.getUnsafe();
         long address = unsafe.allocateMemory(1);
         assertNotEquals(address, 0L);
         unsafe.setMemory(address, 1, (byte)17);
--- a/test/runtime/Unsafe/ThrowException.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/runtime/Unsafe/ThrowException.java	Wed Sep 21 08:38:21 2016 +0000
@@ -30,13 +30,12 @@
  * @run main ThrowException
  */
 
-import jdk.test.lib.unsafe.UnsafeHelper;
 import jdk.internal.misc.Unsafe;
 import static jdk.test.lib.Asserts.*;
 
 public class ThrowException {
     public static void main(String args[]) throws Exception {
-        Unsafe unsafe = UnsafeHelper.getUnsafe();
+        Unsafe unsafe = Unsafe.getUnsafe();
         try {
             unsafe.throwException(new TestException());
         } catch (Throwable t) {
--- a/test/runtime/contended/Basic.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/runtime/contended/Basic.java	Wed Sep 21 08:38:21 2016 +0000
@@ -48,20 +48,11 @@
  */
 public class Basic {
 
-    private static final Unsafe U;
+    private static final Unsafe U = Unsafe.getUnsafe();
     private static int ADDRESS_SIZE;
     private static int HEADER_SIZE;
 
     static {
-        // steal Unsafe
-        try {
-            Field unsafe = Unsafe.class.getDeclaredField("theUnsafe");
-            unsafe.setAccessible(true);
-            U = (Unsafe) unsafe.get(null);
-        } catch (NoSuchFieldException | IllegalAccessException e) {
-            throw new IllegalStateException(e);
-        }
-
         // When running with CompressedOops on 64-bit platform, the address size
         // reported by Unsafe is still 8, while the real reference fields are 4 bytes long.
         // Try to guess the reference field size with this naive trick.
--- a/test/runtime/contended/DefaultValue.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/runtime/contended/DefaultValue.java	Wed Sep 21 08:38:21 2016 +0000
@@ -49,20 +49,11 @@
  */
 public class DefaultValue {
 
-    private static final Unsafe U;
+    private static final Unsafe U = Unsafe.getUnsafe();
     private static int ADDRESS_SIZE;
     private static int HEADER_SIZE;
 
     static {
-        // steal Unsafe
-        try {
-            Field unsafe = Unsafe.class.getDeclaredField("theUnsafe");
-            unsafe.setAccessible(true);
-            U = (Unsafe) unsafe.get(null);
-        } catch (NoSuchFieldException | IllegalAccessException e) {
-            throw new IllegalStateException(e);
-        }
-
         // When running with CompressedOops on 64-bit platform, the address size
         // reported by Unsafe is still 8, while the real reference fields are 4 bytes long.
         // Try to guess the reference field size with this naive trick.
--- a/test/runtime/contended/Inheritance1.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/runtime/contended/Inheritance1.java	Wed Sep 21 08:38:21 2016 +0000
@@ -49,20 +49,11 @@
  */
 public class Inheritance1 {
 
-    private static final Unsafe U;
+    private static final Unsafe U = Unsafe.getUnsafe();
     private static int ADDRESS_SIZE;
     private static int HEADER_SIZE;
 
     static {
-        // steal Unsafe
-        try {
-            Field unsafe = Unsafe.class.getDeclaredField("theUnsafe");
-            unsafe.setAccessible(true);
-            U = (Unsafe) unsafe.get(null);
-        } catch (NoSuchFieldException | IllegalAccessException e) {
-            throw new IllegalStateException(e);
-        }
-
         // When running with CompressedOops on 64-bit platform, the address size
         // reported by Unsafe is still 8, while the real reference fields are 4 bytes long.
         // Try to guess the reference field size with this naive trick.
--- a/test/runtime/defineAnonClass/NestedUnsafe.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/runtime/defineAnonClass/NestedUnsafe.java	Wed Sep 21 08:38:21 2016 +0000
@@ -39,7 +39,6 @@
 import java.lang.*;
 import jdk.test.lib.*;
 import jdk.internal.misc.Unsafe;
-import jdk.test.lib.unsafe.UnsafeHelper;
 
 
 // Test that an anonymous class in package 'p' cannot define its own anonymous class
@@ -54,7 +53,7 @@
         " } } ");
 
     public static void main(String args[]) throws Exception {
-        Unsafe unsafe = UnsafeHelper.getUnsafe();
+        Unsafe unsafe = Unsafe.getUnsafe();
 
         // The anonymous class calls defineAnonymousClass creating a nested anonymous class.
         byte klassbuf2[] = InMemoryJavaCompiler.compile("p.TestClass2",
--- a/test/runtime/defineAnonClass/NestedUnsafe2.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/runtime/defineAnonClass/NestedUnsafe2.java	Wed Sep 21 08:38:21 2016 +0000
@@ -39,7 +39,6 @@
 import java.lang.*;
 import jdk.test.lib.*;
 import jdk.internal.misc.Unsafe;
-import jdk.test.lib.unsafe.UnsafeHelper;
 
 
 // Test that an anonymous class that gets put in its host's package cannot define
@@ -54,7 +53,7 @@
         " } } ");
 
     public static void main(String args[]) throws Exception {
-        Unsafe unsafe = UnsafeHelper.getUnsafe();
+        Unsafe unsafe = Unsafe.getUnsafe();
 
         // The anonymous class calls defineAnonymousClass creating a nested anonymous class.
         byte klassbuf2[] = InMemoryJavaCompiler.compile("TestClass2",
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/jni/checked/TestCheckedJniExceptionCheck.java	Wed Sep 21 08:38:21 2016 +0000
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 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.
+ */
+
+/* @test
+ * @bug 8164086
+ * @summary regression tests for 8164086, verify correct warning from checked JNI
+ * @library /test/lib
+ * @modules java.management
+ * @run main/native TestCheckedJniExceptionCheck launch
+ */
+
+import java.util.List;
+import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class TestCheckedJniExceptionCheck {
+
+    static {
+        System.loadLibrary("TestCheckedJniExceptionCheck");
+    }
+
+    int callableMethodInvokeCount = 0;
+
+    static final String TEST_START           = "TEST STARTED";
+    static final String EXPECT_WARNING_START = "EXPECT_WARNING_START";
+    static final String EXPECT_WARNING_END   = "EXPECT_WARNING_END";
+
+    static final String JNI_CHECK_EXCEPTION = "WARNING in native method: JNI call made without checking exceptions when required to from";
+
+    static void printExpectWarningStart(int count) {
+        System.out.println(EXPECT_WARNING_START + " " + count);
+    }
+
+    static void printExpectWarningEnd() {
+        System.out.println(EXPECT_WARNING_END);
+    }
+
+    public TestCheckedJniExceptionCheck() {
+        initMethodIds("callableMethod", "()V",
+                      "callableNestedMethod", "(IZ)V");
+        System.out.println(TEST_START);
+    }
+
+    public void test() {
+        testSingleCallNoCheck();
+        testSingleCallCheck();
+        testSingleCallNoCheckMultipleTimes();
+
+        testMultipleCallsNoCheck();
+        testMultipleCallsCheck();
+
+        testNestedSingleCallsNoCheck();
+        testNestedSingleCallsCheck();
+        testNestedMultipleCallsNoCheck();
+        testNestedMultipleCallsCheck();
+    }
+
+    public void testSingleCallNoCheck() {
+        System.out.println("testSingleCallNoCheck start");
+        callJavaFromNative(1, false);
+        System.out.println("testSingleCallNoCheck end");
+    }
+
+    public void testSingleCallCheck() {
+        System.out.println("testSingleCallCheck start");
+        callJavaFromNative(1, true);
+        System.out.println("testSingleCallCheck end");
+    }
+
+    public void testSingleCallNoCheckMultipleTimes() {
+        System.out.println("testSingleCallNoCheckMultipleTimes start");
+        callJavaFromNative(1, false);
+        callJavaFromNative(1, false);
+        System.out.println("testSingleCallNoCheckMultipleTimes end");
+    }
+
+    public void testMultipleCallsNoCheck() {
+        System.out.println("testMultipleCallsNoCheck start");
+        printExpectWarningStart(1);
+        callJavaFromNative(2, false);
+        printExpectWarningEnd();
+        System.out.println("testMultipleCallsNoCheck end");
+    }
+
+    public void testMultipleCallsCheck() {
+        System.out.println("testMultipleCallsCheck start");
+        callJavaFromNative(2, true);
+        System.out.println("testMultipleCallsCheck end");
+    }
+
+    public void testNestedSingleCallsNoCheck() {
+        System.out.println("testNestedSingleCallsNoCheck start");
+        callNestedJavaFromNative(1, false);
+        System.out.println("testNestedSingleCallsNoCheck end");
+    }
+
+    public void testNestedSingleCallsCheck() {
+        System.out.println("testNestedSingleCallsCheck start");
+        callNestedJavaFromNative(1, true);
+        System.out.println("testNestedSingleCallsCheck end");
+    }
+
+    public void testNestedMultipleCallsNoCheck() {
+        System.out.println("testNestedMultipleCallsNoCheck start");
+        printExpectWarningStart(3);
+        callNestedJavaFromNative(2, false);
+        printExpectWarningEnd();
+        System.out.println("testNestedMultipleCallsNoCheck end");
+    }
+
+    public void testNestedMultipleCallsCheck() {
+        System.out.println("testNestedMultipleCallsCheck start");
+        callNestedJavaFromNative(2, true);
+        System.out.println("testNestedMultipleCallsCheck end");
+    }
+
+    public void callableMethod() {
+        callableMethodInvokeCount++;
+    }
+
+    public void callableNestedMethod(int nofCalls, boolean withExceptionChecks) {
+        callJavaFromNative(nofCalls, withExceptionChecks);
+    }
+
+    public native void callJavaFromNative(int nofCalls, boolean withExceptionChecks);
+
+    public native void callNestedJavaFromNative(int nofCalls, boolean withExceptionChecks);
+
+    private native void initMethodIds(String callableMethodName,
+                                      String callableMethodSig,
+                                      String callableNestedMethodName,
+                                      String callableNestedMethodSig);
+
+
+    // Check warnings appear where they should, with start/end statements in output...
+    static void checkOuputForCorrectWarnings(OutputAnalyzer oa) throws RuntimeException {
+        List<String> lines = oa.asLines();
+        int expectedWarnings = 0;
+        int warningCount = 0;
+        int lineNo = 0;
+        boolean testStartLine = false;
+        for (String line : lines) {
+            lineNo++;
+            if (!testStartLine) { // Skip any warning before the actual test itself
+                testStartLine = line.startsWith(TEST_START);
+                continue;
+            }
+            if (line.startsWith(JNI_CHECK_EXCEPTION)) {
+                if (expectedWarnings == 0) {
+                    oa.reportDiagnosticSummary();
+                    throw new RuntimeException("Unexpected warning at line " + lineNo);
+                }
+                warningCount++;
+                if (warningCount > expectedWarnings) {
+                    oa.reportDiagnosticSummary();
+                    throw new RuntimeException("Unexpected warning at line " + lineNo);
+                }
+            }
+            else if (line.startsWith(EXPECT_WARNING_START)) {
+                String countStr = line.substring(EXPECT_WARNING_START.length() + 1);
+                expectedWarnings = Integer.parseInt(countStr);
+            }
+            else if (line.startsWith(EXPECT_WARNING_END)) {
+                if (warningCount != expectedWarnings) {
+                    oa.reportDiagnosticSummary();
+                    throw new RuntimeException("Missing warning at line " + lineNo);
+                }
+                warningCount = 0;
+                expectedWarnings = 0;
+            }
+        }
+        /*
+        System.out.println("Output looks good...");
+        oa.reportDiagnosticSummary();
+        */
+    }
+
+    public static void main(String[] args) throws Throwable {
+        if (args == null || args.length == 0) {
+            new TestCheckedJniExceptionCheck().test();
+            return;
+        }
+
+        // launch and check output
+        checkOuputForCorrectWarnings(ProcessTools.executeTestJvm("-Xcheck:jni",
+                                                                  "TestCheckedJniExceptionCheck"));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/jni/checked/libTestCheckedJniExceptionCheck.c	Wed Sep 21 08:38:21 2016 +0000
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 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 <jni.h>
+
+static jmethodID _callable_method_id;
+static jmethodID _callable_nested_method_id;
+
+static void check_exceptions(JNIEnv *env) {
+  if ((*env)->ExceptionCheck(env)) {
+    (*env)->ExceptionDescribe(env);
+    (*env)->FatalError(env, "Unexpected Exception");
+  }
+}
+
+static jmethodID get_method_id(JNIEnv *env, jclass clz, jstring jname, jstring jsig) {
+  jmethodID mid;
+  const char *name, *sig;
+
+  name = (*env)->GetStringUTFChars(env, jname, NULL);
+  check_exceptions(env);
+
+  sig  = (*env)->GetStringUTFChars(env, jsig, NULL);
+  check_exceptions(env);
+
+  mid  = (*env)->GetMethodID(env, clz, name, sig);
+  check_exceptions(env);
+
+  (*env)->ReleaseStringUTFChars(env, jname, name);
+  (*env)->ReleaseStringUTFChars(env, jsig, sig);
+  return mid;
+}
+
+JNIEXPORT void JNICALL
+Java_TestCheckedJniExceptionCheck_initMethodIds(JNIEnv *env,
+                                                jobject obj,
+                                                jstring callable_method_name,
+                                                jstring callable_method_sig,
+                                                jstring callable_nested_method_name,
+                                                jstring callable_nested_method_sig) {
+  jclass clz = (*env)->GetObjectClass(env, obj);
+
+  _callable_method_id = get_method_id(env, clz,
+                                      callable_method_name,
+                                      callable_method_sig);
+
+  _callable_nested_method_id = get_method_id(env, clz,
+                                             callable_nested_method_name,
+                                             callable_nested_method_sig);
+}
+
+JNIEXPORT void JNICALL
+Java_TestCheckedJniExceptionCheck_callJavaFromNative(JNIEnv *env,
+                                                     jobject obj,
+                                                     jint nofCalls,
+                                                     jboolean checkExceptions) {
+  int i;
+  for (i = 0; i < nofCalls; i++) {
+    (*env)->CallVoidMethod(env, obj, _callable_method_id);
+    if (checkExceptions == JNI_TRUE) {
+      check_exceptions(env);
+    }
+  }
+}
+
+JNIEXPORT void JNICALL
+Java_TestCheckedJniExceptionCheck_callNestedJavaFromNative(JNIEnv *env,
+                                                           jobject obj,
+                                                           jint nofCalls,
+                                                           jboolean checkExceptions) {
+  int i;
+  for (i = 0; i < nofCalls; i++) {
+    (*env)->CallVoidMethod(env, obj, _callable_nested_method_id, nofCalls, checkExceptions);
+    if (checkExceptions == JNI_TRUE) {
+      check_exceptions(env);
+    }
+  }
+}
--- a/test/runtime/modules/ModuleOptionsTest.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/runtime/modules/ModuleOptionsTest.java	Wed Sep 21 08:38:21 2016 +0000
@@ -24,8 +24,8 @@
 /*
  * @test
  * @bug 8136930
- * @summary Test that the VM only recognizes the last specified --add-modules
- *          and --list-modules options
+ * @summary Test that the VM only recognizes the last specified --list-modules
+ *          options but accumulates --add-module values.
  * @modules java.base/jdk.internal.misc
  * @library /test/lib
  */
@@ -38,14 +38,16 @@
 
     public static void main(String[] args) throws Exception {
 
-        // Test that last --add-modules is the only one recognized.  No exception
-        // should be thrown.
+        // Test that multiple --add-modules options are cumulative, not last one wins.
+        // An exception should be thrown because module i_dont_exist doesn't exist.
         ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
             "--add-modules=i_dont_exist", "--add-modules=java.base", "-version");
         OutputAnalyzer output = new OutputAnalyzer(pb.start());
-        output.shouldHaveExitValue(0);
+        output.shouldContain("ResolutionException");
+        output.shouldContain("i_dont_exist");
+        output.shouldHaveExitValue(1);
 
-        // Test that last --limit-modules is the only one recognized.  No exception
+        // Test that the last --limit-modules is the only one recognized.  No exception
         // should be thrown.
         pb = ProcessTools.createJavaProcessBuilder(
             "--limit-modules=i_dont_exist", "--limit-modules=java.base", "-version");
--- a/test/runtime/modules/PatchModule/PatchModuleCDS.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/runtime/modules/PatchModule/PatchModuleCDS.java	Wed Sep 21 08:38:21 2016 +0000
@@ -23,41 +23,83 @@
 
 /*
  * @test
+ * @summary test that --patch-module works with CDS
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
+ *          jdk.jartool/sun.tools.jar
+ * @build PatchModuleMain
  * @run main PatchModuleCDS
  */
 
 import java.io.File;
+import jdk.test.lib.InMemoryJavaCompiler;
 import jdk.test.lib.process.OutputAnalyzer;
 import jdk.test.lib.process.ProcessTools;
 
 public class PatchModuleCDS {
 
     public static void main(String args[]) throws Throwable {
-        System.out.println("Test that --patch-module and -Xshare:dump are incompatibable");
-        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("--patch-module=java.naming=mods/java.naming", "-Xshare:dump");
-        OutputAnalyzer output = new OutputAnalyzer(pb.start());
-        output.shouldContain("Cannot use the following option when dumping the shared archive: --patch-module");
 
-        System.out.println("Test that --patch-module and -Xshare:on are incompatibable");
+        // Case 1: Test that --patch-module and -Xshare:dump are compatible
         String filename = "patch_module.jsa";
-        pb = ProcessTools.createJavaProcessBuilder(
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
             "-XX:+UnlockDiagnosticVMOptions",
             "-XX:SharedArchiveFile=" + filename,
-            "-Xshare:dump");
-        output = new OutputAnalyzer(pb.start());
-        output.shouldContain("ro space:"); // Make sure archive got created.
+            "-Xshare:dump",
+            "--patch-module=java.naming=no/such/directory",
+            "-Xlog:class+path=info",
+            "-version");
+        new OutputAnalyzer(pb.start())
+            .shouldContain("ro space:"); // Make sure archive got created.
+
+       // Case 2: Test that only jar file in --patch-module is supported for CDS dumping
+        // Create a class file in the module java.base.
+        String source = "package javax.naming.spi; "                +
+                        "public class NamingManager { "             +
+                        "    static { "                             +
+                        "        System.out.println(\"I pass!\"); " +
+                        "    } "                                    +
+                        "}";
+
+        ClassFileInstaller.writeClassToDisk("javax/naming/spi/NamingManager",
+             InMemoryJavaCompiler.compile("javax.naming.spi.NamingManager", source, "-Xmodule:java.naming"),
+             System.getProperty("test.classes"));
 
         pb = ProcessTools.createJavaProcessBuilder(
             "-XX:+UnlockDiagnosticVMOptions",
             "-XX:SharedArchiveFile=" + filename,
-            "-Xshare:on",
-            "--patch-module=java.naming=mods/java.naming",
+            "-Xshare:dump",
+            "--patch-module=java.base=" + System.getProperty("test.classes"),
+            "-Xlog:class+path=info",
             "-version");
-        output = new OutputAnalyzer(pb.start());
-        output.shouldContain("The shared archive file cannot be used with --patch-module");
+        new OutputAnalyzer(pb.start())
+            .shouldContain("--patch-module requires a regular file during dumping");
 
-        output.shouldHaveExitValue(1);
+        // Case 3a: Test CDS dumping with jar file in --patch-module
+        BasicJarBuilder.build("javanaming", "javax/naming/spi/NamingManager");
+        String moduleJar = BasicJarBuilder.getTestJar("javanaming.jar");
+        pb = ProcessTools.createJavaProcessBuilder(
+            "-XX:+UnlockDiagnosticVMOptions",
+            "-XX:SharedArchiveFile=" + filename,
+            "-Xshare:dump",
+            "--patch-module=java.naming=" + moduleJar,
+            "-Xlog:class+load",
+            "-Xlog:class+path=info",
+            "PatchModuleMain", "javax.naming.spi.NamingManager");
+        new OutputAnalyzer(pb.start())
+            .shouldContain("ro space:"); // Make sure archive got created.
+
+        // Case 3b: Test CDS run with jar file in --patch-module
+        pb = ProcessTools.createJavaProcessBuilder(
+            "-XX:+UnlockDiagnosticVMOptions",
+            "-XX:SharedArchiveFile=" + filename,
+            "-Xshare:auto",
+            "--patch-module=java.naming=" + moduleJar,
+            "-Xlog:class+load",
+            "-Xlog:class+path=info",
+            "PatchModuleMain", "javax.naming.spi.NamingManager");
+        new OutputAnalyzer(pb.start())
+            .shouldContain("I pass!")
+            .shouldHaveExitValue(0);
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/verifier/popTopTests/PopDupTop.java	Wed Sep 21 08:38:21 2016 +0000
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 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.
+ *
+ */
+
+/*
+ * @test
+ * @bug 8149607
+ * @summary Throw VerifyError when popping a stack element of TOP
+ * @compile popDupSwapTests.jasm
+ * @run main/othervm -Xverify:all PopDupTop
+ */
+
+public class PopDupTop {
+
+    public static void testClass(String class_name, String msg) throws Throwable {
+        try {
+            Class newClass = Class.forName(class_name);
+            throw new RuntimeException("Expected VerifyError exception not thrown for " + msg);
+        } catch (java.lang.VerifyError e) {
+            if (!e.getMessage().contains("Bad type on operand stack")) {
+               throw new RuntimeException(
+                   "Unexpected VerifyError message for " + msg + ": " + e.getMessage());
+            }
+        }
+    }
+
+    public static void main(String args[]) throws Throwable {
+        System.out.println("Regression test for bug 8149607");
+
+        testClass("dup_x1", "dup_x1 of long,ref");
+        testClass("dup2toptop", "dup2 of top,top");
+        testClass("dup2longtop", "dup2 of long,top");
+        testClass("dup2_x1", "dup2_x1 long,ref,ref");
+        testClass("dup2_x2", "dup2_x2 top");
+        testClass("dup2_x2_long_refs", "dup2_x2 long,ref,ref,ref");
+        testClass("poptop", "pop of top");
+        testClass("poptoptop", "pop of top,top");
+        testClass("pop2toptop", "pop2 of top,top");
+        testClass("pop2longtop", "pop2 of long,top");
+        testClass("swaptoptop", "swap of top,top");
+        testClass("swapinttop", "swap of int,top");
+        testClass("swaptopint", "swap of top,int");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/verifier/popTopTests/popDupSwapTests.jasm	Wed Sep 21 08:38:21 2016 +0000
@@ -0,0 +1,244 @@
+/*
+ * Copyright (c) 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.
+ *
+ */
+
+// Test that VerifyError is thrown if dup2_x1 tries to replace the filler slot
+// of a category 2 value.
+// The stack map is long,top,null,null.  The verifier should reject dup2_x1's
+// (form1) attempt to turn the stack map into long,top,null,null,null,null
+public class dup2_x1 version 51:0 {
+    public static Method run:"()V" stack 6 locals 0 {
+        lconst_0;
+        aconst_null;
+        aconst_null;
+        dup2_x1;
+        return;
+    }
+}
+
+
+public class dup2_x2 version 51:0 {
+    public static Method run:"()V" stack 6 locals 0 {
+        iconst_0;
+        lconst_0;
+        aconst_null;
+
+        stack_frame_type full;
+        stack_map int, bogus, bogus, null;
+        locals_map;
+
+        dup2_x2;
+        return;
+    }
+}
+
+
+// Test that VerifyError is thrown if dup2_x2 tries to replace the filler slot
+// of a category 2 value.
+// The stack map is long,top,null,null,null.  The verifier should reject dup2_x2's
+// (form 1) attempt to turn the stack map into long,top,null,null,null,top,null.
+public class dup2_x2_long_refs version 51:0 {
+    public static Method run:"()V" stack 6 locals 0 {
+        lconst_0;
+        aconst_null;
+        aconst_null;
+        aconst_null;
+        dup2_x2;
+        return;
+    }
+}
+
+
+// Test that VerifyError is thrown when dup2 is used to remove the upper
+// half of a category 2 type.
+public class dup2longtop version 51:0 {
+    public static Method main:"([Ljava/lang/String;)V" stack 5 locals 1 {
+        lconst_0;
+        iconst_0;
+        dup2;
+        return;
+    }
+}
+
+
+// Test that VerifyError is thrown when dup2 is used to remove top
+// because top may be the upper half of a category 2 type.
+public class dup2toptop version 51:0 {
+    public static Method main:"([Ljava/lang/String;)V" stack 5 locals 1 {
+        // here we have {long, top, null}
+        // EXECUTION: we have {long, null}
+        lconst_0;
+        aconst_null;
+
+        stack_frame_type full;
+        stack_map bogus, bogus, null;
+        locals_map bogus;
+
+        // VERIFIER: use form1 of dup2 - {top, top, null} -> {top, top, null, top, null}
+        // EXECUTION: have {long, null} - no applicable form of dup2 for such type state by JVMS ch. 6
+        dup2;
+
+        return;
+    }
+}
+
+
+// Test that VerifyError is thrown if dup_x1 tries to replace the filler slot
+// of a category 2 value.
+public class dup_x1 version 51:0 {
+    public static Method run:"()V" stack 6 locals 0 {
+        lconst_0;
+        aconst_null;
+        dup_x1;
+        return;
+    }
+}
+
+
+// Test that VerifyError is thrown when pop2 is used to remove top
+// because top may be the upper half of a category 2 type.
+public class pop2longtop version 51:0
+{
+
+    public Method regular:"()V" stack 6 locals 6
+    {
+        lconst_0;
+        iconst_0;
+        stack_frame_type full;
+        stack_map long, bogus;
+        locals_map;
+        pop2;
+        return;
+    }
+} // end Class pop2longtop
+
+
+
+// Test that VerifyError is thrown when pop2 is used to remove top, top
+// because either top may be the upper half of a category 2 type.
+public class pop2toptop version 51:0
+{
+
+    public Method regular:"()V" stack 6 locals 6
+    {
+        iconst_0;
+        iconst_0;
+        stack_frame_type full;
+        stack_map bogus, bogus;
+        locals_map;
+        pop2;
+        return;
+    }
+} // end Class pop2toptop
+
+
+
+// Test that VerifyError is thrown when pop is used to remove top
+// because top may be the upper half of a category 2 type.
+public class poptop version 51:0
+{
+
+    public Method regular:"()V" stack 2 locals 1
+    {
+        iconst_0;
+        stack_frame_type full;
+        stack_map bogus;
+        pop;
+        return;
+    }
+} // end Class poptop
+
+
+
+// Test that VerifyError is thrown when pop is used to remove top, top
+// because either top may be the upper half of a category 2 type.
+public class poptoptop version 51:0
+{
+
+    public Method regular:"()V" stack 2 locals 1
+    {
+        iconst_0;
+        iconst_0;
+        stack_frame_type full;
+        stack_map bogus, bogus;
+        pop;
+        return;
+    }
+} // end Class poptoptop
+
+
+
+// Test that VerifyError is thrown when swap is used to swap int, top
+// because top may be the lower half of a category 2 type.
+public class swapinttop version 51:0
+{
+
+    public Method regular:"()V" stack 6 locals 6
+    {
+        iconst_0;
+        iconst_0;
+        stack_frame_type full;
+        stack_map int, bogus;
+        locals_map;
+        swap;
+        return;
+    }
+} // end Class swapinttop
+
+
+
+// Test that VerifyError is thrown when swap is used to swap top, int
+// because top may be the upper half of a category 2 type.
+public class swaptopint version 51:0
+{
+
+    public Method regular:"()V" stack 6 locals 6
+    {
+        iconst_0;
+        iconst_0;
+        stack_frame_type full;
+        stack_map bogus, int;
+        locals_map;
+        swap;
+        return;
+    }
+} // end Class swaptopint
+
+
+
+// Test that VerifyError is thrown when swap is used to swap top, top
+// because either top may be the upper half of a category 2 type.
+public class swaptoptop version 51:0
+{
+
+    public Method regular:"()V" stack 6 locals 6
+    {
+        iconst_0;
+        iconst_0;
+        stack_frame_type full;
+        stack_map bogus, bogus;
+        locals_map;
+        swap;
+        return;
+    }
+} // end Class swaptoptop
--- a/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/PathHandler.java	Wed Sep 21 01:33:21 2016 -0700
+++ b/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/PathHandler.java	Wed Sep 21 08:38:21 2016 +0000
@@ -39,7 +39,7 @@
  * Concrete subclasses should implement method {@link #process()}.
  */
 public abstract class PathHandler {
-    private static final Unsafe UNSAFE = jdk.test.lib.unsafe.UnsafeHelper.getUnsafe();
+    private static final Unsafe UNSAFE = Unsafe.getUnsafe();
     private static final AtomicLong CLASS_COUNT = new AtomicLong(0L);
     private static volatile boolean CLASSES_LIMIT_REACHED = false;
     private static final Pattern JAR_IN_DIR_PATTERN
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/testlibrary/jvmti/TransformUtil.java	Wed Sep 21 08:38:21 2016 +0000
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 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.
+ */
+
+
+public class TransformUtil {
+    public static final String BeforePattern = "this-should-be-transformed";
+    public static final String AfterPattern  = "this-has-been--transformed";
+    public static final String ParentCheckPattern = "parent-transform-check: ";
+    public static final String ChildCheckPattern = "child-transform-check: ";
+
+    /**
+     * @return the number of occurrences of the <code>from</code> string that
+     * have been replaced.
+     */
+    public static int replace(byte buff[], String from, String to) {
+        if (to.length() != from.length()) {
+            throw new RuntimeException("bad strings");
+        }
+        byte f[] = asciibytes(from);
+        byte t[] = asciibytes(to);
+        byte f0 = f[0];
+
+        int numReplaced = 0;
+        int max = buff.length - f.length;
+        for (int i = 0; i < max; ) {
+            if (buff[i] == f0 && replace(buff, f, t, i)) {
+                i += f.length;
+                numReplaced++;
+            } else {
+                i++;
+            }
+        }
+        return numReplaced;
+    }
+
+    public static boolean replace(byte buff[], byte f[], byte t[], int i) {
+        for (int x = 0; x < f.length; x++) {
+            if (buff[x+i] != f[x]) {
+                return false;
+            }
+        }
+        for (int x = 0; x < f.length; x++) {
+            buff[x+i] = t[x];
+        }
+        return true;
+    }
+
+    static byte[] asciibytes(String s) {
+        byte b[] = new byte[s.length()];
+        for (int i = 0; i < b.length; i++) {
+            b[i] = (byte)s.charAt(i);
+        }
+        return b;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/testlibrary/jvmti/TransformerAgent.java	Wed Sep 21 08:38:21 2016 +0000
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 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.
+ */
+
+import java.lang.instrument.ClassFileTransformer;
+import java.lang.instrument.IllegalClassFormatException;
+import java.lang.instrument.Instrumentation;
+import java.security.ProtectionDomain;
+import java.util.HashMap;
+
+// This is a test utility class used to transform
+// specified classes via initial transformation (ClassFileLoadHook).
+// Names of classes to be transformed are supplied as arguments,
+// the phrase to be transformed is a hard-coded predefined
+// fairly unique phrase.
+
+public class TransformerAgent {
+    private static String[] classesToTransform;
+
+
+    private static void log(String msg) {
+        System.out.println("TransformerAgent: " + msg);
+    }
+
+
+    // arguments are comma-separated list of classes to transform
+    public static void premain(String agentArguments, Instrumentation instrumentation) {
+        log("premain() is called, arguments = " + agentArguments);
+        classesToTransform = agentArguments.split(",");
+        instrumentation.addTransformer(new SimpleTransformer(), /*canRetransform=*/true);
+    }
+
+
+    public static void agentmain(String args, Instrumentation inst) throws Exception {