diff --git a/src/hotspot/os/bsd/gc/z/zPhysicalMemoryBacking_bsd.cpp b/src/hotspot/os/bsd/gc/z/zPhysicalMemoryBacking_bsd.cpp index 29825a9eab2..2e56c092a79 100644 --- a/src/hotspot/os/bsd/gc/z/zPhysicalMemoryBacking_bsd.cpp +++ b/src/hotspot/os/bsd/gc/z/zPhysicalMemoryBacking_bsd.cpp @@ -22,10 +22,10 @@ */ #include "precompiled.hpp" -#include "gc/shared/gcLogPrecious.hpp" #include "gc/z/zAddress.inline.hpp" #include "gc/z/zErrno.hpp" #include "gc/z/zGlobals.hpp" +#include "gc/z/zInitialize.hpp" #include "gc/z/zLargePages.inline.hpp" #include "gc/z/zPhysicalMemory.inline.hpp" #include "gc/z/zPhysicalMemoryBacking_bsd.hpp" @@ -82,7 +82,7 @@ ZPhysicalMemoryBacking::ZPhysicalMemoryBacking(size_t max_capacity) _base = (uintptr_t)os::reserve_memory(max_capacity); if (_base == 0) { // Failed - log_error_pd(gc)("Failed to reserve address space for backing memory"); + ZInitialize::error("Failed to reserve address space for backing memory"); return; } diff --git a/src/hotspot/os/linux/gc/z/zPhysicalMemoryBacking_linux.cpp b/src/hotspot/os/linux/gc/z/zPhysicalMemoryBacking_linux.cpp index f967fee9305..b648876ac60 100644 --- a/src/hotspot/os/linux/gc/z/zPhysicalMemoryBacking_linux.cpp +++ b/src/hotspot/os/linux/gc/z/zPhysicalMemoryBacking_linux.cpp @@ -27,6 +27,7 @@ #include "gc/z/zArray.inline.hpp" #include "gc/z/zErrno.hpp" #include "gc/z/zGlobals.hpp" +#include "gc/z/zInitialize.hpp" #include "gc/z/zLargePages.inline.hpp" #include "gc/z/zMountPoint_linux.hpp" #include "gc/z/zNUMA.inline.hpp" @@ -129,6 +130,7 @@ ZPhysicalMemoryBacking::ZPhysicalMemoryBacking(size_t max_capacity) // Create backing file _fd = create_fd(ZFILENAME_HEAP); if (_fd == -1) { + ZInitialize::error("Failed to create heap backing file"); return; } @@ -136,7 +138,7 @@ ZPhysicalMemoryBacking::ZPhysicalMemoryBacking(size_t max_capacity) while (ftruncate(_fd, max_capacity) == -1) { if (errno != EINTR) { ZErrno err; - log_error_p(gc)("Failed to truncate backing file (%s)", err.to_string()); + ZInitialize::error("Failed to truncate backing file (%s)", err.to_string()); return; } } @@ -145,7 +147,7 @@ ZPhysicalMemoryBacking::ZPhysicalMemoryBacking(size_t max_capacity) struct statfs buf; if (fstatfs(_fd, &buf) == -1) { ZErrno err; - log_error_p(gc)("Failed to determine filesystem type for backing file (%s)", err.to_string()); + ZInitialize::error("Failed to determine filesystem type for backing file (%s)", err.to_string()); return; } @@ -158,39 +160,39 @@ ZPhysicalMemoryBacking::ZPhysicalMemoryBacking(size_t max_capacity) // Make sure the filesystem type matches requested large page type if (ZLargePages::is_transparent() && !is_tmpfs()) { - log_error_p(gc)("-XX:+UseTransparentHugePages can only be enabled when using a %s filesystem", - ZFILESYSTEM_TMPFS); + ZInitialize::error("-XX:+UseTransparentHugePages can only be enabled when using a %s filesystem", + ZFILESYSTEM_TMPFS); return; } if (ZLargePages::is_transparent() && !tmpfs_supports_transparent_huge_pages()) { - log_error_p(gc)("-XX:+UseTransparentHugePages on a %s filesystem not supported by kernel", - ZFILESYSTEM_TMPFS); + ZInitialize::error("-XX:+UseTransparentHugePages on a %s filesystem not supported by kernel", + ZFILESYSTEM_TMPFS); return; } if (ZLargePages::is_explicit() && !is_hugetlbfs()) { - log_error_p(gc)("-XX:+UseLargePages (without -XX:+UseTransparentHugePages) can only be enabled " - "when using a %s filesystem", ZFILESYSTEM_HUGETLBFS); + ZInitialize::error("-XX:+UseLargePages (without -XX:+UseTransparentHugePages) can only be enabled " + "when using a %s filesystem", ZFILESYSTEM_HUGETLBFS); return; } if (!ZLargePages::is_explicit() && is_hugetlbfs()) { - log_error_p(gc)("-XX:+UseLargePages must be enabled when using a %s filesystem", - ZFILESYSTEM_HUGETLBFS); + ZInitialize::error("-XX:+UseLargePages must be enabled when using a %s filesystem", + ZFILESYSTEM_HUGETLBFS); return; } // Make sure the filesystem block size is compatible if (ZGranuleSize % _block_size != 0) { - log_error_p(gc)("Filesystem backing the heap has incompatible block size (" SIZE_FORMAT ")", - _block_size); + ZInitialize::error("Filesystem backing the heap has incompatible block size (" SIZE_FORMAT ")", + _block_size); return; } if (is_hugetlbfs() && _block_size != ZGranuleSize) { - log_error_p(gc)("%s filesystem has unexpected block size " SIZE_FORMAT " (expected " SIZE_FORMAT ")", - ZFILESYSTEM_HUGETLBFS, _block_size, ZGranuleSize); + ZInitialize::error("%s filesystem has unexpected block size " SIZE_FORMAT " (expected " SIZE_FORMAT ")", + ZFILESYSTEM_HUGETLBFS, _block_size, ZGranuleSize); return; } diff --git a/src/hotspot/share/gc/z/zCollectedHeap.cpp b/src/hotspot/share/gc/z/zCollectedHeap.cpp index ccfa7af6b7d..8afefd5a7cc 100644 --- a/src/hotspot/share/gc/z/zCollectedHeap.cpp +++ b/src/hotspot/share/gc/z/zCollectedHeap.cpp @@ -49,6 +49,7 @@ #include "memory/universe.hpp" #include "oops/stackChunkOop.hpp" #include "runtime/continuationJavaClasses.hpp" +#include "runtime/java.hpp" #include "runtime/jniHandles.inline.hpp" #include "runtime/stackWatermarkSet.hpp" #include "services/memoryUsage.hpp" @@ -60,7 +61,7 @@ ZCollectedHeap* ZCollectedHeap::heap() { ZCollectedHeap::ZCollectedHeap() : _barrier_set(), - _initialize(&_barrier_set), + _initializer(&_barrier_set), _heap(), _driver_minor(new ZDriverMinor()), _driver_major(new ZDriverMajor()), @@ -78,11 +79,14 @@ const char* ZCollectedHeap::name() const { jint ZCollectedHeap::initialize() { if (!_heap.is_initialized()) { + vm_shutdown_during_initialization(ZInitialize::error_message()); return JNI_ENOMEM; } Universe::set_verify_data(~(ZAddressHeapBase - 1) | 0x7, ZAddressHeapBase); + ZInitialize::finish(); + return JNI_OK; } diff --git a/src/hotspot/share/gc/z/zCollectedHeap.hpp b/src/hotspot/share/gc/z/zCollectedHeap.hpp index 528bacd8df8..434204e16b8 100644 --- a/src/hotspot/share/gc/z/zCollectedHeap.hpp +++ b/src/hotspot/share/gc/z/zCollectedHeap.hpp @@ -43,7 +43,7 @@ class ZCollectedHeap : public CollectedHeap { private: ZBarrierSet _barrier_set; - ZInitialize _initialize; + ZInitializer _initializer; ZHeap _heap; ZDriverMinor* _driver_minor; ZDriverMajor* _driver_major; diff --git a/src/hotspot/share/gc/z/zHeap.cpp b/src/hotspot/share/gc/z/zHeap.cpp index dc5f1e3d21d..40aa76867f4 100644 --- a/src/hotspot/share/gc/z/zHeap.cpp +++ b/src/hotspot/share/gc/z/zHeap.cpp @@ -34,6 +34,7 @@ #include "gc/z/zHeap.inline.hpp" #include "gc/z/zHeapIterator.hpp" #include "gc/z/zHeuristics.hpp" +#include "gc/z/zInitialize.hpp" #include "gc/z/zPage.inline.hpp" #include "gc/z/zPageTable.inline.hpp" #include "gc/z/zResurrection.hpp" @@ -74,7 +75,7 @@ ZHeap::ZHeap() // Prime cache if (!_page_allocator.prime_cache(_old.workers(), InitialHeapSize)) { - log_error_p(gc)("Failed to allocate initial Java heap (" SIZE_FORMAT "M)", InitialHeapSize / M); + ZInitialize::error("Failed to allocate initial Java heap (" SIZE_FORMAT "M)", InitialHeapSize / M); return; } diff --git a/src/hotspot/share/gc/z/zInitialize.cpp b/src/hotspot/share/gc/z/zInitialize.cpp index 52229bf2830..e37fc550bfe 100644 --- a/src/hotspot/share/gc/z/zInitialize.cpp +++ b/src/hotspot/share/gc/z/zInitialize.cpp @@ -22,6 +22,7 @@ */ #include "precompiled.hpp" +#include "gc/shared/gcLogPrecious.hpp" #include "gc/z/zAddress.hpp" #include "gc/z/zBarrierSet.hpp" #include "gc/z/zCPU.hpp" @@ -38,9 +39,19 @@ #include "gc/z/zThreadLocalAllocBuffer.hpp" #include "gc/z/zTracer.hpp" #include "logging/log.hpp" +#include "nmt/memTag.hpp" #include "runtime/vm_version.hpp" +#include "utilities/formatBuffer.hpp" -ZInitialize::ZInitialize(ZBarrierSet* barrier_set) { +char ZInitialize::_error_message[ErrorMessageLength] = {}; +bool ZInitialize::_had_error = false; +bool ZInitialize::_finished = false; + +ZInitializer::ZInitializer(ZBarrierSet* barrier_set) { + ZInitialize::initialize(barrier_set); +} + +void ZInitialize::initialize(ZBarrierSet* barrier_set) { log_info(gc, init)("Initializing %s", ZName); log_info(gc, init)("Version: %s (%s)", VM_Version::vm_release(), @@ -62,3 +73,51 @@ ZInitialize::ZInitialize(ZBarrierSet* barrier_set) { pd_initialize(); } + +void ZInitialize::register_error(bool debug, const char *error_msg) { + guarantee(!_finished, "Only register errors during initialization"); + + if (!_had_error) { + strncpy(_error_message, error_msg, ErrorMessageLength - 1); + _had_error = true; + } + + if (debug) { + log_error_pd(gc)("%s", error_msg); + } else { + log_error_p(gc)("%s", error_msg); + } +} + +void ZInitialize::error(const char* msg_format, ...) { + va_list argp; + va_start(argp, msg_format); + const FormatBuffer error_msg(FormatBufferDummy(), msg_format, argp); + va_end(argp); + register_error(false /* debug */, error_msg); +} + +void ZInitialize::error_d(const char* msg_format, ...) { + va_list argp; + va_start(argp, msg_format); + const FormatBuffer error_msg(FormatBufferDummy(), msg_format, argp); + va_end(argp); + register_error(true /* debug */, error_msg); +} + +bool ZInitialize::had_error() { + return _had_error; +} + +const char* ZInitialize::error_message() { + assert(had_error(), "Should have registered an error"); + if (had_error()) { + return _error_message; + } + return "Unknown error, check error GC logs"; +} + +void ZInitialize::finish() { + guarantee(!_finished, "Only finish initialization once"); + _finished = true; +} diff --git a/src/hotspot/share/gc/z/zInitialize.hpp b/src/hotspot/share/gc/z/zInitialize.hpp index 599b6566234..3c551b4c622 100644 --- a/src/hotspot/share/gc/z/zInitialize.hpp +++ b/src/hotspot/share/gc/z/zInitialize.hpp @@ -24,16 +24,39 @@ #ifndef SHARE_GC_Z_ZINITIALIZE_HPP #define SHARE_GC_Z_ZINITIALIZE_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" +#include "utilities/compilerWarnings.hpp" + +#include class ZBarrierSet; -class ZInitialize { +class ZInitializer { +public: + ZInitializer(ZBarrierSet* barrier_set); +}; + +class ZInitialize : public AllStatic { private: - void pd_initialize(); + static constexpr size_t ErrorMessageLength = 256; + + static char _error_message[ErrorMessageLength]; + static bool _had_error; + static bool _finished; + + static void register_error(bool debug, const char *error_msg); + + static void pd_initialize(); public: - ZInitialize(ZBarrierSet* barrier_set); + static void error(const char* msg_format, ...) ATTRIBUTE_PRINTF(1, 2); + static void error_d(const char* msg_format, ...) ATTRIBUTE_PRINTF(1, 2); + + static bool had_error(); + static const char* error_message(); + + static void initialize(ZBarrierSet* barrier_set); + static void finish(); }; #endif // SHARE_GC_Z_ZINITIALIZE_HPP diff --git a/src/hotspot/share/gc/z/zMarkStackAllocator.cpp b/src/hotspot/share/gc/z/zMarkStackAllocator.cpp index a9e404a0f55..100036dc3fe 100644 --- a/src/hotspot/share/gc/z/zMarkStackAllocator.cpp +++ b/src/hotspot/share/gc/z/zMarkStackAllocator.cpp @@ -22,8 +22,8 @@ */ #include "precompiled.hpp" -#include "gc/shared/gcLogPrecious.hpp" #include "gc/shared/gc_globals.hpp" +#include "gc/z/zInitialize.hpp" #include "gc/z/zLock.inline.hpp" #include "gc/z/zMarkStack.inline.hpp" #include "gc/z/zMarkStackAllocator.hpp" @@ -43,7 +43,7 @@ ZMarkStackSpace::ZMarkStackSpace() const size_t size = ZMarkStackSpaceLimit; const uintptr_t addr = (uintptr_t)os::reserve_memory(size, !ExecMem, mtGC); if (addr == 0) { - log_error_pd(gc, marking)("Failed to reserve address space for mark stacks"); + ZInitialize::error_d("Failed to reserve address space for mark stacks"); return; } diff --git a/src/hotspot/share/gc/z/zVirtualMemory.cpp b/src/hotspot/share/gc/z/zVirtualMemory.cpp index 6b53b2ba7c8..2160aa38948 100644 --- a/src/hotspot/share/gc/z/zVirtualMemory.cpp +++ b/src/hotspot/share/gc/z/zVirtualMemory.cpp @@ -27,6 +27,7 @@ #include "gc/z/zAddress.inline.hpp" #include "gc/z/zAddressSpaceLimit.hpp" #include "gc/z/zGlobals.hpp" +#include "gc/z/zInitialize.hpp" #include "gc/z/zNMT.hpp" #include "gc/z/zVirtualMemory.inline.hpp" #include "utilities/align.hpp" @@ -44,7 +45,7 @@ ZVirtualMemoryManager::ZVirtualMemoryManager(size_t max_capacity) // Reserve address space if (!reserve(max_capacity)) { - log_error_pd(gc)("Failed to reserve enough address space for Java heap"); + ZInitialize::error_d("Failed to reserve enough address space for Java heap"); return; }