Mercurial > hg > truffle
annotate src/share/vm/runtime/java.cpp @ 3917:eca1193ca245
4965777: GC changes to support use of discovered field for pending references
Summary: If and when the reference handler thread is able to use the discovered field to link reference objects in its pending list, so will GC. In that case, GC will scan through this field once a reference object has been placed on the pending list, but not scan that field before that stage, as the field is used by the concurrent GC thread to link discovered objects. When ReferenceHandleR thread does not use the discovered field for the purpose of linking the elements in the pending list, as would be the case in older JDKs, the JVM will fall back to the old behaviour of using the next field for that purpose.
Reviewed-by: jcoomes, mchung, stefank
author | ysr |
---|---|
date | Wed, 07 Sep 2011 13:55:42 -0700 |
parents | 0f34fdee809e |
children | f08d439fab8c |
rev | line source |
---|---|
0 | 1 /* |
2129
8f8dfba37802
6994753: Implement optional hook to a Java method at VM startup.
kevinw
parents:
2096
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:
1547
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1547
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:
1547
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "classfile/classLoader.hpp" | |
27 #include "classfile/symbolTable.hpp" | |
28 #include "classfile/systemDictionary.hpp" | |
29 #include "code/codeCache.hpp" | |
30 #include "compiler/compileBroker.hpp" | |
31 #include "compiler/compilerOracle.hpp" | |
32 #include "interpreter/bytecodeHistogram.hpp" | |
33 #include "memory/genCollectedHeap.hpp" | |
34 #include "memory/oopFactory.hpp" | |
35 #include "memory/universe.hpp" | |
36 #include "oops/constantPoolOop.hpp" | |
37 #include "oops/generateOopMap.hpp" | |
38 #include "oops/instanceKlass.hpp" | |
39 #include "oops/instanceKlassKlass.hpp" | |
40 #include "oops/instanceOop.hpp" | |
41 #include "oops/methodOop.hpp" | |
42 #include "oops/objArrayOop.hpp" | |
43 #include "oops/oop.inline.hpp" | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2129
diff
changeset
|
44 #include "oops/symbol.hpp" |
1972 | 45 #include "prims/jvmtiExport.hpp" |
46 #include "runtime/aprofiler.hpp" | |
47 #include "runtime/arguments.hpp" | |
48 #include "runtime/biasedLocking.hpp" | |
49 #include "runtime/compilationPolicy.hpp" | |
50 #include "runtime/fprofiler.hpp" | |
51 #include "runtime/init.hpp" | |
52 #include "runtime/interfaceSupport.hpp" | |
53 #include "runtime/java.hpp" | |
54 #include "runtime/memprofiler.hpp" | |
55 #include "runtime/sharedRuntime.hpp" | |
56 #include "runtime/statSampler.hpp" | |
57 #include "runtime/task.hpp" | |
58 #include "runtime/timer.hpp" | |
59 #include "runtime/vm_operations.hpp" | |
60 #include "utilities/dtrace.hpp" | |
61 #include "utilities/globalDefinitions.hpp" | |
62 #include "utilities/histogram.hpp" | |
63 #include "utilities/vmError.hpp" | |
64 #ifdef TARGET_ARCH_x86 | |
65 # include "vm_version_x86.hpp" | |
66 #endif | |
67 #ifdef TARGET_ARCH_sparc | |
68 # include "vm_version_sparc.hpp" | |
69 #endif | |
70 #ifdef TARGET_ARCH_zero | |
71 # include "vm_version_zero.hpp" | |
72 #endif | |
2192
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2177
diff
changeset
|
73 #ifdef TARGET_ARCH_arm |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2177
diff
changeset
|
74 # include "vm_version_arm.hpp" |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2177
diff
changeset
|
75 #endif |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2177
diff
changeset
|
76 #ifdef TARGET_ARCH_ppc |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2177
diff
changeset
|
77 # include "vm_version_ppc.hpp" |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2177
diff
changeset
|
78 #endif |
1972 | 79 #ifdef TARGET_OS_FAMILY_linux |
80 # include "thread_linux.inline.hpp" | |
81 #endif | |
82 #ifdef TARGET_OS_FAMILY_solaris | |
83 # include "thread_solaris.inline.hpp" | |
84 #endif | |
85 #ifdef TARGET_OS_FAMILY_windows | |
86 # include "thread_windows.inline.hpp" | |
87 #endif | |
88 #ifndef SERIALGC | |
89 #include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp" | |
90 #include "gc_implementation/parallelScavenge/psScavenge.hpp" | |
91 #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp" | |
92 #endif | |
93 #ifdef COMPILER1 | |
94 #include "c1/c1_Compiler.hpp" | |
95 #include "c1/c1_Runtime1.hpp" | |
96 #endif | |
97 #ifdef COMPILER2 | |
98 #include "code/compiledIC.hpp" | |
99 #include "compiler/methodLiveness.hpp" | |
100 #include "opto/compile.hpp" | |
101 #include "opto/indexSet.hpp" | |
102 #include "opto/runtime.hpp" | |
103 #endif | |
0 | 104 |
105 HS_DTRACE_PROBE_DECL(hotspot, vm__shutdown); | |
106 | |
107 #ifndef PRODUCT | |
108 | |
109 // Statistics printing (method invocation histogram) | |
110 | |
111 GrowableArray<methodOop>* collected_invoked_methods; | |
112 | |
113 void collect_invoked_methods(methodOop m) { | |
114 if (m->invocation_count() + m->compiled_invocation_count() >= 1 ) { | |
115 collected_invoked_methods->push(m); | |
116 } | |
117 } | |
118 | |
119 | |
120 GrowableArray<methodOop>* collected_profiled_methods; | |
121 | |
122 void collect_profiled_methods(methodOop m) { | |
123 methodHandle mh(Thread::current(), m); | |
124 if ((m->method_data() != NULL) && | |
125 (PrintMethodData || CompilerOracle::should_print(mh))) { | |
126 collected_profiled_methods->push(m); | |
127 } | |
128 } | |
129 | |
130 | |
131 int compare_methods(methodOop* a, methodOop* b) { | |
132 // %%% there can be 32-bit overflow here | |
133 return ((*b)->invocation_count() + (*b)->compiled_invocation_count()) | |
134 - ((*a)->invocation_count() + (*a)->compiled_invocation_count()); | |
135 } | |
136 | |
137 | |
138 void print_method_invocation_histogram() { | |
139 ResourceMark rm; | |
140 HandleMark hm; | |
141 collected_invoked_methods = new GrowableArray<methodOop>(1024); | |
142 SystemDictionary::methods_do(collect_invoked_methods); | |
143 collected_invoked_methods->sort(&compare_methods); | |
144 // | |
145 tty->cr(); | |
146 tty->print_cr("Histogram Over MethodOop Invocation Counters (cutoff = %d):", MethodHistogramCutoff); | |
147 tty->cr(); | |
148 tty->print_cr("____Count_(I+C)____Method________________________Module_________________"); | |
149 unsigned total = 0, int_total = 0, comp_total = 0, static_total = 0, final_total = 0, | |
150 synch_total = 0, nativ_total = 0, acces_total = 0; | |
151 for (int index = 0; index < collected_invoked_methods->length(); index++) { | |
152 methodOop m = collected_invoked_methods->at(index); | |
153 int c = m->invocation_count() + m->compiled_invocation_count(); | |
154 if (c >= MethodHistogramCutoff) m->print_invocation_count(); | |
155 int_total += m->invocation_count(); | |
156 comp_total += m->compiled_invocation_count(); | |
157 if (m->is_final()) final_total += c; | |
158 if (m->is_static()) static_total += c; | |
159 if (m->is_synchronized()) synch_total += c; | |
160 if (m->is_native()) nativ_total += c; | |
161 if (m->is_accessor()) acces_total += c; | |
162 } | |
163 tty->cr(); | |
164 total = int_total + comp_total; | |
165 tty->print_cr("Invocations summary:"); | |
166 tty->print_cr("\t%9d (%4.1f%%) interpreted", int_total, 100.0 * int_total / total); | |
167 tty->print_cr("\t%9d (%4.1f%%) compiled", comp_total, 100.0 * comp_total / total); | |
168 tty->print_cr("\t%9d (100%%) total", total); | |
169 tty->print_cr("\t%9d (%4.1f%%) synchronized", synch_total, 100.0 * synch_total / total); | |
170 tty->print_cr("\t%9d (%4.1f%%) final", final_total, 100.0 * final_total / total); | |
171 tty->print_cr("\t%9d (%4.1f%%) static", static_total, 100.0 * static_total / total); | |
172 tty->print_cr("\t%9d (%4.1f%%) native", nativ_total, 100.0 * nativ_total / total); | |
173 tty->print_cr("\t%9d (%4.1f%%) accessor", acces_total, 100.0 * acces_total / total); | |
174 tty->cr(); | |
175 SharedRuntime::print_call_statistics(comp_total); | |
176 } | |
177 | |
178 void print_method_profiling_data() { | |
179 ResourceMark rm; | |
180 HandleMark hm; | |
181 collected_profiled_methods = new GrowableArray<methodOop>(1024); | |
182 SystemDictionary::methods_do(collect_profiled_methods); | |
183 collected_profiled_methods->sort(&compare_methods); | |
184 | |
185 int count = collected_profiled_methods->length(); | |
186 if (count > 0) { | |
187 for (int index = 0; index < count; index++) { | |
188 methodOop m = collected_profiled_methods->at(index); | |
189 ttyLocker ttyl; | |
190 tty->print_cr("------------------------------------------------------------------------"); | |
191 //m->print_name(tty); | |
192 m->print_invocation_count(); | |
193 tty->cr(); | |
194 m->print_codes(); | |
195 } | |
196 tty->print_cr("------------------------------------------------------------------------"); | |
197 } | |
198 } | |
199 | |
200 void print_bytecode_count() { | |
201 if (CountBytecodes || TraceBytecodes || StopInterpreterAt) { | |
202 tty->print_cr("[BytecodeCounter::counter_value = %d]", BytecodeCounter::counter_value()); | |
203 } | |
204 } | |
205 | |
206 AllocStats alloc_stats; | |
207 | |
208 | |
209 | |
210 // General statistics printing (profiling ...) | |
211 | |
212 void print_statistics() { | |
213 | |
214 #ifdef ASSERT | |
215 | |
216 if (CountRuntimeCalls) { | |
217 extern Histogram *RuntimeHistogram; | |
218 RuntimeHistogram->print(); | |
219 } | |
220 | |
221 if (CountJNICalls) { | |
222 extern Histogram *JNIHistogram; | |
223 JNIHistogram->print(); | |
224 } | |
225 | |
226 if (CountJVMCalls) { | |
227 extern Histogram *JVMHistogram; | |
228 JVMHistogram->print(); | |
229 } | |
230 | |
231 #endif | |
232 | |
233 if (MemProfiling) { | |
234 MemProfiler::disengage(); | |
235 } | |
236 | |
237 if (CITime) { | |
238 CompileBroker::print_times(); | |
239 } | |
240 | |
241 #ifdef COMPILER1 | |
242 if ((PrintC1Statistics || LogVMOutput || LogCompilation) && UseCompiler) { | |
243 FlagSetting fs(DisplayVMOutput, DisplayVMOutput && PrintC1Statistics); | |
244 Runtime1::print_statistics(); | |
245 Deoptimization::print_statistics(); | |
3841
0f34fdee809e
7071427: AdapterFingerPrint can hold 8 entries per int
never
parents:
3769
diff
changeset
|
246 SharedRuntime::print_statistics(); |
0 | 247 nmethod::print_statistics(); |
248 } | |
249 #endif /* COMPILER1 */ | |
250 | |
251 #ifdef COMPILER2 | |
252 if ((PrintOptoStatistics || LogVMOutput || LogCompilation) && UseCompiler) { | |
253 FlagSetting fs(DisplayVMOutput, DisplayVMOutput && PrintOptoStatistics); | |
254 Compile::print_statistics(); | |
255 #ifndef COMPILER1 | |
256 Deoptimization::print_statistics(); | |
257 nmethod::print_statistics(); | |
3841
0f34fdee809e
7071427: AdapterFingerPrint can hold 8 entries per int
never
parents:
3769
diff
changeset
|
258 SharedRuntime::print_statistics(); |
0 | 259 #endif //COMPILER1 |
260 os::print_statistics(); | |
261 } | |
262 | |
263 if (PrintLockStatistics || PrintPreciseBiasedLockingStatistics) { | |
264 OptoRuntime::print_named_counters(); | |
265 } | |
266 | |
267 if (TimeLivenessAnalysis) { | |
268 MethodLiveness::print_times(); | |
269 } | |
270 #ifdef ASSERT | |
271 if (CollectIndexSetStatistics) { | |
272 IndexSet::print_statistics(); | |
273 } | |
274 #endif // ASSERT | |
275 #endif // COMPILER2 | |
276 if (CountCompiledCalls) { | |
277 print_method_invocation_histogram(); | |
278 } | |
1918 | 279 if (ProfileInterpreter COMPILER1_PRESENT(|| C1UpdateMethodData)) { |
0 | 280 print_method_profiling_data(); |
281 } | |
282 if (TimeCompiler) { | |
283 COMPILER2_PRESENT(Compile::print_timers();) | |
284 } | |
285 if (TimeCompilationPolicy) { | |
286 CompilationPolicy::policy()->print_time(); | |
287 } | |
288 if (TimeOopMap) { | |
289 GenerateOopMap::print_time(); | |
290 } | |
291 if (ProfilerCheckIntervals) { | |
292 PeriodicTask::print_intervals(); | |
293 } | |
294 if (PrintSymbolTableSizeHistogram) { | |
295 SymbolTable::print_histogram(); | |
296 } | |
297 if (CountBytecodes || TraceBytecodes || StopInterpreterAt) { | |
298 BytecodeCounter::print(); | |
299 } | |
300 if (PrintBytecodePairHistogram) { | |
301 BytecodePairHistogram::print(); | |
302 } | |
303 | |
304 if (PrintCodeCache) { | |
305 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); | |
306 CodeCache::print(); | |
307 } | |
308 | |
309 if (PrintCodeCache2) { | |
310 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); | |
311 CodeCache::print_internals(); | |
312 } | |
313 | |
314 if (PrintClassStatistics) { | |
315 SystemDictionary::print_class_statistics(); | |
316 } | |
317 if (PrintMethodStatistics) { | |
318 SystemDictionary::print_method_statistics(); | |
319 } | |
320 | |
321 if (PrintVtableStats) { | |
322 klassVtable::print_statistics(); | |
323 klassItable::print_statistics(); | |
324 } | |
325 if (VerifyOops) { | |
326 tty->print_cr("+VerifyOops count: %d", StubRoutines::verify_oop_count()); | |
327 } | |
328 | |
329 print_bytecode_count(); | |
2250 | 330 if (PrintMallocStatistics) { |
0 | 331 tty->print("allocation stats: "); |
332 alloc_stats.print(); | |
333 tty->cr(); | |
334 } | |
335 | |
336 if (PrintSystemDictionaryAtExit) { | |
337 SystemDictionary::print(); | |
338 } | |
339 | |
340 if (PrintBiasedLockingStatistics) { | |
341 BiasedLocking::print_counters(); | |
342 } | |
343 | |
344 #ifdef ENABLE_ZAP_DEAD_LOCALS | |
345 #ifdef COMPILER2 | |
346 if (ZapDeadCompiledLocals) { | |
347 tty->print_cr("Compile::CompiledZap_count = %d", Compile::CompiledZap_count); | |
348 tty->print_cr("OptoRuntime::ZapDeadCompiledLocals_count = %d", OptoRuntime::ZapDeadCompiledLocals_count); | |
349 } | |
350 #endif // COMPILER2 | |
351 #endif // ENABLE_ZAP_DEAD_LOCALS | |
352 } | |
353 | |
354 #else // PRODUCT MODE STATISTICS | |
355 | |
356 void print_statistics() { | |
357 | |
358 if (CITime) { | |
359 CompileBroker::print_times(); | |
360 } | |
361 #ifdef COMPILER2 | |
362 if (PrintPreciseBiasedLockingStatistics) { | |
363 OptoRuntime::print_named_counters(); | |
364 } | |
365 #endif | |
366 if (PrintBiasedLockingStatistics) { | |
367 BiasedLocking::print_counters(); | |
368 } | |
369 } | |
370 | |
371 #endif | |
372 | |
373 | |
374 // Helper class for registering on_exit calls through JVM_OnExit | |
375 | |
376 extern "C" { | |
377 typedef void (*__exit_proc)(void); | |
378 } | |
379 | |
380 class ExitProc : public CHeapObj { | |
381 private: | |
382 __exit_proc _proc; | |
383 // void (*_proc)(void); | |
384 ExitProc* _next; | |
385 public: | |
386 // ExitProc(void (*proc)(void)) { | |
387 ExitProc(__exit_proc proc) { | |
388 _proc = proc; | |
389 _next = NULL; | |
390 } | |
391 void evaluate() { _proc(); } | |
392 ExitProc* next() const { return _next; } | |
393 void set_next(ExitProc* next) { _next = next; } | |
394 }; | |
395 | |
396 | |
397 // Linked list of registered on_exit procedures | |
398 | |
399 static ExitProc* exit_procs = NULL; | |
400 | |
401 | |
402 extern "C" { | |
403 void register_on_exit_function(void (*func)(void)) { | |
404 ExitProc *entry = new ExitProc(func); | |
405 // Classic vm does not throw an exception in case the allocation failed, | |
406 if (entry != NULL) { | |
407 entry->set_next(exit_procs); | |
408 exit_procs = entry; | |
409 } | |
410 } | |
411 } | |
412 | |
413 // Note: before_exit() can be executed only once, if more than one threads | |
414 // are trying to shutdown the VM at the same time, only one thread | |
415 // can run before_exit() and all other threads must wait. | |
416 void before_exit(JavaThread * thread) { | |
417 #define BEFORE_EXIT_NOT_RUN 0 | |
418 #define BEFORE_EXIT_RUNNING 1 | |
419 #define BEFORE_EXIT_DONE 2 | |
420 static jint volatile _before_exit_status = BEFORE_EXIT_NOT_RUN; | |
421 | |
422 // Note: don't use a Mutex to guard the entire before_exit(), as | |
423 // JVMTI post_thread_end_event and post_vm_death_event will run native code. | |
424 // A CAS or OSMutex would work just fine but then we need to manipulate | |
425 // thread state for Safepoint. Here we use Monitor wait() and notify_all() | |
426 // for synchronization. | |
427 { MutexLocker ml(BeforeExit_lock); | |
428 switch (_before_exit_status) { | |
429 case BEFORE_EXIT_NOT_RUN: | |
430 _before_exit_status = BEFORE_EXIT_RUNNING; | |
431 break; | |
432 case BEFORE_EXIT_RUNNING: | |
433 while (_before_exit_status == BEFORE_EXIT_RUNNING) { | |
434 BeforeExit_lock->wait(); | |
435 } | |
436 assert(_before_exit_status == BEFORE_EXIT_DONE, "invalid state"); | |
437 return; | |
438 case BEFORE_EXIT_DONE: | |
439 return; | |
440 } | |
441 } | |
442 | |
443 // The only difference between this and Win32's _onexit procs is that | |
444 // this version is invoked before any threads get killed. | |
445 ExitProc* current = exit_procs; | |
446 while (current != NULL) { | |
447 ExitProc* next = current->next(); | |
448 current->evaluate(); | |
449 delete current; | |
450 current = next; | |
451 } | |
452 | |
453 // Hang forever on exit if we're reporting an error. | |
454 if (ShowMessageBoxOnError && is_error_reported()) { | |
455 os::infinite_sleep(); | |
456 } | |
457 | |
458 // Terminate watcher thread - must before disenrolling any periodic task | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
459 if (PeriodicTask::num_tasks() > 0) |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
460 WatcherThread::stop(); |
0 | 461 |
462 // Print statistics gathered (profiling ...) | |
463 if (Arguments::has_profile()) { | |
464 FlatProfiler::disengage(); | |
465 FlatProfiler::print(10); | |
466 } | |
467 | |
468 // shut down the StatSampler task | |
469 StatSampler::disengage(); | |
470 StatSampler::destroy(); | |
471 | |
3769
ef2d1b8f2dd4
7051430: CMS: ongoing CMS cycle should terminate abruptly to allow prompt JVM termination at exit
ysr
parents:
2304
diff
changeset
|
472 // We do not need to explicitly stop concurrent GC threads because the |
ef2d1b8f2dd4
7051430: CMS: ongoing CMS cycle should terminate abruptly to allow prompt JVM termination at exit
ysr
parents:
2304
diff
changeset
|
473 // JVM will be taken down at a safepoint when such threads are inactive -- |
ef2d1b8f2dd4
7051430: CMS: ongoing CMS cycle should terminate abruptly to allow prompt JVM termination at exit
ysr
parents:
2304
diff
changeset
|
474 // except for some concurrent G1 threads, see (comment in) |
ef2d1b8f2dd4
7051430: CMS: ongoing CMS cycle should terminate abruptly to allow prompt JVM termination at exit
ysr
parents:
2304
diff
changeset
|
475 // Threads::destroy_vm(). |
0 | 476 |
477 // Print GC/heap related information. | |
478 if (PrintGCDetails) { | |
479 Universe::print(); | |
480 AdaptiveSizePolicyOutput(0); | |
481 } | |
482 | |
483 | |
484 if (Arguments::has_alloc_profile()) { | |
485 HandleMark hm; | |
486 // Do one last collection to enumerate all the objects | |
487 // allocated since the last one. | |
488 Universe::heap()->collect(GCCause::_allocation_profiler); | |
489 AllocationProfiler::disengage(); | |
490 AllocationProfiler::print(0); | |
491 } | |
492 | |
493 if (PrintBytecodeHistogram) { | |
494 BytecodeHistogram::print(); | |
495 } | |
496 | |
497 if (JvmtiExport::should_post_thread_life()) { | |
498 JvmtiExport::post_thread_end(thread); | |
499 } | |
500 // Always call even when there are not JVMTI environments yet, since environments | |
501 // may be attached late and JVMTI must track phases of VM execution | |
502 JvmtiExport::post_vm_death(); | |
503 Threads::shutdown_vm_agents(); | |
504 | |
505 // Terminate the signal thread | |
506 // Note: we don't wait until it actually dies. | |
507 os::terminate_signal_thread(); | |
508 | |
509 print_statistics(); | |
510 Universe::heap()->print_tracing_info(); | |
511 | |
512 { MutexLocker ml(BeforeExit_lock); | |
513 _before_exit_status = BEFORE_EXIT_DONE; | |
514 BeforeExit_lock->notify_all(); | |
515 } | |
516 | |
517 #undef BEFORE_EXIT_NOT_RUN | |
518 #undef BEFORE_EXIT_RUNNING | |
519 #undef BEFORE_EXIT_DONE | |
520 } | |
521 | |
522 void vm_exit(int code) { | |
2096
0eb90baf1b69
6583275: Hotspot crash in vm_perform_shutdown_actions due to uninitialized TLS during out of memory handling
coleenp
parents:
1972
diff
changeset
|
523 Thread* thread = ThreadLocalStorage::is_initialized() ? |
0eb90baf1b69
6583275: Hotspot crash in vm_perform_shutdown_actions due to uninitialized TLS during out of memory handling
coleenp
parents:
1972
diff
changeset
|
524 ThreadLocalStorage::get_thread_slow() : NULL; |
0 | 525 if (thread == NULL) { |
526 // we have serious problems -- just exit | |
527 vm_direct_exit(code); | |
528 } | |
529 | |
530 if (VMThread::vm_thread() != NULL) { | |
531 // Fire off a VM_Exit operation to bring VM to a safepoint and exit | |
532 VM_Exit op(code); | |
533 if (thread->is_Java_thread()) | |
534 ((JavaThread*)thread)->set_thread_state(_thread_in_vm); | |
535 VMThread::execute(&op); | |
536 // should never reach here; but in case something wrong with VM Thread. | |
537 vm_direct_exit(code); | |
538 } else { | |
539 // VM thread is gone, just exit | |
540 vm_direct_exit(code); | |
541 } | |
542 ShouldNotReachHere(); | |
543 } | |
544 | |
545 void notify_vm_shutdown() { | |
546 // For now, just a dtrace probe. | |
547 HS_DTRACE_PROBE(hotspot, vm__shutdown); | |
1547
fb1a39993f69
6951319: enable solaris builds using Sun Studio 12 update 1
jcoomes
parents:
242
diff
changeset
|
548 HS_DTRACE_WORKAROUND_TAIL_CALL_BUG(); |
0 | 549 } |
550 | |
551 void vm_direct_exit(int code) { | |
552 notify_vm_shutdown(); | |
2302
da091bb67459
7022037: Pause when exiting if debugger is attached on windows
sla
parents:
2192
diff
changeset
|
553 os::wait_for_keypress_at_exit(); |
0 | 554 ::exit(code); |
555 } | |
556 | |
557 void vm_perform_shutdown_actions() { | |
558 // Warning: do not call 'exit_globals()' here. All threads are still running. | |
559 // Calling 'exit_globals()' will disable thread-local-storage and cause all | |
560 // kinds of assertions to trigger in debug mode. | |
561 if (is_init_completed()) { | |
2096
0eb90baf1b69
6583275: Hotspot crash in vm_perform_shutdown_actions due to uninitialized TLS during out of memory handling
coleenp
parents:
1972
diff
changeset
|
562 Thread* thread = ThreadLocalStorage::is_initialized() ? |
0eb90baf1b69
6583275: Hotspot crash in vm_perform_shutdown_actions due to uninitialized TLS during out of memory handling
coleenp
parents:
1972
diff
changeset
|
563 ThreadLocalStorage::get_thread_slow() : NULL; |
0eb90baf1b69
6583275: Hotspot crash in vm_perform_shutdown_actions due to uninitialized TLS during out of memory handling
coleenp
parents:
1972
diff
changeset
|
564 if (thread != NULL && thread->is_Java_thread()) { |
0 | 565 // We are leaving the VM, set state to native (in case any OS exit |
566 // handlers call back to the VM) | |
567 JavaThread* jt = (JavaThread*)thread; | |
568 // Must always be walkable or have no last_Java_frame when in | |
569 // thread_in_native | |
570 jt->frame_anchor()->make_walkable(jt); | |
571 jt->set_thread_state(_thread_in_native); | |
572 } | |
573 } | |
574 notify_vm_shutdown(); | |
575 } | |
576 | |
577 void vm_shutdown() | |
578 { | |
579 vm_perform_shutdown_actions(); | |
2302
da091bb67459
7022037: Pause when exiting if debugger is attached on windows
sla
parents:
2192
diff
changeset
|
580 os::wait_for_keypress_at_exit(); |
0 | 581 os::shutdown(); |
582 } | |
583 | |
227
8d852b81e775
6694099: Hotspot vm_exit_out_of_memory should dump core
poonam
parents:
61
diff
changeset
|
584 void vm_abort(bool dump_core) { |
0 | 585 vm_perform_shutdown_actions(); |
2302
da091bb67459
7022037: Pause when exiting if debugger is attached on windows
sla
parents:
2192
diff
changeset
|
586 os::wait_for_keypress_at_exit(); |
227
8d852b81e775
6694099: Hotspot vm_exit_out_of_memory should dump core
poonam
parents:
61
diff
changeset
|
587 os::abort(dump_core); |
0 | 588 ShouldNotReachHere(); |
589 } | |
590 | |
591 void vm_notify_during_shutdown(const char* error, const char* message) { | |
592 if (error != NULL) { | |
593 tty->print_cr("Error occurred during initialization of VM"); | |
594 tty->print("%s", error); | |
595 if (message != NULL) { | |
596 tty->print_cr(": %s", message); | |
597 } | |
598 else { | |
599 tty->cr(); | |
600 } | |
601 } | |
602 if (ShowMessageBoxOnError && WizardMode) { | |
603 fatal("Error occurred during initialization of VM"); | |
604 } | |
605 } | |
606 | |
607 void vm_exit_during_initialization(Handle exception) { | |
608 tty->print_cr("Error occurred during initialization of VM"); | |
609 // If there are exceptions on this thread it must be cleared | |
610 // first and here. Any future calls to EXCEPTION_MARK requires | |
611 // that no pending exceptions exist. | |
612 Thread *THREAD = Thread::current(); | |
613 if (HAS_PENDING_EXCEPTION) { | |
614 CLEAR_PENDING_EXCEPTION; | |
615 } | |
616 java_lang_Throwable::print(exception, tty); | |
617 tty->cr(); | |
618 java_lang_Throwable::print_stack_trace(exception(), tty); | |
619 tty->cr(); | |
620 vm_notify_during_shutdown(NULL, NULL); | |
227
8d852b81e775
6694099: Hotspot vm_exit_out_of_memory should dump core
poonam
parents:
61
diff
changeset
|
621 |
8d852b81e775
6694099: Hotspot vm_exit_out_of_memory should dump core
poonam
parents:
61
diff
changeset
|
622 // Failure during initialization, we don't want to dump core |
8d852b81e775
6694099: Hotspot vm_exit_out_of_memory should dump core
poonam
parents:
61
diff
changeset
|
623 vm_abort(false); |
0 | 624 } |
625 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2129
diff
changeset
|
626 void vm_exit_during_initialization(Symbol* ex, const char* message) { |
0 | 627 ResourceMark rm; |
628 vm_notify_during_shutdown(ex->as_C_string(), message); | |
227
8d852b81e775
6694099: Hotspot vm_exit_out_of_memory should dump core
poonam
parents:
61
diff
changeset
|
629 |
8d852b81e775
6694099: Hotspot vm_exit_out_of_memory should dump core
poonam
parents:
61
diff
changeset
|
630 // Failure during initialization, we don't want to dump core |
8d852b81e775
6694099: Hotspot vm_exit_out_of_memory should dump core
poonam
parents:
61
diff
changeset
|
631 vm_abort(false); |
0 | 632 } |
633 | |
634 void vm_exit_during_initialization(const char* error, const char* message) { | |
635 vm_notify_during_shutdown(error, message); | |
227
8d852b81e775
6694099: Hotspot vm_exit_out_of_memory should dump core
poonam
parents:
61
diff
changeset
|
636 |
8d852b81e775
6694099: Hotspot vm_exit_out_of_memory should dump core
poonam
parents:
61
diff
changeset
|
637 // Failure during initialization, we don't want to dump core |
8d852b81e775
6694099: Hotspot vm_exit_out_of_memory should dump core
poonam
parents:
61
diff
changeset
|
638 vm_abort(false); |
0 | 639 } |
640 | |
641 void vm_shutdown_during_initialization(const char* error, const char* message) { | |
642 vm_notify_during_shutdown(error, message); | |
643 vm_shutdown(); | |
644 } | |
645 | |
242 | 646 JDK_Version JDK_Version::_current; |
0 | 647 |
648 void JDK_Version::initialize() { | |
242 | 649 jdk_version_info info; |
650 assert(!_current.is_valid(), "Don't initialize twice"); | |
651 | |
0 | 652 void *lib_handle = os::native_java_library(); |
242 | 653 jdk_version_info_fn_t func = CAST_TO_FN_PTR(jdk_version_info_fn_t, |
654 os::dll_lookup(lib_handle, "JDK_GetVersionInfo0")); | |
0 | 655 |
656 if (func == NULL) { | |
657 // JDK older than 1.6 | |
242 | 658 _current._partially_initialized = true; |
659 } else { | |
660 (*func)(&info, sizeof(info)); | |
0 | 661 |
242 | 662 int major = JDK_VERSION_MAJOR(info.jdk_version); |
663 int minor = JDK_VERSION_MINOR(info.jdk_version); | |
664 int micro = JDK_VERSION_MICRO(info.jdk_version); | |
665 int build = JDK_VERSION_BUILD(info.jdk_version); | |
666 if (major == 1 && minor > 4) { | |
667 // We represent "1.5.0" as "5.0", but 1.4.2 as itself. | |
668 major = minor; | |
669 minor = micro; | |
670 micro = 0; | |
671 } | |
672 _current = JDK_Version(major, minor, micro, info.update_version, | |
673 info.special_update_version, build, | |
2129
8f8dfba37802
6994753: Implement optional hook to a Java method at VM startup.
kevinw
parents:
2096
diff
changeset
|
674 info.thread_park_blocker == 1, |
3917
eca1193ca245
4965777: GC changes to support use of discovered field for pending references
ysr
parents:
3841
diff
changeset
|
675 info.post_vm_init_hook_enabled == 1, |
eca1193ca245
4965777: GC changes to support use of discovered field for pending references
ysr
parents:
3841
diff
changeset
|
676 info.pending_list_uses_discovered_field == 1); |
0 | 677 } |
242 | 678 } |
679 | |
680 void JDK_Version::fully_initialize( | |
681 uint8_t major, uint8_t minor, uint8_t micro, uint8_t update) { | |
682 // This is only called when current is less than 1.6 and we've gotten | |
683 // far enough in the initialization to determine the exact version. | |
684 assert(major < 6, "not needed for JDK version >= 6"); | |
685 assert(is_partially_initialized(), "must not initialize"); | |
686 if (major < 5) { | |
687 // JDK verison sequence: 1.2.x, 1.3.x, 1.4.x, 5.0.x, 6.0.x, etc. | |
688 micro = minor; | |
689 minor = major; | |
690 major = 1; | |
0 | 691 } |
242 | 692 _current = JDK_Version(major, minor, micro, update); |
0 | 693 } |
694 | |
695 void JDK_Version_init() { | |
696 JDK_Version::initialize(); | |
697 } | |
242 | 698 |
699 static int64_t encode_jdk_version(const JDK_Version& v) { | |
700 return | |
701 ((int64_t)v.major_version() << (BitsPerByte * 5)) | | |
702 ((int64_t)v.minor_version() << (BitsPerByte * 4)) | | |
703 ((int64_t)v.micro_version() << (BitsPerByte * 3)) | | |
704 ((int64_t)v.update_version() << (BitsPerByte * 2)) | | |
705 ((int64_t)v.special_update_version() << (BitsPerByte * 1)) | | |
706 ((int64_t)v.build_number() << (BitsPerByte * 0)); | |
707 } | |
708 | |
709 int JDK_Version::compare(const JDK_Version& other) const { | |
710 assert(is_valid() && other.is_valid(), "Invalid version (uninitialized?)"); | |
711 if (!is_partially_initialized() && other.is_partially_initialized()) { | |
712 return -(other.compare(*this)); // flip the comparators | |
713 } | |
714 assert(!other.is_partially_initialized(), "Not initialized yet"); | |
715 if (is_partially_initialized()) { | |
716 assert(other.major_version() >= 6, | |
717 "Invalid JDK version comparison during initialization"); | |
718 return -1; | |
719 } else { | |
720 uint64_t e = encode_jdk_version(*this); | |
721 uint64_t o = encode_jdk_version(other); | |
722 return (e > o) ? 1 : ((e == o) ? 0 : -1); | |
723 } | |
724 } | |
725 | |
726 void JDK_Version::to_string(char* buffer, size_t buflen) const { | |
727 size_t index = 0; | |
728 if (!is_valid()) { | |
729 jio_snprintf(buffer, buflen, "%s", "(uninitialized)"); | |
730 } else if (is_partially_initialized()) { | |
731 jio_snprintf(buffer, buflen, "%s", "(uninitialized) pre-1.6.0"); | |
732 } else { | |
733 index += jio_snprintf( | |
734 &buffer[index], buflen - index, "%d.%d", _major, _minor); | |
735 if (_micro > 0) { | |
736 index += jio_snprintf(&buffer[index], buflen - index, ".%d", _micro); | |
737 } | |
738 if (_update > 0) { | |
739 index += jio_snprintf(&buffer[index], buflen - index, "_%02d", _update); | |
740 } | |
741 if (_special > 0) { | |
742 index += jio_snprintf(&buffer[index], buflen - index, "%c", _special); | |
743 } | |
744 if (_build > 0) { | |
745 index += jio_snprintf(&buffer[index], buflen - index, "-b%02d", _build); | |
746 } | |
747 } | |
748 } |