diff --git a/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp b/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp index 2a9faee7e2f..f78d7261e40 100644 --- a/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp +++ b/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp @@ -5936,7 +5936,6 @@ static const int64_t right_3_bits = right_n_bits(3); } void generate_compiler_stubs() { -#if COMPILER2_OR_JVMCI #ifdef COMPILER2 if (UseMulAddIntrinsic) { StubRoutines::_mulAdd = generate_mulAdd(); @@ -5970,7 +5969,6 @@ static const int64_t right_3_bits = right_n_bits(3); StubRoutines::_bigIntegerLeftShiftWorker = generate_bigIntegerLeftShift(); StubRoutines::_bigIntegerRightShiftWorker = generate_bigIntegerRightShift(); } -#endif // COMPILER2 if (UseSHA256Intrinsics) { Sha2Generator sha2(_masm, this); @@ -5984,10 +5982,6 @@ static const int64_t right_3_bits = right_n_bits(3); StubRoutines::_sha512_implCompressMB = sha2.generate_sha512_implCompress(true); } - generate_compare_long_strings(); - - generate_string_indexof_stubs(); - if (UseMD5Intrinsics) { StubRoutines::_md5_implCompress = generate_md5_implCompress(false, "md5_implCompress"); StubRoutines::_md5_implCompressMB = generate_md5_implCompress(true, "md5_implCompressMB"); @@ -6006,7 +6000,11 @@ static const int64_t right_3_bits = right_n_bits(3); StubRoutines::_updateBytesAdler32 = generate_updateBytesAdler32(); } -#endif // COMPILER2_OR_JVMCI + generate_compare_long_strings(); + + generate_string_indexof_stubs(); + +#endif // COMPILER2 } public: diff --git a/src/hotspot/cpu/riscv/vm_version_riscv.cpp b/src/hotspot/cpu/riscv/vm_version_riscv.cpp index d5a74d18606..ac2d6cde1a2 100644 --- a/src/hotspot/cpu/riscv/vm_version_riscv.cpp +++ b/src/hotspot/cpu/riscv/vm_version_riscv.cpp @@ -58,6 +58,13 @@ void VM_Version::useRVA23U64Profile() { } void VM_Version::initialize() { + common_initialize(); +#ifdef COMPILER2 + c2_initialize(); +#endif // COMPILER2 +} + +void VM_Version::common_initialize() { _supports_atomic_getset4 = true; _supports_atomic_getadd4 = true; _supports_atomic_getset8 = true; @@ -152,10 +159,6 @@ void VM_Version::initialize() { FLAG_SET_DEFAULT(UseVectorizedMismatchIntrinsic, false); } - if (FLAG_IS_DEFAULT(UseMD5Intrinsics)) { - FLAG_SET_DEFAULT(UseMD5Intrinsics, true); - } - if (FLAG_IS_DEFAULT(UsePoly1305Intrinsics)) { FLAG_SET_DEFAULT(UsePoly1305Intrinsics, true); } @@ -230,15 +233,105 @@ void VM_Version::initialize() { _initial_vector_length = cpu_vector_length(); } } +} #ifdef COMPILER2 - c2_initialize(); -#endif // COMPILER2 +void VM_Version::c2_initialize() { + if (UseCMoveUnconditionally) { + FLAG_SET_DEFAULT(UseCMoveUnconditionally, false); + } + + if (ConditionalMoveLimit > 0) { + FLAG_SET_DEFAULT(ConditionalMoveLimit, 0); + } - // NOTE: Make sure codes dependent on UseRVV are put after c2_initialize(), + if (!UseRVV) { + FLAG_SET_DEFAULT(MaxVectorSize, 0); + FLAG_SET_DEFAULT(UseRVVForBigIntegerShiftIntrinsics, false); + } else { + if (!FLAG_IS_DEFAULT(MaxVectorSize) && MaxVectorSize != _initial_vector_length) { + warning("Current system does not support RVV vector length for MaxVectorSize %d. Set MaxVectorSize to %d", + (int)MaxVectorSize, _initial_vector_length); + } + MaxVectorSize = _initial_vector_length; + if (MaxVectorSize < 16) { + warning("RVV does not support vector length less than 16 bytes. Disabling RVV."); + UseRVV = false; + FLAG_SET_DEFAULT(MaxVectorSize, 0); + } + } + + // NOTE: Make sure codes dependent on UseRVV are put after MaxVectorSize initialize, // as there are extra checks inside it which could disable UseRVV // in some situations. + if (FLAG_IS_DEFAULT(UseVectorizedHashCodeIntrinsic)) { + FLAG_SET_DEFAULT(UseVectorizedHashCodeIntrinsic, true); + } + + if (!UseZicbop) { + if (!FLAG_IS_DEFAULT(AllocatePrefetchStyle)) { + warning("Zicbop is not available on this CPU"); + } + FLAG_SET_DEFAULT(AllocatePrefetchStyle, 0); + } else { + // Limit AllocatePrefetchDistance so that it does not exceed the + // static constraint of 512 defined in runtime/globals.hpp. + if (FLAG_IS_DEFAULT(AllocatePrefetchDistance)) { + FLAG_SET_DEFAULT(AllocatePrefetchDistance, MIN2(512, 3 * (int)CacheLineSize)); + } + if (FLAG_IS_DEFAULT(AllocatePrefetchStepSize)) { + FLAG_SET_DEFAULT(AllocatePrefetchStepSize, (int)CacheLineSize); + } + if (FLAG_IS_DEFAULT(PrefetchScanIntervalInBytes)) { + FLAG_SET_DEFAULT(PrefetchScanIntervalInBytes, 3 * (int)CacheLineSize); + } + if (FLAG_IS_DEFAULT(PrefetchCopyIntervalInBytes)) { + FLAG_SET_DEFAULT(PrefetchCopyIntervalInBytes, 3 * (int)CacheLineSize); + } + + if (PrefetchCopyIntervalInBytes != -1 && + ((PrefetchCopyIntervalInBytes & 7) || (PrefetchCopyIntervalInBytes >= 32768))) { + warning("PrefetchCopyIntervalInBytes must be -1, or a multiple of 8 and < 32768"); + PrefetchCopyIntervalInBytes &= ~7; + if (PrefetchCopyIntervalInBytes >= 32768) { + PrefetchCopyIntervalInBytes = 32760; + } + } + if (AllocatePrefetchDistance !=-1 && (AllocatePrefetchDistance & 7)) { + warning("AllocatePrefetchDistance must be multiple of 8"); + AllocatePrefetchDistance &= ~7; + } + if (AllocatePrefetchStepSize & 7) { + warning("AllocatePrefetchStepSize must be multiple of 8"); + AllocatePrefetchStepSize &= ~7; + } + } + + if (FLAG_IS_DEFAULT(UseMulAddIntrinsic)) { + FLAG_SET_DEFAULT(UseMulAddIntrinsic, true); + } + + if (FLAG_IS_DEFAULT(UseMultiplyToLenIntrinsic)) { + FLAG_SET_DEFAULT(UseMultiplyToLenIntrinsic, true); + } + + if (FLAG_IS_DEFAULT(UseSquareToLenIntrinsic)) { + FLAG_SET_DEFAULT(UseSquareToLenIntrinsic, true); + } + + if (FLAG_IS_DEFAULT(UseMontgomeryMultiplyIntrinsic)) { + FLAG_SET_DEFAULT(UseMontgomeryMultiplyIntrinsic, true); + } + + if (FLAG_IS_DEFAULT(UseMontgomerySquareIntrinsic)) { + FLAG_SET_DEFAULT(UseMontgomerySquareIntrinsic, true); + } + + if (FLAG_IS_DEFAULT(UseMD5Intrinsics)) { + FLAG_SET_DEFAULT(UseMD5Intrinsics, true); + } + // Adler32 if (UseRVV) { if (FLAG_IS_DEFAULT(UseAdler32Intrinsics)) { @@ -332,96 +425,6 @@ void VM_Version::initialize() { FLAG_SET_DEFAULT(UseSHA, false); } } - -#ifdef COMPILER2 -void VM_Version::c2_initialize() { - if (UseCMoveUnconditionally) { - FLAG_SET_DEFAULT(UseCMoveUnconditionally, false); - } - - if (ConditionalMoveLimit > 0) { - FLAG_SET_DEFAULT(ConditionalMoveLimit, 0); - } - - if (!UseRVV) { - FLAG_SET_DEFAULT(MaxVectorSize, 0); - FLAG_SET_DEFAULT(UseRVVForBigIntegerShiftIntrinsics, false); - } else { - if (!FLAG_IS_DEFAULT(MaxVectorSize) && MaxVectorSize != _initial_vector_length) { - warning("Current system does not support RVV vector length for MaxVectorSize %d. Set MaxVectorSize to %d", - (int)MaxVectorSize, _initial_vector_length); - } - MaxVectorSize = _initial_vector_length; - if (MaxVectorSize < 16) { - warning("RVV does not support vector length less than 16 bytes. Disabling RVV."); - UseRVV = false; - FLAG_SET_DEFAULT(MaxVectorSize, 0); - } - } - - if (FLAG_IS_DEFAULT(UseVectorizedHashCodeIntrinsic)) { - FLAG_SET_DEFAULT(UseVectorizedHashCodeIntrinsic, true); - } - - if (!UseZicbop) { - if (!FLAG_IS_DEFAULT(AllocatePrefetchStyle)) { - warning("Zicbop is not available on this CPU"); - } - FLAG_SET_DEFAULT(AllocatePrefetchStyle, 0); - } else { - // Limit AllocatePrefetchDistance so that it does not exceed the - // static constraint of 512 defined in runtime/globals.hpp. - if (FLAG_IS_DEFAULT(AllocatePrefetchDistance)) { - FLAG_SET_DEFAULT(AllocatePrefetchDistance, MIN2(512, 3 * (int)CacheLineSize)); - } - if (FLAG_IS_DEFAULT(AllocatePrefetchStepSize)) { - FLAG_SET_DEFAULT(AllocatePrefetchStepSize, (int)CacheLineSize); - } - if (FLAG_IS_DEFAULT(PrefetchScanIntervalInBytes)) { - FLAG_SET_DEFAULT(PrefetchScanIntervalInBytes, 3 * (int)CacheLineSize); - } - if (FLAG_IS_DEFAULT(PrefetchCopyIntervalInBytes)) { - FLAG_SET_DEFAULT(PrefetchCopyIntervalInBytes, 3 * (int)CacheLineSize); - } - - if (PrefetchCopyIntervalInBytes != -1 && - ((PrefetchCopyIntervalInBytes & 7) || (PrefetchCopyIntervalInBytes >= 32768))) { - warning("PrefetchCopyIntervalInBytes must be -1, or a multiple of 8 and < 32768"); - PrefetchCopyIntervalInBytes &= ~7; - if (PrefetchCopyIntervalInBytes >= 32768) { - PrefetchCopyIntervalInBytes = 32760; - } - } - if (AllocatePrefetchDistance !=-1 && (AllocatePrefetchDistance & 7)) { - warning("AllocatePrefetchDistance must be multiple of 8"); - AllocatePrefetchDistance &= ~7; - } - if (AllocatePrefetchStepSize & 7) { - warning("AllocatePrefetchStepSize must be multiple of 8"); - AllocatePrefetchStepSize &= ~7; - } - } - - if (FLAG_IS_DEFAULT(UseMulAddIntrinsic)) { - FLAG_SET_DEFAULT(UseMulAddIntrinsic, true); - } - - if (FLAG_IS_DEFAULT(UseMultiplyToLenIntrinsic)) { - FLAG_SET_DEFAULT(UseMultiplyToLenIntrinsic, true); - } - - if (FLAG_IS_DEFAULT(UseSquareToLenIntrinsic)) { - FLAG_SET_DEFAULT(UseSquareToLenIntrinsic, true); - } - - if (FLAG_IS_DEFAULT(UseMontgomeryMultiplyIntrinsic)) { - FLAG_SET_DEFAULT(UseMontgomeryMultiplyIntrinsic, true); - } - - if (FLAG_IS_DEFAULT(UseMontgomerySquareIntrinsic)) { - FLAG_SET_DEFAULT(UseMontgomerySquareIntrinsic, true); - } -} #endif // COMPILER2 void VM_Version::initialize_cpu_information(void) { diff --git a/src/hotspot/cpu/riscv/vm_version_riscv.hpp b/src/hotspot/cpu/riscv/vm_version_riscv.hpp index 9556e2dc9ad..bd4bfe86d9b 100644 --- a/src/hotspot/cpu/riscv/vm_version_riscv.hpp +++ b/src/hotspot/cpu/riscv/vm_version_riscv.hpp @@ -264,6 +264,8 @@ class VM_Version : public Abstract_VM_Version { static uint32_t cpu_vector_length(); static uint32_t _initial_vector_length; + static void common_initialize(); + #ifdef COMPILER2 static void c2_initialize(); #endif // COMPILER2 diff --git a/src/hotspot/share/classfile/classFileParser.cpp b/src/hotspot/share/classfile/classFileParser.cpp index ddde58e5d20..407078d64fc 100644 --- a/src/hotspot/share/classfile/classFileParser.cpp +++ b/src/hotspot/share/classfile/classFileParser.cpp @@ -835,14 +835,12 @@ void ClassFileParser::parse_interfaces(const ClassFileStream* const stream, guarantee_property(unresolved_klass->char_at(0) != JVM_SIGNATURE_ARRAY, "Bad interface name in class file %s", CHECK); - // Call resolve_super so class circularity is checked - interf = SystemDictionary::resolve_super_or_fail( - _class_name, - unresolved_klass, - Handle(THREAD, _loader_data->class_loader()), - _protection_domain, - false, - CHECK); + // Call resolve on the interface class name with class circularity checking + interf = SystemDictionary::resolve_super_or_fail(_class_name, + unresolved_klass, + Handle(THREAD, _loader_data->class_loader()), + _protection_domain, + false, CHECK); } if (!interf->is_interface()) { diff --git a/src/hotspot/share/classfile/placeholders.cpp b/src/hotspot/share/classfile/placeholders.cpp index a6a86473ea7..38d359efcc2 100644 --- a/src/hotspot/share/classfile/placeholders.cpp +++ b/src/hotspot/share/classfile/placeholders.cpp @@ -95,8 +95,8 @@ SeenThread* PlaceholderEntry::actionToQueue(PlaceholderTable::classloadAction ac case PlaceholderTable::LOAD_INSTANCE: queuehead = _loadInstanceThreadQ; break; - case PlaceholderTable::LOAD_SUPER: - queuehead = _superThreadQ; + case PlaceholderTable::DETECT_CIRCULARITY: + queuehead = _circularityThreadQ; break; case PlaceholderTable::DEFINE_CLASS: queuehead = _defineThreadQ; @@ -111,8 +111,8 @@ void PlaceholderEntry::set_threadQ(SeenThread* seenthread, PlaceholderTable::cla case PlaceholderTable::LOAD_INSTANCE: _loadInstanceThreadQ = seenthread; break; - case PlaceholderTable::LOAD_SUPER: - _superThreadQ = seenthread; + case PlaceholderTable::DETECT_CIRCULARITY: + _circularityThreadQ = seenthread; break; case PlaceholderTable::DEFINE_CLASS: _defineThreadQ = seenthread; @@ -188,10 +188,10 @@ bool PlaceholderEntry::remove_seen_thread(JavaThread* thread, PlaceholderTable:: } -void PlaceholderEntry::set_supername(Symbol* supername) { +void PlaceholderEntry::set_next_klass_name(Symbol* next_klass_name) { assert_locked_or_safepoint(SystemDictionary_lock); - assert(_supername == nullptr || _supername->refcount() > 1, "must be referenced also by the loader"); - _supername = supername; + assert(_next_klass_name == nullptr || _next_klass_name->refcount() > 1, "must be referenced also by the loader"); + _next_klass_name = next_klass_name; } // Placeholder objects represent classes currently being loaded. @@ -199,12 +199,12 @@ void PlaceholderEntry::set_supername(Symbol* supername) { // SystemDictionary_lock, so we don't need special precautions // on store ordering here. static PlaceholderEntry* add_entry(Symbol* class_name, ClassLoaderData* loader_data, - Symbol* supername){ + Symbol* next_klass_name){ assert_locked_or_safepoint(SystemDictionary_lock); assert(class_name != nullptr, "adding nullptr obj"); PlaceholderEntry entry; - entry.set_supername(supername); + entry.set_next_klass_name(next_klass_name); PlaceholderKey key(class_name, loader_data); bool created; PlaceholderEntry* table_copy = _placeholders->put_if_absent(key, entry, &created); @@ -230,7 +230,7 @@ PlaceholderEntry* PlaceholderTable::get_entry(Symbol* class_name, ClassLoaderDat static const char* action_to_string(PlaceholderTable::classloadAction action) { switch (action) { case PlaceholderTable::LOAD_INSTANCE: return "LOAD_INSTANCE"; - case PlaceholderTable::LOAD_SUPER: return "LOAD_SUPER"; + case PlaceholderTable::DETECT_CIRCULARITY: return "DETECT_CIRCULARITY"; case PlaceholderTable::DEFINE_CLASS: return "DEFINE_CLASS"; } return ""; @@ -250,20 +250,21 @@ inline void log(Symbol* name, PlaceholderEntry* entry, const char* function, Pla // If no entry exists, add a placeholder entry // If entry exists, reuse entry // For both, push SeenThread for classloadAction -// If LOAD_SUPER, this is used for circularity detection for instanceklass loading. +// If DETECT_CIRCULARITY, this is used for circularity detection for instanceklass loading. PlaceholderEntry* PlaceholderTable::find_and_add(Symbol* name, ClassLoaderData* loader_data, classloadAction action, - Symbol* supername, + Symbol* next_klass_name, JavaThread* thread) { - assert(action != LOAD_SUPER || supername != nullptr, "must have a super class name"); + assert(action != DETECT_CIRCULARITY || next_klass_name != nullptr, + "must have a class name for the next step in the class resolution recursion"); PlaceholderEntry* probe = get_entry(name, loader_data); if (probe == nullptr) { // Nothing found, add place holder - probe = add_entry(name, loader_data, supername); + probe = add_entry(name, loader_data, next_klass_name); } else { - if (action == LOAD_SUPER) { - probe->set_supername(supername); + if (action == DETECT_CIRCULARITY) { + probe->set_next_klass_name(next_klass_name); } } probe->add_seen_thread(thread, action); @@ -295,11 +296,11 @@ void PlaceholderTable::find_and_remove(Symbol* name, ClassLoaderData* loader_dat assert(probe != nullptr, "must find an entry"); log(name, probe, "find_and_remove", action); probe->remove_seen_thread(thread, action); - if (probe->superThreadQ() == nullptr) { - probe->set_supername(nullptr); + if (probe->circularityThreadQ() == nullptr) { + probe->set_next_klass_name(nullptr); } // If no other threads using this entry, and this thread is not using this entry for other states - if ((probe->superThreadQ() == nullptr) && (probe->loadInstanceThreadQ() == nullptr) + if ((probe->circularityThreadQ() == nullptr) && (probe->loadInstanceThreadQ() == nullptr) && (probe->defineThreadQ() == nullptr) && (probe->definer() == nullptr)) { remove_entry(name, loader_data); } @@ -312,9 +313,9 @@ void PlaceholderKey::print_on(outputStream* st) const { } void PlaceholderEntry::print_on(outputStream* st) const { - if (supername() != nullptr) { - st->print(", supername "); - supername()->print_value_on(st); + if (next_klass_name() != nullptr) { + st->print(", next_klass_name "); + next_klass_name()->print_value_on(st); } if (definer() != nullptr) { st->print(", definer "); @@ -328,8 +329,8 @@ void PlaceholderEntry::print_on(outputStream* st) const { st->print("loadInstanceThreadQ threads:"); SeenThread::print_action_queue(loadInstanceThreadQ(), st); st->cr(); - st->print("superThreadQ threads:"); - SeenThread::print_action_queue(superThreadQ(), st); + st->print("circularityThreadQ threads:"); + SeenThread::print_action_queue(circularityThreadQ(), st); st->cr(); st->print("defineThreadQ threads:"); SeenThread::print_action_queue(defineThreadQ(), st); diff --git a/src/hotspot/share/classfile/placeholders.hpp b/src/hotspot/share/classfile/placeholders.hpp index 7f83cf5d058..6348f76a14e 100644 --- a/src/hotspot/share/classfile/placeholders.hpp +++ b/src/hotspot/share/classfile/placeholders.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, 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 @@ -41,15 +41,15 @@ class PlaceholderTable : public AllStatic { // caller claims ownership of that action // For parallel classloading: // multiple LOAD_INSTANCE threads can proceed in parallel - // multiple LOAD_SUPER threads can proceed in parallel - // LOAD_SUPER needed to check for class circularity + // multiple DETECT_CIRCULARITY threads can proceed in parallel + // DETECT_CIRCULARITY needed to check for class circularity // DEFINE_CLASS: ultimately define class must be single threaded // on a class/classloader basis // so the head of that queue owns the token // and the rest of the threads return the result the first thread gets enum classloadAction { LOAD_INSTANCE = 1, // calling load_instance_class - LOAD_SUPER = 2, // loading superclass for this class + DETECT_CIRCULARITY = 2, // loading while detecting class circularity DEFINE_CLASS = 3 // find_or_define class }; static void initialize(); @@ -81,13 +81,13 @@ class SeenThread; class PlaceholderEntry { friend class PlaceholderTable; private: - SymbolHandle _supername; - JavaThread* _definer; // owner of define token - InstanceKlass* _instanceKlass; // InstanceKlass from successful define - SeenThread* _superThreadQ; // doubly-linked queue of Threads loading a superclass for this class - SeenThread* _loadInstanceThreadQ; // loadInstance thread - // This can't be multiple threads since class loading waits for - // this token to be removed. + SymbolHandle _next_klass_name; // next step in the recursive process of class loading + JavaThread* _definer; // owner of define token + InstanceKlass* _instanceKlass; // InstanceKlass from successful define + SeenThread* _circularityThreadQ; // doubly-linked queue of Threads loading with circularity detection + SeenThread* _loadInstanceThreadQ; // loadInstance thread + // This can't be multiple threads since class loading + // waits for this token to be removed. SeenThread* _defineThreadQ; // queue of Threads trying to define this class // including _definer @@ -99,8 +99,8 @@ class PlaceholderEntry { void add_seen_thread(JavaThread* thread, PlaceholderTable::classloadAction action); bool remove_seen_thread(JavaThread* thread, PlaceholderTable::classloadAction action); - SeenThread* superThreadQ() const { return _superThreadQ; } - void set_superThreadQ(SeenThread* SeenThread) { _superThreadQ = SeenThread; } + SeenThread* circularityThreadQ() const { return _circularityThreadQ; } + void set_circularityThreadQ(SeenThread* SeenThread) { _circularityThreadQ = SeenThread; } SeenThread* loadInstanceThreadQ() const { return _loadInstanceThreadQ; } void set_loadInstanceThreadQ(SeenThread* SeenThread) { _loadInstanceThreadQ = SeenThread; } @@ -110,10 +110,10 @@ class PlaceholderEntry { public: PlaceholderEntry() : _definer(nullptr), _instanceKlass(nullptr), - _superThreadQ(nullptr), _loadInstanceThreadQ(nullptr), _defineThreadQ(nullptr) { } + _circularityThreadQ(nullptr), _loadInstanceThreadQ(nullptr), _defineThreadQ(nullptr) { } - Symbol* supername() const { return _supername; } - void set_supername(Symbol* supername); + Symbol* next_klass_name() const { return _next_klass_name; } + void set_next_klass_name(Symbol* next_klass_name); JavaThread* definer() const {return _definer; } void set_definer(JavaThread* definer) { _definer = definer; } @@ -121,8 +121,8 @@ class PlaceholderEntry { InstanceKlass* instance_klass() const {return _instanceKlass; } void set_instance_klass(InstanceKlass* ik) { _instanceKlass = ik; } - bool super_load_in_progress() { - return (_superThreadQ != nullptr); + bool circularity_detection_in_progress() { + return (_circularityThreadQ != nullptr); } bool instance_load_in_progress() { diff --git a/src/hotspot/share/classfile/systemDictionary.cpp b/src/hotspot/share/classfile/systemDictionary.cpp index 852416e30f5..3016d41b289 100644 --- a/src/hotspot/share/classfile/systemDictionary.cpp +++ b/src/hotspot/share/classfile/systemDictionary.cpp @@ -399,32 +399,32 @@ static inline void log_circularity_error(Symbol* name, PlaceholderEntry* probe) // superclass checks on its own thread to catch class circularity and // to avoid deadlock. // -// resolve_super_or_fail adds a LOAD_SUPER placeholder to the placeholder table before calling -// resolve_instance_class_or_null. ClassCircularityError is detected when a LOAD_SUPER or LOAD_INSTANCE +// resolve_with_circularity_detection adds a DETECT_CIRCULARITY placeholder to the placeholder table before calling +// resolve_instance_class_or_null. ClassCircularityError is detected when a DETECT_CIRCULARITY or LOAD_INSTANCE // placeholder for the same thread, class, classloader is found. // This can be seen with logging option: -Xlog:class+load+placeholders=debug. // -InstanceKlass* SystemDictionary::resolve_super_or_fail(Symbol* class_name, - Symbol* super_name, - Handle class_loader, - Handle protection_domain, - bool is_superclass, - TRAPS) { - - assert(super_name != nullptr, "null superclass for resolving"); - assert(!Signature::is_array(super_name), "invalid superclass name"); +InstanceKlass* SystemDictionary::resolve_with_circularity_detection(Symbol* class_name, + Symbol* next_name, + Handle class_loader, + Handle protection_domain, + bool is_superclass, + TRAPS) { + + assert(next_name != nullptr, "null superclass for resolving"); + assert(!Signature::is_array(next_name), "invalid superclass name"); #if INCLUDE_CDS if (CDSConfig::is_dumping_static_archive()) { // Special processing for handling UNREGISTERED shared classes. InstanceKlass* k = SystemDictionaryShared::lookup_super_for_unregistered_class(class_name, - super_name, is_superclass); + next_name, is_superclass); if (k) { return k; } } #endif // INCLUDE_CDS - // If klass is already loaded, just return the superclass or superinterface. + // If class_name is already loaded, just return the superclass or superinterface. // Make sure there's a placeholder for the class_name before resolving. // This is used as a claim that this thread is currently loading superclass/classloader // and for ClassCircularity checks. @@ -439,28 +439,27 @@ InstanceKlass* SystemDictionary::resolve_super_or_fail(Symbol* class_name, InstanceKlass* klassk = dictionary->find_class(THREAD, class_name); InstanceKlass* quicksuperk; // To support parallel loading: if class is done loading, just return the superclass - // if the super_name matches class->super()->name() and if the class loaders match. - // Otherwise, a LinkageError will be thrown later. + // if the next_name matches class->super()->name() and if the class loaders match. if (klassk != nullptr && is_superclass && - ((quicksuperk = klassk->java_super()) != nullptr) && - ((quicksuperk->name() == super_name) && - (quicksuperk->class_loader() == class_loader()))) { - return quicksuperk; + ((quicksuperk = klassk->java_super()) != nullptr) && + ((quicksuperk->name() == next_name) && + (quicksuperk->class_loader() == class_loader()))) { + return quicksuperk; } else { // Must check ClassCircularity before checking if superclass is already loaded. PlaceholderEntry* probe = PlaceholderTable::get_entry(class_name, loader_data); - if (probe && probe->check_seen_thread(THREAD, PlaceholderTable::LOAD_SUPER)) { + if (probe && probe->check_seen_thread(THREAD, PlaceholderTable::DETECT_CIRCULARITY)) { log_circularity_error(class_name, probe); throw_circularity_error = true; } } if (!throw_circularity_error) { - // Be careful not to exit resolve_super without removing this placeholder. + // Be careful not to exit resolve_with_circularity_detection without removing this placeholder. PlaceholderEntry* newprobe = PlaceholderTable::find_and_add(class_name, loader_data, - PlaceholderTable::LOAD_SUPER, - super_name, THREAD); + PlaceholderTable::DETECT_CIRCULARITY, + next_name, THREAD); } } @@ -471,7 +470,7 @@ InstanceKlass* SystemDictionary::resolve_super_or_fail(Symbol* class_name, // Resolve the superclass or superinterface, check results on return InstanceKlass* superk = - SystemDictionary::resolve_instance_class_or_null(super_name, + SystemDictionary::resolve_instance_class_or_null(next_name, class_loader, protection_domain, THREAD); @@ -479,13 +478,13 @@ InstanceKlass* SystemDictionary::resolve_super_or_fail(Symbol* class_name, // Clean up placeholder entry. { MutexLocker mu(THREAD, SystemDictionary_lock); - PlaceholderTable::find_and_remove(class_name, loader_data, PlaceholderTable::LOAD_SUPER, THREAD); + PlaceholderTable::find_and_remove(class_name, loader_data, PlaceholderTable::DETECT_CIRCULARITY, THREAD); SystemDictionary_lock->notify_all(); } // Check for pending exception or null superk, and throw exception if (HAS_PENDING_EXCEPTION || superk == nullptr) { - handle_resolution_exception(super_name, true, CHECK_NULL); + handle_resolution_exception(next_name, true, CHECK_NULL); } return superk; @@ -502,13 +501,15 @@ static void handle_parallel_super_load(Symbol* name, Handle class_loader, Handle protection_domain, TRAPS) { - // superk is not used; resolve_super_or_fail is called for circularity check only. - Klass* superk = SystemDictionary::resolve_super_or_fail(name, - superclassname, - class_loader, - protection_domain, - true, - CHECK); + // The result superk is not used; resolve_with_circularity_detection is called for circularity check only. + // This passes true to is_superclass even though it might not be the super class in order to perform the + // optimization anyway. + Klass* superk = SystemDictionary::resolve_with_circularity_detection(name, + superclassname, + class_loader, + protection_domain, + true, + CHECK); } // Bootstrap and non-parallel capable class loaders use the LOAD_INSTANCE placeholder to @@ -536,7 +537,7 @@ static InstanceKlass* handle_parallel_loading(JavaThread* current, // Wait until the first thread has finished loading this class. Also wait until all the // threads trying to load its superclass have removed their placeholders. while (oldprobe != nullptr && - (oldprobe->instance_load_in_progress() || oldprobe->super_load_in_progress())) { + (oldprobe->instance_load_in_progress() || oldprobe->circularity_detection_in_progress())) { // LOAD_INSTANCE placeholders are used to implement parallel capable class loading // for the bootclass loader. @@ -575,8 +576,9 @@ InstanceKlass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, Handle protection_domain, TRAPS) { // name must be in the form of "java/lang/Object" -- cannot be "Ljava/lang/Object;" + DEBUG_ONLY(ResourceMark rm(THREAD)); assert(name != nullptr && !Signature::is_array(name) && - !Signature::has_envelope(name), "invalid class name"); + !Signature::has_envelope(name), "invalid class name: %s", name == nullptr ? "nullptr" : name->as_C_string()); EventClassLoad class_load_start_event; @@ -607,7 +609,7 @@ InstanceKlass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, Handle lockObject = get_loader_lock_or_null(class_loader); ObjectLocker ol(lockObject, THREAD); - bool super_load_in_progress = false; + bool circularity_detection_in_progress = false; InstanceKlass* loaded_class = nullptr; SymbolHandle superclassname; // Keep alive while loading in parallel thread. @@ -625,9 +627,9 @@ InstanceKlass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, loaded_class = check; } else { PlaceholderEntry* placeholder = PlaceholderTable::get_entry(name, loader_data); - if (placeholder != nullptr && placeholder->super_load_in_progress()) { - super_load_in_progress = true; - superclassname = placeholder->supername(); + if (placeholder != nullptr && placeholder->circularity_detection_in_progress()) { + circularity_detection_in_progress = true; + superclassname = placeholder->next_klass_name(); assert(superclassname != nullptr, "superclass has to have a name"); } } @@ -635,7 +637,7 @@ InstanceKlass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, // If the class is in the placeholder table with super_class set, // handle superclass loading in progress. - if (super_load_in_progress) { + if (circularity_detection_in_progress) { handle_parallel_super_load(name, superclassname, class_loader, protection_domain, @@ -1052,8 +1054,8 @@ bool SystemDictionary::check_shared_class_super_type(InstanceKlass* klass, Insta } } - Klass *found = resolve_super_or_fail(klass->name(), super_type->name(), - class_loader, protection_domain, is_superclass, CHECK_0); + Klass *found = resolve_with_circularity_detection(klass->name(), super_type->name(), + class_loader, protection_domain, is_superclass, CHECK_0); if (found == super_type) { return true; } else { diff --git a/src/hotspot/share/classfile/systemDictionary.hpp b/src/hotspot/share/classfile/systemDictionary.hpp index 6355de9c4ce..ee50aa38dd0 100644 --- a/src/hotspot/share/classfile/systemDictionary.hpp +++ b/src/hotspot/share/classfile/systemDictionary.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, 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 @@ -102,15 +102,23 @@ class SystemDictionary : AllStatic { return resolve_or_null(class_name, Handle(), Handle(), THREAD); } + static InstanceKlass* resolve_with_circularity_detection(Symbol* class_name, + Symbol* next_name, + Handle class_loader, + Handle protection_domain, + bool is_superclass, + TRAPS); + // Resolve a superclass or superinterface. Called from ClassFileParser, // parse_interfaces, resolve_instance_class_or_null, load_shared_class // "class_name" is the class whose super class or interface is being resolved. - static InstanceKlass* resolve_super_or_fail(Symbol* class_name, - Symbol* super_name, + static InstanceKlass* resolve_super_or_fail(Symbol* class_name, Symbol* super_name, Handle class_loader, - Handle protection_domain, - bool is_superclass, - TRAPS); + Handle protection_domain, bool is_superclass, TRAPS) { + return resolve_with_circularity_detection(class_name, super_name, class_loader, protection_domain, + is_superclass, THREAD); + } + private: // Parse the stream to create a hidden class. // Used by jvm_lookup_define_class. diff --git a/src/hotspot/share/gc/g1/g1_globals.hpp b/src/hotspot/share/gc/g1/g1_globals.hpp index af1ac1f70c6..c8016ddc0dd 100644 --- a/src/hotspot/share/gc/g1/g1_globals.hpp +++ b/src/hotspot/share/gc/g1/g1_globals.hpp @@ -112,7 +112,7 @@ \ product(uint, G1ConfidencePercent, 50, \ "Confidence level for MMU/pause predictions") \ - range(0, 100) \ + range(1, 100) \ \ product(uintx, G1SummarizeRSetStatsPeriod, 0, DIAGNOSTIC, \ "The period (in number of GCs) at which we will generate " \ diff --git a/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.cpp b/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.cpp index cfdb7e9eb29..288a21fd35d 100644 --- a/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.cpp +++ b/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, 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 @@ -205,8 +205,6 @@ void PSAdaptiveSizePolicy::compute_eden_space_size( bool is_full_gc) { // Update statistics - // Time statistics are updated as we go, update footprint stats here - _avg_base_footprint->sample(BaseFootPrintEstimate); avg_young_live()->sample(young_live); avg_eden_live()->sample(eden_live); @@ -363,8 +361,7 @@ void PSAdaptiveSizePolicy::compute_eden_space_size( log_debug(gc, ergo)("Live_space: " SIZE_FORMAT " free_space: " SIZE_FORMAT, live_space(), free_space()); - log_trace(gc, ergo)("Base_footprint: " SIZE_FORMAT " avg_young_live: " SIZE_FORMAT " avg_old_live: " SIZE_FORMAT, - (size_t)_avg_base_footprint->average(), + log_trace(gc, ergo)("avg_young_live: " SIZE_FORMAT " avg_old_live: " SIZE_FORMAT, (size_t)avg_young_live()->average(), (size_t)avg_old_live()->average()); @@ -535,8 +532,7 @@ void PSAdaptiveSizePolicy::compute_old_gen_free_space( log_debug(gc, ergo)("Live_space: " SIZE_FORMAT " free_space: " SIZE_FORMAT, live_space(), free_space()); - log_trace(gc, ergo)("Base_footprint: " SIZE_FORMAT " avg_young_live: " SIZE_FORMAT " avg_old_live: " SIZE_FORMAT, - (size_t)_avg_base_footprint->average(), + log_trace(gc, ergo)("avg_young_live: " SIZE_FORMAT " avg_old_live: " SIZE_FORMAT, (size_t)avg_young_live()->average(), (size_t)avg_old_live()->average()); diff --git a/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.hpp b/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.hpp index 90e1e60db94..4fab160dcb4 100644 --- a/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.hpp +++ b/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, 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 @@ -145,8 +145,7 @@ class PSAdaptiveSizePolicy : public AdaptiveSizePolicy { // Footprint accessors size_t live_space() const { - return (size_t)(avg_base_footprint()->average() + - avg_young_live()->average() + + return (size_t)(avg_young_live()->average() + avg_old_live()->average()); } size_t free_space() const { diff --git a/src/hotspot/share/gc/parallel/psGCAdaptivePolicyCounters.cpp b/src/hotspot/share/gc/parallel/psGCAdaptivePolicyCounters.cpp index 20e14b73ac3..ed96c5c4181 100644 --- a/src/hotspot/share/gc/parallel/psGCAdaptivePolicyCounters.cpp +++ b/src/hotspot/share/gc/parallel/psGCAdaptivePolicyCounters.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, 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 @@ -107,10 +107,6 @@ PSGCAdaptivePolicyCounters::PSGCAdaptivePolicyCounters(const char* name_arg, _free_space = PerfDataManager::create_variable(SUN_GC, cname, PerfData::U_Bytes, ps_size_policy()->free_space(), CHECK); - cname = PerfDataManager::counter_name(name_space(), "avgBaseFootprint"); - _avg_base_footprint = PerfDataManager::create_variable(SUN_GC, cname, - PerfData::U_Bytes, (jlong) ps_size_policy()->avg_base_footprint()->average(), CHECK); - cname = PerfDataManager::counter_name(name_space(), "liveAtLastFullGc"); _live_at_last_full_gc_counter = PerfDataManager::create_variable(SUN_GC, cname, @@ -157,7 +153,6 @@ void PSGCAdaptivePolicyCounters::update_counters_from_policy() { update_decrement_tenuring_threshold_for_survivor_limit(); update_live_space(); update_free_space(); - update_avg_base_footprint(); update_change_old_gen_for_maj_pauses(); update_change_young_gen_for_maj_pauses(); diff --git a/src/hotspot/share/gc/parallel/psGCAdaptivePolicyCounters.hpp b/src/hotspot/share/gc/parallel/psGCAdaptivePolicyCounters.hpp index 620c761004e..ad84eb4368b 100644 --- a/src/hotspot/share/gc/parallel/psGCAdaptivePolicyCounters.hpp +++ b/src/hotspot/share/gc/parallel/psGCAdaptivePolicyCounters.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, 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 @@ -50,7 +50,6 @@ class PSGCAdaptivePolicyCounters : public GCAdaptivePolicyCounters { PerfVariable* _avg_major_interval; PerfVariable* _live_space; PerfVariable* _free_space; - PerfVariable* _avg_base_footprint; PerfVariable* _live_at_last_full_gc_counter; PerfVariable* _old_capacity; @@ -142,11 +141,6 @@ class PSGCAdaptivePolicyCounters : public GCAdaptivePolicyCounters { _free_space->set_value(ps_size_policy()->free_space()); } - inline void update_avg_base_footprint() { - _avg_base_footprint->set_value( - (jlong)(ps_size_policy()->avg_base_footprint()->average()) - ); - } inline void update_avg_old_live() { _avg_old_live_counter->set_value( (jlong)(ps_size_policy()->avg_old_live()->average()) diff --git a/src/hotspot/share/gc/shared/gcCause.cpp b/src/hotspot/share/gc/shared/gcCause.cpp index 426154fdca3..2be7ef7be07 100644 --- a/src/hotspot/share/gc/shared/gcCause.cpp +++ b/src/hotspot/share/gc/shared/gcCause.cpp @@ -78,9 +78,6 @@ const char* GCCause::to_string(GCCause::Cause cause) { case _metadata_GC_clear_soft_refs: return "Metadata GC Clear Soft References"; - case _adaptive_size_policy: - return "Ergonomics"; - case _g1_inc_collection_pause: return "G1 Evacuation Pause"; diff --git a/src/hotspot/share/gc/shared/gcCause.hpp b/src/hotspot/share/gc/shared/gcCause.hpp index 152ca787fc2..f244d17c1ab 100644 --- a/src/hotspot/share/gc/shared/gcCause.hpp +++ b/src/hotspot/share/gc/shared/gcCause.hpp @@ -66,8 +66,6 @@ class GCCause : public AllStatic { _metadata_GC_threshold, _metadata_GC_clear_soft_refs, - _adaptive_size_policy, - _g1_inc_collection_pause, _g1_compaction_pause, _g1_humongous_allocation, @@ -110,20 +108,16 @@ class GCCause : public AllStatic { // Causes for collection of the tenured gernation inline static bool is_tenured_allocation_failure_gc(GCCause::Cause cause) { - // _adaptive_size_policy for a full collection after a young GC // _allocation_failure is the generic cause a collection which could result // in the collection of the tenured generation if there is not enough space // in the tenured generation to support a young GC. - return (cause == GCCause::_adaptive_size_policy || - cause == GCCause::_allocation_failure); + return cause == GCCause::_allocation_failure; } // Causes for collection of the young generation inline static bool is_allocation_failure_gc(GCCause::Cause cause) { // _allocation_failure is the generic cause a collection for allocation failure - // _adaptive_size_policy is for a collection done before a full GC return (cause == GCCause::_allocation_failure || - cause == GCCause::_adaptive_size_policy || cause == GCCause::_shenandoah_allocation_failure_evac); } diff --git a/src/hotspot/share/gc/shared/gc_globals.hpp b/src/hotspot/share/gc/shared/gc_globals.hpp index 66496544b96..34bc638c9ba 100644 --- a/src/hotspot/share/gc/shared/gc_globals.hpp +++ b/src/hotspot/share/gc/shared/gc_globals.hpp @@ -422,10 +422,6 @@ "Initial ratio of young generation/survivor space size") \ range(0, max_uintx) \ \ - product(size_t, BaseFootPrintEstimate, 256*M, \ - "Estimate of footprint other than Java Heap") \ - range(0, max_uintx) \ - \ product(bool, UseGCOverheadLimit, true, \ "Use policy to limit of proportion of time spent in GC " \ "before an OutOfMemory error is thrown") \ diff --git a/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.cpp b/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.cpp index e0bbd8a6ddc..0759d02cb7c 100644 --- a/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.cpp +++ b/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2024, 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 @@ -497,7 +497,7 @@ static bool prepare_for_emergency_dump(Thread* thread) { Service_lock->unlock(); } - if (UseNotificationThread && Notification_lock->owned_by_self()) { + if (Notification_lock->owned_by_self()) { Notification_lock->unlock(); } diff --git a/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp b/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp index c62257bd23b..79bc97f53ac 100644 --- a/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp +++ b/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2024, 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 @@ -664,7 +664,7 @@ JVMCI::CodeInstallResult CodeInstaller::install_runtime_stub(CodeBlob*& cb, GrowableArray *stubs_to_free = nullptr; #ifdef ASSERT const char* val = Arguments::PropertyList_get_value(Arguments::system_properties(), "test.jvmci.forceRuntimeStubAllocFail"); - if (val != nullptr && strstr(name , val) != 0) { + if (val != nullptr && strstr(name , val) != nullptr) { stubs_to_free = new GrowableArray(); JVMCI_event_1("forcing allocation of %s in code cache to fail", name); } diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp index fb49e9baca2..5a9b18fc4d3 100644 --- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp +++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp @@ -424,7 +424,7 @@ C2V_VMENTRY_NULL(jobject, getResolvedJavaMethod, (JNIEnv* env, jobject, jobject C2V_VMENTRY_NULL(jobject, getConstantPool, (JNIEnv* env, jobject, ARGUMENT_PAIR(klass_or_method), jboolean is_klass)) ConstantPool* cp = nullptr; - if (UNPACK_PAIR(address, klass_or_method) == 0) { + if (UNPACK_PAIR(address, klass_or_method) == nullptr) { JVMCI_THROW_NULL(NullPointerException); } if (!is_klass) { @@ -1098,7 +1098,7 @@ C2V_END C2V_VMENTRY_0(jlong, getMaxCallTargetOffset, (JNIEnv* env, jobject, jlong addr)) address target_addr = (address) addr; - if (target_addr != 0x0) { + if (target_addr != nullptr) { int64_t off_low = (int64_t)target_addr - ((int64_t)CodeCache::low_bound() + sizeof(int)); int64_t off_high = (int64_t)target_addr - ((int64_t)CodeCache::high_bound() + sizeof(int)); return MAX2(ABS(off_low), ABS(off_high)); diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp b/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp index f1028b4b2bb..2116133e56e 100644 --- a/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp +++ b/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp @@ -240,7 +240,7 @@ void CompilerToVM::Data::initialize(JVMCI_TRAPS) { cardtable_shift = CardTable::card_shift(); } else { // No card mark barriers - cardtable_start_address = 0; + cardtable_start_address = nullptr; cardtable_shift = 0; } diff --git a/src/hotspot/share/jvmci/jvmciRuntime.cpp b/src/hotspot/share/jvmci/jvmciRuntime.cpp index 371a6540898..ad0430787aa 100644 --- a/src/hotspot/share/jvmci/jvmciRuntime.cpp +++ b/src/hotspot/share/jvmci/jvmciRuntime.cpp @@ -628,7 +628,7 @@ JRT_LEAF(oopDesc*, JVMCIRuntime::load_and_clear_exception(JavaThread* thread)) oop exception = thread->exception_oop(); assert(exception != nullptr, "npe"); thread->set_exception_oop(nullptr); - thread->set_exception_pc(0); + thread->set_exception_pc(nullptr); return exception; JRT_END diff --git a/src/hotspot/share/opto/escape.cpp b/src/hotspot/share/opto/escape.cpp index 2ca722148b6..eb6887f11ba 100644 --- a/src/hotspot/share/opto/escape.cpp +++ b/src/hotspot/share/opto/escape.cpp @@ -3879,7 +3879,7 @@ PhiNode *ConnectionGraph::create_split_phi(PhiNode *orig_phi, int alias_idx, Gro // Return a new version of Memory Phi "orig_phi" with the inputs having the // specified alias index. // -PhiNode *ConnectionGraph::split_memory_phi(PhiNode *orig_phi, int alias_idx, GrowableArray &orig_phi_worklist) { +PhiNode *ConnectionGraph::split_memory_phi(PhiNode *orig_phi, int alias_idx, GrowableArray &orig_phi_worklist, uint rec_depth) { assert(alias_idx != Compile::AliasIdxBot, "can't split out bottom memory"); Compile *C = _compile; PhaseGVN* igvn = _igvn; @@ -3895,7 +3895,7 @@ PhiNode *ConnectionGraph::split_memory_phi(PhiNode *orig_phi, int alias_idx, Gro bool finished = false; while(!finished) { while (idx < phi->req()) { - Node *mem = find_inst_mem(phi->in(idx), alias_idx, orig_phi_worklist); + Node *mem = find_inst_mem(phi->in(idx), alias_idx, orig_phi_worklist, rec_depth + 1); if (mem != nullptr && mem->is_Phi()) { PhiNode *newphi = create_split_phi(mem->as_Phi(), alias_idx, orig_phi_worklist, new_phi_created); if (new_phi_created) { @@ -4037,7 +4037,12 @@ void ConnectionGraph::move_inst_mem(Node* n, GrowableArray &orig_phi // Search memory chain of "mem" to find a MemNode whose address // is the specified alias index. // -Node* ConnectionGraph::find_inst_mem(Node *orig_mem, int alias_idx, GrowableArray &orig_phis) { +#define FIND_INST_MEM_RECURSION_DEPTH_LIMIT 1000 +Node* ConnectionGraph::find_inst_mem(Node *orig_mem, int alias_idx, GrowableArray &orig_phis, uint rec_depth) { + if (rec_depth > FIND_INST_MEM_RECURSION_DEPTH_LIMIT) { + _compile->record_failure(_invocation > 0 ? C2Compiler::retry_no_iterative_escape_analysis() : C2Compiler::retry_no_escape_analysis()); + return nullptr; + } if (orig_mem == nullptr) { return orig_mem; } @@ -4111,7 +4116,7 @@ Node* ConnectionGraph::find_inst_mem(Node *orig_mem, int alias_idx, GrowableArra if (result == mmem->base_memory()) { // Didn't find instance memory, search through general slice recursively. result = mmem->memory_at(C->get_general_index(alias_idx)); - result = find_inst_mem(result, alias_idx, orig_phis); + result = find_inst_mem(result, alias_idx, orig_phis, rec_depth + 1); if (C->failing()) { return nullptr; } @@ -4179,7 +4184,7 @@ Node* ConnectionGraph::find_inst_mem(Node *orig_mem, int alias_idx, GrowableArra orig_phis.append_if_missing(mphi); } else if (C->get_alias_index(t) != alias_idx) { // Create a new Phi with the specified alias index type. - result = split_memory_phi(mphi, alias_idx, orig_phis); + result = split_memory_phi(mphi, alias_idx, orig_phis, rec_depth + 1); } } // the result is either MemNode, PhiNode, InitializeNode. diff --git a/src/hotspot/share/opto/escape.hpp b/src/hotspot/share/opto/escape.hpp index 658c8f6e8fe..32e70be219a 100644 --- a/src/hotspot/share/opto/escape.hpp +++ b/src/hotspot/share/opto/escape.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, 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 @@ -549,10 +549,10 @@ class ConnectionGraph: public ArenaObj { bool split_AddP(Node *addp, Node *base); PhiNode *create_split_phi(PhiNode *orig_phi, int alias_idx, GrowableArray &orig_phi_worklist, bool &new_created); - PhiNode *split_memory_phi(PhiNode *orig_phi, int alias_idx, GrowableArray &orig_phi_worklist); + PhiNode *split_memory_phi(PhiNode *orig_phi, int alias_idx, GrowableArray &orig_phi_worklist, uint rec_depth); void move_inst_mem(Node* n, GrowableArray &orig_phis); - Node* find_inst_mem(Node* mem, int alias_idx,GrowableArray &orig_phi_worklist); + Node* find_inst_mem(Node* mem, int alias_idx,GrowableArray &orig_phi_worklist, uint rec_depth = 0); Node* step_through_mergemem(MergeMemNode *mmem, int alias_idx, const TypeOopPtr *toop); Node_Array _node_map; // used for bookkeeping during type splitting diff --git a/src/hotspot/share/opto/movenode.cpp b/src/hotspot/share/opto/movenode.cpp index eb0a914b994..dc65afff26f 100644 --- a/src/hotspot/share/opto/movenode.cpp +++ b/src/hotspot/share/opto/movenode.cpp @@ -91,17 +91,20 @@ Node *CMoveNode::Ideal(PhaseGVN *phase, bool can_reshape) { phase->type(in(IfTrue)) == Type::TOP) { return nullptr; } - // Canonicalize the node by moving constants to the right input. - if (in(Condition)->is_Bool() && phase->type(in(IfFalse))->singleton() && !phase->type(in(IfTrue))->singleton()) { - BoolNode* b = in(Condition)->as_Bool()->negate(phase); - return make(in(Control), phase->transform(b), in(IfTrue), in(IfFalse), _type); - } + // Check for Min/Max patterns. This is called before constants are pushed to the right input, as that transform can + // make BoolTests non-canonical. Node* minmax = Ideal_minmax(phase, this); if (minmax != nullptr) { return minmax; } + // Canonicalize the node by moving constants to the right input. + if (in(Condition)->is_Bool() && phase->type(in(IfFalse))->singleton() && !phase->type(in(IfTrue))->singleton()) { + BoolNode* b = in(Condition)->as_Bool()->negate(phase); + return make(in(Control), phase->transform(b), in(IfTrue), in(IfFalse), _type); + } + return nullptr; } diff --git a/src/hotspot/share/opto/output.cpp b/src/hotspot/share/opto/output.cpp index 42374a0bcd4..b3f251bb361 100644 --- a/src/hotspot/share/opto/output.cpp +++ b/src/hotspot/share/opto/output.cpp @@ -716,7 +716,7 @@ ObjectValue* PhaseOutput::sv_for_node_id(GrowableArray *objs, int id) { for (int i = 0; i < objs->length(); i++) { assert(objs->at(i)->is_object(), "corrupt object cache"); - ObjectValue* sv = (ObjectValue*) objs->at(i); + ObjectValue* sv = objs->at(i)->as_ObjectValue(); if (sv->id() == id) { return sv; } @@ -755,7 +755,7 @@ void PhaseOutput::FillLocArray( int idx, MachSafePointNode* sfpt, Node *local, if (local->is_SafePointScalarObject()) { SafePointScalarObjectNode* spobj = local->as_SafePointScalarObject(); - ObjectValue* sv = (ObjectValue*) sv_for_node_id(objs, spobj->_idx); + ObjectValue* sv = sv_for_node_id(objs, spobj->_idx); if (sv == nullptr) { ciKlass* cik = t->is_oopptr()->exact_klass(); assert(cik->is_instance_klass() || @@ -987,7 +987,7 @@ bool PhaseOutput::contains_as_scalarized_obj(JVMState* jvms, MachSafePointNode* continue; } - ObjectValue* other = (ObjectValue*) sv_for_node_id(objs, n->_idx); + ObjectValue* other = sv_for_node_id(objs, n->_idx); if (ov == other) { return true; } diff --git a/src/hotspot/share/prims/jni.cpp b/src/hotspot/share/prims/jni.cpp index ae040d66138..a91d7375761 100644 --- a/src/hotspot/share/prims/jni.cpp +++ b/src/hotspot/share/prims/jni.cpp @@ -1148,7 +1148,7 @@ JNI_ENTRY(ResultType, \ jni_Call##Result##Method(JNIEnv *env, jobject obj, jmethodID methodID, ...)) \ \ EntryProbe; \ - ResultType ret = 0;\ + ResultType ret{}; \ DT_RETURN_MARK_FOR(Result, Call##Result##Method, ResultType, \ (const ResultType&)ret);\ \ @@ -1203,7 +1203,7 @@ JNI_ENTRY(ResultType, \ jni_Call##Result##MethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)) \ \ EntryProbe;\ - ResultType ret = 0;\ + ResultType ret{}; \ DT_RETURN_MARK_FOR(Result, Call##Result##MethodV, ResultType, \ (const ResultType&)ret);\ \ @@ -1254,7 +1254,7 @@ DEFINE_CALLMETHODV(jdouble, Double, T_DOUBLE JNI_ENTRY(ResultType, \ jni_Call##Result##MethodA(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args)) \ EntryProbe; \ - ResultType ret = 0;\ + ResultType ret{}; \ DT_RETURN_MARK_FOR(Result, Call##Result##MethodA, ResultType, \ (const ResultType&)ret);\ \ @@ -1546,7 +1546,7 @@ JNI_ENTRY(ResultType, \ jni_CallStatic##Result##Method(JNIEnv *env, jclass cls, jmethodID methodID, ...)) \ \ EntryProbe; \ - ResultType ret = 0;\ + ResultType ret{}; \ DT_RETURN_MARK_FOR(Result, CallStatic##Result##Method, ResultType, \ (const ResultType&)ret);\ \ @@ -1601,7 +1601,7 @@ JNI_ENTRY(ResultType, \ jni_CallStatic##Result##MethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args)) \ \ EntryProbe; \ - ResultType ret = 0;\ + ResultType ret{}; \ DT_RETURN_MARK_FOR(Result, CallStatic##Result##MethodV, ResultType, \ (const ResultType&)ret);\ \ @@ -1657,7 +1657,7 @@ JNI_ENTRY(ResultType, \ jni_CallStatic##Result##MethodA(JNIEnv *env, jclass cls, jmethodID methodID, const jvalue *args)) \ \ EntryProbe; \ - ResultType ret = 0;\ + ResultType ret{}; \ DT_RETURN_MARK_FOR(Result, CallStatic##Result##MethodA, ResultType, \ (const ResultType&)ret);\ \ @@ -1750,7 +1750,7 @@ DT_RETURN_MARK_DECL(GetFieldID, jfieldID JNI_ENTRY(jfieldID, jni_GetFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig)) HOTSPOT_JNI_GETFIELDID_ENTRY(env, clazz, (char *) name, (char *) sig); - jfieldID ret = 0; + jfieldID ret = nullptr; DT_RETURN_MARK(GetFieldID, jfieldID, (const jfieldID&)ret); Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)); @@ -3035,12 +3035,12 @@ extern "C" void* JNICALL jni_GetDirectBufferAddress(JNIEnv *env, jobject buf) if (!directBufferSupportInitializeEnded) { if (!initializeDirectBufferSupport(env, thread)) { - return 0; + return nullptr; } } if ((buf != nullptr) && (!env->IsInstanceOf(buf, directBufferClass))) { - return 0; + return nullptr; } ret = (void*)(intptr_t)env->GetLongField(buf, directBufferAddressField); @@ -3647,8 +3647,8 @@ static jint JNI_CreateJavaVM_inner(JavaVM **vm, void **penv, void *args) { } // Creation failed. We must reset vm_created - *vm = 0; - *(JNIEnv**)penv = 0; + *vm = nullptr; + *(JNIEnv**)penv = nullptr; // reset vm_created last to avoid race condition. Use OrderAccess to // control both compiler and architectural-based reordering. assert(vm_created == IN_PROGRESS, "must be"); diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp index 6aabb65ca40..4f63ebdf9d5 100644 --- a/src/hotspot/share/prims/jvm.cpp +++ b/src/hotspot/share/prims/jvm.cpp @@ -3747,7 +3747,7 @@ JVM_ENTRY(jobjectArray, JVM_DumpThreads(JNIEnv *env, jclass threadClass, jobject // Check if threads is null if (threads == nullptr) { - THROW_(vmSymbols::java_lang_NullPointerException(), 0); + THROW_NULL(vmSymbols::java_lang_NullPointerException()); } objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(threads)); @@ -3755,13 +3755,13 @@ JVM_ENTRY(jobjectArray, JVM_DumpThreads(JNIEnv *env, jclass threadClass, jobject int num_threads = ah->length(); // check if threads is non-empty array if (num_threads == 0) { - THROW_(vmSymbols::java_lang_IllegalArgumentException(), 0); + THROW_NULL(vmSymbols::java_lang_IllegalArgumentException()); } // check if threads is not an array of objects of Thread class Klass* k = ObjArrayKlass::cast(ah->klass())->element_klass(); if (k != vmClasses::Thread_klass()) { - THROW_(vmSymbols::java_lang_IllegalArgumentException(), 0); + THROW_NULL(vmSymbols::java_lang_IllegalArgumentException()); } ResourceMark rm(THREAD); diff --git a/src/hotspot/share/prims/jvmtiExport.cpp b/src/hotspot/share/prims/jvmtiExport.cpp index c2b6d27986b..f79116f5ebe 100644 --- a/src/hotspot/share/prims/jvmtiExport.cpp +++ b/src/hotspot/share/prims/jvmtiExport.cpp @@ -2068,7 +2068,7 @@ void JvmtiExport::post_exception_throw(JavaThread *thread, Method* method, addre jmethodID catch_jmethodID; if (current_bci < 0) { - catch_jmethodID = 0; + catch_jmethodID = nullptr; current_bci = 0; } else { catch_jmethodID = jem.to_jmethodID(current_mh); @@ -2105,8 +2105,8 @@ void JvmtiExport::notice_unwind_due_to_exception(JavaThread *thread, Method* met JvmtiTrace::safe_get_thread_name(thread), (mh() == nullptr) ? "null" : mh()->klass_name()->as_C_string(), (mh() == nullptr) ? "null" : mh()->name()->as_C_string(), - location==0? "no location:" : "", - location==0? 0 : location - mh()->code_base(), + location == nullptr ? "no location:" : "", + location == nullptr ? 0 : location - mh()->code_base(), in_handler_frame? "in handler frame" : "not handler frame" )); if (state->is_exception_detected()) { diff --git a/src/hotspot/share/prims/jvmtiTrace.cpp b/src/hotspot/share/prims/jvmtiTrace.cpp index 002f59957ea..c5fb95c931b 100644 --- a/src/hotspot/share/prims/jvmtiTrace.cpp +++ b/src/hotspot/share/prims/jvmtiTrace.cpp @@ -261,7 +261,7 @@ void JvmtiTrace::shutdown() { const char* JvmtiTrace::enum_name(const char** names, const jint* values, jint value) { - for (int index = 0; names[index] != 0; ++index) { + for (int index = 0; names[index] != nullptr; ++index) { if (values[index] == value) { return names[index]; } diff --git a/src/hotspot/share/prims/methodHandles.cpp b/src/hotspot/share/prims/methodHandles.cpp index fd10f0723bf..473ac396997 100644 --- a/src/hotspot/share/prims/methodHandles.cpp +++ b/src/hotspot/share/prims/methodHandles.cpp @@ -436,7 +436,6 @@ Symbol* MethodHandles::signature_polymorphic_intrinsic_name(vmIntrinsics::ID iid case vmIntrinsics::_linkToNative: return vmSymbols::linkToNative_name(); default: fatal("unexpected intrinsic id: %d %s", vmIntrinsics::as_int(iid), vmIntrinsics::name_at(iid)); - return 0; } } @@ -449,7 +448,6 @@ Bytecodes::Code MethodHandles::signature_polymorphic_intrinsic_bytecode(vmIntrin case vmIntrinsics::_invokeBasic: return Bytecodes::_invokehandle; default: fatal("unexpected id: (%d) %s", (uint)id, vmIntrinsics::name_at(id)); - return Bytecodes::_illegal; } } @@ -463,7 +461,6 @@ int MethodHandles::signature_polymorphic_intrinsic_ref_kind(vmIntrinsics::ID iid case vmIntrinsics::_linkToInterface: return JVM_REF_invokeInterface; default: fatal("unexpected intrinsic id: %d %s", vmIntrinsics::as_int(iid), vmIntrinsics::name_at(iid)); - return 0; } } diff --git a/src/hotspot/share/prims/perf.cpp b/src/hotspot/share/prims/perf.cpp index f10854b5294..9ff831dded9 100644 --- a/src/hotspot/share/prims/perf.cpp +++ b/src/hotspot/share/prims/perf.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, 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 @@ -68,7 +68,7 @@ PERF_ENTRY(jobject, Perf_Attach(JNIEnv *env, jobject unused, int vmid)) PerfWrapper("Perf_Attach"); - char* address = 0; + char* address = nullptr; size_t capacity = 0; // attach to the PerfData memory region for the specified VM @@ -90,7 +90,7 @@ PERF_ENTRY(void, Perf_Detach(JNIEnv *env, jobject unused, jobject buffer)) return; } - void* address = 0; + void* address = nullptr; jlong capacity = 0; // get buffer address and capacity diff --git a/src/hotspot/share/prims/unsafe.cpp b/src/hotspot/share/prims/unsafe.cpp index 942d9100c29..1be157b2e44 100644 --- a/src/hotspot/share/prims/unsafe.cpp +++ b/src/hotspot/share/prims/unsafe.cpp @@ -652,7 +652,7 @@ static jclass Unsafe_DefineClass_impl(JNIEnv *env, jstring name, jbyteArray data jbyte *body; char *utfName = nullptr; - jclass result = 0; + jclass result = nullptr; char buf[128]; assert(data != nullptr, "Class bytes must not be null"); @@ -665,7 +665,7 @@ static jclass Unsafe_DefineClass_impl(JNIEnv *env, jstring name, jbyteArray data body = NEW_C_HEAP_ARRAY_RETURN_NULL(jbyte, length, mtInternal); if (body == nullptr) { throw_new(env, "java/lang/OutOfMemoryError"); - return 0; + return nullptr; } env->GetByteArrayRegion(data, offset, length, body); diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp index 1bded291650..9086a5f6c71 100644 --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -503,7 +503,6 @@ static SpecialFlag const special_jvm_flags[] = { { "RequireSharedSpaces", JDK_Version::jdk(18), JDK_Version::jdk(19), JDK_Version::undefined() }, { "UseSharedSpaces", JDK_Version::jdk(18), JDK_Version::jdk(19), JDK_Version::undefined() }, { "DontYieldALot", JDK_Version::jdk(23), JDK_Version::jdk(24), JDK_Version::jdk(25) }, - { "UseNotificationThread", JDK_Version::jdk(23), JDK_Version::jdk(24), JDK_Version::jdk(25) }, { "LockingMode", JDK_Version::jdk(24), JDK_Version::jdk(26), JDK_Version::jdk(27) }, // --- Deprecated alias flags (see also aliased_jvm_flags) - sorted by obsolete_in then expired_in: { "CreateMinidumpOnCrash", JDK_Version::jdk(9), JDK_Version::undefined(), JDK_Version::undefined() }, @@ -512,6 +511,7 @@ static SpecialFlag const special_jvm_flags[] = { { "MetaspaceReclaimPolicy", JDK_Version::undefined(), JDK_Version::jdk(21), JDK_Version::undefined() }, + { "UseNotificationThread", JDK_Version::jdk(23), JDK_Version::jdk(24), JDK_Version::jdk(25) }, { "PreserveAllAnnotations", JDK_Version::jdk(23), JDK_Version::jdk(24), JDK_Version::jdk(25) }, { "UseEmptySlotsInSupers", JDK_Version::jdk(23), JDK_Version::jdk(24), JDK_Version::jdk(25) }, { "OldSize", JDK_Version::jdk(23), JDK_Version::jdk(24), JDK_Version::jdk(25) }, @@ -521,6 +521,8 @@ static SpecialFlag const special_jvm_flags[] = { { "RTMRetryCount", JDK_Version::jdk(23), JDK_Version::jdk(24), JDK_Version::jdk(25) }, #endif // X86 + + { "BaseFootPrintEstimate", JDK_Version::undefined(), JDK_Version::jdk(24), JDK_Version::jdk(25) }, { "HeapFirstMaximumCompactionCount", JDK_Version::undefined(), JDK_Version::jdk(24), JDK_Version::jdk(25) }, { "UseVtableBasedCHA", JDK_Version::undefined(), JDK_Version::jdk(24), JDK_Version::jdk(25) }, #ifdef ASSERT @@ -1653,9 +1655,6 @@ jint Arguments::set_aggressive_heap_flags() { #endif // Increase some data structure sizes for efficiency - if (FLAG_SET_CMDLINE(BaseFootPrintEstimate, MaxHeapSize) != JVMFlag::SUCCESS) { - return JNI_EINVAL; - } if (FLAG_SET_CMDLINE(ResizeTLAB, false) != JVMFlag::SUCCESS) { return JNI_EINVAL; } diff --git a/src/hotspot/share/runtime/globals.hpp b/src/hotspot/share/runtime/globals.hpp index 562549f247e..61efc0b9376 100644 --- a/src/hotspot/share/runtime/globals.hpp +++ b/src/hotspot/share/runtime/globals.hpp @@ -952,9 +952,6 @@ const int ObjectAlignmentInBytes = 8; product(bool, EnableThreadSMRStatistics, trueInDebug, DIAGNOSTIC, \ "Enable Thread SMR Statistics") \ \ - product(bool, UseNotificationThread, true, \ - "(Deprecated) Use Notification Thread") \ - \ product(bool, Inline, true, \ "Enable inlining") \ \ diff --git a/src/hotspot/share/runtime/mutexLocker.cpp b/src/hotspot/share/runtime/mutexLocker.cpp index add47738db0..a63014d78a1 100644 --- a/src/hotspot/share/runtime/mutexLocker.cpp +++ b/src/hotspot/share/runtime/mutexLocker.cpp @@ -235,13 +235,8 @@ void mutex_init() { MUTEX_DEFN(Patching_lock , PaddedMutex , nosafepoint); // used for safepointing and code patching. MUTEX_DEFN(MonitorDeflation_lock , PaddedMonitor, nosafepoint); // used for monitor deflation thread operations - MUTEX_DEFN(Service_lock , PaddedMonitor, service); // used for service thread operations - - if (UseNotificationThread) { - MUTEX_DEFN(Notification_lock , PaddedMonitor, service); // used for notification thread operations - } else { - Notification_lock = Service_lock; - } + MUTEX_DEFN(Service_lock , PaddedMonitor, service); // used for service thread operations + MUTEX_DEFN(Notification_lock , PaddedMonitor, service); // used for notification thread operations MUTEX_DEFN(JmethodIdCreation_lock , PaddedMutex , nosafepoint-2); // used for creating jmethodIDs. MUTEX_DEFN(InvokeMethodTypeTable_lock , PaddedMutex , safepoint); diff --git a/src/hotspot/share/runtime/serviceThread.cpp b/src/hotspot/share/runtime/serviceThread.cpp index f02e5062e67..a81285ac97c 100644 --- a/src/hotspot/share/runtime/serviceThread.cpp +++ b/src/hotspot/share/runtime/serviceThread.cpp @@ -81,10 +81,7 @@ static void cleanup_oopstorages() { void ServiceThread::service_thread_entry(JavaThread* jt, TRAPS) { while (true) { - bool sensors_changed = false; bool has_jvmti_events = false; - bool has_gc_notification_event = false; - bool has_dcmd_notification_event = false; bool stringtable_work = false; bool symboltable_work = false; bool finalizerservice_work = false; @@ -113,10 +110,7 @@ void ServiceThread::service_thread_entry(JavaThread* jt, TRAPS) { // only the first recognized bit of work, to avoid frequently true early // tests from potentially starving later work. Hence the use of // arithmetic-or to combine results; we don't want short-circuiting. - while (((sensors_changed = (!UseNotificationThread && LowMemoryDetector::has_pending_requests())) | - (has_jvmti_events = _jvmti_service_queue.has_events()) | - (has_gc_notification_event = (!UseNotificationThread && GCNotifier::has_event())) | - (has_dcmd_notification_event = (!UseNotificationThread && DCmdFactory::has_pending_jmx_notification())) | + while (((has_jvmti_events = _jvmti_service_queue.has_events()) | (stringtable_work = StringTable::has_work()) | (symboltable_work = SymbolTable::has_work()) | (finalizerservice_work = FinalizerService::has_work()) | @@ -158,20 +152,6 @@ void ServiceThread::service_thread_entry(JavaThread* jt, TRAPS) { _jvmti_event = nullptr; // reset } - if (!UseNotificationThread) { - if (sensors_changed) { - LowMemoryDetector::process_sensor_changes(jt); - } - - if(has_gc_notification_event) { - GCNotifier::sendNotification(CHECK); - } - - if(has_dcmd_notification_event) { - DCmdFactory::send_notification(CHECK); - } - } - if (resolved_method_table_work) { ResolvedMethodTable::do_concurrent_work(jt); } diff --git a/src/hotspot/share/services/lowMemoryDetector.hpp b/src/hotspot/share/services/lowMemoryDetector.hpp index 5c1201b4641..73491ea8412 100644 --- a/src/hotspot/share/services/lowMemoryDetector.hpp +++ b/src/hotspot/share/services/lowMemoryDetector.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, 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 @@ -61,8 +61,7 @@ // // May need to deal with hysteresis effect. // -// Memory detection code runs in the Notification thread or -// ServiceThread depending on UseNotificationThread flag. +// Memory detection code runs in the Notification thread. class OopClosure; class MemoryPool; diff --git a/src/hotspot/share/services/management.cpp b/src/hotspot/share/services/management.cpp index a9bb72a481a..2c9f36c098d 100644 --- a/src/hotspot/share/services/management.cpp +++ b/src/hotspot/share/services/management.cpp @@ -149,9 +149,8 @@ void Management::init() { } void Management::initialize(TRAPS) { - if (UseNotificationThread) { - NotificationThread::initialize(); - } + NotificationThread::initialize(); + if (ManagementServer) { ResourceMark rm(THREAD); HandleMark hm(THREAD); diff --git a/src/java.desktop/macosx/classes/com/apple/laf/AquaProgressBarUI.java b/src/java.desktop/macosx/classes/com/apple/laf/AquaProgressBarUI.java index bf66a1b4b08..71500f3a95c 100644 --- a/src/java.desktop/macosx/classes/com/apple/laf/AquaProgressBarUI.java +++ b/src/java.desktop/macosx/classes/com/apple/laf/AquaProgressBarUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2024, 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 @@ -256,7 +256,7 @@ protected Point getStringPlacement(final Graphics g, final String progressString y = oldX; } - return new Point(x + Math.round(width / 2 - stringWidth / 2), y + ((height + fontSizer.getAscent() - fontSizer.getLeading() - fontSizer.getDescent()) / 2) - 1); + return new Point(x + (width / 2 - stringWidth / 2), y + ((height + fontSizer.getAscent() - fontSizer.getLeading() - fontSizer.getDescent()) / 2) - 1); } static Dimension getCircularPreferredSize() { diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/GCCause.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/GCCause.java index 4320f61bf36..b301f774390 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/GCCause.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/GCCause.java @@ -48,8 +48,6 @@ public enum GCCause { _metadata_GC_threshold ("Metadata GC Threshold"), _metadata_GC_clear_soft_refs ("Metadata GC Clear Soft References"), - _adaptive_size_policy ("Ergonomics"), - _g1_inc_collection_pause ("G1 Evacuation Pause"), _g1_compaction_pause ("G1 Compaction Pause"), _g1_humongous_allocation ("G1 Humongous Allocation"), diff --git a/src/jdk.internal.jvmstat/share/classes/sun/jvmstat/perfdata/resources/aliasmap b/src/jdk.internal.jvmstat/share/classes/sun/jvmstat/perfdata/resources/aliasmap index 5993acf701f..001ce5b5cac 100644 --- a/src/jdk.internal.jvmstat/share/classes/sun/jvmstat/perfdata/resources/aliasmap +++ b/src/jdk.internal.jvmstat/share/classes/sun/jvmstat/perfdata/resources/aliasmap @@ -404,8 +404,6 @@ alias sun.gc.lastCause // 1.5.0 b39 hotspot.gc.last_cause // 1.4.2_02 // sun.gc.policy -alias sun.gc.policy.avgBaseFootprint // 1.5.0 b39 - hotspot.gc.policy.avg_base_footprint // 1.5.0 b21 alias sun.gc.policy.avgMajorIntervalTime // 1.5.0 b39 hotspot.gc.policy.avg_major_interval // 1.5.0 b21 alias sun.gc.policy.avgMajorPauseTime // 1.5.0 b39 diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/ArgumentParser.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/ArgumentParser.java index a614516d295..c14ce6025ce 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/ArgumentParser.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/ArgumentParser.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2024, 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 @@ -32,6 +32,7 @@ import java.util.Set; import java.util.StringJoiner; import jdk.jfr.internal.util.SpellChecker; +import jdk.jfr.internal.util.TimespanUnit; final class ArgumentParser { private final Map options = new HashMap<>(); @@ -302,16 +303,11 @@ private Object parseNanotime(String name, String text) { } throw new IllegalArgumentException("Integer parsing error nanotime value: unit required"); } - return switch(unit) { - case "ns" -> time; - case "us" -> time * 1000; - case "ms" -> time * 1000 * 1000; - case "s" -> time * 1000 * 1000 * 1000; - case "m" -> time * 60 * 1000 * 1000 * 1000; - case "h" -> time * 60 * 60* 1000 * 1000 * 1000; - case "d" -> time * 24 * 60 * 60 * 1000 * 1000 * 1000; - default -> throw new IllegalArgumentException("Integer parsing error nanotime value: illegal unit"); - }; + TimespanUnit tu = TimespanUnit.fromText(unit); + if (tu == null) { + throw new IllegalArgumentException("Integer parsing error nanotime value: illegal unit"); + } + return tu.toNanos(time); } int indexOfUnit(String text) { diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/model/Utilities.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/model/Utilities.java index 76e834fe6eb..281a0c57949 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/model/Utilities.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/model/Utilities.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2024, 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,11 +25,9 @@ package jdk.jfr.internal.jfc.model; import java.util.StringJoiner; +import jdk.jfr.internal.util.TimespanUnit; public final class Utilities { - private static final String[] UNITS = new String[] { - "ns", "us", "ns", "ms", "s", "m", "h", "d" // order matters - }; static XmlElement instantiate(Class type) { try { @@ -104,9 +102,9 @@ static void checkValid(String value, Object... valid) { static String parseTimespan(String s) { StringBuilder sb = new StringBuilder(); try { - for (String unit : UNITS) { - if (s.endsWith(unit)) { - return parseForUnit(s, unit); + for (TimespanUnit timespan : TimespanUnit.values()) { + if (s.endsWith(timespan.text)) { + return parseForUnit(s, timespan.text); } } Long.parseLong(s); diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/util/TimespanUnit.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/util/TimespanUnit.java index 9026f59b68b..0fdde833beb 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/util/TimespanUnit.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/util/TimespanUnit.java @@ -24,21 +24,29 @@ */ package jdk.jfr.internal.util; +import java.util.concurrent.TimeUnit; + public enum TimespanUnit { - NANOSECONDS ("ns", 1L, 1000), - MICROSECONDS("us", 1000L, 1000), - MILLISECONDS("ms", 1_000_000L, 1000), - SECONDS ("s", 1_000_000_000L, 60), - MINUTES ("m", 60 * 1_000_000_000L, 60), - HOURS ("h", 60 * 60 * 1_000_000_000L, 24), - DAYS ("d", 24 * 60 * 60 * 1_000_000_000L, 7); + NANOSECONDS ("ns", TimeUnit.NANOSECONDS, 1000), + MICROSECONDS("us", TimeUnit.MICROSECONDS, 1000), + MILLISECONDS("ms", TimeUnit.MILLISECONDS, 1000), + SECONDS ("s", TimeUnit.SECONDS, 60), + MINUTES ("m", TimeUnit.MINUTES, 60), + HOURS ("h", TimeUnit.HOURS, 24), + DAYS ("d", TimeUnit.DAYS, 7); public final String text; public final long nanos; public final int size; - TimespanUnit(String text, long nanos, int size) { + private final TimeUnit timeUnit; + TimespanUnit(String text, TimeUnit tu, int size) { this.text = text; - this.nanos = nanos; + this.nanos = tu.toNanos(1); this.size = size; + this.timeUnit = tu; + } + + public long toNanos(long value) { + return timeUnit.toNanos(value); } public static TimespanUnit fromText(String text) { diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/util/ValueParser.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/util/ValueParser.java index e4482c92368..cf112d3beb5 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/util/ValueParser.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/util/ValueParser.java @@ -51,26 +51,12 @@ public static long parseTimespanWithInfinity(String s) { } public static long parseTimespan(String s) { - if (s.endsWith("ns")) { - return Long.parseLong(s.substring(0, s.length() - 2).trim()); - } - if (s.endsWith("us")) { - return MICROSECONDS.toNanos(Long.parseLong(s.substring(0, s.length() - 2).trim())); - } - if (s.endsWith("ms")) { - return MILLISECONDS.toNanos(Long.parseLong(s.substring(0, s.length() - 2).trim())); - } - if (s.endsWith("s")) { - return SECONDS.toNanos(Long.parseLong(s.substring(0, s.length() - 1).trim())); - } - if (s.endsWith("m")) { - return MINUTES.toNanos(Long.parseLong(s.substring(0, s.length() - 1).trim())); - } - if (s.endsWith("h")) { - return HOURS.toNanos(Long.parseLong(s.substring(0, s.length() - 1).trim())); - } - if (s.endsWith("d")) { - return DAYS.toNanos(Long.parseLong(s.substring(0, s.length() - 1).trim())); + for (TimespanUnit unit : TimespanUnit.values()) { + String text = unit.text; + if (s.endsWith(text)) { + long value = Long.parseLong(s.substring(0, s.length() - text.length()).strip()); + return unit.toNanos(value); + } } try { diff --git a/test/hotspot/gtest/classfile/test_placeholders.cpp b/test/hotspot/gtest/classfile/test_placeholders.cpp index 4179a1fc695..8cd9536271e 100644 --- a/test/hotspot/gtest/classfile/test_placeholders.cpp +++ b/test/hotspot/gtest/classfile/test_placeholders.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2024, 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 @@ -49,7 +49,7 @@ TEST_VM(PlaceholderTable, supername) { { MutexLocker ml(THREAD, SystemDictionary_lock); - PlaceholderTable::classloadAction super_action = PlaceholderTable::LOAD_SUPER; + PlaceholderTable::classloadAction super_action = PlaceholderTable::DETECT_CIRCULARITY; PlaceholderTable::classloadAction define_action = PlaceholderTable::DEFINE_CLASS; // DefineClass A and D @@ -71,7 +71,7 @@ TEST_VM(PlaceholderTable, supername) { // Another thread comes in and finds A loading Super PlaceholderEntry* placeholder = PlaceholderTable::get_entry(A, loader_data); - SymbolHandle supername = placeholder->supername(); + SymbolHandle supername = placeholder->next_klass_name(); // Other thread is done before handle_parallel_super_load PlaceholderTable::find_and_remove(A, loader_data, super_action, THREAD); @@ -86,7 +86,7 @@ TEST_VM(PlaceholderTable, supername) { // Refcount should be 3: one in table for class A, one in table for class D // and one locally with SymbolHandle keeping it alive placeholder = PlaceholderTable::get_entry(A, loader_data); - supername = placeholder->supername(); + supername = placeholder->next_klass_name(); EXPECT_EQ(super->refcount(), 3) << "super class name refcount should be 3"; // Second thread's done too diff --git a/test/hotspot/jtreg/compiler/c2/irTests/TestIfMinMax.java b/test/hotspot/jtreg/compiler/c2/irTests/TestIfMinMax.java index 41402036aea..e232895257a 100644 --- a/test/hotspot/jtreg/compiler/c2/irTests/TestIfMinMax.java +++ b/test/hotspot/jtreg/compiler/c2/irTests/TestIfMinMax.java @@ -30,7 +30,7 @@ /* * @test - * @bug 8324655 8329797 + * @bug 8324655 8329797 8331090 * @key randomness * @summary Test that if expressions are properly folded into min/max nodes * @requires os.arch != "riscv64" @@ -505,7 +505,27 @@ public void checkTestMinLongVector(Object[] vals) { } } - @Run(test = { "testMinI1", "testMinI2", "testMaxI1", "testMaxI2", "testMinI1E", "testMinI2E", "testMaxI1E", "testMaxI2E" }) + @Test + @IR(failOn = { IRNode.IF }, counts = { IRNode.MIN_I, "1" }) + public int testMinIConst(int a) { + if (a > 65535) { + a = 65535; + } + + return a; + } + + @Test + @IR(phase = { CompilePhase.BEFORE_MACRO_EXPANSION }, failOn = { IRNode.IF }, counts = { IRNode.MIN_L, "1" }) + public long testMinLConst(long a) { + if (a > 65535) { + a = 65535; + } + + return a; + } + + @Run(test = { "testMinI1", "testMinI2", "testMaxI1", "testMaxI2", "testMinI1E", "testMinI2E", "testMaxI1E", "testMaxI2E", "testMinIConst" }) public void runTestIntegers() { testIntegers(10, 20); testIntegers(20, 10); @@ -526,9 +546,12 @@ public void testIntegers(int a, int b) { Asserts.assertEQ(a >= b ? b : a, testMinI2E(a, b)); Asserts.assertEQ(a >= b ? a : b, testMaxI1E(a, b)); Asserts.assertEQ(a <= b ? b : a, testMaxI2E(a, b)); + + Asserts.assertEQ(a > 65535 ? 65535 : a, testMinIConst(a)); + Asserts.assertEQ(b > 65535 ? 65535 : b, testMinIConst(b)); } - @Run(test = { "testMinL1", "testMinL2", "testMaxL1", "testMaxL2", "testMinL1E", "testMinL2E", "testMaxL1E", "testMaxL2E" }) + @Run(test = { "testMinL1", "testMinL2", "testMaxL1", "testMaxL2", "testMinL1E", "testMinL2E", "testMaxL1E", "testMaxL2E", "testMinLConst" }) public void runTestLongs() { testLongs(10, 20); testLongs(20, 10); @@ -551,5 +574,8 @@ public void testLongs(long a, long b) { Asserts.assertEQ(a >= b ? b : a, testMinL2E(a, b)); Asserts.assertEQ(a >= b ? a : b, testMaxL1E(a, b)); Asserts.assertEQ(a <= b ? b : a, testMaxL2E(a, b)); + + Asserts.assertEQ(a > 65535L ? 65535L : a, testMinLConst(a)); + Asserts.assertEQ(b > 65535L ? 65535L : b, testMinLConst(b)); } } diff --git a/test/hotspot/jtreg/compiler/c2/irTests/gc/ReferenceRefersToTests.java b/test/hotspot/jtreg/compiler/c2/irTests/gc/ReferenceRefersToTests.java new file mode 100644 index 00000000000..7cf7c72c8fd --- /dev/null +++ b/test/hotspot/jtreg/compiler/c2/irTests/gc/ReferenceRefersToTests.java @@ -0,0 +1,156 @@ +/* + * Copyright Amazon.com Inc. 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. + */ +package compiler.c2.irTests.gc; + +import jdk.test.lib.Asserts; +import compiler.lib.ir_framework.*; +import jdk.test.whitebox.gc.GC; + +import java.lang.ref.*; +import java.util.*; + +/* + * @test + * @bug 8256999 + * @summary Test that Reference.refersTo intrinsics are properly handled + * @library /test/lib / + * @build jdk.test.whitebox.WhiteBox + * @requires vm.compiler2.enabled + * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI compiler.c2.irTests.gc.ReferenceRefersToTests + */ +public class ReferenceRefersToTests { + + private static String[] args(String... add) { + List args = new ArrayList<>(); + + // Use PerMethodTrapLimit=0 to compile all branches in the intrinsics. + args.add("-XX:PerMethodTrapLimit=0"); + + // Forcefully inline all methods to reach the intrinsic code. + args.add("-XX:CompileCommand=inline,compiler.c2.irTests.gc.ReferenceRefersToTests::*"); + args.add("-XX:CompileCommand=inline,java.lang.ref.Reference::*"); + args.add("-XX:CompileCommand=inline,java.lang.ref.PhantomReference::*"); + + // Mix in test config code. + args.addAll(Arrays.asList(add)); + + return args.toArray(new String[0]); + } + + public static void main(String[] args) { + TestFramework framework = new TestFramework(); + + int idx = 0; + if (GC.isSelectedErgonomically() && GC.Serial.isSupported()) { + // Serial does not have any barriers in refersTo. + framework.addScenarios(new Scenario(idx++, args( + "-XX:+UseSerialGC" + ))); + } + if (GC.isSelectedErgonomically() && GC.Parallel.isSupported()) { + // Parallel does not have any barriers in refersTo. + framework.addScenarios(new Scenario(idx++, args( + "-XX:+UseParallelGC" + ))); + } + if (GC.isSelectedErgonomically() && GC.G1.isSupported()) { + // G1 nominally needs keep-alive barriers for Reference loads, + // but should not have them for refersTo. + framework.addScenarios(new Scenario(idx++, args( + "-XX:+UseG1GC" + ))); + } + if (GC.isSelectedErgonomically() && GC.Shenandoah.isSupported()) { + // Shenandoah nominally needs keep-alive barriers for Reference loads, + // but should not have them for refersTo. We only care to check that + // SATB barrier is not emitted. Shenandoah would also emit LRB barrier, + // which would false-negative the test. + framework.addScenarios(new Scenario(idx++, args( + "-XX:+UnlockDiagnosticVMOptions", + "-XX:ShenandoahGCMode=passive", + "-XX:+ShenandoahSATBBarrier", + "-XX:+UseShenandoahGC" + ))); + } + if (GC.isSelectedErgonomically() && GC.Z.isSupported()) { + // ZGC does not emit barriers in IR. + framework.addScenarios(new Scenario(idx++, args( + "-XX:+UseZGC" + ))); + } + framework.start(); + } + + static final Object REF = new Object(); + + static final SoftReference SR = new SoftReference<>(REF); + static final WeakReference WR = new WeakReference<>(REF); + static final PhantomReference PR = new PhantomReference<>(REF, null); + + // Verify that we are left with a single load of Reference.referent and no stores. + // This serves as a signal that no GC barriers are emitted in IR. + + @Test + @IR(counts = { IRNode.LOAD, "1" }) + @IR(failOn = { IRNode.STORE }) + public boolean soft_null() { + return SR.refersTo(null); + } + + @Test + @IR(counts = { IRNode.LOAD, "1" }) + @IR(failOn = { IRNode.STORE }) + public boolean soft_ref() { + return SR.refersTo(REF); + } + + @Test + @IR(counts = { IRNode.LOAD, "1" }) + @IR(failOn = { IRNode.STORE }) + public boolean weak_null() { + return WR.refersTo(null); + } + + @Test + @IR(counts = { IRNode.LOAD, "1" }) + @IR(failOn = { IRNode.STORE }) + public boolean weak_ref() { + return WR.refersTo(REF); + } + + @Test + @IR(counts = { IRNode.LOAD, "1" }) + @IR(failOn = { IRNode.STORE }) + public boolean phantom_null() { + return PR.refersTo(null); + } + + @Test + @IR(counts = { IRNode.LOAD, "1" }) + @IR(failOn = { IRNode.STORE }) + public boolean phantom_ref() { + return PR.refersTo(REF); + } + +} diff --git a/test/hotspot/jtreg/compiler/escapeAnalysis/TestFindInstMemRecursion.java b/test/hotspot/jtreg/compiler/escapeAnalysis/TestFindInstMemRecursion.java new file mode 100644 index 00000000000..90a5ff92cd3 --- /dev/null +++ b/test/hotspot/jtreg/compiler/escapeAnalysis/TestFindInstMemRecursion.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2024, 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. + */ + +/** + * @test + * @bug 8324345 + * @summary Ensure that ConnectionGraph::find_inst_mem does not cause a stack + * overflow. + * + * @run main/othervm -Xcomp -XX:CompileThreshold=10 -XX:-TieredCompilation + * -XX:CompileCommand=CompileOnly,javax.swing.plaf.basic.BasicLookAndFeel::initComponentDefaults + * -XX:CompileCommand=MemLimit,*.*,0 + * compiler.escapeAnalysis.TestFindInstMemRecursion + * + */ + +package compiler.escapeAnalysis; + +import javax.swing.*; +import javax.swing.plaf.metal.*; + +public class TestFindInstMemRecursion { + public static void main(String[] args) throws Exception { + LookAndFeel lookAndFeel = new MetalLookAndFeel(); + for (int i = 0; i < 20; ++i) { + UIManager.setLookAndFeel(lookAndFeel); + } + } +} diff --git a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/SimpleDebugInfoTest.java b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/SimpleDebugInfoTest.java index c7d8d2cf830..e77ac8dc4f9 100644 --- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/SimpleDebugInfoTest.java +++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/SimpleDebugInfoTest.java @@ -200,84 +200,4 @@ public void testStackLong() { testLongOnStack(compiler); testLongInLocal(compiler); } - - public static Class objectOnStack() { - return SimpleDebugInfoTest.class; - } - - private void testObjectOnStack(DebugInfoCompiler compiler) { - test(compiler, getMethod("objectOnStack"), 2, JavaKind.Object); - } - - public static Class objectInLocal() { - Class local = SimpleDebugInfoTest.class; - return local; - } - - private void testObjectInLocal(DebugInfoCompiler compiler) { - test(compiler, getMethod("objectInLocal"), 3, JavaKind.Object); - } - - @Test - public void testConstObject() { - ResolvedJavaType type = metaAccess.lookupJavaType(objectOnStack()); - DebugInfoCompiler compiler = (asm, values) -> { - values[0] = constantReflection.asJavaClass(type); - return null; - }; - testObjectOnStack(compiler); - testObjectInLocal(compiler); - } - - @Test - public void testRegObject() { - ResolvedJavaType type = metaAccess.lookupJavaType(objectOnStack()); - DebugInfoCompiler compiler = (asm, values) -> { - Register reg = asm.emitLoadPointer((HotSpotConstant) constantReflection.asJavaClass(type)); - values[0] = reg.asValue(asm.getValueKind(JavaKind.Object)); - return null; - }; - testObjectOnStack(compiler); - testObjectInLocal(compiler); - } - - @Test - public void testStackObject() { - ResolvedJavaType type = metaAccess.lookupJavaType(objectOnStack()); - DebugInfoCompiler compiler = (asm, values) -> { - Register reg = asm.emitLoadPointer((HotSpotConstant) constantReflection.asJavaClass(type)); - values[0] = asm.emitPointerToStack(reg); - return null; - }; - testObjectOnStack(compiler); - testObjectInLocal(compiler); - } - - @Test - public void testRegNarrowObject() { - Assume.assumeTrue(config.useCompressedOops); - ResolvedJavaType type = metaAccess.lookupJavaType(objectOnStack()); - DebugInfoCompiler compiler = (asm, values) -> { - HotSpotConstant wide = (HotSpotConstant) constantReflection.asJavaClass(type); - Register reg = asm.emitLoadPointer((HotSpotConstant) wide.compress()); - values[0] = reg.asValue(asm.narrowOopKind); - return null; - }; - testObjectOnStack(compiler); - testObjectInLocal(compiler); - } - - @Test - public void testStackNarrowObject() { - Assume.assumeTrue(config.useCompressedOops); - ResolvedJavaType type = metaAccess.lookupJavaType(objectOnStack()); - DebugInfoCompiler compiler = (asm, values) -> { - HotSpotConstant wide = (HotSpotConstant) constantReflection.asJavaClass(type); - Register reg = asm.emitLoadPointer((HotSpotConstant) wide.compress()); - values[0] = asm.emitNarrowPointerToStack(reg); - return null; - }; - testObjectOnStack(compiler); - testObjectInLocal(compiler); - } } diff --git a/test/hotspot/jtreg/compiler/vectorapi/VectorReplicateLongSpecialImmTest.java b/test/hotspot/jtreg/compiler/vectorapi/VectorReplicateLongSpecialImmTest.java index e2ad716d1fa..b885abb632a 100644 --- a/test/hotspot/jtreg/compiler/vectorapi/VectorReplicateLongSpecialImmTest.java +++ b/test/hotspot/jtreg/compiler/vectorapi/VectorReplicateLongSpecialImmTest.java @@ -36,7 +36,7 @@ * @library /test/lib * @requires os.arch == "aarch64" * @modules jdk.incubator.vector - * @run testng/othervm -XX:UseSVE=0 -XX:-TieredCompilation -XX:CompileThreshold=100 compiler.vectorapi.VectorReplicateLongSpecialImmTest + * @run testng/othervm -XX:UseSVE=0 -XX:-TieredCompilation -XX:CompileThreshold=100 -XX:+IgnoreUnrecognizedVMOptions -XX:CompileCommand=MemLimit,*.*,0 compiler.vectorapi.VectorReplicateLongSpecialImmTest */ public class VectorReplicateLongSpecialImmTest { diff --git a/test/hotspot/jtreg/gc/arguments/TestG1PercentageOptions.java b/test/hotspot/jtreg/gc/arguments/TestG1PercentageOptions.java index e8ee2598c9a..48345da250a 100644 --- a/test/hotspot/jtreg/gc/arguments/TestG1PercentageOptions.java +++ b/test/hotspot/jtreg/gc/arguments/TestG1PercentageOptions.java @@ -51,14 +51,14 @@ private static final class OptionDescription { } } - private static final String[] defaultValid = new String[] { - "0", "1", "50", "95", "100" }; - private static final String[] defaultInvalid = new String[] { - "-10", "110", "bad" }; + private static final String[] rangeOneToHundredValid = new String[] { + "1", "50", "95", "100" }; + private static final String[] rangeOneToHundredInvalid = new String[] { + "0", "-10", "110", "bad" }; // All of the G1 product arguments that are percentages. private static final OptionDescription[] percentOptions = new OptionDescription[] { - new OptionDescription("G1ConfidencePercent", defaultValid, defaultInvalid) + new OptionDescription("G1ConfidencePercent", rangeOneToHundredValid, rangeOneToHundredInvalid) // Other percentage options are not yet validated by argument processing. }; diff --git a/test/hotspot/jtreg/runtime/ClassInitErrors/TestOutOfMemoryDuringInit.java b/test/hotspot/jtreg/runtime/ClassInitErrors/TestOutOfMemoryDuringInit.java index 1001ede5447..2f8d0fee721 100644 --- a/test/hotspot/jtreg/runtime/ClassInitErrors/TestOutOfMemoryDuringInit.java +++ b/test/hotspot/jtreg/runtime/ClassInitErrors/TestOutOfMemoryDuringInit.java @@ -44,6 +44,10 @@ static class Nested { static void forceInit() { } static { while (theList != null) { + // Use the minimal allocation size to push heap occupation to + // the limit, ensuring there is not enough memory to create the + // ExceptionInInitializerError that the VM tries to create when + // the clinit throws the OOM. theList.add(new Object()); } } diff --git a/test/jdk/jdk/jfr/event/gc/collection/TestGCCauseWithParallelOld.java b/test/jdk/jdk/jfr/event/gc/collection/TestGCCauseWithParallelOld.java index 0715d3c5c2d..4d8f697d837 100644 --- a/test/jdk/jdk/jfr/event/gc/collection/TestGCCauseWithParallelOld.java +++ b/test/jdk/jdk/jfr/event/gc/collection/TestGCCauseWithParallelOld.java @@ -39,7 +39,7 @@ public static void main(String[] args) throws Exception { String testID = "ParallelOld"; String[] vmFlags = {"-XX:+UseParallelGC"}; String[] gcNames = {GCHelper.gcParallelScavenge, GCHelper.gcParallelOld}; - String[] gcCauses = {"Allocation Failure", "Ergonomics", "System.gc()", "GCLocker Initiated GC"}; + String[] gcCauses = {"Allocation Failure", "System.gc()", "GCLocker Initiated GC"}; GCGarbageCollectionUtil.test(testID, vmFlags, gcNames, gcCauses); } }