Mercurial > hg > graal-jvmci-8
comparison src/share/vm/services/lowMemoryDetector.cpp @ 2195:bf8517f4e4d0
6766644: Redefinition of compiled method fails with assertion "Can not load classes with the Compiler thread"
Summary: Defer posting events from the compiler thread: use service thread
Reviewed-by: coleenp, dholmes, never, dcubed
author | kamg |
---|---|
date | Wed, 02 Feb 2011 14:38:01 -0500 |
parents | 3582bf76420e |
children | da91efe96a93 |
comparison
equal
deleted
inserted
replaced
2194:face83fc8882 | 2195:bf8517f4e4d0 |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
32 #include "runtime/mutex.hpp" | 32 #include "runtime/mutex.hpp" |
33 #include "runtime/mutexLocker.hpp" | 33 #include "runtime/mutexLocker.hpp" |
34 #include "services/lowMemoryDetector.hpp" | 34 #include "services/lowMemoryDetector.hpp" |
35 #include "services/management.hpp" | 35 #include "services/management.hpp" |
36 | 36 |
37 LowMemoryDetectorThread* LowMemoryDetector::_detector_thread = NULL; | |
38 volatile bool LowMemoryDetector::_enabled_for_collected_pools = false; | 37 volatile bool LowMemoryDetector::_enabled_for_collected_pools = false; |
39 volatile jint LowMemoryDetector::_disabled_count = 0; | 38 volatile jint LowMemoryDetector::_disabled_count = 0; |
40 | 39 |
41 void LowMemoryDetector::initialize() { | |
42 EXCEPTION_MARK; | |
43 | |
44 instanceKlassHandle klass (THREAD, SystemDictionary::Thread_klass()); | |
45 instanceHandle thread_oop = klass->allocate_instance_handle(CHECK); | |
46 | |
47 const char thread_name[] = "Low Memory Detector"; | |
48 Handle string = java_lang_String::create_from_str(thread_name, CHECK); | |
49 | |
50 // Initialize thread_oop to put it into the system threadGroup | |
51 Handle thread_group (THREAD, Universe::system_thread_group()); | |
52 JavaValue result(T_VOID); | |
53 JavaCalls::call_special(&result, thread_oop, | |
54 klass, | |
55 vmSymbols::object_initializer_name(), | |
56 vmSymbols::threadgroup_string_void_signature(), | |
57 thread_group, | |
58 string, | |
59 CHECK); | |
60 | |
61 { | |
62 MutexLocker mu(Threads_lock); | |
63 _detector_thread = new LowMemoryDetectorThread(&low_memory_detector_thread_entry); | |
64 | |
65 // At this point it may be possible that no osthread was created for the | |
66 // JavaThread due to lack of memory. We would have to throw an exception | |
67 // in that case. However, since this must work and we do not allow | |
68 // exceptions anyway, check and abort if this fails. | |
69 if (_detector_thread == NULL || _detector_thread->osthread() == NULL) { | |
70 vm_exit_during_initialization("java.lang.OutOfMemoryError", | |
71 "unable to create new native thread"); | |
72 } | |
73 | |
74 java_lang_Thread::set_thread(thread_oop(), _detector_thread); | |
75 java_lang_Thread::set_priority(thread_oop(), NearMaxPriority); | |
76 java_lang_Thread::set_daemon(thread_oop()); | |
77 _detector_thread->set_threadObj(thread_oop()); | |
78 | |
79 Threads::add(_detector_thread); | |
80 Thread::start(_detector_thread); | |
81 } | |
82 } | |
83 | |
84 bool LowMemoryDetector::has_pending_requests() { | 40 bool LowMemoryDetector::has_pending_requests() { |
85 assert(LowMemory_lock->owned_by_self(), "Must own LowMemory_lock"); | 41 assert(Service_lock->owned_by_self(), "Must own Service_lock"); |
86 bool has_requests = false; | 42 bool has_requests = false; |
87 int num_memory_pools = MemoryService::num_memory_pools(); | 43 int num_memory_pools = MemoryService::num_memory_pools(); |
88 for (int i = 0; i < num_memory_pools; i++) { | 44 for (int i = 0; i < num_memory_pools; i++) { |
89 MemoryPool* pool = MemoryService::get_memory_pool(i); | 45 MemoryPool* pool = MemoryService::get_memory_pool(i); |
90 SensorInfo* sensor = pool->usage_sensor(); | 46 SensorInfo* sensor = pool->usage_sensor(); |
98 } | 54 } |
99 } | 55 } |
100 return has_requests; | 56 return has_requests; |
101 } | 57 } |
102 | 58 |
103 void LowMemoryDetector::low_memory_detector_thread_entry(JavaThread* jt, TRAPS) { | 59 void LowMemoryDetector::process_sensor_changes(TRAPS) { |
104 while (true) { | 60 ResourceMark rm(THREAD); |
105 bool sensors_changed = false; | 61 HandleMark hm(THREAD); |
106 | 62 |
107 { | 63 // No need to hold Service_lock to call out to Java |
108 // _no_safepoint_check_flag is used here as LowMemory_lock is a | 64 int num_memory_pools = MemoryService::num_memory_pools(); |
109 // special lock and the VMThread may acquire this lock at safepoint. | 65 for (int i = 0; i < num_memory_pools; i++) { |
110 // Need state transition ThreadBlockInVM so that this thread | 66 MemoryPool* pool = MemoryService::get_memory_pool(i); |
111 // will be handled by safepoint correctly when this thread is | 67 SensorInfo* sensor = pool->usage_sensor(); |
112 // notified at a safepoint. | 68 SensorInfo* gc_sensor = pool->gc_usage_sensor(); |
113 | 69 if (sensor != NULL && sensor->has_pending_requests()) { |
114 // This ThreadBlockInVM object is not also considered to be | 70 sensor->process_pending_requests(CHECK); |
115 // suspend-equivalent because LowMemoryDetector threads are | 71 } |
116 // not visible to external suspension. | 72 if (gc_sensor != NULL && gc_sensor->has_pending_requests()) { |
117 | 73 gc_sensor->process_pending_requests(CHECK); |
118 ThreadBlockInVM tbivm(jt); | |
119 | |
120 MutexLockerEx ml(LowMemory_lock, Mutex::_no_safepoint_check_flag); | |
121 while (!(sensors_changed = has_pending_requests())) { | |
122 // wait until one of the sensors has pending requests | |
123 LowMemory_lock->wait(Mutex::_no_safepoint_check_flag); | |
124 } | |
125 } | |
126 | |
127 { | |
128 ResourceMark rm(THREAD); | |
129 HandleMark hm(THREAD); | |
130 | |
131 // No need to hold LowMemory_lock to call out to Java | |
132 int num_memory_pools = MemoryService::num_memory_pools(); | |
133 for (int i = 0; i < num_memory_pools; i++) { | |
134 MemoryPool* pool = MemoryService::get_memory_pool(i); | |
135 SensorInfo* sensor = pool->usage_sensor(); | |
136 SensorInfo* gc_sensor = pool->gc_usage_sensor(); | |
137 if (sensor != NULL && sensor->has_pending_requests()) { | |
138 sensor->process_pending_requests(CHECK); | |
139 } | |
140 if (gc_sensor != NULL && gc_sensor->has_pending_requests()) { | |
141 gc_sensor->process_pending_requests(CHECK); | |
142 } | |
143 } | |
144 } | 74 } |
145 } | 75 } |
146 } | 76 } |
147 | 77 |
148 // This method could be called from any Java threads | 78 // This method could be called from any Java threads |
149 // and also VMThread. | 79 // and also VMThread. |
150 void LowMemoryDetector::detect_low_memory() { | 80 void LowMemoryDetector::detect_low_memory() { |
151 MutexLockerEx ml(LowMemory_lock, Mutex::_no_safepoint_check_flag); | 81 MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag); |
152 | 82 |
153 bool has_pending_requests = false; | 83 bool has_pending_requests = false; |
154 int num_memory_pools = MemoryService::num_memory_pools(); | 84 int num_memory_pools = MemoryService::num_memory_pools(); |
155 for (int i = 0; i < num_memory_pools; i++) { | 85 for (int i = 0; i < num_memory_pools; i++) { |
156 MemoryPool* pool = MemoryService::get_memory_pool(i); | 86 MemoryPool* pool = MemoryService::get_memory_pool(i); |
164 has_pending_requests = has_pending_requests || sensor->has_pending_requests(); | 94 has_pending_requests = has_pending_requests || sensor->has_pending_requests(); |
165 } | 95 } |
166 } | 96 } |
167 | 97 |
168 if (has_pending_requests) { | 98 if (has_pending_requests) { |
169 LowMemory_lock->notify_all(); | 99 Service_lock->notify_all(); |
170 } | 100 } |
171 } | 101 } |
172 | 102 |
173 // This method could be called from any Java threads | 103 // This method could be called from any Java threads |
174 // and also VMThread. | 104 // and also VMThread. |
179 pool->usage_threshold()->high_threshold() == 0) { | 109 pool->usage_threshold()->high_threshold() == 0) { |
180 return; | 110 return; |
181 } | 111 } |
182 | 112 |
183 { | 113 { |
184 MutexLockerEx ml(LowMemory_lock, Mutex::_no_safepoint_check_flag); | 114 MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag); |
185 | 115 |
186 MemoryUsage usage = pool->get_memory_usage(); | 116 MemoryUsage usage = pool->get_memory_usage(); |
187 sensor->set_gauge_sensor_level(usage, | 117 sensor->set_gauge_sensor_level(usage, |
188 pool->usage_threshold()); | 118 pool->usage_threshold()); |
189 if (sensor->has_pending_requests()) { | 119 if (sensor->has_pending_requests()) { |
190 // notify sensor state update | 120 // notify sensor state update |
191 LowMemory_lock->notify_all(); | 121 Service_lock->notify_all(); |
192 } | 122 } |
193 } | 123 } |
194 } | 124 } |
195 | 125 |
196 // Only called by VMThread at GC time | 126 // Only called by VMThread at GC time |
201 pool->gc_usage_threshold()->high_threshold() == 0) { | 131 pool->gc_usage_threshold()->high_threshold() == 0) { |
202 return; | 132 return; |
203 } | 133 } |
204 | 134 |
205 { | 135 { |
206 MutexLockerEx ml(LowMemory_lock, Mutex::_no_safepoint_check_flag); | 136 MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag); |
207 | 137 |
208 MemoryUsage usage = pool->get_last_collection_usage(); | 138 MemoryUsage usage = pool->get_last_collection_usage(); |
209 sensor->set_counter_sensor_level(usage, pool->gc_usage_threshold()); | 139 sensor->set_counter_sensor_level(usage, pool->gc_usage_threshold()); |
210 | 140 |
211 if (sensor->has_pending_requests()) { | 141 if (sensor->has_pending_requests()) { |
212 // notify sensor state update | 142 // notify sensor state update |
213 LowMemory_lock->notify_all(); | 143 Service_lock->notify_all(); |
214 } | 144 } |
215 } | 145 } |
216 } | 146 } |
217 | 147 |
218 // recompute enabled flag | 148 // recompute enabled flag |
382 &args, | 312 &args, |
383 CHECK); | 313 CHECK); |
384 } | 314 } |
385 | 315 |
386 { | 316 { |
387 // Holds LowMemory_lock and update the sensor state | 317 // Holds Service_lock and update the sensor state |
388 MutexLockerEx ml(LowMemory_lock, Mutex::_no_safepoint_check_flag); | 318 MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag); |
389 _sensor_on = true; | 319 _sensor_on = true; |
390 _sensor_count += count; | 320 _sensor_count += count; |
391 _pending_trigger_count = _pending_trigger_count - count; | 321 _pending_trigger_count = _pending_trigger_count - count; |
392 } | 322 } |
393 } | 323 } |
408 &args, | 338 &args, |
409 CHECK); | 339 CHECK); |
410 } | 340 } |
411 | 341 |
412 { | 342 { |
413 // Holds LowMemory_lock and update the sensor state | 343 // Holds Service_lock and update the sensor state |
414 MutexLockerEx ml(LowMemory_lock, Mutex::_no_safepoint_check_flag); | 344 MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag); |
415 _sensor_on = false; | 345 _sensor_on = false; |
416 _pending_clear_count = 0; | 346 _pending_clear_count = 0; |
417 _pending_trigger_count = _pending_trigger_count - count; | 347 _pending_trigger_count = _pending_trigger_count - count; |
418 } | 348 } |
419 } | 349 } |