changeset 12027:53443835ee75

Merge
author jprovino
date Tue, 20 Sep 2016 20:45:35 +0000
parents ab2b45b79d71 1c9533c9629a
children ddb6b697fbd1
files test/serviceability/jdwp/JdwpModuleCmd.java test/serviceability/jdwp/JdwpModuleReply.java test/serviceability/jdwp/JdwpVisibleClassesCmd.java test/serviceability/jdwp/JdwpVisibleClassesReply.java
diffstat 32 files changed, 527 insertions(+), 428 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/classfile/classLoader.cpp	Tue Sep 20 10:27:51 2016 -0400
+++ b/src/share/vm/classfile/classLoader.cpp	Tue Sep 20 20:45:35 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	Tue Sep 20 10:27:51 2016 -0400
+++ b/src/share/vm/classfile/classLoader.hpp	Tue Sep 20 20:45:35 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	Tue Sep 20 10:27:51 2016 -0400
+++ b/src/share/vm/classfile/javaClasses.cpp	Tue Sep 20 20:45:35 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	Tue Sep 20 10:27:51 2016 -0400
+++ b/src/share/vm/classfile/javaClasses.hpp	Tue Sep 20 20:45:35 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/moduleEntry.cpp	Tue Sep 20 10:27:51 2016 -0400
+++ b/src/share/vm/classfile/moduleEntry.cpp	Tue Sep 20 20:45:35 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	Tue Sep 20 10:27:51 2016 -0400
+++ b/src/share/vm/classfile/moduleEntry.hpp	Tue Sep 20 20:45:35 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	Tue Sep 20 10:27:51 2016 -0400
+++ b/src/share/vm/classfile/modules.cpp	Tue Sep 20 20:45:35 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	Tue Sep 20 10:27:51 2016 -0400
+++ b/src/share/vm/classfile/sharedPathsMiscInfo.cpp	Tue Sep 20 20:45:35 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	Tue Sep 20 10:27:51 2016 -0400
+++ b/src/share/vm/classfile/sharedPathsMiscInfo.hpp	Tue Sep 20 20:45:35 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/gc/cms/parNewGeneration.cpp	Tue Sep 20 10:27:51 2016 -0400
+++ b/src/share/vm/gc/cms/parNewGeneration.cpp	Tue Sep 20 20:45:35 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/g1ConcurrentMark.cpp	Tue Sep 20 10:27:51 2016 -0400
+++ b/src/share/vm/gc/g1/g1ConcurrentMark.cpp	Tue Sep 20 20:45:35 2016 +0000
@@ -285,7 +285,7 @@
     return false;
   }
 
-  Copy::conjoint_oops_atomic(ptr_arr, new_chunk->data, OopsPerChunk);
+  Copy::conjoint_memory_atomic(ptr_arr, new_chunk->data, OopsPerChunk * sizeof(oop));
 
   add_chunk_to_chunk_list(new_chunk);
 
@@ -299,7 +299,7 @@
     return false;
   }
 
-  Copy::conjoint_oops_atomic(cur->data, ptr_arr, OopsPerChunk);
+  Copy::conjoint_memory_atomic(cur->data, ptr_arr, OopsPerChunk * sizeof(oop));
 
   add_chunk_to_free_list(cur);
   return true;
