src/hotspot/share/runtime/serviceThread.cpp
changeset 52421 3021c1ad958b
parent 51813 cfa50d6a6fba
child 53582 881c5fbeb849
equal deleted inserted replaced
52420:b6f32c533faf 52421:3021c1ad958b
    27 #include "classfile/stringTable.hpp"
    27 #include "classfile/stringTable.hpp"
    28 #include "classfile/symbolTable.hpp"
    28 #include "classfile/symbolTable.hpp"
    29 #include "classfile/systemDictionary.hpp"
    29 #include "classfile/systemDictionary.hpp"
    30 #include "runtime/interfaceSupport.inline.hpp"
    30 #include "runtime/interfaceSupport.inline.hpp"
    31 #include "runtime/javaCalls.hpp"
    31 #include "runtime/javaCalls.hpp"
       
    32 #include "runtime/jniHandles.hpp"
    32 #include "runtime/serviceThread.hpp"
    33 #include "runtime/serviceThread.hpp"
    33 #include "runtime/mutexLocker.hpp"
    34 #include "runtime/mutexLocker.hpp"
    34 #include "runtime/os.hpp"
    35 #include "runtime/os.hpp"
    35 #include "prims/jvmtiImpl.hpp"
    36 #include "prims/jvmtiImpl.hpp"
    36 #include "prims/resolvedMethodTable.hpp"
    37 #include "prims/resolvedMethodTable.hpp"
    78     Threads::add(thread);
    79     Threads::add(thread);
    79     Thread::start(thread);
    80     Thread::start(thread);
    80   }
    81   }
    81 }
    82 }
    82 
    83 
       
    84 static bool needs_oopstorage_cleanup(OopStorage* const* storages,
       
    85                                      bool* needs_cleanup,
       
    86                                      size_t size) {
       
    87   bool any_needs_cleanup = false;
       
    88   for (size_t i = 0; i < size; ++i) {
       
    89     assert(!needs_cleanup[i], "precondition");
       
    90     if (storages[i]->needs_delete_empty_blocks()) {
       
    91       needs_cleanup[i] = true;
       
    92       any_needs_cleanup = true;
       
    93     }
       
    94   }
       
    95   return any_needs_cleanup;
       
    96 }
       
    97 
       
    98 static void cleanup_oopstorages(OopStorage* const* storages,
       
    99                                 const bool* needs_cleanup,
       
   100                                 size_t size) {
       
   101   for (size_t i = 0; i < size; ++i) {
       
   102     if (needs_cleanup[i]) {
       
   103       storages[i]->delete_empty_blocks();
       
   104     }
       
   105   }
       
   106 }
       
   107 
    83 void ServiceThread::service_thread_entry(JavaThread* jt, TRAPS) {
   108 void ServiceThread::service_thread_entry(JavaThread* jt, TRAPS) {
       
   109   OopStorage* const oopstorages[] = {
       
   110     JNIHandles::global_handles(),
       
   111     JNIHandles::weak_global_handles(),
       
   112     StringTable::weak_storage(),
       
   113     SystemDictionary::vm_weak_oop_storage()
       
   114   };
       
   115   const size_t oopstorage_count = ARRAY_SIZE(oopstorages);
       
   116 
    84   while (true) {
   117   while (true) {
    85     bool sensors_changed = false;
   118     bool sensors_changed = false;
    86     bool has_jvmti_events = false;
   119     bool has_jvmti_events = false;
    87     bool has_gc_notification_event = false;
   120     bool has_gc_notification_event = false;
    88     bool has_dcmd_notification_event = false;
   121     bool has_dcmd_notification_event = false;
    89     bool stringtable_work = false;
   122     bool stringtable_work = false;
    90     bool symboltable_work = false;
   123     bool symboltable_work = false;
    91     bool resolved_method_table_work = false;
   124     bool resolved_method_table_work = false;
    92     bool protection_domain_table_work = false;
   125     bool protection_domain_table_work = false;
       
   126     bool oopstorage_work = false;
       
   127     bool oopstorages_cleanup[oopstorage_count] = {}; // Zero (false) initialize.
    93     JvmtiDeferredEvent jvmti_event;
   128     JvmtiDeferredEvent jvmti_event;
    94     {
   129     {
    95       // Need state transition ThreadBlockInVM so that this thread
   130       // Need state transition ThreadBlockInVM so that this thread
    96       // will be handled by safepoint correctly when this thread is
   131       // will be handled by safepoint correctly when this thread is
    97       // notified at a safepoint.
   132       // notified at a safepoint.
   100       // suspend-equivalent because ServiceThread is not visible to
   135       // suspend-equivalent because ServiceThread is not visible to
   101       // external suspension.
   136       // external suspension.
   102 
   137 
   103       ThreadBlockInVM tbivm(jt);
   138       ThreadBlockInVM tbivm(jt);
   104 
   139 
   105       MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag);
   140       MonitorLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag);
   106       // Process all available work on each (outer) iteration, rather than
   141       // Process all available work on each (outer) iteration, rather than
   107       // only the first recognized bit of work, to avoid frequently true early
   142       // only the first recognized bit of work, to avoid frequently true early
   108       // tests from potentially starving later work.  Hence the use of
   143       // tests from potentially starving later work.  Hence the use of
   109       // arithmetic-or to combine results; we don't want short-circuiting.
   144       // arithmetic-or to combine results; we don't want short-circuiting.
   110       while (((sensors_changed = LowMemoryDetector::has_pending_requests()) |
   145       while (((sensors_changed = LowMemoryDetector::has_pending_requests()) |
   112               (has_gc_notification_event = GCNotifier::has_event()) |
   147               (has_gc_notification_event = GCNotifier::has_event()) |
   113               (has_dcmd_notification_event = DCmdFactory::has_pending_jmx_notification()) |
   148               (has_dcmd_notification_event = DCmdFactory::has_pending_jmx_notification()) |
   114               (stringtable_work = StringTable::has_work()) |
   149               (stringtable_work = StringTable::has_work()) |
   115               (symboltable_work = SymbolTable::has_work()) |
   150               (symboltable_work = SymbolTable::has_work()) |
   116               (resolved_method_table_work = ResolvedMethodTable::has_work()) |
   151               (resolved_method_table_work = ResolvedMethodTable::has_work()) |
   117               (protection_domain_table_work = SystemDictionary::pd_cache_table()->has_work()))
   152               (protection_domain_table_work = SystemDictionary::pd_cache_table()->has_work()) |
       
   153               (oopstorage_work = needs_oopstorage_cleanup(oopstorages,
       
   154                                                           oopstorages_cleanup,
       
   155                                                           oopstorage_count)))
       
   156 
   118              == 0) {
   157              == 0) {
   119         // Wait until notified that there is some work to do.
   158         // Wait until notified that there is some work to do.
   120         Service_lock->wait(Mutex::_no_safepoint_check_flag);
   159         ml.wait(Mutex::_no_safepoint_check_flag);
   121       }
   160       }
   122 
   161 
   123       if (has_jvmti_events) {
   162       if (has_jvmti_events) {
   124         jvmti_event = JvmtiDeferredEventQueue::dequeue();
   163         jvmti_event = JvmtiDeferredEventQueue::dequeue();
   125       }
   164       }
   154     }
   193     }
   155 
   194 
   156     if (protection_domain_table_work) {
   195     if (protection_domain_table_work) {
   157       SystemDictionary::pd_cache_table()->unlink();
   196       SystemDictionary::pd_cache_table()->unlink();
   158     }
   197     }
       
   198 
       
   199     if (oopstorage_work) {
       
   200       cleanup_oopstorages(oopstorages, oopstorages_cleanup, oopstorage_count);
       
   201     }
   159   }
   202   }
   160 }
   203 }
   161 
   204 
   162 bool ServiceThread::is_service_thread(Thread* thread) {
   205 bool ServiceThread::is_service_thread(Thread* thread) {
   163   return thread == _instance;
   206   return thread == _instance;