1
|
1 |
/*
|
|
2 |
* Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
|
|
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 |
*
|
|
19 |
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
|
20 |
* CA 95054 USA or visit www.sun.com if you need additional information or
|
|
21 |
* have any questions.
|
|
22 |
*
|
|
23 |
*/
|
|
24 |
|
|
25 |
#include "incls/_precompiled.incl"
|
|
26 |
#include "incls/_java.cpp.incl"
|
|
27 |
|
|
28 |
HS_DTRACE_PROBE_DECL(hotspot, vm__shutdown);
|
|
29 |
|
|
30 |
#ifndef PRODUCT
|
|
31 |
|
|
32 |
// Statistics printing (method invocation histogram)
|
|
33 |
|
|
34 |
GrowableArray<methodOop>* collected_invoked_methods;
|
|
35 |
|
|
36 |
void collect_invoked_methods(methodOop m) {
|
|
37 |
if (m->invocation_count() + m->compiled_invocation_count() >= 1 ) {
|
|
38 |
collected_invoked_methods->push(m);
|
|
39 |
}
|
|
40 |
}
|
|
41 |
|
|
42 |
|
|
43 |
GrowableArray<methodOop>* collected_profiled_methods;
|
|
44 |
|
|
45 |
void collect_profiled_methods(methodOop m) {
|
|
46 |
methodHandle mh(Thread::current(), m);
|
|
47 |
if ((m->method_data() != NULL) &&
|
|
48 |
(PrintMethodData || CompilerOracle::should_print(mh))) {
|
|
49 |
collected_profiled_methods->push(m);
|
|
50 |
}
|
|
51 |
}
|
|
52 |
|
|
53 |
|
|
54 |
int compare_methods(methodOop* a, methodOop* b) {
|
|
55 |
// %%% there can be 32-bit overflow here
|
|
56 |
return ((*b)->invocation_count() + (*b)->compiled_invocation_count())
|
|
57 |
- ((*a)->invocation_count() + (*a)->compiled_invocation_count());
|
|
58 |
}
|
|
59 |
|
|
60 |
|
|
61 |
void print_method_invocation_histogram() {
|
|
62 |
ResourceMark rm;
|
|
63 |
HandleMark hm;
|
|
64 |
collected_invoked_methods = new GrowableArray<methodOop>(1024);
|
|
65 |
SystemDictionary::methods_do(collect_invoked_methods);
|
|
66 |
collected_invoked_methods->sort(&compare_methods);
|
|
67 |
//
|
|
68 |
tty->cr();
|
|
69 |
tty->print_cr("Histogram Over MethodOop Invocation Counters (cutoff = %d):", MethodHistogramCutoff);
|
|
70 |
tty->cr();
|
|
71 |
tty->print_cr("____Count_(I+C)____Method________________________Module_________________");
|
|
72 |
unsigned total = 0, int_total = 0, comp_total = 0, static_total = 0, final_total = 0,
|
|
73 |
synch_total = 0, nativ_total = 0, acces_total = 0;
|
|
74 |
for (int index = 0; index < collected_invoked_methods->length(); index++) {
|
|
75 |
methodOop m = collected_invoked_methods->at(index);
|
|
76 |
int c = m->invocation_count() + m->compiled_invocation_count();
|
|
77 |
if (c >= MethodHistogramCutoff) m->print_invocation_count();
|
|
78 |
int_total += m->invocation_count();
|
|
79 |
comp_total += m->compiled_invocation_count();
|
|
80 |
if (m->is_final()) final_total += c;
|
|
81 |
if (m->is_static()) static_total += c;
|
|
82 |
if (m->is_synchronized()) synch_total += c;
|
|
83 |
if (m->is_native()) nativ_total += c;
|
|
84 |
if (m->is_accessor()) acces_total += c;
|
|
85 |
}
|
|
86 |
tty->cr();
|
|
87 |
total = int_total + comp_total;
|
|
88 |
tty->print_cr("Invocations summary:");
|
|
89 |
tty->print_cr("\t%9d (%4.1f%%) interpreted", int_total, 100.0 * int_total / total);
|
|
90 |
tty->print_cr("\t%9d (%4.1f%%) compiled", comp_total, 100.0 * comp_total / total);
|
|
91 |
tty->print_cr("\t%9d (100%%) total", total);
|
|
92 |
tty->print_cr("\t%9d (%4.1f%%) synchronized", synch_total, 100.0 * synch_total / total);
|
|
93 |
tty->print_cr("\t%9d (%4.1f%%) final", final_total, 100.0 * final_total / total);
|
|
94 |
tty->print_cr("\t%9d (%4.1f%%) static", static_total, 100.0 * static_total / total);
|
|
95 |
tty->print_cr("\t%9d (%4.1f%%) native", nativ_total, 100.0 * nativ_total / total);
|
|
96 |
tty->print_cr("\t%9d (%4.1f%%) accessor", acces_total, 100.0 * acces_total / total);
|
|
97 |
tty->cr();
|
|
98 |
SharedRuntime::print_call_statistics(comp_total);
|
|
99 |
}
|
|
100 |
|
|
101 |
void print_method_profiling_data() {
|
|
102 |
ResourceMark rm;
|
|
103 |
HandleMark hm;
|
|
104 |
collected_profiled_methods = new GrowableArray<methodOop>(1024);
|
|
105 |
SystemDictionary::methods_do(collect_profiled_methods);
|
|
106 |
collected_profiled_methods->sort(&compare_methods);
|
|
107 |
|
|
108 |
int count = collected_profiled_methods->length();
|
|
109 |
if (count > 0) {
|
|
110 |
for (int index = 0; index < count; index++) {
|
|
111 |
methodOop m = collected_profiled_methods->at(index);
|
|
112 |
ttyLocker ttyl;
|
|
113 |
tty->print_cr("------------------------------------------------------------------------");
|
|
114 |
//m->print_name(tty);
|
|
115 |
m->print_invocation_count();
|
|
116 |
tty->cr();
|
|
117 |
m->print_codes();
|
|
118 |
}
|
|
119 |
tty->print_cr("------------------------------------------------------------------------");
|
|
120 |
}
|
|
121 |
}
|
|
122 |
|
|
123 |
void print_bytecode_count() {
|
|
124 |
if (CountBytecodes || TraceBytecodes || StopInterpreterAt) {
|
|
125 |
tty->print_cr("[BytecodeCounter::counter_value = %d]", BytecodeCounter::counter_value());
|
|
126 |
}
|
|
127 |
}
|
|
128 |
|
|
129 |
AllocStats alloc_stats;
|
|
130 |
|
|
131 |
|
|
132 |
|
|
133 |
// General statistics printing (profiling ...)
|
|
134 |
|
|
135 |
void print_statistics() {
|
|
136 |
|
|
137 |
#ifdef ASSERT
|
|
138 |
|
|
139 |
if (CountRuntimeCalls) {
|
|
140 |
extern Histogram *RuntimeHistogram;
|
|
141 |
RuntimeHistogram->print();
|
|
142 |
}
|
|
143 |
|
|
144 |
if (CountJNICalls) {
|
|
145 |
extern Histogram *JNIHistogram;
|
|
146 |
JNIHistogram->print();
|
|
147 |
}
|
|
148 |
|
|
149 |
if (CountJVMCalls) {
|
|
150 |
extern Histogram *JVMHistogram;
|
|
151 |
JVMHistogram->print();
|
|
152 |
}
|
|
153 |
|
|
154 |
#endif
|
|
155 |
|
|
156 |
if (MemProfiling) {
|
|
157 |
MemProfiler::disengage();
|
|
158 |
}
|
|
159 |
|
|
160 |
if (CITime) {
|
|
161 |
CompileBroker::print_times();
|
|
162 |
}
|
|
163 |
|
|
164 |
#ifdef COMPILER1
|
|
165 |
if ((PrintC1Statistics || LogVMOutput || LogCompilation) && UseCompiler) {
|
|
166 |
FlagSetting fs(DisplayVMOutput, DisplayVMOutput && PrintC1Statistics);
|
|
167 |
Runtime1::print_statistics();
|
|
168 |
Deoptimization::print_statistics();
|
|
169 |
nmethod::print_statistics();
|
|
170 |
}
|
|
171 |
#endif /* COMPILER1 */
|
|
172 |
|
|
173 |
#ifdef COMPILER2
|
|
174 |
if ((PrintOptoStatistics || LogVMOutput || LogCompilation) && UseCompiler) {
|
|
175 |
FlagSetting fs(DisplayVMOutput, DisplayVMOutput && PrintOptoStatistics);
|
|
176 |
Compile::print_statistics();
|
|
177 |
#ifndef COMPILER1
|
|
178 |
Deoptimization::print_statistics();
|
|
179 |
nmethod::print_statistics();
|
|
180 |
#endif //COMPILER1
|
|
181 |
SharedRuntime::print_statistics();
|
|
182 |
os::print_statistics();
|
|
183 |
}
|
|
184 |
|
|
185 |
if (PrintLockStatistics || PrintPreciseBiasedLockingStatistics) {
|
|
186 |
OptoRuntime::print_named_counters();
|
|
187 |
}
|
|
188 |
|
|
189 |
if (TimeLivenessAnalysis) {
|
|
190 |
MethodLiveness::print_times();
|
|
191 |
}
|
|
192 |
#ifdef ASSERT
|
|
193 |
if (CollectIndexSetStatistics) {
|
|
194 |
IndexSet::print_statistics();
|
|
195 |
}
|
|
196 |
#endif // ASSERT
|
|
197 |
#endif // COMPILER2
|
|
198 |
if (CountCompiledCalls) {
|
|
199 |
print_method_invocation_histogram();
|
|
200 |
}
|
|
201 |
if (ProfileInterpreter || Tier1UpdateMethodData) {
|
|
202 |
print_method_profiling_data();
|
|
203 |
}
|
|
204 |
if (TimeCompiler) {
|
|
205 |
COMPILER2_PRESENT(Compile::print_timers();)
|
|
206 |
}
|
|
207 |
if (TimeCompilationPolicy) {
|
|
208 |
CompilationPolicy::policy()->print_time();
|
|
209 |
}
|
|
210 |
if (TimeOopMap) {
|
|
211 |
GenerateOopMap::print_time();
|
|
212 |
}
|
|
213 |
if (ProfilerCheckIntervals) {
|
|
214 |
PeriodicTask::print_intervals();
|
|
215 |
}
|
|
216 |
if (PrintSymbolTableSizeHistogram) {
|
|
217 |
SymbolTable::print_histogram();
|
|
218 |
}
|
|
219 |
if (CountBytecodes || TraceBytecodes || StopInterpreterAt) {
|
|
220 |
BytecodeCounter::print();
|
|
221 |
}
|
|
222 |
if (PrintBytecodePairHistogram) {
|
|
223 |
BytecodePairHistogram::print();
|
|
224 |
}
|
|
225 |
|
|
226 |
if (PrintCodeCache) {
|
|
227 |
MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
|
|
228 |
CodeCache::print();
|
|
229 |
}
|
|
230 |
|
|
231 |
if (PrintCodeCache2) {
|
|
232 |
MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
|
|
233 |
CodeCache::print_internals();
|
|
234 |
}
|
|
235 |
|
|
236 |
if (PrintClassStatistics) {
|
|
237 |
SystemDictionary::print_class_statistics();
|
|
238 |
}
|
|
239 |
if (PrintMethodStatistics) {
|
|
240 |
SystemDictionary::print_method_statistics();
|
|
241 |
}
|
|
242 |
|
|
243 |
if (PrintVtableStats) {
|
|
244 |
klassVtable::print_statistics();
|
|
245 |
klassItable::print_statistics();
|
|
246 |
}
|
|
247 |
if (VerifyOops) {
|
|
248 |
tty->print_cr("+VerifyOops count: %d", StubRoutines::verify_oop_count());
|
|
249 |
}
|
|
250 |
|
|
251 |
print_bytecode_count();
|
|
252 |
if (WizardMode) {
|
|
253 |
tty->print("allocation stats: ");
|
|
254 |
alloc_stats.print();
|
|
255 |
tty->cr();
|
|
256 |
}
|
|
257 |
|
|
258 |
if (PrintSystemDictionaryAtExit) {
|
|
259 |
SystemDictionary::print();
|
|
260 |
}
|
|
261 |
|
|
262 |
if (PrintBiasedLockingStatistics) {
|
|
263 |
BiasedLocking::print_counters();
|
|
264 |
}
|
|
265 |
|
|
266 |
#ifdef ENABLE_ZAP_DEAD_LOCALS
|
|
267 |
#ifdef COMPILER2
|
|
268 |
if (ZapDeadCompiledLocals) {
|
|
269 |
tty->print_cr("Compile::CompiledZap_count = %d", Compile::CompiledZap_count);
|
|
270 |
tty->print_cr("OptoRuntime::ZapDeadCompiledLocals_count = %d", OptoRuntime::ZapDeadCompiledLocals_count);
|
|
271 |
}
|
|
272 |
#endif // COMPILER2
|
|
273 |
#endif // ENABLE_ZAP_DEAD_LOCALS
|
|
274 |
}
|
|
275 |
|
|
276 |
#else // PRODUCT MODE STATISTICS
|
|
277 |
|
|
278 |
void print_statistics() {
|
|
279 |
|
|
280 |
if (CITime) {
|
|
281 |
CompileBroker::print_times();
|
|
282 |
}
|
|
283 |
#ifdef COMPILER2
|
|
284 |
if (PrintPreciseBiasedLockingStatistics) {
|
|
285 |
OptoRuntime::print_named_counters();
|
|
286 |
}
|
|
287 |
#endif
|
|
288 |
if (PrintBiasedLockingStatistics) {
|
|
289 |
BiasedLocking::print_counters();
|
|
290 |
}
|
|
291 |
}
|
|
292 |
|
|
293 |
#endif
|
|
294 |
|
|
295 |
|
|
296 |
// Helper class for registering on_exit calls through JVM_OnExit
|
|
297 |
|
|
298 |
extern "C" {
|
|
299 |
typedef void (*__exit_proc)(void);
|
|
300 |
}
|
|
301 |
|
|
302 |
class ExitProc : public CHeapObj {
|
|
303 |
private:
|
|
304 |
__exit_proc _proc;
|
|
305 |
// void (*_proc)(void);
|
|
306 |
ExitProc* _next;
|
|
307 |
public:
|
|
308 |
// ExitProc(void (*proc)(void)) {
|
|
309 |
ExitProc(__exit_proc proc) {
|
|
310 |
_proc = proc;
|
|
311 |
_next = NULL;
|
|
312 |
}
|
|
313 |
void evaluate() { _proc(); }
|
|
314 |
ExitProc* next() const { return _next; }
|
|
315 |
void set_next(ExitProc* next) { _next = next; }
|
|
316 |
};
|
|
317 |
|
|
318 |
|
|
319 |
// Linked list of registered on_exit procedures
|
|
320 |
|
|
321 |
static ExitProc* exit_procs = NULL;
|
|
322 |
|
|
323 |
|
|
324 |
extern "C" {
|
|
325 |
void register_on_exit_function(void (*func)(void)) {
|
|
326 |
ExitProc *entry = new ExitProc(func);
|
|
327 |
// Classic vm does not throw an exception in case the allocation failed,
|
|
328 |
if (entry != NULL) {
|
|
329 |
entry->set_next(exit_procs);
|
|
330 |
exit_procs = entry;
|
|
331 |
}
|
|
332 |
}
|
|
333 |
}
|
|
334 |
|
|
335 |
// Note: before_exit() can be executed only once, if more than one threads
|
|
336 |
// are trying to shutdown the VM at the same time, only one thread
|
|
337 |
// can run before_exit() and all other threads must wait.
|
|
338 |
void before_exit(JavaThread * thread) {
|
|
339 |
#define BEFORE_EXIT_NOT_RUN 0
|
|
340 |
#define BEFORE_EXIT_RUNNING 1
|
|
341 |
#define BEFORE_EXIT_DONE 2
|
|
342 |
static jint volatile _before_exit_status = BEFORE_EXIT_NOT_RUN;
|
|
343 |
|
|
344 |
// Note: don't use a Mutex to guard the entire before_exit(), as
|
|
345 |
// JVMTI post_thread_end_event and post_vm_death_event will run native code.
|
|
346 |
// A CAS or OSMutex would work just fine but then we need to manipulate
|
|
347 |
// thread state for Safepoint. Here we use Monitor wait() and notify_all()
|
|
348 |
// for synchronization.
|
|
349 |
{ MutexLocker ml(BeforeExit_lock);
|
|
350 |
switch (_before_exit_status) {
|
|
351 |
case BEFORE_EXIT_NOT_RUN:
|
|
352 |
_before_exit_status = BEFORE_EXIT_RUNNING;
|
|
353 |
break;
|
|
354 |
case BEFORE_EXIT_RUNNING:
|
|
355 |
while (_before_exit_status == BEFORE_EXIT_RUNNING) {
|
|
356 |
BeforeExit_lock->wait();
|
|
357 |
}
|
|
358 |
assert(_before_exit_status == BEFORE_EXIT_DONE, "invalid state");
|
|
359 |
return;
|
|
360 |
case BEFORE_EXIT_DONE:
|
|
361 |
return;
|
|
362 |
}
|
|
363 |
}
|
|
364 |
|
|
365 |
// The only difference between this and Win32's _onexit procs is that
|
|
366 |
// this version is invoked before any threads get killed.
|
|
367 |
ExitProc* current = exit_procs;
|
|
368 |
while (current != NULL) {
|
|
369 |
ExitProc* next = current->next();
|
|
370 |
current->evaluate();
|
|
371 |
delete current;
|
|
372 |
current = next;
|
|
373 |
}
|
|
374 |
|
|
375 |
// Hang forever on exit if we're reporting an error.
|
|
376 |
if (ShowMessageBoxOnError && is_error_reported()) {
|
|
377 |
os::infinite_sleep();
|
|
378 |
}
|
|
379 |
|
|
380 |
// Terminate watcher thread - must before disenrolling any periodic task
|
|
381 |
WatcherThread::stop();
|
|
382 |
|
|
383 |
// Print statistics gathered (profiling ...)
|
|
384 |
if (Arguments::has_profile()) {
|
|
385 |
FlatProfiler::disengage();
|
|
386 |
FlatProfiler::print(10);
|
|
387 |
}
|
|
388 |
|
|
389 |
// shut down the StatSampler task
|
|
390 |
StatSampler::disengage();
|
|
391 |
StatSampler::destroy();
|
|
392 |
|
|
393 |
#ifndef SERIALGC
|
|
394 |
// stop CMS threads
|
|
395 |
if (UseConcMarkSweepGC) {
|
|
396 |
ConcurrentMarkSweepThread::stop();
|
|
397 |
}
|
|
398 |
#endif // SERIALGC
|
|
399 |
|
|
400 |
// Print GC/heap related information.
|
|
401 |
if (PrintGCDetails) {
|
|
402 |
Universe::print();
|
|
403 |
AdaptiveSizePolicyOutput(0);
|
|
404 |
}
|
|
405 |
|
|
406 |
|
|
407 |
if (Arguments::has_alloc_profile()) {
|
|
408 |
HandleMark hm;
|
|
409 |
// Do one last collection to enumerate all the objects
|
|
410 |
// allocated since the last one.
|
|
411 |
Universe::heap()->collect(GCCause::_allocation_profiler);
|
|
412 |
AllocationProfiler::disengage();
|
|
413 |
AllocationProfiler::print(0);
|
|
414 |
}
|
|
415 |
|
|
416 |
if (PrintBytecodeHistogram) {
|
|
417 |
BytecodeHistogram::print();
|
|
418 |
}
|
|
419 |
|
|
420 |
if (JvmtiExport::should_post_thread_life()) {
|
|
421 |
JvmtiExport::post_thread_end(thread);
|
|
422 |
}
|
|
423 |
// Always call even when there are not JVMTI environments yet, since environments
|
|
424 |
// may be attached late and JVMTI must track phases of VM execution
|
|
425 |
JvmtiExport::post_vm_death();
|
|
426 |
Threads::shutdown_vm_agents();
|
|
427 |
|
|
428 |
// Terminate the signal thread
|
|
429 |
// Note: we don't wait until it actually dies.
|
|
430 |
os::terminate_signal_thread();
|
|
431 |
|
|
432 |
print_statistics();
|
|
433 |
Universe::heap()->print_tracing_info();
|
|
434 |
|
|
435 |
VTune::exit();
|
|
436 |
|
|
437 |
{ MutexLocker ml(BeforeExit_lock);
|
|
438 |
_before_exit_status = BEFORE_EXIT_DONE;
|
|
439 |
BeforeExit_lock->notify_all();
|
|
440 |
}
|
|
441 |
|
|
442 |
#undef BEFORE_EXIT_NOT_RUN
|
|
443 |
#undef BEFORE_EXIT_RUNNING
|
|
444 |
#undef BEFORE_EXIT_DONE
|
|
445 |
}
|
|
446 |
|
|
447 |
void vm_exit(int code) {
|
|
448 |
Thread* thread = ThreadLocalStorage::thread_index() == -1 ? NULL
|
|
449 |
: ThreadLocalStorage::get_thread_slow();
|
|
450 |
if (thread == NULL) {
|
|
451 |
// we have serious problems -- just exit
|
|
452 |
vm_direct_exit(code);
|
|
453 |
}
|
|
454 |
|
|
455 |
if (VMThread::vm_thread() != NULL) {
|
|
456 |
// Fire off a VM_Exit operation to bring VM to a safepoint and exit
|
|
457 |
VM_Exit op(code);
|
|
458 |
if (thread->is_Java_thread())
|
|
459 |
((JavaThread*)thread)->set_thread_state(_thread_in_vm);
|
|
460 |
VMThread::execute(&op);
|
|
461 |
// should never reach here; but in case something wrong with VM Thread.
|
|
462 |
vm_direct_exit(code);
|
|
463 |
} else {
|
|
464 |
// VM thread is gone, just exit
|
|
465 |
vm_direct_exit(code);
|
|
466 |
}
|
|
467 |
ShouldNotReachHere();
|
|
468 |
}
|
|
469 |
|
|
470 |
void notify_vm_shutdown() {
|
|
471 |
// For now, just a dtrace probe.
|
|
472 |
HS_DTRACE_PROBE(hotspot, vm__shutdown);
|
|
473 |
}
|
|
474 |
|
|
475 |
void vm_direct_exit(int code) {
|
|
476 |
notify_vm_shutdown();
|
|
477 |
::exit(code);
|
|
478 |
}
|
|
479 |
|
|
480 |
void vm_perform_shutdown_actions() {
|
|
481 |
// Warning: do not call 'exit_globals()' here. All threads are still running.
|
|
482 |
// Calling 'exit_globals()' will disable thread-local-storage and cause all
|
|
483 |
// kinds of assertions to trigger in debug mode.
|
|
484 |
if (is_init_completed()) {
|
|
485 |
Thread* thread = Thread::current();
|
|
486 |
if (thread->is_Java_thread()) {
|
|
487 |
// We are leaving the VM, set state to native (in case any OS exit
|
|
488 |
// handlers call back to the VM)
|
|
489 |
JavaThread* jt = (JavaThread*)thread;
|
|
490 |
// Must always be walkable or have no last_Java_frame when in
|
|
491 |
// thread_in_native
|
|
492 |
jt->frame_anchor()->make_walkable(jt);
|
|
493 |
jt->set_thread_state(_thread_in_native);
|
|
494 |
}
|
|
495 |
}
|
|
496 |
notify_vm_shutdown();
|
|
497 |
}
|
|
498 |
|
|
499 |
void vm_shutdown()
|
|
500 |
{
|
|
501 |
vm_perform_shutdown_actions();
|
|
502 |
os::shutdown();
|
|
503 |
}
|
|
504 |
|
|
505 |
void vm_abort() {
|
|
506 |
vm_perform_shutdown_actions();
|
|
507 |
os::abort(PRODUCT_ONLY(false));
|
|
508 |
ShouldNotReachHere();
|
|
509 |
}
|
|
510 |
|
|
511 |
void vm_notify_during_shutdown(const char* error, const char* message) {
|
|
512 |
if (error != NULL) {
|
|
513 |
tty->print_cr("Error occurred during initialization of VM");
|
|
514 |
tty->print("%s", error);
|
|
515 |
if (message != NULL) {
|
|
516 |
tty->print_cr(": %s", message);
|
|
517 |
}
|
|
518 |
else {
|
|
519 |
tty->cr();
|
|
520 |
}
|
|
521 |
}
|
|
522 |
if (ShowMessageBoxOnError && WizardMode) {
|
|
523 |
fatal("Error occurred during initialization of VM");
|
|
524 |
}
|
|
525 |
}
|
|
526 |
|
|
527 |
void vm_exit_during_initialization(Handle exception) {
|
|
528 |
tty->print_cr("Error occurred during initialization of VM");
|
|
529 |
// If there are exceptions on this thread it must be cleared
|
|
530 |
// first and here. Any future calls to EXCEPTION_MARK requires
|
|
531 |
// that no pending exceptions exist.
|
|
532 |
Thread *THREAD = Thread::current();
|
|
533 |
if (HAS_PENDING_EXCEPTION) {
|
|
534 |
CLEAR_PENDING_EXCEPTION;
|
|
535 |
}
|
|
536 |
java_lang_Throwable::print(exception, tty);
|
|
537 |
tty->cr();
|
|
538 |
java_lang_Throwable::print_stack_trace(exception(), tty);
|
|
539 |
tty->cr();
|
|
540 |
vm_notify_during_shutdown(NULL, NULL);
|
|
541 |
vm_abort();
|
|
542 |
}
|
|
543 |
|
|
544 |
void vm_exit_during_initialization(symbolHandle ex, const char* message) {
|
|
545 |
ResourceMark rm;
|
|
546 |
vm_notify_during_shutdown(ex->as_C_string(), message);
|
|
547 |
vm_abort();
|
|
548 |
}
|
|
549 |
|
|
550 |
void vm_exit_during_initialization(const char* error, const char* message) {
|
|
551 |
vm_notify_during_shutdown(error, message);
|
|
552 |
vm_abort();
|
|
553 |
}
|
|
554 |
|
|
555 |
void vm_shutdown_during_initialization(const char* error, const char* message) {
|
|
556 |
vm_notify_during_shutdown(error, message);
|
|
557 |
vm_shutdown();
|
|
558 |
}
|
|
559 |
|
|
560 |
jdk_version_info JDK_Version::_version_info = {0};
|
|
561 |
bool JDK_Version::_pre_jdk16_version = false;
|
|
562 |
int JDK_Version::_jdk_version = 0;
|
|
563 |
|
|
564 |
void JDK_Version::initialize() {
|
|
565 |
void *lib_handle = os::native_java_library();
|
|
566 |
jdk_version_info_fn_t func =
|
|
567 |
CAST_TO_FN_PTR(jdk_version_info_fn_t, hpi::dll_lookup(lib_handle, "JDK_GetVersionInfo0"));
|
|
568 |
|
|
569 |
if (func == NULL) {
|
|
570 |
// JDK older than 1.6
|
|
571 |
_pre_jdk16_version = true;
|
|
572 |
return;
|
|
573 |
}
|
|
574 |
|
|
575 |
if (func != NULL) {
|
|
576 |
(*func)(&_version_info, sizeof(_version_info));
|
|
577 |
}
|
|
578 |
if (jdk_major_version() == 1) {
|
|
579 |
_jdk_version = jdk_minor_version();
|
|
580 |
} else {
|
|
581 |
// If the release version string is changed to n.x.x (e.g. 7.0.0) in a future release
|
|
582 |
_jdk_version = jdk_major_version();
|
|
583 |
}
|
|
584 |
}
|
|
585 |
|
|
586 |
void JDK_Version_init() {
|
|
587 |
JDK_Version::initialize();
|
|
588 |
}
|