changeset 7810:06c52bb8efd2

First implementation of Event-based Tracing to support Modules
author mgronlun
date Sun, 08 Feb 2015 21:57:33 +0100
parents 2b018a13b789
children 5b987349098f
files src/share/vm/c1/c1_LIRGenerator.cpp src/share/vm/classfile/classLoaderData.cpp src/share/vm/classfile/classLoaderData.hpp src/share/vm/classfile/moduleEntry.cpp src/share/vm/classfile/moduleEntry.hpp src/share/vm/classfile/modules.cpp src/share/vm/classfile/modules.hpp src/share/vm/classfile/packageEntry.cpp src/share/vm/classfile/packageEntry.hpp src/share/vm/oops/instanceKlass.hpp src/share/vm/oops/klass.cpp src/share/vm/oops/klass.hpp src/share/vm/opto/library_call.cpp src/share/vm/trace/traceDataTypes.hpp src/share/vm/trace/traceMacros.hpp src/share/vm/trace/traceTypes.xsl src/share/vm/trace/tracetypes.xml src/share/vm/utilities/hashtable.hpp
diffstat 18 files changed, 222 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/c1/c1_LIRGenerator.cpp	Fri Feb 06 07:41:04 2015 -0500
+++ b/src/share/vm/c1/c1_LIRGenerator.cpp	Sun Feb 08 21:57:33 2015 +0100
@@ -3096,7 +3096,7 @@
     LIR_Opr klass = new_pointer_register();
     __ move(new LIR_Address(arg.result(), java_lang_Class::klass_offset_in_bytes(), klass_pointer_type), klass, info);
     LIR_Opr id = new_register(T_LONG);
-    ByteSize offset = TRACE_ID_OFFSET;
+    ByteSize offset = TRACE_KLASS_TRACE_ID_OFFSET;
     LIR_Address* trace_id_addr = new LIR_Address(klass, in_bytes(offset), T_LONG);
     __ move(trace_id_addr, id);
     __ logical_or(id, LIR_OprFact::longConst(0x01l), id);
--- a/src/share/vm/classfile/classLoaderData.cpp	Fri Feb 06 07:41:04 2015 -0500
+++ b/src/share/vm/classfile/classLoaderData.cpp	Sun Feb 08 21:57:33 2015 +0100
@@ -170,6 +170,30 @@
   }
 }
 
+void ClassLoaderData::modules_do(void f(ModuleEntry*)) {
+  if (_modules != NULL) {
+    for (int i = 0; i < _modules->table_size(); i++) {
+      for (ModuleEntry* entry = _modules->bucket(i);
+                              entry != NULL;
+                              entry = entry->next()) {
+        f(entry);
+      }
+    }
+  }
+}
+
+void ClassLoaderData::packages_do(void f(PackageEntry*)) {
+  if (_packages != NULL) {
+    for (int i = 0; i < _packages->table_size(); i++) {
+      for (PackageEntry* entry = _packages->bucket(i);
+                              entry != NULL;
+                              entry = entry->next()) {
+        f(entry);
+      }
+    }
+  }
+}
+
 void ClassLoaderData::record_dependency(Klass* k, TRAPS) {
   ClassLoaderData * const from_cld = this;
   ClassLoaderData * const to_cld = k->class_loader_data();
@@ -717,6 +741,40 @@
   }
 }
 
