1 /*
2 * Copyright (c) 1997, 2018, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "jvm.h"
27 #include "classfile/systemDictionary.hpp"
28 #include "code/codeCache.hpp"
29 #include "code/icBuffer.hpp"
30 #include "code/nmethod.hpp"
31 #include "code/vtableStubs.hpp"
32 #include "compiler/compileBroker.hpp"
33 #include "compiler/disassembler.hpp"
34 #include "gc/shared/collectedHeap.hpp"
35 #include "interpreter/bytecodeHistogram.hpp"
36 #include "interpreter/interpreter.hpp"
37 #include "memory/resourceArea.hpp"
38 #include "memory/universe.hpp"
39 #include "oops/oop.inline.hpp"
40 #include "runtime/arguments.hpp"
41 #include "runtime/atomic.hpp"
42 #include "runtime/flags/flagSetting.hpp"
43 #include "runtime/frame.inline.hpp"
44 #include "runtime/handles.inline.hpp"
45 #include "runtime/java.hpp"
46 #include "runtime/os.hpp"
47 #include "runtime/sharedRuntime.hpp"
48 #include "runtime/stubCodeGenerator.hpp"
49 #include "runtime/stubRoutines.hpp"
50 #include "runtime/thread.inline.hpp"
51 #include "runtime/vframe.hpp"
52 #include "runtime/vm_version.hpp"
53 #include "services/heapDumper.hpp"
54 #include "utilities/defaultStream.hpp"
55 #include "utilities/events.hpp"
56 #include "utilities/formatBuffer.hpp"
57 #include "utilities/globalDefinitions.hpp"
58 #include "utilities/macros.hpp"
59 #include "utilities/vmError.hpp"
60
61 #include <stdio.h>
62
63 // Support for showing register content on asserts/guarantees.
64 #ifdef CAN_SHOW_REGISTERS_ON_ASSERT
65 static char g_dummy;
66 char* g_assert_poison = &g_dummy;
67 static intx g_asserting_thread = 0;
68 static void* g_assertion_context = NULL;
69 #endif // CAN_SHOW_REGISTERS_ON_ASSERT
70
71 #ifndef ASSERT
72 # ifdef _DEBUG
73 // NOTE: don't turn the lines below into a comment -- if you're getting
74 // a compile error here, change the settings to define ASSERT
75 ASSERT should be defined when _DEBUG is defined. It is not intended to be used for debugging
76 functions that do not slow down the system too much and thus can be left in optimized code.
77 On the other hand, the code should not be included in a production version.
78 # endif // _DEBUG
79 #endif // ASSERT
80
81
82 #ifdef _DEBUG
83 # ifndef ASSERT
84 configuration error: ASSERT must be defined in debug version
85 # endif // ASSERT
86 #endif // _DEBUG
87
88
89 #ifdef PRODUCT
90 # if -defined _DEBUG || -defined ASSERT
91 configuration error: ASSERT et al. must not be defined in PRODUCT version
92 # endif
93 #endif // PRODUCT
94
95 ATTRIBUTE_PRINTF(1, 2)
warning(const char * format,...)96 void warning(const char* format, ...) {
97 if (PrintWarnings) {
98 FILE* const err = defaultStream::error_stream();
99 jio_fprintf(err, "%s warning: ", VM_Version::vm_name());
100 va_list ap;
101 va_start(ap, format);
102 vfprintf(err, format, ap);
103 va_end(ap);
104 fputc('\n', err);
105 }
106 if (BreakAtWarning) BREAKPOINT;
107 }
108
109 #ifndef PRODUCT
110
111 #define is_token_break(ch) (isspace(ch) || (ch) == ',')
112
113 static const char* last_file_name = NULL;
114 static int last_line_no = -1;
115
116 // assert/guarantee/... may happen very early during VM initialization.
117 // Don't rely on anything that is initialized by Threads::create_vm(). For
118 // example, don't use tty.
error_is_suppressed(const char * file_name,int line_no)119 bool error_is_suppressed(const char* file_name, int line_no) {
120 // The following 1-element cache requires that passed-in
121 // file names are always only constant literals.
122 if (file_name == last_file_name && line_no == last_line_no) return true;
123
124 int file_name_len = (int)strlen(file_name);
125 char separator = os::file_separator()[0];
126 const char* base_name = strrchr(file_name, separator);
127 if (base_name == NULL)
128 base_name = file_name;
129
130 // scan the SuppressErrorAt option
131 const char* cp = SuppressErrorAt;
132 for (;;) {
133 const char* sfile;
134 int sfile_len;
135 int sline;
136 bool noisy;
137 while ((*cp) != '\0' && is_token_break(*cp)) cp++;
138 if ((*cp) == '\0') break;
139 sfile = cp;
140 while ((*cp) != '\0' && !is_token_break(*cp) && (*cp) != ':') cp++;
141 sfile_len = cp - sfile;
142 if ((*cp) == ':') cp++;
143 sline = 0;
144 while ((*cp) != '\0' && isdigit(*cp)) {
145 sline *= 10;
146 sline += (*cp) - '0';
147 cp++;
148 }
149 // "file:line!" means the assert suppression is not silent
150 noisy = ((*cp) == '!');
151 while ((*cp) != '\0' && !is_token_break(*cp)) cp++;
152 // match the line
153 if (sline != 0) {
154 if (sline != line_no) continue;
155 }
156 // match the file
157 if (sfile_len > 0) {
158 const char* look = file_name;
159 const char* look_max = file_name + file_name_len - sfile_len;
160 const char* foundp;
161 bool match = false;
162 while (!match
163 && (foundp = strchr(look, sfile[0])) != NULL
164 && foundp <= look_max) {
165 match = true;
166 for (int i = 1; i < sfile_len; i++) {
167 if (sfile[i] != foundp[i]) {
168 match = false;
169 break;
170 }
171 }
172 look = foundp + 1;
173 }
174 if (!match) continue;
175 }
176 // got a match!
177 if (noisy) {
178 fdStream out(defaultStream::output_fd());
179 out.print_raw("[error suppressed at ");
180 out.print_raw(base_name);
181 char buf[16];
182 jio_snprintf(buf, sizeof(buf), ":%d]", line_no);
183 out.print_raw_cr(buf);
184 } else {
185 // update 1-element cache for fast silent matches
186 last_file_name = file_name;
187 last_line_no = line_no;
188 }
189 return true;
190 }
191
192 if (!VMError::is_error_reported() && !SuppressFatalErrorMessage) {
193 // print a friendly hint:
194 fdStream out(defaultStream::output_fd());
195 out.print_raw_cr("# To suppress the following error report, specify this argument");
196 out.print_raw ("# after -XX: or in .hotspotrc: SuppressErrorAt=");
197 out.print_raw (base_name);
198 char buf[16];
199 jio_snprintf(buf, sizeof(buf), ":%d", line_no);
200 out.print_raw_cr(buf);
201 }
202 return false;
203 }
204
205 #undef is_token_break
206
207 #else
208
209 // Place-holder for non-existent suppression check:
210 #define error_is_suppressed(file_name, line_no) (false)
211
212 #endif // !PRODUCT
213
report_vm_error(const char * file,int line,const char * error_msg)214 void report_vm_error(const char* file, int line, const char* error_msg)
215 {
216 report_vm_error(file, line, error_msg, "%s", "");
217 }
218
report_vm_error(const char * file,int line,const char * error_msg,const char * detail_fmt,...)219 void report_vm_error(const char* file, int line, const char* error_msg, const char* detail_fmt, ...)
220 {
221 if (Debugging || error_is_suppressed(file, line)) return;
222 va_list detail_args;
223 va_start(detail_args, detail_fmt);
224 void* context = NULL;
225 #ifdef CAN_SHOW_REGISTERS_ON_ASSERT
226 if (g_assertion_context != NULL && os::current_thread_id() == g_asserting_thread) {
227 context = g_assertion_context;
228 }
229 #endif // CAN_SHOW_REGISTERS_ON_ASSERT
230 VMError::report_and_die(Thread::current_or_null(), context, file, line, error_msg, detail_fmt, detail_args);
231 va_end(detail_args);
232 }
233
report_vm_status_error(const char * file,int line,const char * error_msg,int status,const char * detail)234 void report_vm_status_error(const char* file, int line, const char* error_msg,
235 int status, const char* detail) {
236 report_vm_error(file, line, error_msg, "error %s(%d), %s", os::errno_name(status), status, detail);
237 }
238
report_fatal(const char * file,int line,const char * detail_fmt,...)239 void report_fatal(const char* file, int line, const char* detail_fmt, ...)
240 {
241 if (Debugging || error_is_suppressed(file, line)) return;
242 va_list detail_args;
243 va_start(detail_args, detail_fmt);
244 void* context = NULL;
245 #ifdef CAN_SHOW_REGISTERS_ON_ASSERT
246 if (g_assertion_context != NULL && os::current_thread_id() == g_asserting_thread) {
247 context = g_assertion_context;
248 }
249 #endif // CAN_SHOW_REGISTERS_ON_ASSERT
250 VMError::report_and_die(Thread::current_or_null(), context, file, line, "fatal error", detail_fmt, detail_args);
251 va_end(detail_args);
252 }
253
report_vm_out_of_memory(const char * file,int line,size_t size,VMErrorType vm_err_type,const char * detail_fmt,...)254 void report_vm_out_of_memory(const char* file, int line, size_t size,
255 VMErrorType vm_err_type, const char* detail_fmt, ...) {
256 if (Debugging) return;
257 va_list detail_args;
258 va_start(detail_args, detail_fmt);
259 VMError::report_and_die(Thread::current_or_null(), file, line, size, vm_err_type, detail_fmt, detail_args);
260 va_end(detail_args);
261
262 // The UseOSErrorReporting option in report_and_die() may allow a return
263 // to here. If so then we'll have to figure out how to handle it.
264 guarantee(false, "report_and_die() should not return here");
265 }
266
report_should_not_call(const char * file,int line)267 void report_should_not_call(const char* file, int line) {
268 report_vm_error(file, line, "ShouldNotCall()");
269 }
270
report_should_not_reach_here(const char * file,int line)271 void report_should_not_reach_here(const char* file, int line) {
272 report_vm_error(file, line, "ShouldNotReachHere()");
273 }
274
report_unimplemented(const char * file,int line)275 void report_unimplemented(const char* file, int line) {
276 report_vm_error(file, line, "Unimplemented()");
277 }
278
279 #ifdef ASSERT
is_executing_unit_tests()280 bool is_executing_unit_tests() {
281 return ExecutingUnitTests;
282 }
283
report_assert_msg(const char * msg,...)284 void report_assert_msg(const char* msg, ...) {
285 va_list ap;
286 va_start(ap, msg);
287
288 fprintf(stderr, "assert failed: %s\n", err_msg(FormatBufferDummy(), msg, ap).buffer());
289
290 va_end(ap);
291 }
292 #endif // ASSERT
293
report_untested(const char * file,int line,const char * message)294 void report_untested(const char* file, int line, const char* message) {
295 #ifndef PRODUCT
296 warning("Untested: %s in %s: %d\n", message, file, line);
297 #endif // !PRODUCT
298 }
299
report_java_out_of_memory(const char * message)300 void report_java_out_of_memory(const char* message) {
301 static int out_of_memory_reported = 0;
302
303 // A number of threads may attempt to report OutOfMemoryError at around the
304 // same time. To avoid dumping the heap or executing the data collection
305 // commands multiple times we just do it once when the first threads reports
306 // the error.
307 if (Atomic::cmpxchg(1, &out_of_memory_reported, 0) == 0) {
308 // create heap dump before OnOutOfMemoryError commands are executed
309 if (HeapDumpOnOutOfMemoryError) {
310 tty->print_cr("java.lang.OutOfMemoryError: %s", message);
311 HeapDumper::dump_heap_from_oome();
312 }
313
314 if (OnOutOfMemoryError && OnOutOfMemoryError[0]) {
315 VMError::report_java_out_of_memory(message);
316 }
317
318 if (CrashOnOutOfMemoryError) {
319 tty->print_cr("Aborting due to java.lang.OutOfMemoryError: %s", message);
320 fatal("OutOfMemory encountered: %s", message);
321 }
322
323 if (ExitOnOutOfMemoryError) {
324 tty->print_cr("Terminating due to java.lang.OutOfMemoryError: %s", message);
325 os::exit(3);
326 }
327 }
328 }
329
330 // ------ helper functions for debugging go here ------------
331
332 // All debug entries should be wrapped with a stack allocated
333 // Command object. It makes sure a resource mark is set and
334 // flushes the logfile to prevent file sharing problems.
335
336 class Command : public StackObj {
337 private:
338 ResourceMark rm;
339 ResetNoHandleMark rnhm;
340 HandleMark hm;
341 bool debug_save;
342 public:
343 static int level;
Command(const char * str)344 Command(const char* str) {
345 debug_save = Debugging;
346 Debugging = true;
347 if (level++ > 0) return;
348 tty->cr();
349 tty->print_cr("\"Executing %s\"", str);
350 }
351
~Command()352 ~Command() {
353 tty->flush();
354 Debugging = debug_save;
355 level--;
356 }
357 };
358
359 int Command::level = 0;
360
361 #ifndef PRODUCT
362
blob(CodeBlob * cb)363 extern "C" void blob(CodeBlob* cb) {
364 Command c("blob");
365 cb->print();
366 }
367
368
dump_vtable(address p)369 extern "C" void dump_vtable(address p) {
370 Command c("dump_vtable");
371 Klass* k = (Klass*)p;
372 k->vtable().print();
373 }
374
375
nm(intptr_t p)376 extern "C" void nm(intptr_t p) {
377 // Actually we look through all CodeBlobs (the nm name has been kept for backwards compatability)
378 Command c("nm");
379 CodeBlob* cb = CodeCache::find_blob((address)p);
380 if (cb == NULL) {
381 tty->print_cr("NULL");
382 } else {
383 cb->print();
384 }
385 }
386
387
disnm(intptr_t p)388 extern "C" void disnm(intptr_t p) {
389 Command c("disnm");
390 CodeBlob* cb = CodeCache::find_blob((address) p);
391 if (cb != NULL) {
392 nmethod* nm = cb->as_nmethod_or_null();
393 if (nm != NULL) {
394 nm->print();
395 } else {
396 cb->print();
397 }
398 Disassembler::decode(cb);
399 }
400 }
401
402
printnm(intptr_t p)403 extern "C" void printnm(intptr_t p) {
404 char buffer[256];
405 sprintf(buffer, "printnm: " INTPTR_FORMAT, p);
406 Command c(buffer);
407 CodeBlob* cb = CodeCache::find_blob((address) p);
408 if (cb->is_nmethod()) {
409 nmethod* nm = (nmethod*)cb;
410 nm->print_nmethod(true);
411 }
412 }
413
414
universe()415 extern "C" void universe() {
416 Command c("universe");
417 Universe::print_on(tty);
418 }
419
420
verify()421 extern "C" void verify() {
422 // try to run a verify on the entire system
423 // note: this may not be safe if we're not at a safepoint; for debugging,
424 // this manipulates the safepoint settings to avoid assertion failures
425 Command c("universe verify");
426 bool safe = SafepointSynchronize::is_at_safepoint();
427 if (!safe) {
428 tty->print_cr("warning: not at safepoint -- verify may fail");
429 SafepointSynchronize::set_is_at_safepoint();
430 }
431 // Ensure Eden top is correct before verification
432 Universe::heap()->prepare_for_verify();
433 Universe::verify();
434 if (!safe) SafepointSynchronize::set_is_not_at_safepoint();
435 }
436
437
pp(void * p)438 extern "C" void pp(void* p) {
439 Command c("pp");
440 FlagSetting fl(PrintVMMessages, true);
441 FlagSetting f2(DisplayVMOutput, true);
442 if (Universe::heap()->is_in(p)) {
443 oop obj = oop(p);
444 obj->print();
445 } else {
446 tty->print(PTR_FORMAT, p2i(p));
447 }
448 }
449
450
451 // pv: print vm-printable object
pa(intptr_t p)452 extern "C" void pa(intptr_t p) { ((AllocatedObj*) p)->print(); }
453 extern "C" void findpc(intptr_t x);
454
455 #endif // !PRODUCT
456
ps()457 extern "C" void ps() { // print stack
458 if (Thread::current_or_null() == NULL) return;
459 Command c("ps");
460
461
462 // Prints the stack of the current Java thread
463 JavaThread* p = JavaThread::active();
464 tty->print(" for thread: ");
465 p->print();
466 tty->cr();
467
468 if (p->has_last_Java_frame()) {
469 // If the last_Java_fp is set we are in C land and
470 // can call the standard stack_trace function.
471 #ifdef PRODUCT
472 p->print_stack();
473 } else {
474 tty->print_cr("Cannot find the last Java frame, printing stack disabled.");
475 #else // !PRODUCT
476 p->trace_stack();
477 } else {
478 frame f = os::current_frame();
479 RegisterMap reg_map(p);
480 f = f.sender(®_map);
481 tty->print("(guessing starting frame id=" PTR_FORMAT " based on current fp)\n", p2i(f.id()));
482 p->trace_stack_from(vframe::new_vframe(&f, ®_map, p));
483 f.pd_ps();
484 #endif // PRODUCT
485 }
486
487 }
488
pfl()489 extern "C" void pfl() {
490 // print frame layout
491 Command c("pfl");
492 JavaThread* p = JavaThread::active();
493 tty->print(" for thread: ");
494 p->print();
495 tty->cr();
496 if (p->has_last_Java_frame()) {
497 p->print_frame_layout();
498 }
499 }
500
501 #ifndef PRODUCT
502
psf()503 extern "C" void psf() { // print stack frames
504 {
505 Command c("psf");
506 JavaThread* p = JavaThread::active();
507 tty->print(" for thread: ");
508 p->print();
509 tty->cr();
510 if (p->has_last_Java_frame()) {
511 p->trace_frames();
512 }
513 }
514 }
515
516
threads()517 extern "C" void threads() {
518 Command c("threads");
519 Threads::print(false, true);
520 }
521
522
psd()523 extern "C" void psd() {
524 Command c("psd");
525 SystemDictionary::print();
526 }
527
528 #endif // !PRODUCT
529
pss()530 extern "C" void pss() { // print all stacks
531 if (Thread::current_or_null() == NULL) return;
532 Command c("pss");
533 Threads::print(true, PRODUCT_ONLY(false) NOT_PRODUCT(true));
534 }
535
536 #ifndef PRODUCT
537
debug()538 extern "C" void debug() { // to set things up for compiler debugging
539 Command c("debug");
540 WizardMode = true;
541 PrintVMMessages = PrintCompilation = true;
542 PrintInlining = PrintAssembly = true;
543 tty->flush();
544 }
545
546
ndebug()547 extern "C" void ndebug() { // undo debug()
548 Command c("ndebug");
549 PrintCompilation = false;
550 PrintInlining = PrintAssembly = false;
551 tty->flush();
552 }
553
554
flush()555 extern "C" void flush() {
556 Command c("flush");
557 tty->flush();
558 }
559
events()560 extern "C" void events() {
561 Command c("events");
562 Events::print();
563 }
564
findm(intptr_t pc)565 extern "C" Method* findm(intptr_t pc) {
566 Command c("findm");
567 nmethod* nm = CodeCache::find_nmethod((address)pc);
568 return (nm == NULL) ? (Method*)NULL : nm->method();
569 }
570
571
findnm(intptr_t addr)572 extern "C" nmethod* findnm(intptr_t addr) {
573 Command c("findnm");
574 return CodeCache::find_nmethod((address)addr);
575 }
576
577 // Another interface that isn't ambiguous in dbx.
578 // Can we someday rename the other find to hsfind?
hsfind(intptr_t x)579 extern "C" void hsfind(intptr_t x) {
580 Command c("hsfind");
581 os::print_location(tty, x, false);
582 }
583
584
find(intptr_t x)585 extern "C" void find(intptr_t x) {
586 Command c("find");
587 os::print_location(tty, x, false);
588 }
589
590
findpc(intptr_t x)591 extern "C" void findpc(intptr_t x) {
592 Command c("findpc");
593 os::print_location(tty, x, true);
594 }
595
596
597 // Need method pointer to find bcp, when not in permgen.
findbcp(intptr_t method,intptr_t bcp)598 extern "C" void findbcp(intptr_t method, intptr_t bcp) {
599 Command c("findbcp");
600 Method* mh = (Method*)method;
601 if (!mh->is_native()) {
602 tty->print_cr("bci_from(%p) = %d; print_codes():",
603 mh, mh->bci_from(address(bcp)));
604 mh->print_codes_on(tty);
605 }
606 }
607
608 // int versions of all methods to avoid having to type type casts in the debugger
609
pp(intptr_t p)610 void pp(intptr_t p) { pp((void*)p); }
pp(oop p)611 void pp(oop p) { pp((void*)p); }
612
help()613 void help() {
614 Command c("help");
615 tty->print_cr("basic");
616 tty->print_cr(" pp(void* p) - try to make sense of p");
617 tty->print_cr(" pv(intptr_t p)- ((PrintableResourceObj*) p)->print()");
618 tty->print_cr(" ps() - print current thread stack");
619 tty->print_cr(" pss() - print all thread stacks");
620 tty->print_cr(" pm(int pc) - print Method* given compiled PC");
621 tty->print_cr(" findm(intptr_t pc) - finds Method*");
622 tty->print_cr(" find(intptr_t x) - finds & prints nmethod/stub/bytecode/oop based on pointer into it");
623 tty->print_cr(" pns(void* sp, void* fp, void* pc) - print native (i.e. mixed) stack trace. E.g.");
624 tty->print_cr(" pns($sp, $rbp, $pc) on Linux/amd64 and Solaris/amd64 or");
625 tty->print_cr(" pns($sp, $ebp, $pc) on Linux/x86 or");
626 tty->print_cr(" pns($sp, 0, $pc) on Linux/ppc64 or");
627 tty->print_cr(" pns($sp + 0x7ff, 0, $pc) on Solaris/SPARC");
628 tty->print_cr(" - in gdb do 'set overload-resolution off' before calling pns()");
629 tty->print_cr(" - in dbx do 'frame 1' before calling pns()");
630
631 tty->print_cr("misc.");
632 tty->print_cr(" flush() - flushes the log file");
633 tty->print_cr(" events() - dump events from ring buffers");
634
635
636 tty->print_cr("compiler debugging");
637 tty->print_cr(" debug() - to set things up for compiler debugging");
638 tty->print_cr(" ndebug() - undo debug");
639 }
640
pns(void * sp,void * fp,void * pc)641 extern "C" void pns(void* sp, void* fp, void* pc) { // print native stack
642 Command c("pns");
643 static char buf[O_BUFLEN];
644 Thread* t = Thread::current_or_null();
645 // Call generic frame constructor (certain arguments may be ignored)
646 frame fr(sp, fp, pc);
647 VMError::print_native_stack(tty, fr, t, buf, sizeof(buf));
648 }
649
650 //
651 // This version of pns() will not work when called from the debugger, but is
652 // useful when called from within hotspot code. The advantages over pns()
653 // are not having to pass in any arguments, and it will work on Windows/x64.
654 //
655 // WARNING: Only intended for use when debugging. Do not leave calls to
656 // pns2() in committed source (product or debug).
657 //
pns2()658 extern "C" void pns2() { // print native stack
659 Command c("pns2");
660 static char buf[O_BUFLEN];
661 if (os::platform_print_native_stack(tty, NULL, buf, sizeof(buf))) {
662 // We have printed the native stack in platform-specific code,
663 // so nothing else to do in this case.
664 } else {
665 Thread* t = Thread::current_or_null();
666 frame fr = os::current_frame();
667 VMError::print_native_stack(tty, fr, t, buf, sizeof(buf));
668 }
669 }
670
671 #endif // !PRODUCT
672
673 //////////////////////////////////////////////////////////////////////////////
674 // Test multiple STATIC_ASSERT forms in various scopes.
675
676 #ifndef PRODUCT
677
678 // namespace scope
679 STATIC_ASSERT(true);
680 STATIC_ASSERT(true);
681 STATIC_ASSERT(1 == 1);
682 STATIC_ASSERT(0 == 0);
683
test_multiple_static_assert_forms_in_function_scope()684 void test_multiple_static_assert_forms_in_function_scope() {
685 STATIC_ASSERT(true);
686 STATIC_ASSERT(true);
687 STATIC_ASSERT(0 == 0);
688 STATIC_ASSERT(1 == 1);
689 }
690
691 // class scope
692 struct TestMultipleStaticAssertFormsInClassScope {
693 STATIC_ASSERT(true);
694 STATIC_ASSERT(true);
695 STATIC_ASSERT(0 == 0);
696 STATIC_ASSERT(1 == 1);
697 };
698
699 #endif // !PRODUCT
700
701 // Support for showing register content on asserts/guarantees.
702 #ifdef CAN_SHOW_REGISTERS_ON_ASSERT
703
704 static ucontext_t g_stored_assertion_context;
705
initialize_assert_poison()706 void initialize_assert_poison() {
707 char* page = os::reserve_memory(os::vm_page_size());
708 if (page) {
709 if (os::commit_memory(page, os::vm_page_size(), false) &&
710 os::protect_memory(page, os::vm_page_size(), os::MEM_PROT_NONE)) {
711 g_assert_poison = page;
712 }
713 }
714 }
715
store_context(const void * context)716 static void store_context(const void* context) {
717 memcpy(&g_stored_assertion_context, context, sizeof(ucontext_t));
718 #if defined(__linux) && defined(PPC64)
719 // on Linux ppc64, ucontext_t contains pointers into itself which have to be patched up
720 // after copying the context (see comment in sys/ucontext.h):
721 *((void**) &g_stored_assertion_context.uc_mcontext.regs) = &(g_stored_assertion_context.uc_mcontext.gp_regs);
722 #endif
723 }
724
handle_assert_poison_fault(const void * ucVoid,const void * faulting_address)725 bool handle_assert_poison_fault(const void* ucVoid, const void* faulting_address) {
726 if (faulting_address == g_assert_poison) {
727 // Disarm poison page.
728 os::protect_memory((char*)g_assert_poison, os::vm_page_size(), os::MEM_PROT_RWX);
729 // Store Context away.
730 if (ucVoid) {
731 const intx my_tid = os::current_thread_id();
732 if (Atomic::cmpxchg(my_tid, &g_asserting_thread, (intx)0) == 0) {
733 store_context(ucVoid);
734 g_assertion_context = &g_stored_assertion_context;
735 }
736 }
737 return true;
738 }
739 return false;
740 }
741 #endif // CAN_SHOW_REGISTERS_ON_ASSERT
742
743