< prev index next >

src/share/vm/classfile/systemDictionary.cpp

Print this page

        

@@ -36,10 +36,12 @@
 #endif
 #include "classfile/vmSymbols.hpp"
 #include "compiler/compileBroker.hpp"
 #include "interpreter/bytecodeStream.hpp"
 #include "interpreter/interpreter.hpp"
+#include "jfr/jfrEvents.hpp"
+#include "jfr/jni/jfrUpcalls.hpp"
 #include "memory/filemap.hpp"
 #include "memory/gcLocker.hpp"
 #include "memory/oopFactory.hpp"
 #include "oops/instanceKlass.hpp"
 #include "oops/instanceRefKlass.hpp"

@@ -62,13 +64,10 @@
 #include "runtime/signature.hpp"
 #include "services/classLoadingService.hpp"
 #include "services/threadService.hpp"
 #include "utilities/macros.hpp"
 #include "utilities/ticks.hpp"
-#if INCLUDE_TRACE
-#include "trace/tracing.hpp"
-#endif
 
 Dictionary*            SystemDictionary::_dictionary          = NULL;
 PlaceholderTable*      SystemDictionary::_placeholders        = NULL;
 Dictionary*            SystemDictionary::_shared_dictionary   = NULL;
 LoaderConstraintTable* SystemDictionary::_loader_constraints  = NULL;

@@ -94,10 +93,13 @@
 bool        SystemDictionary::_has_checkPackageAccess     =  false;
 
 // lazily initialized klass variables
 Klass* volatile SystemDictionary::_abstract_ownable_synchronizer_klass = NULL;
 
+#if INCLUDE_JFR
+static const Symbol* jfr_event_handler_proxy = NULL;
+#endif // INCLUDE_JFR
 
 // ----------------------------------------------------------------------------
 // Java-level SystemLoader
 
 oop SystemDictionary::java_system_loader() {

@@ -139,10 +141,13 @@
     return true;
   }
 }
 
 #endif
+#if INCLUDE_JFR
+#include "jfr/jfr.hpp"
+#endif
 
 // ----------------------------------------------------------------------------
 // Parallel class loading check
 
 bool SystemDictionary::is_parallelCapable(Handle class_loader) {

@@ -596,19 +601,35 @@
     }
   }
   return (nh);
 }
 
