Mercurial > hg > truffle
annotate src/share/vm/runtime/vm_operations.cpp @ 1721:413ad0331a0c
6977924: Changes for 6975078 produce build error with certain gcc versions
Summary: The changes introduced for 6975078 assign badHeapOopVal to the _allocation field in the ResourceObj class. In 32 bit linux builds with certain versions of gcc this assignment will be flagged as an error while compiling allocation.cpp. In 32 bit builds the constant value badHeapOopVal (which is cast to an intptr_t) is negative. The _allocation field is typed as an unsigned intptr_t and gcc catches this as an error.
Reviewed-by: jcoomes, ysr, phh
author | johnc |
---|---|
date | Wed, 18 Aug 2010 10:59:06 -0700 |
parents | c18cbe5936b8 |
children | ce6848d0666d |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1202
diff
changeset
|
2 * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
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 | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1202
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1202
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1202
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 # include "incls/_precompiled.incl" | |
26 # include "incls/_vm_operations.cpp.incl" | |
27 | |
28 #define VM_OP_NAME_INITIALIZE(name) #name, | |
29 | |
30 const char* VM_Operation::_names[VM_Operation::VMOp_Terminating] = \ | |
31 { VM_OPS_DO(VM_OP_NAME_INITIALIZE) }; | |
32 | |
33 void VM_Operation::set_calling_thread(Thread* thread, ThreadPriority priority) { | |
34 _calling_thread = thread; | |
35 assert(MinPriority <= priority && priority <= MaxPriority, "sanity check"); | |
36 _priority = priority; | |
37 } | |
38 | |
39 | |
40 void VM_Operation::evaluate() { | |
41 ResourceMark rm; | |
42 if (TraceVMOperation) { | |
43 tty->print("["); | |
44 NOT_PRODUCT(print();) | |
45 } | |
46 doit(); | |
47 if (TraceVMOperation) { | |
48 tty->print_cr("]"); | |
49 } | |
50 } | |
51 | |
52 // Called by fatal error handler. | |
53 void VM_Operation::print_on_error(outputStream* st) const { | |
54 st->print("VM_Operation (" PTR_FORMAT "): ", this); | |
55 st->print("%s", name()); | |
56 | |
57 const char* mode; | |
58 switch(evaluation_mode()) { | |
59 case _safepoint : mode = "safepoint"; break; | |
60 case _no_safepoint : mode = "no safepoint"; break; | |
61 case _concurrent : mode = "concurrent"; break; | |
62 case _async_safepoint: mode = "async safepoint"; break; | |
63 default : mode = "unknown"; break; | |
64 } | |
65 st->print(", mode: %s", mode); | |
66 | |
67 if (calling_thread()) { | |
68 st->print(", requested by thread " PTR_FORMAT, calling_thread()); | |
69 } | |
70 } | |
71 | |
72 void VM_ThreadStop::doit() { | |
73 assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint"); | |
74 JavaThread* target = java_lang_Thread::thread(target_thread()); | |
75 // Note that this now allows multiple ThreadDeath exceptions to be | |
76 // thrown at a thread. | |
77 if (target != NULL) { | |
78 // the thread has run and is not already in the process of exiting | |
79 target->send_thread_stop(throwable()); | |
80 } | |
81 } | |
82 | |
83 void VM_Deoptimize::doit() { | |
84 // We do not want any GCs to happen while we are in the middle of this VM operation | |
85 ResourceMark rm; | |
86 DeoptimizationMarker dm; | |
87 | |
88 // Deoptimize all activations depending on marked nmethods | |
89 Deoptimization::deoptimize_dependents(); | |
90 | |
91 // Make the dependent methods zombies | |
92 CodeCache::make_marked_nmethods_zombies(); | |
93 } | |
94 | |
95 | |
96 VM_DeoptimizeFrame::VM_DeoptimizeFrame(JavaThread* thread, intptr_t* id) { | |
97 _thread = thread; | |
98 _id = id; | |
99 } | |
100 | |
101 | |
102 void VM_DeoptimizeFrame::doit() { | |
103 Deoptimization::deoptimize_frame(_thread, _id); | |
104 } | |
105 | |
106 | |
107 #ifndef PRODUCT | |
108 | |
109 void VM_DeoptimizeAll::doit() { | |
110 DeoptimizationMarker dm; | |
111 // deoptimize all java threads in the system | |
112 if (DeoptimizeALot) { | |
113 for (JavaThread* thread = Threads::first(); thread != NULL; thread = thread->next()) { | |
114 if (thread->has_last_Java_frame()) { | |
115 thread->deoptimize(); | |
116 } | |
117 } | |
118 } else if (DeoptimizeRandom) { | |
119 | |
120 // Deoptimize some selected threads and frames | |
121 int tnum = os::random() & 0x3; | |
122 int fnum = os::random() & 0x3; | |
123 int tcount = 0; | |
124 for (JavaThread* thread = Threads::first(); thread != NULL; thread = thread->next()) { | |
125 if (thread->has_last_Java_frame()) { | |
126 if (tcount++ == tnum) { | |
127 tcount = 0; | |
128 int fcount = 0; | |
129 // Deoptimize some selected frames. | |
130 // Biased llocking wants a updated register map | |
131 for(StackFrameStream fst(thread, UseBiasedLocking); !fst.is_done(); fst.next()) { | |
132 if (fst.current()->can_be_deoptimized()) { | |
133 if (fcount++ == fnum) { | |
134 fcount = 0; | |
135 Deoptimization::deoptimize(thread, *fst.current(), fst.register_map()); | |
136 } | |
137 } | |
138 } | |
139 } | |
140 } | |
141 } | |
142 } | |
143 } | |
144 | |
145 | |
146 void VM_ZombieAll::doit() { | |
147 JavaThread *thread = (JavaThread *)calling_thread(); | |
148 assert(thread->is_Java_thread(), "must be a Java thread"); | |
149 thread->make_zombies(); | |
150 } | |
151 | |
152 #endif // !PRODUCT | |
153 | |
1202 | 154 void VM_HandleFullCodeCache::doit() { |
155 NMethodSweeper::speculative_disconnect_nmethods(_is_full); | |
156 } | |
157 | |
0 | 158 void VM_Verify::doit() { |
159 Universe::verify(); | |
160 } | |
161 | |
162 bool VM_PrintThreads::doit_prologue() { | |
163 assert(Thread::current()->is_Java_thread(), "just checking"); | |
164 | |
165 // Make sure AbstractOwnableSynchronizer is loaded | |
166 if (JDK_Version::is_gte_jdk16x_version()) { | |
167 java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(JavaThread::current()); | |
168 } | |
169 | |
170 // Get Heap_lock if concurrent locks will be dumped | |
171 if (_print_concurrent_locks) { | |
172 Heap_lock->lock(); | |
173 } | |
174 return true; | |
175 } | |
176 | |
177 void VM_PrintThreads::doit() { | |
178 Threads::print_on(_out, true, false, _print_concurrent_locks); | |
179 } | |
180 | |
181 void VM_PrintThreads::doit_epilogue() { | |
182 if (_print_concurrent_locks) { | |
183 // Release Heap_lock | |
184 Heap_lock->unlock(); | |
185 } | |
186 } | |
187 | |
188 void VM_PrintJNI::doit() { | |
189 JNIHandles::print_on(_out); | |
190 } | |
191 | |
192 VM_FindDeadlocks::~VM_FindDeadlocks() { | |
193 if (_deadlocks != NULL) { | |
194 DeadlockCycle* cycle = _deadlocks; | |
195 while (cycle != NULL) { | |
196 DeadlockCycle* d = cycle; | |
197 cycle = cycle->next(); | |
198 delete d; | |
199 } | |
200 } | |
201 } | |
202 | |
203 bool VM_FindDeadlocks::doit_prologue() { | |
204 assert(Thread::current()->is_Java_thread(), "just checking"); | |
205 | |
206 // Load AbstractOwnableSynchronizer class | |
207 if (_concurrent_locks && JDK_Version::is_gte_jdk16x_version()) { | |
208 java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(JavaThread::current()); | |
209 } | |
210 | |
211 return true; | |
212 } | |
213 | |
214 void VM_FindDeadlocks::doit() { | |
215 _deadlocks = ThreadService::find_deadlocks_at_safepoint(_concurrent_locks); | |
216 if (_out != NULL) { | |
217 int num_deadlocks = 0; | |
218 for (DeadlockCycle* cycle = _deadlocks; cycle != NULL; cycle = cycle->next()) { | |
219 num_deadlocks++; | |
220 cycle->print_on(_out); | |
221 } | |
222 | |
223 if (num_deadlocks == 1) { | |
224 _out->print_cr("\nFound 1 deadlock.\n"); | |
225 _out->flush(); | |
226 } else if (num_deadlocks > 1) { | |
227 _out->print_cr("\nFound %d deadlocks.\n", num_deadlocks); | |
228 _out->flush(); | |
229 } | |
230 } | |
231 } | |
232 | |
233 VM_ThreadDump::VM_ThreadDump(ThreadDumpResult* result, | |
234 int max_depth, | |
235 bool with_locked_monitors, | |
236 bool with_locked_synchronizers) { | |
237 _result = result; | |
238 _num_threads = 0; // 0 indicates all threads | |
239 _threads = NULL; | |
240 _result = result; | |
241 _max_depth = max_depth; | |
242 _with_locked_monitors = with_locked_monitors; | |
243 _with_locked_synchronizers = with_locked_synchronizers; | |
244 } | |
245 | |
246 VM_ThreadDump::VM_ThreadDump(ThreadDumpResult* result, | |
247 GrowableArray<instanceHandle>* threads, | |
248 int num_threads, | |
249 int max_depth, | |
250 bool with_locked_monitors, | |
251 bool with_locked_synchronizers) { | |
252 _result = result; | |
253 _num_threads = num_threads; | |
254 _threads = threads; | |
255 _result = result; | |
256 _max_depth = max_depth; | |
257 _with_locked_monitors = with_locked_monitors; | |
258 _with_locked_synchronizers = with_locked_synchronizers; | |
259 } | |
260 | |
261 bool VM_ThreadDump::doit_prologue() { | |
262 assert(Thread::current()->is_Java_thread(), "just checking"); | |
263 | |
264 // Load AbstractOwnableSynchronizer class before taking thread snapshots | |
265 if (JDK_Version::is_gte_jdk16x_version()) { | |
266 java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(JavaThread::current()); | |
267 } | |
268 | |
269 if (_with_locked_synchronizers) { | |
270 // Acquire Heap_lock to dump concurrent locks | |
271 Heap_lock->lock(); | |
272 } | |
273 | |
274 return true; | |
275 } | |
276 | |
277 void VM_ThreadDump::doit_epilogue() { | |
278 if (_with_locked_synchronizers) { | |
279 // Release Heap_lock | |
280 Heap_lock->unlock(); | |
281 } | |
282 } | |
283 | |
284 void VM_ThreadDump::doit() { | |
285 ResourceMark rm; | |
286 | |
287 ConcurrentLocksDump concurrent_locks(true); | |
288 if (_with_locked_synchronizers) { | |
289 concurrent_locks.dump_at_safepoint(); | |
290 } | |
291 | |
292 if (_num_threads == 0) { | |
293 // Snapshot all live threads | |
294 for (JavaThread* jt = Threads::first(); jt != NULL; jt = jt->next()) { | |
295 if (jt->is_exiting() || | |
296 jt->is_hidden_from_external_view()) { | |
297 // skip terminating threads and hidden threads | |
298 continue; | |
299 } | |
300 ThreadConcurrentLocks* tcl = NULL; | |
301 if (_with_locked_synchronizers) { | |
302 tcl = concurrent_locks.thread_concurrent_locks(jt); | |
303 } | |
304 ThreadSnapshot* ts = snapshot_thread(jt, tcl); | |
305 _result->add_thread_snapshot(ts); | |
306 } | |
307 } else { | |
308 // Snapshot threads in the given _threads array | |
309 // A dummy snapshot is created if a thread doesn't exist | |
310 for (int i = 0; i < _num_threads; i++) { | |
311 instanceHandle th = _threads->at(i); | |
312 if (th() == NULL) { | |
313 // skip if the thread doesn't exist | |
314 // Add a dummy snapshot | |
315 _result->add_thread_snapshot(new ThreadSnapshot()); | |
316 continue; | |
317 } | |
318 | |
319 // Dump thread stack only if the thread is alive and not exiting | |
320 // and not VM internal thread. | |
321 JavaThread* jt = java_lang_Thread::thread(th()); | |
322 if (jt == NULL || /* thread not alive */ | |
323 jt->is_exiting() || | |
324 jt->is_hidden_from_external_view()) { | |
325 // add a NULL snapshot if skipped | |
326 _result->add_thread_snapshot(new ThreadSnapshot()); | |
327 continue; | |
328 } | |
329 ThreadConcurrentLocks* tcl = NULL; | |
330 if (_with_locked_synchronizers) { | |
331 tcl = concurrent_locks.thread_concurrent_locks(jt); | |
332 } | |
333 ThreadSnapshot* ts = snapshot_thread(jt, tcl); | |
334 _result->add_thread_snapshot(ts); | |
335 } | |
336 } | |
337 } | |
338 | |
339 ThreadSnapshot* VM_ThreadDump::snapshot_thread(JavaThread* java_thread, ThreadConcurrentLocks* tcl) { | |
340 ThreadSnapshot* snapshot = new ThreadSnapshot(java_thread); | |
341 snapshot->dump_stack_at_safepoint(_max_depth, _with_locked_monitors); | |
342 snapshot->set_concurrent_locks(tcl); | |
343 return snapshot; | |
344 } | |
345 | |
346 volatile bool VM_Exit::_vm_exited = false; | |
347 Thread * VM_Exit::_shutdown_thread = NULL; | |
348 | |
349 int VM_Exit::set_vm_exited() { | |
350 Thread * thr_cur = ThreadLocalStorage::get_thread_slow(); | |
351 | |
352 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint already"); | |
353 | |
354 int num_active = 0; | |
355 | |
356 _shutdown_thread = thr_cur; | |
357 _vm_exited = true; // global flag | |
358 for(JavaThread *thr = Threads::first(); thr != NULL; thr = thr->next()) | |
359 if (thr!=thr_cur && thr->thread_state() == _thread_in_native) { | |
360 ++num_active; | |
361 thr->set_terminated(JavaThread::_vm_exited); // per-thread flag | |
362 } | |
363 | |
364 return num_active; | |
365 } | |
366 | |
367 int VM_Exit::wait_for_threads_in_native_to_block() { | |
368 // VM exits at safepoint. This function must be called at the final safepoint | |
369 // to wait for threads in _thread_in_native state to be quiescent. | |
370 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint already"); | |
371 | |
372 Thread * thr_cur = ThreadLocalStorage::get_thread_slow(); | |
373 Monitor timer(Mutex::leaf, "VM_Exit timer", true); | |
374 | |
375 // Compiler threads need longer wait because they can access VM data directly | |
376 // while in native. If they are active and some structures being used are | |
377 // deleted by the shutdown sequence, they will crash. On the other hand, user | |
378 // threads must go through native=>Java/VM transitions first to access VM | |
379 // data, and they will be stopped during state transition. In theory, we | |
380 // don't have to wait for user threads to be quiescent, but it's always | |
381 // better to terminate VM when current thread is the only active thread, so | |
382 // wait for user threads too. Numbers are in 10 milliseconds. | |
383 int max_wait_user_thread = 30; // at least 300 milliseconds | |
384 int max_wait_compiler_thread = 1000; // at least 10 seconds | |
385 | |
386 int max_wait = max_wait_compiler_thread; | |
387 | |
388 int attempts = 0; | |
389 while (true) { | |
390 int num_active = 0; | |
391 int num_active_compiler_thread = 0; | |
392 | |
393 for(JavaThread *thr = Threads::first(); thr != NULL; thr = thr->next()) { | |
394 if (thr!=thr_cur && thr->thread_state() == _thread_in_native) { | |
395 num_active++; | |
396 if (thr->is_Compiler_thread()) { | |
397 num_active_compiler_thread++; | |
398 } | |
399 } | |
400 } | |
401 | |
402 if (num_active == 0) { | |
403 return 0; | |
404 } else if (attempts > max_wait) { | |
405 return num_active; | |
406 } else if (num_active_compiler_thread == 0 && attempts > max_wait_user_thread) { | |
407 return num_active; | |
408 } | |
409 | |
410 attempts++; | |
411 | |
412 MutexLockerEx ml(&timer, Mutex::_no_safepoint_check_flag); | |
413 timer.wait(Mutex::_no_safepoint_check_flag, 10); | |
414 } | |
415 } | |
416 | |
417 void VM_Exit::doit() { | |
418 CompileBroker::set_should_block(); | |
419 | |
420 // Wait for a short period for threads in native to block. Any thread | |
421 // still executing native code after the wait will be stopped at | |
422 // native==>Java/VM barriers. | |
423 // Among 16276 JCK tests, 94% of them come here without any threads still | |
424 // running in native; the other 6% are quiescent within 250ms (Ultra 80). | |
425 wait_for_threads_in_native_to_block(); | |
426 | |
427 set_vm_exited(); | |
428 | |
429 // cleanup globals resources before exiting. exit_globals() currently | |
430 // cleans up outputStream resources and PerfMemory resources. | |
431 exit_globals(); | |
432 | |
433 // Check for exit hook | |
434 exit_hook_t exit_hook = Arguments::exit_hook(); | |
435 if (exit_hook != NULL) { | |
436 // exit hook should exit. | |
437 exit_hook(_exit_code); | |
438 // ... but if it didn't, we must do it here | |
439 vm_direct_exit(_exit_code); | |
440 } else { | |
441 vm_direct_exit(_exit_code); | |
442 } | |
443 } | |
444 | |
445 | |
446 void VM_Exit::wait_if_vm_exited() { | |
447 if (_vm_exited && | |
448 ThreadLocalStorage::get_thread_slow() != _shutdown_thread) { | |
449 // _vm_exited is set at safepoint, and the Threads_lock is never released | |
450 // we will block here until the process dies | |
451 Threads_lock->lock_without_safepoint_check(); | |
452 ShouldNotReachHere(); | |
453 } | |
454 } |