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 } |