Mercurial > hg > truffle
annotate src/share/vm/runtime/vm_operations.cpp @ 8804:91bf0bdae37b
8008217: CDS: Class data sharing limits the malloc heap on Solaris
Summary: In 64bit VM move CDS archive address to 32G on all platforms using new flag SharedBaseAddress. In 32bit VM set CDS archive address to 3Gb on Linux and let other OSs pick the address.
Reviewed-by: kvn, dcubed, zgu, hseigel
author | coleenp |
---|---|
date | Wed, 20 Mar 2013 08:04:54 -0400 |
parents | f34d701e952e |
children | 291ffc492eb6 68fe50d4f1d5 |
rev | line source |
---|---|
0 | 1 /* |
2426
1d1603768966
7010070: Update all 2010 Oracle-changed OpenJDK files to have the proper copyright dates - second pass
trims
parents:
2177
diff
changeset
|
2 * Copyright (c) 1997, 2011, 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 | |
1972 | 25 #include "precompiled.hpp" |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
26 #include "classfile/symbolTable.hpp" |
1972 | 27 #include "classfile/vmSymbols.hpp" |
28 #include "compiler/compileBroker.hpp" | |
29 #include "compiler/compilerOracle.hpp" | |
30 #include "gc_implementation/shared/isGCActiveMark.hpp" | |
31 #include "memory/resourceArea.hpp" | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
32 #include "oops/symbol.hpp" |
1972 | 33 #include "runtime/arguments.hpp" |
34 #include "runtime/deoptimization.hpp" | |
35 #include "runtime/interfaceSupport.hpp" | |
36 #include "runtime/sweeper.hpp" | |
7180
f34d701e952e
8003935: Simplify the needed includes for using Thread::current()
stefank
parents:
3960
diff
changeset
|
37 #include "runtime/thread.inline.hpp" |
1972 | 38 #include "runtime/vm_operations.hpp" |
39 #include "services/threadService.hpp" | |
0 | 40 |
41 #define VM_OP_NAME_INITIALIZE(name) #name, | |
42 | |
43 const char* VM_Operation::_names[VM_Operation::VMOp_Terminating] = \ | |
44 { VM_OPS_DO(VM_OP_NAME_INITIALIZE) }; | |
45 | |
46 void VM_Operation::set_calling_thread(Thread* thread, ThreadPriority priority) { | |
47 _calling_thread = thread; | |
48 assert(MinPriority <= priority && priority <= MaxPriority, "sanity check"); | |
49 _priority = priority; | |
50 } | |
51 | |
52 | |
53 void VM_Operation::evaluate() { | |
54 ResourceMark rm; | |
55 if (TraceVMOperation) { | |
56 tty->print("["); | |
57 NOT_PRODUCT(print();) | |
58 } | |
59 doit(); | |
60 if (TraceVMOperation) { | |
61 tty->print_cr("]"); | |
62 } | |
63 } | |
64 | |
65 // Called by fatal error handler. | |
66 void VM_Operation::print_on_error(outputStream* st) const { | |
67 st->print("VM_Operation (" PTR_FORMAT "): ", this); | |
68 st->print("%s", name()); | |
69 | |
70 const char* mode; | |
71 switch(evaluation_mode()) { | |
72 case _safepoint : mode = "safepoint"; break; | |
73 case _no_safepoint : mode = "no safepoint"; break; | |
74 case _concurrent : mode = "concurrent"; break; | |
75 case _async_safepoint: mode = "async safepoint"; break; | |
76 default : mode = "unknown"; break; | |
77 } | |
78 st->print(", mode: %s", mode); | |
79 | |
80 if (calling_thread()) { | |
81 st->print(", requested by thread " PTR_FORMAT, calling_thread()); | |
82 } | |
83 } | |
84 | |
85 void VM_ThreadStop::doit() { | |
86 assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint"); | |
87 JavaThread* target = java_lang_Thread::thread(target_thread()); | |
88 // Note that this now allows multiple ThreadDeath exceptions to be | |
89 // thrown at a thread. | |
90 if (target != NULL) { | |
91 // the thread has run and is not already in the process of exiting | |
92 target->send_thread_stop(throwable()); | |
93 } | |
94 } | |
95 | |
96 void VM_Deoptimize::doit() { | |
97 // We do not want any GCs to happen while we are in the middle of this VM operation | |
98 ResourceMark rm; | |
99 DeoptimizationMarker dm; | |
100 | |
101 // Deoptimize all activations depending on marked nmethods | |
102 Deoptimization::deoptimize_dependents(); | |
103 | |
104 // Make the dependent methods zombies | |
105 CodeCache::make_marked_nmethods_zombies(); | |
106 } | |
107 | |
108 | |
109 VM_DeoptimizeFrame::VM_DeoptimizeFrame(JavaThread* thread, intptr_t* id) { | |
110 _thread = thread; | |
111 _id = id; | |
112 } | |
113 | |
114 | |
115 void VM_DeoptimizeFrame::doit() { | |
1905
ce6848d0666d
6968367: can_post_on_exceptions is still using VM_DeoptimizeFrame in some places
never
parents:
1552
diff
changeset
|
116 Deoptimization::deoptimize_frame_internal(_thread, _id); |
0 | 117 } |
118 | |
119 | |
120 #ifndef PRODUCT | |
121 | |
122 void VM_DeoptimizeAll::doit() { | |
123 DeoptimizationMarker dm; | |
124 // deoptimize all java threads in the system | |
125 if (DeoptimizeALot) { | |
126 for (JavaThread* thread = Threads::first(); thread != NULL; thread = thread->next()) { | |
127 if (thread->has_last_Java_frame()) { | |
128 thread->deoptimize(); | |
129 } | |
130 } | |
131 } else if (DeoptimizeRandom) { | |
132 | |
133 // Deoptimize some selected threads and frames | |
134 int tnum = os::random() & 0x3; | |
135 int fnum = os::random() & 0x3; | |
136 int tcount = 0; | |
137 for (JavaThread* thread = Threads::first(); thread != NULL; thread = thread->next()) { | |
138 if (thread->has_last_Java_frame()) { | |
139 if (tcount++ == tnum) { | |
140 tcount = 0; | |
141 int fcount = 0; | |
142 // Deoptimize some selected frames. | |
143 // Biased llocking wants a updated register map | |
144 for(StackFrameStream fst(thread, UseBiasedLocking); !fst.is_done(); fst.next()) { | |
145 if (fst.current()->can_be_deoptimized()) { | |
146 if (fcount++ == fnum) { | |
147 fcount = 0; | |
148 Deoptimization::deoptimize(thread, *fst.current(), fst.register_map()); | |
149 } | |
150 } | |
151 } | |
152 } | |
153 } | |
154 } | |
155 } | |
156 } | |
157 | |
158 | |
159 void VM_ZombieAll::doit() { | |
160 JavaThread *thread = (JavaThread *)calling_thread(); | |
161 assert(thread->is_Java_thread(), "must be a Java thread"); | |
162 thread->make_zombies(); | |
163 } | |
164 | |
165 #endif // !PRODUCT | |
166 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
167 void VM_UnlinkSymbols::doit() { |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
168 JavaThread *thread = (JavaThread *)calling_thread(); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
169 assert(thread->is_Java_thread(), "must be a Java thread"); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
170 SymbolTable::unlink(); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
171 } |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
172 |
1202 | 173 void VM_HandleFullCodeCache::doit() { |
174 NMethodSweeper::speculative_disconnect_nmethods(_is_full); | |
175 } | |
176 | |
0 | 177 void VM_Verify::doit() { |
178 Universe::verify(); | |
179 } | |
180 | |
181 bool VM_PrintThreads::doit_prologue() { | |
182 assert(Thread::current()->is_Java_thread(), "just checking"); | |
183 | |
184 // Make sure AbstractOwnableSynchronizer is loaded | |
185 if (JDK_Version::is_gte_jdk16x_version()) { | |
186 java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(JavaThread::current()); | |
187 } | |
188 | |
189 // Get Heap_lock if concurrent locks will be dumped | |
190 if (_print_concurrent_locks) { | |
191 Heap_lock->lock(); | |
192 } | |
193 return true; | |
194 } | |
195 | |
196 void VM_PrintThreads::doit() { | |
197 Threads::print_on(_out, true, false, _print_concurrent_locks); | |
198 } | |
199 | |
200 void VM_PrintThreads::doit_epilogue() { | |
201 if (_print_concurrent_locks) { | |
202 // Release Heap_lock | |
203 Heap_lock->unlock(); | |
204 } | |
205 } | |
206 | |
207 void VM_PrintJNI::doit() { | |
208 JNIHandles::print_on(_out); | |
209 } | |
210 | |
211 VM_FindDeadlocks::~VM_FindDeadlocks() { | |
212 if (_deadlocks != NULL) { | |
213 DeadlockCycle* cycle = _deadlocks; | |
214 while (cycle != NULL) { | |
215 DeadlockCycle* d = cycle; | |
216 cycle = cycle->next(); | |
217 delete d; | |
218 } | |
219 } | |
220 } | |
221 | |
222 bool VM_FindDeadlocks::doit_prologue() { | |
223 assert(Thread::current()->is_Java_thread(), "just checking"); | |
224 | |
225 // Load AbstractOwnableSynchronizer class | |
226 if (_concurrent_locks && JDK_Version::is_gte_jdk16x_version()) { | |
227 java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(JavaThread::current()); | |
228 } | |
229 | |
230 return true; | |
231 } | |
232 | |
233 void VM_FindDeadlocks::doit() { | |
234 _deadlocks = ThreadService::find_deadlocks_at_safepoint(_concurrent_locks); | |
235 if (_out != NULL) { | |
236 int num_deadlocks = 0; | |
237 for (DeadlockCycle* cycle = _deadlocks; cycle != NULL; cycle = cycle->next()) { | |
238 num_deadlocks++; | |
239 cycle->print_on(_out); | |
240 } | |
241 | |
242 if (num_deadlocks == 1) { | |
243 _out->print_cr("\nFound 1 deadlock.\n"); | |
244 _out->flush(); | |
245 } else if (num_deadlocks > 1) { | |
246 _out->print_cr("\nFound %d deadlocks.\n", num_deadlocks); | |
247 _out->flush(); | |
248 } | |
249 } | |
250 } | |
251 | |
252 VM_ThreadDump::VM_ThreadDump(ThreadDumpResult* result, | |
253 int max_depth, | |
254 bool with_locked_monitors, | |
255 bool with_locked_synchronizers) { | |
256 _result = result; | |
257 _num_threads = 0; // 0 indicates all threads | |
258 _threads = NULL; | |
259 _result = result; | |
260 _max_depth = max_depth; | |
261 _with_locked_monitors = with_locked_monitors; | |
262 _with_locked_synchronizers = with_locked_synchronizers; | |
263 } | |
264 | |
265 VM_ThreadDump::VM_ThreadDump(ThreadDumpResult* result, | |
266 GrowableArray<instanceHandle>* threads, | |
267 int num_threads, | |
268 int max_depth, | |
269 bool with_locked_monitors, | |
270 bool with_locked_synchronizers) { | |
271 _result = result; | |
272 _num_threads = num_threads; | |
273 _threads = threads; | |
274 _result = result; | |
275 _max_depth = max_depth; | |
276 _with_locked_monitors = with_locked_monitors; | |
277 _with_locked_synchronizers = with_locked_synchronizers; | |
278 } | |
279 | |
280 bool VM_ThreadDump::doit_prologue() { | |
281 assert(Thread::current()->is_Java_thread(), "just checking"); | |
282 | |
283 // Load AbstractOwnableSynchronizer class before taking thread snapshots | |
284 if (JDK_Version::is_gte_jdk16x_version()) { | |
285 java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(JavaThread::current()); | |
286 } | |
287 | |
288 if (_with_locked_synchronizers) { | |
289 // Acquire Heap_lock to dump concurrent locks | |
290 Heap_lock->lock(); | |
291 } | |
292 | |
293 return true; | |
294 } | |
295 | |
296 void VM_ThreadDump::doit_epilogue() { | |
297 if (_with_locked_synchronizers) { | |
298 // Release Heap_lock | |
299 Heap_lock->unlock(); | |
300 } | |
301 } | |
302 | |
303 void VM_ThreadDump::doit() { | |
304 ResourceMark rm; | |
305 | |
306 ConcurrentLocksDump concurrent_locks(true); | |
307 if (_with_locked_synchronizers) { | |
308 concurrent_locks.dump_at_safepoint(); | |
309 } | |
310 | |
311 if (_num_threads == 0) { | |
312 // Snapshot all live threads | |
313 for (JavaThread* jt = Threads::first(); jt != NULL; jt = jt->next()) { | |
314 if (jt->is_exiting() || | |
315 jt->is_hidden_from_external_view()) { | |
316 // skip terminating threads and hidden threads | |
317 continue; | |
318 } | |
319 ThreadConcurrentLocks* tcl = NULL; | |
320 if (_with_locked_synchronizers) { | |
321 tcl = concurrent_locks.thread_concurrent_locks(jt); | |
322 } | |
323 ThreadSnapshot* ts = snapshot_thread(jt, tcl); | |
324 _result->add_thread_snapshot(ts); | |
325 } | |
326 } else { | |
327 // Snapshot threads in the given _threads array | |
328 // A dummy snapshot is created if a thread doesn't exist | |
329 for (int i = 0; i < _num_threads; i++) { | |
330 instanceHandle th = _threads->at(i); | |
331 if (th() == NULL) { | |
332 // skip if the thread doesn't exist | |
333 // Add a dummy snapshot | |
334 _result->add_thread_snapshot(new ThreadSnapshot()); | |
335 continue; | |
336 } | |
337 | |
338 // Dump thread stack only if the thread is alive and not exiting | |
339 // and not VM internal thread. | |
340 JavaThread* jt = java_lang_Thread::thread(th()); | |
341 if (jt == NULL || /* thread not alive */ | |
342 jt->is_exiting() || | |
343 jt->is_hidden_from_external_view()) { | |
344 // add a NULL snapshot if skipped | |
345 _result->add_thread_snapshot(new ThreadSnapshot()); | |
346 continue; | |
347 } | |
348 ThreadConcurrentLocks* tcl = NULL; | |
349 if (_with_locked_synchronizers) { | |
350 tcl = concurrent_locks.thread_concurrent_locks(jt); | |
351 } | |
352 ThreadSnapshot* ts = snapshot_thread(jt, tcl); | |
353 _result->add_thread_snapshot(ts); | |
354 } | |
355 } | |
356 } | |
357 | |
358 ThreadSnapshot* VM_ThreadDump::snapshot_thread(JavaThread* java_thread, ThreadConcurrentLocks* tcl) { | |
359 ThreadSnapshot* snapshot = new ThreadSnapshot(java_thread); | |
360 snapshot->dump_stack_at_safepoint(_max_depth, _with_locked_monitors); | |
361 snapshot->set_concurrent_locks(tcl); | |
362 return snapshot; | |
363 } | |
364 | |
365 volatile bool VM_Exit::_vm_exited = false; | |
366 Thread * VM_Exit::_shutdown_thread = NULL; | |
367 | |
368 int VM_Exit::set_vm_exited() { | |
369 Thread * thr_cur = ThreadLocalStorage::get_thread_slow(); | |
370 | |
371 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint already"); | |
372 | |
373 int num_active = 0; | |
374 | |
375 _shutdown_thread = thr_cur; | |
376 _vm_exited = true; // global flag | |
377 for(JavaThread *thr = Threads::first(); thr != NULL; thr = thr->next()) | |
378 if (thr!=thr_cur && thr->thread_state() == _thread_in_native) { | |
379 ++num_active; | |
380 thr->set_terminated(JavaThread::_vm_exited); // per-thread flag | |
381 } | |
382 | |
383 return num_active; | |
384 } | |
385 | |
386 int VM_Exit::wait_for_threads_in_native_to_block() { | |
387 // VM exits at safepoint. This function must be called at the final safepoint | |
388 // to wait for threads in _thread_in_native state to be quiescent. | |
389 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint already"); | |
390 | |
391 Thread * thr_cur = ThreadLocalStorage::get_thread_slow(); | |
392 Monitor timer(Mutex::leaf, "VM_Exit timer", true); | |
393 | |
394 // Compiler threads need longer wait because they can access VM data directly | |
395 // while in native. If they are active and some structures being used are | |
396 // deleted by the shutdown sequence, they will crash. On the other hand, user | |
397 // threads must go through native=>Java/VM transitions first to access VM | |
398 // data, and they will be stopped during state transition. In theory, we | |
399 // don't have to wait for user threads to be quiescent, but it's always | |
400 // better to terminate VM when current thread is the only active thread, so | |
401 // wait for user threads too. Numbers are in 10 milliseconds. | |
402 int max_wait_user_thread = 30; // at least 300 milliseconds | |
403 int max_wait_compiler_thread = 1000; // at least 10 seconds | |
404 | |
405 int max_wait = max_wait_compiler_thread; | |
406 | |
407 int attempts = 0; | |
408 while (true) { | |
409 int num_active = 0; | |
410 int num_active_compiler_thread = 0; | |
411 | |
412 for(JavaThread *thr = Threads::first(); thr != NULL; thr = thr->next()) { | |
413 if (thr!=thr_cur && thr->thread_state() == _thread_in_native) { | |
414 num_active++; | |
415 if (thr->is_Compiler_thread()) { | |
416 num_active_compiler_thread++; | |
417 } | |
418 } | |
419 } | |
420 | |
421 if (num_active == 0) { | |
422 return 0; | |
423 } else if (attempts > max_wait) { | |
424 return num_active; | |
425 } else if (num_active_compiler_thread == 0 && attempts > max_wait_user_thread) { | |
426 return num_active; | |
427 } | |
428 | |
429 attempts++; | |
430 | |
431 MutexLockerEx ml(&timer, Mutex::_no_safepoint_check_flag); | |
432 timer.wait(Mutex::_no_safepoint_check_flag, 10); | |
433 } | |
434 } | |
435 | |
436 void VM_Exit::doit() { | |
437 CompileBroker::set_should_block(); | |
438 | |
439 // Wait for a short period for threads in native to block. Any thread | |
440 // still executing native code after the wait will be stopped at | |
441 // native==>Java/VM barriers. | |
442 // Among 16276 JCK tests, 94% of them come here without any threads still | |
443 // running in native; the other 6% are quiescent within 250ms (Ultra 80). | |
444 wait_for_threads_in_native_to_block(); | |
445 | |
446 set_vm_exited(); | |
447 | |
448 // cleanup globals resources before exiting. exit_globals() currently | |
449 // cleans up outputStream resources and PerfMemory resources. | |
450 exit_globals(); | |
451 | |
452 // Check for exit hook | |
453 exit_hook_t exit_hook = Arguments::exit_hook(); | |
454 if (exit_hook != NULL) { | |
455 // exit hook should exit. | |
456 exit_hook(_exit_code); | |
457 // ... but if it didn't, we must do it here | |
458 vm_direct_exit(_exit_code); | |
459 } else { | |
460 vm_direct_exit(_exit_code); | |
461 } | |
462 } | |
463 | |
464 | |
465 void VM_Exit::wait_if_vm_exited() { | |
466 if (_vm_exited && | |
467 ThreadLocalStorage::get_thread_slow() != _shutdown_thread) { | |
468 // _vm_exited is set at safepoint, and the Threads_lock is never released | |
469 // we will block here until the process dies | |
470 Threads_lock->lock_without_safepoint_check(); | |
471 ShouldNotReachHere(); | |
472 } | |
473 } |