+// utility function for class load event
+static void post_class_load_event(EventClassLoad &event,
+                                  instanceKlassHandle k,
+                                  Handle initiating_loader) {
+#if INCLUDE_JFR
+  if (event.should_commit()) {
+    event.set_loadedClass(k());
+    event.set_definingClassLoader(k->class_loader_data());
+    oop class_loader = initiating_loader.is_null() ? (oop)NULL : initiating_loader();
+    event.set_initiatingClassLoader(class_loader != NULL ?
+                                    ClassLoaderData::class_loader_data_or_null(class_loader) :
+                                    (ClassLoaderData*)NULL);
+    event.commit();
+  }
+#endif
+}
 
 Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name,
                                                         Handle class_loader,
                                                         Handle protection_domain,
                                                         TRAPS) {
   assert(name != NULL && !FieldType::is_array(name) &&
          !FieldType::is_obj(name), "invalid class name");
 
-  Ticks class_load_start_time = Ticks::now();
+  EventClassLoad class_load_start_event;
 
   // UseNewReflection
   // Fix for 4474172; see evaluation for more details
   class_loader = Handle(THREAD, java_lang_ClassLoader::non_reflection_class_loader(class_loader()));
   ClassLoaderData *loader_data = register_loader(class_loader, CHECK_NULL);

@@ -855,11 +876,11 @@
 
   if (HAS_PENDING_EXCEPTION || k.is_null()) {
     return NULL;
   }
 
-  post_class_load_event(class_load_start_time, k, class_loader);
+  post_class_load_event(class_load_start_event, k, class_loader);
 
 #ifdef ASSERT
   {
     ClassLoaderData* loader_data = k->class_loader_data();
     MutexLocker mu(SystemDictionary_lock, THREAD);

@@ -980,11 +1001,11 @@
                                       KlassHandle host_klass,
                                       GrowableArray<Handle>* cp_patches,
                                       TRAPS) {
   TempNewSymbol parsed_name = NULL;
 
-  Ticks class_load_start_time = Ticks::now();
+  EventClassLoad class_load_start_event;
 
   ClassLoaderData* loader_data;
   if (host_klass.not_null()) {
     // Create a new CLD for anonymous class, that uses the same class loader
     // as the host_klass

@@ -1041,11 +1062,11 @@
     if (JvmtiExport::should_post_class_load()) {
         assert(THREAD->is_Java_thread(), "thread->is_Java_thread()");
         JvmtiExport::post_class_load((JavaThread *) THREAD, k());
     }
 
-    post_class_load_event(class_load_start_time, k, class_loader);
+    post_class_load_event(class_load_start_event, k, class_loader);
   }
   assert(host_klass.not_null() || cp_patches == NULL,
          "cp_patches only found with host_klass");
 
   return k();

@@ -1083,16 +1104,17 @@
   // already be present in the SystemDictionary, otherwise we would not
   // throw potential ClassFormatErrors.
   //
   // Note: "name" is updated.
 
-  instanceKlassHandle k = ClassFileParser(st).parseClassFile(class_name,
-                                                             loader_data,
-                                                             protection_domain,
-                                                             parsed_name,
-                                                             verify,
-                                                             THREAD);
+  ClassFileParser parser(st);
+  instanceKlassHandle k = parser.parseClassFile(class_name,
+                                                loader_data,
+                                                protection_domain,
+                                                parsed_name,
+                                                verify,
+                                                THREAD);
 
   const char* pkg = "java/";
   size_t pkglen = strlen(pkg);
   if (!HAS_PENDING_EXCEPTION &&
       !class_loader.is_null() &&

@@ -1123,10 +1145,18 @@
     // Verification prevents us from creating names with dots in them, this
     // asserts that that's the case.
     assert(is_internal_format(parsed_name),
            "external class name format used internally");
 
+#if INCLUDE_JFR
+    {
+      InstanceKlass* ik = k();
+      ON_KLASS_CREATION(ik, parser, THREAD);
+      k = instanceKlassHandle(ik);
+    }
+#endif
+
     // Add class just loaded
     // If a class loader supports parallel classloading handle parallel define requests
     // find_or_define_instance_class may return a different InstanceKlass
     if (is_parallelCapable(class_loader)) {
       k = find_or_define_instance_class(class_name, class_loader, k, THREAD);

@@ -1305,10 +1335,28 @@
 
     // find_or_define_instance_class may return a different InstanceKlass
     if (!k.is_null()) {
       k = find_or_define_instance_class(class_name, class_loader, k, CHECK_(nh));
     }
+
+#if INCLUDE_JFR
+    if (k.is_null() && (class_name == jfr_event_handler_proxy)) {
+      assert(jfr_event_handler_proxy != NULL, "invariant");
+      // EventHandlerProxy class is generated dynamically in
+      // EventHandlerProxyCreator::makeEventHandlerProxyClass
+      // method, so we generate a Java call from here.
+      //
+      // EventHandlerProxy class will finally be defined in
+      // SystemDictionary::resolve_from_stream method, down
+      // the call stack. Bootstrap classloader is parallel-capable,
+      // so no concurrency issues are expected.
+      CLEAR_PENDING_EXCEPTION;
+      k = JfrUpcalls::load_event_handler_proxy_class(THREAD);
+      assert(!k.is_null(), "invariant");
+    }
+#endif
+
     return k;
   } else {
     // Use user specified class loader to load class. Call loadClass operation on class_loader.
     ResourceMark rm(THREAD);
 

@@ -1383,10 +1431,19 @@
     // Class is not found or has the wrong name, return NULL
     return nh;
   }
 }
 
+static void post_class_define_event(InstanceKlass* k, const ClassLoaderData* def_cld) {
+  EventClassDefine event;
+  if (event.should_commit()) {
+    event.set_definedClass(k);
+    event.set_definingClassLoader(def_cld);
+    event.commit();
+  }
+}
+
 void SystemDictionary::define_instance_class(instanceKlassHandle k, TRAPS) {
 
   ClassLoaderData* loader_data = k->class_loader_data();
   Handle class_loader_h(THREAD, loader_data->class_loader());
 

@@ -1453,10 +1510,11 @@
       assert(THREAD->is_Java_thread(), "thread->is_Java_thread()");
       JvmtiExport::post_class_load((JavaThread *) THREAD, k());
 
   }
 
+  post_class_define_event(k(), loader_data);
 }
 
 // Support parallel classloading
 // All parallel class loaders, including bootstrap classloader
 // lock a placeholder entry for this class/class_loader pair

@@ -1714,10 +1772,11 @@
 // Note: anonymous classes are not in the SD.
 bool SystemDictionary::do_unloading(BoolObjectClosure* is_alive, bool clean_alive) {
   // First, mark for unload all ClassLoaderData referencing a dead class loader.
   bool unloading_occurred = ClassLoaderDataGraph::do_unloading(is_alive, clean_alive);
   if (unloading_occurred) {
+    JFR_ONLY(Jfr::on_unloading_classes();)
     dictionary()->do_unloading();
     constraints()->purge_loader_constraints();
     resolution_errors()->purge_resolution_errors();
   }
   // Oops referenced by the system dictionary may get unreachable independently

@@ -1847,10 +1906,13 @@
 
   // Allocate private object used as system class loader lock
   _system_loader_lock_obj = oopFactory::new_intArray(0, CHECK);
   // Initialize basic classes
   initialize_preloaded_classes(CHECK);
+#if INCLUDE_JFR
+  jfr_event_handler_proxy = SymbolTable::new_permanent_symbol("jdk/jfr/proxy/internal/EventHandlerProxy", CHECK);
+#endif // INCLUDE_JFR
 }
 
 // Compact table of directions on the initialization of klasses:
 static const short wk_init_info[] = {
   #define WK_KLASS_INIT_INFO(name, symbol, option) \

@@ -2685,30 +2747,10 @@
   // Verify constraint table
   guarantee(constraints() != NULL, "Verify of loader constraints failed");
   constraints()->verify(dictionary(), placeholders());
 }
 
-// utility function for class load event
-void SystemDictionary::post_class_load_event(const Ticks& start_time,
-                                             instanceKlassHandle k,
-                                             Handle initiating_loader) {
-#if INCLUDE_TRACE
-  EventClassLoad event(UNTIMED);
-  if (event.should_commit()) {
-    event.set_starttime(start_time);
-    event.set_loadedClass(k());
-    oop defining_class_loader = k->class_loader();
-    event.set_definingClassLoader(defining_class_loader !=  NULL ?
-                                    defining_class_loader->klass() : (Klass*)NULL);
-    oop class_loader = initiating_loader.is_null() ? (oop)NULL : initiating_loader();
-    event.set_initiatingClassLoader(class_loader != NULL ?
-                                      class_loader->klass() : (Klass*)NULL);
-    event.commit();
-  }
-#endif // INCLUDE_TRACE
-}
-
 #ifndef PRODUCT
 
 // statistics code
 class ClassStatistics: AllStatic {
  private:
< prev index next >