1/*
2 * Copyright (c) 1997, 2017, 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#ifndef SHARE_VM_UTILITIES_DEBUG_HPP
26#define SHARE_VM_UTILITIES_DEBUG_HPP
27
28#include "utilities/breakpoint.hpp"
29#include "utilities/compilerWarnings.hpp"
30#include "utilities/macros.hpp"
31
32#include <stddef.h>
33
34// assertions
35#ifndef ASSERT
36#define vmassert(p, ...)
37#else
38// Note: message says "assert" rather than "vmassert" for backward
39// compatibility with tools that parse/match the message text.
40// Note: The signature is vmassert(p, format, ...), but the solaris
41// compiler can't handle an empty ellipsis in a macro without a warning.
42#define vmassert(p, ...)                                                       \
43do {                                                                           \
44  if (!(p)) {                                                                  \
45    if (is_executing_unit_tests()) {                                           \
46      report_assert_msg(__VA_ARGS__);                                          \
47    }                                                                          \
48    report_vm_error(__FILE__, __LINE__, "assert(" #p ") failed", __VA_ARGS__); \
49    BREAKPOINT;                                                                \
50  }                                                                            \
51} while (0)
52#endif
53
54// For backward compatibility.
55#define assert(p, ...) vmassert(p, __VA_ARGS__)
56
57#ifndef ASSERT
58#define vmassert_status(p, status, msg)
59#else
60// This version of vmassert is for use with checking return status from
61// library calls that return actual error values eg. EINVAL,
62// ENOMEM etc, rather than returning -1 and setting errno.
63// When the status is not what is expected it is very useful to know
64// what status was actually returned, so we pass the status variable as
65// an extra arg and use strerror to convert it to a meaningful string
66// like "Invalid argument", "out of memory" etc
67#define vmassert_status(p, status, msg) \
68do {                                                                           \
69  if (!(p)) {                                                                  \
70    report_vm_status_error(__FILE__, __LINE__, "assert(" #p ") failed",        \
71                           status, msg);                                       \
72    BREAKPOINT;                                                                \
73  }                                                                            \
74} while (0)
75#endif
76
77// For backward compatibility.
78#define assert_status(p, status, msg) vmassert_status(p, status, msg)
79
80// guarantee is like vmassert except it's always executed -- use it for
81// cheap tests that catch errors that would otherwise be hard to find.
82// guarantee is also used for Verify options.
83#define guarantee(p, ...)                                                         \
84do {                                                                              \
85  if (!(p)) {                                                                     \
86    report_vm_error(__FILE__, __LINE__, "guarantee(" #p ") failed", __VA_ARGS__); \
87    BREAKPOINT;                                                                   \
88  }                                                                               \
89} while (0)
90
91#define fatal(...)                                                                \
92do {                                                                              \
93  report_fatal(__FILE__, __LINE__, __VA_ARGS__);                                  \
94  BREAKPOINT;                                                                     \
95} while (0)
96
97// out of memory
98#define vm_exit_out_of_memory(size, vm_err_type, ...)                             \
99do {                                                                              \
100  report_vm_out_of_memory(__FILE__, __LINE__, size, vm_err_type, __VA_ARGS__);    \
101  BREAKPOINT;                                                                     \
102} while (0)
103
104#define ShouldNotCallThis()                                                       \
105do {                                                                              \
106  report_should_not_call(__FILE__, __LINE__);                                     \
107  BREAKPOINT;                                                                     \
108} while (0)
109
110#define ShouldNotReachHere()                                                      \
111do {                                                                              \
112  report_should_not_reach_here(__FILE__, __LINE__);                               \
113  BREAKPOINT;                                                                     \
114} while (0)
115
116#define Unimplemented()                                                           \
117do {                                                                              \
118  report_unimplemented(__FILE__, __LINE__);                                       \
119  BREAKPOINT;                                                                     \
120} while (0)
121
122#define Untested(msg)                                                             \
123do {                                                                              \
124  report_untested(__FILE__, __LINE__, msg);                                       \
125  BREAKPOINT;                                                                     \
126} while (0);
127
128
129// types of VM error - originally in vmError.hpp
130enum VMErrorType {
131  INTERNAL_ERROR   = 0xe0000000,
132  OOM_MALLOC_ERROR = 0xe0000001,
133  OOM_MMAP_ERROR   = 0xe0000002
134};
135
136// error reporting helper functions
137void report_vm_error(const char* file, int line, const char* error_msg);
138#if !defined(__GNUC__) || defined (__clang_major__) || (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || __GNUC__ > 4)
139// ATTRIBUTE_PRINTF works with gcc >= 4.8 and any other compiler.
140void report_vm_error(const char* file, int line, const char* error_msg,
141                     const char* detail_fmt, ...) ATTRIBUTE_PRINTF(4, 5);
142#ifdef ASSERT
143void report_assert_msg(const char* msg, ...) ATTRIBUTE_PRINTF(1, 2);
144#endif // ASSERT
145#else
146// GCC < 4.8 warns because of empty format string.  Warning can not be switched off selectively.
147void report_vm_error(const char* file, int line, const char* error_msg,
148                     const char* detail_fmt, ...);
149#ifdef ASSERT
150void report_assert_msg(const char* msg, ...);
151#endif // ASSERT
152#endif
153void report_vm_status_error(const char* file, int line, const char* error_msg,
154                            int status, const char* detail);
155void report_fatal(const char* file, int line, const char* detail_fmt, ...) ATTRIBUTE_PRINTF(3, 4);
156void report_vm_out_of_memory(const char* file, int line, size_t size, VMErrorType vm_err_type,
157                             const char* detail_fmt, ...) ATTRIBUTE_PRINTF(5, 6);
158void report_should_not_call(const char* file, int line);
159void report_should_not_reach_here(const char* file, int line);
160void report_unimplemented(const char* file, int line);
161void report_untested(const char* file, int line, const char* message);
162
163#ifdef ASSERT
164// unit test support
165bool is_executing_unit_tests();
166#endif // ASSERT
167
168void warning(const char* format, ...) ATTRIBUTE_PRINTF(1, 2);
169
170// Compile-time asserts.  Cond must be a compile-time constant expression that
171// is convertible to bool.  STATIC_ASSERT() can be used anywhere a declaration
172// may appear.
173//
174// Implementation Note: STATIC_ASSERT_FAILURE<true> provides a value member
175// rather than type member that could be used directly in the typedef, because
176// a type member would require conditional use of "typename", depending on
177// whether Cond is dependent or not.  The use of a value member leads to the
178// use of an array type.
179
180template<bool x> struct STATIC_ASSERT_FAILURE;
181template<> struct STATIC_ASSERT_FAILURE<true> { enum { value = 1 }; };
182
183#define STATIC_ASSERT(Cond) \
184  typedef char PASTE_TOKENS(STATIC_ASSERT_DUMMY_TYPE_, __LINE__)[ \
185    STATIC_ASSERT_FAILURE< (Cond) >::value ]
186
187// out of memory reporting
188void report_java_out_of_memory(const char* message);
189
190#endif // SHARE_VM_UTILITIES_DEBUG_HPP
191