25 #include "precompiled.hpp" |
25 #include "precompiled.hpp" |
26 #include "classfile/protectionDomainCache.hpp" |
26 #include "classfile/protectionDomainCache.hpp" |
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 "gc/shared/oopStorage.hpp" |
|
31 #include "gc/shared/oopStorageSet.hpp" |
30 #include "memory/universe.hpp" |
32 #include "memory/universe.hpp" |
31 #include "runtime/handles.inline.hpp" |
33 #include "runtime/handles.inline.hpp" |
32 #include "runtime/interfaceSupport.inline.hpp" |
34 #include "runtime/interfaceSupport.inline.hpp" |
33 #include "runtime/javaCalls.hpp" |
35 #include "runtime/javaCalls.hpp" |
34 #include "runtime/jniHandles.hpp" |
36 #include "runtime/jniHandles.hpp" |
39 #include "prims/resolvedMethodTable.hpp" |
41 #include "prims/resolvedMethodTable.hpp" |
40 #include "services/diagnosticArgument.hpp" |
42 #include "services/diagnosticArgument.hpp" |
41 #include "services/diagnosticFramework.hpp" |
43 #include "services/diagnosticFramework.hpp" |
42 #include "services/gcNotifier.hpp" |
44 #include "services/gcNotifier.hpp" |
43 #include "services/lowMemoryDetector.hpp" |
45 #include "services/lowMemoryDetector.hpp" |
|
46 #include "services/threadIdTable.hpp" |
44 |
47 |
45 ServiceThread* ServiceThread::_instance = NULL; |
48 ServiceThread* ServiceThread::_instance = NULL; |
46 |
49 |
47 void ServiceThread::initialize() { |
50 void ServiceThread::initialize() { |
48 EXCEPTION_MARK; |
51 EXCEPTION_MARK; |
81 Threads::add(thread); |
84 Threads::add(thread); |
82 Thread::start(thread); |
85 Thread::start(thread); |
83 } |
86 } |
84 } |
87 } |
85 |
88 |
86 static bool needs_oopstorage_cleanup(OopStorage* const* storages, |
89 static void cleanup_oopstorages() { |
87 bool* needs_cleanup, |
90 OopStorageSet::Iterator it = OopStorageSet::all_iterator(); |
88 size_t size) { |
91 for ( ; !it.is_end(); ++it) { |
89 bool any_needs_cleanup = false; |
92 it->delete_empty_blocks(); |
90 for (size_t i = 0; i < size; ++i) { |
|
91 assert(!needs_cleanup[i], "precondition"); |
|
92 if (storages[i]->needs_delete_empty_blocks()) { |
|
93 needs_cleanup[i] = true; |
|
94 any_needs_cleanup = true; |
|
95 } |
|
96 } |
|
97 return any_needs_cleanup; |
|
98 } |
|
99 |
|
100 static void cleanup_oopstorages(OopStorage* const* storages, |
|
101 const bool* needs_cleanup, |
|
102 size_t size) { |
|
103 for (size_t i = 0; i < size; ++i) { |
|
104 if (needs_cleanup[i]) { |
|
105 storages[i]->delete_empty_blocks(); |
|
106 } |
|
107 } |
93 } |
108 } |
94 } |
109 |
95 |
110 void ServiceThread::service_thread_entry(JavaThread* jt, TRAPS) { |
96 void ServiceThread::service_thread_entry(JavaThread* jt, TRAPS) { |
111 OopStorage* const oopstorages[] = { |
|
112 JNIHandles::global_handles(), |
|
113 JNIHandles::weak_global_handles(), |
|
114 StringTable::weak_storage(), |
|
115 SystemDictionary::vm_weak_oop_storage() |
|
116 }; |
|
117 const size_t oopstorage_count = ARRAY_SIZE(oopstorages); |
|
118 |
|
119 while (true) { |
97 while (true) { |
120 bool sensors_changed = false; |
98 bool sensors_changed = false; |
121 bool has_jvmti_events = false; |
99 bool has_jvmti_events = false; |
122 bool has_gc_notification_event = false; |
100 bool has_gc_notification_event = false; |
123 bool has_dcmd_notification_event = false; |
101 bool has_dcmd_notification_event = false; |
124 bool stringtable_work = false; |
102 bool stringtable_work = false; |
125 bool symboltable_work = false; |
103 bool symboltable_work = false; |
126 bool resolved_method_table_work = false; |
104 bool resolved_method_table_work = false; |
|
105 bool thread_id_table_work = false; |
127 bool protection_domain_table_work = false; |
106 bool protection_domain_table_work = false; |
128 bool oopstorage_work = false; |
107 bool oopstorage_work = false; |
129 bool oopstorages_cleanup[oopstorage_count] = {}; // Zero (false) initialize. |
|
130 JvmtiDeferredEvent jvmti_event; |
108 JvmtiDeferredEvent jvmti_event; |
131 { |
109 { |
132 // Need state transition ThreadBlockInVM so that this thread |
110 // Need state transition ThreadBlockInVM so that this thread |
133 // will be handled by safepoint correctly when this thread is |
111 // will be handled by safepoint correctly when this thread is |
134 // notified at a safepoint. |
112 // notified at a safepoint. |
142 MonitorLocker ml(Service_lock, Mutex::_no_safepoint_check_flag); |
120 MonitorLocker ml(Service_lock, Mutex::_no_safepoint_check_flag); |
143 // Process all available work on each (outer) iteration, rather than |
121 // Process all available work on each (outer) iteration, rather than |
144 // only the first recognized bit of work, to avoid frequently true early |
122 // only the first recognized bit of work, to avoid frequently true early |
145 // tests from potentially starving later work. Hence the use of |
123 // tests from potentially starving later work. Hence the use of |
146 // arithmetic-or to combine results; we don't want short-circuiting. |
124 // arithmetic-or to combine results; we don't want short-circuiting. |
147 while (((sensors_changed = LowMemoryDetector::has_pending_requests()) | |
125 while (((sensors_changed = (!UseNotificationThread && LowMemoryDetector::has_pending_requests())) | |
148 (has_jvmti_events = JvmtiDeferredEventQueue::has_events()) | |
126 (has_jvmti_events = JvmtiDeferredEventQueue::has_events()) | |
149 (has_gc_notification_event = GCNotifier::has_event()) | |
127 (has_gc_notification_event = (!UseNotificationThread && GCNotifier::has_event())) | |
150 (has_dcmd_notification_event = DCmdFactory::has_pending_jmx_notification()) | |
128 (has_dcmd_notification_event = (!UseNotificationThread && DCmdFactory::has_pending_jmx_notification())) | |
151 (stringtable_work = StringTable::has_work()) | |
129 (stringtable_work = StringTable::has_work()) | |
152 (symboltable_work = SymbolTable::has_work()) | |
130 (symboltable_work = SymbolTable::has_work()) | |
153 (resolved_method_table_work = ResolvedMethodTable::has_work()) | |
131 (resolved_method_table_work = ResolvedMethodTable::has_work()) | |
|
132 (thread_id_table_work = ThreadIdTable::has_work()) | |
154 (protection_domain_table_work = SystemDictionary::pd_cache_table()->has_work()) | |
133 (protection_domain_table_work = SystemDictionary::pd_cache_table()->has_work()) | |
155 (oopstorage_work = needs_oopstorage_cleanup(oopstorages, |
134 (oopstorage_work = OopStorage::has_cleanup_work_and_reset()) |
156 oopstorages_cleanup, |
135 ) == 0) { |
157 oopstorage_count))) |
|
158 |
|
159 == 0) { |
|
160 // Wait until notified that there is some work to do. |
136 // Wait until notified that there is some work to do. |
161 ml.wait(); |
137 ml.wait(); |
162 } |
138 } |
163 |
139 |
164 if (has_jvmti_events) { |
140 if (has_jvmti_events) { |
176 |
152 |
177 if (has_jvmti_events) { |
153 if (has_jvmti_events) { |
178 jvmti_event.post(); |
154 jvmti_event.post(); |
179 } |
155 } |
180 |
156 |
181 if (sensors_changed) { |
157 if (!UseNotificationThread) { |
182 LowMemoryDetector::process_sensor_changes(jt); |
158 if (sensors_changed) { |
183 } |
159 LowMemoryDetector::process_sensor_changes(jt); |
|
160 } |
184 |
161 |
185 if(has_gc_notification_event) { |
162 if(has_gc_notification_event) { |
186 GCNotifier::sendNotification(CHECK); |
163 GCNotifier::sendNotification(CHECK); |
187 } |
164 } |
188 |
165 |
189 if(has_dcmd_notification_event) { |
166 if(has_dcmd_notification_event) { |
190 DCmdFactory::send_notification(CHECK); |
167 DCmdFactory::send_notification(CHECK); |
|
168 } |
191 } |
169 } |
192 |
170 |
193 if (resolved_method_table_work) { |
171 if (resolved_method_table_work) { |
194 ResolvedMethodTable::do_concurrent_work(jt); |
172 ResolvedMethodTable::do_concurrent_work(jt); |
|
173 } |
|
174 |
|
175 if (thread_id_table_work) { |
|
176 ThreadIdTable::do_concurrent_work(jt); |
195 } |
177 } |
196 |
178 |
197 if (protection_domain_table_work) { |
179 if (protection_domain_table_work) { |
198 SystemDictionary::pd_cache_table()->unlink(); |
180 SystemDictionary::pd_cache_table()->unlink(); |
199 } |
181 } |
200 |
182 |
201 if (oopstorage_work) { |
183 if (oopstorage_work) { |
202 cleanup_oopstorages(oopstorages, oopstorages_cleanup, oopstorage_count); |
184 cleanup_oopstorages(); |
203 } |
185 } |
204 } |
186 } |
205 } |
187 } |
206 |
188 |
207 bool ServiceThread::is_service_thread(Thread* thread) { |
189 bool ServiceThread::is_service_thread(Thread* thread) { |