+void ClassLoaderDataGraph::modules_do(void f(ModuleEntry*)) {
+  assert_locked_or_safepoint(Module_lock);
+  for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) {
+    cld->modules_do(f);
+  }
+}
+
+void ClassLoaderDataGraph::modules_unloading_do(void f(ModuleEntry*)) {
+  assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint!");
+  // Only walk the head until any clds not purged from prior unloading
+  // (CMS doesn't purge right away).
+  for (ClassLoaderData* cld = _unloading; cld != _saved_unloading; cld = cld->next()) {
+    assert(cld->is_unloading(), "invariant");
+    cld->modules_do(f);
+  }
+}
+
+void ClassLoaderDataGraph::packages_do(void f(PackageEntry*)) {
+  assert_locked_or_safepoint(Module_lock);
+  for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) {
+    cld->packages_do(f);
+  }
+}
+
+void ClassLoaderDataGraph::packages_unloading_do(void f(PackageEntry*)) {
+  assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint!");
+  // Only walk the head until any clds not purged from prior unloading
+  // (CMS doesn't purge right away).
+  for (ClassLoaderData* cld = _unloading; cld != _saved_unloading; cld = cld->next()) {
+    assert(cld->is_unloading(), "invariant");
+    cld->packages_do(f);
+  }
+}
+
 void ClassLoaderDataGraph::loaded_classes_do(KlassClosure* klass_closure) {
   for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) {
     cld->loaded_classes_do(klass_closure);
@@ -728,6 +786,7 @@
   // Only walk the head until any clds not purged from prior unloading
   // (CMS doesn't purge right away).
   for (ClassLoaderData* cld = _unloading; cld != _saved_unloading; cld = cld->next()) {
+    assert(cld->is_unloading(), "invariant");
     cld->classes_do(f);
   }
 }
@@ -1012,6 +1071,7 @@
 Ticks ClassLoaderDataGraph::_class_unload_time;
 
 void ClassLoaderDataGraph::class_unload_event(Klass* const k) {
+  assert(k != NULL, "invariant");
 
   // post class unload event
   EventClassUnload event(UNTIMED);
--- a/src/share/vm/classfile/classLoaderData.hpp	Fri Feb 06 07:41:04 2015 -0500
+++ b/src/share/vm/classfile/classLoaderData.hpp	Sun Feb 08 21:57:33 2015 +0100
@@ -53,6 +53,8 @@
 class JNIMethodBlock;
 class JNIHandleBlock;
 class Metadebug;
+class ModuleEntry;
+class PackageEntry;
 class ModuleEntryTable;
 class PackageEntryTable;
 
@@ -95,6 +97,10 @@
   static void classes_do(KlassClosure* klass_closure);
   static void classes_do(void f(Klass* const));
   static void methods_do(void f(Method*));
+  static void modules_do(void f(ModuleEntry*));
+  static void modules_unloading_do(void f(ModuleEntry*));
+  static void packages_do(void f(PackageEntry*));
+  static void packages_unloading_do(void f(PackageEntry*));
   static void loaded_classes_do(KlassClosure* klass_closure);
   static void classes_unloading_do(void f(Klass* const));
   static bool do_unloading(BoolObjectClosure* is_alive, bool clean_alive);
@@ -221,6 +227,8 @@
   void loaded_classes_do(KlassClosure* klass_closure);
   void classes_do(void f(InstanceKlass*));
   void methods_do(void f(Method*));
+  void modules_do(void f(ModuleEntry*));
+  void packages_do(void f(PackageEntry*));
 
   // Deallocate free list during class unloading.
   void free_deallocate_list();
--- a/src/share/vm/classfile/moduleEntry.cpp	Fri Feb 06 07:41:04 2015 -0500
+++ b/src/share/vm/classfile/moduleEntry.cpp	Sun Feb 08 21:57:33 2015 +0100
@@ -31,6 +31,7 @@
 #include "prims/jni.h"
 #include "runtime/handles.inline.hpp"
 #include "runtime/safepoint.hpp"
+#include "trace/traceMacros.hpp"
 #include "utilities/events.hpp"
 #include "utilities/growableArray.hpp"
 #include "utilities/hashtable.inline.hpp"
@@ -60,6 +61,10 @@
   _reads->append_if_missing(m);
 }
 
+bool ModuleEntry::has_reads() const {
+  return _reads != NULL && !_reads->is_empty();
+}
+
 // Purge dead module entries out of reads list.
 void ModuleEntry::purge_reads() {
   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
@@ -134,6 +139,7 @@
   entry->set_name(name);
   name->increment_refcount();
   entry->set_loader(class_loader);
+  TRACE_INIT_MODULE_ID(entry);
 
   return entry;
 }
