20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "classfile/protectionDomainCache.hpp"
27 #include "classfile/stringTable.hpp"
28 #include "classfile/symbolTable.hpp"
29 #include "classfile/systemDictionary.hpp"
30 #include "memory/universe.hpp"
31 #include "runtime/handles.inline.hpp"
32 #include "runtime/interfaceSupport.inline.hpp"
33 #include "runtime/javaCalls.hpp"
34 #include "runtime/jniHandles.hpp"
35 #include "runtime/serviceThread.hpp"
36 #include "runtime/mutexLocker.hpp"
37 #include "runtime/os.hpp"
38 #include "prims/jvmtiImpl.hpp"
39 #include "prims/resolvedMethodTable.hpp"
40 #include "services/diagnosticArgument.hpp"
41 #include "services/diagnosticFramework.hpp"
42 #include "services/gcNotifier.hpp"
43 #include "services/lowMemoryDetector.hpp"
44
45 ServiceThread* ServiceThread::_instance = NULL;
46
47 void ServiceThread::initialize() {
48 EXCEPTION_MARK;
49
50 const char* name = "Service Thread";
51 Handle string = java_lang_String::create_from_str(name, CHECK);
52
53 // Initialize thread_oop to put it into the system threadGroup
54 Handle thread_group (THREAD, Universe::system_thread_group());
55 Handle thread_oop = JavaCalls::construct_new_instance(
56 SystemDictionary::Thread_klass(),
57 vmSymbols::threadgroup_string_void_signature(),
58 thread_group,
59 string,
60 CHECK);
61
62 {
63 MutexLocker mu(Threads_lock);
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 }
108 }
109
110 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) {
120 bool sensors_changed = false;
121 bool has_jvmti_events = false;
122 bool has_gc_notification_event = false;
123 bool has_dcmd_notification_event = false;
124 bool stringtable_work = false;
125 bool symboltable_work = false;
126 bool resolved_method_table_work = false;
127 bool protection_domain_table_work = false;
128 bool oopstorage_work = false;
129 bool oopstorages_cleanup[oopstorage_count] = {}; // Zero (false) initialize.
130 JvmtiDeferredEvent jvmti_event;
131 {
132 // Need state transition ThreadBlockInVM so that this thread
133 // will be handled by safepoint correctly when this thread is
134 // notified at a safepoint.
135
136 // This ThreadBlockInVM object is not also considered to be
137 // suspend-equivalent because ServiceThread is not visible to
138 // external suspension.
139
140 ThreadBlockInVM tbivm(jt);
141
142 MonitorLocker ml(Service_lock, Mutex::_no_safepoint_check_flag);
143 // Process all available work on each (outer) iteration, rather than
144 // only the first recognized bit of work, to avoid frequently true early
145 // tests from potentially starving later work. Hence the use of
146 // arithmetic-or to combine results; we don't want short-circuiting.
147 while (((sensors_changed = LowMemoryDetector::has_pending_requests()) |
148 (has_jvmti_events = JvmtiDeferredEventQueue::has_events()) |
149 (has_gc_notification_event = GCNotifier::has_event()) |
150 (has_dcmd_notification_event = DCmdFactory::has_pending_jmx_notification()) |
151 (stringtable_work = StringTable::has_work()) |
152 (symboltable_work = SymbolTable::has_work()) |
153 (resolved_method_table_work = ResolvedMethodTable::has_work()) |
154 (protection_domain_table_work = SystemDictionary::pd_cache_table()->has_work()) |
155 (oopstorage_work = needs_oopstorage_cleanup(oopstorages,
156 oopstorages_cleanup,
157 oopstorage_count)))
158
159 == 0) {
160 // Wait until notified that there is some work to do.
161 ml.wait();
162 }
163
164 if (has_jvmti_events) {
165 jvmti_event = JvmtiDeferredEventQueue::dequeue();
166 }
167 }
168
169 if (stringtable_work) {
170 StringTable::do_concurrent_work(jt);
171 }
172
173 if (symboltable_work) {
174 SymbolTable::do_concurrent_work(jt);
175 }
176
177 if (has_jvmti_events) {
178 jvmti_event.post();
179 }
180
181 if (sensors_changed) {
182 LowMemoryDetector::process_sensor_changes(jt);
183 }
184
185 if(has_gc_notification_event) {
186 GCNotifier::sendNotification(CHECK);
187 }
188
189 if(has_dcmd_notification_event) {
190 DCmdFactory::send_notification(CHECK);
191 }
192
193 if (resolved_method_table_work) {
194 ResolvedMethodTable::do_concurrent_work(jt);
195 }
196
197 if (protection_domain_table_work) {
198 SystemDictionary::pd_cache_table()->unlink();
199 }
200
201 if (oopstorage_work) {
202 cleanup_oopstorages(oopstorages, oopstorages_cleanup, oopstorage_count);
203 }
204 }
205 }
206
207 bool ServiceThread::is_service_thread(Thread* thread) {
208 return thread == _instance;
209 }
|
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "classfile/protectionDomainCache.hpp"
27 #include "classfile/stringTable.hpp"
28 #include "classfile/symbolTable.hpp"
29 #include "classfile/systemDictionary.hpp"
30 #include "memory/universe.hpp"
31 #include "runtime/handles.inline.hpp"
32 #include "runtime/interfaceSupport.inline.hpp"
33 #include "runtime/javaCalls.hpp"
34 #include "runtime/jniHandles.hpp"
35 #include "runtime/serviceThread.hpp"
36 #include "runtime/mutexLocker.hpp"
37 #include "runtime/os.hpp"
38 #include "prims/jvmtiImpl.hpp"
39 #include "prims/resolvedMethodTable.hpp"
40
41 ServiceThread* ServiceThread::_instance = NULL;
42
43 void ServiceThread::initialize() {
44 EXCEPTION_MARK;
45
46 const char* name = "Service Thread";
47 Handle string = java_lang_String::create_from_str(name, CHECK);
48
49 // Initialize thread_oop to put it into the system threadGroup
50 Handle thread_group (THREAD, Universe::system_thread_group());
51 Handle thread_oop = JavaCalls::construct_new_instance(
52 SystemDictionary::Thread_klass(),
53 vmSymbols::threadgroup_string_void_signature(),
54 thread_group,
55 string,
56 CHECK);
57
58 {
59 MutexLocker mu(Threads_lock);
96 static void cleanup_oopstorages(OopStorage* const* storages,
97 const bool* needs_cleanup,
98 size_t size) {
99 for (size_t i = 0; i < size; ++i) {
100 if (needs_cleanup[i]) {
101 storages[i]->delete_empty_blocks();
102 }
103 }
104 }
105
106 void ServiceThread::service_thread_entry(JavaThread* jt, TRAPS) {
107 OopStorage* const oopstorages[] = {
108 JNIHandles::global_handles(),
109 JNIHandles::weak_global_handles(),
110 StringTable::weak_storage(),
111 SystemDictionary::vm_weak_oop_storage()
112 };
113 const size_t oopstorage_count = ARRAY_SIZE(oopstorages);
114
115 while (true) {
116 bool has_jvmti_events = false;
117 bool stringtable_work = false;
118 bool symboltable_work = false;
119 bool resolved_method_table_work = false;
120 bool protection_domain_table_work = false;
121 bool oopstorage_work = false;
122 bool oopstorages_cleanup[oopstorage_count] = {}; // Zero (false) initialize.
123 JvmtiDeferredEvent jvmti_event;
124 {
125 // Need state transition ThreadBlockInVM so that this thread
126 // will be handled by safepoint correctly when this thread is
127 // notified at a safepoint.
128
129 // This ThreadBlockInVM object is not also considered to be
130 // suspend-equivalent because ServiceThread is not visible to
131 // external suspension.
132
133 ThreadBlockInVM tbivm(jt);
134
135 MonitorLocker ml(Service_lock, Mutex::_no_safepoint_check_flag);
136 // Process all available work on each (outer) iteration, rather than
137 // only the first recognized bit of work, to avoid frequently true early
138 // tests from potentially starving later work. Hence the use of
139 // arithmetic-or to combine results; we don't want short-circuiting.
140 while (((has_jvmti_events = JvmtiDeferredEventQueue::has_events()) |
141 (stringtable_work = StringTable::has_work()) |
142 (symboltable_work = SymbolTable::has_work()) |
143 (resolved_method_table_work = ResolvedMethodTable::has_work()) |
144 (protection_domain_table_work = SystemDictionary::pd_cache_table()->has_work()) |
145 (oopstorage_work = needs_oopstorage_cleanup(oopstorages,
146 oopstorages_cleanup,
147 oopstorage_count)))
148
149 == 0) {
150 // Wait until notified that there is some work to do.
151 ml.wait();
152 }
153
154 if (has_jvmti_events) {
155 jvmti_event = JvmtiDeferredEventQueue::dequeue();
156 }
157 }
158
159 if (stringtable_work) {
160 StringTable::do_concurrent_work(jt);
161 }
162
163 if (symboltable_work) {
164 SymbolTable::do_concurrent_work(jt);
165 }
166
167 if (has_jvmti_events) {
168 jvmti_event.post();
169 }
170
171 if (resolved_method_table_work) {
172 ResolvedMethodTable::do_concurrent_work(jt);
173 }
174
175 if (protection_domain_table_work) {
176 SystemDictionary::pd_cache_table()->unlink();
177 }
178
179 if (oopstorage_work) {
180 cleanup_oopstorages(oopstorages, oopstorages_cleanup, oopstorage_count);
181 }
182 }
183 }
184
185 bool ServiceThread::is_service_thread(Thread* thread) {
186 return thread == _instance;
187 }
|