changeset 11571:22bf6db9767b jdk-9+128

Merge
author amurillo
date Thu, 14 Jul 2016 16:21:57 +0000
parents 27f732a0a63c 23f9f75195b5
children ba34c407a6ea 4c809569da7a 19277b56bc7d
files
diffstat 33 files changed, 1392 insertions(+), 80 deletions(-) [+]
line wrap: on
line diff
--- a/make/gensrc/GensrcDtrace.gmk	Thu Jul 14 15:47:44 2016 +0000
+++ b/make/gensrc/GensrcDtrace.gmk	Thu Jul 14 16:21:57 2016 +0000
@@ -45,7 +45,8 @@
   $(DTRACE_GENSRC_DIR)/%.h: $(DTRACE_SOURCE_DIR)/%.d
 	$(call LogInfo, Generating dtrace header file $(@F))
 	$(call MakeDir, $(@D) $(DTRACE_SUPPORT_DIR))
-	$(call ExecuteWithLog, $(DTRACE_SUPPORT_DIR)/$(@F).d, $(CC) -E $(DTRACE_CPP_FLAGS) $< > $(DTRACE_SUPPORT_DIR)/$(@F).d)
+	$(call ExecuteWithLog, $(DTRACE_SUPPORT_DIR)/$(@F).d, \
+	    ( $(CC) -E $(DTRACE_CPP_FLAGS) $< > $(DTRACE_SUPPORT_DIR)/$(@F).d ) )
 	$(call ExecuteWithLog, $@, $(DTRACE) $(DTRACE_FLAGS) -h -o $@ -s $(DTRACE_SUPPORT_DIR)/$(@F).d)
 
   # Process all .d files in DTRACE_SOURCE_DIR. They are:
--- a/make/lib/CompileDtracePostJvm.gmk	Thu Jul 14 15:47:44 2016 +0000
+++ b/make/lib/CompileDtracePostJvm.gmk	Thu Jul 14 16:21:57 2016 +0000
@@ -68,7 +68,7 @@
       $1: $$(BUILD_DTRACE_GEN_OFFSETS)
 	$$(call LogInfo, Generating dtrace $2 file $$(@F))
 	$$(call MakeDir, $$(@D))
-	$$(call ExecuteWithLog, $$@, $$(DTRACE_GEN_OFFSETS_TOOL) -$$(strip $2) > $$@)
+	$$(call ExecuteWithLog, $$@, ( $$(DTRACE_GEN_OFFSETS_TOOL) -$$(strip $2) > $$@ ) )
 
       TARGETS += $1
     endef
--- a/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/UncommonTrap.java	Thu Jul 14 15:47:44 2016 +0000
+++ b/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/UncommonTrap.java	Thu Jul 14 16:21:57 2016 +0000
@@ -16,9 +16,9 @@
  * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
+ * 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 com.sun.hotspot.tools.compiler;
--- a/src/share/vm/classfile/classLoaderData.cpp	Thu Jul 14 15:47:44 2016 +0000
+++ b/src/share/vm/classfile/classLoaderData.cpp	Thu Jul 14 16:21:57 2016 +0000
@@ -501,13 +501,26 @@
   }
 }
 
-/**
- * Returns true if this class loader data is for the platform class loader.
- */
+// Returns true if this class loader data is for the system class loader.
+bool ClassLoaderData::is_system_class_loader_data() const {
+  return SystemDictionary::is_system_class_loader(class_loader());
+}
+
+// Returns true if this class loader data is for the platform class loader.
 bool ClassLoaderData::is_platform_class_loader_data() const {
   return SystemDictionary::is_platform_class_loader(class_loader());
 }
 