--- a/src/share/vm/gc/g1/heapRegion.cpp	Tue Sep 20 10:27:51 2016 -0400
+++ b/src/share/vm/gc/g1/heapRegion.cpp	Tue Sep 20 20:45:35 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	Tue Sep 20 10:27:51 2016 -0400
+++ b/src/share/vm/gc/g1/heapRegion.hpp	Tue Sep 20 20:45:35 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/shared/workgroup.cpp	Tue Sep 20 10:27:51 2016 -0400
+++ b/src/share/vm/gc/shared/workgroup.cpp	Tue Sep 20 20:45:35 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	Tue Sep 20 10:27:51 2016 -0400
+++ b/src/share/vm/gc/shared/workgroup.hpp	Tue Sep 20 20:45:35 2016 +0000
@@ -318,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
@@ -363,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/memory/filemap.cpp	Tue Sep 20 10:27:51 2016 -0400
+++ b/src/share/vm/memory/filemap.cpp	Tue Sep 20 20:45:35 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
@@ -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	Tue Sep 20 10:27:51 2016 -0400
+++ b/src/share/vm/memory/filemap.hpp	Tue Sep 20 20:45:35 2016 +0000
@@ -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);
--- a/src/share/vm/oops/instanceKlass.cpp	Tue Sep 20 10:27:51 2016 -0400
+++ b/src/share/vm/oops/instanceKlass.cpp	Tue Sep 20 20:45:35 2016 +0000
@@ -2247,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,
--- a/src/share/vm/oops/klass.cpp	Tue Sep 20 10:27:51 2016 -0400
+++ b/src/share/vm/oops/klass.cpp	Tue Sep 20 20:45:35 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/typeArrayKlass.cpp	Tue Sep 20 10:27:51 2016 -0400
+++ b/src/share/vm/oops/typeArrayKlass.cpp	Tue Sep 20 20:45:35 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	Tue Sep 20 10:27:51 2016 -0400
+++ b/src/share/vm/prims/jvm.cpp	Tue Sep 20 20:45:35 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/stackwalk.cpp	Tue Sep 20 10:27:51 2016 -0400
+++ b/src/share/vm/prims/stackwalk.cpp	Tue Sep 20 20:45:35 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,7 +115,6 @@
   int frames_decoded = 0;
   for (; !stream.at_end(); stream.next()) {
     Method* method = stream.method();
-    int bci = stream.bci();
 
     if (method == NULL) continue;
 
@@ -129,35 +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 filling in Class object");
-      if (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()));
-      }
-
-      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);
 
@@ -228,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(),
@@ -243,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()));
@@ -256,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);
@@ -315,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 &&
@@ -341,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();
       }
     }
   }
@@ -402,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);
   }
@@ -418,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;
@@ -429,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	Tue Sep 20 10:27:51 2016 -0400
+++ b/src/share/vm/prims/stackwalk.hpp	Tue Sep 20 20:45:35 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,35 +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;
   }
@@ -104,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/runtime/arguments.cpp	Tue Sep 20 10:27:51 2016 -0400
+++ b/src/share/vm/runtime/arguments.cpp	Tue Sep 20 20:45:35 2016 +0000
@@ -3897,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/utilities/hashtable.inline.hpp	Tue Sep 20 10:27:51 2016 -0400
+++ b/src/share/vm/utilities/hashtable.inline.hpp	Tue Sep 20 20:45:35 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/runtime/modules/PatchModule/PatchModuleCDS.java	Tue Sep 20 10:27:51 2016 -0400
+++ b/test/runtime/modules/PatchModule/PatchModuleCDS.java	Tue Sep 20 20:45:35 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);
     }
 }