@@ -296,3 +302,15 @@
 void ModuleEntry::verify() {
   guarantee(literal()->is_oop(), "must be an oop");
 }
+
+void ModuleEntry::module_reads_do(ModuleClosure* const f) {
+  assert_locked_or_safepoint(Module_lock);
+  assert(f != NULL, "invariant");
+
+  if (_reads != NULL) {
+    int reads_len = _reads->length();
+    for (int i = 0; i < reads_len; ++i) {
+      f->do_module(_reads->at(i));
+    }
+  }
+}
--- a/src/share/vm/classfile/moduleEntry.hpp	Fri Feb 06 07:41:04 2015 -0500
+++ b/src/share/vm/classfile/moduleEntry.hpp	Sun Feb 08 21:57:33 2015 +0100
@@ -30,9 +30,12 @@
 #include "oops/symbol.hpp"
 #include "prims/jni.h"
 #include "runtime/mutexLocker.hpp"
+#include "trace/traceMacros.hpp"
 #include "utilities/growableArray.hpp"
 #include "utilities/hashtable.hpp"
 
+class ModuleClosure;
+
 // A ModuleEntry describes a module that has been defined by a call to JVM_DefineModule.
 // It contains:
 //   - a pointer to the java.lang.reflect.Module object for this module.
@@ -49,6 +52,7 @@
   GrowableArray<ModuleEntry*>* _reads; // list of modules that are readable by this module
   char* _version;  // module version number
   bool _pkgs_with_qexports; // this module contains 1 or more packages with qualified exports
+  TRACE_DEFINE_TRACE_ID_FIELD;
 
 public:
   void init() {
@@ -72,6 +76,7 @@
   void               set_version(char* version)     { _version = version; }
 
   bool               can_read(ModuleEntry* m) const;
+  bool               has_reads() const;
   void               add_read(ModuleEntry* m);
 
   bool               pkgs_with_qexports()           { return _pkgs_with_qexports; }
@@ -89,6 +94,11 @@
     f->do_oop(literal_addr());
   }
 
+  // iteration support for readability
+  void module_reads_do(ModuleClosure* const f);
+
+  TRACE_DEFINE_TRACE_ID_METHODS;
+
   // Purge dead weak references out of reads list when any given class loader is unloaded.
   void purge_reads();
   void delete_reads();
@@ -97,6 +107,13 @@
   void verify();
 };
 
+// Iterator interface
+class ModuleClosure: public StackObj {
+ public:
+  virtual void do_module(ModuleEntry* const module) = 0;
+};
+
+
 // The ModuleEntryTable is a Hashtable containing a list of all modules defined
 // by a particular class loader.  Each module is represented as a ModuleEntry node.
 //
--- a/src/share/vm/classfile/modules.cpp	Fri Feb 06 07:41:04 2015 -0500
+++ b/src/share/vm/classfile/modules.cpp	Sun Feb 08 21:57:33 2015 +0100
@@ -31,6 +31,7 @@
 #include "classfile/modules.hpp"
 #include "classfile/packageEntry.hpp"
 #include "classfile/stringTable.hpp"
+#include "classfile/symbolTable.hpp"
 #include "classfile/vmSymbols.hpp"
 #include "oops/instanceKlass.hpp"
 #include "oops/objArrayKlass.hpp"
@@ -74,6 +75,30 @@
   return loader_cld->packages();
 }
 
+static PackageEntry* get_package_entry_by_name(Symbol* package,
+                                               Handle h_loader,
+                                               TRAPS) {
+  if (package != NULL) {
+    ResourceMark rm;
+    if (Modules::verify_package_name(package->as_C_string())) {
+      PackageEntryTable* const package_entry_table =
+        get_package_entry_table(h_loader, THREAD);
+      assert(package_entry_table != NULL, "Unexpected null package entry table");
+      return package_entry_table->lookup_only(package);
+    }
+  }
+  return NULL;
+}
+
+static ModuleEntry* get_module_entry_by_package_name(Symbol* package,
+                                                     Handle h_loader,
+                                                     TRAPS) {
+  const PackageEntry* const pkg_entry =
+    get_package_entry_by_name(package, h_loader, THREAD);
+
+  return pkg_entry != NULL ? pkg_entry->module() : NULL;
+}
+
 // Check if -Xoverride:<path> was specified.  If so, prepend <path>/module_name,
 // if it exists, to bootpath so boot loader can find the class files.  Also, if
 // using exploded modules, prepend <java.home>/modules/module_name, if it exists,
