< prev index next >

src/hotspot/share/runtime/mutexLocker.hpp

Print this page
@@ -23,13 +23,16 @@
   */
  
  #ifndef SHARE_RUNTIME_MUTEXLOCKER_HPP
  #define SHARE_RUNTIME_MUTEXLOCKER_HPP
  
+ #include "logging/log.hpp"
  #include "memory/allocation.hpp"
  #include "runtime/flags/flagSetting.hpp"
  #include "runtime/mutex.hpp"
+ #include "runtime/perfData.hpp"
+ #include "runtime/thread.hpp"
  
  // Mutexes used in the VM.
  
  extern Mutex*   Patching_lock;                   // a lock used to guard code patching of compiled code
  extern Mutex*   NMethodState_lock;               // a lock used to guard a compiled method state

@@ -75,12 +78,19 @@
  extern Mutex*   MarkStackChunkList_lock;         // Protects access to the global mark stack chunk list.
  extern Mutex*   MonitoringSupport_lock;          // Protects updates to the serviceability memory pools and allocated memory high water mark.
  extern Monitor* ConcurrentGCBreakpoints_lock;    // Protects concurrent GC breakpoint management
  extern Mutex*   Compile_lock;                    // a lock held when Compilation is updating code (used to block CodeCache traversal, CHA updates, etc)
  extern Monitor* MethodCompileQueue_lock;         // a lock held when method compilations are enqueued, dequeued
+ extern Monitor* MethodCompileQueueC1_lock;       // a lock held when method compilations are enqueued, dequeued
+ extern Monitor* MethodCompileQueueC2_lock;       // a lock held when method compilations are enqueued, dequeued
+ extern Monitor* MethodCompileQueueC3_lock;       // a lock held when method compilations are enqueued, dequeued
+ extern Monitor* MethodCompileQueueSC1_lock;      // a lock held when method compilations are enqueued, dequeued
+ extern Monitor* MethodCompileQueueSC2_lock;      // a lock held when method compilations are enqueued, dequeued
  extern Monitor* CompileThread_lock;              // a lock held by compile threads during compilation system initialization
  extern Monitor* Compilation_lock;                // a lock used to pause compilation
+ extern Mutex*   TrainingData_lock;               // a lock used when accessing training records
+ extern Monitor* TrainingReplayQueue_lock;        // a lock held when class are added/removed to the training replay queue
  extern Mutex*   CompileTaskAlloc_lock;           // a lock held when CompileTasks are allocated
  extern Mutex*   CompileStatistics_lock;          // a lock held when updating compilation statistics
  extern Mutex*   DirectivesStack_lock;            // a lock held when mutating the dirstack and ref counting directives
  extern Monitor* Terminator_lock;                 // a lock used to guard termination of the vm
  extern Monitor* InitCompleted_lock;              // a lock used to signal threads waiting on init completed

@@ -123,10 +133,11 @@
  extern Mutex*   DumpRegion_lock;                 // Symbol::operator new(size_t sz, int len)
  extern Mutex*   ClassListFile_lock;              // ClassListWriter()
  extern Mutex*   UnregisteredClassesTable_lock;   // UnregisteredClassesTableTable
  extern Mutex*   LambdaFormInvokers_lock;         // Protecting LambdaFormInvokers::_lambdaform_lines
  extern Mutex*   ScratchObjects_lock;             // Protecting _scratch_xxx_table in heapShared.cpp
+ extern Mutex*   ArchivedObjectTables_lock;       // Protecting the table used by HeapShared::get_archived_object_permanent_index()
  #endif // INCLUDE_CDS
  #if INCLUDE_JFR
  extern Mutex*   JfrStacktrace_lock;              // used to guard access to the JFR stacktrace table
  extern Monitor* JfrMsg_lock;                     // protects JFR messaging
  extern Mutex*   JfrBuffer_lock;                  // protects JFR buffer operations

@@ -185,44 +196,83 @@
  // Internal implementation. Skips on null Mutex.
  // Subclasses enforce stronger invariants.
  class MutexLockerImpl: public StackObj {
   protected:
    Mutex* _mutex;
+   bool _prof;
+   elapsedTimer _before;
+   elapsedTimer _after;
+ 
+ private:
+   static PerfCounter** _perf_lock_count;
+   static PerfCounter** _perf_lock_wait_time;
+   static PerfCounter** _perf_lock_hold_time;
+ 
+ public:
  
    MutexLockerImpl(Mutex* mutex, Mutex::SafepointCheckFlag flag = Mutex::_safepoint_check_flag) :
-     _mutex(mutex) {
+     _mutex(mutex), _prof(ProfileVMLocks && Thread::current_or_null() != nullptr && Thread::current()->profile_vm_locks()) {
+ 
      bool no_safepoint_check = flag == Mutex::_no_safepoint_check_flag;
      if (_mutex != nullptr) {
+       if (_prof) { _before.start(); } // before
+ 
        if (no_safepoint_check) {
          _mutex->lock_without_safepoint_check();
        } else {
          _mutex->lock();
        }
+ 
+       if (_prof) { _before.stop(); _after.start(); } // after
      }
    }
  
    MutexLockerImpl(Thread* thread, Mutex* mutex, Mutex::SafepointCheckFlag flag = Mutex::_safepoint_check_flag) :
-     _mutex(mutex) {
+     _mutex(mutex), _prof(thread->profile_vm_locks()) {
+ 
+     if (_prof) { _before.start(); } // before
+ 
      bool no_safepoint_check = flag == Mutex::_no_safepoint_check_flag;
      if (_mutex != nullptr) {
        if (no_safepoint_check) {
          _mutex->lock_without_safepoint_check(thread);
        } else {
          _mutex->lock(thread);
        }
      }
+ 
+     if (_prof) { _before.stop(); _after.start(); } // after
    }
  
    ~MutexLockerImpl() {
      if (_mutex != nullptr) {
        assert_lock_strong(_mutex);
        _mutex->unlock();
+ 
+       if (_mutex->id() == -1) {
+         log_trace(init)("Unnamed unclassified lock: %s", _mutex->name());
+       }
+ 
+       if (_prof) {
+         assert(UsePerfData, "required");
+         _after.stop();
+         _perf_lock_count    [_mutex->id() + 1]->inc();
+         _perf_lock_wait_time[_mutex->id() + 1]->inc(_before.ticks());
+         _perf_lock_hold_time[_mutex->id() + 1]->inc(_after.ticks());
+       }
      }
    }
  
+  private:
+   static void print_counter_on(outputStream* st, const char* name, bool is_unique, int idx);
+ 
   public:
+   static int name2id(const char* name);
+ 
    static void post_initialize();
+   static void init_counters();
+   static void print_counters_on(outputStream* st);
  };
  
  // Simplest mutex locker.
  // Does not allow null mutexes.
  class MutexLocker: public MutexLockerImpl {
< prev index next >