--- a/test/serviceability/jdwp/AllModulesCommandTest.java	Tue Sep 20 10:27:51 2016 -0400
+++ b/test/serviceability/jdwp/AllModulesCommandTest.java	Tue Sep 20 20:45:35 2016 +0000
@@ -30,7 +30,7 @@
 
 /**
  * @test
- * @summary Tests the modules-related JDWP commands
+ * @summary Tests AllModules JDWP command
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
  * @compile AllModulesCommandTestDebuggee.java
@@ -87,12 +87,8 @@
             assertReply(reply);
             for (int i = 0; i < reply.getModulesCount(); ++i) {
                 long modId = reply.getModuleId(i);
-                // For each module reported by JDWP get its name using the JDWP NAME command
-                // and store the reply
-                String modName = getModuleName(modId);
-                if (modName != null) { // JDWP reports unnamed modules, ignore them
-                    jdwpModuleNames.add(modName);
-                }
+                // For each module reported by JDWP get its name using the JDWP  NAME command
+                getModuleName(modId);
                 // Assert the JDWP CANREAD and CLASSLOADER commands
                 assertCanRead(modId);
                 assertClassLoader(modId);
@@ -118,10 +114,14 @@
         }
     }
 
-    private String getModuleName(long modId) throws IOException {
+    private void getModuleName(long modId) throws IOException {
+        // Send out the JDWP NAME command and store the reply
         JdwpModNameReply reply = new JdwpModNameCmd(modId).send(channel);
         assertReply(reply);
-        return reply.getModuleName();
+        String modName = reply.getModuleName();
+        if (modName != null) { // JDWP reports unnamed modules, ignore them
+            jdwpModuleNames.add(modName);
+        }
     }
 
     private void assertReply(JdwpReply reply) {
@@ -139,39 +139,11 @@
     }
 
     private void assertClassLoader(long modId) throws IOException {
-        // Verify that the module classloader id is valid
+        // Simple assert for the CLASSLOADER command
         JdwpClassLoaderReply reply = new JdwpClassLoaderCmd(modId).send(channel);
         assertReply(reply);
-        long moduleClassLoader = reply.getClassLoaderId();
-        assertTrue(moduleClassLoader >= 0, "bad classloader refId " + moduleClassLoader + " for module id " + modId);
-
-        String clsModName = getModuleName(modId);
-        if ("java.base".equals(clsModName)) {
-            // For the java.base module, because there will be some loaded classes, we can verify
-            // that some of the loaded classes do report the java.base module as the module they belong to
-            assertGetModule(moduleClassLoader, modId);
-        }
-    }
-
-    private void assertGetModule(long moduleClassLoader, long modId) throws IOException {
-        // Get all the visible classes for the module classloader
-        JdwpVisibleClassesReply visibleClasses = new JdwpVisibleClassesCmd(moduleClassLoader).send(channel);
-        assertReply(visibleClasses);
-
-        boolean moduleFound = false;
-        for (long clsId : visibleClasses.getVisibleClasses()) {
-            // For each visible class get the module the class belongs to
-            JdwpModuleReply modReply = new JdwpModuleCmd(clsId).send(channel);
-            assertReply(modReply);
-            long clsModId = modReply.getModuleId();
-
-            // At least one of the visible classes should belong to our module
-            if (modId == clsModId) {
-                moduleFound = true;
-                break;
-            }
-        }
-        assertTrue(moduleFound, "None of the visible classes for the classloader of the module " + getModuleName(modId) + " reports the module as its own");
+        long clId = reply.getClassLoaderId();
+        assertTrue(clId >= 0, "bad classloader refId " + clId + " for module id " + modId);
     }
 
 }
--- a/test/serviceability/jdwp/JdwpCmd.java	Tue Sep 20 10:27:51 2016 -0400
+++ b/test/serviceability/jdwp/JdwpCmd.java	Tue Sep 20 20:45:35 2016 +0000
@@ -70,6 +70,7 @@
     }
 
     public final T send(JdwpChannel channel) throws IOException {
+        System.err.println("Sending command: " + this);
         channel.write(data.array(), HEADER_LEN + getDataLength());
         if (reply != null) {
             reply.initFromStream(channel.getInputStream());
--- a/test/serviceability/jdwp/JdwpModuleCmd.java	Tue Sep 20 10:27:51 2016 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- * 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.
- */
-
-/**
- * The JDWP MODULE command
- */
-public class JdwpModuleCmd extends JdwpCmd<JdwpModuleReply> {
-
-    public JdwpModuleCmd(long refId) {
-        super(19, 2, JdwpModuleReply.class, refLen());
-        putRefId(refId);
-    }
-
-}
--- a/test/serviceability/jdwp/JdwpModuleReply.java	Tue Sep 20 10:27:51 2016 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*
- * 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.DataInputStream;
-import java.io.IOException;
-
-/**
- * The reply to the JDWP MODULE command
- */
-public class JdwpModuleReply extends JdwpReply {
-
-    private long moduleId;
-
-    protected void parseData(DataInputStream ds) throws IOException {
-        moduleId = readRefId(ds);
-    }
-
-    public long getModuleId() {
-        return moduleId;
-    }
-
-}
--- a/test/serviceability/jdwp/JdwpVisibleClassesCmd.java	Tue Sep 20 10:27:51 2016 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- * 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.
- */
-
-/**
- * The JDWP VISIBLE CLASSES command
- */
-public class JdwpVisibleClassesCmd extends JdwpCmd<JdwpVisibleClassesReply> {
-
-    public JdwpVisibleClassesCmd(long classLoaderId) {
-        super(1, 14, JdwpVisibleClassesReply.class, refLen());
-        putRefId(classLoaderId);
-    }
-
-}
--- a/test/serviceability/jdwp/JdwpVisibleClassesReply.java	Tue Sep 20 10:27:51 2016 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * 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.DataInputStream;
-import java.io.IOException;
-import java.util.Arrays;
-
-/**
- * The reply to the JDWP VISIBLE CLASSES command
- */
-public class JdwpVisibleClassesReply extends JdwpReply {
-
-    private long[] visibleClasses;
-
-    protected void parseData(DataInputStream ds) throws IOException {
-        int numOfClasses = ds.readInt();
-        visibleClasses = new long[numOfClasses];
-        for (int i = 0; i < numOfClasses; ++i) {
-            byte type = ds.readByte();
-            long refId = readRefId(ds);
-            visibleClasses[i] = refId;
-        }
-    }
-
-    public long[] getVisibleClasses() {
-        return Arrays.copyOf(visibleClasses, visibleClasses.length);
-    }
-
-}