@@ -150,7 +175,6 @@
   return package_entry_table->lookup_only(pkg_symbol);
 }
 
-
 jobject Modules::define_module(JNIEnv *env, jstring name, jobject loader, jobjectArray packages) {
   JavaThread *THREAD = JavaThread::thread_from_jni_environment(env);
   ResourceMark rm(THREAD);
@@ -508,7 +532,7 @@
     tty->print_cr("[is_exported_to_module: package %s from module %s checking if exported to module %s, exported? = %s",
                   package_entry->name()->as_C_string(),
                   from_module_entry->name()->as_C_string(),
-                  to_module_entry->name()->as_C_string(),
+                  to_module_entry != NULL ? to_module_entry->name()->as_C_string() : "unnamed",
                   BOOL_TO_STR(package_entry->is_unqual_exported() ||
                     (to_module != NULL && package_entry->is_qexported_to(to_module_entry)) ||
                     (from_module_entry == to_module_entry)));
@@ -561,6 +585,19 @@
   return JNIHandles::make_local(env, module);
 }
 
+jobject Modules::get_module(Symbol* package_name,
+                           Handle h_loader,
+                           TRAPS) {
+
+  const ModuleEntry* const module =
+    get_module_entry_by_package_name(package_name,
+                                     h_loader,
+                                     THREAD);
+
+  return module != NULL ?
+    JNIHandles::make_local(THREAD, module->literal()) : NULL;
+}
+
 void Modules::add_module_package(JNIEnv *env, jobject module, jstring package) {
   JavaThread *THREAD = JavaThread::thread_from_jni_environment(env);
   ResourceMark rm;
@@ -615,3 +652,7 @@
               err_msg("Package %s already exists for class loader", package_name));
   }
 }
+
+bool Modules::is_package_defined(Symbol* package, Handle h_loader, TRAPS) {
+  return get_package_entry_by_name(package, h_loader, THREAD) != NULL;
+}
--- a/src/share/vm/classfile/modules.hpp	Fri Feb 06 07:41:04 2015 -0500
+++ b/src/share/vm/classfile/modules.hpp	Sun Feb 08 21:57:33 2015 +0100
@@ -25,6 +25,11 @@
 #ifndef SHARE_VM_CLASSFILE_MODULES_HPP
 #define SHARE_VM_CLASSFILE_MODULES_HPP
 
+#include "memory/allocation.hpp"
+#include "runtime/handles.hpp"
+
+class Symbol;
+
 class Modules : AllStatic {
 
 public:
@@ -83,6 +88,11 @@
   // Return the java.lang.reflect.Module object for this class object.
   static jobject get_module(JNIEnv *env, jclass clazz);
 
+  // If package is defined by loader, return the
+  // java.lang.reflect.Module object for the module in which the package is defined.
+  // Returns NULL if package is invalid or not defined by loader.
+  static jobject get_module(Symbol* package_name, Handle h_loader, TRAPS);
+
   // This adds package to module.
   // It throws IllegalArgumentException if:
   // * Module is bad
@@ -93,6 +103,9 @@
   // Return TRUE if package_name is syntactically valid, false otherwise.
   static bool verify_package_name(char *package_name);
 
+  // Return TRUE iff package is defined by loader
+  static bool is_package_defined(Symbol* package_name, Handle h_loader, TRAPS);
+
 };
 
 #endif // SHARE_VM_CLASSFILE_MODULES_HPP