+// Returns true if this class loader data is one of the 3 builtin
+// (boot, application/system or platform) class loaders. Note, the
+// builtin loaders are not freed by a GC.
+bool ClassLoaderData::is_builtin_class_loader_data() const {
+  Handle classLoaderHandle = class_loader();
+  return (is_the_null_class_loader_data() ||
+          SystemDictionary::is_system_class_loader(classLoaderHandle) ||
+          SystemDictionary::is_platform_class_loader(classLoaderHandle));
+}
+
 Metaspace* ClassLoaderData::metaspace_non_null() {
   assert(!DumpSharedSpaces, "wrong metaspace!");
   // If the metaspace has not been allocated, create a new one.  Might want
@@ -957,12 +970,6 @@
   data = _head;
   while (data != NULL) {
     if (data->is_alive(is_alive_closure)) {
-      if (data->packages_defined()) {
-        data->packages()->purge_all_package_exports();
-      }
-      if (data->modules_defined()) {
-        data->modules()->purge_all_module_reads();
-      }
       // clean metaspace
       if (walk_all_metadata) {
         data->classes_do(InstanceKlass::purge_previous_versions);
@@ -990,6 +997,23 @@
   }
 
   if (seen_dead_loader) {
+    // Walk a ModuleEntry's reads and a PackageEntry's exports lists
+    // to determine if there are modules on those lists that are now
+    // dead and should be removed.  A module's life cycle is equivalent
+    // to its defining class loader's life cycle.  Since a module is
+    // considered dead if its class loader is dead, these walks must
+    // occur after each class loader's aliveness is determined.
+    data = _head;
+    while (data != NULL) {
+      if (data->packages_defined()) {
+        data->packages()->purge_all_package_exports();
+      }
+      if (data->modules_defined()) {
+        data->modules()->purge_all_module_reads();
+      }
+      data = data->next();
+    }
+
     post_class_unload_events();
   }
 
--- a/src/share/vm/classfile/classLoaderData.hpp	Thu Jul 14 15:47:44 2016 +0000
+++ b/src/share/vm/classfile/classLoaderData.hpp	Thu Jul 14 16:21:57 2016 +0000
@@ -270,7 +270,9 @@
   bool is_the_null_class_loader_data() const {
     return this == _the_null_class_loader_data;
   }
+  bool is_system_class_loader_data() const;
   bool is_platform_class_loader_data() const;
+  bool is_builtin_class_loader_data() const;
 
   // The Metaspace is created lazily so may be NULL.  This
   // method will allocate a Metaspace if needed.
--- a/src/share/vm/classfile/compactHashtable.cpp	Thu Jul 14 15:47:44 2016 +0000
+++ b/src/share/vm/classfile/compactHashtable.cpp	Thu Jul 14 16:21:57 2016 +0000
@@ -248,7 +248,7 @@
     } else {
       u4*entry_max = _entries + BUCKET_OFFSET(_buckets[i + 1]);
       while (entry < entry_max) {
-        iterator.do_value(_base_address, entry[0]);
+        iterator.do_value(_base_address, entry[1]);
         entry += 2;
       }
     }
--- a/src/share/vm/classfile/moduleEntry.cpp	Thu Jul 14 15:47:44 2016 +0000
+++ b/src/share/vm/classfile/moduleEntry.cpp	Thu Jul 14 16:21:57 2016 +0000
@@ -40,7 +40,6 @@
 
 ModuleEntry* ModuleEntryTable::_javabase_module = NULL;
 
-
 void ModuleEntry::set_location(Symbol* location) {
   if (_location != NULL) {
     // _location symbol's refcounts are managed by ModuleEntry,
@@ -115,10 +114,35 @@
       // Lazily create a module's reads list
       _reads = new (ResourceObj::C_HEAP, mtModule)GrowableArray<ModuleEntry*>(MODULE_READS_SIZE, true);
     }
+
+    // Determine, based on this newly established read edge to module m,
+    // if this module's read list should be walked at a GC safepoint.
+    set_read_walk_required(m->loader_data());
+
+    // Establish readability to module m
     _reads->append_if_missing(m);
   }
 }
 
+// If the module's loader, that a read edge is being established to, is
+// not the same loader as this module's and is not one of the 3 builtin
+// class loaders, then this module's reads list must be walked at GC
+// safepoint. Modules have the same life cycle as their defining class
+// loaders and should be removed if dead.
+void ModuleEntry::set_read_walk_required(ClassLoaderData* m_loader_data) {
+  assert_locked_or_safepoint(Module_lock);
+  if (!_must_walk_reads &&
+      loader_data() != m_loader_data &&
+      !m_loader_data->is_builtin_class_loader_data()) {
+    _must_walk_reads = true;
+    if (log_is_enabled(Trace, modules)) {
+      ResourceMark rm;
+      log_trace(modules)("ModuleEntry::set_read_walk_required(): module %s reads list must be walked",
+                         (name() != NULL) ? name()->as_C_string() : UNNAMED_MODULE);
+    }
+  }
+}
+
 bool ModuleEntry::has_reads() const {
   assert_locked_or_safepoint(Module_lock);
   return ((_reads != NULL) && !_reads->is_empty());
@@ -127,14 +151,28 @@
 // Purge dead module entries out of reads list.
 void ModuleEntry::purge_reads() {
   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
-  if (has_reads()) {
+
+  if (_must_walk_reads && has_reads()) {
+    // This module's _must_walk_reads flag will be reset based
+    // on the remaining live modules on the reads list.
+    _must_walk_reads = false;
+
+    if (log_is_enabled(Trace, modules)) {
+      ResourceMark rm;
+      log_trace(modules)("ModuleEntry::purge_reads(): module %s reads list being walked",
+                         (name() != NULL) ? name()->as_C_string() : UNNAMED_MODULE);
+    }
+
     // Go backwards because this removes entries that are dead.
     int len = _reads->length();
     for (int idx = len - 1; idx >= 0; idx--) {
       ModuleEntry* module_idx = _reads->at(idx);
-      ClassLoaderData* cld = module_idx->loader();
-      if (cld->is_unloading()) {
+      ClassLoaderData* cld_idx = module_idx->loader_data();
+      if (cld_idx->is_unloading()) {
         _reads->delete_at(idx);
+      } else {
+        // Update the need to walk this module's reads based on live modules
+        set_read_walk_required(cld_idx);
       }
     }
   }
@@ -248,7 +286,7 @@
     entry->set_module(loader_data->add_handle(module_handle));
   }
 
-  entry->set_loader(loader_data);
+  entry->set_loader_data(loader_data);
   entry->set_version(version);
   entry->set_location(location);
 
@@ -375,11 +413,11 @@
 
 void ModuleEntry::print(outputStream* st) {
   ResourceMark rm;
-  st->print_cr("entry "PTR_FORMAT" name %s module "PTR_FORMAT" loader %s version %s location %s strict %s next "PTR_FORMAT,
+  st->print_cr("entry " PTR_FORMAT " name %s module " PTR_FORMAT " loader %s version %s location %s strict %s next " PTR_FORMAT,
                p2i(this),
                name() == NULL ? UNNAMED_MODULE : name()->as_C_string(),
                p2i(module()),
-               loader()->loader_name(),
+               loader_data()->loader_name(),
                version() != NULL ? version()->as_C_string() : "NULL",
                location() != NULL ? location()->as_C_string() : "NULL",
                BOOL_TO_STR(!can_read_all_unnamed()), p2i(next()));
@@ -401,5 +439,5 @@
 }
 
 void ModuleEntry::verify() {
-  guarantee(loader() != NULL, "A module entry must be associated with a loader.");
+  guarantee(loader_data() != NULL, "A module entry must be associated with a loader.");
 }
--- a/src/share/vm/classfile/moduleEntry.hpp	Thu Jul 14 15:47:44 2016 +0000
+++ b/src/share/vm/classfile/moduleEntry.hpp	Thu Jul 14 16:21:57 2016 +0000
@@ -43,6 +43,7 @@
 // It contains:
 //   - Symbol* containing the module's name.
 //   - pointer to the java.lang.reflect.Module for this module.
+//   - pointer to the java.security.ProtectionDomain shared by classes defined to this module.
 //   - ClassLoaderData*, class loader of this module.
 //   - a growable array containg other module entries that this module can read.
 //   - a flag indicating if this module can read all unnamed modules.
@@ -54,56 +55,58 @@
   jobject _module;                     // java.lang.reflect.Module
   jobject _pd;                         // java.security.ProtectionDomain, cached
                                        // for shared classes from this module
-  ClassLoaderData* _loader;
+  ClassLoaderData* _loader_data;
   GrowableArray<ModuleEntry*>* _reads; // list of modules that are readable by this module
   Symbol* _version;                    // module version number
   Symbol* _location;                   // module location
   bool _can_read_all_unnamed;
   bool _has_default_read_edges;        // JVMTI redefine/retransform support
+  bool _must_walk_reads;               // walk module's reads list at GC safepoints to purge out dead modules
   TRACE_DEFINE_TRACE_ID_FIELD;
   enum {MODULE_READS_SIZE = 101};      // Initial size of list of modules that the module can read.
 
 public:
   void init() {
     _module = NULL;
-    _loader = NULL;
+    _loader_data = NULL;
     _pd = NULL;
     _reads = NULL;
     _version = NULL;
     _location = NULL;
     _can_read_all_unnamed = false;
     _has_default_read_edges = false;
+    _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
   // created by the ClassLoader when loading a class (shared or non-shared) from the
   // Module for the first time. This ProtectionDomain object is used for all
   // classes from the Module loaded by the same ClassLoader.
-  Handle             shared_protection_domain();
-  void               set_shared_protection_domain(ClassLoaderData *loader_data,
-                                                  Handle pd);
+  Handle           shared_protection_domain();
+  void             set_shared_protection_domain(ClassLoaderData *loader_data, Handle pd);
 
-  ClassLoaderData*   loader() const                 { return _loader; }
-  void               set_loader(ClassLoaderData* l) { _loader = l; }
+  ClassLoaderData* loader_data() const                 { return _loader_data; }
+  void             set_loader_data(ClassLoaderData* l) { _loader_data = l; }
 
-  Symbol*            version() const                { return _version; }
-  void               set_version(Symbol* version);
+  Symbol*          version() const                     { return _version; }
+  void             set_version(Symbol* version);
 
-  Symbol*            location() const               { return _location; }
-  void               set_location(Symbol* location);
+  Symbol*          location() const                    { return _location; }
+  void             set_location(Symbol* location);
 
-  bool               can_read(ModuleEntry* m) const;
-  bool               has_reads() const;
-  void               add_read(ModuleEntry* m);
+  bool             can_read(ModuleEntry* m) const;
+  bool             has_reads() const;
+  void             add_read(ModuleEntry* m);
+  void             set_read_walk_required(ClassLoaderData* m_loader_data);
 
-  bool               is_named() const               { return (literal() != NULL); }
+  bool             is_named() const                    { return (name() != NULL); }
 
   bool can_read_all_unnamed() const {
     assert(is_named() || _can_read_all_unnamed == true,
@@ -178,7 +181,7 @@
   ModuleEntry* _unnamed_module;
 
   ModuleEntry* new_entry(unsigned int hash, Handle module_handle, Symbol* name, Symbol* version,
-                         Symbol* location, ClassLoaderData* class_loader);
+                         Symbol* location, ClassLoaderData* loader_data);
   void add_entry(int index, ModuleEntry* new_entry);
 
   int entry_size() const { return BasicHashtable<mtModule>::entry_size(); }
--- a/src/share/vm/classfile/modules.cpp	Thu Jul 14 15:47:44 2016 +0000
+++ b/src/share/vm/classfile/modules.cpp	Thu Jul 14 16:21:57 2016 +0000
@@ -113,7 +113,7 @@
   const char *package_name = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(package));
   if (package_name == NULL) return NULL;
   TempNewSymbol pkg_symbol = SymbolTable::new_symbol(package_name, CHECK_NULL);
-  PackageEntryTable* package_entry_table = module_entry->loader()->packages();
+  PackageEntryTable* package_entry_table = module_entry->loader_data()->packages();
   assert(package_entry_table != NULL, "Unexpected null package entry table");
   return package_entry_table->lookup_only(pkg_symbol);
 }
@@ -868,7 +868,7 @@
                      package_name, module_entry->name()->as_C_string());
 
   TempNewSymbol pkg_symbol = SymbolTable::new_symbol(package_name, CHECK);
-  PackageEntryTable* package_table = module_entry->loader()->packages();
+  PackageEntryTable* package_table = module_entry->loader_data()->packages();
   assert(package_table != NULL, "Missing package_table");
 
   bool pkg_exists = false;
--- a/src/share/vm/classfile/packageEntry.cpp	Thu Jul 14 15:47:44 2016 +0000
+++ b/src/share/vm/classfile/packageEntry.cpp	Thu Jul 14 16:21:57 2016 +0000
@@ -25,6 +25,7 @@
 #include "precompiled.hpp"
 #include "classfile/moduleEntry.hpp"
 #include "classfile/packageEntry.hpp"
+#include "logging/log.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/symbol.hpp"
 #include "runtime/handles.inline.hpp"
@@ -53,12 +54,40 @@
   if (!has_qual_exports_list()) {
     // Lazily create a package's qualified exports list.
     // Initial size is small, do not anticipate export lists to be large.
-    _qualified_exports =
-      new (ResourceObj::C_HEAP, mtModule) GrowableArray<ModuleEntry*>(QUAL_EXP_SIZE, true);
+    _qualified_exports = new (ResourceObj::C_HEAP, mtModule) GrowableArray<ModuleEntry*>(QUAL_EXP_SIZE, true);
   }
+
+  // Determine, based on this newly established export to module m,
+  // if this package's export list should be walked at a GC safepoint.
+  set_export_walk_required(m->loader_data());
+
+  // Establish exportability to module m
   _qualified_exports->append_if_missing(m);
 }
 
+// If the module's loader, that an export is being established to, is
+// not the same loader as this module's and is not one of the 3 builtin
+// class loaders, then this package's export list must be walked at GC
+// safepoint. Modules have the same life cycle as their defining class
+// loaders and should be removed if dead.
+void PackageEntry::set_export_walk_required(ClassLoaderData* m_loader_data) {
+  assert_locked_or_safepoint(Module_lock);
+  ModuleEntry* this_pkg_mod = module();
+  if (!_must_walk_exports &&
+      (this_pkg_mod == NULL || this_pkg_mod->loader_data() != m_loader_data) &&
+      !m_loader_data->is_builtin_class_loader_data()) {
+    _must_walk_exports = true;
+    if (log_is_enabled(Trace, modules)) {
+      ResourceMark rm;
+      assert(name() != NULL, "PackageEntry without a valid name");
+      log_trace(modules)("PackageEntry::set_export_walk_required(): package %s defined in module %s, exports list must be walked",
+                         name()->as_C_string(),
+                         (this_pkg_mod == NULL || this_pkg_mod->name() == NULL) ?
+                           UNNAMED_MODULE : this_pkg_mod->name()->as_C_string());
+    }
+  }
+}
+
 // Set the package's exported states based on the value of the ModuleEntry.
 void PackageEntry::set_exported(ModuleEntry* m) {
   MutexLocker m1(Module_lock);
@@ -96,14 +125,34 @@
 // Remove dead module entries within the package's exported list.
 void PackageEntry::purge_qualified_exports() {
   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
-  if (_qualified_exports != NULL) {
+  if (_must_walk_exports &&
+      _qualified_exports != NULL &&
+      !_qualified_exports->is_empty()) {
+    ModuleEntry* pkg_module = module();
+
+    // This package's _must_walk_exports flag will be reset based
+    // on the remaining live modules on the exports list.
+    _must_walk_exports = false;
+
+    if (log_is_enabled(Trace, modules)) {
+      ResourceMark rm;
+      assert(name() != NULL, "PackageEntry without a valid name");
+      ModuleEntry* pkg_mod = module();
+      log_trace(modules)("PackageEntry::purge_qualified_exports(): package %s defined in module %s, exports list being walked",
+                         name()->as_C_string(),
+                         (pkg_mod == NULL || pkg_mod->name() == NULL) ? UNNAMED_MODULE : pkg_mod->name()->as_C_string());
+    }
+
     // Go backwards because this removes entries that are dead.
     int len = _qualified_exports->length();
     for (int idx = len - 1; idx >= 0; idx--) {
       ModuleEntry* module_idx = _qualified_exports->at(idx);
-      ClassLoaderData* cld = module_idx->loader();
-      if (cld->is_unloading()) {
+      ClassLoaderData* cld_idx = module_idx->loader_data();
+      if (cld_idx->is_unloading()) {
         _qualified_exports->delete_at(idx);
+      } else {
+        // Update the need to walk this package's exports based on live modules
+        set_export_walk_required(cld_idx);
       }
     }
   }
@@ -297,8 +346,8 @@
 
 void PackageEntry::print(outputStream* st) {
   ResourceMark rm;
-  st->print_cr("package entry "PTR_FORMAT" name %s module %s classpath_index "
-               INT32_FORMAT " is_exported_unqualified %d is_exported_allUnnamed %d " "next "PTR_FORMAT,
+  st->print_cr("package entry " PTR_FORMAT " name %s module %s classpath_index "
+               INT32_FORMAT " is_exported_unqualified %d is_exported_allUnnamed %d " "next " PTR_FORMAT,
                p2i(this), name()->as_C_string(),
                (module()->is_named() ? module()->name()->as_C_string() : UNNAMED_MODULE),
                _classpath_index, _is_exported_unqualified, _is_exported_allUnnamed, p2i(next()));
--- a/src/share/vm/classfile/packageEntry.hpp	Thu Jul 14 15:47:44 2016 +0000
+++ b/src/share/vm/classfile/packageEntry.hpp	Thu Jul 14 16:21:57 2016 +0000
@@ -69,6 +69,7 @@
   s2 _classpath_index;
   bool _is_exported_unqualified;
   bool _is_exported_allUnnamed;
+  bool _must_walk_exports;
   GrowableArray<ModuleEntry*>* _exported_pending_delete; // transitioned from qualified to unqualified, delete at safepoint
   GrowableArray<ModuleEntry*>* _qualified_exports;
   TRACE_DEFINE_TRACE_ID_FIELD;
@@ -82,6 +83,7 @@
     _classpath_index = -1;
     _is_exported_unqualified = false;
     _is_exported_allUnnamed = false;
+    _must_walk_exports = false;
     _exported_pending_delete = NULL;
     _qualified_exports = NULL;
   }
@@ -147,6 +149,7 @@
 
   // add the module to the package's qualified exports
   void add_qexport(ModuleEntry* m);
+  void set_export_walk_required(ClassLoaderData* m_loader_data);
 
   PackageEntry* next() const {
     return (PackageEntry*)HashtableEntry<Symbol*, mtModule>::next();
--- a/src/share/vm/classfile/systemDictionary.cpp	Thu Jul 14 15:47:44 2016 +0000
+++ b/src/share/vm/classfile/systemDictionary.cpp	Thu Jul 14 16:21:57 2016 +0000
@@ -175,9 +175,18 @@
    return false;
 }
 
-/**
- * Returns true if the passed class loader is the platform class loader.
- */
+// Returns true if the passed class loader is the builtin application class loader
+// or a custom system class loader. A customer system class loader can be
+// specified via -Djava.system.class.loader.
+bool SystemDictionary::is_system_class_loader(Handle class_loader) {
+  if (class_loader.is_null()) {
+    return false;
+  }
+  return (class_loader->klass() == SystemDictionary::jdk_internal_loader_ClassLoaders_AppClassLoader_klass() ||
+          class_loader() == _java_system_loader);
+}
+
+// Returns true if the passed class loader is the platform class loader.
 bool SystemDictionary::is_platform_class_loader(Handle class_loader) {
   if (class_loader.is_null()) {
     return false;
--- a/src/share/vm/classfile/systemDictionary.hpp	Thu Jul 14 15:47:44 2016 +0000
+++ b/src/share/vm/classfile/systemDictionary.hpp	Thu Jul 14 16:21:57 2016 +0000
@@ -660,6 +660,7 @@
   static instanceKlassHandle load_shared_class(Symbol* class_name,
                                                Handle class_loader,
                                                TRAPS);
+  static bool is_system_class_loader(Handle class_loader);
   static bool is_platform_class_loader(Handle class_loader);
 
 protected:
--- a/src/share/vm/gc/shared/preservedMarks.cpp	Thu Jul 14 15:47:44 2016 +0000
+++ b/src/share/vm/gc/shared/preservedMarks.cpp	Thu Jul 14 16:21:57 2016 +0000
@@ -48,10 +48,10 @@
 
 #ifndef PRODUCT
 void PreservedMarks::assert_empty() {
-  assert(_stack.is_empty(), "stack expected to be empty, size = "SIZE_FORMAT,
+  assert(_stack.is_empty(), "stack expected to be empty, size = " SIZE_FORMAT,
          _stack.size());
   assert(_stack.cache_size() == 0,
-         "stack expected to have no cached segments, cache size = "SIZE_FORMAT,
+         "stack expected to have no cached segments, cache size = " SIZE_FORMAT,
          _stack.cache_size());
 }
 #endif // ndef PRODUCT
--- a/src/share/vm/interpreter/rewriter.cpp	Thu Jul 14 15:47:44 2016 +0000
+++ b/src/share/vm/interpreter/rewriter.cpp	Thu Jul 14 16:21:57 2016 +0000
@@ -419,21 +419,20 @@
             InstanceKlass* klass = method->method_holder();
             u2 bc_index = Bytes::get_Java_u2(bcp + prefix_length + 1);
             constantPoolHandle cp(method->constants());
-            Symbol* field_name = cp->name_ref_at(bc_index);
-            Symbol* field_sig = cp->signature_ref_at(bc_index);
             Symbol* ref_class_name = cp->klass_name_at(cp->klass_ref_index_at(bc_index));
 
             if (klass->name() == ref_class_name) {
+              Symbol* field_name = cp->name_ref_at(bc_index);
+              Symbol* field_sig = cp->signature_ref_at(bc_index);
+
               fieldDescriptor fd;
               klass->find_field(field_name, field_sig, &fd);
               if (fd.access_flags().is_final()) {
                 if (fd.access_flags().is_static()) {
-                  assert(c == Bytecodes::_putstatic, "must be putstatic");
                   if (!method->is_static_initializer()) {
                     fd.set_has_initialized_final_update(true);
                   }
                 } else {
-                  assert(c == Bytecodes::_putfield, "must be putfield");
                   if (!method->is_object_initializer()) {
                     fd.set_has_initialized_final_update(true);
                   }
--- a/src/share/vm/runtime/arguments.cpp	Thu Jul 14 15:47:44 2016 +0000
+++ b/src/share/vm/runtime/arguments.cpp	Thu Jul 14 16:21:57 2016 +0000
@@ -584,27 +584,26 @@
 // Parses a size specification string.
 bool Arguments::atojulong(const char *s, julong* result) {
   julong n = 0;
-  int args_read = 0;
-  bool is_hex = false;
-  // Skip leading 0[xX] for hexadecimal
-  if (*s =='0' && (*(s+1) == 'x' || *(s+1) == 'X')) {
-    s += 2;
-    is_hex = true;
-    args_read = sscanf(s, JULONG_FORMAT_X, &n);
-  } else {
-    args_read = sscanf(s, JULONG_FORMAT, &n);
-  }
-  if (args_read != 1) {
+
+  // First char must be a digit. Don't allow negative numbers or leading spaces.
+  if (!isdigit(*s)) {
     return false;
   }
-  while (*s != '\0' && (isdigit(*s) || (is_hex && isxdigit(*s)))) {
-    s++;
-  }
-  // 4705540: illegal if more characters are found after the first non-digit
-  if (strlen(s) > 1) {
+
+  bool is_hex = (s[0] == '0' && (s[1] == 'x' || s[1] == 'X'));
+  char* remainder;
+  errno = 0;
+  n = strtoull(s, &remainder, (is_hex ? 16 : 10));
+  if (errno != 0) {
     return false;
   }
-  switch (*s) {
+
+  // Fail if no number was read at all or if the remainder contains more than a single non-digit character.
+  if (remainder == s || strlen(remainder) > 1) {
+    return false;
+  }
+
+  switch (*remainder) {
     case 'T': case 't':
       *result = n * G * K;
       // Check for overflow.
--- a/src/share/vm/utilities/vmError.cpp	Thu Jul 14 15:47:44 2016 +0000
+++ b/src/share/vm/utilities/vmError.cpp	Thu Jul 14 16:21:57 2016 +0000
@@ -205,16 +205,39 @@
 static void print_oom_reasons(outputStream* st) {
   st->print_cr("# Possible reasons:");
   st->print_cr("#   The system is out of physical RAM or swap space");
-  st->print_cr("#   In 32 bit mode, the process size limit was hit");
+  if (UseCompressedOops) {
+    st->print_cr("#   The process is running with CompressedOops enabled, and the Java Heap may be blocking the growth of the native heap");
+  }
+  if (LogBytesPerWord == 2) {
+    st->print_cr("#   In 32 bit mode, the process size limit was hit");
+  }
   st->print_cr("# Possible solutions:");
   st->print_cr("#   Reduce memory load on the system");
   st->print_cr("#   Increase physical memory or swap space");
   st->print_cr("#   Check if swap backing store is full");
-  st->print_cr("#   Use 64 bit Java on a 64 bit OS");
+  if (LogBytesPerWord == 2) {
+    st->print_cr("#   Use 64 bit Java on a 64 bit OS");
+  }
   st->print_cr("#   Decrease Java heap size (-Xmx/-Xms)");
   st->print_cr("#   Decrease number of Java threads");
   st->print_cr("#   Decrease Java thread stack sizes (-Xss)");
   st->print_cr("#   Set larger code cache with -XX:ReservedCodeCacheSize=");
+  if (UseCompressedOops) {
+    switch (Universe::narrow_oop_mode()) {
+      case Universe::UnscaledNarrowOop:
+        st->print_cr("#   JVM is running with Unscaled Compressed Oops mode in which the Java heap is");
+        st->print_cr("#     placed in the first 4GB address space. The Java Heap base address is the");
+        st->print_cr("#     maximum limit for the native heap growth. Please use -XX:HeapBaseMinAddress");
+        st->print_cr("#     to set the Java Heap base and to place the Java Heap above 4GB virtual address.");
+        break;
+      case Universe::ZeroBasedNarrowOop:
+        st->print_cr("#   JVM is running with Zero Based Compressed Oops mode in which the Java heap is");
+        st->print_cr("#     placed in the first 32GB address space. The Java Heap base address is the");
+        st->print_cr("#     maximum limit for the native heap growth. Please use -XX:HeapBaseMinAddress");
+        st->print_cr("#     to set the Java Heap base and to place the Java Heap above 32GB virtual address.");
+        break;
+    }
+  }
   st->print_cr("# This output file may be truncated or incomplete.");
 }
 
--- a/test/TEST.groups	Thu Jul 14 15:47:44 2016 +0000
+++ b/test/TEST.groups	Thu Jul 14 16:21:57 2016 +0000
@@ -395,6 +395,17 @@
   :hotspot_fast_gc_gcold \
   :hotspot_fast_runtime \
   :hotspot_fast_serviceability
+  
+hotspot_runtime_tier2 = \
+  runtime/ \
+  serviceability/ \
+ -:hotspot_fast_runtime \
+ -:hotspot_fast_serviceability \
+ -:hotspot_runtime_tier2_platform_agnostic
+ 
+hotspot_runtime_tier2_platform_agnostic = \
+  runtime/SelectionResolution \
+ -:hotspot_fast_runtime
 
 #All tests that depends on nashorn extension.
 #
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/gc/g1/humongousObjects/TestNoAllocationsInHRegions.java	Thu Jul 14 16:21:57 2016 +0000
@@ -0,0 +1,234 @@
+/*
+ * 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 gc.g1.humongousObjects;
+
+import jdk.test.lib.Utils;
+import sun.hotspot.WhiteBox;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Random;
+import java.util.stream.Collectors;
+
+/**
+ * @test TestNoAllocationsInHRegions
+ * @summary Checks that no additional allocations are made in humongous regions
+ * @requires vm.gc.G1
+ * @library /testlibrary /test/lib /
+ * @modules java.management java.base/jdk.internal.misc
+ * @build sun.hotspot.WhiteBox
+ *        gc.testlibrary.Helpers
+ *        gc.g1.humongousObjects.TestNoAllocationsInHRegions
+ *
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *      sun.hotspot.WhiteBox$WhiteBoxPermission
+ *
+ * @run main/othervm -XX:+UseG1GC -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:.
+ *                   -XX:G1HeapRegionSize=1M -Xms200m -Xmx200m -XX:MaxTenuringThreshold=0
+ *                   -Xlog:gc=trace:file=TestNoAllocationsInHRegions10.log
+ *                   gc.g1.humongousObjects.TestNoAllocationsInHRegions 30 10
+ *
+ * @run main/othervm -XX:+UseG1GC -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:.
+ *                   -XX:G1HeapRegionSize=1M -Xms200m -Xmx200m -XX:MaxTenuringThreshold=0
+ *                   -Xlog:gc=trace:file=TestNoAllocationsInHRegions50.log
+ *                   gc.g1.humongousObjects.TestNoAllocationsInHRegions 30 50
+ *
+ * @run main/othervm -XX:+UseG1GC -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:.
+ *                   -XX:G1HeapRegionSize=1M -Xms200m -Xmx200m -XX:MaxTenuringThreshold=0
+ *                   -Xlog:gc=trace:file=TestNoAllocationsInHRegions70.log
+ *                   gc.g1.humongousObjects.TestNoAllocationsInHRegions 30 70
+ */
+public class TestNoAllocationsInHRegions {
+    private static final WhiteBox WB = WhiteBox.getWhiteBox();
+    private static final Random RND = Utils.getRandomInstance();
+    private static final int G1_REGION_SIZE = WB.g1RegionSize();
+    private static final int[] HUMONGOUS_SIZES = {G1_REGION_SIZE / 2, G1_REGION_SIZE + 1, G1_REGION_SIZE * 2 + 1};
+    private static final int ALLOC_THREAD_COUNT = 5;
+
+    // We fill specified part of heap with humongous objects - we need public static to prevent escape analysis to
+    // collect this field
+    public static LinkedList<byte[]> humongousAllocations = new LinkedList<>();
+
+    private static volatile boolean shouldStop = false;
+    private static volatile Error error = null;
+
+    static class Allocator implements Runnable {
+
+        private final List<byte[]> liveObjects = new LinkedList<>();
+        private int usedMemory = 0;
+        public final Runnable[] actions;
+
+        /**
+         * Maximum size of simple allocation
+         */
+        private static final int MAX_ALLOCATION_SIZE = (int) (G1_REGION_SIZE / 2 * 0.9);
+
+        /**
+         * Maximum size of dead (i.e. one which is made unreachable right after allocation) object
+         */
+        private static final int DEAD_OBJECT_MAX_SIZE = G1_REGION_SIZE / 10;
+
+        public Allocator(int maxAllocationMemory) {
+
+            actions = new Runnable[]{
+                    // Allocation
+                    () -> {
+                        if (maxAllocationMemory - usedMemory != 0) {
+                            int arraySize = RND.nextInt(Math.min(maxAllocationMemory - usedMemory,
+                                    MAX_ALLOCATION_SIZE));
+
+                            if (arraySize != 0) {
+                                byte[] allocation = new byte[arraySize];
+                                liveObjects.add(allocation);
+                                usedMemory += arraySize;
+
+                                // Sanity check
+                                if (WB.g1IsHumongous(allocation)) {
+                                    String errorMessage = String.format("Test Bug: Byte array of size"
+                                                    + " %d is expected to be non-humongous but it is humongous",
+                                            allocation.length);
+
+                                    System.out.println(errorMessage);
+                                    error = new Error(errorMessage);
+                                    shouldStop = true;
+                                }
+
+                                // Test check
+                                if (WB.g1BelongsToHumongousRegion(WB.getObjectAddress(allocation))) {
+                                    String errorMessage = String.format("Non-humongous allocation of byte array of "
+                                            + "length %d and size %d with address %d was made in Humongous Region",
+                                            allocation.length, WB.getObjectSize(allocation),
+                                            WB.getObjectAddress(allocation));
+
+                                    System.out.println(errorMessage);
+                                    error = new Error(errorMessage);
+                                    shouldStop = true;
+                                }
+                            }
+                        }
+                    },
+
+                    // Deallocation
+                    () -> {
+                        if (liveObjects.size() != 0) {
+                            int elementNum = RND.nextInt(liveObjects.size());
+                            int shouldFree = liveObjects.get(elementNum).length;
+                            liveObjects.remove(elementNum);
+                            usedMemory -= shouldFree;
+                        }
+                    },
+
+                    // Dead object allocation
+                    () -> {
+                        int size = RND.nextInt(DEAD_OBJECT_MAX_SIZE);
+                        byte[] deadObject = new byte[size];
+                    },
+
+                    // Check
+                    () -> {
+                        List<byte[]> wrongHumongousAllocations = liveObjects.stream()
+                                .filter(WB::g1IsHumongous)
+                                .collect(Collectors.toList());
+
+                        if (wrongHumongousAllocations.size() > 0) {
+                            wrongHumongousAllocations.stream().forEach(a ->
+                                    System.out.format("Non-humongous allocation of byte array of length %d and"
+                                                    + " size %d with address %d was made in Humongous Region",
+                                            a.length, WB.getObjectSize(a), WB.getObjectAddress(a)));
+                            error = new Error("Some non-humongous allocations were made to humongous region");
+                            shouldStop = true;
+                        }
+                    }
+            };
+        }
+
+        @Override
+        public void run() {
+            while (!shouldStop) {
+                actions[RND.nextInt(actions.length)].run();
+                Thread.yield();
+            }
+        }
+    }
+
+    public static void main(String[] args) {
+        if (args.length != 2) {
+            throw new Error("Test Bug: Expected duration (in seconds) and percent of allocated regions were not "
+                    + "provided as command line argument");
+        }
+
+        // test duration
+        long duration = Integer.parseInt(args[0]) * 1000L;
+        // part of heap preallocated with humongous objects (in percents)
+        int percentOfAllocatedHeap = Integer.parseInt(args[1]);
+
+        long startTime = System.currentTimeMillis();
+
+        long initialFreeRegionsCount = WB.g1NumFreeRegions();
+        int regionsToAllocate = (int) ((double) initialFreeRegionsCount / 100.0 * percentOfAllocatedHeap);
+        long freeRegionLeft = initialFreeRegionsCount - regionsToAllocate;
+
+        System.out.println("Regions to allocate: " + regionsToAllocate + "; regions to left free: " + freeRegionLeft);
+
+        int maxMemoryPerAllocThread = (int) ((Runtime.getRuntime().freeMemory() / 100.0
+                * (100 - percentOfAllocatedHeap)) / ALLOC_THREAD_COUNT * 0.5);
+
+        System.out.println("Using " + maxMemoryPerAllocThread / 1024 + "KB for each of " + ALLOC_THREAD_COUNT
+                + " allocation threads");
+
+        while (WB.g1NumFreeRegions() > freeRegionLeft) {
+            try {
+                humongousAllocations.add(new byte[HUMONGOUS_SIZES[RND.nextInt(HUMONGOUS_SIZES.length)]]);
+            } catch (OutOfMemoryError oom) {
+                //We got OOM trying to fill heap with humongous objects
+                //It probably means that heap is fragmented which is strange since the test logic should avoid it
+                System.out.println("Warning: OOM while allocating humongous objects - it likely means "
+                        + "that heap is fragmented");
+                break;
+            }
+        }
+
+        System.out.println("Initial free regions " + initialFreeRegionsCount + "; Free regions left "
+                + WB.g1NumFreeRegions());
+
+        LinkedList<Thread> threads = new LinkedList<>();
+
+        for (int i = 0; i < ALLOC_THREAD_COUNT; i++) {
+            threads.add(new Thread(new Allocator(maxMemoryPerAllocThread)));
+        }
+
+        threads.stream().forEach(Thread::start);
+
+        while ((System.currentTimeMillis() - startTime < duration) && error == null) {
+            Thread.yield();
+        }
+
+        shouldStop = true;
+        System.out.println("Finished test");
+        if (error != null) {
+            throw error;
+        }
+    }
+}
--- a/test/gc/g1/humongousObjects/objectGraphTest/GC.java	Thu Jul 14 15:47:44 2016 +0000
+++ b/test/gc/g1/humongousObjects/objectGraphTest/GC.java	Thu Jul 14 16:21:57 2016 +0000
@@ -138,6 +138,41 @@
         }
     },
 
+    MIXED_GC {
+        @Override
+        public Runnable get() {
+            return () -> {
+                WHITE_BOX.youngGC();
+                Helpers.waitTillCMCFinished(WHITE_BOX, 0);
+                WHITE_BOX.youngGC();
+                Helpers.waitTillCMCFinished(WHITE_BOX, 0);
+
+                WHITE_BOX.g1StartConcMarkCycle();
+                Helpers.waitTillCMCFinished(WHITE_BOX, 0);
+
+                WHITE_BOX.youngGC();
+                Helpers.waitTillCMCFinished(WHITE_BOX, 0);
+                // Provoking Mixed GC
+                WHITE_BOX.youngGC();// second evacuation pause will be mixed
+                Helpers.waitTillCMCFinished(WHITE_BOX, 0);
+            };
+        }
+
+        public Consumer<ReferenceInfo<Object[]>> getChecker() {
+            return getCheckerImpl(true, false, true, false);
+        }
+
+        @Override
+        public List<String> shouldContain() {
+            return Arrays.asList(GCTokens.WB_INITIATED_CMC);
+        }
+
+        @Override
+        public List<String> shouldNotContain() {
+            return Arrays.asList(GCTokens.YOUNG_GC);
+        }
+    },
+
     FULL_GC_MEMORY_PRESSURE {
         @Override
         public Runnable get() {
--- a/test/gc/g1/humongousObjects/objectGraphTest/README	Thu Jul 14 15:47:44 2016 +0000
+++ b/test/gc/g1/humongousObjects/objectGraphTest/README	Thu Jul 14 16:21:57 2016 +0000
@@ -38,6 +38,9 @@
                         non-humongous and humongous objects are not collected since we make 2 Young GC to promote all
                         weak references to Old Gen.
 
+6. Mixed GC - weakly referenced non-humongous and humongous objects are collected, softly referenced non-humongous and
+              humongous objects are not collected.
+
 The test gets gc type as a command line argument.
 Then the test allocates object graph in heap (currently testing scenarios are pre-generated and stored in
 TestcaseData.getPregeneratedTestcases()) with TestObjectGraphAfterGC::allocateObjectGraph.
--- a/test/gc/g1/humongousObjects/objectGraphTest/TestObjectGraphAfterGC.java	Thu Jul 14 15:47:44 2016 +0000
+++ b/test/gc/g1/humongousObjects/objectGraphTest/TestObjectGraphAfterGC.java	Thu Jul 14 16:21:57 2016 +0000
@@ -66,6 +66,12 @@
  *                                sun.hotspot.WhiteBox$WhiteBoxPermission
  *
  * @run main/othervm -Xms200M -XX:+UseG1GC -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:.
+ * -XX:+UnlockExperimentalVMOptions -XX:MaxGCPauseMillis=30000 -XX:G1MixedGCLiveThresholdPercent=100 -XX:G1HeapWastePercent=0
+ * -XX:G1HeapRegionSize=1M -Xlog:gc=info:file=TestObjectGraphAfterGC_MIXED_GC.gc.log -XX:MaxTenuringThreshold=1
+ * -XX:G1MixedGCCountTarget=1  -XX:G1OldCSetRegionThresholdPercent=100 -XX:SurvivorRatio=1 -XX:InitiatingHeapOccupancyPercent=0
+ * gc.g1.humongousObjects.objectGraphTest.TestObjectGraphAfterGC MIXED_GC
+ *
+ * @run main/othervm -Xms200M -XX:+UseG1GC -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:.
  * -XX:G1HeapRegionSize=1M -Xlog:gc*=debug:file=TestObjectGraphAfterGC_YOUNG_GC.gc.log
  * gc.g1.humongousObjects.objectGraphTest.TestObjectGraphAfterGC YOUNG_GC
  *
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/native/runtime/test_arguments.cpp	Thu Jul 14 16:21:57 2016 +0000
@@ -0,0 +1,71 @@
+/*
+ * 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 "precompiled.hpp"
+#include "runtime/arguments.hpp"
+#include "unittest.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+TEST(arguments, atojulong) {
+  char ullong_max[32];
+  int ret = jio_snprintf(ullong_max, sizeof(ullong_max), JULONG_FORMAT, ULLONG_MAX);
+  ASSERT_NE(-1, ret);
+
+  julong value;
+  const char* invalid_strings[] = {
+    "", "-1", "-100", " 1", "2 ", "3 2", "1.0",
+    "0x4.5", "0x", "0x0x1" "0.001", "4e10", "e"
+    "K", "M", "G", "1MB", "1KM", "AA", "0B",
+    "18446744073709551615K", "17179869184G",
+    "999999999999999999999999999999"
+  };
+  for (uint i = 0; i < ARRAY_SIZE(invalid_strings); i++) {
+    ASSERT_FALSE(Arguments::atojulong(invalid_strings[i], &value))
+        << "Invalid string '" << invalid_strings[i] << "' parsed without error.";
+  }
+
+  struct {
+    const char* str;
+    julong expected_value;
+  } valid_strings[] = {
+      { "0", 0 },
+      { "4711", 4711 },
+      { "1K", 1ULL * K },
+      { "1k", 1ULL * K },
+      { "2M", 2ULL * M },
+      { "2m", 2ULL * M },
+      { "4G", 4ULL * G },
+      { "4g", 4ULL * G },
+      { "0K", 0 },
+      { ullong_max, ULLONG_MAX },
+      { "0xcafebabe", 0xcafebabe },
+      { "0XCAFEBABE", 0xcafebabe },
+      { "0XCAFEbabe", 0xcafebabe },
+      { "0x10K", 0x10 * K }
+  };
+  for (uint i = 0; i < ARRAY_SIZE(valid_strings); i++) {
+    ASSERT_TRUE(Arguments::atojulong(valid_strings[i].str, &value))
+        << "Valid string '" << valid_strings[i].str << "' did not parse.";
+    ASSERT_EQ(valid_strings[i].expected_value, value);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/Final/Bad.jasm	Thu Jul 14 16:21:57 2016 +0000
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+/* Recoded in jasm to provoke an ICCE assigning a non-static final field with putstatic.
+class Bad {
+  public static final int i; //rewritten
+  //rewritten to: public final int i;
+  static { i = 5; } // putstatic instruction
+}
+*/
+
+super class Bad
+	version 53:0
+{
+
+// Remove 'static' keyword
+public final Field i:I;
+
+Method "<init>":"()V"
+	stack 1 locals 1
+{
+		aload_0;
+		invokespecial	Method java/lang/Object."<init>":"()V";
+		return;
+}
+
+static Method "<clinit>":"()V"
+	stack 1 locals 0
+{
+		iconst_5;
+		putstatic	Field i:"I";
+		return;
+}
+
+} // end Class Bad
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/Final/PutfieldError.java	Thu Jul 14 16:21:57 2016 +0000
@@ -0,0 +1,42 @@
+/*
+ * 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 PutfieldError
+ * @bug 8160551
+ * @summary Throw ICCE rather than crashing for nonstatic final field in static initializer
+ * @compile Bad.jasm
+ * @run main PutfieldError
+ */
+
+public class PutfieldError {
+  public static void main(java.lang.String[] unused) {
+    try {
+      Bad b = new Bad();
+      System.out.println("Bad.i = " + 5);
+      throw new RuntimeException("ICCE NOT thrown as expected");
+    } catch (IncompatibleClassChangeError icce) {
+      System.out.println("ICCE thrown as expected");
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/SharedArchiveFile/SharedStringsDedup.java	Thu Jul 14 16:21:57 2016 +0000
@@ -0,0 +1,72 @@
+/*
+ * 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 SharedStringsDedup
+ * @summary Test -Xshare:auto with shared strings and -XX:+UseStringDeduplication
+ * Feature support: G1GC only, compressed oops/kptrs, 64-bit os, not on windows
+ * @requires (sun.arch.data.model != "32") & (os.family != "windows")
+ * @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
+ * @requires vm.gc.G1
+ * @library /testlibrary
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ * @run main SharedStringsDedup
+ */
+
+import jdk.test.lib.*;
+import java.io.File;
+
+// The main purpose is to test the interaction between shared strings
+// and -XX:+UseStringDeduplication. We run in -Xshare:auto mode so
+// we don't need to worry about CDS archive mapping failure (which
+// doesn't happen often so it won't impact coverage).
+public class SharedStringsDedup {
+    public static void main(String[] args) throws Exception {
+        // Dump
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+            "-XX:+UnlockDiagnosticVMOptions",
+            "-XX:SharedArchiveFile=./SharedStringsDedup.jsa",
+            "-XX:+UseCompressedOops", "-XX:+UseG1GC",
+            "-XX:+PrintSharedSpaces",
+            "-Xshare:dump");
+
+        new OutputAnalyzer(pb.start())
+            .shouldContain("Loading classes to share")
+            .shouldContain("Shared string table stats")
+            .shouldHaveExitValue(0);
+
+        // Run with -Xshare:auto
+        pb = ProcessTools.createJavaProcessBuilder(
+           "-XX:+UnlockDiagnosticVMOptions",
+           "-XX:SharedArchiveFile=./SharedStringsDedup.jsa",
+           "-XX:+UseCompressedOops", "-XX:+UseG1GC",
+           "-XX:+UseStringDeduplication",
+           "-Xshare:auto",
+           "-version");
+
+        new OutputAnalyzer(pb.start())
+            .shouldMatch("(java|openjdk) version")
+            .shouldHaveExitValue(0);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/modules/ModuleStress/CustomSystemClassLoader.java	Thu Jul 14 16:21:57 2016 +0000
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+/**
+ * A custom system ClassLoader to define the module "m2" to during iterations of
+ * differing test runs within the test ModuleStress.java
+ */
+public class CustomSystemClassLoader extends ClassLoader {
+    public CustomSystemClassLoader() {
+        super();
+    }
+    public CustomSystemClassLoader(ClassLoader parent) {
+        super(parent);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/modules/ModuleStress/ModuleNonBuiltinCLMain.java	Thu Jul 14 16:21:57 2016 +0000
@@ -0,0 +1,129 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 static jdk.test.lib.Asserts.*;
+
+import java.lang.reflect.Layer;
+import java.lang.module.Configuration;
+import java.lang.module.ModuleDescriptor;
+import java.lang.module.ModuleFinder;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+//
+// ClassLoader1 --> defines m1 --> packages p1
+// ClassLoader2 --> defines m2 --> packages p2
+// Java System Class Loader --> defines m3 --> packages p3
+//
+// m1 can read m2
+// package p2 in m2 is exported to m1 and m3
+//
+// class p1.c1 defined in m1 tries to access p2.c2 defined in m2
+// Access allowed since m1 can read m2 and package p2 is exported to m1.
+//
+public class ModuleNonBuiltinCLMain {
+
+    // Create a Layer over the boot layer.
+    // Define modules within this layer to test access between
+    // publically defined classes within packages of those modules.
+    public void createLayerOnBoot() throws Throwable {
+
+        // Define module:     m1
+        // Can read:          java.base, m2
+        // Packages:          p1
+        // Packages exported: p1 is exported to unqualifiedly
+        ModuleDescriptor descriptor_m1 =
+                new ModuleDescriptor.Builder("m1")
+                        .requires("java.base")
+                        .requires("m2")
+                        .exports("p1")
+                        .build();
+
+        // Define module:     m2
+        // Can read:          java.base, m3
+        // Packages:          p2
+        // Packages exported: package p2 is exported to m1 and m3
+        Set<String> targets = new HashSet<>();
+        targets.add("m1");
+        targets.add("m3");
+        ModuleDescriptor descriptor_m2 =
+                new ModuleDescriptor.Builder("m2")
+                        .requires("java.base")
+                        .requires("m3")
+                        .exports("p2", targets)
+                        .build();
+
+        // Define module:     m3
+        // Can read:          java.base
+        // Packages:          p3
+        // Packages exported: none
+        ModuleDescriptor descriptor_m3 =
+                new ModuleDescriptor.Builder("m3")
+                        .requires("java.base")
+                        .build();
+
+        // Set up a ModuleFinder containing all modules for this layer.
+        ModuleFinder finder = ModuleLibrary.of(descriptor_m1, descriptor_m2, descriptor_m3);
+
+        // Resolves "m1"
+        Configuration cf = Layer.boot()
+                .configuration()
+                .resolveRequires(finder, ModuleFinder.of(), Set.of("m1"));
+
+        // map each module to differing user defined class loaders for this test
+        Map<String, ClassLoader> map = new HashMap<>();
+        Loader1 cl1 = new Loader1();
+        Loader2 cl2 = new Loader2();
+        ClassLoader cl3 = ClassLoader.getSystemClassLoader();
+        map.put("m1", cl1);
+        map.put("m2", cl2);
+        map.put("m3", cl3);
+
+        // Create Layer that contains m1 & m2
+        Layer layer = Layer.boot().defineModules(cf, map::get);
+        assertTrue(layer.findLoader("m1") == cl1);
+        assertTrue(layer.findLoader("m2") == cl2);
+        assertTrue(layer.findLoader("m3") == cl3);
+        assertTrue(layer.findLoader("java.base") == null);
+
+        // now use the same loader to load class p1.c1
+        Class p1_c1_class = cl1.loadClass("p1.c1");
+        try {
+            p1_c1_class.newInstance();
+        } catch (IllegalAccessError e) {
+            throw new RuntimeException("Test Failed, an IAE should not be thrown since p2 is exported qualifiedly to m1");
+        }
+    }
+
+    public static void main(String args[]) throws Throwable {
+      ModuleNonBuiltinCLMain test = new ModuleNonBuiltinCLMain();
+      test.createLayerOnBoot();
+    }
+
+    static class Loader1 extends ClassLoader { }
+    static class Loader2 extends ClassLoader { }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/modules/ModuleStress/ModuleSameCLMain.java	Thu Jul 14 16:21:57 2016 +0000
@@ -0,0 +1,109 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 static jdk.test.lib.Asserts.*;
+
+import java.lang.reflect.Layer;
+import java.lang.module.Configuration;
+import java.lang.module.ModuleDescriptor;
+import java.lang.module.ModuleFinder;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+//
+// ClassLoader1 --> defines m1 --> packages p1
+// ClassLoader1 --> defines m2 --> packages p2
+//
+// m1 can read m2
+// package p2 in m2 is exported to m1
+//
+// class p1.c1 defined in m1 tries to access p2.c2 defined in m2
+// Access allowed since m1 can read m2 and package p2 is exported to m1.
+//
+public class ModuleSameCLMain {
+
+    // Create a Layer over the boot layer.
+    // Define modules within this layer to test access between
+    // publically defined classes within packages of those modules.
+    public void createLayerOnBoot() throws Throwable {
+
+        // Define module:     m1
+        // Can read:          java.base, m2
+        // Packages:          p1
+        // Packages exported: p1 is exported to unqualifiedly
+        ModuleDescriptor descriptor_m1 =
+                new ModuleDescriptor.Builder("m1")
+                        .requires("java.base")
+                        .requires("m2")
+                        .exports("p1")
+                        .build();
+
+        // Define module:     m2
+        // Can read:          java.base
+        // Packages:          p2
+        // Packages exported: package p2 is exported to m1
+        ModuleDescriptor descriptor_m2 =
+                new ModuleDescriptor.Builder("m2")
+                        .requires("java.base")
+                        .exports("p2", "m1")
+                        .build();
+
+        // Set up a ModuleFinder containing all modules for this layer.
+        ModuleFinder finder = ModuleLibrary.of(descriptor_m1, descriptor_m2);
+
+        // Resolves "m1"
+        Configuration cf = Layer.boot()
+                .configuration()
+                .resolveRequires(finder, ModuleFinder.of(), Set.of("m1"));
+
+        // map each module to the same class loader for this test
+        Map<String, ClassLoader> map = new HashMap<>();
+        Loader1 cl1 = new Loader1();
+        map.put("m1", cl1);
+        map.put("m2", cl1);
+
+        // Create Layer that contains m1 & m2
+        Layer layer = Layer.boot().defineModules(cf, map::get);
+        assertTrue(layer.findLoader("m1") == cl1);
+        assertTrue(layer.findLoader("m2") == cl1);
+        assertTrue(layer.findLoader("java.base") == null);
+
+        // now use the same loader to load class p1.c1
+        Class p1_c1_class = cl1.loadClass("p1.c1");
+        try {
+            p1_c1_class.newInstance();
+        } catch (IllegalAccessError e) {
+            throw new RuntimeException("Test Failed, an IAE should not be thrown since p2 is exported qualifiedly to m1");
+        }
+    }
+
+    public static void main(String args[]) throws Throwable {
+      ModuleSameCLMain test = new ModuleSameCLMain();
+      test.createLayerOnBoot();
+    }
+
+    static class Loader1 extends ClassLoader { }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/modules/ModuleStress/ModuleStress.java	Thu Jul 14 16:21:57 2016 +0000
@@ -0,0 +1,131 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 8159262
+ * @summary Test differing scenarios where a module's readability list and a package's exportability list should be walked
+ * @modules java.base/jdk.internal.misc
+ * @library /testlibrary /test/lib
+ * @compile ../AccessCheck/ModuleLibrary.java
+ * @compile ModuleSameCLMain.java
+ * @compile ModuleNonBuiltinCLMain.java
+ * @compile CustomSystemClassLoader.java
+ * @build ModuleStress
+ * @run main/othervm ModuleStress
+ */
+
+import jdk.test.lib.*;
+import java.io.File;
+
+public class ModuleStress {
+
+    public static void main(String[] args) throws Exception {
+
+        // Test #1: java -version
+        //   All modules' readability lists and packages' exportability
+        //   lists should contain only modules defined to the 3 builtin
+        //   loaders (boot, application, platform).  Thus there is
+        //   not a need to walk those lists at a GC safepoint since
+        //   those loaders never die.
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+             "-Xbootclasspath/a:.",
+             "-Xlog:modules=trace",
+             "-version");
+
+        OutputAnalyzer oa = new OutputAnalyzer(pb.start());
+        oa.shouldNotContain("must be walked")
+          .shouldNotContain("being walked")
+          .shouldHaveExitValue(0);
+
+        // Next 2 tests involve the use of class p1.c1 and p2.c2
+        String source1 = "package p1;"   +
+                         "import p2.c2;" +
+                         "public class c1 {" +
+                         "    public c1() {" +
+                         "       p2.c2 c2_obj = new p2.c2();" +
+                         "       c2_obj.method2();" +
+                         "   }" +
+                         "}";
+
+        String source2 = "package p2;" +
+                         "public class c2 {" +
+                         "    public void method2() { }" +
+                         "}";
+
+        ClassFileInstaller.writeClassToDisk("p2/c2",
+             InMemoryJavaCompiler.compile("p2.c2", source2),  System.getProperty("test.classes"));
+
+        ClassFileInstaller.writeClassToDisk("p1/c1",
+             InMemoryJavaCompiler.compile("p1.c1", source1), System.getProperty("test.classes"));
+
+        // Test #2: Load two modules defined to the same customer class loader.
+        //   m1's module readability list and package p2's exportability should
+        //   not be walked at a GC safepoint since both modules are defined to
+        //   the same loader and thus have the exact same life cycle.
+        pb = ProcessTools.createJavaProcessBuilder(
+             "-Xbootclasspath/a:.",
+             "-Xlog:modules=trace",
+             "ModuleSameCLMain");
+
+        oa = new OutputAnalyzer(pb.start());
+        oa.shouldNotContain("must be walked")
+          .shouldNotContain("being walked")
+          .shouldHaveExitValue(0);
+
+        // Test #3: Load two modules in differing custom class loaders.
+        //   m1's module readability list and package p2's exportability list must
+        //   be walked at a GC safepoint since both modules are defined to non-builtin
+        //   class loaders which could die and thus be unloaded.
+        pb = ProcessTools.createJavaProcessBuilder(
+             "-Xbootclasspath/a:.",
+             "-Xlog:modules=trace",
+             "ModuleNonBuiltinCLMain");
+
+        oa = new OutputAnalyzer(pb.start());
+        oa.shouldContain("module m1 reads list must be walked")
+          .shouldContain("package p2 defined in module m2, exports list must be walked")
+          .shouldNotContain("module m2 reads list must be walked")
+          .shouldHaveExitValue(0);
+
+        // Test #4: Load two modules in differing custom class loaders,
+        //   of which one has been designated as the custom system class loader
+        //   via -Djava.system.class.loader=CustomSystemClassLoader. Since
+        //   m3 is defined to the system class loader, m2's module readability
+        //   list does not have to be walked at a GC safepoint, but package p2's
+        //   exportability list does.
+        pb = ProcessTools.createJavaProcessBuilder(
+             "-Djava.system.class.loader=CustomSystemClassLoader",
+             "-Xbootclasspath/a:.",
+             "-Xlog:modules=trace",
+             "ModuleNonBuiltinCLMain");
+
+        oa = new OutputAnalyzer(pb.start());
+        oa.shouldContain("package p2 defined in module m2, exports list must be walked")
+          .shouldNotContain("module m2 reads list must be walked")
+          .shouldHaveExitValue(0);
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/modules/ModuleStress/ModuleStressGC.java	Thu Jul 14 16:21:57 2016 +0000
@@ -0,0 +1,84 @@
+/*
+ * 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 8159262
+ * @summary layers over the boot layer are repeatedly created, during this iteration, GCs are forced to verify correct walk of module and package lists.
+ * @modules java.base/jdk.internal.misc
+ * @library /testlibrary /test/lib
+ * @compile ../CompilerUtils.java
+ * @build ModuleStressGC
+ * @run main/othervm ModuleStressGC
+ */
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import jdk.test.lib.*;
+
+public class ModuleStressGC {
+
+    private static final String TEST_SRC = System.getProperty("test.src");
+    private static final String TEST_CLASSES = System.getProperty("test.classes");
+
+    private static final Path SRC_DIR = Paths.get(TEST_SRC, "src");
+    private static final Path MODS_DIR = Paths.get(TEST_CLASSES, "mods");
+
+    /**
+     * Compile two module definitions used by the test, jdk.test and jdk.translet.
+     */
+    public static void main(String[] args) throws Exception {
+
+        boolean compiled;
+        // Compile module jdk.test declaration
+        compiled = CompilerUtils.compile(
+            SRC_DIR.resolve("jdk.test"),
+            MODS_DIR.resolve("jdk.test"));
+        if (!compiled) {
+            throw new RuntimeException("Test failed to compile module jdk.test");
+        }
+
+        // Compile module jdk.translet declaration
+        compiled = CompilerUtils.compile(
+            SRC_DIR.resolve("jdk.translet"),
+            MODS_DIR.resolve("jdk.translet"),
+            "-XaddExports:jdk.test/test=jdk.translet",
+            "-mp", MODS_DIR.toString());
+        if (!compiled) {
+            throw new RuntimeException("Test failed to compile module jdk.translet");
+        }
+
+        // Sanity check that the test, jdk.test/test/MainGC.java,
+        // correctly walks module jdk.test's reads list and package
+        // test's, defined to module jdk.translet, export list at
+        // GC safepoints.
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+            "-Xlog:modules=trace",
+            "-mp", MODS_DIR.toString(),
+            "-m", "jdk.test/test.MainGC");
+        OutputAnalyzer oa = new OutputAnalyzer(pb.start());
+        oa.shouldContain("package test defined in module jdk.test, exports list being walked")
+          .shouldContain("module jdk.test reads list being walked")
+          .shouldHaveExitValue(0);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/modules/ModuleStress/src/jdk.test/test/MainGC.java	Thu Jul 14 16:21:57 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.
+ */
+
+package test;
+
+import java.lang.module.Configuration;
+import java.lang.module.ModuleFinder;
+import java.lang.reflect.Layer;
+import java.lang.reflect.Method;
+import java.lang.reflect.Module;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.*;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+public class MainGC {
+
+    private static final Path MODS_DIR = Paths.get(System.getProperty("jdk.module.path"));
+    static final String MODULE_NAME = "jdk.translet";
+
+    public static void main(String[] args) throws Exception {
+
+        ModuleFinder finder = ModuleFinder.of(MODS_DIR);
+        Layer layerBoot = Layer.boot();
+
+        Configuration cf = layerBoot
+                .configuration()
+                .resolveRequires(ModuleFinder.of(), finder, Set.of(MODULE_NAME));
+
+        Module testModule = MainGC.class.getModule();
+        ClassLoader scl = ClassLoader.getSystemClassLoader();
+
+        // Create an unique module/class loader in a layer above the boot layer.
+        // Export this module to the jdk.test/test package.
+        // Add a read edge from module jdk.test to this module.
+        Callable<Void> task = new Callable<Void>() {
+            @Override
+            public Void call() throws Exception {
+                Layer layer = Layer.boot().defineModulesWithOneLoader(cf, scl);
+                Module transletModule = layer.findModule(MODULE_NAME).get();
+                testModule.addExports("test", transletModule);
+                testModule.addReads(transletModule);
+                Class<?> c = layer.findLoader(MODULE_NAME).loadClass("translet.MainGC");
+                Method method = c.getDeclaredMethod("go");
+                method.invoke(null);
+                return null;
+            }
+        };
+
+        List<Future<Void>> results = new ArrayList<>();
+
+        // Repeatedly create the layer above stressing the exportation of
+        // package jdk.test/test to several different modules.
+        ExecutorService pool = Executors.newFixedThreadPool(Math.min(100, Runtime.getRuntime().availableProcessors()*10));
+        try {
+            for (int i = 0; i < 10000; i++) {
+                results.add(pool.submit(task));
+                // At specified intervals, force a GC. This provides an
+                // opportunity to verify that both the module jdk.test's reads
+                // and the package test's, which is defined to jdk.test, exports
+                // lists are being walked.
+                if (i == 3000 || i == 6000 || i == 9000) {
+                    System.gc();
+                }
+            }
+        } finally {
+            pool.shutdown();
+        }
+
+        int passed = 0;
+        int failed = 0;
+
+        // The failed state should be 0, the created modules in layers above the
+        // boot layer should be allowed access to the contents of the jdk.test/test
+        // package since that package was exported to the transletModule above.
+        for (Future<Void> result : results) {
+            try {
+                result.get();
+                passed++;
+            } catch (Throwable x) {
+                x.printStackTrace();
+                failed++;
+            }
+        }
+
+        System.out.println("passed: " + passed);
+        System.out.println("failed: " + failed);
+    }
+
+    public static void callback() { }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/modules/ModuleStress/src/jdk.translet/translet/MainGC.java	Thu Jul 14 16:21:57 2016 +0000
@@ -0,0 +1,30 @@
+/*
+ * 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 translet;
+
+public class MainGC {
+    public static void go() {
+        test.MainGC.callback();
+    }
+}