From a0df0a527fc3a6954fc08651947a5cfe1455e652 Mon Sep 17 00:00:00 2001
From: Amit Kumar
Date: Thu, 28 Nov 2024 02:05:45 +0000
Subject: [PATCH 001/171] 8340731: Cleanup remaining IA64 references in hotspot
code
Reviewed-by: dholmes, aph
---
src/hotspot/os/bsd/os_bsd.cpp | 6 +---
src/hotspot/os/linux/hugepages.cpp | 3 +-
src/hotspot/os/linux/os_linux.cpp | 33 ++++++-------------
src/hotspot/os/posix/signals_posix.cpp | 7 ----
src/hotspot/share/opto/chaitin.cpp | 1 -
src/hotspot/share/opto/generateOptoStub.cpp | 4 ---
src/hotspot/share/opto/memnode.hpp | 4 +--
src/hotspot/share/opto/output.cpp | 2 +-
.../share/runtime/abstract_vm_version.cpp | 1 -
src/hotspot/share/runtime/deoptimization.cpp | 6 +---
src/hotspot/share/runtime/frame.hpp | 7 ++--
src/hotspot/share/runtime/javaCalls.cpp | 5 ---
src/hotspot/share/runtime/os.hpp | 3 +-
src/hotspot/share/runtime/relocator.cpp | 2 +-
.../share/utilities/elfFuncDescTable.cpp | 5 ++-
.../share/utilities/elfFuncDescTable.hpp | 5 ++-
src/hotspot/share/utilities/macros.hpp | 12 -------
17 files changed, 25 insertions(+), 81 deletions(-)
diff --git a/src/hotspot/os/bsd/os_bsd.cpp b/src/hotspot/os/bsd/os_bsd.cpp
index a1887aa5975..8185797563c 100644
--- a/src/hotspot/os/bsd/os_bsd.cpp
+++ b/src/hotspot/os/bsd/os_bsd.cpp
@@ -229,8 +229,6 @@ size_t os::rss() {
// Cpu architecture string
#if defined(ZERO)
static char cpu_arch[] = ZERO_LIBARCH;
-#elif defined(IA64)
-static char cpu_arch[] = "ia64";
#elif defined(IA32)
static char cpu_arch[] = "i386";
#elif defined(AMD64)
@@ -1192,8 +1190,6 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) {
static Elf32_Half running_arch_code=EM_386;
#elif (defined AMD64)
static Elf32_Half running_arch_code=EM_X86_64;
- #elif (defined IA64)
- static Elf32_Half running_arch_code=EM_IA_64;
#elif (defined __powerpc64__)
static Elf32_Half running_arch_code=EM_PPC64;
#elif (defined __powerpc__)
@@ -1214,7 +1210,7 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) {
static Elf32_Half running_arch_code=EM_68K;
#else
#error Method os::dll_load requires that one of following is defined:\
- IA32, AMD64, IA64, __powerpc__, ARM, S390, ALPHA, MIPS, MIPSEL, PARISC, M68K
+ IA32, AMD64, __powerpc__, ARM, S390, ALPHA, MIPS, MIPSEL, PARISC, M68K
#endif
// Identify compatibility class for VM's architecture and library's architecture
diff --git a/src/hotspot/os/linux/hugepages.cpp b/src/hotspot/os/linux/hugepages.cpp
index b71593487cf..c04ff7a4ca0 100644
--- a/src/hotspot/os/linux/hugepages.cpp
+++ b/src/hotspot/os/linux/hugepages.cpp
@@ -55,8 +55,7 @@ static size_t scan_default_hugepagesize() {
// large_page_size on Linux is used to round up heap size. x86 uses either
// 2M or 4M page, depending on whether PAE (Physical Address Extensions)
- // mode is enabled. AMD64/EM64T uses 2M page in 64bit mode. IA64 can use
- // page as large as 1G.
+ // mode is enabled. AMD64/EM64T uses 2M page in 64bit mode.
//
// Here we try to figure out page size by parsing /proc/meminfo and looking
// for a line with the following format:
diff --git a/src/hotspot/os/linux/os_linux.cpp b/src/hotspot/os/linux/os_linux.cpp
index b2b9a798119..d51ca8a5ffb 100644
--- a/src/hotspot/os/linux/os_linux.cpp
+++ b/src/hotspot/os/linux/os_linux.cpp
@@ -461,26 +461,17 @@ bool os::Linux::get_tick_information(CPUPerfTicks* pticks, int which_logical_cpu
}
#ifndef SYS_gettid
-// i386: 224, ia64: 1105, amd64: 186, sparc: 143
- #ifdef __ia64__
- #define SYS_gettid 1105
+// i386: 224, amd64: 186, sparc: 143
+ #if defined(__i386__)
+ #define SYS_gettid 224
+ #elif defined(__amd64__)
+ #define SYS_gettid 186
+ #elif defined(__sparc__)
+ #define SYS_gettid 143
#else
- #ifdef __i386__
- #define SYS_gettid 224
- #else
- #ifdef __amd64__
- #define SYS_gettid 186
- #else
- #ifdef __sparc__
- #define SYS_gettid 143
- #else
- #error define gettid for the arch
- #endif
- #endif
- #endif
+ #error "Define SYS_gettid for this architecture"
#endif
-#endif
-
+#endif // SYS_gettid
// pid_t gettid()
//
@@ -1778,8 +1769,6 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) {
static Elf32_Half running_arch_code=EM_386;
#elif (defined AMD64) || (defined X32)
static Elf32_Half running_arch_code=EM_X86_64;
-#elif (defined IA64)
- static Elf32_Half running_arch_code=EM_IA_64;
#elif (defined __sparc) && (defined _LP64)
static Elf32_Half running_arch_code=EM_SPARCV9;
#elif (defined __sparc) && (!defined _LP64)
@@ -1812,7 +1801,7 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) {
static Elf32_Half running_arch_code=EM_LOONGARCH;
#else
#error Method os::dll_load requires that one of following is defined:\
- AARCH64, ALPHA, ARM, AMD64, IA32, IA64, LOONGARCH64, M68K, MIPS, MIPSEL, PARISC, __powerpc__, __powerpc64__, RISCV, S390, SH, __sparc
+ AARCH64, ALPHA, ARM, AMD64, IA32, LOONGARCH64, M68K, MIPS, MIPSEL, PARISC, __powerpc__, __powerpc64__, RISCV, S390, SH, __sparc
#endif
// Identify compatibility class for VM's architecture and library's architecture
@@ -2719,8 +2708,6 @@ void os::get_summary_cpu_info(char* cpuinfo, size_t length) {
strncpy(cpuinfo, "ARM", length);
#elif defined(IA32)
strncpy(cpuinfo, "x86_32", length);
-#elif defined(IA64)
- strncpy(cpuinfo, "IA64", length);
#elif defined(PPC)
strncpy(cpuinfo, "PPC64", length);
#elif defined(RISCV)
diff --git a/src/hotspot/os/posix/signals_posix.cpp b/src/hotspot/os/posix/signals_posix.cpp
index bbf122fabfb..ddc7a05c2ff 100644
--- a/src/hotspot/os/posix/signals_posix.cpp
+++ b/src/hotspot/os/posix/signals_posix.cpp
@@ -960,10 +960,6 @@ static bool get_signal_code_description(const siginfo_t* si, enum_sigcode_desc_t
{ SIGILL, ILL_PRVREG, "ILL_PRVREG", "Privileged register." },
{ SIGILL, ILL_COPROC, "ILL_COPROC", "Coprocessor error." },
{ SIGILL, ILL_BADSTK, "ILL_BADSTK", "Internal stack error." },
-#if defined(IA64) && defined(LINUX)
- { SIGILL, ILL_BADIADDR, "ILL_BADIADDR", "Unimplemented instruction address" },
- { SIGILL, ILL_BREAK, "ILL_BREAK", "Application Break instruction" },
-#endif
{ SIGFPE, FPE_INTDIV, "FPE_INTDIV", "Integer divide by zero." },
{ SIGFPE, FPE_INTOVF, "FPE_INTOVF", "Integer overflow." },
{ SIGFPE, FPE_FLTDIV, "FPE_FLTDIV", "Floating-point divide by zero." },
@@ -977,9 +973,6 @@ static bool get_signal_code_description(const siginfo_t* si, enum_sigcode_desc_t
#if defined(AIX)
// no explanation found what keyerr would be
{ SIGSEGV, SEGV_KEYERR, "SEGV_KEYERR", "key error" },
-#endif
-#if defined(IA64) && !defined(AIX)
- { SIGSEGV, SEGV_PSTKOVF, "SEGV_PSTKOVF", "Paragraph stack overflow" },
#endif
{ SIGBUS, BUS_ADRALN, "BUS_ADRALN", "Invalid address alignment." },
{ SIGBUS, BUS_ADRERR, "BUS_ADRERR", "Nonexistent physical address." },
diff --git a/src/hotspot/share/opto/chaitin.cpp b/src/hotspot/share/opto/chaitin.cpp
index 6252e31d898..c9d1491afc5 100644
--- a/src/hotspot/share/opto/chaitin.cpp
+++ b/src/hotspot/share/opto/chaitin.cpp
@@ -956,7 +956,6 @@ void PhaseChaitin::gather_lrg_masks( bool after_aggressive ) {
// Each entry is reg_pressure_per_value,number_of_regs
// RegL RegI RegFlags RegF RegD INTPRESSURE FLOATPRESSURE
// IA32 2 1 1 1 1 6 6
- // IA64 1 1 1 1 1 50 41
// SPARC 2 2 2 2 2 48 (24) 52 (26)
// SPARCV9 2 2 2 2 2 48 (24) 52 (26)
// AMD64 1 1 1 1 1 14 15
diff --git a/src/hotspot/share/opto/generateOptoStub.cpp b/src/hotspot/share/opto/generateOptoStub.cpp
index 2e3dc878c84..b6f09dcc439 100644
--- a/src/hotspot/share/opto/generateOptoStub.cpp
+++ b/src/hotspot/share/opto/generateOptoStub.cpp
@@ -224,10 +224,6 @@ void GraphKit::gen_stub(address C_function,
store_to_memory(control(), adr_sp, null(), T_ADDRESS, MemNode::unordered);
// Clear last_Java_pc
store_to_memory(control(), adr_last_Java_pc, null(), T_ADDRESS, MemNode::unordered);
-#if (defined(IA64) && !defined(AIX))
- Node* adr_last_Java_fp = basic_plus_adr(top(), thread, in_bytes(JavaThread::last_Java_fp_offset()));
- store_to_memory(control(), adr_last_Java_fp, null(), T_ADDRESS, MemNode::unordered);
-#endif
// For is-fancy-jump, the C-return value is also the branch target
Node* target = map()->in(TypeFunc::Parms);
diff --git a/src/hotspot/share/opto/memnode.hpp b/src/hotspot/share/opto/memnode.hpp
index 83ac80c043f..ee9db7d1cac 100644
--- a/src/hotspot/share/opto/memnode.hpp
+++ b/src/hotspot/share/opto/memnode.hpp
@@ -196,7 +196,7 @@ class LoadNode : public MemNode {
// non-pinned LoadNode by the pinned LoadNode.
ControlDependency _control_dependency;
- // On platforms with weak memory ordering (e.g., PPC, Ia64) we distinguish
+ // On platforms with weak memory ordering (e.g., PPC) we distinguish
// loads that can be reordered, and such requiring acquire semantics to
// adhere to the Java specification. The required behaviour is stored in
// this field.
@@ -566,7 +566,7 @@ class LoadNKlassNode : public LoadNNode {
// Store value; requires Store, Address and Value
class StoreNode : public MemNode {
private:
- // On platforms with weak memory ordering (e.g., PPC, Ia64) we distinguish
+ // On platforms with weak memory ordering (e.g., PPC) we distinguish
// stores that can be reordered, and such requiring release semantics to
// adhere to the Java specification. The required behaviour is stored in
// this field.
diff --git a/src/hotspot/share/opto/output.cpp b/src/hotspot/share/opto/output.cpp
index fa781bf23a6..ee91dc4323a 100644
--- a/src/hotspot/share/opto/output.cpp
+++ b/src/hotspot/share/opto/output.cpp
@@ -383,7 +383,7 @@ bool PhaseOutput::need_stack_bang(int frame_size_in_bytes) const {
bool PhaseOutput::need_register_stack_bang() const {
// Determine if we need to generate a register stack overflow check.
// This is only used on architectures which have split register
- // and memory stacks (ie. IA64).
+ // and memory stacks.
// Bang if the method is not a stub function and has java calls
return (C->stub_function() == nullptr && C->has_java_calls());
}
diff --git a/src/hotspot/share/runtime/abstract_vm_version.cpp b/src/hotspot/share/runtime/abstract_vm_version.cpp
index 96da109dafe..590d164366b 100644
--- a/src/hotspot/share/runtime/abstract_vm_version.cpp
+++ b/src/hotspot/share/runtime/abstract_vm_version.cpp
@@ -187,7 +187,6 @@ const char* Abstract_VM_Version::vm_release() {
#define CPU AARCH64_ONLY("aarch64") \
AMD64_ONLY("amd64") \
IA32_ONLY("x86") \
- IA64_ONLY("ia64") \
S390_ONLY("s390") \
RISCV64_ONLY("riscv64")
#endif // !ZERO
diff --git a/src/hotspot/share/runtime/deoptimization.cpp b/src/hotspot/share/runtime/deoptimization.cpp
index 10fd83750d4..1558f3c9bce 100644
--- a/src/hotspot/share/runtime/deoptimization.cpp
+++ b/src/hotspot/share/runtime/deoptimization.cpp
@@ -607,9 +607,6 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread
// where it will be very difficult to figure out what went wrong. Better
// to die an early death here than some very obscure death later when the
// trail is cold.
- // Note: on ia64 this guarantee can be fooled by frames with no memory stack
- // in that it will fail to detect a problem when there is one. This needs
- // more work in tiger timeframe.
guarantee(array->unextended_sp() == unpack_sp, "vframe_array_head must contain the vframeArray to unpack");
int number_of_frames = array->frames();
@@ -2342,8 +2339,7 @@ JRT_ENTRY(void, Deoptimization::uncommon_trap_inner(JavaThread* current, jint tr
}
// Setting +ProfileTraps fixes the following, on all platforms:
- // 4852688: ProfileInterpreter is off by default for ia64. The result is
- // infinite heroic-opt-uncommon-trap/deopt/recompile cycles, since the
+ // The result is infinite heroic-opt-uncommon-trap/deopt/recompile cycles, since the
// recompile relies on a MethodData* to record heroic opt failures.
// Whether the interpreter is producing MDO data or not, we also need
diff --git a/src/hotspot/share/runtime/frame.hpp b/src/hotspot/share/runtime/frame.hpp
index fe531cff8a6..0363d7305d2 100644
--- a/src/hotspot/share/runtime/frame.hpp
+++ b/src/hotspot/share/runtime/frame.hpp
@@ -164,10 +164,9 @@ class frame {
void patch_pc(Thread* thread, address pc);
// Every frame needs to return a unique id which distinguishes it from all other frames.
- // For sparc and ia32 use sp. ia64 can have memory frames that are empty so multiple frames
- // will have identical sp values. For ia64 the bsp (fp) value will serve. No real frame
- // should have an id() of null so it is a distinguishing value for an unmatchable frame.
- // We also have relationals which allow comparing a frame to anoth frame's id() allow
+ // For sparc and ia32 use sp.
+ // No real frame should have an id() of null so it is a distinguishing value for an unmatchable frame.
+ // We also have relationals which allow comparing a frame to another frame's id() allowing
// us to distinguish younger (more recent activation) from older (less recent activations)
// A null id is only valid when comparing for equality.
diff --git a/src/hotspot/share/runtime/javaCalls.cpp b/src/hotspot/share/runtime/javaCalls.cpp
index b3b7b6f6834..e8f647fe484 100644
--- a/src/hotspot/share/runtime/javaCalls.cpp
+++ b/src/hotspot/share/runtime/javaCalls.cpp
@@ -116,11 +116,6 @@ JavaCallWrapper::~JavaCallWrapper() {
ThreadStateTransition::transition_from_java(_thread, _thread_in_vm);
// State has been restored now make the anchor frame visible for the profiler.
- // Do this after the transition because this allows us to put an assert
- // the Java->vm transition which checks to see that stack is not walkable
- // on sparc/ia64 which will catch violations of the resetting of last_Java_frame
- // invariants (i.e. _flags always cleared on return to Java)
-
_thread->frame_anchor()->copy(&_anchor);
// Release handles after we are marked as being inside the VM again, since this
diff --git a/src/hotspot/share/runtime/os.hpp b/src/hotspot/share/runtime/os.hpp
index 8e4a214b691..0bc543957c9 100644
--- a/src/hotspot/share/runtime/os.hpp
+++ b/src/hotspot/share/runtime/os.hpp
@@ -859,8 +859,7 @@ class os: AllStatic {
// We don't attempt to become a debugger, so we only follow frames if that
// does not require a lookup in the unwind table, which is part of the binary
// file but may be unsafe to read after a fatal error. So on x86, we can
- // only walk stack if %ebp is used as frame pointer; on ia64, it's not
- // possible to walk C stack without having the unwind table.
+ // only walk stack if %ebp is used as frame pointer.
static bool is_first_C_frame(frame *fr);
static frame get_sender_for_C_frame(frame *fr);
diff --git a/src/hotspot/share/runtime/relocator.cpp b/src/hotspot/share/runtime/relocator.cpp
index 5b5ff2b83e6..dc244ce920d 100644
--- a/src/hotspot/share/runtime/relocator.cpp
+++ b/src/hotspot/share/runtime/relocator.cpp
@@ -200,7 +200,7 @@ bool Relocator::handle_code_changes() {
bool Relocator::is_opcode_lookupswitch(Bytecodes::Code bc) {
switch (bc) {
case Bytecodes::_tableswitch: return false;
- case Bytecodes::_lookupswitch: // not rewritten on ia64
+ case Bytecodes::_lookupswitch:
case Bytecodes::_fast_linearswitch: // rewritten _lookupswitch
case Bytecodes::_fast_binaryswitch: return true; // rewritten _lookupswitch
default: ShouldNotReachHere();
diff --git a/src/hotspot/share/utilities/elfFuncDescTable.cpp b/src/hotspot/share/utilities/elfFuncDescTable.cpp
index bd9beb202c6..d23a1da68f4 100644
--- a/src/hotspot/share/utilities/elfFuncDescTable.cpp
+++ b/src/hotspot/share/utilities/elfFuncDescTable.cpp
@@ -34,11 +34,10 @@ ElfFuncDescTable::ElfFuncDescTable(FILE* file, Elf_Shdr shdr, int index) :
_section(file, shdr), _file(file), _index(index) {
assert(file, "null file handle");
// The actual function address (i.e. function entry point) is always the
- // first value in the function descriptor (on IA64 and PPC64 they look as follows):
+ // first value in the function descriptor (on PPC64 they look as follows):
// PPC64: [function entry point, TOC pointer, environment pointer]
- // IA64 : [function entry point, GP (global pointer) value]
// Unfortunately 'shdr.sh_entsize' doesn't always seem to contain this size (it's zero on PPC64) so we can't assert
- // assert(IA64_ONLY(2) PPC64_ONLY(3) * sizeof(address) == shdr.sh_entsize, "Size mismatch for '.opd' section entries");
+ // assert(PPC64_ONLY(3) * sizeof(address) == shdr.sh_entsize, "Size mismatch for '.opd' section entries");
_status = _section.status();
}
diff --git a/src/hotspot/share/utilities/elfFuncDescTable.hpp b/src/hotspot/share/utilities/elfFuncDescTable.hpp
index a0e67611554..daba24ee626 100644
--- a/src/hotspot/share/utilities/elfFuncDescTable.hpp
+++ b/src/hotspot/share/utilities/elfFuncDescTable.hpp
@@ -35,9 +35,8 @@
/*
-On PowerPC-64 (and other architectures like for example IA64) a pointer to a
-function is not just a plain code address, but instead a pointer to a so called
-function descriptor (which is simply a structure containing 3 pointers).
+On PowerPC-64 a pointer to a function is not just a plain code address, but instead a pointer
+to a so-called function descriptor (which is simply a structure containing 3 pointers).
This fact is also reflected in the ELF ABI for PowerPC-64.
On architectures like x86 or SPARC, the ELF symbol table contains the start
diff --git a/src/hotspot/share/utilities/macros.hpp b/src/hotspot/share/utilities/macros.hpp
index 23094c9e8c4..b14905ff8e2 100644
--- a/src/hotspot/share/utilities/macros.hpp
+++ b/src/hotspot/share/utilities/macros.hpp
@@ -458,18 +458,6 @@
#define NOT_IA32(code) code
#endif
-// This is a REALLY BIG HACK, but on AIX unconditionally defines IA64.
-// At least on AIX 7.1 this is a real problem because 'systemcfg.h' is indirectly included
-// by 'pthread.h' and other common system headers.
-
-#if defined(IA64) && !defined(AIX)
-#define IA64_ONLY(code) code
-#define NOT_IA64(code)
-#else
-#define IA64_ONLY(code)
-#define NOT_IA64(code) code
-#endif
-
#ifdef AMD64
#define AMD64_ONLY(code) code
#define NOT_AMD64(code)
From 1a07d542ec810282eb78653698d098a24b35686f Mon Sep 17 00:00:00 2001
From: David Holmes
Date: Thu, 28 Nov 2024 02:24:55 +0000
Subject: [PATCH 002/171] 8343703: Symbol name cleanups after JEP 479
Reviewed-by: kbarrett, amenkov
---
src/hotspot/share/include/jvm.h | 7 ---
src/hotspot/share/prims/jvmtiAgent.cpp | 39 +++++++--------
src/hotspot/share/runtime/os.cpp | 32 ++++--------
src/hotspot/share/runtime/os.hpp | 6 +--
.../share/native/libjava/NativeLibraries.c | 50 +++++++------------
5 files changed, 46 insertions(+), 88 deletions(-)
diff --git a/src/hotspot/share/include/jvm.h b/src/hotspot/share/include/jvm.h
index bc46a2cf852..474d5baa487 100644
--- a/src/hotspot/share/include/jvm.h
+++ b/src/hotspot/share/include/jvm.h
@@ -1147,13 +1147,6 @@ JVM_GetClassFileVersion(JNIEnv *env, jclass current);
JNIEXPORT jboolean JNICALL
JVM_PrintWarningAtDynamicAgentLoad(void);
-#define JNI_ONLOAD_SYMBOLS {"JNI_OnLoad"}
-#define JNI_ONUNLOAD_SYMBOLS {"JNI_OnUnload"}
-#define JVM_ONLOAD_SYMBOLS {"JVM_OnLoad"}
-#define AGENT_ONLOAD_SYMBOLS {"Agent_OnLoad"}
-#define AGENT_ONUNLOAD_SYMBOLS {"Agent_OnUnload"}
-#define AGENT_ONATTACH_SYMBOLS {"Agent_OnAttach"}
-
/*
* This structure is used by the launcher to get the default thread
* stack size from the VM using JNI_GetDefaultJavaVMInitArgs() with a
diff --git a/src/hotspot/share/prims/jvmtiAgent.cpp b/src/hotspot/share/prims/jvmtiAgent.cpp
index 6dd205082a0..06702773d58 100644
--- a/src/hotspot/share/prims/jvmtiAgent.cpp
+++ b/src/hotspot/share/prims/jvmtiAgent.cpp
@@ -27,7 +27,6 @@
#include "cds/cds_globals.hpp"
#include "cds/cdsConfig.hpp"
#include "jni.h"
-#include "jvm.h"
#include "jvm_io.h"
#include "jvmtifiles/jvmtiEnv.hpp"
#include "prims/jvmtiEnvBase.hpp"
@@ -268,10 +267,10 @@ static void assert_preload(const JvmtiAgent* agent) {
// For statically linked agents we can't rely on os_lib == nullptr because
// statically linked agents could have a handle of RTLD_DEFAULT which == 0 on some platforms.
// If this function returns true, then agent->is_static_lib() && agent->is_loaded().
-static bool load_agent_from_executable(JvmtiAgent* agent, const char* on_load_symbols[], size_t num_symbol_entries) {
+static bool load_agent_from_executable(JvmtiAgent* agent, const char* on_load_symbol) {
DEBUG_ONLY(assert_preload(agent);)
- assert(on_load_symbols != nullptr, "invariant");
- return os::find_builtin_agent(agent, &on_load_symbols[0], num_symbol_entries);
+ assert(on_load_symbol != nullptr, "invariant");
+ return os::find_builtin_agent(agent, on_load_symbol);
}
// Load the library from the absolute path of the agent, if available.
@@ -310,7 +309,7 @@ static void* load_agent_from_relative_path(JvmtiAgent* agent, bool vm_exit_on_er
}
// For absolute and relative paths.
-static void* load_library(JvmtiAgent* agent, const char* on_symbols[], size_t num_symbol_entries, bool vm_exit_on_error) {
+static void* load_library(JvmtiAgent* agent, bool vm_exit_on_error) {
return agent->is_absolute_path() ? load_agent_from_absolute_path(agent, vm_exit_on_error) :
load_agent_from_relative_path(agent, vm_exit_on_error);
}
@@ -321,12 +320,11 @@ extern "C" {
}
// Find the OnLoad entry point for -agentlib: -agentpath: -Xrun agents.
-// num_symbol_entries must be passed-in since only the caller knows the number of symbols in the array.
-static OnLoadEntry_t lookup_On_Load_entry_point(JvmtiAgent* agent, const char* on_load_symbols[], size_t num_symbol_entries) {
+static OnLoadEntry_t lookup_On_Load_entry_point(JvmtiAgent* agent, const char* on_load_symbol) {
assert(agent != nullptr, "invariant");
if (!agent->is_loaded()) {
- if (!load_agent_from_executable(agent, on_load_symbols, num_symbol_entries)) {
- void* const library = load_library(agent, on_load_symbols, num_symbol_entries, /* vm exit on error */ true);
+ if (!load_agent_from_executable(agent, on_load_symbol)) {
+ void* const library = load_library(agent, /* vm exit on error */ true);
assert(library != nullptr, "invariant");
agent->set_os_lib(library);
agent->set_loaded();
@@ -334,17 +332,15 @@ static OnLoadEntry_t lookup_On_Load_entry_point(JvmtiAgent* agent, const char* o
}
assert(agent->is_loaded(), "invariant");
// Find the OnLoad function.
- return CAST_TO_FN_PTR(OnLoadEntry_t, os::find_agent_function(agent, false, on_load_symbols, num_symbol_entries));
+ return CAST_TO_FN_PTR(OnLoadEntry_t, os::find_agent_function(agent, false, on_load_symbol));
}
static OnLoadEntry_t lookup_JVM_OnLoad_entry_point(JvmtiAgent* lib) {
- const char* on_load_symbols[] = JVM_ONLOAD_SYMBOLS;
- return lookup_On_Load_entry_point(lib, on_load_symbols, sizeof(on_load_symbols) / sizeof(char*));
+ return lookup_On_Load_entry_point(lib, "JVM_OnLoad");
}
static OnLoadEntry_t lookup_Agent_OnLoad_entry_point(JvmtiAgent* agent) {
- const char* on_load_symbols[] = AGENT_ONLOAD_SYMBOLS;
- return lookup_On_Load_entry_point(agent, on_load_symbols, sizeof(on_load_symbols) / sizeof(char*));
+ return lookup_On_Load_entry_point(agent, "Agent_OnLoad");
}
void JvmtiAgent::convert_xrun_agent() {
@@ -499,14 +495,13 @@ static bool invoke_Agent_OnAttach(JvmtiAgent* agent, outputStream* st) {
assert(agent->is_dynamic(), "invariant");
assert(st != nullptr, "invariant");
assert(JvmtiEnvBase::get_phase() == JVMTI_PHASE_LIVE, "not in live phase!");
- const char* on_attach_symbols[] = AGENT_ONATTACH_SYMBOLS;
- const size_t num_symbol_entries = ARRAY_SIZE(on_attach_symbols);
+ const char* on_attach_symbol = "Agent_OnAttach";
void* library = nullptr;
bool previously_loaded;
- if (load_agent_from_executable(agent, &on_attach_symbols[0], num_symbol_entries)) {
+ if (load_agent_from_executable(agent, on_attach_symbol)) {
previously_loaded = JvmtiAgentList::is_static_lib_loaded(agent->name());
} else {
- library = load_library(agent, &on_attach_symbols[0], num_symbol_entries, /* vm_exit_on_error */ false);
+ library = load_library(agent, /* vm_exit_on_error */ false);
if (library == nullptr) {
st->print_cr("%s was not loaded.", agent->name());
if (*ebuf != '\0') {
@@ -531,10 +526,10 @@ static bool invoke_Agent_OnAttach(JvmtiAgent* agent, outputStream* st) {
assert(agent->is_loaded(), "invariant");
// The library was loaded so we attempt to lookup and invoke the Agent_OnAttach function.
OnAttachEntry_t on_attach_entry = CAST_TO_FN_PTR(OnAttachEntry_t,
- os::find_agent_function(agent, false, &on_attach_symbols[0], num_symbol_entries));
+ os::find_agent_function(agent, false, on_attach_symbol));
if (on_attach_entry == nullptr) {
- st->print_cr("%s is not available in %s", on_attach_symbols[0], agent->name());
+ st->print_cr("%s is not available in %s", on_attach_symbol, agent->name());
unload_library(agent, library);
return false;
}
@@ -629,10 +624,10 @@ extern "C" {
}
void JvmtiAgent::unload() {
- const char* on_unload_symbols[] = AGENT_ONUNLOAD_SYMBOLS;
+ const char* on_unload_symbol = "Agent_OnUnload";
// Find the Agent_OnUnload function.
Agent_OnUnload_t unload_entry = CAST_TO_FN_PTR(Agent_OnUnload_t,
- os::find_agent_function(this, false, &on_unload_symbols[0], ARRAY_SIZE(on_unload_symbols)));
+ os::find_agent_function(this, false, on_unload_symbol));
if (unload_entry != nullptr) {
// Invoke the Agent_OnUnload function
JavaThread* thread = JavaThread::current();
diff --git a/src/hotspot/share/runtime/os.cpp b/src/hotspot/share/runtime/os.cpp
index d8e539ca115..deb2c30500c 100644
--- a/src/hotspot/share/runtime/os.cpp
+++ b/src/hotspot/share/runtime/os.cpp
@@ -546,49 +546,35 @@ void* os::native_java_library() {
* executable if agent_lib->is_static_lib() == true or in the shared library
* referenced by 'handle'.
*/
-void* os::find_agent_function(JvmtiAgent *agent_lib, bool check_lib,
- const char *syms[], size_t syms_len) {
+void* os::find_agent_function(JvmtiAgent *agent_lib, bool check_lib, const char *sym) {
assert(agent_lib != nullptr, "sanity check");
- const char *lib_name;
void *handle = agent_lib->os_lib();
void *entryName = nullptr;
- char *agent_function_name;
- size_t i;
// If checking then use the agent name otherwise test is_static_lib() to
// see how to process this lookup
- lib_name = ((check_lib || agent_lib->is_static_lib()) ? agent_lib->name() : nullptr);
- for (i = 0; i < syms_len; i++) {
- agent_function_name = build_agent_function_name(syms[i], lib_name, agent_lib->is_absolute_path());
- if (agent_function_name == nullptr) {
- break;
- }
+ const char *lib_name = ((check_lib || agent_lib->is_static_lib()) ? agent_lib->name() : nullptr);
+
+ char* agent_function_name = build_agent_function_name(sym, lib_name, agent_lib->is_absolute_path());
+ if (agent_function_name != nullptr) {
entryName = dll_lookup(handle, agent_function_name);
FREE_C_HEAP_ARRAY(char, agent_function_name);
- if (entryName != nullptr) {
- break;
- }
}
return entryName;
}
// See if the passed in agent is statically linked into the VM image.
-bool os::find_builtin_agent(JvmtiAgent* agent, const char *syms[],
- size_t syms_len) {
- void *ret;
- void *proc_handle;
- void *save_handle;
-
+bool os::find_builtin_agent(JvmtiAgent* agent, const char* sym) {
assert(agent != nullptr, "sanity check");
if (agent->name() == nullptr) {
return false;
}
- proc_handle = get_default_process_handle();
+ void* proc_handle = get_default_process_handle();
// Check for Agent_OnLoad/Attach_lib_name function
- save_handle = agent->os_lib();
+ void* save_handle = agent->os_lib();
// We want to look in this process' symbol table.
agent->set_os_lib(proc_handle);
- ret = find_agent_function(agent, true, syms, syms_len);
+ void* ret = find_agent_function(agent, true, sym);
if (ret != nullptr) {
// Found an entry point like Agent_OnLoad_lib_name so we have a static agent
agent->set_static_lib();
diff --git a/src/hotspot/share/runtime/os.hpp b/src/hotspot/share/runtime/os.hpp
index 0bc543957c9..2e52440ead4 100644
--- a/src/hotspot/share/runtime/os.hpp
+++ b/src/hotspot/share/runtime/os.hpp
@@ -777,12 +777,10 @@ class os: AllStatic {
static void* get_default_process_handle();
// Check for static linked agent library
- static bool find_builtin_agent(JvmtiAgent *agent_lib, const char *syms[],
- size_t syms_len);
+ static bool find_builtin_agent(JvmtiAgent* agent_lib, const char* sym);
// Find agent entry point
- static void *find_agent_function(JvmtiAgent *agent_lib, bool check_lib,
- const char *syms[], size_t syms_len);
+ static void* find_agent_function(JvmtiAgent* agent_lib, bool check_lib, const char* sym);
// Provide wrapper versions of these functions to guarantee NUL-termination
// in all cases.
diff --git a/src/java.base/share/native/libjava/NativeLibraries.c b/src/java.base/share/native/libjava/NativeLibraries.c
index df5ff343d61..b6624eccd1d 100644
--- a/src/java.base/share/native/libjava/NativeLibraries.c
+++ b/src/java.base/share/native/libjava/NativeLibraries.c
@@ -64,45 +64,31 @@ static jboolean initIDs(JNIEnv *env)
*/
static void *findJniFunction(JNIEnv *env, void *handle,
const char *cname, jboolean isLoad) {
- const char *onLoadSymbols[] = JNI_ONLOAD_SYMBOLS;
- const char *onUnloadSymbols[] = JNI_ONUNLOAD_SYMBOLS;
- const char **syms;
- int symsLen;
+ const char *sym;
void *entryName = NULL;
char *jniFunctionName;
- int i;
size_t len;
// Check for JNI_On(Un)Load<_libname> function
- if (isLoad) {
- syms = onLoadSymbols;
- symsLen = sizeof(onLoadSymbols) / sizeof(char *);
- } else {
- syms = onUnloadSymbols;
- symsLen = sizeof(onUnloadSymbols) / sizeof(char *);
+ sym = isLoad ? "JNI_OnLoad" : "JNI_OnUnload";
+
+ // sym + '_' + cname + '\0'
+ if ((len = strlen(sym) + (cname != NULL ? (strlen(cname) + 1) : 0) + 1) >
+ FILENAME_MAX) {
+ goto done;
}
- for (i = 0; i < symsLen; i++) {
- // cname + sym + '_' + '\0'
- if ((len = (cname != NULL ? strlen(cname) : 0) + strlen(syms[i]) + 2) >
- FILENAME_MAX) {
- goto done;
- }
- jniFunctionName = malloc(len);
- if (jniFunctionName == NULL) {
- JNU_ThrowOutOfMemoryError(env, NULL);
- goto done;
- }
- strcpy(jniFunctionName, syms[i]);
- if (cname != NULL) {
- strcat(jniFunctionName, "_");
- strcat(jniFunctionName, cname);
- }
- entryName = JVM_FindLibraryEntry(handle, jniFunctionName);
- free(jniFunctionName);
- if(entryName) {
- break;
- }
+ jniFunctionName = malloc(len);
+ if (jniFunctionName == NULL) {
+ JNU_ThrowOutOfMemoryError(env, NULL);
+ goto done;
+ }
+ strcpy(jniFunctionName, sym);
+ if (cname != NULL) {
+ strcat(jniFunctionName, "_");
+ strcat(jniFunctionName, cname);
}
+ entryName = JVM_FindLibraryEntry(handle, jniFunctionName);
+ free(jniFunctionName);
done:
return entryName;
From ce9d543eb1bf26592320fae650fe15638d6d30cf Mon Sep 17 00:00:00 2001
From: Quan Anh Mai
Date: Thu, 28 Nov 2024 06:57:51 +0000
Subject: [PATCH 003/171] 8345119: Some java/foreign tests wrongly assume
aligned memory
Reviewed-by: mcimadamore, jvernee
---
test/jdk/java/foreign/TestByteBuffer.java | 28 +++++++++----------
.../jdk/java/foreign/TestDereferencePath.java | 4 +--
2 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/test/jdk/java/foreign/TestByteBuffer.java b/test/jdk/java/foreign/TestByteBuffer.java
index 77b3dd3b105..a77f97018ca 100644
--- a/test/jdk/java/foreign/TestByteBuffer.java
+++ b/test/jdk/java/foreign/TestByteBuffer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 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
@@ -171,7 +171,7 @@ static void checkBytes(MemorySegment base, SequenceLayout lay
@Test
public void testOffheap() {
try (Arena arena = Arena.ofConfined()) {
- MemorySegment segment = arena.allocate(tuples);;
+ MemorySegment segment = arena.allocate(tuples);
initTuples(segment, tuples.elementCount());
ByteBuffer bb = segment.asByteBuffer();
@@ -385,7 +385,7 @@ static void checkByteArrayAlignment(MemoryLayout layout) {
public void testScopedBuffer(Function bufferFactory, @NoInjection Method method, Object[] args) {
Buffer bb;
try (Arena arena = Arena.ofConfined()) {
- MemorySegment segment = arena.allocate(bytes);;
+ MemorySegment segment = arena.allocate(bytes);
bb = bufferFactory.apply(segment.asByteBuffer());
}
//outside of session!!
@@ -411,7 +411,7 @@ public void testScopedBuffer(Function bufferFactory, @NoInje
public void testScopedBufferAndVarHandle(VarHandle bufferHandle) {
ByteBuffer bb;
try (Arena arena = Arena.ofConfined()) {
- MemorySegment segment = arena.allocate(bytes);;
+ MemorySegment segment = arena.allocate(bytes, Long.BYTES);
bb = segment.asByteBuffer();
for (Map.Entry e : varHandleMembers(bb, bufferHandle).entrySet()) {
MethodHandle handle = e.getKey().bindTo(bufferHandle)
@@ -445,7 +445,7 @@ public void testScopedBufferAndVarHandle(VarHandle bufferHandle) {
@Test(dataProvider = "bufferOps")
public void testDirectBuffer(Function bufferFactory, @NoInjection Method method, Object[] args) {
try (Arena arena = Arena.ofConfined()) {
- MemorySegment segment = arena.allocate(bytes);;
+ MemorySegment segment = arena.allocate(bytes);
Buffer bb = bufferFactory.apply(segment.asByteBuffer());
assertTrue(bb.isDirect());
DirectBuffer directBuffer = ((DirectBuffer)bb);
@@ -458,7 +458,7 @@ public void testDirectBuffer(Function bufferFactory, @NoInje
@Test(dataProvider="resizeOps")
public void testResizeOffheap(Consumer checker, Consumer initializer, SequenceLayout seq) {
try (Arena arena = Arena.ofConfined()) {
- MemorySegment segment = arena.allocate(seq);;
+ MemorySegment segment = arena.allocate(seq);
initializer.accept(segment);
checker.accept(segment);
}
@@ -496,7 +496,7 @@ public void testResizeRoundtripHeap(Consumer checker, Consumer checker, Consumer initializer, SequenceLayout seq) {
try (Arena arena = Arena.ofConfined()) {
- MemorySegment segment = arena.allocate(seq);;
+ MemorySegment segment = arena.allocate(seq);
initializer.accept(segment);
MemorySegment second = MemorySegment.ofBuffer(segment.asByteBuffer());
checker.accept(second);
@@ -507,7 +507,7 @@ public void testResizeRoundtripNative(Consumer checker, Consumer<
public void testBufferOnClosedSession() {
MemorySegment leaked;
try (Arena arena = Arena.ofConfined()) {
- leaked = arena.allocate(bytes);;
+ leaked = arena.allocate(bytes);
}
ByteBuffer byteBuffer = leaked.asByteBuffer(); // ok
byteBuffer.get(); // should throw
@@ -615,7 +615,7 @@ public void testCopyHeapToNative(Consumer checker, Consumer checker, Consumer _unused) {
@Test
public void testRoundTripAccess() {
try (Arena arena = Arena.ofConfined()) {
- MemorySegment ms = arena.allocate(4, 1);;
+ MemorySegment ms = arena.allocate(4, 1);
MemorySegment msNoAccess = ms.asReadOnly();
MemorySegment msRoundTrip = MemorySegment.ofBuffer(msNoAccess.asByteBuffer());
assertEquals(msRoundTrip.scope(), ms.scope());
@@ -741,7 +741,7 @@ public void closeableArenas(Supplier arenaSupplier) throws IOException {
tmp.deleteOnExit();
try (FileChannel channel = FileChannel.open(tmp.toPath(), StandardOpenOption.READ, StandardOpenOption.WRITE) ;
Arena arena = arenaSupplier.get()) {
- MemorySegment segment = arena.allocate(10, 1);;
+ MemorySegment segment = arena.allocate(10, 1);
for (int i = 0; i < 10; i++) {
segment.set(JAVA_BYTE, i, (byte) i);
}
@@ -780,7 +780,7 @@ public void testIOOnClosedSegmentBuffer(Supplier arenaSupplier) throws IO
@Test
public void buffersAndArraysFromSlices() {
try (Arena arena = Arena.ofShared()) {
- MemorySegment segment = arena.allocate(16, 1);;
+ MemorySegment segment = arena.allocate(16, 1);
int newSize = 8;
var slice = segment.asSlice(4, newSize);
@@ -798,7 +798,7 @@ public void buffersAndArraysFromSlices() {
@Test
public void viewsFromSharedSegment() {
try (Arena arena = Arena.ofShared()) {
- MemorySegment segment = arena.allocate(16, 1);;
+ MemorySegment segment = arena.allocate(16, 1);
var byteBuffer = segment.asByteBuffer();
byteBuffer.asReadOnlyBuffer();
byteBuffer.slice(0, 8);
diff --git a/test/jdk/java/foreign/TestDereferencePath.java b/test/jdk/java/foreign/TestDereferencePath.java
index 116f2d318fc..e2281cde235 100644
--- a/test/jdk/java/foreign/TestDereferencePath.java
+++ b/test/jdk/java/foreign/TestDereferencePath.java
@@ -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
@@ -173,7 +173,7 @@ void badDerefMisAligned() {
ValueLayout.ADDRESS.withTargetLayout(ValueLayout.JAVA_INT).withName("x"));
try (Arena arena = Arena.ofConfined()) {
- MemorySegment segment = arena.allocate(struct.byteSize() + 1).asSlice(1);
+ MemorySegment segment = arena.allocate(struct.byteSize() + 1, struct.byteAlignment()).asSlice(1);
VarHandle vhX = struct.varHandle(PathElement.groupElement("x"), PathElement.dereferenceElement());
vhX.set(segment, 0L, 42); // should throw
}
From 81c44e5eb469ceed555a982e65feefcfde340a0b Mon Sep 17 00:00:00 2001
From: Jaikiran Pai
Date: Thu, 28 Nov 2024 07:54:00 +0000
Subject: [PATCH 004/171] 8344908: URLClassPath should not propagate
IllegalArgumentException when finding resources in classpath URLs
Reviewed-by: alanb
---
.../jdk/internal/loader/URLClassPath.java | 6 +-
.../share/classes/sun/net/www/ParseUtil.java | 1 +
.../jdk/internal/loader/FileURLMapper.java | 27 ++-
.../jdk/internal/loader/FileURLMapper.java | 25 ++-
.../URLClassPath/ClassPathUnusableURLs.java | 188 ++++++++++++++++++
5 files changed, 225 insertions(+), 22 deletions(-)
create mode 100644 test/jdk/jdk/internal/loader/URLClassPath/ClassPathUnusableURLs.java
diff --git a/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java b/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java
index 75418111f74..06e3442c244 100644
--- a/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java
+++ b/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java
@@ -903,7 +903,11 @@ private static class FileLoader extends Loader {
private FileLoader(URL url) throws IOException {
super(url);
String path = url.getFile().replace('/', File.separatorChar);
- path = ParseUtil.decode(path);
+ try {
+ path = ParseUtil.decode(path);
+ } catch (IllegalArgumentException iae) {
+ throw new IOException(iae);
+ }
dir = (new File(path)).getCanonicalFile();
@SuppressWarnings("deprecation")
var _unused = normalizedBase = new URL(getBaseURL(), ".");
diff --git a/src/java.base/share/classes/sun/net/www/ParseUtil.java b/src/java.base/share/classes/sun/net/www/ParseUtil.java
index def688ad96a..3a35f86ab88 100644
--- a/src/java.base/share/classes/sun/net/www/ParseUtil.java
+++ b/src/java.base/share/classes/sun/net/www/ParseUtil.java
@@ -171,6 +171,7 @@ private static byte unescape(String s, int i) {
* Returns a new String constructed from the specified String by replacing
* the URL escape sequences and UTF8 encoding with the characters they
* represent.
+ * @throws IllegalArgumentException if {@code s} could not be decoded
*/
public static String decode(String s) {
int n = s.length();
diff --git a/src/java.base/unix/classes/jdk/internal/loader/FileURLMapper.java b/src/java.base/unix/classes/jdk/internal/loader/FileURLMapper.java
index 6507b2961b9..79d0c6faf5b 100644
--- a/src/java.base/unix/classes/jdk/internal/loader/FileURLMapper.java
+++ b/src/java.base/unix/classes/jdk/internal/loader/FileURLMapper.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2003, 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
@@ -25,8 +25,10 @@
package jdk.internal.loader;
+import java.io.IOException;
import java.net.URL;
import java.io.File;
+
import sun.net.www.ParseUtil;
/**
@@ -40,12 +42,12 @@
* @author Michael McMahon
*/
-public class FileURLMapper {
+final class FileURLMapper {
- URL url;
- String path;
+ private final URL url;
+ private String path;
- public FileURLMapper (URL url) {
+ FileURLMapper(URL url) {
this.url = url;
}
@@ -53,15 +55,18 @@ public FileURLMapper (URL url) {
* @return the platform specific path corresponding to the URL
* so long as the URL does not contain a hostname in the authority field.
*/
-
- public String getPath () {
+ String getPath() throws IOException {
if (path != null) {
return path;
}
String host = url.getHost();
if (host == null || host.isEmpty() || "localhost".equalsIgnoreCase(host)) {
path = url.getFile();
- path = ParseUtil.decode(path);
+ try {
+ path = ParseUtil.decode(path);
+ } catch (IllegalArgumentException iae) {
+ throw new IOException(iae);
+ }
}
return path;
}
@@ -69,12 +74,12 @@ public String getPath () {
/**
* Checks whether the file identified by the URL exists.
*/
- public boolean exists () {
- String s = getPath ();
+ boolean exists() throws IOException {
+ String s = getPath();
if (s == null) {
return false;
} else {
- File f = new File (s);
+ File f = new File(s);
return f.exists();
}
}
diff --git a/src/java.base/windows/classes/jdk/internal/loader/FileURLMapper.java b/src/java.base/windows/classes/jdk/internal/loader/FileURLMapper.java
index 0053cf70e9d..b72bc31b206 100644
--- a/src/java.base/windows/classes/jdk/internal/loader/FileURLMapper.java
+++ b/src/java.base/windows/classes/jdk/internal/loader/FileURLMapper.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2003, 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
@@ -25,8 +25,10 @@
package jdk.internal.loader;
+import java.io.IOException;
import java.net.URL;
import java.io.File;
+
import sun.net.www.ParseUtil;
/**
@@ -36,12 +38,12 @@
* @author Michael McMahon
*/
-public class FileURLMapper {
+final class FileURLMapper {
- URL url;
- String file;
+ private final URL url;
+ private String file;
- public FileURLMapper (URL url) {
+ FileURLMapper (URL url) {
this.url = url;
}
@@ -49,8 +51,7 @@ public FileURLMapper (URL url) {
* @return the platform specific path corresponding to the URL, and in particular
* returns a UNC when the authority contains a hostname
*/
-
- public String getPath () {
+ String getPath() throws IOException {
if (file != null) {
return file;
}
@@ -63,13 +64,17 @@ public String getPath () {
return file;
}
String path = url.getFile().replace('/', '\\');
- file = ParseUtil.decode(path);
+ try {
+ file = ParseUtil.decode(path);
+ } catch (IllegalArgumentException iae) {
+ throw new IOException(iae);
+ }
return file;
}
- public boolean exists() {
+ boolean exists() throws IOException {
String path = getPath();
- File f = new File (path);
+ File f = new File(path);
return f.exists();
}
}
diff --git a/test/jdk/jdk/internal/loader/URLClassPath/ClassPathUnusableURLs.java b/test/jdk/jdk/internal/loader/URLClassPath/ClassPathUnusableURLs.java
new file mode 100644
index 00000000000..420425f37fc
--- /dev/null
+++ b/test/jdk/jdk/internal/loader/URLClassPath/ClassPathUnusableURLs.java
@@ -0,0 +1,188 @@
+/*
+ * 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.
+ */
+
+import java.io.OutputStream;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.jar.JarEntry;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+
+import jdk.internal.loader.Resource;
+import jdk.internal.loader.URLClassPath;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import static java.nio.charset.StandardCharsets.US_ASCII;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assumptions.abort;
+
+/*
+ * @test
+ * @bug 8344908
+ * @summary verify that when locating resources, the URLClassPath can function properly
+ * without throwing unexpected exceptions when any URL in the classpath is unusable
+ * @modules java.base/jdk.internal.loader
+ * @run junit ClassPathUnusableURLs
+ */
+public class ClassPathUnusableURLs {
+
+ private static final Path SCRATCH_DIR = Path.of(".").normalize();
+ private static final String RESOURCE_NAME = "foo.txt";
+ private static final String SMILEY_EMOJI = "\uD83D\uDE00";
+
+ private static Path ASCII_DIR;
+ private static Path EMOJI_DIR;
+ private static Path JAR_FILE_IN_EMOJI_DIR;
+ private static int NUM_EXPECTED_LOCATED_RESOURCES;
+
+
+ @BeforeAll
+ static void beforeAll() throws Exception {
+ try {
+ EMOJI_DIR = Files.createTempDirectory(SCRATCH_DIR, SMILEY_EMOJI);
+ } catch (IllegalArgumentException iae) {
+ iae.printStackTrace(); // for debug purpose
+ // if we can't create a directory with an emoji in its path name,
+ // then skip the entire test
+ abort("Skipping test since emoji directory couldn't be created: " + iae);
+ }
+ // successful creation of the dir, continue with the test
+ Files.createFile(EMOJI_DIR.resolve(RESOURCE_NAME));
+
+ ASCII_DIR = Files.createTempDirectory(SCRATCH_DIR, "test-urlclasspath");
+ Files.createFile(ASCII_DIR.resolve(RESOURCE_NAME));
+
+ // create a jar file containing the resource
+ JAR_FILE_IN_EMOJI_DIR = Files.createTempDirectory(SCRATCH_DIR, SMILEY_EMOJI)
+ .resolve("foo.jar");
+ final Manifest manifest = new Manifest();
+ manifest.getMainAttributes().putValue("Manifest-Version", "1.0");
+ try (OutputStream fos = Files.newOutputStream(JAR_FILE_IN_EMOJI_DIR);
+ JarOutputStream jos = new JarOutputStream(fos, manifest)) {
+
+ final JarEntry jarEntry = new JarEntry(RESOURCE_NAME);
+ jos.putNextEntry(jarEntry);
+ jos.write("hello".getBytes(US_ASCII));
+ jos.closeEntry();
+ }
+ // Even if the resource is present in more than one classpath element,
+ // we expect it to be found by the URLClassPath only in the path which has just ascii
+ // characters. URLClassPath currently doesn't have the ability to serve resources
+ // from paths containing emoji character(s).
+ NUM_EXPECTED_LOCATED_RESOURCES = 1;
+ }
+
+ /**
+ * Constructs a URLClassPath and then exercises the URLClassPath.findResource()
+ * and URLClassPath.findResources() methods and expects them to return the expected
+ * resources.
+ */
+ @Test
+ void testFindResource() {
+ // start an empty URL classpath
+ final URLClassPath urlc = new URLClassPath(new URL[0]);
+ final String[] classpathElements = getClassPathElements();
+ try {
+ // use addFile() to construct classpath
+ for (final String path : classpathElements) {
+ urlc.addFile(path);
+ }
+ // findResource()
+ assertNotNull(urlc.findResource(RESOURCE_NAME), "findResource() failed to locate"
+ + " resource: " + RESOURCE_NAME + " in classpath: "
+ + Arrays.toString(classpathElements));
+ // findResources()
+ final Enumeration locatedResources = urlc.findResources(RESOURCE_NAME);
+ assertNotNull(locatedResources, "findResources() failed to"
+ + " locate resource: " + RESOURCE_NAME + " in classpath: "
+ + Arrays.toString(classpathElements));
+ int numFound = 0;
+ while (locatedResources.hasMoreElements()) {
+ System.out.println("located " + locatedResources.nextElement()
+ + " for resource " + RESOURCE_NAME);
+ numFound++;
+ }
+ assertEquals(NUM_EXPECTED_LOCATED_RESOURCES, numFound,
+ "unexpected number of resources located for " + RESOURCE_NAME);
+ } finally {
+ urlc.closeLoaders();
+ }
+ }
+
+ /**
+ * Constructs a URLClassPath and then exercises the URLClassPath.getResource()
+ * and URLClassPath.getResources() methods and expects them to return the expected
+ * resources.
+ */
+ @Test
+ void testGetResource() {
+ // start an empty URL classpath
+ final URLClassPath urlc = new URLClassPath(new URL[0]);
+ final String[] classpathElements = getClassPathElements();
+ try {
+ // use addFile() to construct classpath
+ for (final String path : classpathElements) {
+ urlc.addFile(path);
+ }
+ // getResource()
+ assertNotNull(urlc.getResource(RESOURCE_NAME), "getResource() failed to locate"
+ + " resource: " + RESOURCE_NAME + " in classpath: "
+ + Arrays.toString(classpathElements));
+ // getResources()
+ final Enumeration locatedResources = urlc.getResources(RESOURCE_NAME);
+ assertNotNull(locatedResources, "getResources() failed to"
+ + " locate resource: " + RESOURCE_NAME + " in classpath: "
+ + Arrays.toString(classpathElements));
+ int numFound = 0;
+ while (locatedResources.hasMoreElements()) {
+ System.out.println("located " + locatedResources.nextElement().getURL()
+ + " for resource " + RESOURCE_NAME);
+ numFound++;
+ }
+ assertEquals(NUM_EXPECTED_LOCATED_RESOURCES, numFound,
+ "unexpected number of resources located for " + RESOURCE_NAME);
+ } finally {
+ urlc.closeLoaders();
+ }
+ }
+
+ private static String[] getClassPathElements() {
+ // Maintain the order - in context of this test, paths with emojis
+ // or those which can't serve the resource should come before the
+ // path that can serve the resource.
+ return new String[]{
+ // non-existent path
+ ASCII_DIR.resolve("non-existent").toString(),
+ // existing emoji dir
+ EMOJI_DIR.toString(),
+ // existing jar file in a emoji dir
+ JAR_FILE_IN_EMOJI_DIR.toString(),
+ // existing ascii dir
+ ASCII_DIR.toString()
+ };
+ }
+}
From 103338534f71309e4cc0ba289075fab768e66cd4 Mon Sep 17 00:00:00 2001
From: Per Minborg
Date: Thu, 28 Nov 2024 07:59:48 +0000
Subject: [PATCH 005/171] 8344967: Some tests in TestFill do not use the test
parameter
Reviewed-by: jvernee
---
test/jdk/java/foreign/TestFill.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/test/jdk/java/foreign/TestFill.java b/test/jdk/java/foreign/TestFill.java
index e5f69587f2f..d9bde891120 100644
--- a/test/jdk/java/foreign/TestFill.java
+++ b/test/jdk/java/foreign/TestFill.java
@@ -87,7 +87,7 @@ void testValues(int value) {
@MethodSource("sizes")
void testReadOnly(int len) {
try (var arena = Arena.ofConfined()) {
- var segment = arena.allocate(10).asReadOnly();
+ var segment = arena.allocate(len).asReadOnly();
assertThrows(IllegalArgumentException.class, () -> segment.fill(VALUE));
}
}
@@ -96,7 +96,7 @@ void testReadOnly(int len) {
@MethodSource("sizes")
void testConfinement(int len) {
try (var arena = Arena.ofConfined()) {
- var segment = arena.allocate(10);
+ var segment = arena.allocate(len);
AtomicReference ex = new AtomicReference<>();
CompletableFuture future = CompletableFuture.runAsync(() -> {
try {
From e096660a18905bf1394d722790c5c3883e55dedc Mon Sep 17 00:00:00 2001
From: SendaoYan
Date: Thu, 28 Nov 2024 09:06:34 +0000
Subject: [PATCH 006/171] 8345043: [ASAN] methodMatcher.cpp report reading from
a region of size 0 [-Werror=stringop-overread]
Reviewed-by: kbarrett, dholmes
---
src/hotspot/share/compiler/methodMatcher.cpp | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/src/hotspot/share/compiler/methodMatcher.cpp b/src/hotspot/share/compiler/methodMatcher.cpp
index 1a0ade2fadb..0bd5cdd8501 100644
--- a/src/hotspot/share/compiler/methodMatcher.cpp
+++ b/src/hotspot/share/compiler/methodMatcher.cpp
@@ -219,21 +219,22 @@ bool MethodMatcher::match(Symbol* candidate, Symbol* match, Mode match_mode) con
static MethodMatcher::Mode check_mode(char name[], const char*& error_msg) {
int match = MethodMatcher::Exact;
+ size_t len = strlen(name);
if (name[0] == '*') {
- if (strlen(name) == 1) {
+ if (len == 1) {
return MethodMatcher::Any;
}
match |= MethodMatcher::Suffix;
- memmove(name, name + 1, strlen(name + 1) + 1);
+ memmove(name, name + 1, len); // Include terminating nul in move.
+ len--;
}
- size_t len = strlen(name);
if (len > 0 && name[len - 1] == '*') {
match |= MethodMatcher::Prefix;
name[--len] = '\0';
}
- if (strlen(name) == 0) {
+ if (len == 0) {
error_msg = "** Not a valid pattern";
return MethodMatcher::Any;
}
From d791f4b98d93e5fc64e3191402cc5091e0553592 Mon Sep 17 00:00:00 2001
From: SendaoYan
Date: Thu, 28 Nov 2024 09:29:49 +0000
Subject: [PATCH 007/171] 8341585: Test java/foreign/TestUpcallStress.java
should mark as /native
Reviewed-by: luhenry, pminborg
---
test/jdk/java/foreign/TestUpcallStress.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/jdk/java/foreign/TestUpcallStress.java b/test/jdk/java/foreign/TestUpcallStress.java
index b7a53dd6c01..d910723b559 100644
--- a/test/jdk/java/foreign/TestUpcallStress.java
+++ b/test/jdk/java/foreign/TestUpcallStress.java
@@ -31,7 +31,7 @@
* @build NativeTestHelper CallGeneratorHelper TestUpcallBase
* @bug 8337753
*
- * @run testng/othervm/timeout=3200
+ * @run testng/native/othervm/timeout=3200
* -Xcheck:jni
* -XX:+IgnoreUnrecognizedVMOptions
* -XX:-VerifyDependencies
From 56f1e4ef0524515c7f1ad65bc3f08a0e8dd0a29a Mon Sep 17 00:00:00 2001
From: Aleksey Shipilev
Date: Thu, 28 Nov 2024 09:35:51 +0000
Subject: [PATCH 008/171] 8344093: Implement JEP 501: Deprecate the 32-bit x86
Port for Removal
Reviewed-by: ihse, simonis, dholmes
---
.github/workflows/main.yml | 22 +---------------------
doc/building.html | 7 +++----
doc/building.md | 6 ++----
make/autoconf/platform.m4 | 16 ++++++++--------
4 files changed, 14 insertions(+), 37 deletions(-)
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index aed03f55536..210d53be658 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -36,7 +36,7 @@ on:
platforms:
description: 'Platform(s) to execute on (comma separated, e.g. "linux-x64, macos, aarch64")'
required: true
- default: 'linux-x64, linux-x86-hs, linux-x64-variants, linux-cross-compile, alpine-linux-x64, macos-x64, macos-aarch64, windows-x64, windows-aarch64, docs'
+ default: 'linux-x64, linux-x64-variants, linux-cross-compile, alpine-linux-x64, macos-x64, macos-aarch64, windows-x64, windows-aarch64, docs'
configure-arguments:
description: 'Additional configure arguments'
required: false
@@ -62,7 +62,6 @@ jobs:
EXCLUDED_PLATFORMS: 'alpine-linux-x64'
outputs:
linux-x64: ${{ steps.include.outputs.linux-x64 }}
- linux-x86-hs: ${{ steps.include.outputs.linux-x86-hs }}
linux-x64-variants: ${{ steps.include.outputs.linux-x64-variants }}
linux-cross-compile: ${{ steps.include.outputs.linux-cross-compile }}
alpine-linux-x64: ${{ steps.include.outputs.alpine-linux-x64 }}
@@ -145,7 +144,6 @@ jobs:
}
echo "linux-x64=$(check_platform linux-x64 linux x64)" >> $GITHUB_OUTPUT
- echo "linux-x86-hs=$(check_platform linux-x86-hs linux x86)" >> $GITHUB_OUTPUT
echo "linux-x64-variants=$(check_platform linux-x64-variants variants)" >> $GITHUB_OUTPUT
echo "linux-cross-compile=$(check_platform linux-cross-compile cross-compile)" >> $GITHUB_OUTPUT
echo "alpine-linux-x64=$(check_platform alpine-linux-x64 alpine-linux x64)" >> $GITHUB_OUTPUT
@@ -170,24 +168,6 @@ jobs:
make-arguments: ${{ github.event.inputs.make-arguments }}
if: needs.prepare.outputs.linux-x64 == 'true'
- build-linux-x86-hs:
- name: linux-x86-hs
- needs: prepare
- uses: ./.github/workflows/build-linux.yml
- with:
- platform: linux-x86
- make-target: 'hotspot'
- gcc-major-version: '10'
- gcc-package-suffix: '-multilib'
- apt-architecture: 'i386'
- # Some multilib libraries do not have proper inter-dependencies, so we have to
- # install their dependencies manually.
- apt-extra-packages: 'libfreetype-dev:i386 libtiff-dev:i386 libcupsimage2-dev:i386 libffi-dev:i386'
- extra-conf-options: '--with-target-bits=32 --enable-fallback-linker --enable-libffi-bundling'
- configure-arguments: ${{ github.event.inputs.configure-arguments }}
- make-arguments: ${{ github.event.inputs.make-arguments }}
- if: needs.prepare.outputs.linux-x86-hs == 'true'
-
build-linux-x64-hs-nopch:
name: linux-x64-hs-nopch
needs: prepare
diff --git a/doc/building.html b/doc/building.html
index 63af224584a..cd73863f879 100644
--- a/doc/building.html
+++ b/doc/building.html
@@ -329,8 +329,8 @@
Building on x86
Even for 32-bit builds, it is recommended to use a 64-bit build
machine, and instead create a 32-bit target using
--with-target-bits=32.
-
Note: The Windows 32-bit x86 port is deprecated and may be removed in
-a future release.
+
Note: The 32-bit x86 port is deprecated and may be removed in a
+future release.
Building on aarch64
At a minimum, a machine with 8 cores is advisable, as well as 8 GB of
RAM. (The more cores to use, the more memory you need.) At least 6 GB of
@@ -393,8 +393,7 @@
Operating System
to list successes or failures of building on different platforms.
Windows
Windows XP is not a supported platform, but all newer Windows should
-be able to build the JDK. (Note: The Windows 32-bit x86 port is
-deprecated and may be removed in a future release.)
+be able to build the JDK.
On Windows, it is important that you pay attention to the
instructions in the Special
Considerations.
diff --git a/doc/building.md b/doc/building.md
index 466e8d7edf8..99bc509dc70 100644
--- a/doc/building.md
+++ b/doc/building.md
@@ -134,8 +134,7 @@ space is required.
Even for 32-bit builds, it is recommended to use a 64-bit build machine, and
instead create a 32-bit target using `--with-target-bits=32`.
-Note: The Windows 32-bit x86 port is deprecated and may be removed in a future
-release.
+Note: The 32-bit x86 port is deprecated and may be removed in a future release.
### Building on aarch64
@@ -191,8 +190,7 @@ on different platforms.
### Windows
Windows XP is not a supported platform, but all newer Windows should be able to
-build the JDK. (Note: The Windows 32-bit x86 port is deprecated and may be
-removed in a future release.)
+build the JDK.
On Windows, it is important that you pay attention to the instructions in the
[Special Considerations](#special-considerations).
diff --git a/make/autoconf/platform.m4 b/make/autoconf/platform.m4
index 3f977058a51..5b363e0704a 100644
--- a/make/autoconf/platform.m4
+++ b/make/autoconf/platform.m4
@@ -666,14 +666,14 @@ AC_DEFUN([PLATFORM_CHECK_DEPRECATION],
[
AC_ARG_ENABLE(deprecated-ports, [AS_HELP_STRING([--enable-deprecated-ports@<:@=yes/no@:>@],
[Suppress the error when configuring for a deprecated port @<:@no@:>@])])
- # if test "x$OPENJDK_TARGET_CPU" = xx86; then
- # if test "x$enable_deprecated_ports" = "xyes"; then
- # AC_MSG_WARN([The x86 port is deprecated and may be removed in a future release.])
- # else
- # AC_MSG_ERROR(m4_normalize([The 32-bit x86 port is deprecated and may be removed in a future release.
- # Use --enable-deprecated-ports=yes to suppress this error.]))
- # fi
- # fi
+ if test "x$OPENJDK_TARGET_CPU" = xx86; then
+ if test "x$enable_deprecated_ports" = "xyes"; then
+ AC_MSG_WARN([The 32-bit x86 port is deprecated and may be removed in a future release.])
+ else
+ AC_MSG_ERROR(m4_normalize([The 32-bit x86 port is deprecated and may be removed in a future release.
+ Use --enable-deprecated-ports=yes to suppress this error.]))
+ fi
+ fi
])
AC_DEFUN_ONCE([PLATFORM_SETUP_OPENJDK_BUILD_OS_VERSION],
From d33ad07c32f23aee799750c9964ab26d0cbe56f4 Mon Sep 17 00:00:00 2001
From: Kevin Walls
Date: Thu, 28 Nov 2024 09:54:25 +0000
Subject: [PATCH 009/171] 8334493: Remove SecurityManager Permissions
infrastructure from DiagnosticCommands
Reviewed-by: lmesnik, alanb, coleenp
---
src/hotspot/os/linux/mallocInfoDcmd.hpp | 6 +-
src/hotspot/os/linux/trimCHeapDCmd.hpp | 6 +-
.../classfile/classLoaderHierarchyDCmd.hpp | 7 +-
.../share/classfile/classLoaderStats.hpp | 6 -
src/hotspot/share/jfr/dcmd/jfrDcmds.hpp | 30 +--
.../share/logging/logDiagnosticCommand.hpp | 5 -
.../share/memory/metaspace/metaspaceDCmd.hpp | 7 +-
src/hotspot/share/nmt/nmtDCmd.hpp | 7 +-
.../share/services/diagnosticCommand.cpp | 3 +-
.../share/services/diagnosticCommand.hpp | 175 ------------------
.../share/services/diagnosticFramework.cpp | 2 +-
.../share/services/diagnosticFramework.hpp | 32 +---
src/hotspot/share/services/management.cpp | 4 -
.../management/DiagnosticCommandMBean.java | 22 +--
.../internal/DiagnosticCommandImpl.java | 40 ----
.../internal/DiagnosticCommandInfo.java | 48 +----
.../libmanagement_ext/DiagnosticCommandImpl.c | 12 +-
17 files changed, 16 insertions(+), 396 deletions(-)
diff --git a/src/hotspot/os/linux/mallocInfoDcmd.hpp b/src/hotspot/os/linux/mallocInfoDcmd.hpp
index 9f52d83fba3..f2559fa1571 100644
--- a/src/hotspot/os/linux/mallocInfoDcmd.hpp
+++ b/src/hotspot/os/linux/mallocInfoDcmd.hpp
@@ -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
@@ -41,10 +41,6 @@ class MallocInfoDcmd : public DCmd {
static const char* impact() {
return "Low";
}
- static const JavaPermission permission() {
- JavaPermission p = { "java.lang.management.ManagementPermission", "monitor", nullptr };
- return p;
- }
void execute(DCmdSource source, TRAPS) override;
};
diff --git a/src/hotspot/os/linux/trimCHeapDCmd.hpp b/src/hotspot/os/linux/trimCHeapDCmd.hpp
index 32a49798ea8..53b94f4bb56 100644
--- a/src/hotspot/os/linux/trimCHeapDCmd.hpp
+++ b/src/hotspot/os/linux/trimCHeapDCmd.hpp
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2021 SAP SE. All rights reserved.
- * 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
@@ -42,10 +42,6 @@ class TrimCLibcHeapDCmd : public DCmd {
static const char* impact() {
return "Low";
}
- static const JavaPermission permission() {
- JavaPermission p = { "java.lang.management.ManagementPermission", "control", nullptr };
- return p;
- }
virtual void execute(DCmdSource source, TRAPS);
};
diff --git a/src/hotspot/share/classfile/classLoaderHierarchyDCmd.hpp b/src/hotspot/share/classfile/classLoaderHierarchyDCmd.hpp
index 26c765443c9..cd89c9cb978 100644
--- a/src/hotspot/share/classfile/classLoaderHierarchyDCmd.hpp
+++ b/src/hotspot/share/classfile/classLoaderHierarchyDCmd.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -46,11 +46,6 @@ class ClassLoaderHierarchyDCmd: public DCmdWithParser {
static const char* impact() {
return "Medium: Depends on number of class loaders and classes loaded.";
}
- static const JavaPermission permission() {
- JavaPermission p = {"java.lang.management.ManagementPermission",
- "monitor", nullptr};
- return p;
- }
static int num_arguments() { return 3; }
virtual void execute(DCmdSource source, TRAPS);
diff --git a/src/hotspot/share/classfile/classLoaderStats.hpp b/src/hotspot/share/classfile/classLoaderStats.hpp
index 4818ddff609..06d375b3e9b 100644
--- a/src/hotspot/share/classfile/classLoaderStats.hpp
+++ b/src/hotspot/share/classfile/classLoaderStats.hpp
@@ -58,12 +58,6 @@ class ClassLoaderStatsDCmd : public DCmd {
static int num_arguments() {
return 0;
}
-
- static const JavaPermission permission() {
- JavaPermission p = {"java.lang.management.ManagementPermission",
- "monitor", nullptr};
- return p;
- }
};
diff --git a/src/hotspot/share/jfr/dcmd/jfrDcmds.hpp b/src/hotspot/share/jfr/dcmd/jfrDcmds.hpp
index 45e1addeb87..8e7dad5a20c 100644
--- a/src/hotspot/share/jfr/dcmd/jfrDcmds.hpp
+++ b/src/hotspot/share/jfr/dcmd/jfrDcmds.hpp
@@ -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
@@ -59,10 +59,6 @@ class JfrStartFlightRecordingDCmd : public JfrDCmd {
static const char* impact() {
return "Medium: Depending on the settings for a recording, the impact can range from low to high.";
}
- static const JavaPermission permission() {
- JavaPermission p = {"java.lang.management.ManagementPermission", "monitor", nullptr};
- return p;
- }
virtual const char* javaClass() const {
return "jdk/jfr/internal/dcmd/DCmdStart";
}
@@ -84,10 +80,6 @@ class JfrDumpFlightRecordingDCmd : public JfrDCmd {
static const char* impact() {
return "Low";
}
- static const JavaPermission permission() {
- JavaPermission p = {"java.lang.management.ManagementPermission", "monitor", nullptr};
- return p;
- }
virtual const char* javaClass() const {
return "jdk/jfr/internal/dcmd/DCmdDump";
}
@@ -109,10 +101,6 @@ class JfrCheckFlightRecordingDCmd : public JfrDCmd {
static const char* impact() {
return "Low";
}
- static const JavaPermission permission() {
- JavaPermission p = {"java.lang.management.ManagementPermission", "monitor", nullptr};
- return p;
- }
virtual const char* javaClass() const {
return "jdk/jfr/internal/dcmd/DCmdCheck";
}
@@ -134,10 +122,6 @@ class JfrStopFlightRecordingDCmd : public JfrDCmd {
static const char* impact() {
return "Low";
}
- static const JavaPermission permission() {
- JavaPermission p = {"java.lang.management.ManagementPermission", "monitor", nullptr};
- return p;
- }
virtual const char* javaClass() const {
return "jdk/jfr/internal/dcmd/DCmdStop";
}
@@ -159,10 +143,6 @@ class JfrViewFlightRecordingDCmd : public JfrDCmd {
static const char* impact() {
return "Medium";
}
- static const JavaPermission permission() {
- JavaPermission p = {"java.lang.management.ManagementPermission", "monitor", nullptr};
- return p;
- }
virtual const char* javaClass() const {
return "jdk/jfr/internal/dcmd/DCmdView";
}
@@ -184,10 +164,6 @@ class JfrQueryFlightRecordingDCmd : public JfrDCmd {
static const char* impact() {
return "Medium";
}
- static const JavaPermission permission() {
- JavaPermission p = {"java.lang.management.ManagementPermission", "monitor", nullptr};
- return p;
- }
virtual const char* javaClass() const {
return "jdk/jfr/internal/dcmd/DCmdQuery";
}
@@ -225,10 +201,6 @@ class JfrConfigureFlightRecorderDCmd : public DCmdWithParser {
static const char* impact() {
return "Low";
}
- static const JavaPermission permission() {
- JavaPermission p = {"java.lang.management.ManagementPermission", "monitor", nullptr};
- return p;
- }
static int num_arguments() { return 10; }
virtual void execute(DCmdSource source, TRAPS);
virtual void print_help(const char* name) const;
diff --git a/src/hotspot/share/logging/logDiagnosticCommand.hpp b/src/hotspot/share/logging/logDiagnosticCommand.hpp
index e63509bea9e..a27832306b7 100644
--- a/src/hotspot/share/logging/logDiagnosticCommand.hpp
+++ b/src/hotspot/share/logging/logDiagnosticCommand.hpp
@@ -58,11 +58,6 @@ class LogDiagnosticCommand : public DCmdWithParser {
static const char* description() {
return "Lists current log configuration, enables/disables/configures a log output, or rotates all logs.";
}
-
- static const JavaPermission permission() {
- JavaPermission p = {"java.lang.management.ManagementPermission", "control", nullptr};
- return p;
- }
};
#endif // SHARE_LOGGING_LOGDIAGNOSTICCOMMAND_HPP
diff --git a/src/hotspot/share/memory/metaspace/metaspaceDCmd.hpp b/src/hotspot/share/memory/metaspace/metaspaceDCmd.hpp
index 453b6721202..69377057950 100644
--- a/src/hotspot/share/memory/metaspace/metaspaceDCmd.hpp
+++ b/src/hotspot/share/memory/metaspace/metaspaceDCmd.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2020 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -52,11 +52,6 @@ class MetaspaceDCmd : public DCmdWithParser {
static const char* impact() {
return "Medium: Depends on number of classes loaded.";
}
- static const JavaPermission permission() {
- JavaPermission p = {"java.lang.management.ManagementPermission",
- "monitor", nullptr};
- return p;
- }
static int num_arguments() { return 8; }
virtual void execute(DCmdSource source, TRAPS);
};
diff --git a/src/hotspot/share/nmt/nmtDCmd.hpp b/src/hotspot/share/nmt/nmtDCmd.hpp
index c70d17a481f..2a9f9be49bb 100644
--- a/src/hotspot/share/nmt/nmtDCmd.hpp
+++ b/src/hotspot/share/nmt/nmtDCmd.hpp
@@ -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
@@ -53,11 +53,6 @@ class NMTDCmd: public DCmdWithParser {
static const char* impact() {
return "Medium";
}
- static const JavaPermission permission() {
- JavaPermission p = {"java.lang.management.ManagementPermission",
- "monitor", nullptr};
- return p;
- }
virtual void execute(DCmdSource source, TRAPS);
private:
diff --git a/src/hotspot/share/services/diagnosticCommand.cpp b/src/hotspot/share/services/diagnosticCommand.cpp
index b807a42661c..b081ce29e26 100644
--- a/src/hotspot/share/services/diagnosticCommand.cpp
+++ b/src/hotspot/share/services/diagnosticCommand.cpp
@@ -151,8 +151,7 @@ void DCmd::register_dcmds(){
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false));
// Enhanced JMX Agent Support
- // These commands won't be exported via the DiagnosticCommandMBean until an
- // appropriate permission is created for them
+ // These commands not currently exported via the DiagnosticCommandMBean
uint32_t jmx_agent_export_flags = DCmd_Source_Internal | DCmd_Source_AttachAPI;
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(jmx_agent_export_flags, true,false));
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(jmx_agent_export_flags, true,false));
diff --git a/src/hotspot/share/services/diagnosticCommand.hpp b/src/hotspot/share/services/diagnosticCommand.hpp
index 92e5849cbcd..30b2be2a61b 100644
--- a/src/hotspot/share/services/diagnosticCommand.hpp
+++ b/src/hotspot/share/services/diagnosticCommand.hpp
@@ -64,11 +64,6 @@ class VersionDCmd : public DCmd {
return "Print JVM version information.";
}
static const char* impact() { return "Low"; }
- static const JavaPermission permission() {
- JavaPermission p = {"java.util.PropertyPermission",
- "java.vm.version", "read"};
- return p;
- }
virtual void execute(DCmdSource source, TRAPS);
};
@@ -80,11 +75,6 @@ class CommandLineDCmd : public DCmd {
return "Print the command line used to start this VM instance.";
}
static const char* impact() { return "Low"; }
- static const JavaPermission permission() {
- JavaPermission p = {"java.lang.management.ManagementPermission",
- "monitor", nullptr};
- return p;
- }
virtual void execute(DCmdSource source, TRAPS) {
Arguments::print_on(_output);
}
@@ -101,11 +91,6 @@ class PrintSystemPropertiesDCmd : public DCmd {
static const char* impact() {
return "Low";
}
- static const JavaPermission permission() {
- JavaPermission p = {"java.util.PropertyPermission",
- "*", "read"};
- return p;
- }
virtual void execute(DCmdSource source, TRAPS);
};
@@ -123,11 +108,6 @@ class PrintVMFlagsDCmd : public DCmdWithParser {
static const char* impact() {
return "Low";
}
- static const JavaPermission permission() {
- JavaPermission p = {"java.lang.management.ManagementPermission",
- "monitor", nullptr};
- return p;
- }
virtual void execute(DCmdSource source, TRAPS);
};
@@ -146,11 +126,6 @@ class SetVMFlagDCmd : public DCmdWithParser {
static const char* impact() {
return "Low";
}
- static const JavaPermission permission() {
- JavaPermission p = {"java.lang.management.ManagementPermission",
- "control", nullptr};
- return p;
- }
virtual void execute(DCmdSource source, TRAPS);
};
@@ -164,11 +139,6 @@ class JVMTIDataDumpDCmd : public DCmd {
static const char* impact() {
return "High";
}
- static const JavaPermission permission() {
- JavaPermission p = {"java.lang.management.ManagementPermission",
- "monitor", nullptr};
- return p;
- }
virtual void execute(DCmdSource source, TRAPS);
};
@@ -186,11 +156,6 @@ class JVMTIAgentLoadDCmd : public DCmdWithParser {
return "Load JVMTI native agent.";
}
static const char* impact() { return "Low"; }
- static const JavaPermission permission() {
- JavaPermission p = {"java.lang.management.ManagementPermission",
- "control", nullptr};
- return p;
- }
virtual void execute(DCmdSource source, TRAPS);
};
#endif // INCLUDE_JVMTI
@@ -208,11 +173,6 @@ class VMDynamicLibrariesDCmd : public DCmd {
static const char* impact() {
return "Low";
}
- static const JavaPermission permission() {
- JavaPermission p = {"java.lang.management.ManagementPermission",
- "monitor", nullptr};
- return p;
- }
virtual void execute(DCmdSource source, TRAPS);
};
@@ -240,11 +200,6 @@ class VMInfoDCmd : public DCmd {
return "Print information about JVM environment and status.";
}
static const char* impact() { return "Low"; }
- static const JavaPermission permission() {
- JavaPermission p = {"java.lang.management.ManagementPermission",
- "monitor", nullptr};
- return p;
- }
virtual void execute(DCmdSource source, TRAPS);
};
@@ -284,11 +239,6 @@ class HeapInfoDCmd : public DCmd {
static const char* impact() {
return "Medium";
}
- static const JavaPermission permission() {
- JavaPermission p = {"java.lang.management.ManagementPermission",
- "monitor", nullptr};
- return p;
- }
virtual void execute(DCmdSource source, TRAPS);
};
@@ -303,11 +253,6 @@ class FinalizerInfoDCmd : public DCmd {
static const char* impact() {
return "Medium";
}
- static const JavaPermission permission() {
- JavaPermission p = {"java.lang.management.ManagementPermission",
- "monitor", nullptr};
- return p;
- }
virtual void execute(DCmdSource source, TRAPS);
};
@@ -334,11 +279,6 @@ class HeapDumpDCmd : public DCmdWithParser {
return "High: Depends on Java heap size and content. "
"Request a full GC unless the '-all' option is specified.";
}
- static const JavaPermission permission() {
- JavaPermission p = {"java.lang.management.ManagementPermission",
- "monitor", nullptr};
- return p;
- }
virtual void execute(DCmdSource source, TRAPS);
};
#endif // INCLUDE_SERVICES
@@ -360,11 +300,6 @@ class ClassHistogramDCmd : public DCmdWithParser {
static const char* impact() {
return "High: Depends on Java heap size and content.";
}
- static const JavaPermission permission() {
- JavaPermission p = {"java.lang.management.ManagementPermission",
- "monitor", nullptr};
- return p;
- }
virtual void execute(DCmdSource source, TRAPS);
};
@@ -387,11 +322,6 @@ class ClassHierarchyDCmd : public DCmdWithParser {
static const char* impact() {
return "Medium: Depends on number of loaded classes.";
}
- static const JavaPermission permission() {
- JavaPermission p = {"java.lang.management.ManagementPermission",
- "monitor", nullptr};
- return p;
- }
virtual void execute(DCmdSource source, TRAPS);
};
@@ -412,11 +342,6 @@ class DumpSharedArchiveDCmd: public DCmdWithParser {
static const char* impact() {
return "Medium: Pause time depends on number of loaded classes";
}
- static const JavaPermission permission() {
- JavaPermission p = {"java.lang.management.ManagementPermission",
- "monitor", nullptr};
- return p;
- }
virtual void execute(DCmdSource source, TRAPS);
};
#endif // INCLUDE_CDS
@@ -436,11 +361,6 @@ class ThreadDumpDCmd : public DCmdWithParser {
static const char* impact() {
return "Medium: Depends on the number of threads.";
}
- static const JavaPermission permission() {
- JavaPermission p = {"java.lang.management.ManagementPermission",
- "monitor", nullptr};
- return p;
- }
virtual void execute(DCmdSource source, TRAPS);
};
@@ -546,12 +466,6 @@ class JMXStatusDCmd : public DCmd {
return "Print the management agent status.";
}
- static const JavaPermission permission() {
- JavaPermission p = {"java.lang.management.ManagementPermission",
- "monitor", nullptr};
- return p;
- }
-
virtual void execute(DCmdSource source, TRAPS);
};
@@ -568,11 +482,6 @@ class CompileQueueDCmd : public DCmd {
static const char* impact() {
return "Low";
}
- static const JavaPermission permission() {
- JavaPermission p = {"java.lang.management.ManagementPermission",
- "monitor", nullptr};
- return p;
- }
virtual void execute(DCmdSource source, TRAPS);
};
@@ -592,11 +501,6 @@ class PerfMapDCmd : public DCmdWithParser {
static const char* impact() {
return "Low";
}
- static const JavaPermission permission() {
- JavaPermission p = {"java.lang.management.ManagementPermission",
- "monitor", nullptr};
- return p;
- }
virtual void execute(DCmdSource source, TRAPS);
};
#endif // LINUX
@@ -613,11 +517,6 @@ class CodeListDCmd : public DCmd {
static const char* impact() {
return "Medium";
}
- static const JavaPermission permission() {
- JavaPermission p = {"java.lang.management.ManagementPermission",
- "monitor", nullptr};
- return p;
- }
virtual void execute(DCmdSource source, TRAPS);
};
@@ -633,11 +532,6 @@ class CodeCacheDCmd : public DCmd {
static const char* impact() {
return "Low";
}
- static const JavaPermission permission() {
- JavaPermission p = {"java.lang.management.ManagementPermission",
- "monitor", nullptr};
- return p;
- }
virtual void execute(DCmdSource source, TRAPS);
};
@@ -659,11 +553,6 @@ class CodeHeapAnalyticsDCmd : public DCmdWithParser {
return "Low: Depends on code heap size and content. "
"Holds CodeCache_lock during analysis step, usually sub-second duration.";
}
- static const JavaPermission permission() {
- JavaPermission p = {"java.lang.management.ManagementPermission",
- "monitor", nullptr};
- return p;
- }
virtual void execute(DCmdSource source, TRAPS);
};
//---< END >--- CodeHeap State Analytics.
@@ -680,11 +569,6 @@ class CompilerDirectivesPrintDCmd : public DCmd {
static const char* impact() {
return "Low";
}
- static const JavaPermission permission() {
- JavaPermission p = {"java.lang.management.ManagementPermission",
- "monitor", nullptr};
- return p;
- }
virtual void execute(DCmdSource source, TRAPS);
};
@@ -700,11 +584,6 @@ class CompilerDirectivesRemoveDCmd : public DCmd {
static const char* impact() {
return "Low";
}
- static const JavaPermission permission() {
- JavaPermission p = {"java.lang.management.ManagementPermission",
- "control", nullptr};
- return p;
- }
virtual void execute(DCmdSource source, TRAPS);
};
@@ -723,11 +602,6 @@ class CompilerDirectivesAddDCmd : public DCmdWithParser {
static const char* impact() {
return "Low";
}
- static const JavaPermission permission() {
- JavaPermission p = {"java.lang.management.ManagementPermission",
- "control", nullptr};
- return p;
- }
virtual void execute(DCmdSource source, TRAPS);
};
@@ -743,11 +617,6 @@ class CompilerDirectivesClearDCmd : public DCmd {
static const char* impact() {
return "Low";
}
- static const JavaPermission permission() {
- JavaPermission p = {"java.lang.management.ManagementPermission",
- "control", nullptr};
- return p;
- }
virtual void execute(DCmdSource source, TRAPS);
};
@@ -809,11 +678,6 @@ class SymboltableDCmd : public DCmdWithParser {
static const char* impact() {
return "Medium: Depends on Java content.";
}
- static const JavaPermission permission() {
- JavaPermission p = {"java.lang.management.ManagementPermission",
- "monitor", nullptr};
- return p;
- }
virtual void execute(DCmdSource source, TRAPS);
};
@@ -832,11 +696,6 @@ class StringtableDCmd : public DCmdWithParser {
static const char* impact() {
return "Medium: Depends on Java content.";
}
- static const JavaPermission permission() {
- JavaPermission p = {"java.lang.management.ManagementPermission",
- "monitor", nullptr};
- return p;
- }
virtual void execute(DCmdSource source, TRAPS);
};
@@ -855,11 +714,6 @@ class SystemDictionaryDCmd : public DCmdWithParser {
static const char* impact() {
return "Medium: Depends on Java content.";
}
- static const JavaPermission permission() {
- JavaPermission p = {"java.lang.management.ManagementPermission",
- "monitor", nullptr};
- return p;
- }
virtual void execute(DCmdSource source, TRAPS);
};
@@ -878,11 +732,6 @@ class ClassesDCmd : public DCmdWithParser {
static const char* impact() {
return "Medium: Depends on number of loaded classes.";
}
- static const JavaPermission permission() {
- JavaPermission p = {"java.lang.management.ManagementPermission",
- "monitor", nullptr};
- return p;
- }
virtual void execute(DCmdSource source, TRAPS);
};
@@ -902,11 +751,6 @@ class EventLogDCmd : public DCmdWithParser {
static const char* impact() {
return "Low: Depends on event log size. ";
}
- static const JavaPermission permission() {
- JavaPermission p = {"java.lang.management.ManagementPermission",
- "monitor", nullptr};
- return p;
- }
virtual void execute(DCmdSource source, TRAPS);
};
@@ -929,10 +773,6 @@ class ThreadDumpToFileDCmd : public DCmdWithParser {
static const char* impact() {
return "Medium: Depends on the number of threads.";
}
- static const JavaPermission permission() {
- JavaPermission p = {"java.lang.management.ManagementPermission", "monitor", nullptr};
- return p;
- }
virtual void execute(DCmdSource source, TRAPS);
};
@@ -952,11 +792,6 @@ class CompilationMemoryStatisticDCmd: public DCmdWithParser {
static const char* impact() {
return "Medium: Pause time depends on number of compiled methods";
}
- static const JavaPermission permission() {
- JavaPermission p = {"java.lang.management.ManagementPermission",
- "monitor", nullptr};
- return p;
- }
virtual void execute(DCmdSource source, TRAPS);
};
@@ -970,11 +805,6 @@ class SystemMapDCmd : public DCmd {
return "Prints an annotated process memory map of the VM process (linux and Windows only).";
}
static const char* impact() { return "Medium; can be high for very large java heaps."; }
- static const JavaPermission permission() {
- JavaPermission p = {"java.lang.management.ManagementPermission",
- "control", nullptr};
- return p;
- }
virtual void execute(DCmdSource source, TRAPS);
};
@@ -988,11 +818,6 @@ class SystemDumpMapDCmd : public DCmdWithParser {
return "Dumps an annotated process memory map to an output file (linux and Windows only).";
}
static const char* impact() { return "Medium; can be high for very large java heaps."; }
- static const JavaPermission permission() {
- JavaPermission p = {"java.lang.management.ManagementPermission",
- "control", nullptr};
- return p;
- }
virtual void execute(DCmdSource source, TRAPS);
};
diff --git a/src/hotspot/share/services/diagnosticFramework.cpp b/src/hotspot/share/services/diagnosticFramework.cpp
index 16f074c9cb5..27870d9d933 100644
--- a/src/hotspot/share/services/diagnosticFramework.cpp
+++ b/src/hotspot/share/services/diagnosticFramework.cpp
@@ -587,7 +587,7 @@ GrowableArray* DCmdFactory::DCmdInfo_list(DCmdSource source ) {
if (!factory->is_hidden() && (factory->export_flags() & source)) {
array->append(new DCmdInfo(factory->name(),
factory->description(), factory->impact(),
- factory->permission(), factory->num_arguments(),
+ factory->num_arguments(),
factory->is_enabled()));
}
factory = factory->next();
diff --git a/src/hotspot/share/services/diagnosticFramework.hpp b/src/hotspot/share/services/diagnosticFramework.hpp
index 357482ec5a1..16a7ecbe48e 100644
--- a/src/hotspot/share/services/diagnosticFramework.hpp
+++ b/src/hotspot/share/services/diagnosticFramework.hpp
@@ -40,16 +40,6 @@ enum DCmdSource {
DCmd_Source_MBean = 0x04U // invocation via a MBean
};
-// Warning: strings referenced by the JavaPermission struct are passed to
-// the native part of the JDK. Avoid use of dynamically allocated strings
-// that could be de-allocated before the JDK native code had time to
-// convert them into Java Strings.
-struct JavaPermission {
- const char* _class;
- const char* _name;
- const char* _action;
-};
-
// CmdLine is the class used to handle a command line containing a single
// diagnostic command and its arguments. It provides methods to access the
// command name and the beginning of the arguments. The class is also
@@ -127,23 +117,20 @@ class DCmdInfo : public ResourceObj {
const char* const _name; /* Name of the diagnostic command */
const char* const _description; /* Short description */
const char* const _impact; /* Impact on the JVM */
- const JavaPermission _permission; /* Java Permission required to execute this command if any */
const int _num_arguments; /* Number of supported options or arguments */
const bool _is_enabled; /* True if the diagnostic command can be invoked, false otherwise */
public:
DCmdInfo(const char* name,
const char* description,
const char* impact,
- JavaPermission permission,
int num_arguments,
bool enabled)
- : _name(name), _description(description), _impact(impact), _permission(permission),
+ : _name(name), _description(description), _impact(impact),
_num_arguments(num_arguments), _is_enabled(enabled) {}
const char* name() const { return _name; }
bool name_equals(const char* cmd_name) const;
const char* description() const { return _description; }
const char* impact() const { return _impact; }
- const JavaPermission& permission() const { return _permission; }
int num_arguments() const { return _num_arguments; }
bool is_enabled() const { return _is_enabled; }
};
@@ -261,19 +248,6 @@ class DCmd : public AnyObj {
// impact depends on the heap size.
static const char* impact() { return "Low: No impact"; }
- // The permission() method returns the description of Java Permission. This
- // permission is required when the diagnostic command is invoked via the
- // DiagnosticCommandMBean. The rationale for this permission check is that
- // the DiagnosticCommandMBean can be used to perform remote invocations of
- // diagnostic commands through the PlatformMBeanServer. The (optional) Java
- // Permission associated with each diagnostic command should ease the work
- // of system administrators to write policy files granting permissions to
- // execute diagnostic commands to remote users. Any diagnostic command with
- // a potential impact on security should overwrite this method.
- static const JavaPermission permission() {
- JavaPermission p = {nullptr, nullptr, nullptr};
- return p;
- }
// num_arguments() is used by the DCmdFactoryImpl::get_num_arguments() template functions.
// All subclasses should override this to report the actual number of arguments.
static int num_arguments() { return 0; }
@@ -387,7 +361,6 @@ class DCmdFactory: public CHeapObj {
virtual const char* name() const = 0;
virtual const char* description() const = 0;
virtual const char* impact() const = 0;
- virtual const JavaPermission permission() const = 0;
virtual const char* disabled_message() const = 0;
// Register a DCmdFactory to make a diagnostic command available.
// Once registered, a diagnostic command must not be unregistered.
@@ -431,9 +404,6 @@ template class DCmdFactoryImpl : public DCmdFactory {
const char* impact() const {
return DCmdClass::impact();
}
- const JavaPermission permission() const {
- return DCmdClass::permission();
- }
const char* disabled_message() const {
return DCmdClass::disabled_message();
}
diff --git a/src/hotspot/share/services/management.cpp b/src/hotspot/share/services/management.cpp
index 7729fb08808..8b8efc577cb 100644
--- a/src/hotspot/share/services/management.cpp
+++ b/src/hotspot/share/services/management.cpp
@@ -2013,10 +2013,6 @@ JVM_ENTRY(void, jmm_GetDiagnosticCommandInfo(JNIEnv *env, jobjectArray cmds,
infoArray[i].name = info->name();
infoArray[i].description = info->description();
infoArray[i].impact = info->impact();
- JavaPermission p = info->permission();
- infoArray[i].permission_class = p._class;
- infoArray[i].permission_name = p._name;
- infoArray[i].permission_action = p._action;
infoArray[i].num_arguments = info->num_arguments();
infoArray[i].enabled = info->is_enabled();
}
diff --git a/src/jdk.management/share/classes/com/sun/management/DiagnosticCommandMBean.java b/src/jdk.management/share/classes/com/sun/management/DiagnosticCommandMBean.java
index 4e64e17f45f..d5fedf93855 100644
--- a/src/jdk.management/share/classes/com/sun/management/DiagnosticCommandMBean.java
+++ b/src/jdk.management/share/classes/com/sun/management/DiagnosticCommandMBean.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -138,26 +138,6 @@
*
True if the diagnostic command is enabled, false otherwise
*
*
- *
dcmd.permissionClass
String
- *
Some diagnostic command might require a specific permission to be
- * executed, in addition to the MBeanPermission to invoke their
- * associated MBean operation. This field returns the fully qualified
- * name of the permission class or null if no permission is required
- *
- *
- *
- *
dcmd.permissionName
String
- *
The fist argument of the permission required to execute this
- * diagnostic command or null if no permission is required
- *
- *
- *
dcmd.permissionAction
String
- *
The second argument of the permission required to execute this
- * diagnostic command or null if the permission constructor has only
- * one argument (like the ManagementPermission) or if no permission
- * is required
- *
- *
*
dcmd.arguments
Descriptor
*
A Descriptor instance containing the descriptions of options and
* arguments supported by the diagnostic command (see below)
diff --git a/src/jdk.management/share/classes/com/sun/management/internal/DiagnosticCommandImpl.java b/src/jdk.management/share/classes/com/sun/management/internal/DiagnosticCommandImpl.java
index 6e456c7ad02..89c292b37d0 100644
--- a/src/jdk.management/share/classes/com/sun/management/internal/DiagnosticCommandImpl.java
+++ b/src/jdk.management/share/classes/com/sun/management/internal/DiagnosticCommandImpl.java
@@ -28,7 +28,6 @@
import com.sun.management.DiagnosticCommandMBean;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
-import java.security.Permission;
import java.util.*;
import javax.management.Attribute;
import javax.management.AttributeList;
@@ -104,48 +103,12 @@ private class Wrapper {
String name;
String cmd;
DiagnosticCommandInfo info;
- Permission permission;
Wrapper(String name, String cmd, DiagnosticCommandInfo info)
throws InstantiationException {
this.name = name;
this.cmd = cmd;
this.info = info;
- this.permission = null;
- Exception cause = null;
- if (info.getPermissionClass() != null) {
- try {
- Class> c = Class.forName(info.getPermissionClass());
- if (info.getPermissionAction() == null) {
- try {
- Constructor> constructor = c.getConstructor(String.class);
- permission = (Permission) constructor.newInstance(info.getPermissionName());
-
- } catch (InstantiationException | IllegalAccessException
- | IllegalArgumentException | InvocationTargetException
- | NoSuchMethodException | SecurityException ex) {
- cause = ex;
- }
- }
- if (permission == null) {
- try {
- Constructor> constructor = c.getConstructor(String.class, String.class);
- permission = (Permission) constructor.newInstance(
- info.getPermissionName(),
- info.getPermissionAction());
- } catch (InstantiationException | IllegalAccessException
- | IllegalArgumentException | InvocationTargetException
- | NoSuchMethodException | SecurityException ex) {
- cause = ex;
- }
- }
- } catch (ClassNotFoundException ex) { }
- if (permission == null) {
- InstantiationException iex =
- new InstantiationException("Unable to instantiate required permission");
- iex.initCause(cause);
- }
- }
}
public String execute(String[] args) {
@@ -297,9 +260,6 @@ private Descriptor commandDescriptor(Wrapper w) throws IllegalArgumentException
map.put("dcmd.name", w.info.getName());
map.put("dcmd.description", w.info.getDescription());
map.put("dcmd.vmImpact", w.info.getImpact());
- map.put("dcmd.permissionClass", w.info.getPermissionClass());
- map.put("dcmd.permissionName", w.info.getPermissionName());
- map.put("dcmd.permissionAction", w.info.getPermissionAction());
map.put("dcmd.enabled", w.info.isEnabled());
StringBuilder sb = new StringBuilder();
sb.append("help ");
diff --git a/src/jdk.management/share/classes/com/sun/management/internal/DiagnosticCommandInfo.java b/src/jdk.management/share/classes/com/sun/management/internal/DiagnosticCommandInfo.java
index 1184a40b64c..90632e5332d 100644
--- a/src/jdk.management/share/classes/com/sun/management/internal/DiagnosticCommandInfo.java
+++ b/src/jdk.management/share/classes/com/sun/management/internal/DiagnosticCommandInfo.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -38,9 +38,6 @@ class DiagnosticCommandInfo {
private final String name;
private final String description;
private final String impact;
- private final String permissionClass;
- private final String permissionName;
- private final String permissionAction;
private final boolean enabled;
private final List arguments;
@@ -73,43 +70,6 @@ String getImpact() {
return impact;
}
- /**
- * Returns the name of the permission class required to be allowed
- * to invoke the diagnostic command, or null if no permission
- * is required.
- *
- * @return the name of the permission class name required to be allowed
- * to invoke the diagnostic command, or null if no permission
- * is required
- */
- String getPermissionClass() {
- return permissionClass;
- }
-
- /**
- * Returns the permission name required to be allowed to invoke the
- * diagnostic command, or null if no permission is required.
- *
- * @return the permission name required to be allowed to invoke the
- * diagnostic command, or null if no permission is required
- */
- String getPermissionName() {
- return permissionName;
- }
-
- /**
- * Returns the permission action required to be allowed to invoke the
- * diagnostic command, or null if no permission is required or
- * if the permission has no action specified.
- *
- * @return the permission action required to be allowed to invoke the
- * diagnostic command, or null if no permission is required or
- * if the permission has no action specified
- */
- String getPermissionAction() {
- return permissionAction;
- }
-
/**
* Returns {@code true} if the diagnostic command is enabled,
* {@code false} otherwise. The enabled/disabled
@@ -134,17 +94,13 @@ List getArgumentsInfo() {
}
DiagnosticCommandInfo(String name, String description,
- String impact, String permissionClass,
- String permissionName, String permissionAction,
+ String impact,
boolean enabled,
List arguments)
{
this.name = name;
this.description = description;
this.impact = impact;
- this.permissionClass = permissionClass;
- this.permissionName = permissionName;
- this.permissionAction = permissionAction;
this.enabled = enabled;
this.arguments = arguments;
}
diff --git a/src/jdk.management/share/native/libmanagement_ext/DiagnosticCommandImpl.c b/src/jdk.management/share/native/libmanagement_ext/DiagnosticCommandImpl.c
index b931c6e9893..6c0554a5c32 100644
--- a/src/jdk.management/share/native/libmanagement_ext/DiagnosticCommandImpl.c
+++ b/src/jdk.management/share/native/libmanagement_ext/DiagnosticCommandImpl.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -191,10 +191,9 @@ Java_com_sun_management_internal_DiagnosticCommandImpl_getDiagnosticCommandInfo
}
jmm_interface_management_ext->GetDiagnosticCommandInfo(env, commands, dcmd_info_array);
for (i=0; i jname, jdesc, jimpact, cmd, args, obj
- // 3 => permission class, name, action
- (*env)->PushLocalFrame(env, 6 + 3);
+ (*env)->PushLocalFrame(env, 6);
cmd = (*env)->GetObjectArrayElement(env, commands, i);
args = getDiagnosticCommandArgumentInfoArray(env,
@@ -218,11 +217,8 @@ Java_com_sun_management_internal_DiagnosticCommandImpl_getDiagnosticCommandInfo
obj = JNU_NewObjectByName(env,
"com/sun/management/internal/DiagnosticCommandInfo",
- "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZLjava/util/List;)V",
+ "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZLjava/util/List;)V",
jname, jdesc, jimpact,
- dcmd_info_array[i].permission_class==NULL?NULL:(*env)->NewStringUTF(env,dcmd_info_array[i].permission_class),
- dcmd_info_array[i].permission_name==NULL?NULL:(*env)->NewStringUTF(env,dcmd_info_array[i].permission_name),
- dcmd_info_array[i].permission_action==NULL?NULL:(*env)->NewStringUTF(env,dcmd_info_array[i].permission_action),
dcmd_info_array[i].enabled,
args);
if (obj == NULL) {
From edfe28541a6ed94357f873aa69778c7eba707cbb Mon Sep 17 00:00:00 2001
From: Robbin Ehn
Date: Thu, 28 Nov 2024 12:05:23 +0000
Subject: [PATCH 010/171] 8344306: RISC-V: Add zicond
Reviewed-by: fyang, luhenry, mli
---
src/hotspot/cpu/riscv/assembler_riscv.hpp | 32 ++++
.../cpu/riscv/c1_LIRAssembler_riscv.cpp | 1 +
.../cpu/riscv/c2_MacroAssembler_riscv.cpp | 46 +++++-
.../cpu/riscv/c2_MacroAssembler_riscv.hpp | 1 -
src/hotspot/cpu/riscv/globals_riscv.hpp | 1 +
.../cpu/riscv/macroAssembler_riscv.cpp | 141 ++++++++++++++++++
.../cpu/riscv/macroAssembler_riscv.hpp | 11 ++
src/hotspot/cpu/riscv/vm_version_riscv.hpp | 4 +
.../os_cpu/linux_riscv/riscv_hwprobe.cpp | 3 +
.../gtest/riscv/test_assembler_riscv.cpp | 109 ++++++++++++++
10 files changed, 344 insertions(+), 5 deletions(-)
create mode 100644 test/hotspot/gtest/riscv/test_assembler_riscv.cpp
diff --git a/src/hotspot/cpu/riscv/assembler_riscv.hpp b/src/hotspot/cpu/riscv/assembler_riscv.hpp
index 7334ec675e3..31713d7362a 100644
--- a/src/hotspot/cpu/riscv/assembler_riscv.hpp
+++ b/src/hotspot/cpu/riscv/assembler_riscv.hpp
@@ -3107,6 +3107,38 @@ enum Nf {
#undef INSN
+// -------------- Zicond Instruction Definitions --------------
+// Zicond conditional operations extension
+ private:
+ enum CZERO_OP : unsigned int {
+ CZERO_NEZ = 0b111,
+ CZERO_EQZ = 0b101
+ };
+
+ template
+ void czero(Register Rd, Register Rs1, Register Rs2) {
+ assert_cond(UseZicond);
+ uint32_t insn = 0;
+ patch ((address)&insn, 6, 0, 0b0110011); // bits: 7, name: 0x33, attr: ['OP']
+ patch_reg((address)&insn, 7, Rd); // bits: 5, name: 'rd'
+ patch ((address)&insn, 14, 12, OP_VALUE); // bits: 3, name: 0x7, attr: ['CZERO.NEZ'] / 0x5, attr: ['CZERO.EQZ']}
+ patch_reg((address)&insn, 15, Rs1); // bits: 5, name: 'rs1', attr: ['value']
+ patch_reg((address)&insn, 20, Rs2); // bits: 5, name: 'rs2', attr: ['condition']
+ patch ((address)&insn, 31, 25, 0b0000111); // bits: 7, name: 0x7, attr: ['CZERO']
+ emit_int32(insn);
+ }
+
+ public:
+ // Moves zero to a register rd, if the condition rs2 is equal to zero, otherwise moves rs1 to rd.
+ void czero_eqz(Register rd, Register rs1_value, Register rs2_condition) {
+ czero(rd, rs1_value, rs2_condition);
+ }
+
+ // Moves zero to a register rd, if the condition rs2 is nonzero, otherwise moves rs1 to rd.
+ void czero_nez(Register rd, Register rs1_value, Register rs2_condition) {
+ czero(rd, rs1_value, rs2_condition);
+ }
+
// -------------- ZCB Instruction Definitions --------------
// Zcb additional C instructions
private:
diff --git a/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp b/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp
index eb715227f7e..b7edd3d231f 100644
--- a/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp
+++ b/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp
@@ -870,6 +870,7 @@ void LIR_Assembler::emit_op3(LIR_Op3* op) {
}
}
+// Consider using cmov (Zicond)
void LIR_Assembler::cmove(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result, BasicType type,
LIR_Opr cmp_opr1, LIR_Opr cmp_opr2) {
Label label;
diff --git a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp
index 49efb619093..2125f67cf9d 100644
--- a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp
+++ b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp
@@ -2003,10 +2003,48 @@ void C2_MacroAssembler::enc_cmpEqNe_imm0_branch(int cmpFlag, Register op1, Label
}
void C2_MacroAssembler::enc_cmove(int cmpFlag, Register op1, Register op2, Register dst, Register src) {
- Label L;
- cmp_branch(cmpFlag ^ (1 << neg_cond_bits), op1, op2, L);
- mv(dst, src);
- bind(L);
+ bool is_unsigned = (cmpFlag & unsigned_branch_mask) == unsigned_branch_mask;
+ int op_select = cmpFlag & (~unsigned_branch_mask);
+
+ switch (op_select) {
+ case BoolTest::eq:
+ cmov_eq(op1, op2, dst, src);
+ break;
+ case BoolTest::ne:
+ cmov_ne(op1, op2, dst, src);
+ break;
+ case BoolTest::le:
+ if (is_unsigned) {
+ cmov_leu(op1, op2, dst, src);
+ } else {
+ cmov_le(op1, op2, dst, src);
+ }
+ break;
+ case BoolTest::ge:
+ if (is_unsigned) {
+ cmov_geu(op1, op2, dst, src);
+ } else {
+ cmov_ge(op1, op2, dst, src);
+ }
+ break;
+ case BoolTest::lt:
+ if (is_unsigned) {
+ cmov_ltu(op1, op2, dst, src);
+ } else {
+ cmov_lt(op1, op2, dst, src);
+ }
+ break;
+ case BoolTest::gt:
+ if (is_unsigned) {
+ cmov_gtu(op1, op2, dst, src);
+ } else {
+ cmov_gt(op1, op2, dst, src);
+ }
+ break;
+ default:
+ assert(false, "unsupported compare condition");
+ ShouldNotReachHere();
+ }
}
// Set dst to NaN if any NaN input.
diff --git a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp
index 2d14f98780d..a8eb0df419c 100644
--- a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp
+++ b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp
@@ -98,7 +98,6 @@
// refer to conditional_branches and float_conditional_branches
static const int bool_test_bits = 3;
- static const int neg_cond_bits = 2;
static const int unsigned_branch_mask = 1 << bool_test_bits;
static const int double_branch_mask = 1 << bool_test_bits;
diff --git a/src/hotspot/cpu/riscv/globals_riscv.hpp b/src/hotspot/cpu/riscv/globals_riscv.hpp
index ffbb7c58911..6772fae50ca 100644
--- a/src/hotspot/cpu/riscv/globals_riscv.hpp
+++ b/src/hotspot/cpu/riscv/globals_riscv.hpp
@@ -110,6 +110,7 @@ define_pd_global(intx, InlineSmallCode, 1000);
product(bool, UseZicbom, false, EXPERIMENTAL, "Use Zicbom instructions") \
product(bool, UseZicbop, false, EXPERIMENTAL, "Use Zicbop instructions") \
product(bool, UseZicboz, false, EXPERIMENTAL, "Use Zicboz instructions") \
+ product(bool, UseZicond, false, DIAGNOSTIC, "Use Zicond instructions") \
product(bool, UseZihintpause, false, EXPERIMENTAL, \
"Use Zihintpause instructions") \
product(bool, UseZtso, false, EXPERIMENTAL, "Assume Ztso memory model") \
diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp
index cf3c851a7ec..c39a086838d 100644
--- a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp
+++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp
@@ -1128,6 +1128,147 @@ void MacroAssembler::wrap_label(Register r1, Register r2, Label &L,
#undef INSN
+// cmov
+void MacroAssembler::cmov_eq(Register cmp1, Register cmp2, Register dst, Register src) {
+ if (UseZicond) {
+ xorr(t0, cmp1, cmp2);
+ czero_eqz(dst, dst, t0);
+ czero_nez(t0 , src, t0);
+ orr(dst, dst, t0);
+ return;
+ }
+ Label no_set;
+ bne(cmp1, cmp2, no_set);
+ mv(dst, src);
+ bind(no_set);
+}
+
+void MacroAssembler::cmov_ne(Register cmp1, Register cmp2, Register dst, Register src) {
+ if (UseZicond) {
+ xorr(t0, cmp1, cmp2);
+ czero_nez(dst, dst, t0);
+ czero_eqz(t0 , src, t0);
+ orr(dst, dst, t0);
+ return;
+ }
+ Label no_set;
+ beq(cmp1, cmp2, no_set);
+ mv(dst, src);
+ bind(no_set);
+}
+
+void MacroAssembler::cmov_le(Register cmp1, Register cmp2, Register dst, Register src) {
+ if (UseZicond) {
+ slt(t0, cmp2, cmp1);
+ czero_eqz(dst, dst, t0);
+ czero_nez(t0, src, t0);
+ orr(dst, dst, t0);
+ return;
+ }
+ Label no_set;
+ bgt(cmp1, cmp2, no_set);
+ mv(dst, src);
+ bind(no_set);
+}
+
+void MacroAssembler::cmov_leu(Register cmp1, Register cmp2, Register dst, Register src) {
+ if (UseZicond) {
+ sltu(t0, cmp2, cmp1);
+ czero_eqz(dst, dst, t0);
+ czero_nez(t0, src, t0);
+ orr(dst, dst, t0);
+ return;
+ }
+ Label no_set;
+ bgtu(cmp1, cmp2, no_set);
+ mv(dst, src);
+ bind(no_set);
+}
+
+void MacroAssembler::cmov_ge(Register cmp1, Register cmp2, Register dst, Register src) {
+ if (UseZicond) {
+ slt(t0, cmp1, cmp2);
+ czero_eqz(dst, dst, t0);
+ czero_nez(t0, src, t0);
+ orr(dst, dst, t0);
+ return;
+ }
+ Label no_set;
+ blt(cmp1, cmp2, no_set);
+ mv(dst, src);
+ bind(no_set);
+}
+
+void MacroAssembler::cmov_geu(Register cmp1, Register cmp2, Register dst, Register src) {
+ if (UseZicond) {
+ sltu(t0, cmp1, cmp2);
+ czero_eqz(dst, dst, t0);
+ czero_nez(t0, src, t0);
+ orr(dst, dst, t0);
+ return;
+ }
+ Label no_set;
+ bltu(cmp1, cmp2, no_set);
+ mv(dst, src);
+ bind(no_set);
+}
+
+void MacroAssembler::cmov_lt(Register cmp1, Register cmp2, Register dst, Register src) {
+ if (UseZicond) {
+ slt(t0, cmp1, cmp2);
+ czero_nez(dst, dst, t0);
+ czero_eqz(t0, src, t0);
+ orr(dst, dst, t0);
+ return;
+ }
+ Label no_set;
+ bge(cmp1, cmp2, no_set);
+ mv(dst, src);
+ bind(no_set);
+}
+
+void MacroAssembler::cmov_ltu(Register cmp1, Register cmp2, Register dst, Register src) {
+ if (UseZicond) {
+ sltu(t0, cmp1, cmp2);
+ czero_nez(dst, dst, t0);
+ czero_eqz(t0, src, t0);
+ orr(dst, dst, t0);
+ return;
+ }
+ Label no_set;
+ bgeu(cmp1, cmp2, no_set);
+ mv(dst, src);
+ bind(no_set);
+}
+
+void MacroAssembler::cmov_gt(Register cmp1, Register cmp2, Register dst, Register src) {
+ if (UseZicond) {
+ slt(t0, cmp2, cmp1);
+ czero_nez(dst, dst, t0);
+ czero_eqz(t0, src, t0);
+ orr(dst, dst, t0);
+ return;
+ }
+ Label no_set;
+ ble(cmp1, cmp2, no_set);
+ mv(dst, src);
+ bind(no_set);
+}
+
+void MacroAssembler::cmov_gtu(Register cmp1, Register cmp2, Register dst, Register src) {
+ if (UseZicond) {
+ sltu(t0, cmp2, cmp1);
+ czero_nez(dst, dst, t0);
+ czero_eqz(t0, src, t0);
+ orr(dst, dst, t0);
+ return;
+ }
+ Label no_set;
+ bleu(cmp1, cmp2, no_set);
+ mv(dst, src);
+ bind(no_set);
+}
+
// Float compare branch instructions
#define INSN(NAME, FLOATCMP, BRANCH) \
diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp
index 54f7127106b..cbf69e93c5c 100644
--- a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp
+++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp
@@ -626,6 +626,17 @@ class MacroAssembler: public Assembler {
void bltz(Register Rs, const address dest);
void bgtz(Register Rs, const address dest);
+ void cmov_eq(Register cmp1, Register cmp2, Register dst, Register src);
+ void cmov_ne(Register cmp1, Register cmp2, Register dst, Register src);
+ void cmov_le(Register cmp1, Register cmp2, Register dst, Register src);
+ void cmov_leu(Register cmp1, Register cmp2, Register dst, Register src);
+ void cmov_ge(Register cmp1, Register cmp2, Register dst, Register src);
+ void cmov_geu(Register cmp1, Register cmp2, Register dst, Register src);
+ void cmov_lt(Register cmp1, Register cmp2, Register dst, Register src);
+ void cmov_ltu(Register cmp1, Register cmp2, Register dst, Register src);
+ void cmov_gt(Register cmp1, Register cmp2, Register dst, Register src);
+ void cmov_gtu(Register cmp1, Register cmp2, Register dst, Register src);
+
public:
// We try to follow risc-v asm menomics.
// But as we don't layout a reachable GOT,
diff --git a/src/hotspot/cpu/riscv/vm_version_riscv.hpp b/src/hotspot/cpu/riscv/vm_version_riscv.hpp
index 8fdde0094f4..e08838c3a6f 100644
--- a/src/hotspot/cpu/riscv/vm_version_riscv.hpp
+++ b/src/hotspot/cpu/riscv/vm_version_riscv.hpp
@@ -116,6 +116,8 @@ class VM_Version : public Abstract_VM_Version {
//
// Zfh Half-Precision Floating-Point instructions
//
+ // Zicond Conditional operations
+ //
// Zicsr Control and Status Register (CSR) Instructions
// Zifencei Instruction-Fetch Fence
// Zic64b Cache blocks must be 64 bytes in size, naturally aligned in the address space.
@@ -164,6 +166,7 @@ class VM_Version : public Abstract_VM_Version {
decl(ext_Zvbb , "Zvbb" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZvbb)) \
decl(ext_Zvfh , "Zvfh" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZvfh)) \
decl(ext_Zvkn , "Zvkn" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZvkn)) \
+ decl(ext_Zicond , "Zicond" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZicond)) \
decl(mvendorid , "VendorId" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \
decl(marchid , "ArchId" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \
decl(mimpid , "ImpId" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \
@@ -223,6 +226,7 @@ class VM_Version : public Abstract_VM_Version {
RV_ENABLE_EXTENSION(UseZicbom) \
RV_ENABLE_EXTENSION(UseZicbop) \
RV_ENABLE_EXTENSION(UseZicboz) \
+ RV_ENABLE_EXTENSION(UseZicond) \
RV_ENABLE_EXTENSION(UseZihintpause) \
static void useRVA23U64Profile();
diff --git a/src/hotspot/os_cpu/linux_riscv/riscv_hwprobe.cpp b/src/hotspot/os_cpu/linux_riscv/riscv_hwprobe.cpp
index 2020e2fdb24..f785d935393 100644
--- a/src/hotspot/os_cpu/linux_riscv/riscv_hwprobe.cpp
+++ b/src/hotspot/os_cpu/linux_riscv/riscv_hwprobe.cpp
@@ -181,6 +181,9 @@ void RiscvHwprobe::add_features_from_query_result() {
if (is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_EXT_ZVFH)) {
VM_Version::ext_Zvfh.enable_feature();
}
+ if (is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_EXT_ZICOND)) {
+ VM_Version::ext_Zicond.enable_feature();
+ }
if (is_valid(RISCV_HWPROBE_KEY_CPUPERF_0)) {
VM_Version::unaligned_access.enable_feature(
query[RISCV_HWPROBE_KEY_CPUPERF_0].value & RISCV_HWPROBE_MISALIGNED_MASK);
diff --git a/test/hotspot/gtest/riscv/test_assembler_riscv.cpp b/test/hotspot/gtest/riscv/test_assembler_riscv.cpp
new file mode 100644
index 00000000000..152b997b3c8
--- /dev/null
+++ b/test/hotspot/gtest/riscv/test_assembler_riscv.cpp
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2024, Rivos Inc. 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.
+ */
+
+#include "precompiled.hpp"
+
+#if (defined(RISCV) || defined(RISCV64)) && !defined(ZERO)
+
+#include "asm/assembler.inline.hpp"
+#include "asm/macroAssembler.hpp"
+#include "memory/resourceArea.hpp"
+#include "runtime/orderAccess.hpp"
+#include "unittest.hpp"
+
+typedef int64_t (*zicond_func)(int64_t cmp1, int64_t cmp2, int64_t dst, int64_t src);
+typedef void (MacroAssembler::*cmov_func)(Register cmp1, Register cmp2, Register dst, Register src);
+
+class CmovTester {
+ public:
+ static void test(cmov_func func, int64_t a0, int64_t a1, int64_t a2, int64_t a3, int64_t result) {
+ BufferBlob* bb = BufferBlob::create("riscvTest", 128);
+ CodeBuffer code(bb);
+ MacroAssembler _masm(&code);
+ address entry = _masm.pc();
+ {
+ ((&_masm)->*func)(c_rarg0, c_rarg1, c_rarg2, c_rarg3);
+ _masm.mv(c_rarg0, c_rarg2);
+ _masm.ret();
+ }
+ _masm.flush();
+ OrderAccess::cross_modify_fence();
+ int64_t ret = ((zicond_func)entry)(a0, a1, a2, a3);
+ ASSERT_EQ(ret, result);
+ BufferBlob::free(bb);
+ }
+};
+
+void run_cmov_tests() {
+ // If 42(a0) eq 42(a1): assign dest(a2/66) the src(a3/77), expect result: 77
+ CmovTester::test(&MacroAssembler::cmov_eq, 42, 42, 66, 77, 77);
+ // If 41(a0) eq 42(a1): assign dest(a2/66) the src(a3/77), expect result: 66
+ CmovTester::test(&MacroAssembler::cmov_eq, 41, 42, 66, 77, 66);
+
+ CmovTester::test(&MacroAssembler::cmov_ne, 41, 42, 66, 77, 77);
+ CmovTester::test(&MacroAssembler::cmov_ne, 42, 42, 66, 77, 66);
+
+ CmovTester::test(&MacroAssembler::cmov_le, 41, 42, 66, 77, 77);
+ CmovTester::test(&MacroAssembler::cmov_le, 42, 42, 66, 77, 77);
+ CmovTester::test(&MacroAssembler::cmov_le, 42, -1, 66, 77, 66);
+
+ CmovTester::test(&MacroAssembler::cmov_leu, 41, 42, 66, 77, 77);
+ CmovTester::test(&MacroAssembler::cmov_leu, 42, 42, 66, 77, 77);
+ CmovTester::test(&MacroAssembler::cmov_leu, -1, 42, 66, 77, 66);
+
+ CmovTester::test(&MacroAssembler::cmov_ge, 43, 42, 66, 77, 77);
+ CmovTester::test(&MacroAssembler::cmov_ge, 42, 42, 66, 77, 77);
+ CmovTester::test(&MacroAssembler::cmov_ge, -1, 42, 66, 77, 66);
+
+ CmovTester::test(&MacroAssembler::cmov_geu, 43, 42, 66, 77, 77);
+ CmovTester::test(&MacroAssembler::cmov_geu, 42, 42, 66, 77, 77);
+ CmovTester::test(&MacroAssembler::cmov_geu, 42, -1, 66, 77, 66);
+
+ CmovTester::test(&MacroAssembler::cmov_lt, 41, 42, 66, 77, 77);
+ CmovTester::test(&MacroAssembler::cmov_lt, 42, 42, 66, 77, 66);
+ CmovTester::test(&MacroAssembler::cmov_lt, 42, -1, 66, 77, 66);
+
+ CmovTester::test(&MacroAssembler::cmov_ltu, 41, 42, 66, 77, 77);
+ CmovTester::test(&MacroAssembler::cmov_ltu, 42, 42, 66, 77, 66);
+ CmovTester::test(&MacroAssembler::cmov_ltu, -1, 42, 66, 77, 66);
+
+ CmovTester::test(&MacroAssembler::cmov_gt, 43, 42, 66, 77, 77);
+ CmovTester::test(&MacroAssembler::cmov_gt, 42, 42, 66, 77, 66);
+ CmovTester::test(&MacroAssembler::cmov_gt, -1, 42, 66, 77, 66);
+
+ CmovTester::test(&MacroAssembler::cmov_gtu, 43, 42, 66, 77, 77);
+ CmovTester::test(&MacroAssembler::cmov_gtu, 42, 42, 66, 77, 66);
+ CmovTester::test(&MacroAssembler::cmov_gtu, 42, -1, 66, 77, 66);
+}
+
+TEST_VM(RiscV, cmov) {
+ run_cmov_tests();
+ if (UseZicond) {
+ UseZicond = false;
+ run_cmov_tests();
+ UseZicond = true;
+ }
+}
+
+#endif // RISCV
From db535c86bc56b89b7213b3b097d80935fe9e8516 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C5=A0t=C4=9Bp=C3=A1n=20Schejbal?=
Date: Thu, 28 Nov 2024 13:12:45 +0000
Subject: [PATCH 011/171] 8313367: SunMSCAPI cannot read Local Computer certs
w/o Windows elevation
Reviewed-by: weijun
---
.../windows/native/libsunmscapi/security.cpp | 12 ++++++---
test/jdk/sun/security/mscapi/AllTypes.java | 27 +++----------------
2 files changed, 11 insertions(+), 28 deletions(-)
diff --git a/src/jdk.crypto.mscapi/windows/native/libsunmscapi/security.cpp b/src/jdk.crypto.mscapi/windows/native/libsunmscapi/security.cpp
index 4787708779d..747db000158 100644
--- a/src/jdk.crypto.mscapi/windows/native/libsunmscapi/security.cpp
+++ b/src/jdk.crypto.mscapi/windows/native/libsunmscapi/security.cpp
@@ -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
@@ -444,7 +444,7 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_CKeyStore_loadKeysOrCertificateC
}
else if (jCertStoreLocation == KEYSTORE_LOCATION_LOCALMACHINE) {
hCertStore = ::CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, NULL,
- CERT_SYSTEM_STORE_LOCAL_MACHINE, pszCertStoreName);
+ CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_MAXIMUM_ALLOWED_FLAG, pszCertStoreName);
}
else {
PP("jCertStoreLocation is not a valid value");
@@ -798,11 +798,15 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_CSignature_signHash
::CryptGetProvParam((HCRYPTPROV)hCryptProv, PP_CONTAINER, //deprecated
(BYTE *)pbData, &cbData, 0);
+ DWORD keysetType = 0;
+ DWORD keysetTypeLen = sizeof(keysetType);
+ ::CryptGetProvParam((HCRYPTPROV)hCryptProv, PP_KEYSET_TYPE, //deprecated
+ (BYTE*)&keysetType, &keysetTypeLen, 0);
+
// Acquire an alternative CSP handle
if (::CryptAcquireContext(&hCryptProvAlt, LPCSTR(pbData), NULL, //deprecated
- PROV_RSA_AES, 0) == FALSE)
+ PROV_RSA_AES, 0 | keysetType) == FALSE)
{
-
ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
__leave;
}
diff --git a/test/jdk/sun/security/mscapi/AllTypes.java b/test/jdk/sun/security/mscapi/AllTypes.java
index f9c98860702..9f5fb2f13d6 100644
--- a/test/jdk/sun/security/mscapi/AllTypes.java
+++ b/test/jdk/sun/security/mscapi/AllTypes.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022, 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
@@ -45,33 +45,12 @@ public static void main(String[] args) throws Exception {
var nr = test("windows-root");
var nmu = test("windows-my-currentuser");
var nru = test("windows-root-currentuser");
- var hasAdminPrivileges = detectIfRunningWithAdminPrivileges();
- var nmm = adminTest("windows-my-localmachine", hasAdminPrivileges);
- var nrm = adminTest("windows-root-localmachine", hasAdminPrivileges);
+ var nmm = test("windows-my-localmachine");
+ var nrm = test("windows-root-localmachine");
Asserts.assertEQ(nm, nmu);
Asserts.assertEQ(nr, nru);
}
- private static boolean detectIfRunningWithAdminPrivileges() {
- try {
- Process p = Runtime.getRuntime().exec("reg query \"HKU\\S-1-5-19\"");
- p.waitFor();
- return (p.exitValue() == 0);
- }
- catch (Exception ex) {
- System.out.println("Warning: unable to detect admin privileges, assuming none");
- return false;
- }
- }
-
- private static List adminTest(String type, boolean hasAdminPrivileges) throws Exception {
- if (hasAdminPrivileges) {
- return test(type);
- }
- System.out.println("Ignoring: " + type + " as it requires admin privileges");
- return null;
- }
-
private static List test(String type) throws Exception {
var stdType = "Windows-" + type.substring(8).toUpperCase(Locale.ROOT);
SecurityTools.keytool("-storetype " + type + " -list")
From 1e086b1d7305769b59271e2fa428c003216dd52a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Johan=20Sj=C3=B6len?=
Date: Thu, 28 Nov 2024 13:15:10 +0000
Subject: [PATCH 012/171] 8340103: Add internal set_flag function to VMATree
Reviewed-by: stuefe, azafari, gziemski
---
src/hotspot/share/nmt/nmtTreap.hpp | 36 +++++
src/hotspot/share/nmt/vmatree.cpp | 105 +++++++++++++-
src/hotspot/share/nmt/vmatree.hpp | 55 +++++--
test/hotspot/gtest/nmt/test_vmatree.cpp | 184 +++++++++++++++++++++++-
4 files changed, 366 insertions(+), 14 deletions(-)
diff --git a/src/hotspot/share/nmt/nmtTreap.hpp b/src/hotspot/share/nmt/nmtTreap.hpp
index 70063497439..b6be654f127 100644
--- a/src/hotspot/share/nmt/nmtTreap.hpp
+++ b/src/hotspot/share/nmt/nmtTreap.hpp
@@ -234,6 +234,10 @@ class Treap {
this->remove_all();
}
+ int size() {
+ return _node_count;
+ }
+
void upsert(const K& k, const V& v) {
TreapNode* found = find(_root, k);
if (found != nullptr) {
@@ -304,6 +308,38 @@ class Treap {
return candidate;
}
+ TreapNode* closest_gt(const K& key) {
+ TreapNode* candidate = nullptr;
+ TreapNode* pos = _root;
+ while (pos != nullptr) {
+ int cmp_r = COMPARATOR::cmp(pos->key(), key);
+ if (cmp_r > 0) {
+ // Found a match, try to find a better one.
+ candidate = pos;
+ pos = pos->_left;
+ } else if (cmp_r <= 0) {
+ pos = pos->_right;
+ }
+ }
+ return candidate;
+ }
+
+ struct Range {
+ TreapNode* start;
+ TreapNode* end;
+ Range(TreapNode* start, TreapNode* end)
+ : start(start), end(end) {}
+ };
+
+ // Return the range [start, end)
+ // where start->key() <= addr < end->key().
+ // Failure to find the range leads to start and/or end being null.
+ Range find_enclosing_range(K addr) {
+ TreapNode* start = closest_leq(addr);
+ TreapNode* end = closest_gt(addr);
+ return Range(start, end);
+ }
+
// Visit all TreapNodes in ascending key order.
template
void visit_in_order(F f) const {
diff --git a/src/hotspot/share/nmt/vmatree.cpp b/src/hotspot/share/nmt/vmatree.cpp
index 65a5bdb94ae..ec4f405f1c9 100644
--- a/src/hotspot/share/nmt/vmatree.cpp
+++ b/src/hotspot/share/nmt/vmatree.cpp
@@ -26,6 +26,7 @@
#include "precompiled.hpp"
#include "logging/log.hpp"
#include "nmt/vmatree.hpp"
+#include "utilities/globalDefinitions.hpp"
#include "utilities/growableArray.hpp"
const VMATree::RegionData VMATree::empty_regiondata{NativeCallStackStorage::StackIndex{}, mtNone};
@@ -82,12 +83,12 @@ VMATree::SummaryDiff VMATree::register_mapping(position A, position B, StateType
// Unless we know better, let B's outgoing state be the outgoing state of the node at or preceding A.
// Consider the case where the found node is the start of a region enclosing [A,B)
- stB.out = leqA_n->val().out;
+ stB.out = out_state(leqA_n);
// Direct address match.
if (leqA_n->key() == A) {
// Take over in state from old address.
- stA.in = leqA_n->val().in;
+ stA.in = in_state(leqA_n);
// We may now be able to merge two regions:
// If the node's old state matches the new, it becomes a noop. That happens, for example,
@@ -113,7 +114,7 @@ VMATree::SummaryDiff VMATree::register_mapping(position A, position B, StateType
// We add a new node, but only if there would be a state change. If there would not be a
// state change, we just omit the node.
// That happens, for example, when reserving within an already reserved region with identical metadata.
- stA.in = leqA_n->val().out; // .. and the region's prior state is the incoming state
+ stA.in = out_state(leqA_n); // .. and the region's prior state is the incoming state
if (stA.is_noop()) {
// Nothing to do.
} else {
@@ -134,7 +135,7 @@ VMATree::SummaryDiff VMATree::register_mapping(position A, position B, StateType
// outgoing state.
_tree.visit_range_in_order(A + 1, B + 1, [&](TreapNode* head) {
int cmp_B = PositionComparator::cmp(head->key(), B);
- stB.out = head->val().out;
+ stB.out = out_state(head);
if (cmp_B < 0) {
// Record all nodes preceding B.
to_be_deleted_inbetween_a_b.push({head->key(), head->val()});
@@ -215,3 +216,99 @@ VMATree::SummaryDiff VMATree::register_mapping(position A, position B, StateType
}
return diff;
}
+
+#ifdef ASSERT
+void VMATree::print_on(outputStream* out) {
+ visit_in_order([&](TreapNode* current) {
+ out->print(SIZE_FORMAT " (%s) - %s - ", current->key(), NMTUtil::tag_to_name(out_state(current).mem_tag()),
+ statetype_to_string(out_state(current).type()));
+ });
+ out->cr();
+}
+#endif
+
+VMATree::SummaryDiff VMATree::set_tag(const position start, const size size, const MemTag tag) {
+ auto pos = [](TreapNode* n) { return n->key(); };
+ position from = start;
+ position end = from+size;
+ size_t remsize = size;
+ VMATreap::Range range(nullptr, nullptr);
+
+ // Find the next range to adjust and set range, remsize and from
+ // appropriately. If it returns false, there is no valid next range.
+ auto find_next_range = [&]() -> bool {
+ range = _tree.find_enclosing_range(from);
+ if ((range.start == nullptr && range.end == nullptr) ||
+ (range.start != nullptr && range.end == nullptr)) {
+ // There is no range containing the starting address
+ assert(range.start->val().out.type() == StateType::Released, "must be");
+ return false;
+ } else if (range.start == nullptr && range.end != nullptr) {
+ position found_end = pos(range.end);
+ if (found_end >= end) {
+ // The found address is outside of our range, we can end now.
+ return false;
+ }
+ // There is at least one range [found_end, ?) which starts within [start, end)
+ // Use this as the range instead.
+ range = _tree.find_enclosing_range(found_end);
+ remsize = end - found_end;
+ from = found_end;
+ }
+ return true;
+ };
+
+ bool success = find_next_range();
+ if (!success) return SummaryDiff();
+ assert(range.start != nullptr && range.end != nullptr, "must be");
+
+ end = MIN2(from + remsize, pos(range.end));
+ IntervalState& out = out_state(range.start);
+ StateType type = out.type();
+
+ SummaryDiff diff;
+ // Ignore any released ranges, these must be mtNone and have no stack
+ if (type != StateType::Released) {
+ RegionData new_data = RegionData(out.stack(), tag);
+ SummaryDiff result = register_mapping(from, end, type, new_data);
+ diff.add(result);
+ }
+
+ remsize = remsize - (end - from);
+ from = end;
+
+ // If end < from + sz then there are multiple ranges for which to set the flag.
+ while (end < from + remsize) {
+ // Using register_mapping may invalidate the already found range, so we must
+ // use find_next_range repeatedly
+ bool success = find_next_range();
+ if (!success) return diff;
+ assert(range.start != nullptr && range.end != nullptr, "must be");
+
+ end = MIN2(from + remsize, pos(range.end));
+ IntervalState& out = out_state(range.start);
+ StateType type = out.type();
+
+ if (type != StateType::Released) {
+ RegionData new_data = RegionData(out.stack(), tag);
+ SummaryDiff result = register_mapping(from, end, type, new_data);
+ diff.add(result);
+ }
+ remsize = remsize - (end - from);
+ from = end;
+ }
+
+ return diff;
+}
+
+#ifdef ASSERT
+void VMATree::SummaryDiff::print_on(outputStream* out) {
+ for (int i = 0; i < mt_number_of_tags; i++) {
+ if (tag[i].reserve == 0 && tag[i].commit == 0) {
+ continue;
+ }
+ out->print_cr("Tag %s R: " INT64_FORMAT " C: " INT64_FORMAT, NMTUtil::tag_to_enum_name((MemTag)i), tag[i].reserve,
+ tag[i].commit);
+ }
+}
+#endif
diff --git a/src/hotspot/share/nmt/vmatree.hpp b/src/hotspot/share/nmt/vmatree.hpp
index cfb3c8ab524..75f814c81c0 100644
--- a/src/hotspot/share/nmt/vmatree.hpp
+++ b/src/hotspot/share/nmt/vmatree.hpp
@@ -26,10 +26,11 @@
#ifndef SHARE_NMT_VMATREE_HPP
#define SHARE_NMT_VMATREE_HPP
+#include "nmt/memTag.hpp"
#include "nmt/nmtNativeCallStackStorage.hpp"
#include "nmt/nmtTreap.hpp"
-#include "runtime/os.hpp"
#include "utilities/globalDefinitions.hpp"
+#include "utilities/ostream.hpp"
#include
// A VMATree stores a sequence of points on the natural number line.
@@ -42,6 +43,7 @@ class VMATree {
// A position in memory.
public:
using position = size_t;
+ using size = size_t;
class PositionComparator {
public:
@@ -140,6 +142,14 @@ class VMATree {
private:
VMATreap _tree;
+ static IntervalState& in_state(TreapNode* node) {
+ return node->val().in;
+ }
+
+ static IntervalState& out_state(TreapNode* node) {
+ return node->val().out;
+ }
+
// AddressState saves the necessary information for performing online summary accounting.
struct AddressState {
position address;
@@ -162,6 +172,7 @@ class VMATree {
delta reserve;
delta commit;
};
+
struct SummaryDiff {
SingleDiff tag[mt_number_of_tags];
SummaryDiff() {
@@ -169,26 +180,47 @@ class VMATree {
tag[i] = SingleDiff{0, 0};
}
}
+
+ void add(SummaryDiff& other) {
+ for (int i = 0; i < mt_number_of_tags; i++) {
+ tag[i].reserve += other.tag[i].reserve;
+ tag[i].commit += other.tag[i].commit;
+ }
+ }
+
+#ifdef ASSERT
+ void print_on(outputStream* out);
+#endif
};
private:
SummaryDiff register_mapping(position A, position B, StateType state, const RegionData& metadata, bool use_tag_inplace = false);
public:
- SummaryDiff reserve_mapping(position from, position sz, const RegionData& metadata) {
- return register_mapping(from, from + sz, StateType::Reserved, metadata, false);
+ SummaryDiff reserve_mapping(position from, size size, const RegionData& metadata) {
+ return register_mapping(from, from + size, StateType::Reserved, metadata, false);
+ }
+
+ SummaryDiff commit_mapping(position from, size size, const RegionData& metadata, bool use_tag_inplace = false) {
+ return register_mapping(from, from + size, StateType::Committed, metadata, use_tag_inplace);
}
- SummaryDiff commit_mapping(position from, position sz, const RegionData& metadata, bool use_tag_inplace = false) {
- return register_mapping(from, from + sz, StateType::Committed, metadata, use_tag_inplace);
+ // Given an interval and a tag, find all reserved and committed ranges at least
+ // partially contained within that interval and set their tag to the one provided.
+ // This may cause merging and splitting of ranges.
+ // Released regions are ignored.
+ SummaryDiff set_tag(position from, size size, MemTag tag);
+
+ SummaryDiff uncommit_mapping(position from, size size, const RegionData& metadata) {
+ return register_mapping(from, from + size, StateType::Reserved, metadata, true);
}
- SummaryDiff uncommit_mapping(position from, position sz, const RegionData& metadata) {
- return register_mapping(from, from + sz, StateType::Reserved, metadata, true);
+ SummaryDiff release_mapping(position from, size size) {
+ return register_mapping(from, from + size, StateType::Released, VMATree::empty_regiondata);
}
- SummaryDiff release_mapping(position from, position sz) {
- return register_mapping(from, from + sz, StateType::Released, VMATree::empty_regiondata);
+ VMATreap& tree() {
+ return _tree;
}
public:
@@ -196,6 +228,11 @@ class VMATree {
void visit_in_order(F f) const {
_tree.visit_in_order(f);
}
+
+#ifdef ASSERT
+ void print_on(outputStream* out);
+#endif
+
};
#endif
diff --git a/test/hotspot/gtest/nmt/test_vmatree.cpp b/test/hotspot/gtest/nmt/test_vmatree.cpp
index d7a9a5fcff7..3a61e0c7cca 100644
--- a/test/hotspot/gtest/nmt/test_vmatree.cpp
+++ b/test/hotspot/gtest/nmt/test_vmatree.cpp
@@ -284,6 +284,188 @@ TEST_VM_F(NMTVMATreeTest, LowLevel) {
}
}
+TEST_VM_F(NMTVMATreeTest, SetTag) {
+ using State = VMATree::StateType;
+ struct testrange {
+ VMATree::position from;
+ VMATree::position to;
+ MemTag tag;
+ NCS::StackIndex stack;
+ State state;
+ };
+
+ // Take a sorted list of testranges and check that those and only those are found in the tree.
+ auto expect_equivalent_form = [&](auto& expected, VMATree& tree) {
+ // With auto& our arrays do not deteriorate to pointers but are kept as testrange[N]
+ // so this actually works!
+ int len = sizeof(expected) / sizeof(testrange);
+ VMATree::position previous_to = 0;
+ for (int i = 0; i < len; i++) {
+ testrange expect = expected[i];
+ assert(previous_to == 0 || previous_to <= expect.from, "the expected list must be sorted");
+ previous_to = expect.to;
+
+ VMATree::VMATreap::Range found = tree.tree().find_enclosing_range(expect.from);
+ ASSERT_NE(nullptr, found.start);
+ ASSERT_NE(nullptr, found.end);
+ // Same region
+ EXPECT_EQ(expect.from, found.start->key());
+ EXPECT_EQ(expect.to, found.end->key());
+ // Same tag
+ EXPECT_EQ(expect.tag, found.start->val().out.mem_tag());
+ EXPECT_EQ(expect.tag, found.end->val().in.mem_tag());
+ // Same stack
+ EXPECT_EQ(expect.stack, found.start->val().out.stack());
+ EXPECT_EQ(expect.stack, found.end->val().in.stack());
+ // Same state
+ EXPECT_EQ(expect.state, found.start->val().out.type());
+ EXPECT_EQ(expect.state, found.end->val().in.type());
+ }
+ // expected must cover all nodes
+ EXPECT_EQ(len+1, tree.tree().size());
+ };
+ NCS::StackIndex si = NCS::StackIndex();
+ Tree::RegionData rd(si, mtNone);
+
+ { // The gc/cds case with only reserved data
+ testrange expected[2]{
+ { 0, 500, mtGC, si, State::Reserved},
+ {500, 600, mtClassShared, si, State::Reserved}
+ };
+ VMATree tree;
+
+ tree.reserve_mapping(0, 600, rd);
+
+ tree.set_tag(0, 500, mtGC);
+ tree.set_tag(500, 100, mtClassShared);
+ expect_equivalent_form(expected, tree);
+ }
+
+ { // Now let's add in some committed data
+ testrange expected[]{
+ { 0, 100, mtGC, si, State::Reserved},
+ {100, 225, mtGC, si, State::Committed},
+ {225, 500, mtGC, si, State::Reserved},
+ {500, 550, mtClassShared, si, State::Reserved},
+ {550, 560, mtClassShared, si, State::Committed},
+ {560, 565, mtClassShared, si, State::Reserved},
+ {565, 575, mtClassShared, si, State::Committed},
+ {575, 600, mtClassShared, si, State::Reserved}
+ };
+ VMATree tree;
+
+ tree.reserve_mapping(0, 600, rd);
+ // The committed areas
+ tree.commit_mapping(100, 125, rd);
+ tree.commit_mapping(550, 10, rd);
+ tree.commit_mapping(565, 10, rd);
+ // OK, set tag
+ tree.set_tag(0, 500, mtGC);
+ tree.set_tag(500, 100, mtClassShared);
+ expect_equivalent_form(expected, tree);
+ }
+
+ { // Setting the tag for adjacent regions with same stacks should merge the regions
+ testrange expected[]{
+ {0, 200, mtGC, si, State::Reserved}
+ };
+ VMATree tree;
+ Tree::RegionData gc(si, mtGC);
+ Tree::RegionData compiler(si, mtCompiler);
+ tree.reserve_mapping(0, 100, gc);
+ tree.reserve_mapping(100, 100, compiler);
+ tree.set_tag(0, 200, mtGC);
+ expect_equivalent_form(expected, tree);
+ }
+
+ { // Setting the tag for adjacent regions with different stacks should NOT merge the regions
+ NCS::StackIndex si1 = 1;
+ NCS::StackIndex si2 = 2;
+ testrange expected[]{
+ { 0, 100, mtGC, si1, State::Reserved},
+ {100, 200, mtGC, si2, State::Reserved}
+ };
+ VMATree tree;
+ Tree::RegionData gc(si1, mtGC);
+ Tree::RegionData compiler(si2, mtCompiler);
+ tree.reserve_mapping(0, 100, gc);
+ tree.reserve_mapping(100, 100, compiler);
+ tree.set_tag(0, 200, mtGC);
+ expect_equivalent_form(expected, tree);
+ }
+
+ { // Setting the tag in the middle of a range causes a split
+ testrange expected[]{
+ { 0, 100, mtCompiler, si, State::Reserved},
+ {100, 150, mtGC, si, State::Reserved},
+ {150, 200, mtCompiler, si, State::Reserved}
+ };
+ VMATree tree;
+ Tree::RegionData compiler(si, mtCompiler);
+ tree.reserve_mapping(0, 200, compiler);
+ tree.set_tag(100, 50, mtGC);
+ expect_equivalent_form(expected, tree);
+ }
+
+ { // Setting the tag in between two ranges causes a split
+ testrange expected[]{
+ { 0, 75, mtGC, si, State::Reserved},
+ { 75, 125, mtClass, si, State::Reserved},
+ {125, 200, mtCompiler, si, State::Reserved},
+ };
+ VMATree tree;
+ Tree::RegionData gc(si, mtGC);
+ Tree::RegionData compiler(si, mtCompiler);
+ tree.reserve_mapping(0, 100, gc);
+ tree.reserve_mapping(100, 100, compiler);
+ tree.set_tag(75, 50, mtClass);
+ expect_equivalent_form(expected, tree);
+ }
+
+ { // Holes in the address range are acceptable and untouched
+ testrange expected[]{
+ { 0, 50, mtGC, si, State::Reserved},
+ {50, 75, mtNone, si, State::Released},
+ {75, 80, mtGC, si, State::Reserved},
+ {80, 100, mtClassShared, si, State::Reserved}
+ };
+ VMATree tree;
+ Tree::RegionData class_shared(si, mtClassShared);
+ tree.reserve_mapping(0, 50, class_shared);
+ tree.reserve_mapping(75, 25, class_shared);
+ tree.set_tag(0, 80, mtGC);
+ expect_equivalent_form(expected, tree);
+ }
+
+ { // Check that setting tag with 'hole' not consisting of any regions work
+ testrange expected[]{
+ {10, 20, mtCompiler, si, State::Reserved}
+ };
+ VMATree tree;
+ Tree::RegionData class_shared(si, mtClassShared);
+ tree.reserve_mapping(10, 10, class_shared);
+ tree.set_tag(0, 100, mtCompiler);
+ expect_equivalent_form(expected, tree);
+ }
+
+ { // Check that multiple holes still work
+ testrange expected[]{
+ { 0, 1, mtGC, si, State::Reserved},
+ { 1, 50, mtNone, si, State::Released},
+ {50, 75, mtGC, si, State::Reserved},
+ {75, 99, mtNone, si, State::Released},
+ {99, 100, mtGC, si, State::Reserved}
+ };
+ VMATree tree;
+ Tree::RegionData class_shared(si, mtClassShared);
+ tree.reserve_mapping(0, 100, class_shared);
+ tree.release_mapping(1, 49);
+ tree.release_mapping(75, 24);
+ tree.set_tag(0, 100, mtGC);
+ expect_equivalent_form(expected, tree);
+ }
+}
+
// Tests for summary accounting
TEST_VM_F(NMTVMATreeTest, SummaryAccounting) {
{ // Fully enclosed re-reserving works correctly.
@@ -330,7 +512,7 @@ TEST_VM_F(NMTVMATreeTest, SummaryAccounting) {
diff = all_diff.tag[NMTUtil::tag_to_index(mtTest)];
EXPECT_EQ(100, diff.reserve);
}
- { // Adjacent reserved mappings with different flags
+ { // Adjacent reserved mappings with different tags
Tree::RegionData rd(NCS::StackIndex(), mtTest);
Tree::RegionData rd2(NCS::StackIndex(), mtNMT);
Tree tree;
From 7dc00d39b4e184a59cbcd644d22db61b1abe8a4b Mon Sep 17 00:00:00 2001
From: Christian Hagedorn
Date: Thu, 28 Nov 2024 13:58:14 +0000
Subject: [PATCH 013/171] 8345154: IGV: Show Parse and Assertion Predicate type
as extra label
Reviewed-by: rcastanedalo
---
src/hotspot/share/opto/ifnode.cpp | 4 ++--
.../filters/customNodeInfo.filter | 24 +++++++++++++++++++
2 files changed, 26 insertions(+), 2 deletions(-)
diff --git a/src/hotspot/share/opto/ifnode.cpp b/src/hotspot/share/opto/ifnode.cpp
index c0ed3f7e5d4..677cf5b7d60 100644
--- a/src/hotspot/share/opto/ifnode.cpp
+++ b/src/hotspot/share/opto/ifnode.cpp
@@ -2213,10 +2213,10 @@ void ParsePredicateNode::dump_spec(outputStream* st) const {
st->print("Loop ");
break;
case Deoptimization::DeoptReason::Reason_profile_predicate:
- st->print("Profiled_Loop ");
+ st->print("Profiled Loop ");
break;
case Deoptimization::DeoptReason::Reason_loop_limit_check:
- st->print("Loop_Limit_Check ");
+ st->print("Loop Limit Check ");
break;
default:
fatal("unknown kind");
diff --git a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/customNodeInfo.filter b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/customNodeInfo.filter
index bcdd86ba7d3..f94f06ab284 100644
--- a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/customNodeInfo.filter
+++ b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/customNodeInfo.filter
@@ -34,3 +34,27 @@ editProperty(matches("name", "CallLeafDirect|CallLeafDirectVector|CallLeafNoFPDi
// Show pre/main/post at CountedLoopNodes.
editProperty(hasProperty("loop_kind"), ["loop_kind"], "extra_label",
function(loop_kind) { return loop_kind[0]; });
+
+// Show Parse Predicate type.
+function parsePredicateInfo(dump_spec) {
+ // It's easier to match with ".*" because type "Loop" can also be found in type "Loop Limit Check" and "Profiled Loop".
+ // Matching with ".*" also requires us to exclude the optional "#useless" string at the end.
+ var predicateMatch = /#(.*)(#useless)?/.exec(dump_spec);
+ if (predicateMatch != null) {
+ return predicateMatch[1].trim();
+ }
+ return null;
+}
+editProperty(matches("name", "ParsePredicate"), ["dump_spec"], "extra_label",
+ function(dump_spec) { return parsePredicateInfo(dump_spec[0]);});
+
+// Show Assertion Predicate type.
+function assertionPredicateInfo(dump_spec) {
+ var predicateMatch = /#((Init|Last) Value Assertion Predicate)/.exec(dump_spec);
+ if (predicateMatch != null) {
+ return predicateMatch[1];
+ }
+ return null;
+}
+editProperty(matches("name", "If|RangeCheck"), ["dump_spec"], "extra_label",
+ function(dump_spec) { return assertionPredicateInfo(dump_spec[0]);});
From 3b21a298c29d88720f6bfb2dc1f3305b6a3db307 Mon Sep 17 00:00:00 2001
From: Daniel Fuchs
Date: Thu, 28 Nov 2024 14:17:15 +0000
Subject: [PATCH 014/171] 8345175: Further cleanup in java.logging and
jdk.internal.logger after JEP 486 integration
Reviewed-by: alanb, coffeys
---
.../jdk/internal/logger/LoggerFinderLoader.java | 4 ----
.../share/classes/java/util/logging/LogManager.java | 13 ++++---------
2 files changed, 4 insertions(+), 13 deletions(-)
diff --git a/src/java.base/share/classes/jdk/internal/logger/LoggerFinderLoader.java b/src/java.base/share/classes/jdk/internal/logger/LoggerFinderLoader.java
index 36edb918712..72fe24c25bb 100644
--- a/src/java.base/share/classes/jdk/internal/logger/LoggerFinderLoader.java
+++ b/src/java.base/share/classes/jdk/internal/logger/LoggerFinderLoader.java
@@ -148,8 +148,6 @@ public Logger getLogger(String name, Module module) {
private static System.LoggerFinder loadLoggerFinder() {
System.LoggerFinder result;
try {
- // Iterator iterates with the access control context stored
- // at ServiceLoader creation time.
final Iterator iterator =
findLoggerFinderProviders();
if (iterator.hasNext()) {
@@ -197,8 +195,6 @@ private static System.LoggerFinder loadDefaultImplementation() {
DefaultLoggerFinder result = null;
try {
- // Iterator iterates with the access control context stored
- // at ServiceLoader creation time.
if (iterator.hasNext()) {
result = iterator.next();
}
diff --git a/src/java.logging/share/classes/java/util/logging/LogManager.java b/src/java.logging/share/classes/java/util/logging/LogManager.java
index 0b7a854dddf..9c9c708a062 100644
--- a/src/java.logging/share/classes/java/util/logging/LogManager.java
+++ b/src/java.logging/share/classes/java/util/logging/LogManager.java
@@ -164,7 +164,7 @@ public class LogManager {
// LoggerContext for system loggers and user loggers
private final LoggerContext systemContext = new SystemLoggerContext();
private final LoggerContext userContext = new LoggerContext();
- // non final field - make it volatile to make sure that other threads
+ // non-final field - make it volatile to make sure that other threads
// will see the new value once ensureLogManagerInitialized() has finished
// executing.
private volatile Logger rootLogger;
@@ -312,7 +312,6 @@ protected LogManager() {
*/
private boolean initializedCalled = false;
private volatile boolean initializationDone = false;
- @SuppressWarnings("removal")
final void ensureLogManagerInitialized() {
final LogManager owner = this;
if (initializationDone || owner != manager) {
@@ -422,15 +421,11 @@ private void readPrimordialConfiguration() { // must be called while holding con
}
}
- // LoggerContext maps from AppContext
- private WeakHashMap