--- a/src/share/vm/classfile/packageEntry.cpp	Fri Feb 06 07:41:04 2015 -0500
+++ b/src/share/vm/classfile/packageEntry.cpp	Sun Feb 08 21:57:33 2015 +0100
@@ -28,6 +28,7 @@
 #include "memory/resourceArea.hpp"
 #include "oops/symbol.hpp"
 #include "runtime/handles.inline.hpp"
+#include "trace/traceMacros.hpp"
 #include "utilities/events.hpp"
 #include "utilities/growableArray.hpp"
 #include "utilities/hashtable.inline.hpp"
@@ -162,6 +163,8 @@
   entry->set_hash(hash);
   entry->set_literal(name);
 
+  TRACE_INIT_PACKAGE_ID(entry);
+
   // Initialize fields specific to a PackageEntry
   entry->init();
   entry->name()->increment_refcount();
@@ -286,3 +289,17 @@
 void PackageEntry::verify() {
   guarantee(name() != NULL, "A package entry must have a corresponding symbol name.");
 }
+
+// iteration of qualified exports
+void PackageEntry::package_exports_do(ModuleClosure* const f) {
+  assert_locked_or_safepoint(Module_lock);
+  assert(f != NULL, "invariant");
+
+  if (is_qual_exported()) {
+    int qe_len = _qualified_exports->length();
+
+    for (int i = 0; i < qe_len; ++i) {
+      f->do_module(_qualified_exports->at(i));
+    }
+  }
+}
--- a/src/share/vm/classfile/packageEntry.hpp	Fri Feb 06 07:41:04 2015 -0500
+++ b/src/share/vm/classfile/packageEntry.hpp	Sun Feb 08 21:57:33 2015 +0100
@@ -50,6 +50,7 @@
   bool _is_exported;
   GrowableArray<ModuleEntry*>* _exported_pending_delete; // transitioned from qualified to unqualified, delete at safepoint
   GrowableArray<ModuleEntry*>* _qualified_exports;
+  TRACE_DEFINE_TRACE_ID_FIELD;
 
 public:
   void init() {
@@ -93,6 +94,11 @@
     return (PackageEntry**)HashtableEntry<Symbol*, mtClass>::next_addr();
   }
 
+  // iteration of qualified exports
+  void package_exports_do(ModuleClosure* const f);
+
+  TRACE_DEFINE_TRACE_ID_METHODS;
+
   // Purge dead weak references out of exported list when any given class loader is unloaded.
   void purge_qualified_exports();
   void delete_qualified_exports();
@@ -144,7 +150,7 @@
     return (unsigned int)(name->identity_hash());
   }
 
