From 83ff43e7372bef4120ab92c40df3e0a3e2f1308f Mon Sep 17 00:00:00 2001
From: Rachel Protacio <rprotacio@openjdk.org>
Date: Mon, 5 Dec 2016 11:45:20 -0500
Subject: [PATCH] 8168850: Mark module entries that have been specified by
 --patch-module

Adds a boolean to ModuleEntry to specify whether the module has been patched using the command line --patch-module

Reviewed-by: jiangli, lfoltan, dholmes
---
 .../src/share/vm/classfile/classLoader.cpp    | 22 ++++++++++++++++---
 .../src/share/vm/classfile/classLoader.hpp    |  2 ++
 .../src/share/vm/classfile/moduleEntry.cpp    |  8 +++++++
 .../src/share/vm/classfile/moduleEntry.hpp    |  9 ++++++++
 hotspot/src/share/vm/logging/logTag.hpp       |  1 +
 5 files changed, 39 insertions(+), 3 deletions(-)

diff --git a/hotspot/src/share/vm/classfile/classLoader.cpp b/hotspot/src/share/vm/classfile/classLoader.cpp
index a7e2222fe4d..88b00362d06 100644
--- a/hotspot/src/share/vm/classfile/classLoader.cpp
+++ b/hotspot/src/share/vm/classfile/classLoader.cpp
@@ -751,6 +751,21 @@ void ClassLoader::setup_patch_mod_entries() {
   }
 }
 
+// Determine whether the module has been patched via the command-line
+// option --patch-module
+bool ClassLoader::is_in_patch_mod_entries(Symbol* module_name) {
+  if (_patch_mod_entries != NULL && _patch_mod_entries->is_nonempty()) {
+    int table_len = _patch_mod_entries->length();
+    for (int i = 0; i < table_len; i++) {
+      ModuleClassPathList* patch_mod = _patch_mod_entries->at(i);
+      if (module_name->fast_compare(patch_mod->module_name()) == 0) {
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
 void ClassLoader::setup_search_path(const char *class_path, bool bootstrap_search) {
   int len = (int)strlen(class_path);
   int end = 0;
@@ -1764,9 +1779,6 @@ void classLoader_init1() {
 
 // Complete the ClassPathEntry setup for the boot loader
 void ClassLoader::classLoader_init2(TRAPS) {
-  // Create the moduleEntry for java.base
-  create_javabase();
-
   // Setup the list of module/path pairs for --patch-module processing
   // This must be done after the SymbolTable is created in order
   // to use fast_compare on module names instead of a string compare.
@@ -1774,6 +1786,10 @@ void ClassLoader::classLoader_init2(TRAPS) {
     setup_patch_mod_entries();
   }
 
+  // Create the ModuleEntry for java.base (must occur after setup_patch_mod_entries
+  // to successfully determine if java.base has been patched)
+  create_javabase();
+
   // Setup the initial java.base/path pair for the exploded build entries.
   // As more modules are defined during module system initialization, more
   // entries will be added to the exploded build array.
diff --git a/hotspot/src/share/vm/classfile/classLoader.hpp b/hotspot/src/share/vm/classfile/classLoader.hpp
index 1bdbd7025b8..b7f494ce178 100644
--- a/hotspot/src/share/vm/classfile/classLoader.hpp
+++ b/hotspot/src/share/vm/classfile/classLoader.hpp
@@ -418,6 +418,8 @@ class ClassLoader: AllStatic {
     }
   }
 
+  static bool is_in_patch_mod_entries(Symbol* module_name);
+
 #if INCLUDE_CDS
   // Sharing dump and restore
 
diff --git a/hotspot/src/share/vm/classfile/moduleEntry.cpp b/hotspot/src/share/vm/classfile/moduleEntry.cpp
index 42f79db8dc5..f9c8d5977fc 100644
--- a/hotspot/src/share/vm/classfile/moduleEntry.cpp
+++ b/hotspot/src/share/vm/classfile/moduleEntry.cpp
@@ -301,6 +301,14 @@ ModuleEntry* ModuleEntryTable::new_entry(unsigned int hash, Handle module_handle
   entry->set_version(version);
   entry->set_location(location);
 
+  if (ClassLoader::is_in_patch_mod_entries(name)) {
+    entry->set_is_patched();
+    if (log_is_enabled(Trace, modules, patch)) {
+      ResourceMark rm;
+      log_trace(modules, patch)("Marked module %s as patched from --patch-module", name->as_C_string());
+    }
+  }
+
   TRACE_INIT_MODULE_ID(entry);
 
   return entry;
diff --git a/hotspot/src/share/vm/classfile/moduleEntry.hpp b/hotspot/src/share/vm/classfile/moduleEntry.hpp
index cffc672a7f2..fa5d1cd3712 100644
--- a/hotspot/src/share/vm/classfile/moduleEntry.hpp
+++ b/hotspot/src/share/vm/classfile/moduleEntry.hpp
@@ -63,6 +63,7 @@ private:
   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
+  bool _is_patched;                    // whether the module is patched via --patch-module
   TRACE_DEFINE_TRACE_ID_FIELD;
   enum {MODULE_READS_SIZE = 101};      // Initial size of list of modules that the module can read.
 
@@ -77,6 +78,7 @@ public:
     _can_read_all_unnamed = false;
     _has_default_read_edges = false;
     _must_walk_reads = false;
+    _is_patched = false;
   }
 
   Symbol*          name() const                        { return literal(); }
@@ -131,6 +133,13 @@ public:
     return prev;
   }
 
+  void set_is_patched() {
+      _is_patched = true;
+  }
+  bool is_patched() {
+      return _is_patched;
+  }
+
   ModuleEntry* next() const {
     return (ModuleEntry*)HashtableEntry<Symbol*, mtModule>::next();
   }
diff --git a/hotspot/src/share/vm/logging/logTag.hpp b/hotspot/src/share/vm/logging/logTag.hpp
index 90638b41b38..5b9e03ba228 100644
--- a/hotspot/src/share/vm/logging/logTag.hpp
+++ b/hotspot/src/share/vm/logging/logTag.hpp
@@ -90,6 +90,7 @@
   LOG_TAG(oopmap) \
   LOG_TAG(os) \
   LOG_TAG(pagesize) \
+  LOG_TAG(patch) \
   LOG_TAG(path) \
   LOG_TAG(phases) \
   LOG_TAG(plab) \