Author SHA1 Message Date
DingliZhang 1d0c2e911f Add supports_misaligned_vector_accesses
OpenJDK GHA Sanity Checks / Prepare the run (push) Has been cancelled
OpenJDK GHA Sanity Checks / linux-x64 (push) Has been cancelled
OpenJDK GHA Sanity Checks / linux-x64-hs-nopch (push) Has been cancelled
OpenJDK GHA Sanity Checks / linux-x64-hs-zero (push) Has been cancelled
OpenJDK GHA Sanity Checks / linux-x64-hs-minimal (push) Has been cancelled
OpenJDK GHA Sanity Checks / linux-x64-hs-optimized (push) Has been cancelled
OpenJDK GHA Sanity Checks / linux-x64-static (push) Has been cancelled
OpenJDK GHA Sanity Checks / linux-x64-static-libs (push) Has been cancelled
OpenJDK GHA Sanity Checks / linux-cross-compile (push) Has been cancelled
OpenJDK GHA Sanity Checks / alpine-linux-x64 (push) Has been cancelled
OpenJDK GHA Sanity Checks / macos-x64 (push) Has been cancelled
OpenJDK GHA Sanity Checks / macos-aarch64 (push) Has been cancelled
OpenJDK GHA Sanity Checks / windows-x64 (push) Has been cancelled
OpenJDK GHA Sanity Checks / windows-aarch64 (push) Has been cancelled
OpenJDK GHA Sanity Checks / docs (push) Has been cancelled
2025-10-09 16:03:20 +08:00
DingliZhang a36d5f8fa9 8368722: RISC-V: Several vector load/store tests fail without support for misaligned vector access 2025-09-30 10:31:18 +08:00
Fei Yang 538a722c2e 8368732: RISC-V: Detect support for misaligned vector access via hwprobe
Reviewed-by: mli, dzhang
2025-09-30 01:40:35 +00:00
Alexey Semenyuk c57003c9b8 8368890: open/test/jdk/tools/jpackage/macosx/NameWithSpaceTest.java fails randomly
Reviewed-by: almatvee
2025-09-29 21:39:42 +00:00
Afshin Zafari 2f29b3f24a 8366884: NMT fails with MallocLimit: reached category "mtCompiler" limit
Reviewed-by: phubner, jsjolen
2025-09-29 19:24:28 +00:00
Hannes GreuleandChristian Hagedorn 59e76af47b 8367967: C2: "fatal error: Not monotonic" with Mod nodes
Co-authored-by: Christian Hagedorn <chagedorn@openjdk.org>
Reviewed-by: bmaillard, vlivanov, chagedorn, shade
2025-09-29 18:40:43 +00:00
Chen Liang 6c8e384c63 8356022: Migrate descriptor parsing from generics to BytecodeDescriptor
Reviewed-by: rriggs
2025-09-29 18:22:24 +00:00
Chris Plummer 3d97e17a31 8367318: Test vmTestbase/nsk/jdi/MethodEntryRequest/addClassFilter_rt/filter_rt001/TestDescription.java timed out after passing
Reviewed-by: amenkov, sspitsyn
2025-09-29 17:46:17 +00:00
Brian Burkhalter aabf699dd0 8355339: Test java/io/File/GetCanonicalPath.java failed: The specified network name is no longer available
Reviewed-by: alanb
2025-09-29 17:43:35 +00:00
Hamlin Li 9d71af108e 8367253: RISC-V: refactor dependent cpu extensions
Reviewed-by: fyang, luhenry
2025-09-29 16:04:54 +00:00
Joe Darcy 63688d894e 8368822: Refactor Float16.valueOf(double)
Reviewed-by: rgiulietti
2025-09-29 14:48:04 +00:00
Roger Riggs 9d9c0e0670 8368793: java/lang/StringBuilder/RacingSBThreads.java timed out in Xcomp subtest
Reviewed-by: iris, alanb, syan
2025-09-29 13:55:49 +00:00
Daniel Gredler fdbba049a2 8368775: Remove outdated comment in OutlineTextRenderer
Reviewed-by: prr, dnguyen, serb
2025-09-29 10:39:25 +00:00
Daniel Gredler 6165921449 7156751: [macosx] Problem with printing
Reviewed-by: prr, serb
2025-09-29 10:28:45 +00:00
Thomas Schatzl 08b677bba4 8071277: G1: Merge commits and uncommits of contiguous memory
Reviewed-by: iwalulya, ayang
2025-09-29 10:05:45 +00:00
Albert Mingkun Yang 75269fdb49 8368715: Serial: Add GCTraceTime for marking from roots subphases during full gc marking
Reviewed-by: fandreuzzi, tschatzl, iwalulya
2025-09-29 07:26:43 +00:00
Jan Lahoda d53190ac44 8366582: Test jdk/jshell/ToolSimpleTest.java failed: provider not found
Reviewed-by: asotona
2025-09-29 05:36:18 +00:00
Axel Boldt-Christmas e19ec6f785 8368754: runtime/cds/appcds/SignedJar.java log regex is too strict
Reviewed-by: iklam, dholmes
2025-09-29 05:19:56 +00:00
Sergey Bylokhov 320230db5f 8367795: HeadlessMalfunctionTest may fail due to timeout
Reviewed-by: prr
2025-09-28 04:49:58 +00:00
Kelvin Nilsen af8fb20ac0 8368307: Shenandoah: get_next_bit_impl should special case weak and strong mark bits
Reviewed-by: wkemper
2025-09-27 04:07:29 +00:00
SendaoYan 9093d3a04c 8368668: Several vmTestbase/vm/gc/compact tests timed out on large memory machine
Reviewed-by: lmesnik
2025-09-27 02:37:39 +00:00
Archie Cobbs 5b1ebbb271 8366561: Improve documentation for how the -Xlint flag works
Reviewed-by: vromero
2025-09-27 02:34:27 +00:00
Mohamed Issa 37f0e74d32 8364305: Support AVX10 saturating floating point conversion instructions
Reviewed-by: sviswanathan, sparasa, jbhateja
2025-09-26 21:10:30 +00:00
Alex MenkovandAlan Bateman cedc0117ac 8365057: Add support for java.util.concurrent lock information to Thread.dump_to_file
Co-authored-by: Alex Menkov <amenkov@openjdk.org>
Co-authored-by: Alan Bateman <alanb@openjdk.org>
Reviewed-by: sspitsyn, alanb
2025-09-26 20:49:36 +00:00
Justin Lu 12c0f29b97 8368498: Use JUnit instead of TestNG for jdk_text tests
Reviewed-by: naoto
2025-09-26 20:12:48 +00:00
Francesco Andreuzzi c6cecc581f 8283198: Remove src/jdk.hotspot.agent/test
Reviewed-by: amenkov, ayang, sspitsyn
2025-09-26 19:51:04 +00:00
Leonid Mesnik 62cc347242 8368699: nsk/jvmti/scenarios/events/EM04/em04t001/em04t001.cpp destroys jvmti monitor when VM is dead
Reviewed-by: sspitsyn
2025-09-26 19:36:00 +00:00
Leonid Mesnik 556dfddac8 8308027: GetThreadListStackTraces/OneGetThreadListStackTraces.java should be skipped when thread factory is used
Reviewed-by: dholmes, sspitsyn
2025-09-26 19:34:04 +00:00
Naoto Sato bdf6853cfd 8368328: CompactNumberFormat.clone does not produce independent instances
Reviewed-by: rgiulietti, jlu
2025-09-26 16:50:05 +00:00
Ashutosh Mehra aa6ff45052 8368693: Duplicate methods in vmClasses
Reviewed-by: liach, coleenp, dholmes
2025-09-26 14:56:03 +00:00
Albert Mingkun Yang 25abdd85c4 8368752: Serial: Remove unused arg of DefNewGeneration::gc_epilogue
Reviewed-by: tschatzl, fandreuzzi
2025-09-26 14:48:26 +00:00
Manuel Hässig 501b2b3ebc 8368615: VSCode IDE: Oracle Java extension routinely runs out of memory
Reviewed-by: erikj
2025-09-26 14:28:35 +00:00
Roger Riggs 2360542e89 8368683: [process] Increase jtreg debug output maxOutputSize for TreeTest
Reviewed-by: msheppar
2025-09-26 14:19:12 +00:00
Alexey Semenyuk bdb7d25ac1 8358723: jpackage signing issues: the main launcher doesn't have entitlements
Reviewed-by: almatvee
2025-09-26 13:59:39 +00:00
Joachim Kern f0e1078c71 8368250: [AIX] now ubsan vptr check is also possible (follow up of JDK-8354686)
Reviewed-by: erikj, stuefe, mbaesken
2025-09-26 12:14:58 +00:00
Matthias Baesken 7bfdb01207 8368565: Adjust comment regarding dependency of libjvm.so to librt
Reviewed-by: dholmes
2025-09-26 09:00:59 +00:00
Matthias Baesken a80ba6260e 8357691: File blocked.certs contains bad content when boot jdk 25 is used, sun/security/lib/CheckBlockedCerts.java failing
Reviewed-by: erikj, iklam
2025-09-26 07:56:40 +00:00
Arno Zeller b90799c0e9 8368616: runtime/cds/appcds/aotCache/JavaAgent.java#dynamic fails on non CDS platforms/builds after JDK-8362561
Reviewed-by: mbaesken, shade, iklam
2025-09-26 07:47:26 +00:00
Albert Mingkun Yang 873078028b 8368006: Parallel: Skip full regions in dense prefix during Full GC
Reviewed-by: gli, fandreuzzi
2025-09-26 07:27:51 +00:00
143 changed files with 2986 additions and 1383 deletions
+1 -1
View File
@@ -63,7 +63,7 @@ TOOL_GENERATECURRENCYDATA = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_
TOOL_TZDB = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \
build.tools.tzdb.TzdbZoneRulesCompiler
TOOL_BLOCKED_CERTS = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \
TOOL_BLOCKED_CERTS = $(JAVA_SMALL) -Xlog:disable -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \
--add-exports java.base/sun.security.util=ALL-UNNAMED \
build.tools.blockedcertsconverter.BlockedCertsConverter
+1 -1
View File
@@ -79,7 +79,7 @@ AC_DEFUN([FLAGS_SETUP_LDFLAGS_HELPER],
fi
if test "x$OPENJDK_TARGET_OS" = xaix; then
BASIC_LDFLAGS="-Wl,-b64 -Wl,-brtl -Wl,-bnorwexec -Wl,-blibpath:/usr/lib:lib -Wl,-bnoexpall \
-Wl,-bernotok -Wl,-bdatapsize:64k -Wl,-btextpsize:64k -Wl,-bstackpsize:64k"
-Wl,-bernotok -Wl,-bcdtors:mbr::s -Wl,-bdatapsize:64k -Wl,-btextpsize:64k -Wl,-bstackpsize:64k"
BASIC_LDFLAGS_JVM_ONLY="$BASIC_LDFLAGS_JVM_ONLY -Wl,-lC_r -Wl,-bbigtoc"
fi
+7 -2
View File
@@ -565,9 +565,14 @@ AC_DEFUN_ONCE([JDKOPT_SETUP_UNDEFINED_BEHAVIOR_SANITIZER],
# with an additional define LLVM_SYMBOLIZER, which we set here.
# To calculate the correct llvm_symbolizer path we can use the location of the compiler, because
# their relation is fixed.
# In the ubsan case we have to link every binary with the C++-compiler as linker, because inherently
# the C-Compiler and the C++-compiler used as linker provide a different set of ubsan exports.
# Linking an executable with the C-compiler and one of its shared libraries with the C++-compiler
# leeds to unresolved symbols.
if test "x$TOOLCHAIN_TYPE" = "xclang" && test "x$OPENJDK_TARGET_OS" = "xaix"; then
UBSAN_CFLAGS="$UBSAN_CFLAGS -fno-sanitize=function,vptr -DLLVM_SYMBOLIZER=$(dirname $(dirname $CC))/tools/ibm-llvm-symbolizer"
UBSAN_LDFLAGS="$UBSAN_LDFLAGS -fno-sanitize=function,vptr -Wl,-bbigtoc"
UBSAN_CFLAGS="$UBSAN_CFLAGS -DLLVM_SYMBOLIZER=$(dirname $(dirname $CC))/tools/ibm-llvm-symbolizer"
UBSAN_LDFLAGS="$UBSAN_LDFLAGS -Wl,-bbigtoc"
LD="$LDCXX"
fi
UTIL_ARG_ENABLE(NAME: ubsan, DEFAULT: false, RESULT: UBSAN_ENABLED,
DESC: [enable UndefinedBehaviorSanitizer],
+1 -5
View File
@@ -136,12 +136,8 @@ AC_DEFUN_ONCE([LIB_SETUP_LIBRARIES],
BASIC_JVM_LIBS="$BASIC_JVM_LIBS $LIBPTHREAD"
fi
# librt for legacy clock_gettime
# librt - for timers (timer_* functions)
if test "x$OPENJDK_TARGET_OS" = xlinux; then
# Hotspot needs to link librt to get the clock_* functions.
# But once our supported minimum build and runtime platform
# has glibc 2.17, this can be removed as the functions are
# in libc.
BASIC_JVM_LIBS="$BASIC_JVM_LIBS -lrt"
fi
@@ -22,6 +22,7 @@
// Java extension
"jdk.project.jdkhome": "{{OUTPUTDIR}}/jdk",
"jdk.java.onSave.organizeImports": false, // prevents unnecessary changes
"jdk.serverVmOptions": ["-Xmx2G"], // prevent out of memory
// Additional conventions
"files.associations": {
@@ -199,6 +199,8 @@ enum Ampere_CPU_Model {
constexpr static bool supports_secondary_supers_table() { return true; }
constexpr static bool supports_misaligned_vector_accesses() { return true; }
static void get_compatible_board(char *buf, int buflen);
static const SpinWait& spin_wait_desc() { return _spin_wait; }
+1
View File
@@ -64,6 +64,7 @@ public:
constexpr static bool supports_stack_watermark_barrier() { return true; }
constexpr static bool supports_recursive_lightweight_locking() { return true; }
constexpr static bool supports_secondary_supers_table() { return true; }
constexpr static bool supports_misaligned_vector_accesses() { return true; }
static bool supports_float16() { return PowerArchitecturePPC64 >= 9; }
+10 -32
View File
@@ -160,7 +160,7 @@ void VM_Version::common_initialize() {
if (FLAG_IS_DEFAULT(AvoidUnalignedAccesses)) {
FLAG_SET_DEFAULT(AvoidUnalignedAccesses,
unaligned_access.value() != MISALIGNED_FAST);
unaligned_scalar.value() != MISALIGNED_SCALAR_FAST);
}
if (!AvoidUnalignedAccesses) {
@@ -175,7 +175,15 @@ void VM_Version::common_initialize() {
// This machine has fast unaligned memory accesses
if (FLAG_IS_DEFAULT(UseUnalignedAccesses)) {
FLAG_SET_DEFAULT(UseUnalignedAccesses,
unaligned_access.value() == MISALIGNED_FAST);
(unaligned_scalar.value() == MISALIGNED_SCALAR_FAST));
}
if (FLAG_IS_DEFAULT(AlignVector)) {
FLAG_SET_DEFAULT(AlignVector,
unaligned_vector.value() != MISALIGNED_VECTOR_FAST);
} else if (unaligned_vector.value() != MISALIGNED_VECTOR_FAST){
warning("Misaligned vector accesses are not supported on this CPU");
FLAG_SET_DEFAULT(AlignVector, true);
}
#ifdef __riscv_ztso
@@ -234,36 +242,6 @@ void VM_Version::common_initialize() {
warning("CRC32C intrinsics are not available on this CPU.");
FLAG_SET_DEFAULT(UseCRC32CIntrinsics, false);
}
// UseZvbb (depends on RVV).
if (UseZvbb && !UseRVV) {
warning("Cannot enable UseZvbb on cpu without RVV support.");
FLAG_SET_DEFAULT(UseZvbb, false);
}
// UseZvbc (depends on RVV).
if (UseZvbc && !UseRVV) {
warning("Cannot enable UseZvbc on cpu without RVV support.");
FLAG_SET_DEFAULT(UseZvbc, false);
}
// UseZvkn (depends on RVV).
if (UseZvkn && !UseRVV) {
warning("Cannot enable UseZvkn on cpu without RVV support.");
FLAG_SET_DEFAULT(UseZvkn, false);
}
// UseZvfh (depends on RVV)
if (UseZvfh) {
if (!UseRVV) {
warning("Cannot enable UseZvfh on cpu without RVV support.");
FLAG_SET_DEFAULT(UseZvfh, false);
}
if (!UseZfh) {
warning("Cannot enable UseZvfh on cpu without Zfh support.");
FLAG_SET_DEFAULT(UseZvfh, false);
}
}
}
#ifdef COMPILER2
+110 -63
View File
@@ -70,6 +70,35 @@ class VM_Version : public Abstract_VM_Version {
int64_t value() { return _value; }
virtual bool enabled() = 0;
virtual void update_flag() = 0;
protected:
bool deps_all_enabled(RVFeatureValue* dep0, ...) {
assert(dep0 != nullptr, "must not");
va_list va;
va_start(va, dep0);
RVFeatureValue* next = dep0;
bool enabled = true;
while (next != nullptr && enabled) {
enabled = next->enabled();
next = va_arg(va, RVFeatureValue*);
}
va_end(va);
return enabled;
}
void deps_string(stringStream& ss, RVFeatureValue* dep0, ...) {
assert(dep0 != nullptr, "must not");
ss.print("%s (%s)", dep0->pretty(), dep0->enabled() ? "enabled" : "disabled");
va_list va;
va_start(va, dep0);
RVFeatureValue* next = nullptr;
while ((next = va_arg(va, RVFeatureValue*)) != nullptr) {
ss.print(", %s (%s)", next->pretty(), next->enabled() ? "enabled" : "disabled");
}
va_end(va);
}
};
#define UPDATE_DEFAULT(flag) \
@@ -85,27 +114,34 @@ class VM_Version : public Abstract_VM_Version {
} \
} \
#define UPDATE_DEFAULT_DEP(flag, dep) \
void update_flag() { \
assert(enabled(), "Must be."); \
/* dep must be declared before */ \
assert((uintptr_t)(this) > \
(uintptr_t)(&dep), "Invalid"); \
if (FLAG_IS_DEFAULT(flag)) { \
if (dep.enabled()) { \
FLAG_SET_DEFAULT(flag, true); \
} else { \
FLAG_SET_DEFAULT(flag, false); \
/* Sync CPU features with flags */ \
disable_feature(); \
} \
} else { \
/* Sync CPU features with flags */ \
if (!flag) { \
disable_feature(); \
} \
} \
} \
#define UPDATE_DEFAULT_DEP(flag, dep0, ...) \
void update_flag() { \
assert(enabled(), "Must be."); \
if (FLAG_IS_DEFAULT(flag)) { \
if (this->deps_all_enabled(dep0, ##__VA_ARGS__)) { \
FLAG_SET_DEFAULT(flag, true); \
} else { \
FLAG_SET_DEFAULT(flag, false); \
stringStream ss; \
deps_string(ss, dep0, ##__VA_ARGS__); \
warning("Cannot enable " #flag ", it's missing dependent extension(s) %s", ss.as_string(true)); \
/* Sync CPU features with flags */ \
disable_feature(); \
} \
} else { \
/* Sync CPU features with flags */ \
if (!flag) { \
disable_feature(); \
} else if (!deps_all_enabled(dep0, ##__VA_ARGS__)) { \
FLAG_SET_DEFAULT(flag, false); \
stringStream ss; \
deps_string(ss, dep0, ##__VA_ARGS__); \
warning("Cannot enable " #flag ", it's missing dependent extension(s) %s", ss.as_string(true)); \
/* Sync CPU features with flags */ \
disable_feature(); \
} \
} \
} \
#define NO_UPDATE_DEFAULT \
void update_flag() {} \
@@ -191,7 +227,8 @@ class VM_Version : public Abstract_VM_Version {
// mvendorid Manufactory JEDEC id encoded, ISA vol 2 3.1.2..
// marchid Id for microarch. Mvendorid plus marchid uniquely identify the microarch.
// mimpid A unique encoding of the version of the processor implementation.
// unaligned_access Unaligned memory accesses (unknown, unspported, emulated, slow, firmware, fast)
// unaligned_scalar Performance of misaligned scalar accesses (unknown, emulated, slow, fast, unsupported)
// unaligned_vector Performance of misaligned vector accesses (unknown, unspported, slow, fast)
// satp mode SATP bits (number of virtual addr bits) mbare, sv39, sv48, sv57, sv64
public:
@@ -202,40 +239,40 @@ class VM_Version : public Abstract_VM_Version {
//
// Fields description in `decl`:
// declaration name, extension name, bit value from linux, feature string?, mapped flag)
#define RV_EXT_FEATURE_FLAGS(decl) \
decl(ext_I , i , ('I' - 'A'), true , NO_UPDATE_DEFAULT) \
decl(ext_M , m , ('M' - 'A'), true , NO_UPDATE_DEFAULT) \
decl(ext_A , a , ('A' - 'A'), true , NO_UPDATE_DEFAULT) \
decl(ext_F , f , ('F' - 'A'), true , NO_UPDATE_DEFAULT) \
decl(ext_D , d , ('D' - 'A'), true , NO_UPDATE_DEFAULT) \
decl(ext_C , c , ('C' - 'A'), true , UPDATE_DEFAULT(UseRVC)) \
decl(ext_Q , q , ('Q' - 'A'), true , NO_UPDATE_DEFAULT) \
decl(ext_H , h , ('H' - 'A'), true , NO_UPDATE_DEFAULT) \
decl(ext_V , v , ('V' - 'A'), true , UPDATE_DEFAULT(UseRVV)) \
decl(ext_Zicbom , Zicbom , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZicbom)) \
decl(ext_Zicboz , Zicboz , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZicboz)) \
decl(ext_Zicbop , Zicbop , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZicbop)) \
decl(ext_Zba , Zba , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZba)) \
decl(ext_Zbb , Zbb , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZbb)) \
decl(ext_Zbc , Zbc , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \
decl(ext_Zbs , Zbs , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZbs)) \
decl(ext_Zbkb , Zbkb , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZbkb)) \
decl(ext_Zcb , Zcb , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZcb)) \
decl(ext_Zfa , Zfa , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZfa)) \
decl(ext_Zfh , Zfh , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZfh)) \
decl(ext_Zfhmin , Zfhmin , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZfhmin)) \
decl(ext_Zicsr , Zicsr , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \
decl(ext_Zicntr , Zicntr , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \
decl(ext_Zifencei , Zifencei , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \
decl(ext_Zic64b , Zic64b , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZic64b)) \
decl(ext_Ztso , Ztso , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZtso)) \
decl(ext_Zihintpause , Zihintpause , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZihintpause)) \
decl(ext_Zacas , Zacas , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZacas)) \
decl(ext_Zvbb , Zvbb , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT_DEP(UseZvbb, ext_V)) \
decl(ext_Zvbc , Zvbc , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT_DEP(UseZvbc, ext_V)) \
decl(ext_Zvfh , Zvfh , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT_DEP(UseZvfh, ext_V)) \
decl(ext_Zvkn , Zvkn , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT_DEP(UseZvkn, ext_V)) \
decl(ext_Zicond , Zicond , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZicond)) \
#define RV_EXT_FEATURE_FLAGS(decl) \
decl(ext_I , i , ('I' - 'A'), true , NO_UPDATE_DEFAULT) \
decl(ext_M , m , ('M' - 'A'), true , NO_UPDATE_DEFAULT) \
decl(ext_A , a , ('A' - 'A'), true , NO_UPDATE_DEFAULT) \
decl(ext_F , f , ('F' - 'A'), true , NO_UPDATE_DEFAULT) \
decl(ext_D , d , ('D' - 'A'), true , NO_UPDATE_DEFAULT) \
decl(ext_C , c , ('C' - 'A'), true , UPDATE_DEFAULT(UseRVC)) \
decl(ext_Q , q , ('Q' - 'A'), true , NO_UPDATE_DEFAULT) \
decl(ext_H , h , ('H' - 'A'), true , NO_UPDATE_DEFAULT) \
decl(ext_V , v , ('V' - 'A'), true , UPDATE_DEFAULT(UseRVV)) \
decl(ext_Zicbom , Zicbom , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZicbom)) \
decl(ext_Zicboz , Zicboz , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZicboz)) \
decl(ext_Zicbop , Zicbop , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZicbop)) \
decl(ext_Zba , Zba , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZba)) \
decl(ext_Zbb , Zbb , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZbb)) \
decl(ext_Zbc , Zbc , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \
decl(ext_Zbs , Zbs , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZbs)) \
decl(ext_Zbkb , Zbkb , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZbkb)) \
decl(ext_Zcb , Zcb , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZcb)) \
decl(ext_Zfa , Zfa , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZfa)) \
decl(ext_Zfh , Zfh , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZfh)) \
decl(ext_Zfhmin , Zfhmin , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZfhmin)) \
decl(ext_Zicsr , Zicsr , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \
decl(ext_Zicntr , Zicntr , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \
decl(ext_Zifencei , Zifencei , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \
decl(ext_Zic64b , Zic64b , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZic64b)) \
decl(ext_Ztso , Ztso , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZtso)) \
decl(ext_Zihintpause , Zihintpause , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZihintpause)) \
decl(ext_Zacas , Zacas , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZacas)) \
decl(ext_Zvbb , Zvbb , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT_DEP(UseZvbb, &ext_V, nullptr)) \
decl(ext_Zvbc , Zvbc , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT_DEP(UseZvbc, &ext_V, nullptr)) \
decl(ext_Zvfh , Zvfh , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT_DEP(UseZvfh, &ext_V, &ext_Zfh, nullptr)) \
decl(ext_Zvkn , Zvkn , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT_DEP(UseZvkn, &ext_V, nullptr)) \
decl(ext_Zicond , Zicond , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZicond)) \
#define DECLARE_RV_EXT_FEATURE(NAME, PRETTY, LINUX_BIT, FSTRING, FLAGF) \
struct NAME##RVExtFeatureValue : public RVExtFeatureValue { \
@@ -251,11 +288,12 @@ class VM_Version : public Abstract_VM_Version {
// Non-extension features
//
#define RV_NON_EXT_FEATURE_FLAGS(decl) \
decl(unaligned_access , Unaligned , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \
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) \
decl(satp_mode , SATP , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \
decl(unaligned_scalar , UnalignedScalar , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \
decl(unaligned_vector , UnalignedVector , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \
decl(zicboz_block_size, ZicbozBlockSize , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \
#define DECLARE_RV_NON_EXT_FEATURE(NAME, PRETTY, LINUX_BIT, FSTRING, FLAGF) \
@@ -396,12 +434,19 @@ private:
static VM_MODE parse_satp_mode(const char* vm_mode);
// Values from riscv_hwprobe()
enum UNALIGNED_ACCESS : int {
MISALIGNED_UNKNOWN = 0,
MISALIGNED_EMULATED = 1,
MISALIGNED_SLOW = 2,
MISALIGNED_FAST = 3,
MISALIGNED_UNSUPPORTED = 4
enum UNALIGNED_SCALAR_ACCESS : int {
MISALIGNED_SCALAR_UNKNOWN = 0,
MISALIGNED_SCALAR_EMULATED = 1,
MISALIGNED_SCALAR_SLOW = 2,
MISALIGNED_SCALAR_FAST = 3,
MISALIGNED_SCALAR_UNSUPPORTED = 4
};
enum UNALIGNED_VECTOR_ACCESS : int {
MISALIGNED_VECTOR_UNKNOWN = 0,
MISALIGNED_VECTOR_SLOW = 2,
MISALIGNED_VECTOR_FAST = 3,
MISALIGNED_VECTOR_UNSUPPORTED = 4
};
// Null terminated list
@@ -438,6 +483,8 @@ private:
constexpr static bool supports_secondary_supers_table() { return true; }
static bool supports_misaligned_vector_accesses() { return unaligned_vector.value() == MISALIGNED_VECTOR_FAST; }
static bool supports_on_spin_wait() { return UseZihintpause; }
// RISCV64 supports fast class initialization checks
+2
View File
@@ -425,6 +425,8 @@ class VM_Version: public Abstract_VM_Version {
constexpr static bool supports_secondary_supers_table() { return true; }
constexpr static bool supports_misaligned_vector_accesses() { return true; }
constexpr static bool supports_recursive_lightweight_locking() { return true; }
// CPU feature query functions
+152
View File
@@ -2225,6 +2225,44 @@ void Assembler::cvttss2sil(Register dst, XMMRegister src) {
emit_int16(0x2C, (0xC0 | encode));
}
void Assembler::evcvttss2sisl(Register dst, XMMRegister src) {
assert(VM_Version::supports_avx10_2(), "");
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
attributes.set_is_evex_instruction();
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_MAP5, &attributes);
emit_int16(0x6D, (0xC0 | encode));
}
void Assembler::evcvttss2sisl(Register dst, Address src) {
assert(VM_Version::supports_avx10_2(), "");
InstructionMark im(this);
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
attributes.set_is_evex_instruction();
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_F3, VEX_OPCODE_MAP5, &attributes);
emit_int8((unsigned char)0x6D);
emit_operand(dst, src, 0);
}
void Assembler::evcvttss2sisq(Register dst, XMMRegister src) {
assert(VM_Version::supports_avx10_2(), "");
InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
attributes.set_is_evex_instruction();
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_F3, VEX_OPCODE_MAP5, &attributes);
emit_int16(0x6D, (0xC0 | encode));
}
void Assembler::evcvttss2sisq(Register dst, Address src) {
assert(VM_Version::supports_avx10_2(), "");
InstructionMark im(this);
InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_32bit);
attributes.set_is_evex_instruction();
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_F3, VEX_OPCODE_MAP5, &attributes);
emit_int8((unsigned char)0x6D);
emit_operand(dst, src, 0);
}
void Assembler::cvttpd2dq(XMMRegister dst, XMMRegister src) {
int vector_len = VM_Version::supports_avx512novl() ? AVX_512bit : AVX_128bit;
InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
@@ -2310,6 +2348,25 @@ void Assembler::vcvttps2dq(XMMRegister dst, XMMRegister src, int vector_len) {
emit_int16(0x5B, (0xC0 | encode));
}
void Assembler::evcvttps2dqs(XMMRegister dst, XMMRegister src, int vector_len) {
assert(VM_Version::supports_avx10_2(), "");
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
attributes.set_is_evex_instruction();
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_MAP5, &attributes);
emit_int16(0x6D, (0xC0 | encode));
}
void Assembler::evcvttps2dqs(XMMRegister dst, Address src, int vector_len) {
assert(VM_Version::supports_avx10_2(), "");
InstructionMark im(this);
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_32bit);
attributes.set_is_evex_instruction();
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_MAP5, &attributes);
emit_int8((unsigned char)0x6D);
emit_operand(dst, src, 0);
}
void Assembler::vcvttpd2dq(XMMRegister dst, XMMRegister src, int vector_len) {
assert(vector_len <= AVX_256bit ? VM_Version::supports_avx() : VM_Version::supports_evex(), "");
InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
@@ -2317,6 +2374,25 @@ void Assembler::vcvttpd2dq(XMMRegister dst, XMMRegister src, int vector_len) {
emit_int16((unsigned char)0xE6, (0xC0 | encode));
}
void Assembler::evcvttpd2dqs(XMMRegister dst, XMMRegister src, int vector_len) {
assert(VM_Version::supports_avx10_2(), "");
InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
attributes.set_is_evex_instruction();
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_NONE, VEX_OPCODE_MAP5, &attributes);
emit_int16(0x6D, (0xC0 | encode));
}
void Assembler::evcvttpd2dqs(XMMRegister dst, Address src, int vector_len) {
assert(VM_Version::supports_avx10_2(), "");
InstructionMark im(this);
InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit);
attributes.set_is_evex_instruction();
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_NONE, VEX_OPCODE_MAP5, &attributes);
emit_int8((unsigned char)0x6D);
emit_operand(dst, src, 0);
}
void Assembler::vcvtps2dq(XMMRegister dst, XMMRegister src, int vector_len) {
assert(vector_len <= AVX_256bit ? VM_Version::supports_avx() : VM_Version::supports_evex(), "");
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
@@ -2332,6 +2408,25 @@ void Assembler::evcvttps2qq(XMMRegister dst, XMMRegister src, int vector_len) {
emit_int16(0x7A, (0xC0 | encode));
}
void Assembler::evcvttps2qqs(XMMRegister dst, XMMRegister src, int vector_len) {
assert(VM_Version::supports_avx10_2(), "");
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
attributes.set_is_evex_instruction();
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_MAP5, &attributes);
emit_int16(0x6D, (0xC0 | encode));
}
void Assembler::evcvttps2qqs(XMMRegister dst, Address src, int vector_len) {
assert(VM_Version::supports_avx10_2(), "");
InstructionMark im(this);
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
attributes.set_address_attributes(/* tuple_type */ EVEX_HV, /* input_size_in_bits */ EVEX_32bit);
attributes.set_is_evex_instruction();
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_MAP5, &attributes);
emit_int8((unsigned char)0x6D);
emit_operand(dst, src, 0);
}
void Assembler::evcvtpd2qq(XMMRegister dst, XMMRegister src, int vector_len) {
assert(VM_Version::supports_avx512dq(), "");
InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
@@ -2356,6 +2451,25 @@ void Assembler::evcvttpd2qq(XMMRegister dst, XMMRegister src, int vector_len) {
emit_int16(0x7A, (0xC0 | encode));
}
void Assembler::evcvttpd2qqs(XMMRegister dst, XMMRegister src, int vector_len) {
assert(VM_Version::supports_avx10_2(), "");
InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
attributes.set_is_evex_instruction();
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_MAP5, &attributes);
emit_int16(0x6D, (0xC0 | encode));
}
void Assembler::evcvttpd2qqs(XMMRegister dst, Address src, int vector_len) {
assert(VM_Version::supports_avx10_2(), "");
InstructionMark im(this);
InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
attributes.set_address_attributes(/* tuple_type */ EVEX_FV, /* input_size_in_bits */ EVEX_64bit);
attributes.set_is_evex_instruction();
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_66, VEX_OPCODE_MAP5, &attributes);
emit_int8((unsigned char)0x6D);
emit_operand(dst, src, 0);
}
void Assembler::evcvtqq2pd(XMMRegister dst, XMMRegister src, int vector_len) {
assert(VM_Version::supports_avx512dq(), "");
InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
@@ -14988,6 +15102,44 @@ void Assembler::cvttsd2siq(Register dst, Address src) {
emit_operand(dst, src, 0);
}
void Assembler::evcvttsd2sisl(Register dst, XMMRegister src) {
assert(VM_Version::supports_avx10_2(), "");
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
attributes.set_is_evex_instruction();
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_F2, VEX_OPCODE_MAP5, &attributes);
emit_int16(0x6D, (0xC0 | encode));
}
void Assembler::evcvttsd2sisl(Register dst, Address src) {
assert(VM_Version::supports_avx10_2(), "");
InstructionMark im(this);
InstructionAttr attributes(AVX_128bit, /* vex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
attributes.set_is_evex_instruction();
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_F2, VEX_OPCODE_MAP5, &attributes);
emit_int8((unsigned char)0x6D);
emit_operand(dst, src, 0);
}
void Assembler::evcvttsd2sisq(Register dst, XMMRegister src) {
assert(VM_Version::supports_avx10_2(), "");
InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
attributes.set_is_evex_instruction();
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_F2, VEX_OPCODE_MAP5, &attributes);
emit_int16(0x6D, (0xC0 | encode));
}
void Assembler::evcvttsd2sisq(Register dst, Address src) {
assert(VM_Version::supports_avx10_2(), "");
InstructionMark im(this);
InstructionAttr attributes(AVX_128bit, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
attributes.set_address_attributes(/* tuple_type */ EVEX_T1S, /* input_size_in_bits */ EVEX_64bit);
attributes.set_is_evex_instruction();
vex_prefix(src, 0, dst->encoding(), VEX_SIMD_F2, VEX_OPCODE_MAP5, &attributes);
emit_int8((unsigned char)0x6D);
emit_operand(dst, src, 0);
}
void Assembler::cvttsd2siq(Register dst, XMMRegister src) {
InstructionAttr attributes(AVX_128bit, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ false);
int encode = simd_prefix_and_encode(as_XMMRegister(dst->encoding()), xnoreg, src, VEX_SIMD_F2, VEX_OPCODE_0F, &attributes);
+16
View File
@@ -1316,11 +1316,19 @@ private:
void cvttsd2sil(Register dst, XMMRegister src);
void cvttsd2siq(Register dst, Address src);
void cvttsd2siq(Register dst, XMMRegister src);
void evcvttsd2sisl(Register dst, XMMRegister src);
void evcvttsd2sisl(Register dst, Address src);
void evcvttsd2sisq(Register dst, XMMRegister src);
void evcvttsd2sisq(Register dst, Address src);
// Convert with Truncation Scalar Single-Precision Floating-Point Value to Doubleword Integer
void cvttss2sil(Register dst, XMMRegister src);
void cvttss2siq(Register dst, XMMRegister src);
void cvtss2sil(Register dst, XMMRegister src);
void evcvttss2sisl(Register dst, XMMRegister src);
void evcvttss2sisl(Register dst, Address src);
void evcvttss2sisq(Register dst, XMMRegister src);
void evcvttss2sisq(Register dst, Address src);
// Convert vector double to int
void cvttpd2dq(XMMRegister dst, XMMRegister src);
@@ -1332,7 +1340,11 @@ private:
// Convert vector float to int/long
void vcvtps2dq(XMMRegister dst, XMMRegister src, int vector_len);
void vcvttps2dq(XMMRegister dst, XMMRegister src, int vector_len);
void evcvttps2dqs(XMMRegister dst, XMMRegister src, int vector_len);
void evcvttps2dqs(XMMRegister dst, Address src, int vector_len);
void evcvttps2qq(XMMRegister dst, XMMRegister src, int vector_len);
void evcvttps2qqs(XMMRegister dst, XMMRegister src, int vector_len);
void evcvttps2qqs(XMMRegister dst, Address src, int vector_len);
// Convert vector long to vector FP
void evcvtqq2ps(XMMRegister dst, XMMRegister src, int vector_len);
@@ -1341,9 +1353,13 @@ private:
// Convert vector double to long
void evcvtpd2qq(XMMRegister dst, XMMRegister src, int vector_len);
void evcvttpd2qq(XMMRegister dst, XMMRegister src, int vector_len);
void evcvttpd2qqs(XMMRegister dst, XMMRegister src, int vector_len);
void evcvttpd2qqs(XMMRegister dst, Address src, int vector_len);
// Convert vector double to int
void vcvttpd2dq(XMMRegister dst, XMMRegister src, int vector_len);
void evcvttpd2dqs(XMMRegister dst, XMMRegister src, int vector_len);
void evcvttpd2dqs(XMMRegister dst, Address src, int vector_len);
// Evex casts with truncation
void evpmovwb(XMMRegister dst, XMMRegister src, int vector_len);
+85 -5
View File
@@ -5053,12 +5053,12 @@ void C2_MacroAssembler::vector_cast_int_to_subword(BasicType to_elem_bt, XMMRegi
}
vpackuswb(dst, dst, zero, vec_enc);
break;
default: assert(false, "%s", type2name(to_elem_bt));
default: assert(false, "Unexpected basic type for target of vector cast int to subword: %s", type2name(to_elem_bt));
}
}
/*
* Algorithm for vector D2L and F2I conversions:-
* Algorithm for vector D2L and F2I conversions (AVX 10.2 unsupported):-
* a) Perform vector D2L/F2I cast.
* b) Choose fast path if none of the result vector lane contains 0x80000000 value.
* It signifies that source value could be any of the special floating point
@@ -5096,7 +5096,7 @@ void C2_MacroAssembler::vector_castF2X_evex(BasicType to_elem_bt, XMMRegister ds
case T_BYTE:
evpmovdb(dst, dst, vec_enc);
break;
default: assert(false, "%s", type2name(to_elem_bt));
default: assert(false, "Unexpected basic type for target of vector castF2X EVEX: %s", type2name(to_elem_bt));
}
}
@@ -5143,7 +5143,7 @@ void C2_MacroAssembler::vector_castD2X_evex(BasicType to_elem_bt, XMMRegister ds
evpmovsqd(dst, dst, vec_enc);
evpmovdb(dst, dst, vec_enc);
break;
default: assert(false, "%s", type2name(to_elem_bt));
default: assert(false, "Unexpected basic type for target of vector castD2X AVX512DQ EVEX: %s", type2name(to_elem_bt));
}
} else {
assert(type2aelembytes(to_elem_bt) <= 4, "");
@@ -5158,11 +5158,91 @@ void C2_MacroAssembler::vector_castD2X_evex(BasicType to_elem_bt, XMMRegister ds
case T_BYTE:
evpmovdb(dst, dst, vec_enc);
break;
default: assert(false, "%s", type2name(to_elem_bt));
default: assert(false, "Unexpected basic type for target of vector castD2X EVEX: %s", type2name(to_elem_bt));
}
}
}
void C2_MacroAssembler::vector_castF2X_avx10(BasicType to_elem_bt, XMMRegister dst, XMMRegister src, int vec_enc) {
switch(to_elem_bt) {
case T_LONG:
evcvttps2qqs(dst, src, vec_enc);
break;
case T_INT:
evcvttps2dqs(dst, src, vec_enc);
break;
case T_SHORT:
evcvttps2dqs(dst, src, vec_enc);
evpmovdw(dst, dst, vec_enc);
break;
case T_BYTE:
evcvttps2dqs(dst, src, vec_enc);
evpmovdb(dst, dst, vec_enc);
break;
default: assert(false, "Unexpected basic type for target of vector castF2X AVX10 (reg src): %s", type2name(to_elem_bt));
}
}
void C2_MacroAssembler::vector_castF2X_avx10(BasicType to_elem_bt, XMMRegister dst, Address src, int vec_enc) {
switch(to_elem_bt) {
case T_LONG:
evcvttps2qqs(dst, src, vec_enc);
break;
case T_INT:
evcvttps2dqs(dst, src, vec_enc);
break;
case T_SHORT:
evcvttps2dqs(dst, src, vec_enc);
evpmovdw(dst, dst, vec_enc);
break;
case T_BYTE:
evcvttps2dqs(dst, src, vec_enc);
evpmovdb(dst, dst, vec_enc);
break;
default: assert(false, "Unexpected basic type for target of vector castF2X AVX10 (mem src): %s", type2name(to_elem_bt));
}
}
void C2_MacroAssembler::vector_castD2X_avx10(BasicType to_elem_bt, XMMRegister dst, XMMRegister src, int vec_enc) {
switch(to_elem_bt) {
case T_LONG:
evcvttpd2qqs(dst, src, vec_enc);
break;
case T_INT:
evcvttpd2dqs(dst, src, vec_enc);
break;
case T_SHORT:
evcvttpd2dqs(dst, src, vec_enc);
evpmovdw(dst, dst, vec_enc);
break;
case T_BYTE:
evcvttpd2dqs(dst, src, vec_enc);
evpmovdb(dst, dst, vec_enc);
break;
default: assert(false, "Unexpected basic type for target of vector castD2X AVX10 (reg src): %s", type2name(to_elem_bt));
}
}
void C2_MacroAssembler::vector_castD2X_avx10(BasicType to_elem_bt, XMMRegister dst, Address src, int vec_enc) {
switch(to_elem_bt) {
case T_LONG:
evcvttpd2qqs(dst, src, vec_enc);
break;
case T_INT:
evcvttpd2dqs(dst, src, vec_enc);
break;
case T_SHORT:
evcvttpd2dqs(dst, src, vec_enc);
evpmovdw(dst, dst, vec_enc);
break;
case T_BYTE:
evcvttpd2dqs(dst, src, vec_enc);
evpmovdb(dst, dst, vec_enc);
break;
default: assert(false, "Unexpected basic type for target of vector castD2X AVX10 (mem src): %s", type2name(to_elem_bt));
}
}
void C2_MacroAssembler::vector_round_double_evex(XMMRegister dst, XMMRegister src,
AddressLiteral double_sign_flip, AddressLiteral new_mxcsr, int vec_enc,
Register tmp, XMMRegister xtmp1, XMMRegister xtmp2, KRegister ktmp1, KRegister ktmp2) {
@@ -347,6 +347,13 @@ public:
XMMRegister xtmp2, XMMRegister xtmp3, XMMRegister xtmp4, XMMRegister xtmp5,
AddressLiteral float_sign_flip, Register rscratch, int vec_enc);
void vector_castF2X_avx10(BasicType to_elem_bt, XMMRegister dst, XMMRegister src, int vec_enc);
void vector_castF2X_avx10(BasicType to_elem_bt, XMMRegister dst, Address src, int vec_enc);
void vector_castD2X_avx10(BasicType to_elem_bt, XMMRegister dst, XMMRegister src, int vec_enc);
void vector_castD2X_avx10(BasicType to_elem_bt, XMMRegister dst, Address src, int vec_enc);
void vector_cast_double_to_int_special_cases_avx(XMMRegister dst, XMMRegister src, XMMRegister xtmp1, XMMRegister xtmp2,
XMMRegister xtmp3, XMMRegister xtmp4, XMMRegister xtmp5, Register rscratch,
+4
View File
@@ -991,6 +991,10 @@ public:
return true;
}
constexpr static bool supports_misaligned_vector_accesses() {
return true;
}
constexpr static bool supports_stack_watermark_barrier() {
return true;
}
+66 -5
View File
@@ -7664,8 +7664,11 @@ instruct vcastFtoD_reg(vec dst, vec src) %{
instruct castFtoX_reg_avx(vec dst, vec src, vec xtmp1, vec xtmp2, vec xtmp3, vec xtmp4, rFlagsReg cr) %{
predicate(!VM_Version::supports_avx512vl() && Matcher::vector_length_in_bytes(n->in(1)) < 64 &&
type2aelembytes(Matcher::vector_element_basic_type(n)) <= 4);
predicate(!VM_Version::supports_avx10_2() &&
!VM_Version::supports_avx512vl() &&
Matcher::vector_length_in_bytes(n->in(1)) < 64 &&
type2aelembytes(Matcher::vector_element_basic_type(n)) <= 4 &&
is_integral_type(Matcher::vector_element_basic_type(n)));
match(Set dst (VectorCastF2X src));
effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP xtmp3, TEMP xtmp4, KILL cr);
format %{ "vector_cast_f2x $dst,$src\t! using $xtmp1, $xtmp2, $xtmp3 and $xtmp4 as TEMP" %}
@@ -7687,7 +7690,8 @@ instruct castFtoX_reg_avx(vec dst, vec src, vec xtmp1, vec xtmp2, vec xtmp3, vec
%}
instruct castFtoX_reg_evex(vec dst, vec src, vec xtmp1, vec xtmp2, kReg ktmp1, kReg ktmp2, rFlagsReg cr) %{
predicate((VM_Version::supports_avx512vl() || Matcher::vector_length_in_bytes(n->in(1)) == 64) &&
predicate(!VM_Version::supports_avx10_2() &&
(VM_Version::supports_avx512vl() || Matcher::vector_length_in_bytes(n->in(1)) == 64) &&
is_integral_type(Matcher::vector_element_basic_type(n)));
match(Set dst (VectorCastF2X src));
effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP ktmp1, TEMP ktmp2, KILL cr);
@@ -7709,6 +7713,33 @@ instruct castFtoX_reg_evex(vec dst, vec src, vec xtmp1, vec xtmp2, kReg ktmp1, k
ins_pipe( pipe_slow );
%}
instruct castFtoX_reg_avx10(vec dst, vec src) %{
predicate(VM_Version::supports_avx10_2() &&
is_integral_type(Matcher::vector_element_basic_type(n)));
match(Set dst (VectorCastF2X src));
format %{ "vector_cast_f2x_avx10 $dst, $src\t!" %}
ins_encode %{
BasicType to_elem_bt = Matcher::vector_element_basic_type(this);
int vlen_enc = (to_elem_bt == T_LONG) ? vector_length_encoding(this) : vector_length_encoding(this, $src);
__ vector_castF2X_avx10(to_elem_bt, $dst$$XMMRegister, $src$$XMMRegister, vlen_enc);
%}
ins_pipe( pipe_slow );
%}
instruct castFtoX_mem_avx10(vec dst, memory src) %{
predicate(VM_Version::supports_avx10_2() &&
is_integral_type(Matcher::vector_element_basic_type(n)));
match(Set dst (VectorCastF2X (LoadVector src)));
format %{ "vector_cast_f2x_avx10 $dst, $src\t!" %}
ins_encode %{
int vlen = Matcher::vector_length(this);
BasicType to_elem_bt = Matcher::vector_element_basic_type(this);
int vlen_enc = (to_elem_bt == T_LONG) ? vector_length_encoding(this) : vector_length_encoding(vlen * sizeof(jfloat));
__ vector_castF2X_avx10(to_elem_bt, $dst$$XMMRegister, $src$$Address, vlen_enc);
%}
ins_pipe( pipe_slow );
%}
instruct vcastDtoF_reg(vec dst, vec src) %{
predicate(Matcher::vector_element_basic_type(n) == T_FLOAT);
match(Set dst (VectorCastD2X src));
@@ -7721,7 +7752,9 @@ instruct vcastDtoF_reg(vec dst, vec src) %{
%}
instruct castDtoX_reg_avx(vec dst, vec src, vec xtmp1, vec xtmp2, vec xtmp3, vec xtmp4, vec xtmp5, rFlagsReg cr) %{
predicate(!VM_Version::supports_avx512vl() && Matcher::vector_length_in_bytes(n->in(1)) < 64 &&
predicate(!VM_Version::supports_avx10_2() &&
!VM_Version::supports_avx512vl() &&
Matcher::vector_length_in_bytes(n->in(1)) < 64 &&
is_integral_type(Matcher::vector_element_basic_type(n)));
match(Set dst (VectorCastD2X src));
effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP xtmp3, TEMP xtmp4, TEMP xtmp5, KILL cr);
@@ -7737,7 +7770,8 @@ instruct castDtoX_reg_avx(vec dst, vec src, vec xtmp1, vec xtmp2, vec xtmp3, vec
%}
instruct castDtoX_reg_evex(vec dst, vec src, vec xtmp1, vec xtmp2, kReg ktmp1, kReg ktmp2, rFlagsReg cr) %{
predicate((VM_Version::supports_avx512vl() || Matcher::vector_length_in_bytes(n->in(1)) == 64) &&
predicate(!VM_Version::supports_avx10_2() &&
(VM_Version::supports_avx512vl() || Matcher::vector_length_in_bytes(n->in(1)) == 64) &&
is_integral_type(Matcher::vector_element_basic_type(n)));
match(Set dst (VectorCastD2X src));
effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP ktmp1, TEMP ktmp2, KILL cr);
@@ -7753,6 +7787,33 @@ instruct castDtoX_reg_evex(vec dst, vec src, vec xtmp1, vec xtmp2, kReg ktmp1, k
ins_pipe( pipe_slow );
%}
instruct castDtoX_reg_avx10(vec dst, vec src) %{
predicate(VM_Version::supports_avx10_2() &&
is_integral_type(Matcher::vector_element_basic_type(n)));
match(Set dst (VectorCastD2X src));
format %{ "vector_cast_d2x_avx10 $dst, $src\t!" %}
ins_encode %{
int vlen_enc = vector_length_encoding(this, $src);
BasicType to_elem_bt = Matcher::vector_element_basic_type(this);
__ vector_castD2X_avx10(to_elem_bt, $dst$$XMMRegister, $src$$XMMRegister, vlen_enc);
%}
ins_pipe( pipe_slow );
%}
instruct castDtoX_mem_avx10(vec dst, memory src) %{
predicate(VM_Version::supports_avx10_2() &&
is_integral_type(Matcher::vector_element_basic_type(n)));
match(Set dst (VectorCastD2X (LoadVector src)));
format %{ "vector_cast_d2x_avx10 $dst, $src\t!" %}
ins_encode %{
int vlen = Matcher::vector_length(this);
int vlen_enc = vector_length_encoding(vlen * sizeof(jdouble));
BasicType to_elem_bt = Matcher::vector_element_basic_type(this);
__ vector_castD2X_avx10(to_elem_bt, $dst$$XMMRegister, $src$$Address, vlen_enc);
%}
ins_pipe( pipe_slow );
%}
instruct vucast(vec dst, vec src) %{
match(Set dst (VectorUCastB2X src));
match(Set dst (VectorUCastS2X src));
+92
View File
@@ -11712,6 +11712,7 @@ instruct convD2F_reg_mem(regF dst, memory src)
// XXX do mem variants
instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr)
%{
predicate(!VM_Version::supports_avx10_2());
match(Set dst (ConvF2I src));
effect(KILL cr);
format %{ "convert_f2i $dst, $src" %}
@@ -11721,8 +11722,31 @@ instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr)
ins_pipe(pipe_slow);
%}
instruct convF2I_reg_reg_avx10(rRegI dst, regF src)
%{
predicate(VM_Version::supports_avx10_2());
match(Set dst (ConvF2I src));
format %{ "evcvttss2sisl $dst, $src" %}
ins_encode %{
__ evcvttss2sisl($dst$$Register, $src$$XMMRegister);
%}
ins_pipe(pipe_slow);
%}
instruct convF2I_reg_mem_avx10(rRegI dst, memory src)
%{
predicate(VM_Version::supports_avx10_2());
match(Set dst (ConvF2I (LoadF src)));
format %{ "evcvttss2sisl $dst, $src" %}
ins_encode %{
__ evcvttss2sisl($dst$$Register, $src$$Address);
%}
ins_pipe(pipe_slow);
%}
instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr)
%{
predicate(!VM_Version::supports_avx10_2());
match(Set dst (ConvF2L src));
effect(KILL cr);
format %{ "convert_f2l $dst, $src"%}
@@ -11732,8 +11756,31 @@ instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr)
ins_pipe(pipe_slow);
%}
instruct convF2L_reg_reg_avx10(rRegL dst, regF src)
%{
predicate(VM_Version::supports_avx10_2());
match(Set dst (ConvF2L src));
format %{ "evcvttss2sisq $dst, $src" %}
ins_encode %{
__ evcvttss2sisq($dst$$Register, $src$$XMMRegister);
%}
ins_pipe(pipe_slow);
%}
instruct convF2L_reg_mem_avx10(rRegL dst, memory src)
%{
predicate(VM_Version::supports_avx10_2());
match(Set dst (ConvF2L (LoadF src)));
format %{ "evcvttss2sisq $dst, $src" %}
ins_encode %{
__ evcvttss2sisq($dst$$Register, $src$$Address);
%}
ins_pipe(pipe_slow);
%}
instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr)
%{
predicate(!VM_Version::supports_avx10_2());
match(Set dst (ConvD2I src));
effect(KILL cr);
format %{ "convert_d2i $dst, $src"%}
@@ -11743,8 +11790,31 @@ instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr)
ins_pipe(pipe_slow);
%}
instruct convD2I_reg_reg_avx10(rRegI dst, regD src)
%{
predicate(VM_Version::supports_avx10_2());
match(Set dst (ConvD2I src));
format %{ "evcvttsd2sisl $dst, $src" %}
ins_encode %{
__ evcvttsd2sisl($dst$$Register, $src$$XMMRegister);
%}
ins_pipe(pipe_slow);
%}
instruct convD2I_reg_mem_avx10(rRegI dst, memory src)
%{
predicate(VM_Version::supports_avx10_2());
match(Set dst (ConvD2I (LoadD src)));
format %{ "evcvttsd2sisl $dst, $src" %}
ins_encode %{
__ evcvttsd2sisl($dst$$Register, $src$$Address);
%}
ins_pipe(pipe_slow);
%}
instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr)
%{
predicate(!VM_Version::supports_avx10_2());
match(Set dst (ConvD2L src));
effect(KILL cr);
format %{ "convert_d2l $dst, $src"%}
@@ -11754,6 +11824,28 @@ instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr)
ins_pipe(pipe_slow);
%}
instruct convD2L_reg_reg_avx10(rRegL dst, regD src)
%{
predicate(VM_Version::supports_avx10_2());
match(Set dst (ConvD2L src));
format %{ "evcvttsd2sisq $dst, $src" %}
ins_encode %{
__ evcvttsd2sisq($dst$$Register, $src$$XMMRegister);
%}
ins_pipe(pipe_slow);
%}
instruct convD2L_reg_mem_avx10(rRegL dst, memory src)
%{
predicate(VM_Version::supports_avx10_2());
match(Set dst (ConvD2L (LoadD src)));
format %{ "evcvttsd2sisq $dst, $src" %}
ins_encode %{
__ evcvttsd2sisq($dst$$Register, $src$$Address);
%}
ins_pipe(pipe_slow);
%}
instruct round_double_reg(rRegL dst, regD src, rRegL rtmp, rcx_RegL rcx, rFlagsReg cr)
%{
match(Set dst (RoundD src));
@@ -89,7 +89,24 @@
#define RISCV_HWPROBE_MISALIGNED_UNSUPPORTED (4 << 0)
#define RISCV_HWPROBE_MISALIGNED_MASK (7 << 0)
#define RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE 6
#define RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE 6
#define RISCV_HWPROBE_KEY_HIGHEST_VIRT_ADDRESS 7
#define RISCV_HWPROBE_KEY_TIME_CSR_FREQ 8
#define RISCV_HWPROBE_KEY_MISALIGNED_SCALAR_PERF 9
#define RISCV_HWPROBE_MISALIGNED_SCALAR_UNKNOWN 0
#define RISCV_HWPROBE_MISALIGNED_SCALAR_EMULATED 1
#define RISCV_HWPROBE_MISALIGNED_SCALAR_SLOW 2
#define RISCV_HWPROBE_MISALIGNED_SCALAR_FAST 3
#define RISCV_HWPROBE_MISALIGNED_SCALAR_UNSUPPORTED 4
#define RISCV_HWPROBE_KEY_MISALIGNED_VECTOR_PERF 10
#define RISCV_HWPROBE_MISALIGNED_VECTOR_UNKNOWN 0
#define RISCV_HWPROBE_MISALIGNED_VECTOR_SLOW 2
#define RISCV_HWPROBE_MISALIGNED_VECTOR_FAST 3
#define RISCV_HWPROBE_MISALIGNED_VECTOR_UNSUPPORTED 4
#ifndef NR_riscv_hwprobe
#ifndef NR_arch_specific_syscall
@@ -117,7 +134,11 @@ static struct riscv_hwprobe query[] = {{RISCV_HWPROBE_KEY_MVENDORID, 0},
{RISCV_HWPROBE_KEY_BASE_BEHAVIOR, 0},
{RISCV_HWPROBE_KEY_IMA_EXT_0, 0},
{RISCV_HWPROBE_KEY_CPUPERF_0, 0},
{RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE, 0}};
{RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE, 0},
{RISCV_HWPROBE_KEY_HIGHEST_VIRT_ADDRESS, 0},
{RISCV_HWPROBE_KEY_TIME_CSR_FREQ, 0},
{RISCV_HWPROBE_KEY_MISALIGNED_SCALAR_PERF, 0},
{RISCV_HWPROBE_KEY_MISALIGNED_VECTOR_PERF, 0}};
bool RiscvHwprobe::probe_features() {
assert(!rw_hwprobe_completed, "Called twice.");
@@ -246,9 +267,20 @@ void RiscvHwprobe::add_features_from_query_result() {
VM_Version::ext_Zicond.enable_feature();
}
#endif
// RISCV_HWPROBE_KEY_CPUPERF_0 is deprecated and returns similar values
// to RISCV_HWPROBE_KEY_MISALIGNED_SCALAR_PERF. Keep it there for backward
// compatibility with old kernels.
if (is_valid(RISCV_HWPROBE_KEY_CPUPERF_0)) {
VM_Version::unaligned_access.enable_feature(
VM_Version::unaligned_scalar.enable_feature(
query[RISCV_HWPROBE_KEY_CPUPERF_0].value & RISCV_HWPROBE_MISALIGNED_MASK);
} else if (is_valid(RISCV_HWPROBE_KEY_MISALIGNED_SCALAR_PERF)) {
VM_Version::unaligned_scalar.enable_feature(
query[RISCV_HWPROBE_KEY_MISALIGNED_SCALAR_PERF].value);
}
if (is_valid(RISCV_HWPROBE_KEY_MISALIGNED_VECTOR_PERF)) {
VM_Version::unaligned_vector.enable_feature(
query[RISCV_HWPROBE_KEY_MISALIGNED_VECTOR_PERF].value);
}
if (is_valid(RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE)) {
VM_Version::zicboz_block_size.enable_feature(query[RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE].value);
@@ -303,7 +303,7 @@ void VM_Version::rivos_features() {
ext_Zvfh.enable_feature();
unaligned_access.enable_feature(MISALIGNED_FAST);
unaligned_scalar.enable_feature(MISALIGNED_SCALAR_FAST);
satp_mode.enable_feature(VM_SV48);
// Features dependent on march/mimpid.
@@ -2445,7 +2445,7 @@ Method* ClassFileParser::parse_method(const ClassFileStream* const cfs,
cfs->skip_u2_fast(method_parameters_length);
cfs->skip_u2_fast(method_parameters_length);
// ignore this attribute if it cannot be reflected
if (!vmClasses::Parameter_klass_loaded())
if (!vmClasses::reflect_Parameter_klass_is_loaded())
method_parameters_length = -1;
} else if (method_attribute_name == vmSymbols::tag_synthetic()) {
if (method_attribute_length != 0) {
@@ -3979,7 +3979,7 @@ void ClassFileParser::set_precomputed_flags(InstanceKlass* ik) {
#endif
// Check if this klass supports the java.lang.Cloneable interface
if (vmClasses::Cloneable_klass_loaded()) {
if (vmClasses::Cloneable_klass_is_loaded()) {
if (ik->is_subtype_of(vmClasses::Cloneable_klass())) {
ik->set_is_cloneable();
}
+2 -2
View File
@@ -1150,7 +1150,7 @@ void java_lang_Class::create_mirror(Klass* k, Handle class_loader,
// Class_klass has to be loaded because it is used to allocate
// the mirror.
if (vmClasses::Class_klass_loaded()) {
if (vmClasses::Class_klass_is_loaded()) {
Handle mirror;
Handle comp_mirror;
@@ -1223,7 +1223,7 @@ bool java_lang_Class::restore_archived_mirror(Klass *k,
Handle protection_domain, TRAPS) {
// Postpone restoring archived mirror until java.lang.Class is loaded. Please
// see more details in vmClasses::resolve_all().
if (!vmClasses::Class_klass_loaded() && !CDSConfig::is_using_aot_linked_classes()) {
if (!vmClasses::Class_klass_is_loaded() && !CDSConfig::is_using_aot_linked_classes()) {
assert(fixup_mirror_list() != nullptr, "fixup_mirror_list not initialized");
fixup_mirror_list()->push(k);
return true;
+1 -1
View File
@@ -456,7 +456,7 @@ void Modules::define_module(Handle module, jboolean is_open, jstring version,
#if COMPILER2_OR_JVMCI
// Special handling of jdk.incubator.vector
if (strcmp(module_name, "jdk.incubator.vector") == 0) {
if (FLAG_IS_DEFAULT(EnableVectorSupport)) {
if (FLAG_IS_DEFAULT(EnableVectorSupport) && VM_Version::supports_misaligned_vector_accesses()) {
FLAG_SET_DEFAULT(EnableVectorSupport, true);
}
if (EnableVectorSupport && FLAG_IS_DEFAULT(EnableVectorReboxing)) {
+1 -1
View File
@@ -113,7 +113,7 @@ void vmClasses::resolve_until(vmClassID limit_id, vmClassID &start_id, TRAPS) {
}
void vmClasses::resolve_all(TRAPS) {
assert(!Object_klass_loaded(), "well-known classes should only be initialized once");
assert(!Object_klass_is_loaded(), "well-known classes should only be initialized once");
// Create the ModuleEntry for java.base. This call needs to be done here,
// after vmSymbols::initialize() is called but before any classes are pre-loaded.
@@ -102,12 +102,6 @@ public:
assert((uint)t < T_VOID+1, "range check");
return check_klass(_box_klasses[t]);
}
static bool Object_klass_loaded() { return is_loaded(VM_CLASS_AT(Object_klass)); }
static bool Class_klass_loaded() { return is_loaded(VM_CLASS_AT(Class_klass)); }
static bool Cloneable_klass_loaded() { return is_loaded(VM_CLASS_AT(Cloneable_klass)); }
static bool Parameter_klass_loaded() { return is_loaded(VM_CLASS_AT(reflect_Parameter_klass)); }
static bool ClassLoader_klass_loaded() { return is_loaded(VM_CLASS_AT(ClassLoader_klass)); }
};
#endif // SHARE_CLASSFILE_VMCLASSES_HPP
+1 -3
View File
@@ -203,9 +203,7 @@ uint G1NUMA::index_for_region(G1HeapRegion* hr) const {
// * G1HeapRegion #: |-#0-||-#1-||-#2-||-#3-||-#4-||-#5-||-#6-||-#7-||-#8-||-#9-||#10-||#11-||#12-||#13-||#14-||#15-|
// * NUMA node #: |----#0----||----#1----||----#2----||----#3----||----#0----||----#1----||----#2----||----#3----|
void G1NUMA::request_memory_on_node(void* aligned_address, size_t size_in_bytes, uint region_index) {
if (!is_enabled()) {
return;
}
assert(is_enabled(), "must be, check before");
if (size_in_bytes == 0) {
return;
@@ -96,13 +96,15 @@ class G1RegionsLargerThanCommitSizeMapper : public G1RegionToSpaceMapper {
const size_t start_page = (size_t)start_idx * _pages_per_region;
const size_t size_in_pages = num_regions * _pages_per_region;
bool zero_filled = _storage.commit(start_page, size_in_pages);
if (_memory_tag == mtJavaHeap) {
if (should_distribute_across_numa_nodes()) {
for (uint region_index = start_idx; region_index < start_idx + num_regions; region_index++ ) {
void* address = _storage.page_start(region_index * _pages_per_region);
size_t size_in_bytes = _storage.page_size() * _pages_per_region;
G1NUMA::numa()->request_memory_on_node(address, size_in_bytes, region_index);
}
}
if (AlwaysPreTouch) {
_storage.pretouch(start_page, size_in_pages, pretouch_workers);
}
@@ -122,7 +124,7 @@ class G1RegionsLargerThanCommitSizeMapper : public G1RegionToSpaceMapper {
// G1RegionToSpaceMapper implementation where the region granularity is smaller
// than the commit granularity.
// Basically, the contents of one OS page span several regions.
// Basically, the contents of one OS page spans several regions.
class G1RegionsSmallerThanCommitSizeMapper : public G1RegionToSpaceMapper {
size_t _regions_per_page;
// Lock to prevent bitmap updates and the actual underlying
@@ -148,13 +150,18 @@ class G1RegionsSmallerThanCommitSizeMapper : public G1RegionToSpaceMapper {
return _region_commit_map.find_first_set_bit(region, region_limit) != region_limit;
}
void numa_request_on_node(size_t page_idx) {
if (_memory_tag == mtJavaHeap) {
uint region = (uint)(page_idx * _regions_per_page);
void* address = _storage.page_start(page_idx);
size_t size_in_bytes = _storage.page_size();
G1NUMA::numa()->request_memory_on_node(address, size_in_bytes, region);
bool commit_pages(size_t start_page, size_t size_in_pages) {
bool result = _storage.commit(start_page, size_in_pages);
if (should_distribute_across_numa_nodes()) {
for (size_t page = start_page; page < start_page + size_in_pages; page++) {
uint region = checked_cast<uint>(page * _regions_per_page);
void* address = _storage.page_start(page);
size_t size_in_bytes = _storage.page_size();
G1NUMA::numa()->request_memory_on_node(address, size_in_bytes, region);
}
}
return result;
}
public:
@@ -171,6 +178,21 @@ class G1RegionsSmallerThanCommitSizeMapper : public G1RegionToSpaceMapper {
guarantee((page_size * commit_factor) >= alloc_granularity, "allocation granularity smaller than commit granularity");
}
size_t find_first_uncommitted(size_t page, size_t end) {
assert(page < end, "must be");
while (page < end && is_page_committed(page)) {
page++;
}
return page;
}
size_t find_first_committed(size_t page, size_t end) {
while (page < end && !is_page_committed(page)) {
page++;
}
return MIN2(page, end);
}
virtual void commit_regions(uint start_idx, size_t num_regions, WorkerThreads* pretouch_workers) {
uint region_limit = (uint)(start_idx + num_regions);
assert(num_regions > 0, "Must commit at least one region");
@@ -179,11 +201,11 @@ class G1RegionsSmallerThanCommitSizeMapper : public G1RegionToSpaceMapper {
size_t const NoPage = SIZE_MAX;
size_t first_committed = NoPage;
size_t num_committed = 0;
size_t first_newly_committed = NoPage;
size_t num_committed_pages = 0;
size_t start_page = region_idx_to_page_idx(start_idx);
size_t end_page = region_idx_to_page_idx(region_limit - 1);
size_t const start_page = region_idx_to_page_idx(start_idx);
size_t const end_page = region_idx_to_page_idx(region_limit - 1) + 1;
bool all_zero_filled = true;
@@ -191,34 +213,27 @@ class G1RegionsSmallerThanCommitSizeMapper : public G1RegionToSpaceMapper {
// underlying OS page. See lock declaration for more details.
{
MutexLocker ml(&_lock, Mutex::_no_safepoint_check_flag);
for (size_t page = start_page; page <= end_page; page++) {
if (!is_page_committed(page)) {
// Page not committed.
if (num_committed == 0) {
first_committed = page;
}
num_committed++;
if (!_storage.commit(page, 1)) {
// Found dirty region during commit.
all_zero_filled = false;
}
size_t uncommitted_l = find_first_uncommitted(start_page, end_page);
size_t uncommitted_r = find_first_committed(uncommitted_l + 1, end_page);
// Move memory to correct NUMA node for the heap.
numa_request_on_node(page);
} else {
// Page already committed.
all_zero_filled = false;
}
first_newly_committed = uncommitted_l;
num_committed_pages = uncommitted_r - uncommitted_l;
if (num_committed_pages > 0 &&
!commit_pages(first_newly_committed, num_committed_pages)) {
all_zero_filled = false;
}
all_zero_filled &= (uncommitted_l == start_page) && (uncommitted_r == end_page);
// Update the commit map for the given range. Not using the par_set_range
// since updates to _region_commit_map for this mapper is protected by _lock.
_region_commit_map.set_range(start_idx, region_limit, BitMap::unknown_range);
}
if (AlwaysPreTouch && num_committed > 0) {
_storage.pretouch(first_committed, num_committed, pretouch_workers);
if (AlwaysPreTouch && num_committed_pages > 0) {
_storage.pretouch(first_newly_committed, num_committed_pages, pretouch_workers);
}
fire_on_commit(start_idx, num_regions, all_zero_filled);
@@ -230,8 +245,8 @@ class G1RegionsSmallerThanCommitSizeMapper : public G1RegionToSpaceMapper {
assert(_region_commit_map.find_first_clear_bit(start_idx, region_limit) == region_limit,
"Should only be committed regions in the range [%u, %u)", start_idx, region_limit);
size_t start_page = region_idx_to_page_idx(start_idx);
size_t end_page = region_idx_to_page_idx(region_limit - 1);
size_t const start_page = region_idx_to_page_idx(start_idx);
size_t const end_page = region_idx_to_page_idx(region_limit - 1) + 1;
// Concurrent operations might operate on regions sharing the same
// underlying OS page. See lock declaration for more details.
@@ -240,13 +255,16 @@ class G1RegionsSmallerThanCommitSizeMapper : public G1RegionToSpaceMapper {
// updates to _region_commit_map for this mapper is protected by _lock.
_region_commit_map.clear_range(start_idx, region_limit, BitMap::unknown_range);
for (size_t page = start_page; page <= end_page; page++) {
// We know all pages were committed before clearing the map. If the
// the page is still marked as committed after the clear we should
// not uncommit it.
if (!is_page_committed(page)) {
_storage.uncommit(page, 1);
}
// We know all pages were committed before clearing the map. If the
// the page is still marked as committed after the clear we should
// not uncommit it.
size_t uncommitted_l = find_first_uncommitted(start_page, end_page);
size_t uncommitted_r = find_first_committed(uncommitted_l + 1, end_page);
size_t num_uncommitted_pages_found = uncommitted_r - uncommitted_l;
if (num_uncommitted_pages_found > 0) {
_storage.uncommit(uncommitted_l, num_uncommitted_pages_found);
}
}
};
@@ -257,6 +275,10 @@ void G1RegionToSpaceMapper::fire_on_commit(uint start_idx, size_t num_regions, b
}
}
bool G1RegionToSpaceMapper::should_distribute_across_numa_nodes() const {
return _memory_tag == mtJavaHeap && G1NUMA::numa()->is_enabled();
}
G1RegionToSpaceMapper* G1RegionToSpaceMapper::create_mapper(ReservedSpace rs,
size_t actual_size,
size_t page_size,
@@ -58,6 +58,8 @@ class G1RegionToSpaceMapper : public CHeapObj<mtGC> {
G1RegionToSpaceMapper(ReservedSpace rs, size_t used_size, size_t page_size, size_t region_granularity, size_t commit_factor, MemTag mem_tag);
void fire_on_commit(uint start_idx, size_t num_regions, bool zero_filled);
bool should_distribute_across_numa_nodes() const;
public:
MemRegion reserved() { return _storage.reserved(); }
@@ -1660,21 +1660,19 @@ static void compaction_with_stealing_work(TaskTerminator* terminator, uint worke
}
class FillDensePrefixAndCompactionTask: public WorkerTask {
uint _num_workers;
TaskTerminator _terminator;
public:
FillDensePrefixAndCompactionTask(uint active_workers) :
WorkerTask("FillDensePrefixAndCompactionTask"),
_num_workers(active_workers),
_terminator(active_workers, ParCompactionManager::region_task_queues()) {
}
virtual void work(uint worker_id) {
{
if (worker_id == 0) {
auto start = Ticks::now();
PSParallelCompact::fill_dead_objs_in_dense_prefix(worker_id, _num_workers);
log_trace(gc, phases)("Fill dense prefix by worker %u: %.3f ms", worker_id, (Ticks::now() - start).seconds() * 1000);
PSParallelCompact::fill_dead_objs_in_dense_prefix();
log_trace(gc, phases)("Fill dense prefix by worker 0: %.3f ms", (Ticks::now() - start).seconds() * 1000);
}
compaction_with_stealing_work(&_terminator, worker_id);
}
@@ -1687,9 +1685,10 @@ void PSParallelCompact::fill_range_in_dense_prefix(HeapWord* start, HeapWord* en
assert(mark_bitmap()->find_obj_beg(start, end) == end, "precondition");
HeapWord* bottom = _space_info[old_space_id].space()->bottom();
if (start != bottom) {
// The preceding live obj.
HeapWord* obj_start = mark_bitmap()->find_obj_beg_reverse(bottom, start);
HeapWord* after_obj = obj_start + cast_to_oop(obj_start)->size();
assert(after_obj == start, "precondition");
HeapWord* obj_end = obj_start + cast_to_oop(obj_start)->size();
assert(obj_end == start, "precondition");
}
}
#endif
@@ -1703,58 +1702,51 @@ void PSParallelCompact::fill_range_in_dense_prefix(HeapWord* start, HeapWord* en
} while (addr < end);
}
void PSParallelCompact::fill_dead_objs_in_dense_prefix(uint worker_id, uint num_workers) {
void PSParallelCompact::fill_dead_objs_in_dense_prefix() {
ParMarkBitMap* bitmap = mark_bitmap();
HeapWord* const bottom = _space_info[old_space_id].space()->bottom();
HeapWord* const prefix_end = dense_prefix(old_space_id);
if (bottom == prefix_end) {
return;
}
const size_t region_size = ParallelCompactData::RegionSize;
size_t bottom_region = _summary_data.addr_to_region_idx(bottom);
size_t prefix_end_region = _summary_data.addr_to_region_idx(prefix_end);
// Fill dead space in [start_addr, end_addr)
HeapWord* const start_addr = bottom;
HeapWord* const end_addr = prefix_end;
size_t start_region;
size_t end_region;
split_regions_for_worker(bottom_region, prefix_end_region,
worker_id, num_workers,
&start_region, &end_region);
for (HeapWord* cur_addr = start_addr; cur_addr < end_addr; /* empty */) {
RegionData* cur_region_ptr = _summary_data.addr_to_region_ptr(cur_addr);
if (cur_region_ptr->data_size() == region_size) {
// Full; no dead space. Next region.
if (_summary_data.is_region_aligned(cur_addr)) {
cur_addr += region_size;
} else {
cur_addr = _summary_data.region_align_up(cur_addr);
}
continue;
}
if (start_region == end_region) {
return;
}
// Fill dead space inside cur_region.
if (_summary_data.is_region_aligned(cur_addr)) {
cur_addr += cur_region_ptr->partial_obj_size();
}
HeapWord* const start_addr = _summary_data.region_to_addr(start_region);
HeapWord* const end_addr = _summary_data.region_to_addr(end_region);
// Skip live partial obj (if any) from previous region.
HeapWord* cur_addr;
RegionData* start_region_ptr = _summary_data.region(start_region);
if (start_region_ptr->partial_obj_size() != 0) {
HeapWord* partial_obj_start = start_region_ptr->partial_obj_addr();
assert(bitmap->is_marked(partial_obj_start), "inv");
cur_addr = partial_obj_start + cast_to_oop(partial_obj_start)->size();
} else {
cur_addr = start_addr;
}
// end_addr is inclusive to handle regions starting with dead space.
while (cur_addr <= end_addr) {
// Use prefix_end to handle trailing obj in each worker region-chunk.
HeapWord* live_start = bitmap->find_obj_beg(cur_addr, prefix_end);
if (cur_addr != live_start) {
// Only worker 0 handles proceeding dead space.
if (cur_addr != start_addr || worker_id == 0) {
HeapWord* region_end_addr = _summary_data.region_align_up(cur_addr + 1);
assert(region_end_addr <= end_addr, "inv");
while (cur_addr < region_end_addr) {
// Use end_addr to allow filler-obj to cross region boundary.
HeapWord* live_start = bitmap->find_obj_beg(cur_addr, end_addr);
if (cur_addr != live_start) {
// Found dead space [cur_addr, live_start).
fill_range_in_dense_prefix(cur_addr, live_start);
}
if (live_start >= region_end_addr) {
cur_addr = live_start;
break;
}
assert(bitmap->is_marked(live_start), "inv");
cur_addr = live_start + cast_to_oop(live_start)->size();
}
if (live_start >= end_addr) {
break;
}
assert(bitmap->is_marked(live_start), "inv");
cur_addr = live_start + cast_to_oop(live_start)->size();
}
}
@@ -1787,15 +1779,38 @@ void PSParallelCompact::compact() {
void PSParallelCompact::verify_filler_in_dense_prefix() {
HeapWord* bottom = _space_info[old_space_id].space()->bottom();
HeapWord* dense_prefix_end = dense_prefix(old_space_id);
HeapWord* cur_addr = bottom;
while (cur_addr < dense_prefix_end) {
oop obj = cast_to_oop(cur_addr);
oopDesc::verify(obj);
if (!mark_bitmap()->is_marked(cur_addr)) {
Klass* k = cast_to_oop(cur_addr)->klass();
assert(k == Universe::fillerArrayKlass() || k == vmClasses::FillerObject_klass(), "inv");
const size_t region_size = ParallelCompactData::RegionSize;
for (HeapWord* cur_addr = bottom; cur_addr < dense_prefix_end; /* empty */) {
RegionData* cur_region_ptr = _summary_data.addr_to_region_ptr(cur_addr);
if (cur_region_ptr->data_size() == region_size) {
// Full; no dead space. Next region.
if (_summary_data.is_region_aligned(cur_addr)) {
cur_addr += region_size;
} else {
cur_addr = _summary_data.region_align_up(cur_addr);
}
continue;
}
// This region contains filler objs.
if (_summary_data.is_region_aligned(cur_addr)) {
cur_addr += cur_region_ptr->partial_obj_size();
}
HeapWord* region_end_addr = _summary_data.region_align_up(cur_addr + 1);
assert(region_end_addr <= dense_prefix_end, "inv");
while (cur_addr < region_end_addr) {
oop obj = cast_to_oop(cur_addr);
oopDesc::verify(obj);
if (!mark_bitmap()->is_marked(cur_addr)) {
Klass* k = cast_to_oop(cur_addr)->klass();
assert(k == Universe::fillerArrayKlass() || k == vmClasses::FillerObject_klass(), "inv");
}
cur_addr += obj->size();
}
cur_addr += obj->size();
}
}
@@ -755,7 +755,7 @@ private:
static void fill_range_in_dense_prefix(HeapWord* start, HeapWord* end);
public:
static void fill_dead_objs_in_dense_prefix(uint worker_id, uint num_workers);
static void fill_dead_objs_in_dense_prefix();
// This method invokes a full collection.
// clear_all_soft_refs controls whether soft-refs should be cleared or not.
@@ -807,7 +807,7 @@ void DefNewGeneration::reset_scratch() {
}
}
void DefNewGeneration::gc_epilogue(bool full) {
void DefNewGeneration::gc_epilogue() {
assert(!GCLocker::is_active(), "We should not be executing here");
// update the generation and space performance counters
update_counters();
@@ -187,7 +187,7 @@ class DefNewGeneration: public Generation {
HeapWord* allocate(size_t word_size);
HeapWord* par_allocate(size_t word_size);
void gc_epilogue(bool full);
void gc_epilogue();
// For Old collection (part of running Full GC), the DefNewGeneration can
// contribute the free part of "to-space" as the scratch space.
@@ -482,6 +482,8 @@ void SerialFullGC::phase1_mark(bool clear_all_softrefs) {
ref_processor()->start_discovery(clear_all_softrefs);
{
GCTraceTime(Debug, gc, phases) tm_m("Marking From Roots", gc_timer());
// Start tracing from roots, there are 3 kinds of roots in full-gc.
//
// 1. CLD. This method internally takes care of whether class loading is
+1 -1
View File
@@ -779,7 +779,7 @@ void SerialHeap::gc_epilogue(bool full) {
resize_all_tlabs();
_young_gen->gc_epilogue(full);
_young_gen->gc_epilogue();
_old_gen->gc_epilogue();
if (_is_heap_almost_full) {
@@ -135,14 +135,12 @@ inline ShenandoahMarkBitMap::idx_t ShenandoahMarkBitMap::get_next_bit_impl(idx_t
// Get the word containing l_index, and shift out low bits.
idx_t index = to_words_align_down(l_index);
bm_word_t cword = (map(index) ^ flip) >> bit_in_word(l_index);
if ((cword & 1) != 0) {
// The first bit is similarly often interesting. When it matters
// (density or features of the calling algorithm make it likely
// the first bit is set), going straight to the next clause compares
// poorly with doing this check first; count_trailing_zeros can be
// relatively expensive, plus there is the additional range check.
// But when the first bit isn't set, the cost of having tested for
// it is relatively small compared to the rest of the search.
if ((cword & 0x03) != 0) {
// The first bits (representing weak mark or strong mark) are similarly often interesting. When it matters
// (density or features of the calling algorithm make it likely the first bits are set), going straight to
// the next clause compares poorly with doing this check first; count_trailing_zeros can be relatively expensive,
// plus there is the additional range check. But when the first bits are not set, the cost of having tested for
// them is relatively small compared to the rest of the search.
return l_index;
} else if (cword != 0) {
// Flipped and shifted first word is non-zero.
+2 -2
View File
@@ -504,7 +504,7 @@ void Universe::genesis(TRAPS) {
// Since some of the old system object arrays have been converted to
// ordinary object arrays, _objectArrayKlass will be loaded when
// SystemDictionary::initialize(CHECK); is run. See the extra check
// for Object_klass_loaded in objArrayKlassKlass::allocate_objArray_klass_impl.
// for Object_klass_is_loaded in ObjArrayKlass::allocate_objArray_klass.
{
Klass* oak = vmClasses::Object_klass()->array_klass(CHECK);
_objectArrayKlass = ObjArrayKlass::cast(oak);
@@ -593,7 +593,7 @@ void Universe::fixup_mirrors(TRAPS) {
// but we cannot do that for classes created before java.lang.Class is loaded. Here we simply
// walk over permanent objects created so far (mostly classes) and fixup their mirrors. Note
// that the number of objects allocated at this point is very small.
assert(vmClasses::Class_klass_loaded(), "java.lang.Class should be loaded");
assert(vmClasses::Class_klass_is_loaded(), "java.lang.Class should be loaded");
HandleMark hm(THREAD);
if (!CDSConfig::is_using_archive()) {
+1 -1
View File
@@ -110,7 +110,7 @@ void CompressedKlassPointers::sanity_check_after_initialization() {
// Check that Klass range is fully engulfed in the encoding range
const address encoding_start = _base;
const address encoding_end = (address)
LP64_ONLY(p2u(_base) + (uintptr_t)nth_bit(narrow_klass_pointer_bits() + _shift))
LP64_ONLY((p2u(_base) + (uintptr_t)nth_bit(narrow_klass_pointer_bits() + _shift)))
NOT_LP64(max_klass_range_size());
ASSERT_HERE_2(_klass_range_start >= _base && _klass_range_end <= encoding_end,
"Resulting encoding range does not fully cover the class range");
+1 -1
View File
@@ -395,7 +395,7 @@ void ConstantPool::restore_unshareable_info(TRAPS) {
// Only create the new resolved references array if it hasn't been attempted before
if (resolved_references() != nullptr) return;
if (vmClasses::Object_klass_loaded()) {
if (vmClasses::Object_klass_is_loaded()) {
ClassLoaderData* loader_data = pool_holder()->class_loader_data();
#if INCLUDE_CDS_JAVA_HEAP
if (ArchiveHeapLoader::is_in_use() &&
+1 -1
View File
@@ -159,7 +159,7 @@ static inline bool is_class_loader(const Symbol* class_name,
return true;
}
if (vmClasses::ClassLoader_klass_loaded()) {
if (vmClasses::ClassLoader_klass_is_loaded()) {
const Klass* const super_klass = parser.super_klass();
if (super_klass != nullptr) {
if (super_klass->is_subtype_of(vmClasses::ClassLoader_klass())) {
+1 -1
View File
@@ -78,7 +78,7 @@ ObjArrayKlass* ObjArrayKlass::allocate_objArray_klass(ClassLoaderData* loader_da
// Eagerly allocate the direct array supertype.
Klass* super_klass = nullptr;
if (!Universe::is_bootstrapping() || vmClasses::Object_klass_loaded()) {
if (!Universe::is_bootstrapping() || vmClasses::Object_klass_is_loaded()) {
assert(MultiArray_lock->holds_lock(THREAD), "must hold lock after bootstrapping");
Klass* element_super = element_klass->super();
if (element_super != nullptr) {
+5 -5
View File
@@ -1206,6 +1206,11 @@ static const Type* mod_value(const PhaseGVN* phase, const Node* in1, const Node*
if (t1 == Type::TOP) { return Type::TOP; }
if (t2 == Type::TOP) { return Type::TOP; }
// Mod by zero? Throw exception at runtime!
if (t2 == TypeInteger::zero(bt)) {
return Type::TOP;
}
// We always generate the dynamic check for 0.
// 0 MOD X is 0
if (t1 == TypeInteger::zero(bt)) { return t1; }
@@ -1215,11 +1220,6 @@ static const Type* mod_value(const PhaseGVN* phase, const Node* in1, const Node*
return TypeInteger::zero(bt);
}
// Mod by zero? Throw exception at runtime!
if (t2 == TypeInteger::zero(bt)) {
return Type::TOP;
}
const TypeInteger* i1 = t1->is_integer(bt);
const TypeInteger* i2 = t2->is_integer(bt);
if (i1->is_con() && i2->is_con()) {
@@ -197,6 +197,9 @@ class Abstract_VM_Version: AllStatic {
// Does platform support secondary supers table lookup?
constexpr static bool supports_secondary_supers_table() { return false; }
// Does platform support misaligned vector accesses?
constexpr static bool supports_misaligned_vector_accesses() { return true; }
// Does platform support float16 instructions?
static bool supports_float16() { return false; }
+19 -4
View File
@@ -1161,9 +1161,11 @@ public:
Type _type;
// park blocker or an object the thread waiting on/trying to lock
OopHandle _obj;
// thread that owns park blocker object when park blocker is AbstractOwnableSynchronizer
OopHandle _owner;
Blocker(Type type, OopHandle obj): _type(type), _obj(obj) {}
Blocker(): _type(NOTHING), _obj(nullptr) {}
Blocker(Type type, OopHandle obj): _type(type), _obj(obj), _owner() {}
Blocker(): _type(NOTHING), _obj(), _owner() {}
bool is_empty() const {
return _type == NOTHING;
@@ -1198,6 +1200,7 @@ public:
delete _locks;
}
_blocker._obj.release(oop_storage());
_blocker._owner.release(oop_storage());
}
private:
@@ -1300,6 +1303,13 @@ public:
oop park_blocker = java_lang_Thread::park_blocker(_thread_h());
if (park_blocker != nullptr) {
_blocker = Blocker(Blocker::PARK_BLOCKER, OopHandle(oop_storage(), park_blocker));
if (park_blocker->is_a(vmClasses::java_util_concurrent_locks_AbstractOwnableSynchronizer_klass())) {
// could be stale (unlikely in practice), but it's good enough to see deadlocks
oop ownerObj = java_util_concurrent_locks_AbstractOwnableSynchronizer::get_owner_threadObj(park_blocker);
if (ownerObj != nullptr) {
_blocker._owner = OopHandle(oop_storage(), ownerObj);
}
}
}
ResourceMark rm(current);
@@ -1381,6 +1391,7 @@ class jdk_internal_vm_ThreadSnapshot: AllStatic {
static int _locks_offset;
static int _blockerTypeOrdinal_offset;
static int _blockerObject_offset;
static int _parkBlockerOwner_offset;
static void compute_offsets(InstanceKlass* klass, TRAPS) {
JavaClasses::compute_offset(_name_offset, klass, "name", vmSymbols::string_signature(), false);
@@ -1390,6 +1401,7 @@ class jdk_internal_vm_ThreadSnapshot: AllStatic {
JavaClasses::compute_offset(_locks_offset, klass, "locks", vmSymbols::jdk_internal_vm_ThreadLock_array(), false);
JavaClasses::compute_offset(_blockerTypeOrdinal_offset, klass, "blockerTypeOrdinal", vmSymbols::int_signature(), false);
JavaClasses::compute_offset(_blockerObject_offset, klass, "blockerObject", vmSymbols::object_signature(), false);
JavaClasses::compute_offset(_parkBlockerOwner_offset, klass, "parkBlockerOwner", vmSymbols::thread_signature(), false);
}
public:
static void init(InstanceKlass* klass, TRAPS) {
@@ -1420,9 +1432,10 @@ public:
static void set_locks(oop snapshot, oop locks) {
snapshot->obj_field_put(_locks_offset, locks);
}
static void set_blocker(oop snapshot, int type_ordinal, oop lock) {
static void set_blocker(oop snapshot, int type_ordinal, oop lock, oop owner) {
snapshot->int_field_put(_blockerTypeOrdinal_offset, type_ordinal);
snapshot->obj_field_put(_blockerObject_offset, lock);
snapshot->obj_field_put(_parkBlockerOwner_offset, owner);
}
};
@@ -1434,6 +1447,7 @@ int jdk_internal_vm_ThreadSnapshot::_stackTrace_offset;
int jdk_internal_vm_ThreadSnapshot::_locks_offset;
int jdk_internal_vm_ThreadSnapshot::_blockerTypeOrdinal_offset;
int jdk_internal_vm_ThreadSnapshot::_blockerObject_offset;
int jdk_internal_vm_ThreadSnapshot::_parkBlockerOwner_offset;
oop ThreadSnapshotFactory::get_thread_snapshot(jobject jthread, TRAPS) {
ThreadsListHandle tlh(THREAD);
@@ -1559,7 +1573,8 @@ oop ThreadSnapshotFactory::get_thread_snapshot(jobject jthread, TRAPS) {
jdk_internal_vm_ThreadSnapshot::set_stack_trace(snapshot(), trace());
jdk_internal_vm_ThreadSnapshot::set_locks(snapshot(), locks());
if (!cl._blocker.is_empty()) {
jdk_internal_vm_ThreadSnapshot::set_blocker(snapshot(), cl._blocker._type, cl._blocker._obj.resolve());
jdk_internal_vm_ThreadSnapshot::set_blocker(snapshot(),
cl._blocker._type, cl._blocker._obj.resolve(), cl._blocker._owner.resolve());
}
return snapshot();
}
@@ -84,12 +84,11 @@ import jdk.internal.vm.annotation.AOTSafeClassInitializer;
import jdk.internal.vm.annotation.IntrinsicCandidate;
import jdk.internal.vm.annotation.Stable;
import sun.invoke.util.BytecodeDescriptor;
import sun.invoke.util.Wrapper;
import sun.reflect.generics.factory.CoreReflectionFactory;
import sun.reflect.generics.factory.GenericsFactory;
import sun.reflect.generics.repository.ClassRepository;
import sun.reflect.generics.repository.MethodRepository;
import sun.reflect.generics.repository.ConstructorRepository;
import sun.reflect.generics.scope.ClassScope;
import sun.reflect.annotation.*;
@@ -1447,17 +1446,10 @@ public final class Class<T> implements java.io.Serializable,
if (!enclosingInfo.isMethod())
return null;
MethodRepository typeInfo = MethodRepository.make(enclosingInfo.getDescriptor(),
getFactory());
Class<?> returnType = toClass(typeInfo.getReturnType());
Type [] parameterTypes = typeInfo.getParameterTypes();
Class<?>[] parameterClasses = new Class<?>[parameterTypes.length];
// Convert Types to Classes; returned types *should*
// be class objects since the methodDescriptor's used
// don't have generics information
for(int i = 0; i < parameterClasses.length; i++)
parameterClasses[i] = toClass(parameterTypes[i]);
// Descriptor already validated by VM
List<Class<?>> types = BytecodeDescriptor.parseMethod(enclosingInfo.getDescriptor(), getClassLoader());
Class<?> returnType = types.removeLast();
Class<?>[] parameterClasses = types.toArray(EMPTY_CLASS_ARRAY);
final Class<?> enclosingCandidate = enclosingInfo.getEnclosingClass();
Method[] candidates = enclosingCandidate.privateGetDeclaredMethods(false);
@@ -1576,17 +1568,10 @@ public final class Class<T> implements java.io.Serializable,
if (!enclosingInfo.isConstructor())
return null;
ConstructorRepository typeInfo = ConstructorRepository.make(enclosingInfo.getDescriptor(),
getFactory());
Type [] parameterTypes = typeInfo.getParameterTypes();
Class<?>[] parameterClasses = new Class<?>[parameterTypes.length];
// Convert Types to Classes; returned types *should*
// be class objects since the methodDescriptor's used
// don't have generics information
for (int i = 0; i < parameterClasses.length; i++)
parameterClasses[i] = toClass(parameterTypes[i]);
// Descriptor already validated by VM
List<Class<?>> types = BytecodeDescriptor.parseMethod(enclosingInfo.getDescriptor(), getClassLoader());
types.removeLast();
Class<?>[] parameterClasses = types.toArray(EMPTY_CLASS_ARRAY);
final Class<?> enclosingCandidate = enclosingInfo.getEnclosingClass();
Constructor<?>[] candidates = enclosingCandidate
@@ -1892,7 +1877,7 @@ public final class Class<T> implements java.io.Serializable,
}
currentClass = currentClass.getSuperclass();
}
return list.toArray(new Class<?>[0]);
return list.toArray(EMPTY_CLASS_ARRAY);
}
@@ -250,38 +250,43 @@ public final class CompactNumberFormat extends NumberFormat {
/**
* List of positive prefix patterns of this formatter's
* compact number patterns.
* compact number patterns. This field is a read-only
* constant once initialized.
*/
private transient List<Patterns> positivePrefixPatterns;
/**
* List of negative prefix patterns of this formatter's
* compact number patterns.
* compact number patterns. This field is a read-only
* constant once initialized.
*/
private transient List<Patterns> negativePrefixPatterns;
/**
* List of positive suffix patterns of this formatter's
* compact number patterns.
* compact number patterns. This field is a read-only
* constant once initialized.
*/
private transient List<Patterns> positiveSuffixPatterns;
/**
* List of negative suffix patterns of this formatter's
* compact number patterns.
* compact number patterns. This field is a read-only
* constant once initialized.
*/
private transient List<Patterns> negativeSuffixPatterns;
/**
* List of divisors of this formatter's compact number patterns.
* Divisor can be either Long or BigInteger (if the divisor value goes
* beyond long boundary)
* beyond long boundary). This field is a read-only constant
* once initialized.
*/
private transient List<Number> divisors;
/**
* List of place holders that represent minimum integer digits at each index
* for each count.
* for each count. This field is a read-only constant once initialized.
*/
private transient List<Patterns> placeHolderPatterns;
@@ -374,7 +379,7 @@ public final class CompactNumberFormat extends NumberFormat {
/**
* The map for plural rules that maps LDML defined tags (e.g. "one") to
* its rule.
* its rule. This field is a read-only constant once initialized.
*/
private transient Map<String, String> rulesMap;
@@ -1515,7 +1520,7 @@ public final class CompactNumberFormat extends NumberFormat {
}
}
private final transient DigitList digitList = new DigitList();
private transient DigitList digitList = new DigitList();
private static final int STATUS_INFINITE = 0;
private static final int STATUS_POSITIVE = 1;
private static final int STATUS_LENGTH = 2;
@@ -2506,8 +2511,14 @@ public final class CompactNumberFormat extends NumberFormat {
@Override
public CompactNumberFormat clone() {
CompactNumberFormat other = (CompactNumberFormat) super.clone();
// Cloning reference fields. Other fields (e.g., "positivePrefixPatterns")
// are not cloned since they are read-only constants after initialization.
other.compactPatterns = compactPatterns.clone();
other.symbols = (DecimalFormatSymbols) symbols.clone();
other.decimalFormat = (DecimalFormat) decimalFormat.clone();
other.defaultDecimalFormat = (DecimalFormat) defaultDecimalFormat.clone();
other.digitList = (DigitList) digitList.clone();
return other;
}
@@ -205,7 +205,10 @@ public class ThreadDumper {
// park blocker
Object parkBlocker = snapshot.parkBlocker();
if (parkBlocker != null) {
writer.println(" - parking to wait for " + decorateObject(parkBlocker));
String suffix = (snapshot.parkBlockerOwner() instanceof Thread owner)
? ", owner #" + owner.threadId()
: "";
writer.println(" - parking to wait for " + decorateObject(parkBlocker) + suffix);
}
// blocked on monitor enter or Object.wait
@@ -335,6 +338,9 @@ public class ThreadDumper {
// parkBlocker is an object to allow for exclusiveOwnerThread in the future
jsonWriter.startObject("parkBlocker");
jsonWriter.writeProperty("object", Objects.toIdentityString(parkBlocker));
if (snapshot.parkBlockerOwner() instanceof Thread owner) {
jsonWriter.writeProperty("owner", owner.threadId());
}
jsonWriter.endObject();
}
@@ -44,6 +44,8 @@ class ThreadSnapshot {
// an object the thread is blocked/waiting on, converted to ThreadBlocker by ThreadSnapshot.of()
private int blockerTypeOrdinal;
private Object blockerObject;
// the owner of the blockerObject when the object is park blocker and is AbstractOwnableSynchronizer
private Thread parkBlockerOwner;
// set by ThreadSnapshot.of()
private ThreadBlocker blocker;
@@ -70,8 +72,11 @@ class ThreadSnapshot {
snapshot.locks = EMPTY_LOCKS;
}
if (snapshot.blockerObject != null) {
snapshot.blocker = new ThreadBlocker(snapshot.blockerTypeOrdinal, snapshot.blockerObject);
snapshot.blocker = new ThreadBlocker(snapshot.blockerTypeOrdinal,
snapshot.blockerObject,
snapshot.parkBlockerOwner);
snapshot.blockerObject = null; // release
snapshot.parkBlockerOwner = null;
}
return snapshot;
}
@@ -104,6 +109,13 @@ class ThreadSnapshot {
return getBlocker(BlockerLockType.PARK_BLOCKER);
}
/**
* Returns the owner of the parkBlocker if the parkBlocker is an AbstractOwnableSynchronizer.
*/
Thread parkBlockerOwner() {
return (blocker != null && blocker.type == BlockerLockType.PARK_BLOCKER) ? blocker.owner : null;
}
/**
* Returns the object that the thread is blocked on.
* @throws IllegalStateException if not in the blocked state
@@ -211,11 +223,11 @@ class ThreadSnapshot {
}
}
private record ThreadBlocker(BlockerLockType type, Object obj) {
private record ThreadBlocker(BlockerLockType type, Object obj, Thread owner) {
private static final BlockerLockType[] lockTypeValues = BlockerLockType.values(); // cache
ThreadBlocker(int typeOrdinal, Object obj) {
this(lockTypeValues[typeOrdinal], obj);
ThreadBlocker(int typeOrdinal, Object obj, Thread owner) {
this(lockTypeValues[typeOrdinal], obj, owner);
}
}
@@ -37,12 +37,33 @@ public class BytecodeDescriptor {
private BytecodeDescriptor() { } // cannot instantiate
/**
* @param loader the class loader in which to look up the types (null means
* bootstrap class loader)
*/
public static List<Class<?>> parseMethod(String bytecodeSignature, ClassLoader loader) {
return parseMethod(bytecodeSignature, 0, bytecodeSignature.length(), loader);
/// Parses and validates a field descriptor string in the {@code loader} context.
///
/// @param descriptor a field descriptor string
/// @param loader the class loader in which to look up the types (null means
/// bootstrap class loader)
/// @throws IllegalArgumentException if the descriptor is invalid
/// @throws TypeNotPresentException if the descriptor is valid, but
/// the class cannot be found by the loader
public static Class<?> parseClass(String descriptor, ClassLoader loader) {
int[] i = {0};
var ret = parseSig(descriptor, i, descriptor.length(), loader);
if (i[0] != descriptor.length() || ret == null) {
parseError("not a class descriptor", descriptor);
}
return ret;
}
/// Parses and validates a method descriptor string in the {@code loader} context.
///
/// @param descriptor a method descriptor string
/// @param loader the class loader in which to look up the types (null means
/// bootstrap class loader)
/// @throws IllegalArgumentException if the descriptor is invalid
/// @throws TypeNotPresentException if a reference type cannot be found by
/// the loader (before the descriptor is found invalid)
public static List<Class<?>> parseMethod(String descriptor, ClassLoader loader) {
return parseMethod(descriptor, 0, descriptor.length(), loader);
}
/**
@@ -77,10 +98,19 @@ public class BytecodeDescriptor {
throw new IllegalArgumentException("bad signature: "+str+": "+msg);
}
/**
* @param loader the class loader in which to look up the types (null means
* bootstrap class loader)
*/
/// Parse a single type in a descriptor. Results can be:
///
/// - A `Class` for successful parsing
/// - `null` for malformed descriptor format
/// - Throwing a [TypeNotPresentException] for valid class name,
/// but class cannot be found
///
/// @param str contains the string to parse
/// @param i cursor for the next token in the string, modified in-place
/// @param end the limit for parsing
/// @param loader the class loader in which to look up the types (null means
/// bootstrap class loader)
///
private static Class<?> parseSig(String str, int[] i, int end, ClassLoader loader) {
if (i[0] == end) return null;
char c = str.charAt(i[0]++);
@@ -107,7 +137,14 @@ public class BytecodeDescriptor {
}
return t;
} else {
return Wrapper.forBasicType(c).primitiveType();
Wrapper w;
try {
w = Wrapper.forBasicType(c);
} catch (IllegalArgumentException ex) {
// Our reporting has better error message
return null;
}
return w.primitiveType();
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2025, 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
@@ -34,12 +34,7 @@ import java.util.function.Supplier;
import jdk.internal.reflect.ConstantPool;
import sun.reflect.generics.parser.SignatureParser;
import sun.reflect.generics.tree.TypeSignature;
import sun.reflect.generics.factory.GenericsFactory;
import sun.reflect.generics.factory.CoreReflectionFactory;
import sun.reflect.generics.visitor.Reifier;
import sun.reflect.generics.scope.ClassScope;
import sun.invoke.util.BytecodeDescriptor;
/**
* Parser for Java programming language annotations. Translates
@@ -429,19 +424,11 @@ public class AnnotationParser {
}
private static Class<?> parseSig(String sig, Class<?> container) {
if (sig.equals("V")) return void.class;
SignatureParser parser = SignatureParser.make();
TypeSignature typeSig = parser.parseTypeSig(sig);
GenericsFactory factory = CoreReflectionFactory.make(container, ClassScope.make(container));
Reifier reify = Reifier.make(factory);
typeSig.accept(reify);
Type result = reify.getResult();
return toClass(result);
}
static Class<?> toClass(Type o) {
if (o instanceof GenericArrayType gat)
return toClass(gat.getGenericComponentType()).arrayType();
return (Class<?>) o;
try {
return BytecodeDescriptor.parseClass(sig, container.getClassLoader());
} catch (IllegalArgumentException ex) {
throw new GenericSignatureFormatError(ex.getMessage());
}
}
/**
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2025, 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,7 +41,7 @@
/* We should also include jdk_util.h here, for the prototype of JDK_Canonicalize.
This isn't possible though because canonicalize_md.c is as well used in
different contexts within Oracle.
*/
*/
#include "io_util_md.h"
/* Copy bytes to dst, not going past dend; return dst + number of bytes copied,
@@ -139,7 +139,8 @@ lastErrorReportable()
|| (errval == ERROR_ACCESS_DENIED)
|| (errval == ERROR_NETWORK_UNREACHABLE)
|| (errval == ERROR_NETWORK_ACCESS_DENIED)
|| (errval == ERROR_NO_MORE_FILES)) {
|| (errval == ERROR_NO_MORE_FILES)
|| (errval == ERROR_NETNAME_DELETED)) {
return 0;
}
return 1;
@@ -183,7 +184,7 @@ wcanonicalize(WCHAR *orig_path, WCHAR *result, int size)
/* Copy prefix, assuming path is absolute */
c = src[0];
if (((c <= L'z' && c >= L'a') || (c <= L'Z' && c >= L'A'))
&& (src[1] == L':') && (src[2] == L'\\')) {
&& (src[1] == L':') && (src[2] == L'\\')) {
/* Drive specifier */
*src = towupper(*src); /* Canonicalize drive letter */
if (!(dst = wcp(dst, dend, L'\0', src, src + 2))) {
@@ -244,9 +245,9 @@ wcanonicalize(WCHAR *orig_path, WCHAR *result, int size)
continue;
} else {
if (!lastErrorReportable()) {
if (!(dst = wcp(dst, dend, L'\0', src, src + wcslen(src)))){
goto err;
}
if (!(dst = wcp(dst, dend, L'\0', src, src + wcslen(src)))){
goto err;
}
break;
} else {
goto err;
@@ -255,7 +256,7 @@ wcanonicalize(WCHAR *orig_path, WCHAR *result, int size)
}
if (dst >= dend) {
errno = ENAMETOOLONG;
errno = ENAMETOOLONG;
goto err;
}
*dst = L'\0';
@@ -366,7 +367,7 @@ JDK_Canonicalize(const char *orig, char *out, int len) {
// Change return value to success.
ret = 0;
finish:
finish:
free(wresult);
free(wpath);
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2025, 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
@@ -457,15 +457,17 @@ static inline void doDrawGlyphsPipe_fillGlyphAndAdvanceBuffers
}
}
if (positions != NULL) {
CGAffineTransform invTx = CGAffineTransformInvert(strike->fFontTx);
CGPoint prev;
prev.x = positions[0];
prev.y = positions[1];
prev = CGPointApplyAffineTransform(prev, invTx);
// <rdar://problem/4294061> take the first point, and move the context to that location
CGContextTranslateCTM(qsdo->cgRef, prev.x, prev.y);
CGAffineTransform invTx = CGAffineTransformInvert(strike->fFontTx);
// for each position, figure out the advance (since CG won't take positions directly)
size_t i;
for (i = 0; i < length - 1; i++)
@@ -476,7 +478,7 @@ static inline void doDrawGlyphsPipe_fillGlyphAndAdvanceBuffers
pt.y = positions[i2+1];
pt = CGPointApplyAffineTransform(pt, invTx);
advances[i].width = pt.x - prev.x;
advances[i].height = -(pt.y - prev.y); // negative to translate to device space
advances[i].height = pt.y - prev.y;
prev.x = pt.x;
prev.y = pt.y;
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2025, 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
@@ -73,8 +73,8 @@ public class OutlineTextRenderer implements TextPipe {
public void drawString(SunGraphics2D g2d, String str, double x, double y) {
if ("".equals(str)) {
return; // TextLayout constructor throws IAE on "".
if (str.length() == 0) {
return;
}
TextLayout tl = new TextLayout(str, g2d.getFont(),
g2d.getFontRenderContext());
@@ -161,24 +161,7 @@ public class Lint {
values = LintCategory.newEmptySet();
} else {
// otherwise, enable on-by-default categories
values = LintCategory.newEmptySet();
Source source = Source.instance(context);
if (source.compareTo(Source.JDK9) >= 0) {
values.add(LintCategory.DEP_ANN);
}
if (Source.Feature.REDUNDANT_STRICTFP.allowedInSource(source)) {
values.add(LintCategory.STRICTFP);
}
values.add(LintCategory.REQUIRES_TRANSITIVE_AUTOMATIC);
values.add(LintCategory.OPENS);
values.add(LintCategory.MODULE);
values.add(LintCategory.REMOVAL);
if (!options.isSet(Option.PREVIEW)) {
values.add(LintCategory.PREVIEW);
}
values.add(LintCategory.IDENTITY);
values.add(LintCategory.INCUBATING);
values = getDefaults();
}
// Look for specific overrides
@@ -193,6 +176,23 @@ public class Lint {
suppressedValues = LintCategory.newEmptySet();
}
// Obtain the set of on-by-default categories. Note that for a few categories,
// whether the category is on-by-default depends on other compiler options.
private EnumSet<LintCategory> getDefaults() {
EnumSet<LintCategory> defaults = LintCategory.newEmptySet();
Source source = Source.instance(context);
Stream.of(LintCategory.values())
.filter(lc ->
switch (lc) {
case DEP_ANN -> source.compareTo(Source.JDK9) >= 0;
case STRICTFP -> Source.Feature.REDUNDANT_STRICTFP.allowedInSource(source);
case PREVIEW -> !options.isSet(Option.PREVIEW);
default -> lc.enabledByDefault;
})
.forEach(defaults::add);
return defaults;
}
@Override
public String toString() {
initializeRootIfNeeded();
@@ -221,7 +221,7 @@ public class Lint {
* <p>
* This category is not supported by {@code @SuppressWarnings}.
*/
CLASSFILE("classfile", false),
CLASSFILE("classfile", false, false),
/**
* Warn about "dangling" documentation comments,
@@ -238,7 +238,7 @@ public class Lint {
* Warn about items which are documented with an {@code @deprecated} JavaDoc
* comment, but which do not have {@code @Deprecated} annotation.
*/
DEP_ANN("dep-ann"),
DEP_ANN("dep-ann", true, true),
/**
* Warn about division by constant integer 0.
@@ -268,7 +268,7 @@ public class Lint {
/**
* Warn about uses of @ValueBased classes where an identity class is expected.
*/
IDENTITY("identity", true, "synchronization"),
IDENTITY("identity", true, true, "synchronization"),
/**
* Warn about use of incubating modules.
@@ -276,7 +276,7 @@ public class Lint {
* <p>
* This category is not supported by {@code @SuppressWarnings}.
*/
INCUBATING("incubating", false),
INCUBATING("incubating", false, true),
/**
* Warn about compiler possible lossy conversions.
@@ -291,12 +291,12 @@ public class Lint {
/**
* Warn about module system related issues.
*/
MODULE("module"),
MODULE("module", true, true),
/**
* Warn about issues regarding module opens.
*/
OPENS("opens"),
OPENS("opens", true, true),
/**
* Warn about issues relating to use of command line options.
@@ -304,7 +304,7 @@ public class Lint {
* <p>
* This category is not supported by {@code @SuppressWarnings}.
*/
OPTIONS("options", false),
OPTIONS("options", false, false),
/**
* Warn when any output file is written to more than once.
@@ -312,7 +312,7 @@ public class Lint {
* <p>
* This category is not supported by {@code @SuppressWarnings}.
*/
OUTPUT_FILE_CLASH("output-file-clash", false),
OUTPUT_FILE_CLASH("output-file-clash", false, false),
/**
* Warn about issues regarding method overloads.
@@ -330,12 +330,15 @@ public class Lint {
* <p>
* This category is not supported by {@code @SuppressWarnings}.
*/
PATH("path", false),
PATH("path", false, false),
/**
* Warn about issues regarding annotation processing.
*
* <p>
* This category is not supported by {@code @SuppressWarnings}.
*/
PROCESSING("processing"),
PROCESSING("processing", false, false),
/**
* Warn about unchecked operations on raw types.
@@ -345,7 +348,7 @@ public class Lint {
/**
* Warn about use of deprecated-for-removal items.
*/
REMOVAL("removal"),
REMOVAL("removal", true, true),
/**
* Warn about use of automatic modules in the requires clauses.
@@ -355,7 +358,7 @@ public class Lint {
/**
* Warn about automatic modules in requires transitive.
*/
REQUIRES_TRANSITIVE_AUTOMATIC("requires-transitive-automatic"),
REQUIRES_TRANSITIVE_AUTOMATIC("requires-transitive-automatic", true, true),
/**
* Warn about Serializable classes that do not provide a serial version ID.
@@ -370,7 +373,7 @@ public class Lint {
/**
* Warn about unnecessary uses of the strictfp modifier
*/
STRICTFP("strictfp"),
STRICTFP("strictfp", true, true),
/**
* Warn about issues relating to use of text blocks
@@ -400,7 +403,7 @@ public class Lint {
/**
* Warn about use of preview features.
*/
PREVIEW("preview"),
PREVIEW("preview", true, true),
/**
* Warn about use of restricted methods.
@@ -408,12 +411,13 @@ public class Lint {
RESTRICTED("restricted");
LintCategory(String option) {
this(option, true);
this(option, true, false);
}
LintCategory(String option, boolean annotationSuppression, String... aliases) {
LintCategory(String option, boolean annotationSuppression, boolean enabledByDefault, String... aliases) {
this.option = option;
this.annotationSuppression = annotationSuppression;
this.enabledByDefault = enabledByDefault;
ArrayList<String> optionList = new ArrayList<>(1 + aliases.length);
optionList.add(option);
Collections.addAll(optionList, aliases);
@@ -450,6 +454,12 @@ public class Lint {
/** Does this category support being suppressed by the {@code @SuppressWarnings} annotation? */
public final boolean annotationSuppression;
/**
* Is this category included in the default set of enabled lint categories?
* Note that for some categories, command line options can alter this at runtime.
*/
public final boolean enabledByDefault;
}
/**
@@ -39,10 +39,12 @@ import java.util.Comparator;
import java.util.EnumSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.ServiceLoader;
import java.util.Set;
import java.util.StringJoiner;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@@ -484,24 +486,54 @@ public enum Option {
},
HELP_LINT("--help-lint", "opt.help.lint", EXTENDED, INFO) {
private final String LINT_KEY_FORMAT = SMALL_INDENT + SMALL_INDENT + "%-" +
private final String HELP_INDENT = SMALL_INDENT + SMALL_INDENT;
private final String LINT_KEY_FORMAT = HELP_INDENT + "%-" +
(DEFAULT_SYNOPSIS_WIDTH - LARGE_INDENT.length()) + "s %s";
@Override
public void process(OptionHelper helper, String option) throws InvalidValueException {
Log log = helper.getLog();
// Print header
log.printRawLines(WriterKind.STDOUT, log.localize(PrefixKind.JAVAC, "opt.help.lint.header"));
// Print "all" option
log.printRawLines(WriterKind.STDOUT,
String.format(LINT_KEY_FORMAT,
LINT_CUSTOM_ALL,
log.localize(PrefixKind.JAVAC, "opt.Xlint.all")));
LintCategory.options().forEach(ident -> log.printRawLines(WriterKind.STDOUT,
String.format(LINT_KEY_FORMAT,
ident,
log.localize(PrefixKind.JAVAC, "opt.Xlint.desc." + ident))));
// Alphabetize all the category names and their aliases together, and then list them with their descriptions
TreeMap<String, String> keyMap = new TreeMap<>();
Stream.of(LintCategory.values()).forEach(lc ->
lc.optionList.stream()
.forEach(key -> keyMap.put(key,
String.format(LINT_KEY_FORMAT,
key,
key.equals(lc.option) ?
log.localize(PrefixKind.JAVAC, "opt.Xlint.desc." + key) :
log.localize(PrefixKind.JAVAC, "opt.Xlint.alias.of", lc.option, key)))));
keyMap.values().forEach(desc -> log.printRawLines(WriterKind.STDOUT, desc));
// Print "none" option
log.printRawLines(WriterKind.STDOUT,
String.format(LINT_KEY_FORMAT,
LINT_CUSTOM_NONE,
log.localize(PrefixKind.JAVAC, "opt.Xlint.none")));
// Show which lint categories are enabled by default
log.printRawLines(WriterKind.STDOUT, log.localize(PrefixKind.JAVAC, "opt.help.lint.enabled.by.default"));
String defaults = Stream.of(LintCategory.values())
.filter(lc -> lc.enabledByDefault)
.map(lc -> lc.option)
.sorted()
.collect(Collectors.joining(", "));
log.printRawLines(WriterKind.STDOUT,
String.format("%s%s.", HELP_INDENT, defaults));
// Add trailing blurb about aliases
List<String> aliasExample = LintCategory.IDENTITY.optionList;
log.printRawLines(WriterKind.STDOUT,
log.localize(PrefixKind.JAVAC, "opt.help.lint.footer", aliasExample.get(0), aliasExample.get(1)));
super.process(helper, option);
}
},
@@ -168,18 +168,20 @@ javac.opt.Xbootclasspath.p=\
javac.opt.Xbootclasspath.a=\
Append to the bootstrap class path
javac.opt.Xlint=\
Enable recommended warning categories
Enable recommended lint warning categories. In this release, all\n\
available lint warning categories are recommended.
javac.opt.Xlint.all=\
Enable all warning categories
Enable all lint warning categories
javac.opt.Xlint.none=\
Disable all warning categories
Disable all lint warning categories
#L10N: do not localize: -Xlint
javac.opt.arg.Xlint=\
<key>(,<key>)*
javac.opt.Xlint.custom=\
Warning categories to enable or disable, separated by comma.\n\
Precede a key by ''-'' to disable the specified warning.\n\
Use --help-lint to see the supported keys.
Lint warning categories to enable or disable, separated by comma.\n\
Precede a key by ''-'' to disable the specified category. Use\n\
''--help-lint'' to show supported keys and which categories are\n\
enabled by default.
javac.opt.Xlint.desc.auxiliaryclass=\
Warn about an auxiliary class that is hidden in a source file, and is used from other files.
@@ -291,16 +293,13 @@ javac.opt.Xlint.desc.preview=\
javac.opt.Xlint.desc.restricted=\
Warn about use of restricted methods.
# L10N: do not localize: identity synchronization
javac.opt.Xlint.desc.synchronization=\
Warn about synchronization attempts on instances of value-based classes.\n\
\ This key is a deprecated alias for ''identity'', which has the same uses and\n\
\ effects. Users are encouraged to use the ''identity'' category for all future\n\
\ and existing uses of ''synchronization''.
javac.opt.Xlint.desc.identity=\
Warn about uses of value-based classes where an identity class is expected.
javac.opt.Xlint.alias.of=\
Deprecated alias for ''{0}'' with an identical effect. Users are encouraged to use\n\
\ ''{0}'' instead of ''{1}'' for all current and future uses.
javac.opt.Xdoclint=\
Enable recommended checks for problems in javadoc comments
# L10N: do not localize: all none
@@ -334,6 +333,11 @@ javac.opt.help.lint=\
Print the supported keys for -Xlint
javac.opt.help.lint.header=\
The supported keys for -Xlint are:
javac.opt.help.lint.enabled.by.default=\
The following lint warning categories are enabled by default:
javac.opt.help.lint.footer=\
Categories and their aliases can be used interchangeably; for example, the flag\n\
''-Xlint:{0},{1}'' would be redundant.
javac.opt.print=\
Print out a textual representation of specified types
javac.opt.printRounds=\
@@ -346,8 +350,9 @@ javac.opt.userpathsfirst=\
javac.opt.prefer=\
Specify which file to read when both a source file and class file\n\
are found for an implicitly compiled class
# L10N: do not localize: ''preview''
javac.opt.preview=\
Enable preview language features.\n\
Enable preview language features. Also disables the ''preview'' lint category.\n\
To be used in conjunction with either -source or --release.
javac.opt.AT=\
Read options and filenames from file
+25 -10
View File
@@ -141,7 +141,8 @@ import javax.tools.StandardLocation;
*
* In addition, <em>javac</em> also supports other strings that can be used
* to suppress other kinds of warnings. The following table lists all the
* strings that can be used with {@code @SuppressWarnings}.
* strings that are recognized by <em>javac</em> in {@code @SuppressWarnings}
* annotations. Unrecognized strings are ignored.
*
* <table class="striped">
* <caption>Strings supported by {@code SuppressWarnings}</caption>
@@ -152,7 +153,6 @@ import javax.tools.StandardLocation;
* <tr><th scope="row">{@code auxiliaryclass} <td>an auxiliary class that is hidden in a source file, and is used
* from other files
* <tr><th scope="row">{@code cast} <td>use of unnecessary casts
* <tr><th scope="row">{@code classfile} <td>issues related to classfile contents
* <tr><th scope="row">{@code dangling-doc-comments} <td>issues related to "dangling" documentation comments,
* not attached to a declaration
* <tr><th scope="row">{@code deprecation} <td>use of deprecated items
@@ -165,7 +165,6 @@ import javax.tools.StandardLocation;
* the next
* <tr><th scope="row">{@code finally} <td>{@code finally} clauses that do not terminate normally
* <tr><th scope="row">{@code identity} <td>use of a value-based class where an identity class is expected
* <tr><th scope="row">{@code incubating} <td>use of incubating modules
* <tr><th scope="row">{@code lossy-conversions} <td>possible lossy conversions in compound assignment
* <tr><th scope="row">{@code missing-explicit-ctor} <td>missing explicit constructors in public and protected classes
* in exported packages
@@ -173,13 +172,12 @@ import javax.tools.StandardLocation;
* <tr><th scope="row">{@code opens} <td>issues regarding module opens
* <tr><th scope="row">{@code overloads} <td>issues regarding method overloads
* <tr><th scope="row">{@code overrides} <td>issues regarding method overrides
* <tr><th scope="row">{@code path} <td>invalid path elements on the command line
* <tr><th scope="row">{@code preview} <td>use of preview language features
* <tr><th scope="row">{@code rawtypes} <td>use of raw types
* <tr><th scope="row">{@code removal} <td>use of API that has been marked for removal
* <tr><th scope="row">{@code restricted} <td>use of restricted methods
* <tr><th scope="row">{@code requires-automatic} <td>use of automatic modules in the {@code requires} clauses
* <tr><th scope="row">{@code requires-transitive-automatic} <td>automatic modules in {@code requires transitive}
* <tr><th scope="row">{@code restricted} <td>use of restricted methods
* <tr><th scope="row">{@code serial} <td>{@link java.base/java.io.Serializable Serializable} classes
* that do not have a {@code serialVersionUID} field, or other
* suspect declarations in {@code Serializable} and
@@ -187,11 +185,9 @@ import javax.tools.StandardLocation;
* and interfaces
* <tr><th scope="row">{@code static} <td>accessing a static member using an instance
* <tr><th scope="row">{@code strictfp} <td>unnecessary use of the {@code strictfp} modifier
* <tr><th scope="row">{@code synchronization} <td>synchronization attempts on instances of value-based classes;
* this key is a deprecated alias for {@code identity}, which has
* the same uses and effects. Users are encouraged to use the
* {@code identity} category for all future and existing uses of
* {@code synchronization}
* <tr><th scope="row">{@code synchronization} <td>deprecated alias for {@code identity} with an identical effect.
* Users are encouraged to use {@code identity} instead of
* {@code synchronization} for all current and future uses.
* <tr><th scope="row">{@code text-blocks} <td>inconsistent white space characters in text block indentation
* <tr><th scope="row">{@code this-escape} <td>superclass constructor leaking {@code this} before subclass initialized
* <tr><th scope="row">{@code try} <td>issues relating to use of {@code try} blocks
@@ -207,6 +203,25 @@ import javax.tools.StandardLocation;
* </tbody>
* </table>
*
* All of the non-{@code docllint:} strings listed above may also be used with the {@code -Xlint} command line flag.
* The {@code -Xlint} flag also supports these strings not supported by {@code @SuppressWarnings}:
*
* <table class="striped">
* <caption>Strings supported by {@code -Xlint} but not {@code SuppressWarnings}</caption>
* <thead>
* <tr><th>String<th>Warnings Related To ...
* </thead>
* <tbody>
* <tr><th scope="row">{@code classfile} <td>issues related to classfile contents
* <tr><th scope="row">{@code incubating} <td>use of incubating modules
* <tr><th scope="row">{@code options} <td>issues relating to use of command line options
* <tr><th scope="row">{@code output-file-clash} <td>output files being overwritten due to filename clashes
* <tr><th scope="row">{@code path} <td>invalid path elements on the command line
* <tr><th scope="row">{@code processing} <td>issues regarding annotation processing
* <tr><th scope="row">{@code restricted} <td>use of restricted methods
* </tbody>
* </table>
*
* @toolGuide javac
*
* @provides java.util.spi.ToolProvider
+15 -12
View File
@@ -208,8 +208,8 @@ file system locations may be directories, JAR files or JMOD files.
`-deprecation` option is shorthand for `-Xlint:deprecation`.
<a id="option-enable-preview">`--enable-preview`</a>
: Enables preview language features. Used in conjunction with either
[`-source`](#option-source) or [`--release`](#option-release).
: Enables preview language features. Also disables the `preview` lint category.
Used in conjunction with either [`-source`](#option-source) or [`--release`](#option-release).
<a id="option-encoding">`-encoding` *encoding*</a>
: Specifies character encoding used by source files, such as EUC-JP and
@@ -557,11 +557,11 @@ file system locations may be directories, JAR files or JMOD files.
section of the `javadoc` command documentation.
<a id="option-Xlint">`-Xlint`</a>
: Enables all recommended warnings. In this release, enabling all available
warnings is recommended.
: Enables recommended lint warning categories. In this release, all available
lint warning categories are recommended.
<a id="option-Xlint-custom">`-Xlint:`\[`-`\]*key*(`,`\[`-`\]*key*)\*</a>
: Enables and/or disables warning categories using the one or more of the keys described
: Enables and/or disables lint warning categories using the one or more of the keys described
below separated by commas. The keys `all` and `none` enable or disable all categories
(respectively); other keys enable the corresponding category, or disable it if preceded
by a hyphen (`-`).
@@ -648,10 +648,9 @@ file system locations may be directories, JAR files or JMOD files.
- `strictfp`: Warns about unnecessary use of the `strictfp` modifier.
- `synchronization`: Warns about synchronization attempts on instances
of value-based classes. This key is a deprecated alias for `identity`,
which has the same uses and effects. Users are encouraged to use the
`identity` category for all future and existing uses of `synchronization`.
- `synchronization`: Deprecated alias for `identity` with an identical
effect. Users are encouraged to use `identity` instead of `synchronization`
for all current and future uses.
- `text-blocks`: Warns about inconsistent white space characters in text
block indentation.
@@ -667,9 +666,13 @@ file system locations may be directories, JAR files or JMOD files.
- `none`: Disables all warning categories.
With the exception of `all` and `none`, the keys can be used with
the `@SuppressWarnings` annotation to suppress warnings in a part
of the source code being compiled.
The keys listed above may be used in `@SuppressWarnings` annotations to suppress
warnings within the annotated declaration, with the exception of: `all`, `none`,
`classfile`, `incubating`, `options`, `output-file-clash`, `processing`, and `path`.
By default, the following lint warning categories are enabled: `dep-ann`, `identity`,
`incubating`, `module`, `opens`, `preview`, `removal`, `requires-transitive-automatic`,
and `strictfp`.
See [Examples of Using -Xlint keys].
@@ -1,164 +0,0 @@
/*
* Copyright (c) 2003, 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 sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.runtime.*;
import sun.jvm.hotspot.tools.*;
import sun.jvm.hotspot.utilities.*;
/**
We don't run any of the "standard" SA command line tools for sanity
check. This is because the standard tools print addresses in hex
which could change legally. Also, textual comparison of output may
not match because of other reasons as well. This tool checks
validity of threads and frames logically. This class has reference
frame names from "known" threads. The debuggee is assumed to run
"LibprocTest.java".
*/
public class LibprocClient extends Tool {
public void run() {
// try to get VM version and check
String version = VM.getVM().getVMRelease();
Assert.that(version.startsWith("1.5"), "1.5 expected");
// try getting threads
Threads threads = VM.getVM().getThreads();
boolean mainTested = false;
// check frames of each thread
for (JavaThread cur = threads.first(); cur != null; cur = cur.next()) {
if (cur.isJavaThread()) {
String name = cur.getThreadName();
// testing of basic frame walking for all threads
for (JavaVFrame vf = getLastJavaVFrame(cur); vf != null; vf = vf.javaSender()) {
checkFrame(vf);
}
// special testing for "known" threads. For now, only "main" thread.
if (name.equals("main")) {
checkMainThread(cur);
mainTested = true;
}
}
}
Assert.that(mainTested, "main thread missing");
}
public static void main(String[] args) {
try {
LibprocClient lc = new LibprocClient();
lc.start(args);
lc.getAgent().detach();
System.out.println("\nPASSED\n");
} catch (Exception exp) {
System.out.println("\nFAILED\n");
exp.printStackTrace();
}
}
// -- Internals only below this point
private static JavaVFrame getLastJavaVFrame(JavaThread cur) {
RegisterMap regMap = cur.newRegisterMap(true);
Frame f = cur.getCurrentFrameGuess();
if (f == null) {
System.err.println(" (Unable to get a top most frame)");
return null;
}
VFrame vf = VFrame.newVFrame(f, regMap, cur, true, true);
if (vf == null) {
System.err.println(" (Unable to create vframe for topmost frame guess)");
return null;
}
if (vf.isJavaFrame()) {
return (JavaVFrame) vf;
}
return (JavaVFrame) vf.javaSender();
}
private void checkMethodSignature(Symbol sig) {
SignatureIterator itr = new SignatureIterator(sig) {
public void doBool () {}
public void doChar () {}
public void doFloat () {}
public void doDouble() {}
public void doByte () {}
public void doShort () {}
public void doInt () {}
public void doLong () {}
public void doVoid () {}
public void doObject(int begin, int end) {}
public void doArray (int begin, int end) {}
};
// this will throw RuntimeException for any invalid item in signature.
itr.iterate();
}
private void checkBCI(Method m, int bci) {
if (! m.isNative()) {
byte[] buf = m.getByteCode();
Assert.that(bci >= 0 && bci < buf.length, "invalid bci, not in code range");
if (m.hasLineNumberTable()) {
int lineNum = m.getLineNumberFromBCI(bci);
Assert.that(lineNum >= 0, "expecting non-negative line number");
}
}
}
private void checkMethodHolder(Method method) {
Klass klass = method.getMethodHolder();
Assert.that(klass != null, "expecting non-null instance klass");
}
private void checkFrame(JavaVFrame vf) {
Method method = vf.getMethod();
Assert.that(method != null, "expecting a non-null method here");
Assert.that(method.getName() != null, "expecting non-null method name");
checkMethodHolder(method);
checkMethodSignature(method.getSignature());
checkBCI(method, vf.getBCI());
}
// from the test case LibprocTest.java - in the main thread we
// should see frames as below
private static String[] mainThreadMethods = new String[] {
"java.lang.Object.wait(long)",
"java.lang.Object.wait()",
"LibprocTest.main(java.lang.String[])"
};
private void checkMainThread(JavaThread thread) {
checkFrames(thread, mainThreadMethods);
}
private void checkFrames(JavaThread thread, String[] expectedMethodNames) {
int i = 0;
for (JavaVFrame vf = getLastJavaVFrame(thread); vf != null; vf = vf.javaSender(), i++) {
Method m = vf.getMethod();
Assert.that(m.externalNameAndSignature().equals(expectedMethodNames[i]),
"expected frame missing");
}
}
}
@@ -1,41 +0,0 @@
/*
* Copyright (c) 2003, 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.
*
*/
/**
This is test case run by debuggee for running LibprocClient.java.
*/
public class LibprocTest {
public static void main(String[] args) throws Exception {
String myStr = "";
System.out.println("main start");
synchronized(myStr) {
try {
myStr.wait();
} catch (InterruptedException ee) {
}
}
System.out.println("main end");
}
}
@@ -1,30 +0,0 @@
#
# Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# 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.
#
#
all:
javac LibprocTest.java
javac -classpath ../../build/classes LibprocClient.java
clean:
rm -rf *.class
-42
View File
@@ -1,42 +0,0 @@
#
# Copyright (c) 2007, 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.
#
#
After making any changes to libproc.so, the shell scripts described
below can be run to verify that it does not break Java Serviceability
Agent.
Setup:
You need to have jdk 1.5 installed to run this test. Set environment
variable SA_JAVA to point to the java executable of jdk
1.5. Otherwise, the script picks-up 'java' from PATH.
Running the tests:
run libproctest.sh (32-bit debuggee) and libproctest64.sh (64-bit
debuggee)
Interpreting result:
"PASSED" or "FAILED" is printed in standard output.
@@ -1,66 +0,0 @@
#!/bin/ksh
#
# Copyright (c) 2003, 2020, 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.
#
#
# This script is used to run consistency check of Serviceabilty Agent
# after making any libproc.so changes. Prints "PASSED" or "FAILED" in
# standard output.
usage() {
echo "usage: $0"
echo " set SA_JAVA to be java executable from JDK 1.5"
exit 1
}
STARTDIR=`dirname $0`
if [ "$1" == "-help" ]; then
usage
fi
if [ "x$SA_JAVA" = "x" ]; then
SA_JAVA=java
fi
# create java process with test case
tmp=/tmp/libproctest
rm -f $tmp
$SA_JAVA -classpath $STARTDIR LibprocTest > $tmp &
pid=$!
while [ ! -s $tmp ] ; do
# Kludge alert!
sleep 2
done
# dump core
gcore $pid
kill -9 $pid
# run libproc client
$SA_JAVA -showversion -cp $STARTDIR/../../build/classes::$STARTDIR/../sa.jar:$STARTDIR LibprocClient x core.$pid
# delete core
rm -f core.$pid
@@ -1,65 +0,0 @@
#!/bin/ksh
#
# Copyright (c) 2003, 2020, 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.
#
#
# This script is used to run consistency check of Serviceabilty Agent
# after making any libproc.so changes. Prints "PASSED" or "FAILED" in
# standard output.
usage() {
echo "usage: $0"
echo " set SA_JAVA to be the java executable from JDK 1.5"
exit 1
}
if [ "$1" == "-help" ]; then
usage
fi
if [ "x$SA_JAVA" = "x" ]; then
SA_JAVA=java
fi
STARTDIR=`dirname $0`
# create java process with test case
tmp=/tmp/libproctest
rm -f $tmp
$SA_JAVA -d64 -classpath $STARTDIR LibprocTest > $tmp &
pid=$!
while [ ! -s $tmp ] ; do
# Kludge alert!
sleep 2
done
# dump core
gcore $pid
kill -9 $pid
# run libproc client
$SA_JAVA -d64 -showversion -cp $STARTDIR/../../build/classes::$STARTDIR/../sa.jar:$STARTDIR LibprocClient x core.$pid
# delete core
rm -f core.$pid
@@ -222,6 +222,16 @@ public final class Float16
*/
public static final int BYTES = SIZE / Byte.SIZE;
/**
* The overflow threshold (for round to nearest) is MAX_VALUE + 1/2 ulp.
*/
private static final double OVERFLOW_THRESH = 0x1.ffcp15 + 0x0.002p15;
/**
* The underflow threshold (for round to nearest) is MIN_VALUE * 0.5.
*/
private static final double UNDERFLOW_THRESH = 0x1.0p-24d * 0.5d;
/**
* Returns a string representation of the {@code Float16}
* argument.
@@ -340,51 +350,51 @@ public final class Float16
* @param d a {@code double}
*/
public static Float16 valueOf(double d) {
long doppel = Double.doubleToRawLongBits(d);
short sign_bit = (short)((doppel & 0x8000_0000_0000_0000L) >> 48);
if (Double.isNaN(d)) {
// Have existing float code handle any attempts to
// preserve NaN bits.
return valueOf((float)d);
}
long doppel = Double.doubleToRawLongBits(d);
short sign_bit = (short)((doppel & 0x8000_0000_0000_0000L) >> (64 - 16));
double abs_d = Math.abs(d);
// The overflow threshold is binary16 MAX_VALUE + 1/2 ulp
if (abs_d >= (0x1.ffcp15 + 0x0.002p15) ) {
if (abs_d >= OVERFLOW_THRESH) {
// correctly signed infinity
return new Float16((short)(sign_bit | 0x7c00));
}
// Smallest magnitude nonzero representable binary16 value
// is equal to 0x1.0p-24; half-way and smaller rounds to zero.
if (abs_d <= 0x1.0p-24d * 0.5d) { // Covers double zeros and subnormals.
return new Float16(sign_bit); // Positive or negative zero
if (abs_d <= UNDERFLOW_THRESH) { // Covers double zeros and subnormals.
// positive or negative zero
return new Float16(sign_bit);
}
// Dealing with finite values in exponent range of binary16
// (when rounding is done, could still round up)
int exp = Math.getExponent(d);
assert -25 <= exp && exp <= 15;
assert
(MIN_EXPONENT - PRECISION) <= exp &&
exp <= MAX_EXPONENT;
// For binary16 subnormals, beside forcing exp to -15, retain
// the difference expdelta = E_min - exp. This is the excess
// shift value, in addition to 42, to be used in the
// For target format subnormals, beside forcing exp to
// MIN_EXPONENT-1, retain the difference expdelta = E_min -
// exp. This is the excess shift value, in addition to the
// difference in precision bits, to be used in the
// computations below. Further the (hidden) msb with value 1
// in d must be involved as well.
int expdelta = 0;
long msb = 0x0000_0000_0000_0000L;
if (exp < -14) {
expdelta = -14 - exp; // FIXME?
exp = -15;
msb = 0x0010_0000_0000_0000L; // should be 0x0020_... ?
if (exp < MIN_EXPONENT) {
expdelta = MIN_EXPONENT - exp;
exp = MIN_EXPONENT - 1;
msb = 0x0010_0000_0000_0000L;
}
long f_signif_bits = doppel & 0x000f_ffff_ffff_ffffL | msb;
int PRECISION_DIFF = Double.PRECISION - PRECISION; // 42
// Significand bits as if using rounding to zero (truncation).
short signif_bits = (short)(f_signif_bits >> (42 + expdelta));
short signif_bits = (short)(f_signif_bits >> (PRECISION_DIFF + expdelta));
// For round to nearest even, determining whether or not to
// round up (in magnitude) is a function of the least
@@ -399,9 +409,9 @@ public final class Float16
// 1 1 1
// See "Computer Arithmetic Algorithms," Koren, Table 4.9
long lsb = f_signif_bits & (1L << 42 + expdelta);
long round = f_signif_bits & (1L << 41 + expdelta);
long sticky = f_signif_bits & ((1L << 41 + expdelta) - 1);
long lsb = f_signif_bits & (1L << (PRECISION_DIFF + expdelta));
long round = f_signif_bits & (1L << (PRECISION_DIFF - 1) + expdelta);
long sticky = f_signif_bits & ((1L << (PRECISION_DIFF - 1) + expdelta) - 1);
if (round != 0 && ((lsb | sticky) != 0 )) {
signif_bits++;
@@ -412,7 +422,9 @@ public final class Float16
// to implement a carry out from rounding the significand.
assert (0xf800 & signif_bits) == 0x0;
return new Float16((short)(sign_bit | ( ((exp + 15) << 10) + signif_bits ) ));
// Exponent bias adjust in the representation is equal to MAX_EXPONENT.
return new Float16((short)(sign_bit |
( ((exp + MAX_EXPONENT) << (PRECISION - 1)) + signif_bits ) ));
}
/**
@@ -237,7 +237,7 @@ final class AppImageSigner {
final var codesignExecutableFile = Codesign.build(signingCfg::toCodesignArgs).quiet(true).create().asConsumer();
final var codesignFile = Codesign.build(signingCfgWithoutEntitlements::toCodesignArgs).quiet(true).create().asConsumer();
final var codesignDir = Codesign.build(signingCfgWithoutEntitlements::toCodesignArgs).force(true).create().asConsumer();
final var codesignDir = Codesign.build(signingCfg::toCodesignArgs).force(true).create().asConsumer();
return new Codesigners(codesignFile, codesignExecutableFile, codesignDir);
}
@@ -24,21 +24,141 @@
*/
package jdk.jpackage.internal.util;
import static jdk.jpackage.internal.util.function.ThrowingSupplier.toSupplier;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Stream;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import jdk.jpackage.internal.util.function.ThrowingSupplier;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
/**
* Property list (plist) file reader.
*/
public final class PListReader {
public record Raw(String value, Type type) {
public enum Type {
STRING,
BOOLEAN,
REAL,
INTEGER,
DATE,
DATA;
private static Optional<Type> fromElementName(String name) {
switch (name) {
case "string" -> {
return Optional.of(STRING);
}
case "true" -> {
return Optional.of(BOOLEAN);
}
case "false" -> {
return Optional.of(BOOLEAN);
}
case "real" -> {
return Optional.of(REAL);
}
case "integer" -> {
return Optional.of(INTEGER);
}
case "date" -> {
return Optional.of(DATE);
}
case "data" -> {
return Optional.of(DATA);
}
default -> {
return Optional.empty();
}
}
}
}
public Raw {
Objects.requireNonNull(value);
Objects.requireNonNull(type);
}
private static Optional<Raw> tryCreate(Element e) {
return Type.fromElementName(e.getNodeName()).map(type -> {
if (type == Type.BOOLEAN) {
if ("true".equals(e.getNodeName())) {
return new Raw(Boolean.TRUE.toString(), type);
} else {
return new Raw(Boolean.FALSE.toString(), type);
}
} else {
return new Raw(e.getTextContent(), type);
}
});
}
}
/**
* Returns the contents of the the underlying "dict" element as a Map.
* <p>
* The keys in the returned map are names of the properties.
* <p>
* Values of nested "dict" properties are stored as {@code Map<String, Object>}
* or {@code PListReader} objects depending on the value of the
* {@code fetchDictionaries} parameter.
* <p>
* Values of "array" properties are stored as {@code List<Object>} objects.
* <p>
* Values of other properties are stored as {@code Raw} objects.
*
* @param fetchDictionaries controls the type of objects of nested "dict"
* elements. If the value is {@code true},
* {@code Map<String, Object>} type is used, and
* {@code PListReader} type otherwise.
* @return the contents of the the underlying "dict" element as a Map
*/
public Map<String, Object> toMap(boolean fetchDictionaries) {
Map<String, Object> reply = new HashMap<>();
var nodes = root.getChildNodes();
for (int i = 0; i != nodes.getLength(); i++) {
if (nodes.item(i) instanceof Element e) {
tryCreateValue(e, fetchDictionaries).ifPresent(value -> {
final var query = "preceding-sibling::*[1]";
Optional.ofNullable(toSupplier(() -> {
return (Node) XPathSingleton.INSTANCE.evaluate(query, e, XPathConstants.NODE);
}).get()).ifPresent(n -> {
if ("key".equals(n.getNodeName())) {
var keyName = n.getTextContent();
reply.putIfAbsent(keyName, value);
}
});
});
}
}
return reply;
}
/**
* Returns the value of the given string property in the underlying "dict"
* element.
*
* @param keyName the name of a string property whose value to query
* @return the value of the string property with the specified name in the
* underlying "dict" element
* @throws NoSuchElementException if there is no string property with the given
* name in the underlying "dict" element
*/
public String queryValue(String keyName) {
final var node = getNode(keyName);
switch (node.getNodeName()) {
@@ -51,6 +171,38 @@ public final class PListReader {
}
}
/**
* Returns the value of the given "dict" property in the underlying "dict"
* element.
*
* @param keyName the name of a "dict" property whose value to query
* @return the value of the "dict" property with the specified name in the
* underlying "dict" element
* @throws NoSuchElementException if there is no "dict" property with the given
* name in the underlying "dict" element
*/
public PListReader queryDictValue(String keyName) {
final var node = getNode(keyName);
switch (node.getNodeName()) {
case "dict" -> {
return new PListReader(node);
}
default -> {
throw new NoSuchElementException();
}
}
}
/**
* Returns the value of the given boolean property in the underlying "dict"
* element.
*
* @param keyName the name of a boolean property whose value to query
* @return the value of the boolean property with the specified name in the
* underlying "dict" element
* @throws NoSuchElementException if there is no string property with the given
* name in the underlying "dict" element
*/
public boolean queryBoolValue(String keyName) {
final var node = getNode(keyName);
switch (node.getNodeName()) {
@@ -66,13 +218,58 @@ public final class PListReader {
}
}
public List<String> queryArrayValue(String keyName) {
/**
* Returns the value of the given array property in the underlying "dict"
* element as a list of strings.
* <p>
* Processes the result of calling {@link #queryArrayValue(String)} on the
* specified property name by filtering {@link Raw} instances of type
* {@link Raw.Type#STRING}.
*
* @param keyName the name of an array property whose value to query
* @return the value of the array property with the specified name in the
* underlying "dict" element
* @throws NoSuchElementException if there is no array property with the given
* name in the underlying "dict" element
*/
public List<String> queryStringArrayValue(String keyName) {
return queryArrayValue(keyName, false).map(v -> {
if (v instanceof Raw r) {
if (r.type() == Raw.Type.STRING) {
return r.value();
}
}
return (String)null;
}).filter(Objects::nonNull).toList();
}
/**
* Returns the value of the given array property in the underlying "dict"
* element as a stream of {@link Object}-s.
* <p>
* Values of "dict" array items are stored as {@code Map<String, Object>} or
* {@code PListReader} objects depending on the value of the
* {@code fetchDictionaries} parameter.
* <p>
* Values of "array" array items are stored as {@code List<Object>} objects.
* <p>
* Values of other types are stored as {@code Raw} objects.
*
* @param keyName the name of an array property whose value to query
* @param fetchDictionaries controls the type of objects of "dict" elements. If
* the value is {@code true},
* {@code Map<String, Object>} type is used, and
* {@code PListReader} type otherwise.
* @return the value of the array property with the specified name in the
* underlying "dict" element
* @throws NoSuchElementException if there is no array key with the given name
* in the underlying "dict" element
*/
public Stream<Object> queryArrayValue(String keyName, boolean fetchDictionaries) {
final var node = getNode(keyName);
switch (node.getNodeName()) {
case "array" -> {
return XmlUtils.toStream(node.getChildNodes()).filter(n -> {
return n.getNodeName().equals("string");
}).map(Node::getTextContent).toList();
return readArray(node, fetchDictionaries);
}
default -> {
throw new NoSuchElementException();
@@ -80,21 +277,75 @@ public final class PListReader {
}
}
public PListReader(Node doc) {
this.root = Objects.requireNonNull(doc);
/**
* Creates plist reader from the given node.
* <p>
* If the specified node is an element with the name "dict", the reader is bound
* to the specified node; otherwise, it is bound to the {@code /plist/dict}
* element in the document.
*
* @param node the node
* @throws NoSuchElementException if the specified node is not an element with
* name "dict" and there is no
* {@code /plist/dict} node in the document
*/
public PListReader(Node node) {
Objects.requireNonNull(node);
if (node.getNodeName().equals("dict")) {
this.root = node;
} else {
this.root = Optional.ofNullable(toSupplier(() -> {
return (Node) XPathSingleton.INSTANCE.evaluate("/plist[1]/dict[1]", node, XPathConstants.NODE);
}).get()).orElseThrow(NoSuchElementException::new);
}
}
public PListReader(byte[] xmlData) throws ParserConfigurationException, SAXException, IOException {
this(XmlUtils.initDocumentBuilder().parse(new ByteArrayInputStream(xmlData)));
}
private Optional<?> tryCreateValue(Element e, boolean fetchDictionaries) {
switch (e.getNodeName()) {
case "dict" -> {
var plistReader = new PListReader(e);
if (fetchDictionaries) {
return Optional.of(plistReader.toMap(fetchDictionaries));
} else {
return Optional.of(plistReader);
}
}
case "array" -> {
return Optional.of(readArray(e, fetchDictionaries).toList());
}
default -> {
return Raw.tryCreate(e);
}
}
}
private Stream<Object> readArray(Node node, boolean fetchDictionaries) {
return XmlUtils.toStream(node.getChildNodes()).map(n -> {
if (n instanceof Element e) {
return tryCreateValue(e, fetchDictionaries);
} else {
return Optional.<Raw>empty();
}
}).filter(Optional::isPresent).map(Optional::get);
}
private Node getNode(String keyName) {
final var xPath = XPathFactory.newInstance().newXPath();
final var query = String.format("//*[preceding-sibling::key = \"%s\"][1]", keyName);
return Optional.ofNullable(ThrowingSupplier.toSupplier(() -> {
return (Node) xPath.evaluate(query, root, XPathConstants.NODE);
Objects.requireNonNull(keyName);
final var query = String.format("*[preceding-sibling::key = \"%s\"][1]", keyName);
return Optional.ofNullable(toSupplier(() -> {
return (Node) XPathSingleton.INSTANCE.evaluate(query, root, XPathConstants.NODE);
}).get()).orElseThrow(NoSuchElementException::new);
}
private static final class XPathSingleton {
private static final XPath INSTANCE = XPathFactory.newInstance().newXPath();
}
private final Node root;
}
@@ -2303,7 +2303,8 @@ class SourceCodeAnalysisImpl extends SourceCodeAnalysis {
//if an index exists for the given entry, the existing index is kept unless the timestamp is modified
private ClassIndex indexForPath(Path path) {
if (!Files.isDirectory(path)) {
if (Files.exists(path)) {
if (Files.exists(path) &&
!isJRTMarkerFile(path)) { //don't directly index lib/modules
return PATH_TO_INDEX.compute(path, (p, index) -> {
try {
long lastModified = Files.getLastModifiedTime(p).toMillis();
@@ -2334,6 +2335,10 @@ class SourceCodeAnalysisImpl extends SourceCodeAnalysis {
}
}
private static boolean isJRTMarkerFile(Path path) {
return path.equals(Paths.get(System.getProperty("java.home"), "lib", "modules"));
}
//create an index based on the content of the given dirs; the original JavaFileManager entry is originalPath.
private ClassIndex doIndex(long timestamp, Path originalPath, Iterable<? extends Path> dirs) {
Set<String> packages = new HashSet<>();
@@ -78,6 +78,10 @@
"description": "The blocker object responsible for the thread parking."
}
},
"owner": {
"type": "string",
"description": "The thread identifier of the owner when the parkBlocker is an AbstractOwnableSynchronizer."
}
"required": [
"object"
]
@@ -115,9 +119,9 @@
"items": {
"type": [
"string",
null
"null"
],
"description": "The object for which the monitor is owned by the thread, null if eliminated"
"description": "The object for which the monitor is owned by the thread, null if eliminated."
}
}
},
@@ -25,7 +25,6 @@
# Bugs
serviceability/AsyncGetCallTrace/MyPackage/ASGCTBaseTest.java 8308026 generic-all
serviceability/jvmti/GetThreadListStackTraces/OneGetThreadListStackTraces.java 8308027 generic-all
serviceability/jvmti/Heap/IterateHeapWithEscapeAnalysisEnabled.java 8264699 generic-all
vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2manyDiff_a/TestDescription.java 8308367 generic-all
@@ -0,0 +1,66 @@
/*
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8367967
* @summary Ensure ModI/LNode::Value is monotonic with potential division by 0
* @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:CompileOnly=compiler.ccp.TestModValueMonotonic::test*
* -XX:+StressCCP -XX:RepeatCompilation=100 -Xcomp compiler.ccp.TestModValueMonotonic
* @run main compiler.ccp.TestModValueMonotonic
*/
package compiler.ccp;
public class TestModValueMonotonic {
static int iFld;
static long lFld;
static int limit = 1000;
static boolean flag;
public static void main(String[] args) {
testInt();
testLong();
}
static void testInt() {
int zero = 0;
// Make sure loop is not counted such that it is not removed. Created a more complex graph for CCP.
for (int i = 1; i < limit; i*=4) {
zero = 34;
}
int three = flag ? 0 : 3;
iFld = three % zero; // phi[0..3] % phi[0..34]
}
static void testLong() {
long zero = 0;
// Make sure loop is not counted such that it is not removed. Created a more complex graph for CCP.
for (int i = 1; i < limit; i*=4) {
zero = 34;
}
long three = flag ? 0 : 3;
lFld = three % zero; // phi[0..3] % phi[0..34]
}
}
@@ -0,0 +1,207 @@
/*
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 8364305
* @summary Test scalar float/double to integral cast
* @requires vm.compiler2.enabled
* @library /test/lib /
* @run main/othervm/native compiler.floatingpoint.ScalarFPtoIntCastTest
*/
package compiler.floatingpoint;
import compiler.lib.ir_framework.*;
import compiler.lib.generators.Generator;
import static compiler.lib.generators.Generators.G;
import compiler.lib.verify.Verify;
public class ScalarFPtoIntCastTest {
private static final int COUNT = 16;
private float[] float_arr;
private double[] double_arr;
private long[] long_float_arr;
private long[] long_double_arr;
private int[] int_float_arr;
private int[] int_double_arr;
private short[] short_float_arr;
private short[] short_double_arr;
private byte[] byte_float_arr;
private byte[] byte_double_arr;
private static final Generator<Float> genF = G.floats();
private static final Generator<Double> genD = G.doubles();
public static void main(String[] args) {
TestFramework testFramework = new TestFramework();
testFramework.start();
}
public ScalarFPtoIntCastTest() {
long_float_arr = new long[COUNT];
long_double_arr = new long[COUNT];
int_float_arr = new int[COUNT];
int_double_arr = new int[COUNT];
short_float_arr = new short[COUNT];
short_double_arr = new short[COUNT];
byte_float_arr = new byte[COUNT];
byte_double_arr = new byte[COUNT];
float_arr = new float[COUNT];
double_arr = new double[COUNT];
G.fill(genF, float_arr);
G.fill(genD, double_arr);
for (int i = 0; i < COUNT; i++) {
long_float_arr[i] = (long) float_arr[i];
long_double_arr[i] = (long) double_arr[i];
int_float_arr[i] = (int) float_arr[i];
int_double_arr[i] = (int) double_arr[i];
short_float_arr[i] = (short) float_arr[i];
short_double_arr[i] = (short) double_arr[i];
byte_float_arr[i] = (byte) float_arr[i];
byte_double_arr[i] = (byte) double_arr[i];
}
}
@Test
@IR(counts = {IRNode.CONV_F2I, "> 0"})
@IR(counts = {IRNode.X86_SCONV_F2I, "> 0"},
applyIfCPUFeature = {"avx10_2", "false"})
@IR(counts = {IRNode.X86_SCONV_F2I_AVX10, "> 0"},
applyIfCPUFeature = {"avx10_2", "true"})
public void float2int() {
for (int i = 0; i < COUNT; i++) {
float float_val = float_arr[i];
int computed = (int) float_val;
int expected = int_float_arr[i];
Verify.checkEQ(computed, expected);
}
}
@Test
@IR(counts = {IRNode.CONV_F2L, "> 0"})
@IR(counts = {IRNode.X86_SCONV_F2L, "> 0"},
applyIfCPUFeature = {"avx10_2", "false"})
@IR(counts = {IRNode.X86_SCONV_F2L_AVX10, "> 0"},
applyIfCPUFeature = {"avx10_2", "true"})
public void float2long() {
for (int i = 0; i < COUNT; i++) {
float float_val = float_arr[i];
long computed = (long) float_val;
long expected = long_float_arr[i];
Verify.checkEQ(computed, expected);
}
}
@Test
@IR(counts = {IRNode.CONV_F2I, "> 0"})
@IR(counts = {IRNode.X86_SCONV_F2I, "> 0"},
applyIfCPUFeature = {"avx10_2", "false"})
@IR(counts = {IRNode.X86_SCONV_F2I_AVX10, "> 0"},
applyIfCPUFeature = {"avx10_2", "true"})
public void float2short() {
for (int i = 0; i < COUNT; i++) {
float float_val = float_arr[i];
short computed = (short) float_val;
short expected = short_float_arr[i];
Verify.checkEQ(computed, expected);
}
}
@Test
@IR(counts = {IRNode.CONV_F2I, "> 0"})
@IR(counts = {IRNode.X86_SCONV_F2I, "> 0"},
applyIfCPUFeature = {"avx10_2", "false"})
@IR(counts = {IRNode.X86_SCONV_F2I_AVX10, "> 0"},
applyIfCPUFeature = {"avx10_2", "true"})
public void float2byte() {
for (int i = 0; i < COUNT; i++) {
float float_val = float_arr[i];
byte computed = (byte) float_val;
byte expected = byte_float_arr[i];
Verify.checkEQ(computed, expected);
}
}
@Test
@IR(counts = {IRNode.CONV_D2I, "> 0"})
@IR(counts = {IRNode.X86_SCONV_D2I, "> 0"},
applyIfCPUFeature = {"avx10_2", "false"})
@IR(counts = {IRNode.X86_SCONV_D2I_AVX10, "> 0"},
applyIfCPUFeature = {"avx10_2", "true"})
public void double2int() {
for (int i = 0; i < COUNT; i++) {
double double_val = double_arr[i];
int computed = (int) double_val;
int expected = int_double_arr[i];
Verify.checkEQ(computed, expected);
}
}
@Test
@IR(counts = {IRNode.CONV_D2L, "> 0"})
@IR(counts = {IRNode.X86_SCONV_D2L, "> 0"},
applyIfCPUFeature = {"avx10_2", "false"})
@IR(counts = {IRNode.X86_SCONV_D2L_AVX10, "> 0"},
applyIfCPUFeature = {"avx10_2", "true"})
public void double2long() {
for (int i = 0; i < COUNT; i++) {
double double_val = double_arr[i];
long computed = (long) double_val;
long expected = long_double_arr[i];
Verify.checkEQ(computed, expected);
}
}
@Test
@IR(counts = {IRNode.CONV_D2I, "> 0"})
@IR(counts = {IRNode.X86_SCONV_D2I, "> 0"},
applyIfCPUFeature = {"avx10_2", "false"})
@IR(counts = {IRNode.X86_SCONV_D2I_AVX10, "> 0"},
applyIfCPUFeature = {"avx10_2", "true"})
public void double2short() {
for (int i = 0; i < COUNT; i++) {
double double_val = double_arr[i];
short computed = (short) double_val;
short expected = short_double_arr[i];
Verify.checkEQ(computed, expected);
}
}
@Test
@IR(counts = {IRNode.CONV_D2I, "> 0"})
@IR(counts = {IRNode.X86_SCONV_D2I, "> 0"},
applyIfCPUFeature = {"avx10_2", "false"})
@IR(counts = {IRNode.X86_SCONV_D2I_AVX10, "> 0"},
applyIfCPUFeature = {"avx10_2", "true"})
public void double2byte() {
for (int i = 0; i < COUNT; i++) {
double double_val = double_arr[i];
byte computed = (byte) double_val;
byte expected = byte_double_arr[i];
Verify.checkEQ(computed, expected);
}
}
}
@@ -610,11 +610,31 @@ public class IRNode {
beforeMatchingNameRegex(CONV, "Conv");
}
public static final String CONV_D2I = PREFIX + "CONV_D2I" + POSTFIX;
static {
beforeMatchingNameRegex(CONV_D2I, "ConvD2I");
}
public static final String CONV_D2L = PREFIX + "CONV_D2L" + POSTFIX;
static {
beforeMatchingNameRegex(CONV_D2L, "ConvD2L");
}
public static final String CONV_F2HF = PREFIX + "CONV_F2HF" + POSTFIX;
static {
beforeMatchingNameRegex(CONV_F2HF, "ConvF2HF");
}
public static final String CONV_F2I = PREFIX + "CONV_F2I" + POSTFIX;
static {
beforeMatchingNameRegex(CONV_F2I, "ConvF2I");
}
public static final String CONV_F2L = PREFIX + "CONV_F2L" + POSTFIX;
static {
beforeMatchingNameRegex(CONV_F2L, "ConvF2L");
}
public static final String CONV_I2L = PREFIX + "CONV_I2L" + POSTFIX;
static {
beforeMatchingNameRegex(CONV_I2L, "ConvI2L");
@@ -2675,6 +2695,66 @@ public class IRNode {
machOnlyNameRegex(VSTOREMASK_TRUECOUNT, "vstoremask_truecount_neon");
}
public static final String X86_SCONV_D2I = PREFIX + "X86_SCONV_D2I" + POSTFIX;
static {
machOnlyNameRegex(X86_SCONV_D2I, "convD2I_reg_reg");
}
public static final String X86_SCONV_D2L = PREFIX + "X86_SCONV_D2L" + POSTFIX;
static {
machOnlyNameRegex(X86_SCONV_D2L, "convD2L_reg_reg");
}
public static final String X86_SCONV_F2I = PREFIX + "X86_SCONV_F2I" + POSTFIX;
static {
machOnlyNameRegex(X86_SCONV_F2I, "convF2I_reg_reg");
}
public static final String X86_SCONV_F2L = PREFIX + "X86_SCONV_F2L" + POSTFIX;
static {
machOnlyNameRegex(X86_SCONV_F2L, "convF2L_reg_reg");
}
public static final String X86_SCONV_D2I_AVX10 = PREFIX + "X86_SCONV2_D2I_AVX10" + POSTFIX;
static {
machOnlyNameRegex(X86_SCONV_D2I_AVX10, "convD2I_(reg_reg|reg_mem)_avx10");
}
public static final String X86_SCONV_D2L_AVX10 = PREFIX + "X86_SCONV_D2L_AVX10" + POSTFIX;
static {
machOnlyNameRegex(X86_SCONV_D2L_AVX10, "convD2L_(reg_reg|reg_mem)_avx10");
}
public static final String X86_SCONV_F2I_AVX10 = PREFIX + "X86_SCONV_F2I_AVX10" + POSTFIX;
static {
machOnlyNameRegex(X86_SCONV_F2I_AVX10, "convF2I_(reg_reg|reg_mem)_avx10");
}
public static final String X86_SCONV_F2L_AVX10 = PREFIX + "X86_SCONV_F2L_AVX10" + POSTFIX;
static {
machOnlyNameRegex(X86_SCONV_F2L_AVX10, "convF2L_(reg_reg|reg_mem)_avx10");
}
public static final String X86_VCAST_F2X = PREFIX + "X86_VCAST_F2X" + POSTFIX;
static {
machOnlyNameRegex(X86_VCAST_F2X, "castFtoX_reg_(av|eve)x");
}
public static final String X86_VCAST_D2X = PREFIX + "X86_VCAST_D2X" + POSTFIX;
static {
machOnlyNameRegex(X86_VCAST_D2X, "castDtoX_reg_(av|eve)x");
}
public static final String X86_VCAST_F2X_AVX10 = PREFIX + "X86_VCAST_F2X_AVX10" + POSTFIX;
static {
machOnlyNameRegex(X86_VCAST_F2X_AVX10, "castFtoX_(reg|mem)_avx10");
}
public static final String X86_VCAST_D2X_AVX10 = PREFIX + "X86_VCAST_D2X_AVX10" + POSTFIX;
static {
machOnlyNameRegex(X86_VCAST_D2X_AVX10, "castDtoX_(reg|mem)_avx10");
}
public static final String XOR = PREFIX + "XOR" + POSTFIX;
static {
beforeMatchingNameRegex(XOR, "Xor(I|L)");
@@ -106,6 +106,7 @@ public class IREncodingPrinter {
"avx512_fp16",
"avx512_vnni",
"avx512_vbmi",
"avx10_2",
"bmi2",
// AArch64
"sha3",
@@ -30,6 +30,7 @@
* @requires vm.flagless
* @requires vm.debug & vm.compiler2.enabled
* @requires os.simpleArch == "x64" | os.arch == "aarch64" | (os.arch == "riscv64" & vm.cpu.features ~= ".*rvv.*")
* @requires vm.opt.EnableVectorSupport == true
* @modules jdk.incubator.vector
* @run main/othervm compiler.rangechecks.TestRangeCheckHoistingScaledIV
*/
@@ -41,6 +41,7 @@ import jdk.test.lib.Utils;
* @library /test/lib /
* @summary Verify non-strictly ordered AddReductionVF/VD and MulReductionVF/VD
* nodes are generated in VectorAPI
* @requires vm.opt.EnableVectorSupport == true
* @modules jdk.incubator.vector
* @run driver compiler.vectorapi.TestVectorAddMulReduction
*/
@@ -36,6 +36,7 @@ import jdk.incubator.vector.VectorMask;
* @requires (os.simpleArch == "x64" & vm.cpu.features ~= ".*sse4.*" & (vm.opt.UseSSE == "null" | vm.opt.UseSSE > 3))
* | os.arch == "aarch64"
* | (os.arch == "riscv64" & vm.cpu.features ~= ".*rvv.*")
* @requires vm.opt.EnableVectorSupport == true
* @run driver compiler.vectorapi.TestVectorTest
*/
public class TestVectorTest {
@@ -35,6 +35,7 @@ import jdk.test.lib.Utils;
* @key randomness
* @library /test/lib /
* @summary Promote vector IR node sharing
* @requires vm.opt.EnableVectorSupport == true
* @modules jdk.incubator.vector
*
* @run driver compiler.vectorapi.VectorCommutativeOperSharingTest
@@ -34,6 +34,7 @@ import jdk.test.lib.Asserts;
* @key randomness
* @library /test/lib /
* @summary AArch64: Add missing backend support of VectorAPI expand operation
* @requires vm.opt.EnableVectorSupport == true
* @modules jdk.incubator.vector
*
* @run driver compiler.vectorapi.VectorExpandTest
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2022, 2025, 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
@@ -23,8 +23,8 @@
/**
* @test
* @bug 8287835
* @summary Test float/double to integral cast
* @bug 8287835 8364305
* @summary Test vector float/double to integral cast
* @modules jdk.incubator.vector
* @requires vm.compiler2.enabled
* @library /test/lib /
@@ -87,7 +87,11 @@ public class VectorFPtoIntCastTest {
@Test
@IR(counts = {IRNode.VECTOR_CAST_F2I, IRNode.VECTOR_SIZE_16, "> 0"},
applyIfCPUFeature = {"avx512f", "true"})
applyIfCPUFeatureOr = {"avx512f", "true", "avx10_2", "true"})
@IR(counts = {IRNode.X86_VCAST_F2X, "> 0"},
applyIfCPUFeatureAnd = {"avx512f", "true", "avx10_2", "false"})
@IR(counts = {IRNode.X86_VCAST_F2X_AVX10, "> 0"},
applyIfCPUFeature = {"avx10_2", "true"})
public void float2int() {
var cvec = (IntVector)fvec512.convertShape(VectorOperators.F2I, ispec512, 0);
cvec.intoArray(int_arr, 0);
@@ -96,7 +100,7 @@ public class VectorFPtoIntCastTest {
public void checkf2int(int len) {
for (int i = 0; i < len; i++) {
int expected = (int)float_arr[i];
int expected = (int) float_arr[i];
if (int_arr[i] != expected) {
throw new RuntimeException("Invalid result: int_arr[" + i + "] = " + int_arr[i] + " != " + expected);
}
@@ -105,7 +109,11 @@ public class VectorFPtoIntCastTest {
@Test
@IR(counts = {IRNode.VECTOR_CAST_F2L, IRNode.VECTOR_SIZE_8, "> 0"},
applyIfCPUFeature = {"avx512dq", "true"})
applyIfCPUFeatureOr = {"avx512dq", "true", "avx10_2", "true"})
@IR(counts = {IRNode.X86_VCAST_F2X, "> 0"},
applyIfCPUFeatureAnd = {"avx512dq", "true", "avx10_2", "false"})
@IR(counts = {IRNode.X86_VCAST_F2X_AVX10, "> 0"},
applyIfCPUFeature = {"avx10_2", "true"})
public void float2long() {
var cvec = (LongVector)fvec512.convertShape(VectorOperators.F2L, lspec512, 0);
cvec.intoArray(long_arr, 0);
@@ -114,7 +122,7 @@ public class VectorFPtoIntCastTest {
public void checkf2long(int len) {
for (int i = 0; i < len; i++) {
long expected = (long)float_arr[i];
long expected = (long) float_arr[i];
if (long_arr[i] != expected) {
throw new RuntimeException("Invalid result: long_arr[" + i + "] = " + long_arr[i] + " != " + expected);
}
@@ -123,7 +131,11 @@ public class VectorFPtoIntCastTest {
@Test
@IR(counts = {IRNode.VECTOR_CAST_F2S, IRNode.VECTOR_SIZE_16, "> 0"},
applyIfCPUFeature = {"avx512f", "true"})
applyIfCPUFeatureOr = {"avx512f", "true", "avx10_2", "true"})
@IR(counts = {IRNode.X86_VCAST_F2X, "> 0"},
applyIfCPUFeatureAnd = {"avx512f", "true", "avx10_2", "false"})
@IR(counts = {IRNode.X86_VCAST_F2X_AVX10, "> 0"},
applyIfCPUFeature = {"avx10_2", "true"})
public void float2short() {
var cvec = (ShortVector)fvec512.convertShape(VectorOperators.F2S, sspec256, 0);
cvec.intoArray(short_arr, 0);
@@ -132,7 +144,7 @@ public class VectorFPtoIntCastTest {
public void checkf2short(int len) {
for (int i = 0; i < len; i++) {
short expected = (short)float_arr[i];
short expected = (short) float_arr[i];
if (short_arr[i] != expected) {
throw new RuntimeException("Invalid result: short_arr[" + i + "] = " + short_arr[i] + " != " + expected);
}
@@ -141,7 +153,11 @@ public class VectorFPtoIntCastTest {
@Test
@IR(counts = {IRNode.VECTOR_CAST_F2B, IRNode.VECTOR_SIZE_16, "> 0"},
applyIfCPUFeature = {"avx512f", "true"})
applyIfCPUFeatureOr = {"avx512f", "true", "avx10_2", "true"})
@IR(counts = {IRNode.X86_VCAST_F2X, "> 0"},
applyIfCPUFeatureAnd = {"avx512f", "true", "avx10_2", "false"})
@IR(counts = {IRNode.X86_VCAST_F2X_AVX10, "> 0"},
applyIfCPUFeature = {"avx10_2", "true"})
public void float2byte() {
var cvec = (ByteVector)fvec512.convertShape(VectorOperators.F2B, bspec128, 0);
cvec.intoArray(byte_arr, 0);
@@ -150,7 +166,7 @@ public class VectorFPtoIntCastTest {
public void checkf2byte(int len) {
for (int i = 0; i < len; i++) {
byte expected = (byte)float_arr[i];
byte expected = (byte) float_arr[i];
if (byte_arr[i] != expected) {
throw new RuntimeException("Invalid result: byte_arr[" + i + "] = " + byte_arr[i] + " != " + expected);
}
@@ -159,7 +175,11 @@ public class VectorFPtoIntCastTest {
@Test
@IR(counts = {IRNode.VECTOR_CAST_D2I, IRNode.VECTOR_SIZE_8, "> 0"},
applyIfCPUFeature = {"avx512f", "true"})
applyIfCPUFeatureOr = {"avx512f", "true", "avx10_2", "true"})
@IR(counts = {IRNode.X86_VCAST_D2X, "> 0"},
applyIfCPUFeatureAnd = {"avx512f", "true", "avx10_2", "false"})
@IR(counts = {IRNode.X86_VCAST_D2X_AVX10, "> 0"},
applyIfCPUFeature = {"avx10_2", "true"})
public void double2int() {
var cvec = (IntVector)dvec512.convertShape(VectorOperators.D2I, ispec256, 0);
cvec.intoArray(int_arr, 0);
@@ -168,7 +188,7 @@ public class VectorFPtoIntCastTest {
public void checkd2int(int len) {
for (int i = 0; i < len; i++) {
int expected = (int)double_arr[i];
int expected = (int) double_arr[i];
if (int_arr[i] != expected) {
throw new RuntimeException("Invalid result: int_arr[" + i + "] = " + int_arr[i] + " != " + expected);
}
@@ -177,7 +197,11 @@ public class VectorFPtoIntCastTest {
@Test
@IR(counts = {IRNode.VECTOR_CAST_D2L, IRNode.VECTOR_SIZE_8, "> 0"},
applyIfCPUFeature = {"avx512dq", "true"})
applyIfCPUFeatureOr = {"avx512dq", "true", "avx10_2", "true"})
@IR(counts = {IRNode.X86_VCAST_D2X, "> 0"},
applyIfCPUFeatureAnd = {"avx512dq", "true", "avx10_2", "false"})
@IR(counts = {IRNode.X86_VCAST_D2X_AVX10, "> 0"},
applyIfCPUFeature = {"avx10_2", "true"})
public void double2long() {
var cvec = (LongVector)dvec512.convertShape(VectorOperators.D2L, lspec512, 0);
cvec.intoArray(long_arr, 0);
@@ -186,7 +210,7 @@ public class VectorFPtoIntCastTest {
public void checkd2long(int len) {
for (int i = 0; i < len; i++) {
long expected = (long)double_arr[i];
long expected = (long) double_arr[i];
if (long_arr[i] != expected) {
throw new RuntimeException("Invalid result: long_arr[" + i + "] = " + long_arr[i] + " != " + expected);
}
@@ -195,7 +219,11 @@ public class VectorFPtoIntCastTest {
@Test
@IR(counts = {IRNode.VECTOR_CAST_D2S, IRNode.VECTOR_SIZE_8, "> 0"},
applyIfCPUFeature = {"avx512f", "true"})
applyIfCPUFeatureOr = {"avx512f", "true", "avx10_2", "true"})
@IR(counts = {IRNode.X86_VCAST_D2X, "> 0"},
applyIfCPUFeatureAnd = {"avx512f", "true", "avx10_2", "false"})
@IR(counts = {IRNode.X86_VCAST_D2X_AVX10, "> 0"},
applyIfCPUFeature = {"avx10_2", "true"})
public void double2short() {
var cvec = (ShortVector)dvec512.convertShape(VectorOperators.D2S, sspec128, 0);
cvec.intoArray(short_arr, 0);
@@ -204,7 +232,7 @@ public class VectorFPtoIntCastTest {
public void checkd2short(int len) {
for (int i = 0; i < len; i++) {
short expected = (short)double_arr[i];
short expected = (short) double_arr[i];
if (short_arr[i] != expected) {
throw new RuntimeException("Invalid result: short_arr[" + i + "] = " + short_arr[i] + " != " + expected);
}
@@ -213,7 +241,11 @@ public class VectorFPtoIntCastTest {
@Test
@IR(counts = {IRNode.VECTOR_CAST_D2B, IRNode.VECTOR_SIZE_8, "> 0"},
applyIfCPUFeature = {"avx512f", "true"})
applyIfCPUFeatureOr = {"avx512f", "true", "avx10_2", "true"})
@IR(counts = {IRNode.X86_VCAST_D2X, "> 0"},
applyIfCPUFeatureAnd = {"avx512f", "true", "avx10_2", "false"})
@IR(counts = {IRNode.X86_VCAST_D2X_AVX10, "> 0"},
applyIfCPUFeature = {"avx10_2", "true"})
public void double2byte() {
var cvec = (ByteVector)dvec512.convertShape(VectorOperators.D2B, bspec64, 0);
cvec.intoArray(byte_arr, 0);
@@ -222,7 +254,7 @@ public class VectorFPtoIntCastTest {
public void checkd2byte(int len) {
for (int i = 0; i < len; i++) {
byte expected = (byte)double_arr[i];
byte expected = (byte) double_arr[i];
if (byte_arr[i] != expected) {
throw new RuntimeException("Invalid result: byte_arr[" + i + "] = " + byte_arr[i] + " != " + expected);
}
@@ -48,6 +48,7 @@ import jdk.test.lib.Utils;
* @key randomness
* @library /test/lib /
* @requires vm.cpu.features ~= ".*sve.*" | vm.cpu.features ~= ".*rvv.*"
* @requires vm.opt.EnableVectorSupport == true
* @summary Add optimized rules for masked vector multiply-add/sub for SVE and RVV
* @modules jdk.incubator.vector
*
@@ -36,6 +36,7 @@ import jdk.test.lib.Asserts;
* @summary test combining vector not operation with compare
* @modules jdk.incubator.vector
* @requires (os.arch != "riscv64" | (os.arch == "riscv64" & vm.cpu.features ~= ".*rvv.*"))
* @requires vm.opt.EnableVectorSupport == true
*
* @run driver compiler.vectorapi.VectorMaskCompareNotTest
*/
@@ -26,6 +26,7 @@
* @bug 8356760 8367391
* @library /test/lib /
* @summary Optimize VectorMask.fromLong for all-true/all-false cases
* @requires vm.opt.EnableVectorSupport == true
* @modules jdk.incubator.vector
*
* @run driver compiler.vectorapi.VectorMaskFromLongTest
@@ -33,6 +33,7 @@ import jdk.test.lib.Asserts;
* @key randomness
* @library /test/lib /
* @summary VectorAPI: Re-intrinsify VectorMask.laneIsSet where the input index is a variable
* @requires vm.opt.EnableVectorSupport == true
* @modules jdk.incubator.vector
*
* @run driver compiler.vectorapi.VectorMaskLaneIsSetTest
@@ -26,6 +26,7 @@
* @bug 8356760
* @library /test/lib /
* @summary Optimize VectorMask.fromLong for all-true/all-false cases
* @requires vm.opt.EnableVectorSupport == true
* @modules jdk.incubator.vector
*
* @run driver compiler.vectorapi.VectorMaskToLongTest
@@ -25,6 +25,7 @@
* @test
* @bug 8338021 8342677 8349522
* @summary Add IR validation tests for newly added saturated vector add / sub operations
* @requires vm.opt.EnableVectorSupport == true
* @modules jdk.incubator.vector
* @library /test/lib /
* @run driver compiler.vectorapi.VectorSaturatedOperationsTest
@@ -25,6 +25,7 @@
* @test
* @bug 8342676
* @summary Unsigned Vector Min / Max transforms
* @requires vm.opt.EnableVectorSupport == true
* @modules jdk.incubator.vector
* @library /test/lib /
* @run driver compiler.vectorapi.VectorUnsignedMinMaxOperationsTest
@@ -35,6 +35,7 @@ import compiler.vectorapi.reshape.utils.VectorReshapeHelper;
* @modules java.base/jdk.internal.misc
* @summary Test that vector cast intrinsics work as intended on riscv (rvv).
* @requires os.arch == "riscv64" & vm.cpu.features ~= ".*rvv.*"
* @requires vm.opt.EnableVectorSupport == true
* @library /test/lib /
* @run main/timeout=300 compiler.vectorapi.reshape.TestVectorCastRVV
*/
@@ -40,6 +40,7 @@ import jdk.incubator.vector.VectorSpecies;
* @modules java.base/jdk.internal.misc
* @summary Test that vector reinterpret intrinsics work as intended.
* @requires os.arch != "riscv64" | vm.cpu.features ~= ".*rvv.*"
* @requires vm.opt.EnableVectorSupport == true
* @library /test/lib /
* @run main compiler.vectorapi.reshape.TestVectorReinterpret
*/
@@ -294,8 +294,12 @@ public class ArrayTypeConvertTest extends VectorizationTestRunner {
// ---------------- Convert F/D to I/L ----------------
@Test
@IR(applyIfCPUFeatureOr = {"asimd", "true", "avx", "true", "rvv", "true"},
counts = {IRNode.VECTOR_CAST_F2I, IRNode.VECTOR_SIZE + "min(max_float, max_int)", ">0"})
@IR(applyIfCPUFeatureOr = {"asimd", "true", "avx", "true", "avx10_2", "true", "rvv", "true"},
counts = {IRNode.VECTOR_CAST_F2I, IRNode.VECTOR_SIZE + "min(max_float, max_int)", "> 0"})
@IR(counts = {IRNode.X86_VCAST_F2X, "> 0"},
applyIfCPUFeatureAnd = {"avx", "true", "avx10_2", "false"})
@IR(counts = {IRNode.X86_VCAST_F2X_AVX10, "> 0"},
applyIfCPUFeature = {"avx10_2", "true"})
public int[] convertFloatToInt() {
int[] res = new int[SIZE];
for (int i = 0; i < SIZE; i++) {
@@ -305,8 +309,12 @@ public class ArrayTypeConvertTest extends VectorizationTestRunner {
}
@Test
@IR(applyIfCPUFeatureOr = {"asimd", "true", "avx512dq", "true", "rvv", "true"},
counts = {IRNode.VECTOR_CAST_F2L, IRNode.VECTOR_SIZE + "min(max_float, max_long)", ">0"})
@IR(applyIfCPUFeatureOr = {"asimd", "true", "avx512dq", "true", "avx10_2", "true", "rvv", "true"},
counts = {IRNode.VECTOR_CAST_F2L, IRNode.VECTOR_SIZE + "min(max_float, max_long)", "> 0"})
@IR(counts = {IRNode.X86_VCAST_F2X, "> 0"},
applyIfCPUFeatureAnd = {"avx512dq", "true", "avx10_2", "false"})
@IR(counts = {IRNode.X86_VCAST_F2X_AVX10, "> 0"},
applyIfCPUFeature = {"avx10_2", "true"})
public long[] convertFloatToLong() {
long[] res = new long[SIZE];
for (int i = 0; i < SIZE; i++) {
@@ -316,8 +324,12 @@ public class ArrayTypeConvertTest extends VectorizationTestRunner {
}
@Test
@IR(applyIfCPUFeatureOr = {"sve", "true", "avx", "true", "rvv", "true"},
counts = {IRNode.VECTOR_CAST_D2I, IRNode.VECTOR_SIZE + "min(max_double, max_int)", ">0"})
@IR(applyIfCPUFeatureOr = {"sve", "true", "avx", "true", "avx10_2", "true", "rvv", "true"},
counts = {IRNode.VECTOR_CAST_D2I, IRNode.VECTOR_SIZE + "min(max_double, max_int)", "> 0"})
@IR(counts = {IRNode.X86_VCAST_D2X, "> 0"},
applyIfCPUFeatureAnd = {"avx", "true", "avx10_2", "false"})
@IR(counts = {IRNode.X86_VCAST_D2X_AVX10, "> 0"},
applyIfCPUFeature = {"avx10_2", "true"})
public int[] convertDoubleToInt() {
int[] res = new int[SIZE];
for (int i = 0; i < SIZE; i++) {
@@ -327,8 +339,12 @@ public class ArrayTypeConvertTest extends VectorizationTestRunner {
}
@Test
@IR(applyIfCPUFeatureOr = {"asimd", "true", "avx512dq", "true", "rvv", "true"},
counts = {IRNode.VECTOR_CAST_D2L, IRNode.VECTOR_SIZE + "min(max_double, max_long)", ">0"})
@IR(applyIfCPUFeatureOr = {"asimd", "true", "avx512dq", "true", "avx10_2", "true", "rvv", "true"},
counts = {IRNode.VECTOR_CAST_D2L, IRNode.VECTOR_SIZE + "min(max_double, max_long)", "> 0"})
@IR(counts = {IRNode.X86_VCAST_D2X, "> 0"},
applyIfCPUFeatureAnd = {"avx512dq", "true", "avx10_2", "false"})
@IR(counts = {IRNode.X86_VCAST_D2X_AVX10, "> 0"},
applyIfCPUFeature = {"avx10_2", "true"})
public long[] convertDoubleToLong() {
long[] res = new long[SIZE];
for (int i = 0; i < SIZE; i++) {
@@ -339,9 +355,15 @@ public class ArrayTypeConvertTest extends VectorizationTestRunner {
// ---------------- Convert F/D to Subword-I ----------------
@Test
@IR(applyIfCPUFeatureOr = {"asimd", "true", "avx2", "true", "rvv", "true"},
@IR(applyIfCPUFeatureOr = {"asimd", "true", "avx2", "true", "avx10_2", "true", "rvv", "true"},
applyIfOr = {"AlignVector", "false", "UseCompactObjectHeaders", "false"},
counts = {IRNode.VECTOR_CAST_F2S, IRNode.VECTOR_SIZE + "min(max_float, max_short)", ">0"})
counts = {IRNode.VECTOR_CAST_F2S, IRNode.VECTOR_SIZE + "min(max_float, max_short)", "> 0"})
@IR(counts = {IRNode.X86_VCAST_F2X, "> 0"},
applyIfOr = {"AlignVector", "false", "UseCompactObjectHeaders", "false"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx10_2", "false"})
@IR(counts = {IRNode.X86_VCAST_F2X_AVX10, "> 0"},
applyIfOr = {"AlignVector", "false", "UseCompactObjectHeaders", "false"},
applyIfCPUFeature = {"avx10_2", "true"})
public short[] convertFloatToShort() {
short[] res = new short[SIZE];
for (int i = 0; i < SIZE; i++) {
@@ -358,9 +380,15 @@ public class ArrayTypeConvertTest extends VectorizationTestRunner {
}
@Test
@IR(applyIfCPUFeatureOr = {"asimd", "true", "avx2", "true", "rvv", "true"},
@IR(applyIfCPUFeatureOr = {"asimd", "true", "avx2", "true", "avx10_2", "true", "rvv", "true"},
applyIfOr = {"AlignVector", "false", "UseCompactObjectHeaders", "false"},
counts = {IRNode.VECTOR_CAST_F2S, IRNode.VECTOR_SIZE + "min(max_float, max_char)", ">0"})
counts = {IRNode.VECTOR_CAST_F2S, IRNode.VECTOR_SIZE + "min(max_float, max_char)", "> 0"})
@IR(counts = {IRNode.X86_VCAST_F2X, "> 0"},
applyIfOr = {"AlignVector", "false", "UseCompactObjectHeaders", "false"},
applyIfCPUFeatureAnd = {"avx2", "true", "avx10_2", "false"})
@IR(counts = {IRNode.X86_VCAST_F2X_AVX10, "> 0"},
applyIfOr = {"AlignVector", "false", "UseCompactObjectHeaders", "false"},
applyIfCPUFeature = {"avx10_2", "true"})
public char[] convertFloatToChar() {
char[] res = new char[SIZE];
for (int i = 0; i < SIZE; i++) {
@@ -379,10 +407,16 @@ public class ArrayTypeConvertTest extends VectorizationTestRunner {
@Test
@IR(applyIfCPUFeature = {"rvv", "true"},
applyIf = {"MaxVectorSize", ">=32"},
counts = {IRNode.VECTOR_CAST_D2S, IRNode.VECTOR_SIZE + "min(max_double, max_short)", ">0"})
@IR(applyIfCPUFeatureOr = {"sve", "true", "avx", "true"},
counts = {IRNode.VECTOR_CAST_D2S, IRNode.VECTOR_SIZE + "min(max_double, max_short)", "> 0"})
@IR(applyIfCPUFeatureOr = {"sve", "true", "avx", "true", "avx10_2", "true"},
applyIf = {"MaxVectorSize", ">=16"},
counts = {IRNode.VECTOR_CAST_D2S, IRNode.VECTOR_SIZE + "min(max_double, max_short)", ">0"})
counts = {IRNode.VECTOR_CAST_D2S, IRNode.VECTOR_SIZE + "min(max_double, max_short)", "> 0"})
@IR(counts = {IRNode.X86_VCAST_D2X, "> 0"},
applyIf = {"MaxVectorSize", ">=16"},
applyIfCPUFeatureAnd = {"avx", "true", "avx10_2", "false"})
@IR(counts = {IRNode.X86_VCAST_D2X_AVX10, "> 0"},
applyIf = {"MaxVectorSize", ">=16"},
applyIfCPUFeature = {"avx10_2", "true"})
public short[] convertDoubleToShort() {
short[] res = new short[SIZE];
for (int i = 0; i < SIZE; i++) {
@@ -393,11 +427,17 @@ public class ArrayTypeConvertTest extends VectorizationTestRunner {
@Test
@IR(applyIfCPUFeature = {"rvv", "true"},
applyIf = {"MaxVectorSize", ">=32"},
counts = {IRNode.VECTOR_CAST_D2S, IRNode.VECTOR_SIZE + "min(max_double, max_char)", ">0"})
@IR(applyIfCPUFeatureOr = {"sve", "true", "avx", "true"},
applyIf = {"MaxVectorSize", ">= 32"},
counts = {IRNode.VECTOR_CAST_D2S, IRNode.VECTOR_SIZE + "min(max_double, max_char)", "> 0"})
@IR(applyIfCPUFeatureOr = {"sve", "true", "avx", "true", "avx10_2", "true"},
applyIf = {"MaxVectorSize", ">= 16"},
counts = {IRNode.VECTOR_CAST_D2S, IRNode.VECTOR_SIZE + "min(max_double, max_char)", "> 0"})
@IR(counts = {IRNode.X86_VCAST_D2X, "> 0"},
applyIf = {"MaxVectorSize", ">=16"},
counts = {IRNode.VECTOR_CAST_D2S, IRNode.VECTOR_SIZE + "min(max_double, max_char)", ">0"})
applyIfCPUFeatureAnd = {"avx", "true", "avx10_2", "false"})
@IR(counts = {IRNode.X86_VCAST_D2X_AVX10, "> 0"},
applyIf = {"MaxVectorSize", ">=16"},
applyIfCPUFeature = {"avx10_2", "true"})
public char[] convertDoubleToChar() {
char[] res = new char[SIZE];
for (int i = 0; i < SIZE; i++) {
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2022 SAP SE. All rights reserved.
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2022, 2025, 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
@@ -47,7 +47,7 @@
* @requires vm.flagless
* @modules java.base/jdk.internal.misc
* @library /test/lib
* @run driver MallocLimitTest compiler-limit-fatal
* @run driver/timeout=480 MallocLimitTest compiler-limit-fatal
*/
/*
@@ -50,8 +50,8 @@ public class SignedJar {
String skipMsg = "Skipping Hello: Signed JAR";
String lambdaInArchive = "klasses.*=.*app.*Hello[$][$]Lambda.*hidden";
String loadFromJar = ".class,load. Hello source: file:.*signed_hello.jar";
String lambdaLoadFromHello = ".class.load. Hello[$][$]Lambda.*/0x.*source.*Hello";
String loadFromJar = ".class,load\s*. Hello source: file:.*signed_hello.jar";
String lambdaLoadFromHello = ".class.load\s*. Hello[$][$]Lambda.*/0x.*source.*Hello";
for (String mainArg : mainArgs) {
output = TestCommon.dump(signedJar, TestCommon.list(mainClass),
@@ -38,6 +38,7 @@
* @test id=dynamic
* @bug 8362561
* @summary -javaagent is not allowed when creating dynamic CDS archive
* @requires vm.cds.supports.aot.class.linking
* @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds/test-classes
* @build JavaAgent JavaAgentTransformer Util
* @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar JavaAgentApp JavaAgentApp$ShouldBeTransformed
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, NTT DATA.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -27,6 +27,7 @@
* @bug 8242428
* @summary Verifies JVMTI GetThreadListStackTraces API with thread_count = 1
* @requires vm.jvmti
* @requires test.thread.factory == null
* @library /test/lib
* @run main/othervm/native -agentlib:OneGetThreadListStackTraces OneGetThreadListStackTraces
*
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2025, 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
@@ -37,7 +37,7 @@
*
* @library /vmTestbase
* /test/lib
* @run main/othervm
* @run main/othervm/timeout=480
* -XX:-UseGCOverheadLimit
* gc.gctests.AllocateWithoutOomTest.AllocateWithoutOomTest
*/
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2004, 2025, 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
@@ -118,6 +118,13 @@ cbDynamicCodeGenerated2(jvmtiEnv *jvmti_env, const char *name,
}
void JNICALL
cbVMDeath(jvmtiEnv* jvmti, JNIEnv* jni) {
if (!NSK_JVMTI_VERIFY(jvmti->DestroyRawMonitor(syncLock))) {
nsk_jvmti_setFailStatus();
}
}
/* ============================================================================= */
static int
@@ -138,6 +145,7 @@ int setCallBacks(int stage) {
eventCallbacks.DynamicCodeGenerated = (stage == 1) ?
cbDynamicCodeGenerated1 : cbDynamicCodeGenerated2;
eventCallbacks.VMDeath = &cbVMDeath;
if (!NSK_JVMTI_VERIFY(jvmti->SetEventCallbacks(&eventCallbacks, sizeof(eventCallbacks))))
return NSK_FALSE;
@@ -256,9 +264,6 @@ Agent_OnUnload(JavaVM *jvm)
nsk_jvmti_setFailStatus();
}
if (!NSK_JVMTI_VERIFY(jvmti->DestroyRawMonitor(syncLock))) {
nsk_jvmti_setFailStatus();
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2025, 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
@@ -345,12 +345,10 @@ public class EventHandler implements Runnable {
public boolean eventReceived(Event event) {
if (event instanceof VMDisconnectEvent) {
display("receieved VMDisconnect");
synchronized(EventHandler.this) {
vmDisconnected = true;
status = 0; // OK finish
EventHandler.this.notifyAll();
removeListener(this);
}
vmDisconnected = true;
status = 0; // OK finish
EventHandler.this.notifyAll();
removeListener(this);
return true;
}
return false;
@@ -431,6 +429,10 @@ public class EventHandler implements Runnable {
}
public boolean eventReceived(Event event) {
if (en.event != null) {
// If we already got the requested event, don't handle this one.
return false;
}
EventSet set = en.set;
en.set = null; // We'll reset it below if the event matches a request.
for (int i = 0; i < requests.length; i++) {
@@ -441,11 +443,9 @@ public class EventHandler implements Runnable {
if (request.equals(event.request())) {
display("waitForRequestedEventCommon: Received event(" + event +
") for request(" + request + ")");
synchronized (EventHandler.this) {
en.event = event;
en.set = set;
EventHandler.this.notifyAll();
}
en.event = event;
en.set = set;
EventHandler.this.notifyAll();
return true; // event was handled
}
}
@@ -204,11 +204,9 @@ public abstract class TestDebuggerType1 {
new EventHandler.EventListener() {
public boolean eventReceived(Event event) {
if (event instanceof BreakpointEvent && bpRequest.equals(event.request())) {
synchronized(eventHandler) {
display("Received communication breakpoint event.");
bpCount++;
eventHandler.notifyAll();
}
display("Received communication breakpoint event.");
bpCount++;
eventHandler.notifyAll();
return true;
}
return false;
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2025, 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
@@ -36,7 +36,7 @@
*
* @library /vmTestbase
* /test/lib
* @run main/othervm
* @run main/othervm/timeout=480
* -XX:-UseGCOverheadLimit
* vm.gc.compact.Compact
* -gp interned(randomString)
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2025, 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
@@ -36,7 +36,7 @@
*
* @library /vmTestbase
* /test/lib
* @run main/othervm
* @run main/othervm/timeout=480
* -XX:-UseGCOverheadLimit
* vm.gc.compact.Compact
* -gp nonbranchyTree(high)
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2025, 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
@@ -36,7 +36,7 @@
*
* @library /vmTestbase
* /test/lib
* @run main/othervm
* @run main/othervm/timeout=480
* -XX:-UseGCOverheadLimit
* vm.gc.compact.Compact
* -gp nonbranchyTree(high)
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2025, 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
@@ -36,7 +36,7 @@
*
* @library /vmTestbase
* /test/lib
* @run main/othervm
* @run main/othervm/timeout=480
* -XX:-UseGCOverheadLimit
* vm.gc.compact.Compact
* -gp nonbranchyTree(high)

Some files were not shown because too many files have changed in this diff Show More