-  int index_for(Symbol* name) {
+  int index_for(Symbol* name) const {
     return hash_to_index(compute_hash(name));
   }
 
--- a/src/share/vm/oops/instanceKlass.hpp	Fri Feb 06 07:41:04 2015 -0500
+++ b/src/share/vm/oops/instanceKlass.hpp	Sun Feb 08 21:57:33 2015 +0100
@@ -779,7 +779,7 @@
 
   // support for stub routines
   static ByteSize init_state_offset()  { return in_ByteSize(offset_of(InstanceKlass, _init_state)); }
-  TRACE_DEFINE_OFFSET;
+  TRACE_DEFINE_KLASS_TRACE_ID_OFFSET;
   static ByteSize init_thread_offset() { return in_ByteSize(offset_of(InstanceKlass, _init_thread)); }
 
   // subclass/subinterface checks
--- a/src/share/vm/oops/klass.cpp	Fri Feb 06 07:41:04 2015 -0500
+++ b/src/share/vm/oops/klass.cpp	Sun Feb 08 21:57:33 2015 +0100
@@ -185,7 +185,7 @@
   set_subklass(NULL);
   set_next_sibling(NULL);
   set_next_link(NULL);
-  TRACE_INIT_ID(this);
+  TRACE_INIT_KLASS_ID(this);
 
   set_prototype_header(markOopDesc::prototype());
   set_biased_lock_revocation_count(0);
@@ -511,7 +511,7 @@
 }
 
 void Klass::restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPS) {
-  TRACE_INIT_ID(this);
+  TRACE_INIT_KLASS_ID(this);
   // If an exception happened during CDS restore, some of these fields may already be
   // set.  We leave the class on the CLD list, even if incomplete so that we don't
   // modify the CLD list outside a safepoint.
--- a/src/share/vm/oops/klass.hpp	Fri Feb 06 07:41:04 2015 -0500
+++ b/src/share/vm/oops/klass.hpp	Sun Feb 08 21:57:33 2015 +0100
@@ -142,7 +142,7 @@
   markOop  _prototype_header;   // Used when biased locking is both enabled and disabled for this type
   jint     _biased_lock_revocation_count;
 
-  TRACE_DEFINE_KLASS_TRACE_ID;
+  TRACE_DEFINE_TRACE_ID_FIELD;
 
   // Remembered sets support for the oops in the klasses.
   jbyte _modified_oops;             // Card Table Equivalent (YC/CMS support)
@@ -564,7 +564,7 @@
   jlong last_biased_lock_bulk_revocation_time() { return _last_biased_lock_bulk_revocation_time; }
   void  set_last_biased_lock_bulk_revocation_time(jlong cur_time) { _last_biased_lock_bulk_revocation_time = cur_time; }
 
-  TRACE_DEFINE_KLASS_METHODS;
+  TRACE_DEFINE_TRACE_ID_METHODS;
 
   // garbage collection support
   void oops_do(OopClosure* cl);
--- a/src/share/vm/opto/library_call.cpp	Fri Feb 06 07:41:04 2015 -0500
+++ b/src/share/vm/opto/library_call.cpp	Sun Feb 08 21:57:33 2015 +0100
@@ -3148,7 +3148,7 @@
   Node* cls = null_check(argument(1), T_OBJECT);
   Node* kls = load_klass_from_mirror(cls, false, NULL, 0);
   kls = null_check(kls, T_OBJECT);
-  ByteSize offset = TRACE_ID_OFFSET;
+  ByteSize offset = TRACE_KLASS_TRACE_ID_OFFSET;
   Node* insp = basic_plus_adr(kls, in_bytes(offset));
   Node* tvalue = make_load(NULL, insp, TypeLong::LONG, T_LONG, MemNode::unordered);
   Node* bits = longcon(~0x03l); // ignore bit 0 & 1
--- a/src/share/vm/trace/traceDataTypes.hpp	Fri Feb 06 07:41:04 2015 -0500
+++ b/src/share/vm/trace/traceDataTypes.hpp	Sun Feb 08 21:57:33 2015 +0100
@@ -58,12 +58,11 @@
 
 typedef enum ReservedEvent ReservedEvent;
 
-typedef u8 classid;
-typedef u8 stacktraceid;
-typedef u8 methodid;
-typedef u8 fieldid;
+typedef u8 traceid;
 
+class ModuleEntry;
+class PackageEntry;
 class TraceUnicodeString;
+class Symbol;
 
 #endif // SHARE_VM_TRACE_TRACEDATATYPES_HPP
-
--- a/src/share/vm/trace/traceMacros.hpp	Fri Feb 06 07:41:04 2015 -0500
+++ b/src/share/vm/trace/traceMacros.hpp	Sun Feb 08 21:57:33 2015 +0100
@@ -28,16 +28,18 @@
 #define EVENT_THREAD_EXIT(thread)
 #define EVENT_THREAD_DESTRUCT(thread)
 
-#define TRACE_INIT_ID(k)
+#define TRACE_INIT_KLASS_ID(k)
+#define TRACE_INIT_MODULE_ID(m)
+#define TRACE_INIT_PACKAGE_ID(p)
 #define TRACE_DATA TraceThreadData
 
 #define TRACE_START() JNI_OK
 #define TRACE_INITIALIZE() JNI_OK
 
-#define TRACE_DEFINE_KLASS_METHODS typedef int ___IGNORED_hs_trace_type1
-#define TRACE_DEFINE_KLASS_TRACE_ID typedef int ___IGNORED_hs_trace_type2
-#define TRACE_DEFINE_OFFSET typedef int ___IGNORED_hs_trace_type3
-#define TRACE_ID_OFFSET in_ByteSize(0); ShouldNotReachHere()
+#define TRACE_DEFINE_TRACE_ID_METHODS typedef int ___IGNORED_hs_trace_type1
+#define TRACE_DEFINE_TRACE_ID_FIELD typedef int ___IGNORED_hs_trace_type2
+#define TRACE_DEFINE_KLASS_TRACE_ID_OFFSET typedef int ___IGNORED_hs_trace_type3
+#define TRACE_KLASS_TRACE_ID_OFFSET in_ByteSize(0); ShouldNotReachHere()
 #define TRACE_TEMPLATES(template)
 #define TRACE_INTRINSICS(do_intrinsic, do_class, do_name, do_signature, do_alias)
 
--- a/src/share/vm/trace/traceTypes.xsl	Fri Feb 06 07:41:04 2015 -0500
+++ b/src/share/vm/trace/traceTypes.xsl	Sun Feb 08 21:57:33 2015 +0100
@@ -32,7 +32,6 @@
 #ifndef TRACEFILES_TRACETYPES_HPP
 #define TRACEFILES_TRACETYPES_HPP
 
-#include "oops/symbol.hpp"
 #include "trace/traceDataTypes.hpp"
 #include "utilities/globalDefinitions.hpp"
 #include "utilities/ticks.hpp"
--- a/src/share/vm/trace/tracetypes.xml	Fri Feb 06 07:41:04 2015 -0500
+++ b/src/share/vm/trace/tracetypes.xml	Sun Feb 08 21:57:33 2015 +0100
@@ -89,6 +89,7 @@
                   type="U8" builtin_type="CLASS">
       <value type="CLASS" field="loaderClass" label="ClassLoader"/>
       <value type="SYMBOL" field="name" label="Name"/>
+      <value type="PACKAGE" field="package" label="Package"/>
       <value type="SHORT" field="modifiers" label="Access modifiers"/>
     </content_type>
 
@@ -176,6 +177,19 @@
       <value type="UTF8" field="type" label="type" />
     </content_type>
 
+    <content_type id="Module" hr_name="Module"
+              type="U8" jvm_type="MODULE">
+      <value type="SYMBOL" field="name" label="Name"/>
+      <value type="UTF8" field="version" label="Version"/>
+      <value type="CLASS" field="classLoader" label="ClassLoader"/>
+    </content_type>
+
+    <content_type id="Package" hr_name="Package"
+              type="U8" jvm_type="PACKAGE">
+      <value type="SYMBOL" field="name" label="Name"/>
+      <value type="MODULE" field="module" label="Module"/>
+      <value type="BOOLEAN" field="exported" label="Exported"/>
+    </content_type>
   </content_types>
 
 
@@ -292,6 +306,12 @@
     <primary_type symbol="CLASS" datatype="U8" contenttype="CLASS"
                   type="Klass *" sizeop="sizeof(u8)"/>
 
+    <primary_type symbol="MODULE" datatype="U8" contenttype="MODULE"
+                  type="const ModuleEntry *" sizeop="sizeof(u8)"/>
+
+    <primary_type symbol="PACKAGE" datatype="U8" contenttype="PACKAGE"
+              type="const PackageEntry *" sizeop="sizeof(u8)"/>
+
     <!-- A Method *. The method is marked as "used" and will eventually be
          written into the recording constant pool. -->
     <primary_type symbol="METHOD" datatype="U8" contenttype="METHOD"
--- a/src/share/vm/utilities/hashtable.hpp	Fri Feb 06 07:41:04 2015 -0500
+++ b/src/share/vm/utilities/hashtable.hpp	Sun Feb 08 21:57:33 2015 +0100
@@ -151,7 +151,7 @@
   void copy_table(char** top, char* end);
 
   // Bucket handling
-  int hash_to_index(unsigned int full_hash) {
+  int hash_to_index(unsigned int full_hash) const {
     int h = full_hash % _table_size;
     assert(h >= 0 && h < _table_size, "Illegal hash value");
     return h;