8303805: [REDO] JDK-8302189 and JDK-8302799
Reviewed-by: dholmes, coleenp
This commit is contained in:
parent
b524a74165
commit
b3ff8d1c89
@ -100,7 +100,7 @@ endif
|
||||
|
||||
DISABLED_WARNINGS_xlc := tautological-compare shift-negative-value
|
||||
|
||||
DISABLED_WARNINGS_microsoft := 4624 4244 4291 4146 4127
|
||||
DISABLED_WARNINGS_microsoft := 4624 4244 4291 4146 4127 4722
|
||||
|
||||
################################################################################
|
||||
# Platform specific setup
|
||||
|
@ -42,7 +42,6 @@
|
||||
#include "oops/klass.inline.hpp"
|
||||
#include "prims/methodHandles.hpp"
|
||||
#include "runtime/continuation.hpp"
|
||||
#include "runtime/flags/flagSetting.hpp"
|
||||
#include "runtime/interfaceSupport.inline.hpp"
|
||||
#include "runtime/javaThread.hpp"
|
||||
#include "runtime/jniHandles.hpp"
|
||||
@ -403,7 +402,7 @@ void MacroAssembler::debug32(int rdi, int rsi, int rbp, int rsp, int rbx, int rd
|
||||
|
||||
void MacroAssembler::print_state32(int rdi, int rsi, int rbp, int rsp, int rbx, int rdx, int rcx, int rax, int eip) {
|
||||
ttyLocker ttyl;
|
||||
FlagSetting fs(Debugging, true);
|
||||
DebuggingContext debugging{};
|
||||
tty->print_cr("eip = 0x%08x", eip);
|
||||
#ifndef PRODUCT
|
||||
if ((WizardMode || Verbose) && PrintMiscellaneous) {
|
||||
@ -832,7 +831,7 @@ void MacroAssembler::debug64(char* msg, int64_t pc, int64_t regs[]) {
|
||||
|
||||
void MacroAssembler::print_state64(int64_t pc, int64_t regs[]) {
|
||||
ttyLocker ttyl;
|
||||
FlagSetting fs(Debugging, true);
|
||||
DebuggingContext debugging{};
|
||||
tty->print_cr("rip = 0x%016lx", (intptr_t)pc);
|
||||
#ifndef PRODUCT
|
||||
tty->cr();
|
||||
|
@ -628,7 +628,9 @@ HeapWord* ParallelScavengeHeap::block_start(const void* addr) const {
|
||||
assert(young_gen()->is_in(addr),
|
||||
"addr should be in allocated part of young gen");
|
||||
// called from os::print_location by find or VMError
|
||||
if (Debugging || VMError::is_error_reported()) return nullptr;
|
||||
if (DebuggingContext::is_enabled() || VMError::is_error_reported()) {
|
||||
return nullptr;
|
||||
}
|
||||
Unimplemented();
|
||||
} else if (old_gen()->is_in_reserved(addr)) {
|
||||
assert(old_gen()->is_in(addr),
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -209,7 +209,7 @@ namespace AccessInternal {
|
||||
|
||||
#ifdef ASSERT
|
||||
void check_access_thread_state() {
|
||||
if (VMError::is_error_reported() || Debugging) {
|
||||
if (VMError::is_error_reported() || DebuggingContext::is_enabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -376,6 +376,9 @@ void JavaThread::check_possible_safepoint() {
|
||||
}
|
||||
|
||||
void JavaThread::check_for_valid_safepoint_state() {
|
||||
// Don't complain if running a debugging command.
|
||||
if (DebuggingContext::is_enabled()) return;
|
||||
|
||||
// Check NoSafepointVerifier, which is implied by locks taken that can be
|
||||
// shared with the VM thread. This makes sure that no locks with allow_vm_block
|
||||
// are held.
|
||||
|
@ -165,6 +165,7 @@ static int _num_mutex;
|
||||
|
||||
#ifdef ASSERT
|
||||
void assert_locked_or_safepoint(const Mutex* lock) {
|
||||
if (DebuggingContext::is_enabled()) return;
|
||||
// check if this thread owns the lock (common case)
|
||||
assert(lock != nullptr, "Need non-null lock");
|
||||
if (lock->owned_by_self()) return;
|
||||
@ -175,6 +176,7 @@ void assert_locked_or_safepoint(const Mutex* lock) {
|
||||
|
||||
// a weaker assertion than the above
|
||||
void assert_locked_or_safepoint_weak(const Mutex* lock) {
|
||||
if (DebuggingContext::is_enabled()) return;
|
||||
assert(lock != nullptr, "Need non-null lock");
|
||||
if (lock->is_locked()) return;
|
||||
if (SafepointSynchronize::is_at_safepoint()) return;
|
||||
@ -184,6 +186,7 @@ void assert_locked_or_safepoint_weak(const Mutex* lock) {
|
||||
|
||||
// a stronger assertion than the above
|
||||
void assert_lock_strong(const Mutex* lock) {
|
||||
if (DebuggingContext::is_enabled()) return;
|
||||
assert(lock != nullptr, "Need non-null lock");
|
||||
if (lock->owned_by_self()) return;
|
||||
fatal("must own lock %s", lock->name());
|
||||
|
@ -576,7 +576,7 @@ class os: AllStatic {
|
||||
// multiple calls to naked_short_sleep. Only for use by non-JavaThreads.
|
||||
static void naked_sleep(jlong millis);
|
||||
// Never returns, use with CAUTION
|
||||
[[noreturn]] static void infinite_sleep();
|
||||
ATTRIBUTE_NORETURN static void infinite_sleep();
|
||||
static void naked_yield () ;
|
||||
static OSReturn set_priority(Thread* thread, ThreadPriority priority);
|
||||
static OSReturn get_priority(const Thread* const thread, ThreadPriority& priority);
|
||||
@ -601,26 +601,26 @@ class os: AllStatic {
|
||||
static int fork_and_exec(const char *cmd);
|
||||
|
||||
// Call ::exit() on all platforms
|
||||
[[noreturn]] static void exit(int num);
|
||||
ATTRIBUTE_NORETURN static void exit(int num);
|
||||
|
||||
// Call ::_exit() on all platforms. Similar semantics to die() except we never
|
||||
// want a core dump.
|
||||
[[noreturn]] static void _exit(int num);
|
||||
ATTRIBUTE_NORETURN static void _exit(int num);
|
||||
|
||||
// Terminate the VM, but don't exit the process
|
||||
static void shutdown();
|
||||
|
||||
// Terminate with an error. Default is to generate a core file on platforms
|
||||
// that support such things. This calls shutdown() and then aborts.
|
||||
[[noreturn]] static void abort(bool dump_core, void *siginfo, const void *context);
|
||||
[[noreturn]] static void abort(bool dump_core = true);
|
||||
ATTRIBUTE_NORETURN static void abort(bool dump_core, void *siginfo, const void *context);
|
||||
ATTRIBUTE_NORETURN static void abort(bool dump_core = true);
|
||||
|
||||
// Die immediately, no exit hook, no abort hook, no cleanup.
|
||||
// Dump a core file, if possible, for debugging. os::abort() is the
|
||||
// preferred means to abort the VM on error. os::die() should only
|
||||
// be called if something has gone badly wrong. CreateCoredumpOnCrash
|
||||
// is intentionally not honored by this function.
|
||||
[[noreturn]] static void die();
|
||||
ATTRIBUTE_NORETURN static void die();
|
||||
|
||||
// File i/o operations
|
||||
static int open(const char *path, int oflag, int mode);
|
||||
|
50
src/hotspot/share/utilities/attributeNoreturn.hpp
Normal file
50
src/hotspot/share/utilities/attributeNoreturn.hpp
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SHARE_UTILITY_ATTRIBUTENORETURN_HPP
|
||||
#define SHARE_UTILITY_ATTRIBUTENORETURN_HPP
|
||||
|
||||
// Provide a (temporary) macro for the [[noreturn]] attribute.
|
||||
//
|
||||
// Unfortunately, some older (though still in use) compilers have bugs when
|
||||
// using [[noreturn]]. For them we use an empty definition for the attribute.
|
||||
//
|
||||
// Note: This can't be placed in globalDefinitions_xxx.hpp because the
|
||||
// attribute is used in debug.hpp, which can't include globalDefinitions.hpp.
|
||||
|
||||
// clang 12 (and possibly prior) crashes during build if we use [[noreturn]]
|
||||
// for assertion failure reporting functions. The problem seems to be fixed
|
||||
// in clang 13.
|
||||
#ifdef __clang__
|
||||
#if __clang_major__ < 13
|
||||
#define ATTRIBUTE_NORETURN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// All other platforms can use [[noreturn]].
|
||||
#ifndef ATTRIBUTE_NORETURN
|
||||
#define ATTRIBUTE_NORETURN [[noreturn]]
|
||||
#endif
|
||||
|
||||
#endif // SHARE_UTILITY_ATTRIBUTENORETURN_HPP
|
@ -76,8 +76,19 @@ static intx g_asserting_thread = 0;
|
||||
static void* g_assertion_context = nullptr;
|
||||
#endif // CAN_SHOW_REGISTERS_ON_ASSERT
|
||||
|
||||
// Set to suppress secondary error reporting.
|
||||
bool Debugging = false;
|
||||
int DebuggingContext::_enabled = 0; // Initially disabled.
|
||||
|
||||
DebuggingContext::DebuggingContext() {
|
||||
_enabled += 1; // Increase nesting count.
|
||||
}
|
||||
|
||||
DebuggingContext::~DebuggingContext() {
|
||||
if (is_enabled()) {
|
||||
_enabled -= 1; // Decrease nesting count.
|
||||
} else {
|
||||
fatal("Debugging nesting confusion");
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef ASSERT
|
||||
# ifdef _DEBUG
|
||||
@ -166,7 +177,6 @@ static void print_error_for_unit_test(const char* message, const char* detail_fm
|
||||
|
||||
void report_vm_error(const char* file, int line, const char* error_msg, const char* detail_fmt, ...)
|
||||
{
|
||||
if (Debugging) return;
|
||||
va_list detail_args;
|
||||
va_start(detail_args, detail_fmt);
|
||||
void* context = nullptr;
|
||||
@ -188,7 +198,6 @@ void report_vm_status_error(const char* file, int line, const char* error_msg,
|
||||
}
|
||||
|
||||
void report_fatal(VMErrorType error_type, const char* file, int line, const char* detail_fmt, ...) {
|
||||
if (Debugging) return;
|
||||
va_list detail_args;
|
||||
va_start(detail_args, detail_fmt);
|
||||
void* context = nullptr;
|
||||
@ -208,7 +217,6 @@ void report_fatal(VMErrorType error_type, const char* file, int line, const char
|
||||
|
||||
void report_vm_out_of_memory(const char* file, int line, size_t size,
|
||||
VMErrorType vm_err_type, const char* detail_fmt, ...) {
|
||||
if (Debugging) return;
|
||||
va_list detail_args;
|
||||
va_start(detail_args, detail_fmt);
|
||||
|
||||
@ -278,13 +286,11 @@ void report_java_out_of_memory(const char* message) {
|
||||
|
||||
class Command : public StackObj {
|
||||
private:
|
||||
ResourceMark rm;
|
||||
bool debug_save;
|
||||
ResourceMark _rm;
|
||||
DebuggingContext _debugging;
|
||||
public:
|
||||
static int level;
|
||||
Command(const char* str) {
|
||||
debug_save = Debugging;
|
||||
Debugging = true;
|
||||
if (level++ > 0) return;
|
||||
tty->cr();
|
||||
tty->print_cr("\"Executing %s\"", str);
|
||||
@ -292,7 +298,6 @@ class Command : public StackObj {
|
||||
|
||||
~Command() {
|
||||
tty->flush();
|
||||
Debugging = debug_save;
|
||||
level--;
|
||||
}
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,6 +25,7 @@
|
||||
#ifndef SHARE_UTILITIES_DEBUG_HPP
|
||||
#define SHARE_UTILITIES_DEBUG_HPP
|
||||
|
||||
#include "utilities/attributeNoreturn.hpp"
|
||||
#include "utilities/breakpoint.hpp"
|
||||
#include "utilities/compilerWarnings.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
@ -46,6 +47,98 @@ bool handle_assert_poison_fault(const void* ucVoid, const void* faulting_address
|
||||
#define TOUCH_ASSERT_POISON
|
||||
#endif // CAN_SHOW_REGISTERS_ON_ASSERT
|
||||
|
||||
// The DebuggingContext class provides a mechanism for temporarily disabling
|
||||
// asserts and various consistency checks. Ordinarily that would be a really
|
||||
// bad idea, but it's essential for some of the debugging commands provided by
|
||||
// HotSpot. (See the Command class in debug.cpp.) These commands are intended
|
||||
// to be invoked from the debugger while the program is otherwise stopped.
|
||||
// The commands may invoke operations while the program is in a state where
|
||||
// those operations are not normally permitted, with the state checked by an
|
||||
// assert. We want the debugging commands to bypass those checks.
|
||||
class DebuggingContext {
|
||||
static int _enabled; // Nesting counter.
|
||||
|
||||
public:
|
||||
DebuggingContext();
|
||||
~DebuggingContext();
|
||||
// Asserts and other code use this to determine whether to bypass checks
|
||||
// that would otherwise lead to program termination.
|
||||
static bool is_enabled() { return _enabled > 0; }
|
||||
};
|
||||
|
||||
// VMASSERT_CHECK_PASSED(P) provides the mechanism by which DebuggingContext
|
||||
// disables asserts. It returns true if P is true or DebuggingContext is
|
||||
// enabled. Assertion failure is reported if it returns false, terminating
|
||||
// the program.
|
||||
//
|
||||
// The DebuggingContext check being enabled isn't placed inside the report
|
||||
// function, as that would prevent the report function from being noreturn.
|
||||
// The report function should be noreturn so there isn't a control path to the
|
||||
// assertion's continuation that has P being false. Otherwise, the compiler
|
||||
// might logically split the continuation to include that path explicitly,
|
||||
// possibly leading to discovering (and warning about) invalid code. For
|
||||
// example, if P := x != nullptr, and the continuation contains a dereference
|
||||
// of x, the compiler might warn because there is a control path (!P -> report
|
||||
// -> continuation) where that dereference is known to be invalid. (Of
|
||||
// course, if execution actually took that path things would go wrong, but
|
||||
// that's the risk the DebuggingContext mechanism takes.)
|
||||
//
|
||||
// Similarly, the check for enabled DebuggingContext shouldn't follow P.
|
||||
// Having this macro expand to `P || DebuggingContext::is_enabled()` has the
|
||||
// same problem of a control path through !P to the assertion's continuation.
|
||||
//
|
||||
// But it can't be just `DebuggingContext::is_enabled() || P` either. That
|
||||
// prevents the compiler from inferring based on P that it is true in the
|
||||
// continuation. But it also prevents the use of assertions in constexpr
|
||||
// contexts, since that expression is not constexpr.
|
||||
//
|
||||
// We could accomodate constexpr usage with std::is_constant_evaluated() (from
|
||||
// C++20). Unfortunately, we don't currently support C++20. However, most
|
||||
// supported compilers have implemented it, and that implementation uses a
|
||||
// compiler intrinsic that we can use directly without otherwise using C++20.
|
||||
//
|
||||
// Note that if we could use std::is_constant_evaluated() then we could just
|
||||
// use this definition for DebuggingContext::is_enabled:
|
||||
// static constexpr bool is_enabled() {
|
||||
// return !std::is_constant_evaluated() && _enabled;
|
||||
// }
|
||||
// The idea being that we are definitely not executing for debugging if doing
|
||||
// constant evaluation in the compiler. We don't do something like that now,
|
||||
// because we need a fallback when we don't have any mechanism for detecting
|
||||
// constant evaluation.
|
||||
#if defined(TARGET_COMPILER_gcc) || defined(TARGET_COMPILER_xlc)
|
||||
|
||||
// gcc10 added both __has_builtin and __builtin_is_constant_evaluated.
|
||||
// clang has had __has_builtin for a long time, so likely also in xlclang++.
|
||||
// Similarly, clang has had __builtin_is_constant_evaluated for a long time.
|
||||
|
||||
#ifdef __has_builtin
|
||||
#if __has_builtin(__builtin_is_constant_evaluated)
|
||||
#define VMASSERT_CHECK_PASSED(p) \
|
||||
((! __builtin_is_constant_evaluated() && DebuggingContext::is_enabled()) || (p))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#elif defined(TARGET_COMPILER_visCPP)
|
||||
|
||||
// std::is_constant_evaluated() and it's associated intrinsic are available in
|
||||
// VS 2019 16.5. The minimum supported version of VS 2019 is already past
|
||||
// that, so we can rely on the intrinsic being available.
|
||||
#define VMASSERT_CHECK_PASSED(p) \
|
||||
((! __builtin_is_constant_evaluated() && DebuggingContext::is_enabled()) || (p))
|
||||
|
||||
#endif // End dispatch on TARGET_COMPILER_xxx
|
||||
|
||||
// If we don't have a way to detect constant evaluation, then fall back to the
|
||||
// less than ideal form of the check, and hope it works. This succeeds at
|
||||
// least for gcc. The support needed to use the above definition was added in
|
||||
// gcc10. The problems arising from analyzing the failed P case don't seem to
|
||||
// appear until gcc12. An alternative is to not provide DebuggingContext
|
||||
// support for such a configuration.
|
||||
#ifndef VMASSERT_CHECK_PASSED
|
||||
#define VMASSERT_CHECK_PASSED(p) ((p) || DebuggingContext::is_enabled())
|
||||
#endif
|
||||
|
||||
// assertions
|
||||
#ifndef ASSERT
|
||||
#define vmassert(p, ...)
|
||||
@ -56,10 +149,9 @@ bool handle_assert_poison_fault(const void* ucVoid, const void* faulting_address
|
||||
// compiler can't handle an empty ellipsis in a macro without a warning.
|
||||
#define vmassert(p, ...) \
|
||||
do { \
|
||||
if (!(p)) { \
|
||||
if (! VMASSERT_CHECK_PASSED(p)) { \
|
||||
TOUCH_ASSERT_POISON; \
|
||||
report_vm_error(__FILE__, __LINE__, "assert(" #p ") failed", __VA_ARGS__); \
|
||||
BREAKPOINT; \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
@ -82,14 +174,13 @@ do { \
|
||||
// like "Invalid argument", "out of memory" etc
|
||||
#define vmassert_status(p, status, msg) \
|
||||
do { \
|
||||
if (!(p)) { \
|
||||
if (! VMASSERT_CHECK_PASSED(p)) { \
|
||||
TOUCH_ASSERT_POISON; \
|
||||
report_vm_status_error(__FILE__, __LINE__, "assert(" #p ") failed", \
|
||||
status, msg); \
|
||||
BREAKPOINT; \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
#endif // ASSERT
|
||||
|
||||
// For backward compatibility.
|
||||
#define assert_status(p, status, msg) vmassert_status(p, status, msg)
|
||||
@ -97,12 +188,12 @@ do { \
|
||||
// guarantee is like vmassert except it's always executed -- use it for
|
||||
// cheap tests that catch errors that would otherwise be hard to find.
|
||||
// guarantee is also used for Verify options.
|
||||
// guarantee is not subject to DebuggingContext bypass.
|
||||
#define guarantee(p, ...) \
|
||||
do { \
|
||||
if (!(p)) { \
|
||||
TOUCH_ASSERT_POISON; \
|
||||
report_vm_error(__FILE__, __LINE__, "guarantee(" #p ") failed", __VA_ARGS__); \
|
||||
BREAKPOINT; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
@ -110,35 +201,30 @@ do {
|
||||
do { \
|
||||
TOUCH_ASSERT_POISON; \
|
||||
report_fatal(INTERNAL_ERROR, __FILE__, __LINE__, __VA_ARGS__); \
|
||||
BREAKPOINT; \
|
||||
} while (0)
|
||||
|
||||
// out of memory
|
||||
#define vm_exit_out_of_memory(size, vm_err_type, ...) \
|
||||
do { \
|
||||
report_vm_out_of_memory(__FILE__, __LINE__, size, vm_err_type, __VA_ARGS__); \
|
||||
BREAKPOINT; \
|
||||
} while (0)
|
||||
|
||||
#define ShouldNotCallThis() \
|
||||
do { \
|
||||
TOUCH_ASSERT_POISON; \
|
||||
report_should_not_call(__FILE__, __LINE__); \
|
||||
BREAKPOINT; \
|
||||
} while (0)
|
||||
|
||||
#define ShouldNotReachHere() \
|
||||
do { \
|
||||
TOUCH_ASSERT_POISON; \
|
||||
report_should_not_reach_here(__FILE__, __LINE__); \
|
||||
BREAKPOINT; \
|
||||
} while (0)
|
||||
|
||||
#define Unimplemented() \
|
||||
do { \
|
||||
TOUCH_ASSERT_POISON; \
|
||||
report_unimplemented(__FILE__, __LINE__); \
|
||||
BREAKPOINT; \
|
||||
} while (0)
|
||||
|
||||
#define Untested(msg) \
|
||||
@ -157,25 +243,37 @@ enum VMErrorType {
|
||||
OOM_JAVA_HEAP_FATAL = 0xe0000004
|
||||
};
|
||||
|
||||
// Set to suppress secondary error reporting.
|
||||
// Really should have a qualified name or something.
|
||||
extern bool Debugging;
|
||||
|
||||
// error reporting helper functions
|
||||
ATTRIBUTE_NORETURN
|
||||
void report_vm_error(const char* file, int line, const char* error_msg);
|
||||
|
||||
ATTRIBUTE_NORETURN
|
||||
ATTRIBUTE_PRINTF(4, 5)
|
||||
void report_vm_error(const char* file, int line, const char* error_msg,
|
||||
const char* detail_fmt, ...) ATTRIBUTE_PRINTF(4, 5);
|
||||
const char* detail_fmt, ...);
|
||||
|
||||
ATTRIBUTE_NORETURN
|
||||
void report_vm_status_error(const char* file, int line, const char* error_msg,
|
||||
int status, const char* detail);
|
||||
void report_fatal(VMErrorType error_type, const char* file, int line, const char* detail_fmt, ...) ATTRIBUTE_PRINTF(4, 5);
|
||||
|
||||
ATTRIBUTE_NORETURN
|
||||
ATTRIBUTE_PRINTF(4, 5)
|
||||
void report_fatal(VMErrorType error_type, const char* file, int line, const char* detail_fmt, ...);
|
||||
|
||||
ATTRIBUTE_NORETURN
|
||||
ATTRIBUTE_PRINTF(5, 6)
|
||||
void report_vm_out_of_memory(const char* file, int line, size_t size, VMErrorType vm_err_type,
|
||||
const char* detail_fmt, ...) ATTRIBUTE_PRINTF(5, 6);
|
||||
void report_should_not_call(const char* file, int line);
|
||||
void report_should_not_reach_here(const char* file, int line);
|
||||
void report_unimplemented(const char* file, int line);
|
||||
const char* detail_fmt, ...);
|
||||
|
||||
ATTRIBUTE_NORETURN void report_should_not_call(const char* file, int line);
|
||||
ATTRIBUTE_NORETURN void report_should_not_reach_here(const char* file, int line);
|
||||
ATTRIBUTE_NORETURN void report_unimplemented(const char* file, int line);
|
||||
|
||||
// NOT ATTRIBUTE_NORETURN
|
||||
void report_untested(const char* file, int line, const char* message);
|
||||
|
||||
void warning(const char* format, ...) ATTRIBUTE_PRINTF(1, 2);
|
||||
ATTRIBUTE_PRINTF(1, 2)
|
||||
void warning(const char* format, ...);
|
||||
|
||||
#define STATIC_ASSERT(Cond) static_assert((Cond), #Cond)
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
#ifndef SHARE_UTILITIES_GLOBALDEFINITIONS_HPP
|
||||
#define SHARE_UTILITIES_GLOBALDEFINITIONS_HPP
|
||||
|
||||
#include "utilities/attributeNoreturn.hpp"
|
||||
#include "utilities/compilerWarnings.hpp"
|
||||
#include "utilities/debug.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
|
@ -136,7 +136,7 @@ class VMError : public AllStatic {
|
||||
static jlong get_step_start_time();
|
||||
static void clear_step_start_time();
|
||||
|
||||
WINDOWS_ONLY([[noreturn]] static void raise_fail_fast(void* exrecord, void* context);)
|
||||
WINDOWS_ONLY(ATTRIBUTE_NORETURN static void raise_fail_fast(void* exrecord, void* context);)
|
||||
|
||||
public:
|
||||
|
||||
@ -156,27 +156,27 @@ public:
|
||||
static void print_vm_info(outputStream* st);
|
||||
|
||||
// main error reporting function
|
||||
[[noreturn]]
|
||||
ATTRIBUTE_NORETURN
|
||||
ATTRIBUTE_PRINTF(6, 7)
|
||||
static void report_and_die(Thread* thread, unsigned int sig, address pc, void* siginfo,
|
||||
void* context, const char* detail_fmt, ...);
|
||||
|
||||
[[noreturn]]
|
||||
ATTRIBUTE_NORETURN
|
||||
ATTRIBUTE_PRINTF(3, 0)
|
||||
static void report_and_die(int id, const char* message, const char* detail_fmt, va_list detail_args,
|
||||
Thread* thread, address pc, void* siginfo, void* context,
|
||||
const char* filename, int lineno, size_t size);
|
||||
|
||||
[[noreturn]]
|
||||
ATTRIBUTE_NORETURN
|
||||
static void report_and_die(Thread* thread, unsigned int sig, address pc,
|
||||
void* siginfo, void* context);
|
||||
|
||||
[[noreturn]]
|
||||
ATTRIBUTE_NORETURN
|
||||
ATTRIBUTE_PRINTF(6, 0)
|
||||
static void report_and_die(Thread* thread, void* context, const char* filename, int lineno, const char* message,
|
||||
const char* detail_fmt, va_list detail_args);
|
||||
|
||||
[[noreturn]]
|
||||
ATTRIBUTE_NORETURN
|
||||
ATTRIBUTE_PRINTF(6, 0)
|
||||
static void report_and_die(Thread* thread, const char* filename, int lineno, size_t size,
|
||||
VMErrorType vm_err_type, const char* detail_fmt,
|
||||
|
Loading…
Reference in New Issue
Block a user