changeset 5733:e47086077559

6642881: Improve performance of Class.getClassLoader() Summary: Add classLoader to java/lang/Class instance for fast access Reviewed-by: fparain, lfoltan, alanb, mchung, dholmes, kevinw
author coleenp
date Fri, 12 Sep 2014 14:41:42 +0100
parents f0769f0382d7
children 34aea5177b9c
files src/share/vm/classfile/classFileParser.cpp src/share/vm/classfile/javaClasses.cpp src/share/vm/classfile/javaClasses.hpp src/share/vm/classfile/vmSymbols.hpp
diffstat 4 files changed, 36 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/classfile/classFileParser.cpp	Mon Jul 21 10:40:50 2014 +0100
+++ b/src/share/vm/classfile/classFileParser.cpp	Fri Sep 12 14:41:42 2014 +0100
@@ -3743,7 +3743,7 @@
     }
 
     // Allocate mirror and initialize static fields
-    java_lang_Class::create_mirror(this_klass, CHECK_(nullHandle));
+    java_lang_Class::create_mirror(this_klass, class_loader, CHECK_(nullHandle));
 
     ClassLoadingService::notify_class_loaded(instanceKlass::cast(this_klass()),
                                              false /* not shared class */);
--- a/src/share/vm/classfile/javaClasses.cpp	Mon Jul 21 10:40:50 2014 +0100
+++ b/src/share/vm/classfile/javaClasses.cpp	Fri Sep 12 14:41:42 2014 +0100
@@ -530,10 +530,10 @@
       }
     }
   }
-  create_mirror(k, CHECK);
+  create_mirror(k, Handle(NULL), CHECK);
 }
 
-oop java_lang_Class::create_mirror(KlassHandle k, TRAPS) {
+oop java_lang_Class::create_mirror(KlassHandle k, Handle class_loader, TRAPS) {
   assert(k->java_mirror() == NULL, "should only assign mirror once");
   // Use this moment of initialization to cache modifier_flags also,
   // to support Class.getModifiers().  Instance classes recalculate
@@ -574,6 +574,8 @@
       // Initialize static fields
       instanceKlass::cast(k())->do_local_static_fields(&initialize_static_field, CHECK_NULL);
     }
+    // set the classLoader field in the java_lang_Class instance
+    set_class_loader(mirror(), class_loader());
     return mirror();
   } else {
     return NULL;
@@ -599,6 +601,18 @@
   java_class->int_field_put(_static_oop_field_count_offset, size);
 }
 
+void java_lang_Class::set_class_loader(oop java_class, oop loader) {
+  // jdk7 runs Queens in bootstrapping and jdk8-9 has no coordinated pushes yet.
+  if (_class_loader_offset != 0) {
+    java_class->obj_field_put(_class_loader_offset, loader);
+  }
+}
+
+oop java_lang_Class::class_loader(oop java_class) {
+  assert(_class_loader_offset != 0, "must be set");
+  return java_class->obj_field(_class_loader_offset);
+}
+
 oop java_lang_Class::create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS) {
   // This should be improved by adding a field at the Java level or by
   // introducing a new VM klass (see comment in ClassFileParser)
@@ -762,6 +776,12 @@
   compute_optional_offset(classRedefinedCount_offset,
                           klass_oop, vmSymbols::classRedefinedCount_name(), vmSymbols::int_signature());
 
+  // Needs to be optional because the old build runs Queens during bootstrapping
+  // and jdk8-9 doesn't have coordinated pushes yet.
+  compute_optional_offset(_class_loader_offset,
+                 klass_oop, vmSymbols::classClassLoader_name(),
+                 vmSymbols::classloader_signature());
+
   CLASS_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET);
 }
 
@@ -2830,6 +2850,7 @@
 int java_lang_Class::_resolved_constructor_offset;
 int java_lang_Class::_oop_size_offset;
 int java_lang_Class::_static_oop_field_count_offset;
+int java_lang_Class::_class_loader_offset;
 int java_lang_Throwable::backtrace_offset;
 int java_lang_Throwable::detailMessage_offset;
 int java_lang_Throwable::cause_offset;
@@ -3277,3 +3298,4 @@
   JavaClasses::check_offsets();
   FilteredFieldsMap::initialize();  // must be done after computing offsets.
 }
+
--- a/src/share/vm/classfile/javaClasses.hpp	Mon Jul 21 10:40:50 2014 +0100
+++ b/src/share/vm/classfile/javaClasses.hpp	Fri Sep 12 14:41:42 2014 +0100
@@ -224,14 +224,21 @@
   static int _oop_size_offset;
   static int _static_oop_field_count_offset;
 
+  static int _class_loader_offset;
+
   static bool offsets_computed;
   static int classRedefinedCount_offset;
 
+  static void set_class_loader(oop java_class, oop class_loader);
  public:
   static void compute_offsets();
 
   // Instance creation
-  static oop  create_mirror(KlassHandle k, TRAPS);
+  static oop  create_mirror(KlassHandle k, Handle class_loader, TRAPS);
+  static oop  create_mirror(KlassHandle k, TRAPS) {
+    return create_mirror(k, Handle(), THREAD);
+  }
+
   static void fixup_mirror(KlassHandle k, TRAPS);
   static oop  create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS);
   // Conversion
@@ -267,6 +274,8 @@
   static int classRedefinedCount(oop the_class_mirror);
   static void set_classRedefinedCount(oop the_class_mirror, int value);
 
+  static oop class_loader(oop java_class);
+
   static int oop_size(oop java_class);
   static void set_oop_size(oop java_class, int size);
   static int static_oop_field_count(oop java_class);
--- a/src/share/vm/classfile/vmSymbols.hpp	Mon Jul 21 10:40:50 2014 +0100
+++ b/src/share/vm/classfile/vmSymbols.hpp	Fri Sep 12 14:41:42 2014 +0100
@@ -546,6 +546,7 @@
   template(serializePropertiesToByteArray_signature,   "()[B")                                                    \
   template(serializeAgentPropertiesToByteArray_name,   "serializeAgentPropertiesToByteArray")                     \
   template(classRedefinedCount_name,                   "classRedefinedCount")                                     \
+  template(classClassLoader_name,                      "classLoader")                                             \
                                                                                                                   \
   /* trace signatures */                                                                                          \
   TRACE_TEMPLATES(template)                                                                                       \