Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e5d7497dd5 |
@@ -62,13 +62,13 @@ $(eval $(call SetupJdkLibrary, BUILD_GTEST_LIBGTEST, \
|
||||
DISABLED_WARNINGS_gcc := format-nonliteral maybe-uninitialized undef \
|
||||
unused-result zero-as-null-pointer-constant, \
|
||||
DISABLED_WARNINGS_clang := format-nonliteral undef unused-result, \
|
||||
DISABLED_WARNINGS_microsoft := 4530, \
|
||||
DEFAULT_CFLAGS := false, \
|
||||
CFLAGS := $(JVM_CFLAGS) \
|
||||
-I$(GTEST_FRAMEWORK_SRC)/googletest \
|
||||
-I$(GTEST_FRAMEWORK_SRC)/googletest/include \
|
||||
-I$(GTEST_FRAMEWORK_SRC)/googlemock \
|
||||
-I$(GTEST_FRAMEWORK_SRC)/googlemock/include, \
|
||||
CFLAGS_windows := -EHsc, \
|
||||
CFLAGS_macosx := -DGTEST_OS_MAC=1, \
|
||||
OPTIMIZATION := $(JVM_OPTIMIZATION), \
|
||||
COPY_DEBUG_SYMBOLS := $(GTEST_COPY_DEBUG_SYMBOLS), \
|
||||
@@ -98,6 +98,7 @@ $(eval $(call SetupJdkLibrary, BUILD_GTEST_LIBJVM, \
|
||||
-I$(GTEST_FRAMEWORK_SRC)/googletest/include \
|
||||
-I$(GTEST_FRAMEWORK_SRC)/googlemock/include \
|
||||
$(addprefix -I, $(GTEST_TEST_SRC)), \
|
||||
CFLAGS_windows := -EHsc, \
|
||||
CFLAGS_macosx := -DGTEST_OS_MAC=1, \
|
||||
DISABLED_WARNINGS_gcc := $(DISABLED_WARNINGS_gcc) \
|
||||
undef stringop-overflow, \
|
||||
@@ -109,7 +110,7 @@ $(eval $(call SetupJdkLibrary, BUILD_GTEST_LIBJVM, \
|
||||
self-assign-overloaded, \
|
||||
DISABLED_WARNINGS_clang_test_g1ServiceThread.cpp := delete-abstract-non-virtual-dtor, \
|
||||
DISABLED_WARNINGS_clang_test_logDecorations.cpp := missing-field-initializers, \
|
||||
DISABLED_WARNINGS_microsoft := $(DISABLED_WARNINGS_microsoft) 4530, \
|
||||
DISABLED_WARNINGS_microsoft := $(DISABLED_WARNINGS_microsoft), \
|
||||
LD_SET_ORIGIN := false, \
|
||||
DEFAULT_LDFLAGS := false, \
|
||||
LDFLAGS := $(JVM_LDFLAGS), \
|
||||
|
||||
@@ -5965,6 +5965,9 @@ attributes %{
|
||||
instruction_unit_size = 4; // An instruction is 4 bytes long
|
||||
instruction_fetch_unit_size = 64; // The processor fetches one line
|
||||
instruction_fetch_units = 1; // of 64 bytes
|
||||
|
||||
// List of nop instructions
|
||||
nops( MachNop );
|
||||
%}
|
||||
|
||||
// We don't use an actual pipeline model so don't care about resources
|
||||
|
||||
@@ -3814,11 +3814,7 @@ private:
|
||||
starti;
|
||||
assert(T != Q, "invalid size");
|
||||
int sh = 0;
|
||||
if (isFloat) {
|
||||
assert(T != B, "invalid size");
|
||||
assert((imm8 >> 8) == 0, "invalid immediate");
|
||||
sh = 0;
|
||||
} else if (imm8 <= 127 && imm8 >= -128) {
|
||||
if (imm8 <= 127 && imm8 >= -128) {
|
||||
sh = 0;
|
||||
} else if (T != B && imm8 <= 32512 && imm8 >= -32768 && (imm8 & 0xff) == 0) {
|
||||
sh = 1;
|
||||
@@ -3828,7 +3824,7 @@ private:
|
||||
}
|
||||
int m = isMerge ? 1 : 0;
|
||||
f(0b00000101, 31, 24), f(T, 23, 22), f(0b01, 21, 20);
|
||||
prf(Pg, 16), f(isFloat ? 1 : 0, 15), f(m, 14), f(sh, 13), f(imm8 & 0xff, 12, 5), rf(Zd, 0);
|
||||
prf(Pg, 16), f(isFloat ? 1 : 0, 15), f(m, 14), f(sh, 13), sf(imm8, 12, 5), rf(Zd, 0);
|
||||
}
|
||||
|
||||
public:
|
||||
@@ -3838,7 +3834,7 @@ public:
|
||||
}
|
||||
// SVE copy floating-point immediate to vector elements (predicated)
|
||||
void sve_cpy(FloatRegister Zd, SIMD_RegVariant T, PRegister Pg, double d) {
|
||||
sve_cpy(Zd, T, Pg, checked_cast<uint8_t>(pack(d)), /*isMerge*/true, /*isFloat*/true);
|
||||
sve_cpy(Zd, T, Pg, checked_cast<int8_t>(pack(d)), /*isMerge*/true, /*isFloat*/true);
|
||||
}
|
||||
|
||||
// SVE conditionally select elements from two vectors
|
||||
|
||||
@@ -115,22 +115,8 @@ public:
|
||||
return Atomic::load_acquire(guard_addr());
|
||||
}
|
||||
|
||||
void set_value(int value, int bit_mask) {
|
||||
if (bit_mask == ~0) {
|
||||
Atomic::release_store(guard_addr(), value);
|
||||
return;
|
||||
}
|
||||
assert((value & ~bit_mask) == 0, "trying to set bits outside the mask");
|
||||
value &= bit_mask;
|
||||
int old_value = Atomic::load(guard_addr());
|
||||
while (true) {
|
||||
// Only bits in the mask are changed
|
||||
int new_value = value | (old_value & ~bit_mask);
|
||||
if (new_value == old_value) break;
|
||||
int v = Atomic::cmpxchg(guard_addr(), old_value, new_value, memory_order_release);
|
||||
if (v == old_value) break;
|
||||
old_value = v;
|
||||
}
|
||||
void set_value(int value) {
|
||||
Atomic::release_store(guard_addr(), value);
|
||||
}
|
||||
|
||||
bool check_barrier(err_msg& msg) const;
|
||||
@@ -193,7 +179,7 @@ void BarrierSetNMethod::deoptimize(nmethod* nm, address* return_address_ptr) {
|
||||
new_frame->pc = SharedRuntime::get_handle_wrong_method_stub();
|
||||
}
|
||||
|
||||
void BarrierSetNMethod::set_guard_value(nmethod* nm, int value, int bit_mask) {
|
||||
void BarrierSetNMethod::set_guard_value(nmethod* nm, int value) {
|
||||
if (!supports_entry_barrier(nm)) {
|
||||
return;
|
||||
}
|
||||
@@ -210,7 +196,7 @@ void BarrierSetNMethod::set_guard_value(nmethod* nm, int value, int bit_mask) {
|
||||
}
|
||||
|
||||
NativeNMethodBarrier barrier(nm);
|
||||
barrier.set_value(value, bit_mask);
|
||||
barrier.set_value(value);
|
||||
}
|
||||
|
||||
int BarrierSetNMethod::guard_value(nmethod* nm) {
|
||||
|
||||
@@ -2638,6 +2638,9 @@ attributes %{
|
||||
instruction_unit_size = 4; // An instruction is 4 bytes long
|
||||
instruction_fetch_unit_size = 16; // The processor fetches one line
|
||||
instruction_fetch_units = 1; // of 16 bytes
|
||||
|
||||
// List of nop instructions
|
||||
nops( Nop_A0, Nop_A1, Nop_MS, Nop_FA, Nop_BR );
|
||||
%}
|
||||
|
||||
//----------RESOURCES----------------------------------------------------------
|
||||
|
||||
@@ -51,22 +51,8 @@ public:
|
||||
return Atomic::load_acquire(guard_addr());
|
||||
}
|
||||
|
||||
void set_value(int value, int bit_mask) {
|
||||
if (bit_mask == ~0) {
|
||||
Atomic::release_store(guard_addr(), value);
|
||||
return;
|
||||
}
|
||||
assert((value & ~bit_mask) == 0, "trying to set bits outside the mask");
|
||||
value &= bit_mask;
|
||||
int old_value = Atomic::load(guard_addr());
|
||||
while (true) {
|
||||
// Only bits in the mask are changed
|
||||
int new_value = value | (old_value & ~bit_mask);
|
||||
if (new_value == old_value) break;
|
||||
int v = Atomic::cmpxchg(guard_addr(), old_value, new_value, memory_order_release);
|
||||
if (v == old_value) break;
|
||||
old_value = v;
|
||||
}
|
||||
void set_value(int value) {
|
||||
Atomic::release_store(guard_addr(), value);
|
||||
}
|
||||
|
||||
void verify() const;
|
||||
@@ -129,7 +115,7 @@ void BarrierSetNMethod::deoptimize(nmethod* nm, address* return_address_ptr) {
|
||||
new_frame->pc = SharedRuntime::get_handle_wrong_method_stub();
|
||||
}
|
||||
|
||||
void BarrierSetNMethod::set_guard_value(nmethod* nm, int value, int bit_mask) {
|
||||
void BarrierSetNMethod::set_guard_value(nmethod* nm, int value) {
|
||||
if (!supports_entry_barrier(nm)) {
|
||||
return;
|
||||
}
|
||||
@@ -137,7 +123,7 @@ void BarrierSetNMethod::set_guard_value(nmethod* nm, int value, int bit_mask) {
|
||||
// Disarms the nmethod guard emitted by BarrierSetAssembler::nmethod_entry_barrier.
|
||||
// Symmetric "LDR; DMB ISHLD" is in the nmethod barrier.
|
||||
NativeNMethodBarrier* barrier = native_nmethod_barrier(nm);
|
||||
barrier->set_value(value, bit_mask);
|
||||
barrier->set_value(value);
|
||||
}
|
||||
|
||||
int BarrierSetNMethod::guard_value(nmethod* nm) {
|
||||
|
||||
@@ -183,10 +183,13 @@ void BarrierSetAssembler::nmethod_entry_barrier(MacroAssembler* masm, Register t
|
||||
BarrierSetNMethod* bs_nm = BarrierSet::barrier_set()->barrier_set_nmethod();
|
||||
assert_different_registers(tmp, R0);
|
||||
|
||||
__ align(8); // must align the following block which requires atomic updates
|
||||
|
||||
__ block_comment("nmethod_entry_barrier (nmethod_entry_barrier) {");
|
||||
|
||||
// Load stub address using toc (fixed instruction size, unlike load_const_optimized)
|
||||
__ calculate_address_from_global_toc(tmp, StubRoutines::method_entry_barrier(),
|
||||
true, true, false); // 2 instructions
|
||||
__ mtctr(tmp);
|
||||
|
||||
// This is a compound instruction. Patching support is provided by NativeMovRegMem.
|
||||
// Actual patching is done in (platform-specific part of) BarrierSetNMethod.
|
||||
__ load_const32(tmp, 0 /* Value is patched */); // 2 instructions
|
||||
@@ -195,11 +198,6 @@ void BarrierSetAssembler::nmethod_entry_barrier(MacroAssembler* masm, Register t
|
||||
__ ld(R0, in_bytes(bs_nm->thread_disarmed_guard_value_offset()), R16_thread);
|
||||
__ cmpw(CR0, R0, tmp);
|
||||
|
||||
// Load stub address using toc (fixed instruction size, unlike load_const_optimized)
|
||||
__ calculate_address_from_global_toc(tmp, StubRoutines::method_entry_barrier(),
|
||||
true, true, false); // 2 instructions
|
||||
__ mtctr(tmp);
|
||||
|
||||
__ bnectrl(CR0);
|
||||
|
||||
// Oops may have been changed. Make those updates observable.
|
||||
|
||||
@@ -38,7 +38,7 @@ class NativeNMethodBarrier: public NativeInstruction {
|
||||
|
||||
NativeMovRegMem* get_patchable_instruction_handle() const {
|
||||
// Endianness is handled by NativeMovRegMem
|
||||
return reinterpret_cast<NativeMovRegMem*>(get_barrier_start_address());
|
||||
return reinterpret_cast<NativeMovRegMem*>(get_barrier_start_address() + 3 * 4);
|
||||
}
|
||||
|
||||
public:
|
||||
@@ -47,7 +47,7 @@ public:
|
||||
return get_patchable_instruction_handle()->offset();
|
||||
}
|
||||
|
||||
void release_set_guard_value(int value, int bit_mask) {
|
||||
void release_set_guard_value(int value) {
|
||||
// Patching is not atomic.
|
||||
// Stale observations of the "armed" state is okay as invoking the barrier stub in that case has no
|
||||
// unwanted side effects. Disarming is thus a non-critical operation.
|
||||
@@ -55,37 +55,8 @@ public:
|
||||
|
||||
OrderAccess::release(); // Release modified oops
|
||||
|
||||
if (bit_mask == ~0) {
|
||||
// Set the guard value (naming of 'offset' function is misleading).
|
||||
get_patchable_instruction_handle()->set_offset(value);
|
||||
return;
|
||||
}
|
||||
|
||||
assert((value & ~bit_mask) == 0, "trying to set bits outside the mask");
|
||||
value &= bit_mask;
|
||||
|
||||
NativeMovRegMem* mov = get_patchable_instruction_handle();
|
||||
assert(align_up(mov->instruction_address(), sizeof(uint64_t)) ==
|
||||
align_down(mov->instruction_address(), sizeof(uint64_t)), "instruction not aligned");
|
||||
uint64_t *instr = (uint64_t*)mov->instruction_address();
|
||||
assert(NativeMovRegMem::instruction_size == sizeof(*instr), "must be");
|
||||
union {
|
||||
u_char buf[NativeMovRegMem::instruction_size];
|
||||
uint64_t u64;
|
||||
} new_mov_instr, old_mov_instr;
|
||||
new_mov_instr.u64 = old_mov_instr.u64 = Atomic::load(instr);
|
||||
while (true) {
|
||||
// Only bits in the mask are changed
|
||||
int old_value = nativeMovRegMem_at(old_mov_instr.buf)->offset();
|
||||
int new_value = value | (old_value & ~bit_mask);
|
||||
if (new_value == old_value) return; // skip icache flush if nothing changed
|
||||
nativeMovRegMem_at(new_mov_instr.buf)->set_offset(new_value, false /* no icache flush */);
|
||||
// Swap in the new value
|
||||
uint64_t v = Atomic::cmpxchg(instr, old_mov_instr.u64, new_mov_instr.u64, memory_order_relaxed);
|
||||
if (v == old_mov_instr.u64) break;
|
||||
old_mov_instr.u64 = v;
|
||||
}
|
||||
ICache::ppc64_flush_icache_bytes(addr_at(0), NativeMovRegMem::instruction_size);
|
||||
// Set the guard value (naming of 'offset' function is misleading).
|
||||
get_patchable_instruction_handle()->set_offset(value);
|
||||
}
|
||||
|
||||
void verify() const {
|
||||
@@ -95,6 +66,12 @@ public:
|
||||
|
||||
uint* current_instruction = reinterpret_cast<uint*>(get_barrier_start_address());
|
||||
|
||||
// calculate_address_from_global_toc (compound instruction)
|
||||
verify_op_code_manually(current_instruction, MacroAssembler::is_addis(*current_instruction));
|
||||
verify_op_code_manually(current_instruction, MacroAssembler::is_addi(*current_instruction));
|
||||
|
||||
verify_op_code_manually(current_instruction, MacroAssembler::is_mtctr(*current_instruction));
|
||||
|
||||
get_patchable_instruction_handle()->verify();
|
||||
current_instruction += 2;
|
||||
|
||||
@@ -103,12 +80,6 @@ public:
|
||||
// cmpw (mnemonic)
|
||||
verify_op_code(current_instruction, Assembler::CMP_OPCODE);
|
||||
|
||||
// calculate_address_from_global_toc (compound instruction)
|
||||
verify_op_code_manually(current_instruction, MacroAssembler::is_addis(*current_instruction));
|
||||
verify_op_code_manually(current_instruction, MacroAssembler::is_addi(*current_instruction));
|
||||
|
||||
verify_op_code_manually(current_instruction, MacroAssembler::is_mtctr(*current_instruction));
|
||||
|
||||
// bnectrl (mnemonic) (weak check; not checking the exact type)
|
||||
verify_op_code(current_instruction, Assembler::BCCTR_OPCODE);
|
||||
|
||||
@@ -146,13 +117,13 @@ void BarrierSetNMethod::deoptimize(nmethod* nm, address* return_address_ptr) {
|
||||
// Thus, there's nothing to do here.
|
||||
}
|
||||
|
||||
void BarrierSetNMethod::set_guard_value(nmethod* nm, int value, int bit_mask) {
|
||||
void BarrierSetNMethod::set_guard_value(nmethod* nm, int value) {
|
||||
if (!supports_entry_barrier(nm)) {
|
||||
return;
|
||||
}
|
||||
|
||||
NativeNMethodBarrier* barrier = get_nmethod_barrier(nm);
|
||||
barrier->release_set_guard_value(value, bit_mask);
|
||||
barrier->release_set_guard_value(value);
|
||||
}
|
||||
|
||||
int BarrierSetNMethod::guard_value(nmethod* nm) {
|
||||
|
||||
@@ -462,7 +462,7 @@ class NativeMovRegMem: public NativeInstruction {
|
||||
return ((*hi_ptr) << 16) | ((*lo_ptr) & 0xFFFF);
|
||||
}
|
||||
|
||||
void set_offset(intptr_t x, bool flush_icache = true) {
|
||||
void set_offset(intptr_t x) {
|
||||
#ifdef VM_LITTLE_ENDIAN
|
||||
short *hi_ptr = (short*)(addr_at(0));
|
||||
short *lo_ptr = (short*)(addr_at(4));
|
||||
@@ -472,9 +472,7 @@ class NativeMovRegMem: public NativeInstruction {
|
||||
#endif
|
||||
*hi_ptr = x >> 16;
|
||||
*lo_ptr = x & 0xFFFF;
|
||||
if (flush_icache) {
|
||||
ICache::ppc64_flush_icache_bytes(addr_at(0), NativeMovRegMem::instruction_size);
|
||||
}
|
||||
ICache::ppc64_flush_icache_bytes(addr_at(0), NativeMovRegMem::instruction_size);
|
||||
}
|
||||
|
||||
void add_offset_in_bytes(intptr_t radd_offset) {
|
||||
|
||||
@@ -4920,6 +4920,10 @@ attributes %{
|
||||
|
||||
// ...in one line
|
||||
instruction_fetch_units = 1
|
||||
|
||||
// Unused, list one so that array generated by adlc is not empty.
|
||||
// Aix compiler chokes if _nop_count = 0.
|
||||
nops(fxNop);
|
||||
%}
|
||||
|
||||
//----------RESOURCES----------------------------------------------------------
|
||||
|
||||
@@ -109,22 +109,8 @@ public:
|
||||
return Atomic::load_acquire(guard_addr());
|
||||
}
|
||||
|
||||
void set_value(int value, int bit_mask) {
|
||||
if (bit_mask == ~0) {
|
||||
Atomic::release_store(guard_addr(), value);
|
||||
return;
|
||||
}
|
||||
assert((value & ~bit_mask) == 0, "trying to set bits outside the mask");
|
||||
value &= bit_mask;
|
||||
int old_value = Atomic::load(guard_addr());
|
||||
while (true) {
|
||||
// Only bits in the mask are changed
|
||||
int new_value = value | (old_value & ~bit_mask);
|
||||
if (new_value == old_value) break;
|
||||
int v = Atomic::cmpxchg(guard_addr(), old_value, new_value, memory_order_release);
|
||||
if (v == old_value) break;
|
||||
old_value = v;
|
||||
}
|
||||
void set_value(int value) {
|
||||
Atomic::release_store(guard_addr(), value);
|
||||
}
|
||||
|
||||
bool check_barrier(err_msg& msg) const;
|
||||
@@ -206,7 +192,7 @@ void BarrierSetNMethod::deoptimize(nmethod* nm, address* return_address_ptr) {
|
||||
new_frame->pc = SharedRuntime::get_handle_wrong_method_stub();
|
||||
}
|
||||
|
||||
void BarrierSetNMethod::set_guard_value(nmethod* nm, int value, int bit_mask) {
|
||||
void BarrierSetNMethod::set_guard_value(nmethod* nm, int value) {
|
||||
if (!supports_entry_barrier(nm)) {
|
||||
return;
|
||||
}
|
||||
@@ -223,7 +209,7 @@ void BarrierSetNMethod::set_guard_value(nmethod* nm, int value, int bit_mask) {
|
||||
}
|
||||
|
||||
NativeNMethodBarrier barrier(nm);
|
||||
barrier.set_value(value, bit_mask);
|
||||
barrier.set_value(value);
|
||||
}
|
||||
|
||||
int BarrierSetNMethod::guard_value(nmethod* nm) {
|
||||
|
||||
@@ -3845,6 +3845,9 @@ attributes %{
|
||||
|
||||
// ...in one line.
|
||||
instruction_fetch_units = 1;
|
||||
|
||||
// List of nop instructions
|
||||
nops( MachNop );
|
||||
%}
|
||||
|
||||
// We don't use an actual pipeline model so don't care about resources
|
||||
|
||||
@@ -182,6 +182,11 @@ void VM_Version::common_initialize() {
|
||||
}
|
||||
|
||||
if (UseZicboz) {
|
||||
if (zicboz_block_size.enabled()) {
|
||||
assert(UseZic64b ? zicboz_block_size.value()== 64 : true, "Zicboz block size should be 64 when UseZic64b is true");
|
||||
assert(is_power_of_2(zicboz_block_size.value()), "CacheLineSize must be a power of 2");
|
||||
FLAG_SET_DEFAULT(CacheLineSize, zicboz_block_size.value());
|
||||
}
|
||||
if (FLAG_IS_DEFAULT(UseBlockZeroing)) {
|
||||
FLAG_SET_DEFAULT(UseBlockZeroing, true);
|
||||
}
|
||||
|
||||
@@ -86,27 +86,25 @@ 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, 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); \
|
||||
} \
|
||||
} else { \
|
||||
/* Sync CPU features with flags */ \
|
||||
if (!flag) { \
|
||||
disable_feature(); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
|
||||
#define NO_UPDATE_DEFAULT \
|
||||
void update_flag() {} \
|
||||
@@ -162,45 +160,46 @@ class VM_Version : public Abstract_VM_Version {
|
||||
|
||||
// Note: the order matters, depender should be after their dependee. E.g. ext_V before ext_Zvbb.
|
||||
// declaration name , extension name, bit pos ,in str, mapped flag)
|
||||
#define RV_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)) \
|
||||
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(unaligned_access, "Unaligned" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \
|
||||
decl(satp_mode , "SATP" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \
|
||||
#define RV_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)) \
|
||||
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(unaligned_access , "Unaligned" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \
|
||||
decl(satp_mode , "SATP" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \
|
||||
decl(zicboz_block_size, "ZicbozBlockSize", RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \
|
||||
|
||||
#define DECLARE_RV_FEATURE(NAME, PRETTY, BIT, FSTRING, FLAGF) \
|
||||
struct NAME##RVFeatureValue : public RVFeatureValue { \
|
||||
|
||||
@@ -53,26 +53,11 @@ class NativeMethodBarrier: public NativeInstruction {
|
||||
return *((int32_t*)data_addr);
|
||||
}
|
||||
|
||||
void set_guard_value(int value, int bit_mask) {
|
||||
if (bit_mask == ~0) {
|
||||
int32_t* data_addr = (int32_t*)get_patchable_data_address();
|
||||
|
||||
// Set guard instruction value
|
||||
*data_addr = value;
|
||||
return;
|
||||
}
|
||||
assert((value & ~bit_mask) == 0, "trying to set bits outside the mask");
|
||||
value &= bit_mask;
|
||||
void set_guard_value(int value) {
|
||||
int32_t* data_addr = (int32_t*)get_patchable_data_address();
|
||||
int old_value = Atomic::load(data_addr);
|
||||
while (true) {
|
||||
// Only bits in the mask are changed
|
||||
int new_value = value | (old_value & ~bit_mask);
|
||||
if (new_value == old_value) break;
|
||||
int v = Atomic::cmpxchg(data_addr, old_value, new_value, memory_order_release);
|
||||
if (v == old_value) break;
|
||||
old_value = v;
|
||||
}
|
||||
|
||||
// Set guard instruction value
|
||||
*data_addr = value;
|
||||
}
|
||||
|
||||
#ifdef ASSERT
|
||||
@@ -115,13 +100,13 @@ void BarrierSetNMethod::deoptimize(nmethod* nm, address* return_address_ptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
void BarrierSetNMethod::set_guard_value(nmethod* nm, int value, int bit_mask) {
|
||||
void BarrierSetNMethod::set_guard_value(nmethod* nm, int value) {
|
||||
if (!supports_entry_barrier(nm)) {
|
||||
return;
|
||||
}
|
||||
|
||||
NativeMethodBarrier* barrier = get_nmethod_barrier(nm);
|
||||
barrier->set_guard_value(value, bit_mask);
|
||||
barrier->set_guard_value(value);
|
||||
}
|
||||
|
||||
int BarrierSetNMethod::guard_value(nmethod* nm) {
|
||||
|
||||
@@ -50,31 +50,8 @@ public:
|
||||
address instruction_address() const { return addr_at(0); }
|
||||
address immediate_address() const { return addr_at(imm_offset); }
|
||||
|
||||
NativeNMethodCmpBarrier* nativeNMethodCmpBarrier_at(address a) { return (NativeNMethodCmpBarrier*)a; }
|
||||
|
||||
jint get_immediate() const { return int_at(imm_offset); }
|
||||
void set_immediate(jint imm, int bit_mask) {
|
||||
if (bit_mask == ~0) {
|
||||
set_int_at(imm_offset, imm);
|
||||
return;
|
||||
}
|
||||
|
||||
assert((imm & ~bit_mask) == 0, "trying to set bits outside the mask");
|
||||
imm &= bit_mask;
|
||||
|
||||
assert(align_up(immediate_address(), sizeof(jint)) ==
|
||||
align_down(immediate_address(), sizeof(jint)), "immediate not aligned");
|
||||
jint* data_addr = (jint*)immediate_address();
|
||||
jint old_value = Atomic::load(data_addr);
|
||||
while (true) {
|
||||
// Only bits in the mask are changed
|
||||
jint new_value = imm | (old_value & ~bit_mask);
|
||||
if (new_value == old_value) break;
|
||||
jint v = Atomic::cmpxchg(data_addr, old_value, new_value, memory_order_release);
|
||||
if (v == old_value) break;
|
||||
old_value = v;
|
||||
}
|
||||
}
|
||||
void set_immediate(jint imm) { set_int_at(imm_offset, imm); }
|
||||
bool check_barrier(err_msg& msg) const;
|
||||
void verify() const {
|
||||
#ifdef ASSERT
|
||||
@@ -182,13 +159,13 @@ static NativeNMethodCmpBarrier* native_nmethod_barrier(nmethod* nm) {
|
||||
return barrier;
|
||||
}
|
||||
|
||||
void BarrierSetNMethod::set_guard_value(nmethod* nm, int value, int bit_mask) {
|
||||
void BarrierSetNMethod::set_guard_value(nmethod* nm, int value) {
|
||||
if (!supports_entry_barrier(nm)) {
|
||||
return;
|
||||
}
|
||||
|
||||
NativeNMethodCmpBarrier* cmp = native_nmethod_barrier(nm);
|
||||
cmp->set_immediate(value, bit_mask);
|
||||
cmp->set_immediate(value);
|
||||
}
|
||||
|
||||
int BarrierSetNMethod::guard_value(nmethod* nm) {
|
||||
|
||||
@@ -3429,6 +3429,9 @@ attributes %{
|
||||
instruction_unit_size = 1; // An instruction is 1 bytes long
|
||||
instruction_fetch_unit_size = 16; // The processor fetches one line
|
||||
instruction_fetch_units = 1; // of 16 bytes
|
||||
|
||||
// List of nop instructions
|
||||
nops( MachNop );
|
||||
%}
|
||||
|
||||
//----------RESOURCES----------------------------------------------------------
|
||||
|
||||
@@ -29,7 +29,7 @@ void BarrierSetNMethod::deoptimize(nmethod* nm, address* return_address_ptr) {
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
|
||||
void BarrierSetNMethod::set_guard_value(nmethod* nm, int value, int bit_mask) {
|
||||
void BarrierSetNMethod::set_guard_value(nmethod* nm, int value) {
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
|
||||
|
||||
@@ -24,19 +24,19 @@
|
||||
|
||||
#include "logging/log.hpp"
|
||||
#include "memory/allocation.inline.hpp"
|
||||
#include "os_posix.hpp"
|
||||
#include "runtime/interfaceSupport.inline.hpp"
|
||||
#include "runtime/os.inline.hpp"
|
||||
#include "os_posix.hpp"
|
||||
#include "services/attachListener.hpp"
|
||||
#include "utilities/checkedCast.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
|
||||
#include <signal.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/un.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#if INCLUDE_SERVICES
|
||||
#ifndef AIX
|
||||
|
||||
@@ -70,13 +70,14 @@
|
||||
#include <grp.h>
|
||||
#include <locale.h>
|
||||
#include <netdb.h>
|
||||
#include <pthread.h>
|
||||
#include <pwd.h>
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <spawn.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/socket.h>
|
||||
#include <spawn.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/times.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
@@ -30,9 +30,9 @@
|
||||
#include "runtime/mutex.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
|
||||
#include <netdb.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
|
||||
// Aix does not have NUMA support but need these for compilation.
|
||||
inline bool os::numa_has_group_homing() { AIX_ONLY(ShouldNotReachHere();) return false; }
|
||||
|
||||
@@ -40,14 +40,15 @@
|
||||
#include "os_linux.hpp"
|
||||
#endif
|
||||
|
||||
# include <errno.h>
|
||||
# include <pwd.h>
|
||||
# include <signal.h>
|
||||
# include <stdio.h>
|
||||
# include <sys/mman.h>
|
||||
# include <sys/stat.h>
|
||||
// put OS-includes here
|
||||
# include <sys/types.h>
|
||||
# include <sys/mman.h>
|
||||
# include <errno.h>
|
||||
# include <stdio.h>
|
||||
# include <unistd.h>
|
||||
# include <sys/stat.h>
|
||||
# include <signal.h>
|
||||
# include <pwd.h>
|
||||
|
||||
#if defined(LINUX)
|
||||
# include <sys/file.h>
|
||||
|
||||
@@ -32,8 +32,8 @@
|
||||
#ifdef SAFEFETCH_METHOD_SIGSETJMP
|
||||
|
||||
// For SafeFetch we need POSIX TLS and sigsetjmp/longjmp.
|
||||
#include <pthread.h>
|
||||
#include <setjmp.h>
|
||||
#include <pthread.h>
|
||||
static pthread_key_t g_jmpbuf_key;
|
||||
|
||||
struct InitTLSKey { InitTLSKey() { pthread_key_create(&g_jmpbuf_key, nullptr); } };
|
||||
|
||||
@@ -25,10 +25,9 @@
|
||||
#ifndef __APPLE__
|
||||
#include "os_posix.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
#include "utilities/debug.hpp"
|
||||
// POSIX unnamed semaphores are not supported on OS X.
|
||||
#include "semaphore_posix.hpp"
|
||||
#include "utilities/debug.hpp"
|
||||
|
||||
#include <semaphore.h>
|
||||
|
||||
PosixSemaphore::PosixSemaphore(uint value) {
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
|
||||
#include "runtime/threadLocalStorage.hpp"
|
||||
#include "utilities/debug.hpp"
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
static pthread_key_t _thread_key;
|
||||
|
||||
@@ -88,6 +88,7 @@
|
||||
#define RISCV_HWPROBE_MISALIGNED_FAST (3 << 0)
|
||||
#define RISCV_HWPROBE_MISALIGNED_UNSUPPORTED (4 << 0)
|
||||
#define RISCV_HWPROBE_MISALIGNED_MASK (7 << 0)
|
||||
#define RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE 6
|
||||
|
||||
#ifndef NR_riscv_hwprobe
|
||||
#ifndef NR_arch_specific_syscall
|
||||
@@ -114,7 +115,8 @@ static struct riscv_hwprobe query[] = {{RISCV_HWPROBE_KEY_MVENDORID, 0},
|
||||
{RISCV_HWPROBE_KEY_MIMPID, 0},
|
||||
{RISCV_HWPROBE_KEY_BASE_BEHAVIOR, 0},
|
||||
{RISCV_HWPROBE_KEY_IMA_EXT_0, 0},
|
||||
{RISCV_HWPROBE_KEY_CPUPERF_0, 0}};
|
||||
{RISCV_HWPROBE_KEY_CPUPERF_0, 0},
|
||||
{RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE, 0}};
|
||||
|
||||
bool RiscvHwprobe::probe_features() {
|
||||
assert(!rw_hwprobe_completed, "Called twice.");
|
||||
@@ -244,4 +246,7 @@ void RiscvHwprobe::add_features_from_query_result() {
|
||||
VM_Version::unaligned_access.enable_feature(
|
||||
query[RISCV_HWPROBE_KEY_CPUPERF_0].value & RISCV_HWPROBE_MISALIGNED_MASK);
|
||||
}
|
||||
if (is_valid(RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE)) {
|
||||
VM_Version::zicboz_block_size.enable_feature(query[RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE].value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@@ -1507,8 +1507,36 @@ void ADLParser::pipe_parse(void) {
|
||||
}
|
||||
|
||||
if (!strcmp(ident, "nops")) {
|
||||
parse_err(WARN, "Using obsolete token, nops");
|
||||
skipws();
|
||||
if (_curchar != '(') {
|
||||
parse_err(SYNERR, "expected `(`, found '%c'\n", _curchar);
|
||||
break;
|
||||
}
|
||||
|
||||
next_char(); skipws();
|
||||
|
||||
while (_curchar != ')') {
|
||||
ident = get_ident();
|
||||
if (ident == nullptr) {
|
||||
parse_err(SYNERR, "expected identifier for nop instruction, found '%c'\n", _curchar);
|
||||
break;
|
||||
}
|
||||
|
||||
pipeline->_noplist.addName(ident);
|
||||
pipeline->_nopcnt++;
|
||||
skipws();
|
||||
|
||||
if (_curchar == ',') {
|
||||
next_char(); skipws();
|
||||
}
|
||||
}
|
||||
|
||||
next_char(); skipws();
|
||||
|
||||
if (_curchar == ';') {
|
||||
next_char(); skipws();
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 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
|
||||
@@ -511,6 +511,8 @@ PipelineForm::PipelineForm()
|
||||
, _stagecnt (0)
|
||||
, _classlist ()
|
||||
, _classcnt (0)
|
||||
, _noplist ()
|
||||
, _nopcnt (0)
|
||||
, _variableSizeInstrs (false)
|
||||
, _branchHasDelaySlot (false)
|
||||
, _maxInstrsPerBundle (0)
|
||||
@@ -531,6 +533,7 @@ void PipelineForm::output(FILE *fp) { // Write info to output files
|
||||
const char *res;
|
||||
const char *stage;
|
||||
const char *cls;
|
||||
const char *nop;
|
||||
int count = 0;
|
||||
|
||||
fprintf(fp,"\nPipeline:");
|
||||
@@ -571,6 +574,9 @@ void PipelineForm::output(FILE *fp) { // Write info to output files
|
||||
for ( _classlist.reset(); (cls = _classlist.iter()) != nullptr; )
|
||||
_classdict[cls]->is_pipeclass()->output(fp);
|
||||
|
||||
fprintf(fp,"\nNop Instructions:");
|
||||
for ( _noplist.reset(); (nop = _noplist.iter()) != nullptr; )
|
||||
fprintf(fp, " \"%s\"", nop);
|
||||
fprintf(fp,"\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 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
|
||||
@@ -386,6 +386,9 @@ public:
|
||||
FormDict _classdict; // Class Name -> PipeClassForm mapping
|
||||
int _classcnt; // Number of classes
|
||||
|
||||
NameList _noplist; // List of NOP instructions
|
||||
int _nopcnt; // Number of nop instructions
|
||||
|
||||
bool _variableSizeInstrs; // Indicates if this architecture has variable sized instructions
|
||||
bool _branchHasDelaySlot; // Indicates that branches have delay slot instructions
|
||||
int _maxInstrsPerBundle; // Indicates the maximum number of instructions for ILP
|
||||
|
||||
@@ -977,6 +977,18 @@ void ArchDesc::build_pipe_classes(FILE *fp_cpp) {
|
||||
}
|
||||
fprintf(fp_cpp, "}\n\n");
|
||||
|
||||
// Output the list of nop nodes
|
||||
fprintf(fp_cpp, "// Descriptions for emitting different functional unit nops\n");
|
||||
const char *nop;
|
||||
int nopcnt = 0;
|
||||
for ( _pipeline->_noplist.reset(); (nop = _pipeline->_noplist.iter()) != nullptr; nopcnt++ );
|
||||
|
||||
fprintf(fp_cpp, "void Bundle::initialize_nops(MachNode * nop_list[%d]) {\n", nopcnt);
|
||||
int i = 0;
|
||||
for ( _pipeline->_noplist.reset(); (nop = _pipeline->_noplist.iter()) != nullptr; i++ ) {
|
||||
fprintf(fp_cpp, " nop_list[%d] = (MachNode *) new %sNode();\n", i, nop);
|
||||
}
|
||||
fprintf(fp_cpp, "};\n\n");
|
||||
fprintf(fp_cpp, "#ifndef PRODUCT\n");
|
||||
fprintf(fp_cpp, "void Bundle::dump(outputStream *st) const {\n");
|
||||
fprintf(fp_cpp, " static const char * bundle_flags[] = {\n");
|
||||
@@ -992,7 +1004,7 @@ void ArchDesc::build_pipe_classes(FILE *fp_cpp) {
|
||||
fprintf(fp_cpp, " static const char *resource_names[%d] = {", _pipeline->_rescount);
|
||||
// Don't add compound resources to the list of resource names
|
||||
const char* resource;
|
||||
int i = 0;
|
||||
i = 0;
|
||||
for (_pipeline->_reslist.reset(); (resource = _pipeline->_reslist.iter()) != nullptr;) {
|
||||
if (_pipeline->_resdict[resource]->is_resource()->is_discrete()) {
|
||||
fprintf(fp_cpp, " \"%s\"%c", resource, i < _pipeline->_rescount - 1 ? ',' : ' ');
|
||||
|
||||
@@ -1115,6 +1115,12 @@ void ArchDesc::declare_pipe_classes(FILE *fp_hpp) {
|
||||
fprintf(fp_hpp, " bool use_delay() { return ((_flags & _use_delay) != 0); }\n");
|
||||
fprintf(fp_hpp, " bool used_in_delay() { return ((_flags & _used_in_delay) != 0); }\n\n");
|
||||
|
||||
fprintf(fp_hpp, " enum {\n");
|
||||
fprintf(fp_hpp, " _nop_count = %d\n",
|
||||
_pipeline->_nopcnt);
|
||||
fprintf(fp_hpp, " };\n\n");
|
||||
fprintf(fp_hpp, " static void initialize_nops(MachNode *nop_list[%d]);\n\n",
|
||||
_pipeline->_nopcnt);
|
||||
fprintf(fp_hpp, "#ifndef PRODUCT\n");
|
||||
fprintf(fp_hpp, " void dump(outputStream *st = tty) const;\n");
|
||||
fprintf(fp_hpp, "#endif\n");
|
||||
|
||||
@@ -2583,64 +2583,85 @@ class BacktraceIterator : public StackObj {
|
||||
};
|
||||
|
||||
|
||||
// Print stack trace element to the specified output stream.
|
||||
// The output is formatted into a stringStream and written to the outputStream in one step.
|
||||
// Print stack trace element to resource allocated buffer
|
||||
static void print_stack_element_to_stream(outputStream* st, Handle mirror, int method_id,
|
||||
int version, int bci, Symbol* name) {
|
||||
ResourceMark rm;
|
||||
stringStream ss;
|
||||
|
||||
// Get strings and string lengths
|
||||
InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(mirror()));
|
||||
const char* klass_name = holder->external_name();
|
||||
char* method_name = name->as_C_string();
|
||||
ss.print("\tat %s.%s(", klass_name, method_name);
|
||||
int buf_len = (int)strlen(klass_name);
|
||||
|
||||
// Print module information
|
||||
ModuleEntry* module = holder->module();
|
||||
if (module->is_named()) {
|
||||
char* module_name = module->name()->as_C_string();
|
||||
if (module->version() != nullptr) {
|
||||
char* module_version = module->version()->as_C_string();
|
||||
ss.print("%s@%s/", module_name, module_version);
|
||||
} else {
|
||||
ss.print("%s/", module_name);
|
||||
}
|
||||
}
|
||||
char* method_name = name->as_C_string();
|
||||
buf_len += (int)strlen(method_name);
|
||||
|
||||
char* source_file_name = nullptr;
|
||||
Symbol* source = Backtrace::get_source_file_name(holder, version);
|
||||
if (source != nullptr) {
|
||||
source_file_name = source->as_C_string();
|
||||
buf_len += (int)strlen(source_file_name);
|
||||
}
|
||||
|
||||
char *module_name = nullptr, *module_version = nullptr;
|
||||
ModuleEntry* module = holder->module();
|
||||
if (module->is_named()) {
|
||||
module_name = module->name()->as_C_string();
|
||||
buf_len += (int)strlen(module_name);
|
||||
if (module->version() != nullptr) {
|
||||
module_version = module->version()->as_C_string();
|
||||
buf_len += (int)strlen(module_version);
|
||||
}
|
||||
}
|
||||
|
||||
// Allocate temporary buffer with extra space for formatting and line number
|
||||
const size_t buf_size = buf_len + 64;
|
||||
char* buf = NEW_RESOURCE_ARRAY(char, buf_size);
|
||||
|
||||
// Print stack trace line in buffer
|
||||
int buf_off = os::snprintf(buf, buf_size, "\tat %s.%s(", klass_name, method_name);
|
||||
assert(static_cast<size_t>(buf_off) < buf_size, "buffer is wrong size");
|
||||
// Print module information
|
||||
if (module_name != nullptr) {
|
||||
if (module_version != nullptr) {
|
||||
buf_off += os::snprintf(buf + buf_off, buf_size - buf_off, "%s@%s/", module_name, module_version);
|
||||
assert(static_cast<size_t>(buf_off) < buf_size, "buffer is wrong size");
|
||||
} else {
|
||||
buf_off += os::snprintf(buf + buf_off, buf_size - buf_off, "%s/", module_name);
|
||||
assert(static_cast<size_t>(buf_off) < buf_size, "buffer is wrong size");
|
||||
}
|
||||
}
|
||||
|
||||
// The method can be null if the requested class version is gone
|
||||
Method* method = holder->method_with_orig_idnum(method_id, version);
|
||||
if (!version_matches(method, version)) {
|
||||
ss.print("Redefined)");
|
||||
strcat(buf, "Redefined)");
|
||||
} else {
|
||||
int line_number = Backtrace::get_line_number(method, bci);
|
||||
if (line_number == -2) {
|
||||
ss.print("Native Method)");
|
||||
strcat(buf, "Native Method)");
|
||||
} else {
|
||||
if (source_file_name != nullptr && (line_number != -1)) {
|
||||
// Sourcename and linenumber
|
||||
ss.print("%s:%d)", source_file_name, line_number);
|
||||
buf_off += os::snprintf(buf + buf_off, buf_size - buf_off, "%s:%d)", source_file_name, line_number);
|
||||
assert(static_cast<size_t>(buf_off) < buf_size, "buffer is wrong size");
|
||||
} else if (source_file_name != nullptr) {
|
||||
// Just sourcename
|
||||
ss.print("%s)", source_file_name);
|
||||
buf_off += os::snprintf(buf + buf_off, buf_size - buf_off, "%s)", source_file_name);
|
||||
assert(static_cast<size_t>(buf_off) < buf_size, "buffer is wrong size");
|
||||
} else {
|
||||
// Neither sourcename nor linenumber
|
||||
ss.print("Unknown Source)");
|
||||
buf_off += os::snprintf(buf + buf_off, buf_size - buf_off, "Unknown Source)");
|
||||
assert(static_cast<size_t>(buf_off) < buf_size, "buffer is wrong size");
|
||||
}
|
||||
nmethod* nm = method->code();
|
||||
if (WizardMode && nm != nullptr) {
|
||||
ss.print("(nmethod " INTPTR_FORMAT ")", p2i(nm));
|
||||
os::snprintf_checked(buf + buf_off, buf_size - buf_off, "(nmethod " INTPTR_FORMAT ")", (intptr_t)nm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ss.cr();
|
||||
st->print_raw(ss.freeze(), ss.size());
|
||||
st->print_cr("%s", buf);
|
||||
}
|
||||
|
||||
void java_lang_Throwable::print_stack_element(outputStream *st, Method* method, int bci) {
|
||||
|
||||
@@ -72,12 +72,21 @@ bool BarrierSetNMethod::supports_entry_barrier(nmethod* nm) {
|
||||
}
|
||||
|
||||
void BarrierSetNMethod::disarm(nmethod* nm) {
|
||||
set_guard_value(nm, disarmed_guard_value());
|
||||
guard_with(nm, disarmed_guard_value());
|
||||
}
|
||||
|
||||
void BarrierSetNMethod::guard_with(nmethod* nm, int value) {
|
||||
assert((value & not_entrant) == 0, "not_entrant bit is reserved");
|
||||
set_guard_value(nm, value);
|
||||
// Enter critical section. Does not block for safepoint.
|
||||
ConditionalMutexLocker ml(NMethodEntryBarrier_lock, !NMethodEntryBarrier_lock->owned_by_self(), Mutex::_no_safepoint_check_flag);
|
||||
// Do not undo sticky bit
|
||||
if (is_not_entrant(nm)) {
|
||||
value |= not_entrant;
|
||||
}
|
||||
if (guard_value(nm) != value) {
|
||||
// Patch the code only if needed.
|
||||
set_guard_value(nm, value);
|
||||
}
|
||||
}
|
||||
|
||||
bool BarrierSetNMethod::is_armed(nmethod* nm) {
|
||||
@@ -110,8 +119,6 @@ bool BarrierSetNMethod::nmethod_entry_barrier(nmethod* nm) {
|
||||
return true;
|
||||
}
|
||||
|
||||
MACOS_AARCH64_ONLY(ThreadWXEnable wx(WXWrite, Thread::current()));
|
||||
|
||||
// If the nmethod is the only thing pointing to the oops, and we are using a
|
||||
// SATB GC, then it is important that this code marks them live.
|
||||
// Also, with concurrent GC, it is possible that frames in continuation stack
|
||||
@@ -172,6 +179,10 @@ void BarrierSetNMethod::arm_all_nmethods() {
|
||||
}
|
||||
|
||||
int BarrierSetNMethod::nmethod_stub_entry_barrier(address* return_address_ptr) {
|
||||
// Enable WXWrite: the function is called directly from nmethod_entry_barrier
|
||||
// stub.
|
||||
MACOS_AARCH64_ONLY(ThreadWXEnable wx(WXWrite, Thread::current()));
|
||||
|
||||
address return_address = *return_address_ptr;
|
||||
AARCH64_PORT_ONLY(return_address = pauth_strip_pointer(return_address));
|
||||
CodeBlob* cb = CodeCache::find_blob(return_address);
|
||||
@@ -232,7 +243,13 @@ oop BarrierSetNMethod::oop_load_phantom(const nmethod* nm, int index) {
|
||||
// nmethod_stub_entry_barrier() may appear to be spurious, because is_armed() still returns
|
||||
// false and nmethod_entry_barrier() is not called.
|
||||
void BarrierSetNMethod::make_not_entrant(nmethod* nm) {
|
||||
set_guard_value(nm, not_entrant, not_entrant);
|
||||
// Enter critical section. Does not block for safepoint.
|
||||
ConditionalMutexLocker ml(NMethodEntryBarrier_lock, !NMethodEntryBarrier_lock->owned_by_self(), Mutex::_no_safepoint_check_flag);
|
||||
int value = guard_value(nm) | not_entrant;
|
||||
if (guard_value(nm) != value) {
|
||||
// Patch the code only if needed.
|
||||
set_guard_value(nm, value);
|
||||
}
|
||||
}
|
||||
|
||||
bool BarrierSetNMethod::is_not_entrant(nmethod* nm) {
|
||||
|
||||
@@ -36,18 +36,17 @@ class nmethod;
|
||||
class BarrierSetNMethod: public CHeapObj<mtGC> {
|
||||
private:
|
||||
int _current_phase;
|
||||
|
||||
void deoptimize(nmethod* nm, address* return_addr_ptr);
|
||||
|
||||
protected:
|
||||
enum {
|
||||
not_entrant = 1 << 31, // armed sticky bit, see make_not_entrant
|
||||
armed = 0,
|
||||
initial = 1,
|
||||
};
|
||||
|
||||
int guard_value(nmethod* nm);
|
||||
void set_guard_value(nmethod* nm, int value, int bit_mask = ~not_entrant);
|
||||
void deoptimize(nmethod* nm, address* return_addr_ptr);
|
||||
|
||||
protected:
|
||||
virtual int guard_value(nmethod* nm);
|
||||
void set_guard_value(nmethod* nm, int value);
|
||||
|
||||
public:
|
||||
BarrierSetNMethod() : _current_phase(initial) {}
|
||||
@@ -61,13 +60,13 @@ public:
|
||||
|
||||
static int nmethod_stub_entry_barrier(address* return_address_ptr);
|
||||
bool nmethod_osr_entry_barrier(nmethod* nm);
|
||||
bool is_armed(nmethod* nm);
|
||||
virtual bool is_armed(nmethod* nm);
|
||||
void arm(nmethod* nm) { guard_with(nm, armed); }
|
||||
void disarm(nmethod* nm);
|
||||
void make_not_entrant(nmethod* nm);
|
||||
bool is_not_entrant(nmethod* nm);
|
||||
virtual void make_not_entrant(nmethod* nm);
|
||||
virtual bool is_not_entrant(nmethod* nm);
|
||||
|
||||
void guard_with(nmethod* nm, int value);
|
||||
virtual void guard_with(nmethod* nm, int value);
|
||||
|
||||
virtual void arm_all_nmethods();
|
||||
|
||||
|
||||
@@ -106,6 +106,34 @@ oop ZBarrierSetNMethod::oop_load_phantom(const nmethod* nm, int index) {
|
||||
return ZNMethod::oop_load_phantom(nm, index);
|
||||
}
|
||||
|
||||
void ZBarrierSetNMethod::guard_with(nmethod* nm, int value) {
|
||||
assert((value & not_entrant) == 0, "not_entrant bit is reserved");
|
||||
ZLocker<ZReentrantLock> locker(ZNMethod::lock_for_nmethod(nm));
|
||||
// Preserve the sticky bit
|
||||
if (is_not_entrant(nm)) {
|
||||
value |= not_entrant;
|
||||
}
|
||||
if (guard_value(nm) != value) {
|
||||
// Patch the code only if needed.
|
||||
set_guard_value(nm, value);
|
||||
}
|
||||
}
|
||||
|
||||
bool ZBarrierSetNMethod::is_armed(nmethod* nm) {
|
||||
int value = guard_value(nm) & ~not_entrant;
|
||||
return value != disarmed_guard_value();
|
||||
}
|
||||
|
||||
void ZBarrierSetNMethod::make_not_entrant(nmethod* nm) {
|
||||
ZLocker<ZReentrantLock> locker(ZNMethod::lock_for_nmethod(nm));
|
||||
int value = guard_value(nm) | not_entrant; // permanent sticky value
|
||||
set_guard_value(nm, value);
|
||||
}
|
||||
|
||||
bool ZBarrierSetNMethod::is_not_entrant(nmethod* nm) {
|
||||
return (guard_value(nm) & not_entrant) != 0;
|
||||
}
|
||||
|
||||
uintptr_t ZBarrierSetNMethod::color(nmethod* nm) {
|
||||
// color is stored at low order bits of int; conversion to uintptr_t is fine
|
||||
return uintptr_t(guard_value(nm) & ~not_entrant);
|
||||
|
||||
@@ -30,6 +30,10 @@
|
||||
class nmethod;
|
||||
|
||||
class ZBarrierSetNMethod : public BarrierSetNMethod {
|
||||
enum : int {
|
||||
not_entrant = 1 << 31, // armed sticky bit, see make_not_entrant
|
||||
};
|
||||
|
||||
protected:
|
||||
virtual bool nmethod_entry_barrier(nmethod* nm);
|
||||
|
||||
@@ -42,6 +46,10 @@ public:
|
||||
virtual oop oop_load_no_keepalive(const nmethod* nm, int index);
|
||||
virtual oop oop_load_phantom(const nmethod* nm, int index);
|
||||
|
||||
virtual void make_not_entrant(nmethod* nm);
|
||||
virtual bool is_not_entrant(nmethod* nm);
|
||||
virtual void guard_with(nmethod* nm, int value);
|
||||
virtual bool is_armed(nmethod* nm);
|
||||
virtual void arm_all_nmethods() { ShouldNotCallThis(); }
|
||||
};
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "jfr/periodic/sampling/jfrCPUTimeThreadSampler.hpp"
|
||||
#include "logging/log.hpp"
|
||||
|
||||
|
||||
#if defined(LINUX)
|
||||
#include "jfr/periodic/sampling/jfrThreadSampling.hpp"
|
||||
#include "jfr/support/jfrThreadLocal.hpp"
|
||||
@@ -66,7 +67,7 @@ static JavaThread* get_java_thread_if_valid() {
|
||||
}
|
||||
|
||||
JfrCPUTimeTraceQueue::JfrCPUTimeTraceQueue(u4 capacity) :
|
||||
_data(nullptr), _capacity(capacity), _head(0), _lost_samples(0), _lost_samples_due_to_queue_full(0) {
|
||||
_data(nullptr), _capacity(capacity), _head(0), _lost_samples(0) {
|
||||
if (capacity != 0) {
|
||||
_data = JfrCHeapObj::new_array<JfrCPUTimeSampleRequest>(capacity);
|
||||
}
|
||||
@@ -109,13 +110,10 @@ void JfrCPUTimeTraceQueue::set_size(u4 size) {
|
||||
}
|
||||
|
||||
u4 JfrCPUTimeTraceQueue::capacity() const {
|
||||
return Atomic::load_acquire(&_capacity);
|
||||
return _capacity;
|
||||
}
|
||||
|
||||
void JfrCPUTimeTraceQueue::set_capacity(u4 capacity) {
|
||||
if (capacity == Atomic::load(&_capacity)) {
|
||||
return;
|
||||
}
|
||||
_head = 0;
|
||||
if (_data != nullptr) {
|
||||
assert(_capacity != 0, "invariant");
|
||||
@@ -126,7 +124,7 @@ void JfrCPUTimeTraceQueue::set_capacity(u4 capacity) {
|
||||
} else {
|
||||
_data = nullptr;
|
||||
}
|
||||
Atomic::release_store(&_capacity, capacity);
|
||||
_capacity = capacity;
|
||||
}
|
||||
|
||||
bool JfrCPUTimeTraceQueue::is_empty() const {
|
||||
@@ -142,51 +140,28 @@ void JfrCPUTimeTraceQueue::increment_lost_samples() {
|
||||
Atomic::inc(&_lost_samples);
|
||||
}
|
||||
|
||||
void JfrCPUTimeTraceQueue::increment_lost_samples_due_to_queue_full() {
|
||||
Atomic::inc(&_lost_samples_due_to_queue_full);
|
||||
}
|
||||
|
||||
u4 JfrCPUTimeTraceQueue::get_and_reset_lost_samples() {
|
||||
return Atomic::xchg(&_lost_samples, (u4)0);
|
||||
}
|
||||
|
||||
u4 JfrCPUTimeTraceQueue::get_and_reset_lost_samples_due_to_queue_full() {
|
||||
return Atomic::xchg(&_lost_samples_due_to_queue_full, (u4)0);
|
||||
void JfrCPUTimeTraceQueue::resize(u4 capacity) {
|
||||
if (capacity != _capacity) {
|
||||
set_capacity(capacity);
|
||||
}
|
||||
}
|
||||
|
||||
void JfrCPUTimeTraceQueue::init() {
|
||||
set_capacity(JfrCPUTimeTraceQueue::CPU_TIME_QUEUE_INITIAL_CAPACITY);
|
||||
void JfrCPUTimeTraceQueue::resize_for_period(u4 period_millis) {
|
||||
u4 capacity = CPU_TIME_QUEUE_CAPACITY;
|
||||
if (period_millis > 0 && period_millis < 10) {
|
||||
capacity = (u4) ((double) capacity * 10 / period_millis);
|
||||
}
|
||||
resize(capacity);
|
||||
}
|
||||
|
||||
void JfrCPUTimeTraceQueue::clear() {
|
||||
Atomic::release_store(&_head, (u4)0);
|
||||
}
|
||||
|
||||
void JfrCPUTimeTraceQueue::resize_if_needed() {
|
||||
u4 lost_samples_due_to_queue_full = get_and_reset_lost_samples_due_to_queue_full();
|
||||
if (lost_samples_due_to_queue_full == 0) {
|
||||
return;
|
||||
}
|
||||
u4 capacity = Atomic::load(&_capacity);
|
||||
if (capacity < CPU_TIME_QUEUE_MAX_CAPACITY) {
|
||||
float ratio = (float)lost_samples_due_to_queue_full / (float)capacity;
|
||||
int factor = 1;
|
||||
if (ratio > 8) { // idea is to quickly scale the queue in the worst case
|
||||
factor = ratio;
|
||||
} else if (ratio > 2) {
|
||||
factor = 8;
|
||||
} else if (ratio > 0.5) {
|
||||
factor = 4;
|
||||
} else if (ratio > 0.01) {
|
||||
factor = 2;
|
||||
}
|
||||
if (factor > 1) {
|
||||
u4 new_capacity = MIN2(CPU_TIME_QUEUE_MAX_CAPACITY, capacity * factor);
|
||||
set_capacity(new_capacity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// A throttle is either a rate or a fixed period
|
||||
class JfrCPUSamplerThrottle {
|
||||
|
||||
@@ -230,8 +205,6 @@ class JfrCPUSamplerThread : public NonJavaThread {
|
||||
volatile bool _is_async_processing_of_cpu_time_jfr_requests_triggered;
|
||||
volatile bool _warned_about_timer_creation_failure;
|
||||
volatile bool _signal_handler_installed;
|
||||
DEBUG_ONLY(volatile bool _out_of_stack_walking_enabled;)
|
||||
DEBUG_ONLY(volatile u8 _out_of_stack_walking_iterations;)
|
||||
|
||||
static const u4 STOP_SIGNAL_BIT = 0x80000000;
|
||||
|
||||
@@ -277,16 +250,6 @@ public:
|
||||
void stop_timer();
|
||||
|
||||
void trigger_async_processing_of_cpu_time_jfr_requests();
|
||||
|
||||
#ifdef ASSERT
|
||||
void set_out_of_stack_walking_enabled(bool runnable) {
|
||||
Atomic::release_store(&_out_of_stack_walking_enabled, runnable);
|
||||
}
|
||||
|
||||
u8 out_of_stack_walking_iterations() const {
|
||||
return Atomic::load(&_out_of_stack_walking_iterations);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
JfrCPUSamplerThread::JfrCPUSamplerThread(JfrCPUSamplerThrottle& throttle) :
|
||||
@@ -312,7 +275,7 @@ void JfrCPUSamplerThread::on_javathread_create(JavaThread* thread) {
|
||||
}
|
||||
JfrThreadLocal* tl = thread->jfr_thread_local();
|
||||
assert(tl != nullptr, "invariant");
|
||||
tl->cpu_time_jfr_queue().init();
|
||||
tl->cpu_time_jfr_queue().resize_for_period(_current_sampling_period_ns / 1000000);
|
||||
timer_t timerid;
|
||||
if (create_timer_for_thread(thread, timerid)) {
|
||||
tl->set_cpu_timer(&timerid);
|
||||
@@ -331,14 +294,12 @@ void JfrCPUSamplerThread::on_javathread_terminate(JavaThread* thread) {
|
||||
if (timer == nullptr) {
|
||||
return; // no timer was created for this thread
|
||||
}
|
||||
tl->acquire_cpu_time_jfr_dequeue_lock();
|
||||
tl->unset_cpu_timer();
|
||||
tl->deallocate_cpu_time_jfr_queue();
|
||||
s4 lost_samples = tl->cpu_time_jfr_queue().lost_samples();
|
||||
if (lost_samples > 0) {
|
||||
JfrCPUTimeThreadSampling::send_lost_event(JfrTicks::now(), JfrThreadLocal::thread_id(thread), lost_samples);
|
||||
}
|
||||
tl->release_cpu_time_jfr_queue_lock();
|
||||
}
|
||||
|
||||
void JfrCPUSamplerThread::start_thread() {
|
||||
@@ -391,12 +352,10 @@ void JfrCPUSamplerThread::run() {
|
||||
recompute_period_if_needed();
|
||||
last_recompute_check = os::javaTimeNanos();
|
||||
}
|
||||
DEBUG_ONLY(if (Atomic::load_acquire(&_out_of_stack_walking_enabled)) {)
|
||||
if (Atomic::cmpxchg(&_is_async_processing_of_cpu_time_jfr_requests_triggered, true, false)) {
|
||||
DEBUG_ONLY(Atomic::inc(&_out_of_stack_walking_iterations);)
|
||||
stackwalk_threads_in_native();
|
||||
}
|
||||
DEBUG_ONLY(})
|
||||
|
||||
if (Atomic::cmpxchg(&_is_async_processing_of_cpu_time_jfr_requests_triggered, true, false)) {
|
||||
stackwalk_threads_in_native();
|
||||
}
|
||||
os::naked_sleep(100);
|
||||
}
|
||||
}
|
||||
@@ -586,21 +545,6 @@ void JfrCPUTimeThreadSampling::handle_timer_signal(siginfo_t* info, void* contex
|
||||
_sampler->decrement_signal_handler_count();
|
||||
}
|
||||
|
||||
#ifdef ASSERT
|
||||
void JfrCPUTimeThreadSampling::set_out_of_stack_walking_enabled(bool runnable) {
|
||||
if (_instance != nullptr && _instance->_sampler != nullptr) {
|
||||
_instance->_sampler->set_out_of_stack_walking_enabled(runnable);
|
||||
}
|
||||
}
|
||||
|
||||
u8 JfrCPUTimeThreadSampling::out_of_stack_walking_iterations() {
|
||||
if (_instance != nullptr && _instance->_sampler != nullptr) {
|
||||
return _instance->_sampler->out_of_stack_walking_iterations();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void JfrCPUSamplerThread::sample_thread(JfrSampleRequest& request, void* ucontext, JavaThread* jt, JfrThreadLocal* tl, JfrTicks& now) {
|
||||
JfrSampleRequestBuilder::build_cpu_time_sample_request(request, ucontext, jt, jt->jfr_thread_local(), now);
|
||||
}
|
||||
@@ -646,7 +590,6 @@ void JfrCPUSamplerThread::handle_timer_signal(siginfo_t* info, void* context) {
|
||||
}
|
||||
} else {
|
||||
queue.increment_lost_samples();
|
||||
queue.increment_lost_samples_due_to_queue_full();
|
||||
}
|
||||
|
||||
if (jt->thread_state() == _thread_in_native) {
|
||||
@@ -864,10 +807,4 @@ void JfrCPUTimeThreadSampling::on_javathread_create(JavaThread* thread) {
|
||||
void JfrCPUTimeThreadSampling::on_javathread_terminate(JavaThread* thread) {
|
||||
}
|
||||
|
||||
#ifdef ASSERT
|
||||
static void set_out_of_stack_walking_enabled(bool runnable) {
|
||||
warn();
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // defined(LINUX) && defined(INCLUDE_JFR)
|
||||
|
||||
@@ -50,15 +50,12 @@ class JfrCPUTimeTraceQueue {
|
||||
static const u4 CPU_TIME_QUEUE_CAPACITY = 500;
|
||||
|
||||
JfrCPUTimeSampleRequest* _data;
|
||||
volatile u4 _capacity;
|
||||
u4 _capacity;
|
||||
// next unfilled index
|
||||
volatile u4 _head;
|
||||
|
||||
volatile u4 _lost_samples;
|
||||
volatile u4 _lost_samples_due_to_queue_full;
|
||||
|
||||
static const u4 CPU_TIME_QUEUE_INITIAL_CAPACITY = 20;
|
||||
static const u4 CPU_TIME_QUEUE_MAX_CAPACITY = 2000;
|
||||
public:
|
||||
JfrCPUTimeTraceQueue(u4 capacity);
|
||||
|
||||
@@ -84,17 +81,12 @@ public:
|
||||
|
||||
void increment_lost_samples();
|
||||
|
||||
void increment_lost_samples_due_to_queue_full();
|
||||
|
||||
// returns the previous lost samples count
|
||||
u4 get_and_reset_lost_samples();
|
||||
|
||||
u4 get_and_reset_lost_samples_due_to_queue_full();
|
||||
void resize(u4 capacity);
|
||||
|
||||
void resize_if_needed();
|
||||
|
||||
// init the queue capacity
|
||||
void init();
|
||||
void resize_for_period(u4 period_millis);
|
||||
|
||||
void clear();
|
||||
|
||||
@@ -138,10 +130,6 @@ class JfrCPUTimeThreadSampling : public JfrCHeapObj {
|
||||
static void send_lost_event(const JfrTicks& time, traceid tid, s4 lost_samples);
|
||||
|
||||
static void trigger_async_processing_of_cpu_time_jfr_requests();
|
||||
|
||||
DEBUG_ONLY(static void set_out_of_stack_walking_enabled(bool runnable);)
|
||||
|
||||
DEBUG_ONLY(static u8 out_of_stack_walking_iterations();)
|
||||
};
|
||||
|
||||
#else
|
||||
@@ -162,8 +150,6 @@ private:
|
||||
|
||||
static void on_javathread_create(JavaThread* thread);
|
||||
static void on_javathread_terminate(JavaThread* thread);
|
||||
DEBUG_ONLY(static void set_out_of_stack_walking_enabled(bool runnable));
|
||||
DEBUG_ONLY(static u8 out_of_stack_walking_iterations();)
|
||||
};
|
||||
|
||||
#endif // defined(LINUX)
|
||||
|
||||
@@ -368,7 +368,6 @@ static void drain_enqueued_cpu_time_requests(const JfrTicks& now, JfrThreadLocal
|
||||
tl->set_has_cpu_time_jfr_requests(false);
|
||||
if (queue.lost_samples() > 0) {
|
||||
JfrCPUTimeThreadSampling::send_lost_event( now, JfrThreadLocal::thread_id(jt), queue.get_and_reset_lost_samples());
|
||||
queue.resize_if_needed();
|
||||
}
|
||||
if (lock) {
|
||||
tl->release_cpu_time_jfr_queue_lock();
|
||||
|
||||
@@ -656,7 +656,7 @@ JfrCPUTimeTraceQueue& JfrThreadLocal::cpu_time_jfr_queue() {
|
||||
}
|
||||
|
||||
void JfrThreadLocal::deallocate_cpu_time_jfr_queue() {
|
||||
cpu_time_jfr_queue().set_capacity(0);
|
||||
cpu_time_jfr_queue().resize(0);
|
||||
}
|
||||
|
||||
void JfrThreadLocal::set_do_async_processing_of_cpu_time_jfr_requests(bool wants) {
|
||||
|
||||
@@ -1399,6 +1399,10 @@ CodeBuffer* PhaseOutput::init_buffer() {
|
||||
cb->initialize_stubs_size(stub_req);
|
||||
cb->initialize_oop_recorder(C->env()->oop_recorder());
|
||||
|
||||
// fill in the nop array for bundling computations
|
||||
MachNode *_nop_list[Bundle::_nop_count];
|
||||
Bundle::initialize_nops(_nop_list);
|
||||
|
||||
return cb;
|
||||
}
|
||||
|
||||
@@ -2058,7 +2062,8 @@ Scheduling::Scheduling(Arena *arena, Compile &compile)
|
||||
// Create a MachNopNode
|
||||
_nop = new MachNopNode();
|
||||
|
||||
// Save the count
|
||||
// Now that the nops are in the array, save the count
|
||||
// (but allow entries for the nops)
|
||||
_node_bundling_limit = compile.unique();
|
||||
uint node_max = _regalloc->node_regs_max_index();
|
||||
|
||||
|
||||
@@ -2502,7 +2502,7 @@ bool LibraryCallKit::inline_vector_extract() {
|
||||
if (vector_klass == nullptr || vector_klass->const_oop() == nullptr ||
|
||||
elem_klass == nullptr || elem_klass->const_oop() == nullptr ||
|
||||
vlen == nullptr || !vlen->is_con() ||
|
||||
idx == nullptr) {
|
||||
idx == nullptr || !idx->is_con()) {
|
||||
log_if_needed(" ** missing constant: vclass=%s etype=%s vlen=%s",
|
||||
NodeClassNames[argument(0)->Opcode()],
|
||||
NodeClassNames[argument(1)->Opcode()],
|
||||
|
||||
@@ -418,7 +418,6 @@ JvmtiExport::get_jvmti_interface(JavaVM *jvm, void **penv, jint version) {
|
||||
JvmtiThreadState*
|
||||
JvmtiExport::get_jvmti_thread_state(JavaThread *thread, bool allow_suspend) {
|
||||
assert(thread == JavaThread::current(), "must be current thread");
|
||||
assert(thread->thread_state() == _thread_in_vm, "thread should be in vm");
|
||||
if (thread->is_vthread_mounted() && thread->jvmti_thread_state() == nullptr) {
|
||||
JvmtiEventController::thread_started(thread);
|
||||
if (allow_suspend && thread->is_suspended()) {
|
||||
@@ -1827,50 +1826,47 @@ void JvmtiExport::post_method_entry(JavaThread *thread, Method* method, frame cu
|
||||
}
|
||||
|
||||
void JvmtiExport::post_method_exit(JavaThread* thread, Method* method, frame current_frame) {
|
||||
// At this point we only have the address of a "raw result" and
|
||||
// we just call into the interpreter to convert this into a jvalue.
|
||||
// This method always makes transition to vm and back where GC can happen.
|
||||
// So it is needed to preserve result and then restore it
|
||||
// even if events are not actually posted.
|
||||
// Saving oop_result into value.j is deferred until jvmti state is ready.
|
||||
HandleMark hm(thread);
|
||||
methodHandle mh(thread, method);
|
||||
|
||||
JvmtiThreadState *state = get_jvmti_thread_state(thread);
|
||||
|
||||
if (state == nullptr || !state->is_interp_only_mode()) {
|
||||
// for any thread that actually wants method exit, interp_only_mode is set
|
||||
return;
|
||||
}
|
||||
|
||||
Handle result;
|
||||
oop oop_result;
|
||||
jvalue value;
|
||||
value.j = 0L;
|
||||
BasicType type = current_frame.interpreter_frame_result(&oop_result, &value);
|
||||
assert(mh->is_native() || type == T_VOID || current_frame.interpreter_frame_expression_stack_size() > 0,
|
||||
"Stack shouldn't be empty");
|
||||
if (is_reference_type(type)) {
|
||||
result = Handle(thread, oop_result);
|
||||
}
|
||||
JvmtiThreadState* state; // should be initialized in vm state only
|
||||
JavaThread* current = thread; // for JRT_BLOCK
|
||||
bool interp_only; // might be changed in JRT_BLOCK_END
|
||||
JRT_BLOCK
|
||||
state = get_jvmti_thread_state(thread);
|
||||
interp_only = state != nullptr && state->is_interp_only_mode();
|
||||
if (interp_only) {
|
||||
if (state->is_enabled(JVMTI_EVENT_METHOD_EXIT)) {
|
||||
// Deferred saving Object result into value.
|
||||
if (is_reference_type(type)) {
|
||||
value.l = JNIHandles::make_local(thread, result());
|
||||
}
|
||||
}
|
||||
|
||||
// Do not allow NotifyFramePop to add new FramePop event request at
|
||||
// depth 0 as it is already late in the method exiting dance.
|
||||
state->set_top_frame_is_exiting();
|
||||
|
||||
post_method_exit_inner(thread, mh, state, false /* not exception exit */, current_frame, value);
|
||||
if (state->is_enabled(JVMTI_EVENT_METHOD_EXIT)) {
|
||||
// At this point we only have the address of a "raw result" and
|
||||
// we just call into the interpreter to convert this into a jvalue.
|
||||
oop oop_result;
|
||||
BasicType type = current_frame.interpreter_frame_result(&oop_result, &value);
|
||||
assert(type == T_VOID || current_frame.interpreter_frame_expression_stack_size() > 0,
|
||||
"Stack shouldn't be empty");
|
||||
if (is_reference_type(type)) {
|
||||
result = Handle(thread, oop_result);
|
||||
value.l = JNIHandles::make_local(thread, result());
|
||||
}
|
||||
JRT_BLOCK_END
|
||||
if (interp_only) {
|
||||
// The JRT_BLOCK_END can safepoint in ThreadInVMfromJava destructor. Now it is safe to allow
|
||||
// adding FramePop event requests as no safepoint can happen before removing activation.
|
||||
state->clr_top_frame_is_exiting();
|
||||
}
|
||||
|
||||
// Do not allow NotifyFramePop to add new FramePop event request at
|
||||
// depth 0 as it is already late in the method exiting dance.
|
||||
state->set_top_frame_is_exiting();
|
||||
|
||||
// Deferred transition to VM, so we can stash away the return oop before GC.
|
||||
JavaThread* current = thread; // for JRT_BLOCK
|
||||
JRT_BLOCK
|
||||
post_method_exit_inner(thread, mh, state, false /* not exception exit */, current_frame, value);
|
||||
JRT_BLOCK_END
|
||||
|
||||
// The JRT_BLOCK_END can safepoint in ThreadInVMfromJava desctructor. Now it is safe to allow
|
||||
// adding FramePop event requests as no safepoint can happen before removing activation.
|
||||
state->clr_top_frame_is_exiting();
|
||||
|
||||
if (result.not_null() && !mh->is_native()) {
|
||||
// We have to restore the oop on the stack for interpreter frames
|
||||
*(oop*)current_frame.interpreter_frame_tos_address() = result();
|
||||
|
||||
@@ -46,7 +46,6 @@
|
||||
#include "gc/shared/concurrentGCBreakpoints.hpp"
|
||||
#include "gc/shared/gcConfig.hpp"
|
||||
#include "gc/shared/genArguments.hpp"
|
||||
#include "jfr/periodic/sampling/jfrCPUTimeThreadSampler.hpp"
|
||||
#include "jvm.h"
|
||||
#include "jvmtifiles/jvmtiEnv.hpp"
|
||||
#include "logging/log.hpp"
|
||||
@@ -2661,32 +2660,6 @@ WB_ENTRY(void, WB_WaitUnsafe(JNIEnv* env, jobject wb, jint time))
|
||||
os::naked_short_sleep(time);
|
||||
WB_END
|
||||
|
||||
WB_ENTRY(void, WB_BusyWait(JNIEnv* env, jobject wb, jint time))
|
||||
ThreadToNativeFromVM ttn(thread);
|
||||
u8 start = os::current_thread_cpu_time();
|
||||
u8 target_duration = time * (u8)1000000;
|
||||
while (os::current_thread_cpu_time() - start < target_duration) {
|
||||
for (volatile int i = 0; i < 1000000; i++);
|
||||
}
|
||||
WB_END
|
||||
|
||||
WB_ENTRY(jboolean, WB_CPUSamplerSetOutOfStackWalking(JNIEnv* env, jobject wb, jboolean enable))
|
||||
#if defined(ASSERT) && INCLUDE_JFR && defined(LINUX)
|
||||
JfrCPUTimeThreadSampling::set_out_of_stack_walking_enabled(enable == JNI_TRUE);
|
||||
return JNI_TRUE;
|
||||
#else
|
||||
return JNI_FALSE;
|
||||
#endif
|
||||
WB_END
|
||||
|
||||
WB_ENTRY(jlong, WB_CPUSamplerOutOfStackWalkingIterations(JNIEnv* env, jobject wb))
|
||||
#if defined(ASSERT) && INCLUDE_JFR && defined(LINUX)
|
||||
return (jlong)JfrCPUTimeThreadSampling::out_of_stack_walking_iterations();
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
WB_END
|
||||
|
||||
WB_ENTRY(jstring, WB_GetLibcName(JNIEnv* env, jobject o))
|
||||
ThreadToNativeFromVM ttn(thread);
|
||||
jstring info_string = env->NewStringUTF(XSTR(LIBC));
|
||||
@@ -3040,9 +3013,6 @@ static JNINativeMethod methods[] = {
|
||||
|
||||
{CC"isJVMTIIncluded", CC"()Z", (void*)&WB_IsJVMTIIncluded},
|
||||
{CC"waitUnsafe", CC"(I)V", (void*)&WB_WaitUnsafe},
|
||||
{CC"busyWait", CC"(I)V", (void*)&WB_BusyWait},
|
||||
{CC"cpuSamplerSetOutOfStackWalking", CC"(Z)Z", (void*)&WB_CPUSamplerSetOutOfStackWalking},
|
||||
{CC"cpuSamplerOutOfStackWalkingIterations", CC"()J",(void*)&WB_CPUSamplerOutOfStackWalkingIterations},
|
||||
{CC"getLibcName", CC"()Ljava/lang/String;", (void*)&WB_GetLibcName},
|
||||
|
||||
{CC"pinObject", CC"(Ljava/lang/Object;)V", (void*)&WB_PinObject},
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
// Mutexes used in the VM (see comment in mutexLocker.hpp):
|
||||
|
||||
Mutex* NMethodState_lock = nullptr;
|
||||
Mutex* NMethodEntryBarrier_lock = nullptr;
|
||||
Monitor* SystemDictionary_lock = nullptr;
|
||||
Mutex* InvokeMethodTypeTable_lock = nullptr;
|
||||
Monitor* InvokeMethodIntrinsicTable_lock = nullptr;
|
||||
@@ -206,6 +207,8 @@ void assert_lock_strong(const Mutex* lock) {
|
||||
void mutex_init() {
|
||||
MUTEX_DEFN(tty_lock , PaddedMutex , tty); // allow to lock in VM
|
||||
|
||||
MUTEX_DEFN(NMethodEntryBarrier_lock , PaddedMutex , service-1);
|
||||
|
||||
MUTEX_DEFN(STS_lock , PaddedMonitor, nosafepoint);
|
||||
|
||||
#if INCLUDE_G1GC
|
||||
|
||||
@@ -34,6 +34,7 @@ class Thread;
|
||||
// Mutexes used in the VM.
|
||||
|
||||
extern Mutex* NMethodState_lock; // a lock used to guard a compiled method state
|
||||
extern Mutex* NMethodEntryBarrier_lock; // protects nmethod entry barrier
|
||||
extern Monitor* SystemDictionary_lock; // a lock on the system dictionary
|
||||
extern Mutex* InvokeMethodTypeTable_lock;
|
||||
extern Monitor* InvokeMethodIntrinsicTable_lock;
|
||||
|
||||
@@ -38,15 +38,6 @@
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
// Workaround for noexcept functions in glibc when using clang.
|
||||
// clang errors if declaration without exception specification preceeds
|
||||
// noexcept declaration, but not the other way around.
|
||||
#ifdef __clang__
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#include "forbiddenFunctions_windows.hpp"
|
||||
#else
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
|
||||
package java.io;
|
||||
|
||||
import java.lang.annotation.Native;
|
||||
import java.util.*;
|
||||
import java.nio.charset.Charset;
|
||||
import jdk.internal.access.JavaIOAccess;
|
||||
@@ -551,12 +550,7 @@ public sealed class Console implements Flushable permits ProxyingConsole {
|
||||
"Console class itself does not provide implementation");
|
||||
}
|
||||
|
||||
@Native static final int TTY_STDIN_MASK = 0x00000001;
|
||||
@Native static final int TTY_STDOUT_MASK = 0x00000002;
|
||||
@Native static final int TTY_STDERR_MASK = 0x00000004;
|
||||
// ttyStatus() returns bit patterns above, a bit is set if the corresponding file
|
||||
// descriptor is a character device
|
||||
private static final int ttyStatus = ttyStatus();
|
||||
private static final boolean istty = istty();
|
||||
private static final Charset STDIN_CHARSET =
|
||||
Charset.forName(StaticProperty.stdinEncoding(), UTF_8.INSTANCE);
|
||||
private static final Charset STDOUT_CHARSET =
|
||||
@@ -568,9 +562,6 @@ public sealed class Console implements Flushable permits ProxyingConsole {
|
||||
public Console console() {
|
||||
return cons;
|
||||
}
|
||||
public boolean isStdinTty() {
|
||||
return Console.isStdinTty();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -592,7 +583,7 @@ public sealed class Console implements Flushable permits ProxyingConsole {
|
||||
|
||||
for (var jcp : ServiceLoader.load(ModuleLayer.boot(), JdkConsoleProvider.class)) {
|
||||
if (consModName.equals(jcp.getClass().getModule().getName())) {
|
||||
var jc = jcp.console(isStdinTty() && isStdoutTty(), STDIN_CHARSET, STDOUT_CHARSET);
|
||||
var jc = jcp.console(istty, STDIN_CHARSET, STDOUT_CHARSET);
|
||||
if (jc != null) {
|
||||
c = new ProxyingConsole(jc);
|
||||
}
|
||||
@@ -603,21 +594,12 @@ public sealed class Console implements Flushable permits ProxyingConsole {
|
||||
}
|
||||
|
||||
// If not found, default to built-in Console
|
||||
if (isStdinTty() && isStdoutTty() && c == null) {
|
||||
if (istty && c == null) {
|
||||
c = new ProxyingConsole(new JdkConsoleImpl(STDIN_CHARSET, STDOUT_CHARSET));
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
private static boolean isStdinTty() {
|
||||
return (ttyStatus & TTY_STDIN_MASK) != 0;
|
||||
}
|
||||
private static boolean isStdoutTty() {
|
||||
return (ttyStatus & TTY_STDOUT_MASK) != 0;
|
||||
}
|
||||
private static boolean isStderrTty() {
|
||||
return (ttyStatus & TTY_STDERR_MASK) != 0;
|
||||
}
|
||||
private static native int ttyStatus();
|
||||
private static native boolean istty();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2022, 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
|
||||
@@ -29,5 +29,4 @@ import java.io.Console;
|
||||
|
||||
public interface JavaIOAccess {
|
||||
Console console();
|
||||
boolean isStdinTty();
|
||||
}
|
||||
|
||||
@@ -38,13 +38,10 @@ import java.util.Arrays;
|
||||
import java.util.Formatter;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import jdk.internal.access.SharedSecrets;
|
||||
import jdk.internal.util.StaticProperty;
|
||||
import sun.nio.cs.StreamDecoder;
|
||||
import sun.nio.cs.StreamEncoder;
|
||||
import sun.nio.cs.UTF_8;
|
||||
|
||||
/**
|
||||
* JdkConsole implementation based on the platform's TTY.
|
||||
@@ -106,42 +103,6 @@ public final class JdkConsoleImpl implements JdkConsole {
|
||||
|
||||
@Override
|
||||
public char[] readPassword(Locale locale, String format, Object ... args) {
|
||||
return readPassword0(false, locale, format, args);
|
||||
}
|
||||
|
||||
// These two methods are intended for sun.security.util.Password, so tools like keytool can
|
||||
// use JdkConsoleImpl even when standard output is redirected. The Password class should first
|
||||
// check if `System.console()` returns a Console instance and use it if available. Otherwise,
|
||||
// it should call this method to obtain a JdkConsoleImpl. This ensures only one Console
|
||||
// instance exists in the Java runtime.
|
||||
private static final StableValue<Optional<JdkConsoleImpl>> INSTANCE = StableValue.of();
|
||||
public static Optional<JdkConsoleImpl> passwordConsole() {
|
||||
return INSTANCE.orElseSet(() -> {
|
||||
// If there's already a proper console, throw an exception
|
||||
if (System.console() != null) {
|
||||
throw new IllegalStateException("Can’t create a dedicated password " +
|
||||
"console since a real console already exists");
|
||||
}
|
||||
|
||||
// If stdin is NOT redirected, return an Optional containing a JdkConsoleImpl
|
||||
// instance, otherwise an empty Optional.
|
||||
return SharedSecrets.getJavaIOAccess().isStdinTty() ?
|
||||
Optional.of(
|
||||
new JdkConsoleImpl(
|
||||
Charset.forName(StaticProperty.stdinEncoding(), UTF_8.INSTANCE),
|
||||
Charset.forName(StaticProperty.stdoutEncoding(), UTF_8.INSTANCE))) :
|
||||
Optional.empty();
|
||||
});
|
||||
}
|
||||
|
||||
// Dedicated entry for sun.security.util.Password when stdout is redirected.
|
||||
// This method strictly avoids producing any output by using noNewLine = true
|
||||
// and an empty format string.
|
||||
public char[] readPasswordNoNewLine() {
|
||||
return readPassword0(true, Locale.getDefault(Locale.Category.FORMAT), "");
|
||||
}
|
||||
|
||||
private char[] readPassword0(boolean noNewLine, Locale locale, String format, Object ... args) {
|
||||
char[] passwd = null;
|
||||
synchronized (writeLock) {
|
||||
synchronized(readLock) {
|
||||
@@ -185,9 +146,7 @@ public final class JdkConsoleImpl implements JdkConsole {
|
||||
throw ioe;
|
||||
}
|
||||
}
|
||||
if (!noNewLine) {
|
||||
pw.println();
|
||||
}
|
||||
pw.println();
|
||||
}
|
||||
}
|
||||
return passwd;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@@ -31,19 +31,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_java_io_Console_ttyStatus(JNIEnv *env, jclass cls)
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_java_io_Console_istty(JNIEnv *env, jclass cls)
|
||||
{
|
||||
jint ret = 0;
|
||||
|
||||
if (isatty(fileno(stdin))) {
|
||||
ret |= java_io_Console_TTY_STDIN_MASK;
|
||||
}
|
||||
if (isatty(fileno(stdout))) {
|
||||
ret |= java_io_Console_TTY_STDOUT_MASK;
|
||||
}
|
||||
if (isatty(fileno(stderr))) {
|
||||
ret |= java_io_Console_TTY_STDERR_MASK;
|
||||
}
|
||||
return ret;
|
||||
return isatty(fileno(stdin)) && isatty(fileno(stdout));
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@@ -31,28 +31,21 @@
|
||||
#include <stdlib.h>
|
||||
#include <Wincon.h>
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_java_io_Console_ttyStatus(JNIEnv *env, jclass cls)
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_java_io_Console_istty(JNIEnv *env, jclass cls)
|
||||
{
|
||||
jint ret = 0;
|
||||
HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE);
|
||||
HANDLE hStdErr = GetStdHandle(STD_ERROR_HANDLE);
|
||||
|
||||
if (hStdIn != INVALID_HANDLE_VALUE &&
|
||||
GetFileType(hStdIn) == FILE_TYPE_CHAR) {
|
||||
ret |= java_io_Console_TTY_STDIN_MASK;
|
||||
if (hStdIn == INVALID_HANDLE_VALUE ||
|
||||
hStdOut == INVALID_HANDLE_VALUE) {
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
if (hStdOut != INVALID_HANDLE_VALUE &&
|
||||
GetFileType(hStdOut) == FILE_TYPE_CHAR) {
|
||||
ret |= java_io_Console_TTY_STDOUT_MASK;
|
||||
if (GetFileType(hStdIn) != FILE_TYPE_CHAR ||
|
||||
GetFileType(hStdOut) != FILE_TYPE_CHAR) {
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
if (hStdErr != INVALID_HANDLE_VALUE &&
|
||||
GetFileType(hStdErr) == FILE_TYPE_CHAR) {
|
||||
ret |= java_io_Console_TTY_STDERR_MASK;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
@@ -78,8 +78,6 @@ environment=\
|
||||
process.top process.ps \
|
||||
memory.free memory.vmstat.default memory.vmstat.statistics \
|
||||
memory.vmstat.slabinfo memory.vmstat.disk \
|
||||
memory.proc_meminfo memory.proc_vmstat \
|
||||
memory.thp \
|
||||
files \
|
||||
locks \
|
||||
net.sockets net.statistics net.ifconfig net.hostsfile \
|
||||
@@ -117,15 +115,6 @@ memory.vmstat.default.args=3 3
|
||||
memory.vmstat.statistics.args=-s
|
||||
memory.vmstat.slabinfo.args=-m
|
||||
memory.vmstat.disk.args=-d
|
||||
memory.proc_meminfo.app=bash
|
||||
memory.proc_meminfo.args=-c\0cat /proc/meminfo
|
||||
memory.proc_meminfo.delimiter=\0
|
||||
memory.proc_vmstat.app=bash
|
||||
memory.proc_vmstat.args=-c\0cat /proc/vmstat
|
||||
memory.proc_vmstat.delimiter=\0
|
||||
memory.thp.app=bash
|
||||
memory.thp.args=-c\0cat /sys/kernel/mm/transparent_hugepage/{enabled,defrag,shmem_enabled}
|
||||
memory.thp.delimiter=\0
|
||||
|
||||
files.app=lsof
|
||||
locks.app=lslocks
|
||||
|
||||
@@ -1958,8 +1958,6 @@ generate(SpecialCases, [["ccmn", "__ ccmn(zr, zr, 3u, Assembler::LE);",
|
||||
["cpy", "__ sve_cpy(z5, __ D, p0, -32768, false);", "mov\tz5.d, p0/z, -32768"],
|
||||
["cpy", "__ sve_cpy(z10, __ B, p0, -1, false);", "mov\tz10.b, p0/z, -1"],
|
||||
["cpy", "__ sve_cpy(z11, __ S, p0, -1, false);", "mov\tz11.s, p0/z, -1"],
|
||||
["fcpy", "__ sve_cpy(z11, __ S, p0, 0.5);", "fcpy\tz11.s, p0/m, #0.5"],
|
||||
["fcpy", "__ sve_cpy(z11, __ S, p0, -1.0);", "fcpy\tz11.s, p0/m, #-1.0"],
|
||||
["inc", "__ sve_inc(r0, __ S);", "incw\tx0"],
|
||||
["dec", "__ sve_dec(r1, __ H);", "dech\tx1"],
|
||||
["lsl", "__ sve_lsl(z0, __ B, z1, 7);", "lsl\tz0.b, z1.b, #7"],
|
||||
|
||||
@@ -971,8 +971,6 @@
|
||||
__ sve_cpy(z5, __ D, p0, -32768, false); // mov z5.d, p0/z, -32768
|
||||
__ sve_cpy(z10, __ B, p0, -1, false); // mov z10.b, p0/z, -1
|
||||
__ sve_cpy(z11, __ S, p0, -1, false); // mov z11.s, p0/z, -1
|
||||
__ sve_cpy(z11, __ S, p0, 0.5); // fcpy z11.s, p0/m, #0.5
|
||||
__ sve_cpy(z11, __ S, p0, -1.0); // fcpy z11.s, p0/m, #-1.0
|
||||
__ sve_inc(r0, __ S); // incw x0
|
||||
__ sve_dec(r1, __ H); // dech x1
|
||||
__ sve_lsl(z0, __ B, z1, 7); // lsl z0.b, z1.b, #7
|
||||
@@ -1444,30 +1442,30 @@
|
||||
0x9101a1a0, 0xb10a5cc8, 0xd10810aa, 0xf10fd061,
|
||||
0x120cb166, 0x321764bc, 0x52174681, 0x720c0227,
|
||||
0x9241018e, 0xb25a2969, 0xd278b411, 0xf26aad01,
|
||||
0x14000000, 0x17ffffd7, 0x140004b6, 0x94000000,
|
||||
0x97ffffd4, 0x940004b3, 0x3400000a, 0x34fffa2a,
|
||||
0x3400960a, 0x35000008, 0x35fff9c8, 0x350095a8,
|
||||
0xb400000b, 0xb4fff96b, 0xb400954b, 0xb500001d,
|
||||
0xb5fff91d, 0xb50094fd, 0x10000013, 0x10fff8b3,
|
||||
0x10009493, 0x90000013, 0x36300016, 0x3637f836,
|
||||
0x36309416, 0x3758000c, 0x375ff7cc, 0x375893ac,
|
||||
0x14000000, 0x17ffffd7, 0x140004b4, 0x94000000,
|
||||
0x97ffffd4, 0x940004b1, 0x3400000a, 0x34fffa2a,
|
||||
0x340095ca, 0x35000008, 0x35fff9c8, 0x35009568,
|
||||
0xb400000b, 0xb4fff96b, 0xb400950b, 0xb500001d,
|
||||
0xb5fff91d, 0xb50094bd, 0x10000013, 0x10fff8b3,
|
||||
0x10009453, 0x90000013, 0x36300016, 0x3637f836,
|
||||
0x363093d6, 0x3758000c, 0x375ff7cc, 0x3758936c,
|
||||
0x128313a0, 0x528a32c7, 0x7289173b, 0x92ab3acc,
|
||||
0xd2a0bf94, 0xf2c285e8, 0x9358722f, 0x330e652f,
|
||||
0x53067f3b, 0x93577c53, 0xb34a1aac, 0xd35a4016,
|
||||
0x13946c63, 0x93c3dbc8, 0x54000000, 0x54fff5a0,
|
||||
0x54009180, 0x54000001, 0x54fff541, 0x54009121,
|
||||
0x54000002, 0x54fff4e2, 0x540090c2, 0x54000002,
|
||||
0x54fff482, 0x54009062, 0x54000003, 0x54fff423,
|
||||
0x54009003, 0x54000003, 0x54fff3c3, 0x54008fa3,
|
||||
0x54000004, 0x54fff364, 0x54008f44, 0x54000005,
|
||||
0x54fff305, 0x54008ee5, 0x54000006, 0x54fff2a6,
|
||||
0x54008e86, 0x54000007, 0x54fff247, 0x54008e27,
|
||||
0x54000008, 0x54fff1e8, 0x54008dc8, 0x54000009,
|
||||
0x54fff189, 0x54008d69, 0x5400000a, 0x54fff12a,
|
||||
0x54008d0a, 0x5400000b, 0x54fff0cb, 0x54008cab,
|
||||
0x5400000c, 0x54fff06c, 0x54008c4c, 0x5400000d,
|
||||
0x54fff00d, 0x54008bed, 0x5400000e, 0x54ffefae,
|
||||
0x54008b8e, 0x5400000f, 0x54ffef4f, 0x54008b2f,
|
||||
0x54009140, 0x54000001, 0x54fff541, 0x540090e1,
|
||||
0x54000002, 0x54fff4e2, 0x54009082, 0x54000002,
|
||||
0x54fff482, 0x54009022, 0x54000003, 0x54fff423,
|
||||
0x54008fc3, 0x54000003, 0x54fff3c3, 0x54008f63,
|
||||
0x54000004, 0x54fff364, 0x54008f04, 0x54000005,
|
||||
0x54fff305, 0x54008ea5, 0x54000006, 0x54fff2a6,
|
||||
0x54008e46, 0x54000007, 0x54fff247, 0x54008de7,
|
||||
0x54000008, 0x54fff1e8, 0x54008d88, 0x54000009,
|
||||
0x54fff189, 0x54008d29, 0x5400000a, 0x54fff12a,
|
||||
0x54008cca, 0x5400000b, 0x54fff0cb, 0x54008c6b,
|
||||
0x5400000c, 0x54fff06c, 0x54008c0c, 0x5400000d,
|
||||
0x54fff00d, 0x54008bad, 0x5400000e, 0x54ffefae,
|
||||
0x54008b4e, 0x5400000f, 0x54ffef4f, 0x54008aef,
|
||||
0xd40658e1, 0xd4014d22, 0xd4046543, 0xd4273f60,
|
||||
0xd44cad80, 0xd503201f, 0xd503203f, 0xd503205f,
|
||||
0xd503209f, 0xd50320bf, 0xd503219f, 0xd50323bf,
|
||||
@@ -1642,110 +1640,109 @@
|
||||
0x4e21c862, 0x0e79c862, 0x4e79c862, 0x4e61b8a4,
|
||||
0x0e79b8a4, 0x4e79b8a4, 0x05a08020, 0x05104fe0,
|
||||
0x05505001, 0x05906fe2, 0x05d03005, 0x05101fea,
|
||||
0x05901feb, 0x0590cc0b, 0x0590de0b, 0x04b0e3e0,
|
||||
0x0470e7e1, 0x042f9c20, 0x043f9c35, 0x047f9c20,
|
||||
0x04ff9c20, 0x04299420, 0x04319160, 0x0461943e,
|
||||
0x04a19020, 0x04038100, 0x040381a0, 0x040387e1,
|
||||
0x04438be2, 0x04c38fe3, 0x040181e0, 0x04018100,
|
||||
0x04018621, 0x04418b22, 0x04418822, 0x04818c23,
|
||||
0x040081e0, 0x04008120, 0x04008761, 0x04008621,
|
||||
0x04408822, 0x04808c23, 0x042053ff, 0x047f5401,
|
||||
0x25208028, 0x2538cfe0, 0x2578d001, 0x25b8efe2,
|
||||
0x25f8f007, 0x2538dfea, 0x25b8dfeb, 0xa400a3e0,
|
||||
0xa420a7e0, 0xa4484be0, 0xa467afe0, 0xa4a8a7ea,
|
||||
0xa547a814, 0xa4084ffe, 0xa55c53e0, 0xa5e1540b,
|
||||
0xe400fbf6, 0xe408ffff, 0xe420e7e0, 0xe4484be0,
|
||||
0xe460efe0, 0xe547e400, 0xe4014be0, 0xe4a84fe0,
|
||||
0xe5f15000, 0x858043e0, 0x85a043ff, 0xe59f5d08,
|
||||
0x0420e3e9, 0x0460e3ea, 0x04a0e3eb, 0x04e0e3ec,
|
||||
0x25104042, 0x25104871, 0x25904861, 0x25904c92,
|
||||
0x05344020, 0x05744041, 0x05b44062, 0x05f44083,
|
||||
0x252c8840, 0x253c1420, 0x25681572, 0x25a21ce3,
|
||||
0x25ea1e34, 0x253c0421, 0x25680572, 0x25a20ce3,
|
||||
0x25ea0e34, 0x0522c020, 0x05e6c0a4, 0x2401a001,
|
||||
0x2443a051, 0x24858881, 0x24c78cd1, 0x24850891,
|
||||
0x24c70cc1, 0x250f9001, 0x25508051, 0x25802491,
|
||||
0x25df28c1, 0x25850c81, 0x251e10d1, 0x65816001,
|
||||
0x65c36051, 0x65854891, 0x65c74cc1, 0x05733820,
|
||||
0x05b238a4, 0x05f138e6, 0x0570396a, 0x65d0a001,
|
||||
0x65d6a443, 0x65d4a826, 0x6594ac26, 0x6554ac26,
|
||||
0x6556ac26, 0x6552ac26, 0x65cbac85, 0x65caac01,
|
||||
0x6589ac85, 0x6588ac01, 0x65c9ac85, 0x65c8ac01,
|
||||
0x65dea833, 0x659ca509, 0x65d8a801, 0x65dcac01,
|
||||
0x655cb241, 0x0520a1e0, 0x0521a601, 0x052281e0,
|
||||
0x05238601, 0x04a14026, 0x042244a6, 0x046344a6,
|
||||
0x04a444a6, 0x04e544a7, 0x0568aca7, 0x05b23230,
|
||||
0x05302a30, 0x05702a30, 0x05b02a30, 0x05f02a30,
|
||||
0x853040af, 0xc5b040af, 0xe57080af, 0xe5b080af,
|
||||
0x25034440, 0x254054c4, 0x25034640, 0x25415a05,
|
||||
0x25834440, 0x25c54489, 0x250b5d3a, 0x2550dc20,
|
||||
0x2518e3e1, 0x2518e021, 0x2518e0a1, 0x2518e121,
|
||||
0x2518e1a1, 0x2558e3e2, 0x2558e042, 0x2558e0c2,
|
||||
0x2558e142, 0x2598e3e3, 0x2598e063, 0x2598e0e3,
|
||||
0x2598e163, 0x25d8e3e4, 0x25d8e084, 0x25d8e104,
|
||||
0x25d8e184, 0x2518e407, 0x05214800, 0x05614800,
|
||||
0x05a14800, 0x05e14800, 0x05214c00, 0x05614c00,
|
||||
0x05a14c00, 0x05e14c00, 0x05304001, 0x05314001,
|
||||
0x05a18610, 0x05e18610, 0x05271e11, 0x6545e891,
|
||||
0x6585e891, 0x65c5e891, 0x6545c891, 0x6585c891,
|
||||
0x65c5c891, 0x45b0c210, 0x45f1c231, 0x1e601000,
|
||||
0x1e603000, 0x1e621000, 0x1e623000, 0x1e641000,
|
||||
0x1e643000, 0x1e661000, 0x1e663000, 0x1e681000,
|
||||
0x1e683000, 0x1e6a1000, 0x1e6a3000, 0x1e6c1000,
|
||||
0x1e6c3000, 0x1e6e1000, 0x1e6e3000, 0x1e701000,
|
||||
0x1e703000, 0x1e721000, 0x1e723000, 0x1e741000,
|
||||
0x1e743000, 0x1e761000, 0x1e763000, 0x1e781000,
|
||||
0x1e783000, 0x1e7a1000, 0x1e7a3000, 0x1e7c1000,
|
||||
0x1e7c3000, 0x1e7e1000, 0x1e7e3000, 0xf8268267,
|
||||
0xf82d023c, 0xf8301046, 0xf83d2083, 0xf8263290,
|
||||
0xf82d528c, 0xf8284299, 0xf8337160, 0xf8386286,
|
||||
0xf8bf820e, 0xf8a600e0, 0xf8af1353, 0xf8a922ea,
|
||||
0xf8b53396, 0xf8a251e3, 0xf8b340f4, 0xf8a470fd,
|
||||
0xf8a06209, 0xf8f48097, 0xf8f002ea, 0xf8eb10d9,
|
||||
0xf8ff21b0, 0xf8f7302c, 0xf8ee52a9, 0xf8f041fa,
|
||||
0xf8e471e4, 0xf8e863c6, 0xf864823d, 0xf87d013a,
|
||||
0xf86f1162, 0xf87d20e3, 0xf86132bb, 0xf870510e,
|
||||
0xf8704336, 0xf86572b4, 0xf8706217, 0xb83e8294,
|
||||
0xb8200264, 0xb8381284, 0xb8242358, 0xb8333102,
|
||||
0xb828530e, 0xb83042df, 0xb824703f, 0xb82a6194,
|
||||
0xb8a080e9, 0xb8b80090, 0xb8bb1146, 0xb8bb21b8,
|
||||
0xb8b032df, 0xb8b653f4, 0xb8bd41c9, 0xb8b47287,
|
||||
0xb8bc6169, 0xb8ee828c, 0xb8e10138, 0xb8f3126d,
|
||||
0xb8f020b0, 0xb8e03183, 0xb8e851ef, 0xb8f041e4,
|
||||
0xb8fe7005, 0xb8ea6376, 0xb8638120, 0xb873015d,
|
||||
0xb8781284, 0xb86723b8, 0xb86e3175, 0xb87b51ed,
|
||||
0xb87f41d1, 0xb863721e, 0xb87660f4, 0xce216874,
|
||||
0xce104533, 0xce648c15, 0xce8e3302, 0xce6e82ab,
|
||||
0xce6c87d1, 0xcec08063, 0xce638937, 0x25e0c358,
|
||||
0x25a1c7d3, 0x0580785a, 0x05426328, 0x05009892,
|
||||
0x25a0cc29, 0x2561cec8, 0x058044b3, 0x05401c99,
|
||||
0x05006b49, 0x25e0d6f7, 0x2561c528, 0x0583c8bc,
|
||||
0x0542522f, 0x05001ec0, 0x25e0de65, 0x25a1c113,
|
||||
0x05803cad, 0x0540f3c0, 0x0500ab15, 0x2560c28c,
|
||||
0x2561d7c0, 0x05801ed7, 0x0542633b, 0x05003696,
|
||||
0x2560d4b4, 0x25e1c918, 0x058021ff, 0x05400e15,
|
||||
0x0500f3de, 0x0473025a, 0x04bd05ab, 0x658e0025,
|
||||
0x658a08e2, 0x659a0493, 0x043e1062, 0x04f418b4,
|
||||
0x046d15bd, 0x04611fce, 0x04d6a07c, 0x04001929,
|
||||
0x041a09da, 0x04d098f4, 0x04db10d4, 0x0459a3ad,
|
||||
0x041aa029, 0x041919fb, 0x04d39e24, 0x04118302,
|
||||
0x04101dba, 0x04d7ae16, 0x04dea571, 0x04180210,
|
||||
0x05e786fc, 0x05e4915c, 0x04881cf1, 0x044a0f04,
|
||||
0x04090969, 0x048b16c4, 0x044101e4, 0x04dcbf44,
|
||||
0x65809745, 0x658d833f, 0x65c68468, 0x65c79b07,
|
||||
0x65829e38, 0x049dafca, 0x6582bba8, 0x65c0b7ff,
|
||||
0x65c1b4e0, 0x658dbadd, 0x65819a9d, 0x65ed9246,
|
||||
0x65b30815, 0x65e6263c, 0x65eebb94, 0x65bad14e,
|
||||
0x65efe178, 0x65fc5697, 0x65e07f14, 0x040c55a6,
|
||||
0x04977f4d, 0x043d3046, 0x04b733a0, 0x046830a4,
|
||||
0x04ed322d, 0x05686948, 0x05bd6c13, 0x65c88ef0,
|
||||
0x450db3d7, 0x4540b6d9, 0x043e3979, 0x445896ce,
|
||||
0x445a9005, 0x44d98069, 0x445b87ae, 0x04da348e,
|
||||
0x04982edb, 0x0499397f, 0x0408338c, 0x04ca309c,
|
||||
0x65c721e6, 0x65c63641, 0x65982882, 0x04812b8b,
|
||||
0x0e251083, 0x4e3712d5, 0x0e61101f, 0x4e6d118b,
|
||||
0x0eba1338, 0x4eb712d5, 0x2e31120f, 0x6e2e11ac,
|
||||
0x2e6810e6, 0x6e6f11cd, 0x2eaa1128, 0x6eb1120f,
|
||||
|
||||
0x05901feb, 0x04b0e3e0, 0x0470e7e1, 0x042f9c20,
|
||||
0x043f9c35, 0x047f9c20, 0x04ff9c20, 0x04299420,
|
||||
0x04319160, 0x0461943e, 0x04a19020, 0x04038100,
|
||||
0x040381a0, 0x040387e1, 0x04438be2, 0x04c38fe3,
|
||||
0x040181e0, 0x04018100, 0x04018621, 0x04418b22,
|
||||
0x04418822, 0x04818c23, 0x040081e0, 0x04008120,
|
||||
0x04008761, 0x04008621, 0x04408822, 0x04808c23,
|
||||
0x042053ff, 0x047f5401, 0x25208028, 0x2538cfe0,
|
||||
0x2578d001, 0x25b8efe2, 0x25f8f007, 0x2538dfea,
|
||||
0x25b8dfeb, 0xa400a3e0, 0xa420a7e0, 0xa4484be0,
|
||||
0xa467afe0, 0xa4a8a7ea, 0xa547a814, 0xa4084ffe,
|
||||
0xa55c53e0, 0xa5e1540b, 0xe400fbf6, 0xe408ffff,
|
||||
0xe420e7e0, 0xe4484be0, 0xe460efe0, 0xe547e400,
|
||||
0xe4014be0, 0xe4a84fe0, 0xe5f15000, 0x858043e0,
|
||||
0x85a043ff, 0xe59f5d08, 0x0420e3e9, 0x0460e3ea,
|
||||
0x04a0e3eb, 0x04e0e3ec, 0x25104042, 0x25104871,
|
||||
0x25904861, 0x25904c92, 0x05344020, 0x05744041,
|
||||
0x05b44062, 0x05f44083, 0x252c8840, 0x253c1420,
|
||||
0x25681572, 0x25a21ce3, 0x25ea1e34, 0x253c0421,
|
||||
0x25680572, 0x25a20ce3, 0x25ea0e34, 0x0522c020,
|
||||
0x05e6c0a4, 0x2401a001, 0x2443a051, 0x24858881,
|
||||
0x24c78cd1, 0x24850891, 0x24c70cc1, 0x250f9001,
|
||||
0x25508051, 0x25802491, 0x25df28c1, 0x25850c81,
|
||||
0x251e10d1, 0x65816001, 0x65c36051, 0x65854891,
|
||||
0x65c74cc1, 0x05733820, 0x05b238a4, 0x05f138e6,
|
||||
0x0570396a, 0x65d0a001, 0x65d6a443, 0x65d4a826,
|
||||
0x6594ac26, 0x6554ac26, 0x6556ac26, 0x6552ac26,
|
||||
0x65cbac85, 0x65caac01, 0x6589ac85, 0x6588ac01,
|
||||
0x65c9ac85, 0x65c8ac01, 0x65dea833, 0x659ca509,
|
||||
0x65d8a801, 0x65dcac01, 0x655cb241, 0x0520a1e0,
|
||||
0x0521a601, 0x052281e0, 0x05238601, 0x04a14026,
|
||||
0x042244a6, 0x046344a6, 0x04a444a6, 0x04e544a7,
|
||||
0x0568aca7, 0x05b23230, 0x05302a30, 0x05702a30,
|
||||
0x05b02a30, 0x05f02a30, 0x853040af, 0xc5b040af,
|
||||
0xe57080af, 0xe5b080af, 0x25034440, 0x254054c4,
|
||||
0x25034640, 0x25415a05, 0x25834440, 0x25c54489,
|
||||
0x250b5d3a, 0x2550dc20, 0x2518e3e1, 0x2518e021,
|
||||
0x2518e0a1, 0x2518e121, 0x2518e1a1, 0x2558e3e2,
|
||||
0x2558e042, 0x2558e0c2, 0x2558e142, 0x2598e3e3,
|
||||
0x2598e063, 0x2598e0e3, 0x2598e163, 0x25d8e3e4,
|
||||
0x25d8e084, 0x25d8e104, 0x25d8e184, 0x2518e407,
|
||||
0x05214800, 0x05614800, 0x05a14800, 0x05e14800,
|
||||
0x05214c00, 0x05614c00, 0x05a14c00, 0x05e14c00,
|
||||
0x05304001, 0x05314001, 0x05a18610, 0x05e18610,
|
||||
0x05271e11, 0x6545e891, 0x6585e891, 0x65c5e891,
|
||||
0x6545c891, 0x6585c891, 0x65c5c891, 0x45b0c210,
|
||||
0x45f1c231, 0x1e601000, 0x1e603000, 0x1e621000,
|
||||
0x1e623000, 0x1e641000, 0x1e643000, 0x1e661000,
|
||||
0x1e663000, 0x1e681000, 0x1e683000, 0x1e6a1000,
|
||||
0x1e6a3000, 0x1e6c1000, 0x1e6c3000, 0x1e6e1000,
|
||||
0x1e6e3000, 0x1e701000, 0x1e703000, 0x1e721000,
|
||||
0x1e723000, 0x1e741000, 0x1e743000, 0x1e761000,
|
||||
0x1e763000, 0x1e781000, 0x1e783000, 0x1e7a1000,
|
||||
0x1e7a3000, 0x1e7c1000, 0x1e7c3000, 0x1e7e1000,
|
||||
0x1e7e3000, 0xf8268267, 0xf82d023c, 0xf8301046,
|
||||
0xf83d2083, 0xf8263290, 0xf82d528c, 0xf8284299,
|
||||
0xf8337160, 0xf8386286, 0xf8bf820e, 0xf8a600e0,
|
||||
0xf8af1353, 0xf8a922ea, 0xf8b53396, 0xf8a251e3,
|
||||
0xf8b340f4, 0xf8a470fd, 0xf8a06209, 0xf8f48097,
|
||||
0xf8f002ea, 0xf8eb10d9, 0xf8ff21b0, 0xf8f7302c,
|
||||
0xf8ee52a9, 0xf8f041fa, 0xf8e471e4, 0xf8e863c6,
|
||||
0xf864823d, 0xf87d013a, 0xf86f1162, 0xf87d20e3,
|
||||
0xf86132bb, 0xf870510e, 0xf8704336, 0xf86572b4,
|
||||
0xf8706217, 0xb83e8294, 0xb8200264, 0xb8381284,
|
||||
0xb8242358, 0xb8333102, 0xb828530e, 0xb83042df,
|
||||
0xb824703f, 0xb82a6194, 0xb8a080e9, 0xb8b80090,
|
||||
0xb8bb1146, 0xb8bb21b8, 0xb8b032df, 0xb8b653f4,
|
||||
0xb8bd41c9, 0xb8b47287, 0xb8bc6169, 0xb8ee828c,
|
||||
0xb8e10138, 0xb8f3126d, 0xb8f020b0, 0xb8e03183,
|
||||
0xb8e851ef, 0xb8f041e4, 0xb8fe7005, 0xb8ea6376,
|
||||
0xb8638120, 0xb873015d, 0xb8781284, 0xb86723b8,
|
||||
0xb86e3175, 0xb87b51ed, 0xb87f41d1, 0xb863721e,
|
||||
0xb87660f4, 0xce216874, 0xce104533, 0xce648c15,
|
||||
0xce8e3302, 0xce6e82ab, 0xce6c87d1, 0xcec08063,
|
||||
0xce638937, 0x25e0c358, 0x25a1c7d3, 0x0580785a,
|
||||
0x05426328, 0x05009892, 0x25a0cc29, 0x2561cec8,
|
||||
0x058044b3, 0x05401c99, 0x05006b49, 0x25e0d6f7,
|
||||
0x2561c528, 0x0583c8bc, 0x0542522f, 0x05001ec0,
|
||||
0x25e0de65, 0x25a1c113, 0x05803cad, 0x0540f3c0,
|
||||
0x0500ab15, 0x2560c28c, 0x2561d7c0, 0x05801ed7,
|
||||
0x0542633b, 0x05003696, 0x2560d4b4, 0x25e1c918,
|
||||
0x058021ff, 0x05400e15, 0x0500f3de, 0x0473025a,
|
||||
0x04bd05ab, 0x658e0025, 0x658a08e2, 0x659a0493,
|
||||
0x043e1062, 0x04f418b4, 0x046d15bd, 0x04611fce,
|
||||
0x04d6a07c, 0x04001929, 0x041a09da, 0x04d098f4,
|
||||
0x04db10d4, 0x0459a3ad, 0x041aa029, 0x041919fb,
|
||||
0x04d39e24, 0x04118302, 0x04101dba, 0x04d7ae16,
|
||||
0x04dea571, 0x04180210, 0x05e786fc, 0x05e4915c,
|
||||
0x04881cf1, 0x044a0f04, 0x04090969, 0x048b16c4,
|
||||
0x044101e4, 0x04dcbf44, 0x65809745, 0x658d833f,
|
||||
0x65c68468, 0x65c79b07, 0x65829e38, 0x049dafca,
|
||||
0x6582bba8, 0x65c0b7ff, 0x65c1b4e0, 0x658dbadd,
|
||||
0x65819a9d, 0x65ed9246, 0x65b30815, 0x65e6263c,
|
||||
0x65eebb94, 0x65bad14e, 0x65efe178, 0x65fc5697,
|
||||
0x65e07f14, 0x040c55a6, 0x04977f4d, 0x043d3046,
|
||||
0x04b733a0, 0x046830a4, 0x04ed322d, 0x05686948,
|
||||
0x05bd6c13, 0x65c88ef0, 0x450db3d7, 0x4540b6d9,
|
||||
0x043e3979, 0x445896ce, 0x445a9005, 0x44d98069,
|
||||
0x445b87ae, 0x04da348e, 0x04982edb, 0x0499397f,
|
||||
0x0408338c, 0x04ca309c, 0x65c721e6, 0x65c63641,
|
||||
0x65982882, 0x04812b8b, 0x0e251083, 0x4e3712d5,
|
||||
0x0e61101f, 0x4e6d118b, 0x0eba1338, 0x4eb712d5,
|
||||
0x2e31120f, 0x6e2e11ac, 0x2e6810e6, 0x6e6f11cd,
|
||||
0x2eaa1128, 0x6eb1120f,
|
||||
};
|
||||
// END Generated code -- do not edit
|
||||
|
||||
@@ -1417,11 +1417,6 @@ public class IRNode {
|
||||
beforeMatchingNameRegex(VECTOR_MASK_TO_LONG, "VectorMaskToLong");
|
||||
}
|
||||
|
||||
public static final String VECTOR_MASK_LANE_IS_SET = PREFIX + "VECTOR_MASK_LANE_IS_SET" + POSTFIX;
|
||||
static {
|
||||
beforeMatchingNameRegex(VECTOR_MASK_LANE_IS_SET, "ExtractUB");
|
||||
}
|
||||
|
||||
// Can only be used if avx512_vnni is available.
|
||||
public static final String MUL_ADD_VS2VI_VNNI = PREFIX + "MUL_ADD_VS2VI_VNNI" + POSTFIX;
|
||||
static {
|
||||
|
||||
@@ -42,8 +42,8 @@ public class CheckLoopStripMining {
|
||||
"-XX:+SafepointTimeout",
|
||||
"-XX:+SafepointALot",
|
||||
"-XX:+AbortVMOnSafepointTimeout",
|
||||
"-XX:SafepointTimeoutDelay=" + Utils.adjustTimeout(1200),
|
||||
"-XX:GuaranteedSafepointInterval=" + Utils.adjustTimeout(1200),
|
||||
"-XX:SafepointTimeoutDelay=" + Utils.adjustTimeout(300),
|
||||
"-XX:GuaranteedSafepointInterval=" + Utils.adjustTimeout(300),
|
||||
"-XX:-TieredCompilation",
|
||||
"-XX:+UseCountedLoopSafepoints",
|
||||
"-XX:LoopStripMiningIter=1000",
|
||||
@@ -58,8 +58,8 @@ public class CheckLoopStripMining {
|
||||
"-XX:+SafepointTimeout",
|
||||
"-XX:+SafepointALot",
|
||||
"-XX:+AbortVMOnSafepointTimeout",
|
||||
"-XX:SafepointTimeoutDelay=" + Utils.adjustTimeout(1200),
|
||||
"-XX:GuaranteedSafepointInterval=" + Utils.adjustTimeout(1200),
|
||||
"-XX:SafepointTimeoutDelay=" + Utils.adjustTimeout(300),
|
||||
"-XX:GuaranteedSafepointInterval=" + Utils.adjustTimeout(300),
|
||||
"-XX:-TieredCompilation",
|
||||
"-XX:+UseCountedLoopSafepoints",
|
||||
"-XX:LoopStripMiningIter=1000",
|
||||
|
||||
@@ -1,160 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package compiler.vectorapi;
|
||||
|
||||
import compiler.lib.ir_framework.*;
|
||||
import jdk.incubator.vector.*;
|
||||
import jdk.test.lib.Asserts;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8366588
|
||||
* @key randomness
|
||||
* @library /test/lib /
|
||||
* @summary VectorAPI: Re-intrinsify VectorMask.laneIsSet where the input index is a variable
|
||||
* @modules jdk.incubator.vector
|
||||
*
|
||||
* @run driver compiler.vectorapi.VectorMaskLaneIsSetTest
|
||||
*/
|
||||
|
||||
public class VectorMaskLaneIsSetTest {
|
||||
static final VectorSpecies<Byte> B_SPECIES = ByteVector.SPECIES_MAX;
|
||||
static final VectorSpecies<Short> S_SPECIES = ShortVector.SPECIES_MAX;
|
||||
static final VectorSpecies<Integer> I_SPECIES = IntVector.SPECIES_MAX;
|
||||
static final VectorSpecies<Float> F_SPECIES = FloatVector.SPECIES_MAX;
|
||||
static final VectorSpecies<Long> L_SPECIES = LongVector.SPECIES_MAX;
|
||||
static final VectorSpecies<Double> D_SPECIES = DoubleVector.SPECIES_MAX;
|
||||
static final int LENGTH = 512;
|
||||
static boolean[] ma;
|
||||
static VectorMask<Byte> mask_b;
|
||||
static VectorMask<Short> mask_s;
|
||||
static VectorMask<Integer> mask_i;
|
||||
static VectorMask<Long> mask_l;
|
||||
static VectorMask<Float> mask_f;
|
||||
static VectorMask<Double> mask_d;
|
||||
|
||||
static {
|
||||
ma = new boolean[LENGTH];
|
||||
for (int i = 0; i < LENGTH; i++) {
|
||||
ma[i] = i % 2 == 0;
|
||||
}
|
||||
mask_b = VectorMask.fromArray(B_SPECIES, ma, 0);
|
||||
mask_s = VectorMask.fromArray(S_SPECIES, ma, 0);
|
||||
mask_i = VectorMask.fromArray(I_SPECIES, ma, 0);
|
||||
mask_l = VectorMask.fromArray(L_SPECIES, ma, 0);
|
||||
mask_f = VectorMask.fromArray(F_SPECIES, ma, 0);
|
||||
mask_d = VectorMask.fromArray(D_SPECIES, ma, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.VECTOR_MASK_LANE_IS_SET, "= 6" }, applyIfCPUFeature = { "asimd", "true" })
|
||||
@IR(counts = { IRNode.VECTOR_MASK_TO_LONG, "= 6" }, applyIfCPUFeatureOr = { "avx2", "true", "rvv", "true" })
|
||||
public static void testVectorMaskLaneIsSetByte_const() {
|
||||
Asserts.assertEquals(ma[0], mask_b.laneIsSet(0));
|
||||
Asserts.assertEquals(ma[0], mask_s.laneIsSet(0));
|
||||
Asserts.assertEquals(ma[0], mask_i.laneIsSet(0));
|
||||
Asserts.assertEquals(ma[0], mask_l.laneIsSet(0));
|
||||
Asserts.assertEquals(ma[0], mask_f.laneIsSet(0));
|
||||
Asserts.assertEquals(ma[0], mask_d.laneIsSet(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.VECTOR_MASK_LANE_IS_SET, "= 1" }, applyIfCPUFeature = { "asimd", "true" })
|
||||
@IR(counts = { IRNode.VECTOR_MASK_TO_LONG, "= 1" }, applyIfCPUFeatureOr = { "avx", "true", "rvv", "true" })
|
||||
public static boolean testVectorMaskLaneIsSet_Byte_variable(int i) {
|
||||
return mask_b.laneIsSet(i);
|
||||
}
|
||||
|
||||
@Run(test = "testVectorMaskLaneIsSet_Byte_variable")
|
||||
public static void testVectorMaskLaneIsSet_Byte_variable_runner() {
|
||||
Asserts.assertEquals(ma[0], testVectorMaskLaneIsSet_Byte_variable(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.VECTOR_MASK_LANE_IS_SET, "= 1" }, applyIfCPUFeature = { "asimd", "true" })
|
||||
@IR(counts = { IRNode.VECTOR_MASK_TO_LONG, "= 1" }, applyIfCPUFeatureOr = { "avx", "true", "rvv", "true" })
|
||||
public static boolean testVectorMaskLaneIsSet_Short_variable(int i) {
|
||||
return mask_s.laneIsSet(i);
|
||||
}
|
||||
|
||||
@Run(test = "testVectorMaskLaneIsSet_Short_variable")
|
||||
public static void testVectorMaskLaneIsSet_Short_variable_runner() {
|
||||
Asserts.assertEquals(ma[0], testVectorMaskLaneIsSet_Short_variable(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.VECTOR_MASK_LANE_IS_SET, "= 1" }, applyIfCPUFeature = { "asimd", "true" })
|
||||
@IR(counts = { IRNode.VECTOR_MASK_TO_LONG, "= 1" }, applyIfCPUFeatureOr = { "avx", "true", "rvv", "true" })
|
||||
public static boolean testVectorMaskLaneIsSet_Int_variable(int i) {
|
||||
return mask_i.laneIsSet(i);
|
||||
}
|
||||
|
||||
@Run(test = "testVectorMaskLaneIsSet_Int_variable")
|
||||
public static void testVectorMaskLaneIsSet_Int_variable_runner() {
|
||||
Asserts.assertEquals(ma[0], testVectorMaskLaneIsSet_Int_variable(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.VECTOR_MASK_LANE_IS_SET, "= 1" }, applyIfCPUFeature = { "asimd", "true" })
|
||||
@IR(counts = { IRNode.VECTOR_MASK_TO_LONG, "= 1" }, applyIfCPUFeatureOr = { "avx2", "true", "rvv", "true" })
|
||||
public static boolean testVectorMaskLaneIsSet_Long_variable(int i) {
|
||||
return mask_l.laneIsSet(i);
|
||||
}
|
||||
|
||||
@Run(test = "testVectorMaskLaneIsSet_Long_variable")
|
||||
public static void testVectorMaskLaneIsSet_Long_variable_runner() {
|
||||
Asserts.assertEquals(ma[0], testVectorMaskLaneIsSet_Long_variable(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.VECTOR_MASK_LANE_IS_SET, "= 1" }, applyIfCPUFeature = { "asimd", "true" })
|
||||
@IR(counts = { IRNode.VECTOR_MASK_TO_LONG, "= 1" }, applyIfCPUFeatureOr = { "avx", "true", "rvv", "true" })
|
||||
public static boolean testVectorMaskLaneIsSet_Float_variable(int i) {
|
||||
return mask_f.laneIsSet(i);
|
||||
}
|
||||
|
||||
@Run(test = "testVectorMaskLaneIsSet_Float_variable")
|
||||
public static void testVectorMaskLaneIsSet_Float_variable_runner() {
|
||||
Asserts.assertEquals(ma[0], testVectorMaskLaneIsSet_Float_variable(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = { IRNode.VECTOR_MASK_LANE_IS_SET, "= 1" }, applyIfCPUFeature = { "asimd", "true" })
|
||||
@IR(counts = { IRNode.VECTOR_MASK_TO_LONG, "= 1" }, applyIfCPUFeatureOr = { "avx2", "true", "rvv", "true" })
|
||||
public static boolean testVectorMaskLaneIsSet_Double_variable(int i) {
|
||||
return mask_d.laneIsSet(i);
|
||||
}
|
||||
|
||||
@Run(test = "testVectorMaskLaneIsSet_Double_variable")
|
||||
public static void testVectorMaskLaneIsSet_Double_variable_runner() {
|
||||
Asserts.assertEquals(ma[0], testVectorMaskLaneIsSet_Double_variable(0));
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
TestFramework testFramework = new TestFramework();
|
||||
testFramework.setDefaultWarmup(10000)
|
||||
.addFlags("--add-modules=jdk.incubator.vector")
|
||||
.start();
|
||||
}
|
||||
}
|
||||
@@ -44,7 +44,6 @@ public class TestIncludesAreSorted {
|
||||
*/
|
||||
private static final String[] HOTSPOT_SOURCES_TO_CHECK = {
|
||||
"os/linux",
|
||||
"os/posix",
|
||||
"share"
|
||||
};
|
||||
|
||||
|
||||
@@ -21,9 +21,9 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
/**
|
||||
* @test
|
||||
* @bug 8295803 8299689 8351435 8361613 8366261
|
||||
* @bug 8295803 8299689 8351435 8361613
|
||||
* @summary Tests System.console() returns correct Console (or null) from the expected
|
||||
* module.
|
||||
* @library /test/lib
|
||||
@@ -92,12 +92,9 @@ public class ModuleSelectionTest {
|
||||
var con = System.console();
|
||||
var pc = Class.forName("java.io.ProxyingConsole");
|
||||
var jdkc = Class.forName("jdk.internal.io.JdkConsole");
|
||||
var lookup = MethodHandles.privateLookupIn(Console.class, MethodHandles.lookup());
|
||||
var istty = (boolean)lookup.findStatic(Console.class, "isStdinTty", MethodType.methodType(boolean.class))
|
||||
.invoke() &&
|
||||
(boolean)lookup.findStatic(Console.class, "isStdoutTty", MethodType.methodType(boolean.class))
|
||||
.invoke();
|
||||
|
||||
var istty = (boolean)MethodHandles.privateLookupIn(Console.class, MethodHandles.lookup())
|
||||
.findStatic(Console.class, "istty", MethodType.methodType(boolean.class))
|
||||
.invoke();
|
||||
var impl = con != null ? MethodHandles.privateLookupIn(pc, MethodHandles.lookup())
|
||||
.findGetter(pc, "delegate", jdkc)
|
||||
.invoke(con) : null;
|
||||
|
||||
@@ -212,7 +212,7 @@ public class Basic {
|
||||
|
||||
private static String winEnvFilter(String env) {
|
||||
return env.replaceAll("\r", "")
|
||||
.replaceAll("(?m)^(?:COMSPEC|PROMPT|PATHEXT|PROCESSOR_ARCHITECTURE)=.*\n","");
|
||||
.replaceAll("(?m)^(?:COMSPEC|PROMPT|PATHEXT)=.*\n","");
|
||||
}
|
||||
|
||||
private static String unixEnvProg() {
|
||||
@@ -811,14 +811,6 @@ public class Basic {
|
||||
return vars.replace("AIXTHREAD_GUARDPAGES=0,", "");
|
||||
}
|
||||
|
||||
/* Only used for Windows AArch64 --
|
||||
* Windows AArch64 adds the variable PROCESSOR_ARCHITECTURE=ARM64 to the environment.
|
||||
* Remove it from the list of env variables
|
||||
*/
|
||||
private static String removeWindowsAArch64ExpectedVars(String vars) {
|
||||
return vars.replace("PROCESSOR_ARCHITECTURE=ARM64,", "");
|
||||
}
|
||||
|
||||
private static String sortByLinesWindowsly(String text) {
|
||||
String[] lines = text.split("\n");
|
||||
Arrays.sort(lines, new WindowsComparator());
|
||||
@@ -1329,9 +1321,6 @@ public class Basic {
|
||||
if (AIX.is()) {
|
||||
result = removeAixExpectedVars(result);
|
||||
}
|
||||
if (Windows.is() && Platform.isAArch64()) {
|
||||
result = removeWindowsAArch64ExpectedVars(result);
|
||||
}
|
||||
equal(result, expected);
|
||||
} catch (Throwable t) { unexpected(t); }
|
||||
|
||||
@@ -1844,9 +1833,6 @@ public class Basic {
|
||||
if (AIX.is()) {
|
||||
commandOutput = removeAixExpectedVars(commandOutput);
|
||||
}
|
||||
if (Windows.is() && Platform.isAArch64()) {
|
||||
commandOutput = removeWindowsAArch64ExpectedVars(commandOutput);
|
||||
}
|
||||
equal(commandOutput, expected);
|
||||
if (Windows.is()) {
|
||||
ProcessBuilder pb = new ProcessBuilder(childArgs);
|
||||
@@ -1854,11 +1840,7 @@ public class Basic {
|
||||
pb.environment().put("SystemRoot", systemRoot);
|
||||
pb.environment().put("=ExitValue", "3");
|
||||
pb.environment().put("=C:", "\\");
|
||||
commandOutput = commandOutput(pb);
|
||||
if (Platform.isAArch64()) {
|
||||
commandOutput = removeWindowsAArch64ExpectedVars(commandOutput);
|
||||
}
|
||||
equal(commandOutput, expected);
|
||||
equal(commandOutput(pb), expected);
|
||||
}
|
||||
} catch (Throwable t) { unexpected(t); }
|
||||
|
||||
@@ -1910,9 +1892,6 @@ public class Basic {
|
||||
if (AIX.is()) {
|
||||
commandOutput = removeAixExpectedVars(commandOutput);
|
||||
}
|
||||
if (Windows.is() && Platform.isAArch64()) {
|
||||
commandOutput = removeWindowsAArch64ExpectedVars(commandOutput);
|
||||
}
|
||||
check(commandOutput.equals(Windows.is()
|
||||
? "LC_ALL=C,SystemRoot="+systemRoot+","
|
||||
: AIX.is()
|
||||
|
||||
@@ -23,9 +23,7 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4068067 4101150 8366401
|
||||
* @library /java/text/testlib
|
||||
* @build HexDumpReader
|
||||
* @bug 8366401
|
||||
* @summary Check serialization of DecimalFormatSymbols. That is, ensure the
|
||||
* behavior for each stream version is correct during de-serialization.
|
||||
* @run junit/othervm --add-opens java.base/java.text=ALL-UNNAMED DFSSerializationTest
|
||||
@@ -37,11 +35,9 @@ import org.junit.jupiter.api.Test;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InvalidObjectException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Field;
|
||||
import java.text.DecimalFormatSymbols;
|
||||
import java.util.Currency;
|
||||
@@ -55,36 +51,13 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
public class DFSSerializationTest {
|
||||
|
||||
// Test that rely on hex dump files that were written from older JDK versions
|
||||
@Nested
|
||||
class HexDumpTests {
|
||||
|
||||
@Test // See 4068067 and CDFS which is the class in the serialized hex dump
|
||||
void JDK1_1_4Test() {
|
||||
// Reconstruct a class serialized during 1.1.4 which has a DFS holder
|
||||
var cdfs = (CheckDecimalFormatSymbols) assertDoesNotThrow(
|
||||
() -> deSer("DecimalFormatSymbols.114.txt"));
|
||||
assertDoesNotThrow(cdfs::Update); // Checks getDigit call succeeds
|
||||
}
|
||||
|
||||
@Test // See 4068067
|
||||
void JDK1_4_2Test() {
|
||||
// Reconstruct a 1.4.2 DFS
|
||||
var dfs = (DecimalFormatSymbols) assertDoesNotThrow(
|
||||
() -> deSer("DecimalFormatSymbols.142.txt"));
|
||||
// Checks curr symbol is saved, and exponent separator default set
|
||||
assertEquals("E", dfs.getExponentSeparator());
|
||||
assertEquals("*SpecialCurrencySymbol*", dfs.getCurrencySymbol());
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
class StreamVersionTests {
|
||||
class VersionTests {
|
||||
|
||||
// Ensure correct monetarySeparator and exponential field defaults
|
||||
// Reads monetary from decimal, and sets exponential to 'E'
|
||||
@Test
|
||||
void version0Test() {
|
||||
public void version0Test() {
|
||||
var crafted = new DFSBuilder()
|
||||
.setVer(0)
|
||||
.set("monetarySeparator", '~')
|
||||
@@ -103,7 +76,7 @@ public class DFSSerializationTest {
|
||||
// Note that other versions did allow a locale field, which was nullable.
|
||||
// E.g. see nullableLocaleTest which does not set locale when it is `null`
|
||||
@Test
|
||||
void version1Test() {
|
||||
public void version1Test() {
|
||||
var crafted = new DFSBuilder()
|
||||
.setVer(1)
|
||||
.set("locale", null)
|
||||
@@ -116,7 +89,7 @@ public class DFSSerializationTest {
|
||||
// Version 2 did not have an exponential separator, and created it via exponent
|
||||
// char field.
|
||||
@Test
|
||||
void version2Test() {
|
||||
public void version2Test() {
|
||||
var crafted = new DFSBuilder()
|
||||
.setVer(2)
|
||||
.set("exponentialSeparator", null)
|
||||
@@ -130,7 +103,7 @@ public class DFSSerializationTest {
|
||||
// Version 3 didn't have perMillText, percentText, and minusSignText.
|
||||
// These were created from the corresponding char equivalents.
|
||||
@Test
|
||||
void version3Test() {
|
||||
public void version3Test() {
|
||||
var crafted = new DFSBuilder()
|
||||
.setVer(3)
|
||||
.set("perMillText", null)
|
||||
@@ -152,7 +125,7 @@ public class DFSSerializationTest {
|
||||
// Version 4 did not have monetaryGroupingSeparator. It should be based
|
||||
// off of groupingSeparator.
|
||||
@Test
|
||||
void version4Test() {
|
||||
public void version4Test() {
|
||||
var crafted = new DFSBuilder()
|
||||
.setVer(4)
|
||||
.set("monetaryGroupingSeparator", 'Z')
|
||||
@@ -169,7 +142,7 @@ public class DFSSerializationTest {
|
||||
// the case and previous stream versions can contain a null locale. Thus,
|
||||
// ensure that a null locale does not cause number data loading to fail.
|
||||
@Test
|
||||
void nullableLocaleTest() {
|
||||
public void nullableLocaleTest() {
|
||||
var bytes = ser(new DFSBuilder()
|
||||
.set("locale", null)
|
||||
.set("minusSignText", "zFoo")
|
||||
@@ -184,7 +157,7 @@ public class DFSSerializationTest {
|
||||
// readObject fails when the {@code char} and {@code String} representations
|
||||
// of percent, per mille, and/or minus sign disagree.
|
||||
@Test
|
||||
void disagreeingTextTest() {
|
||||
public void disagreeingTextTest() {
|
||||
var expected = "'char' and 'String' representations of either percent, " +
|
||||
"per mille, and/or minus sign disagree.";
|
||||
assertEquals(expected, assertThrows(InvalidObjectException.class, () ->
|
||||
@@ -206,7 +179,7 @@ public class DFSSerializationTest {
|
||||
|
||||
// Ensure the serial version is updated to the current after de-serialization.
|
||||
@Test
|
||||
void updatedVersionTest() {
|
||||
public void updatedVersionTest() {
|
||||
var bytes = ser(new DFSBuilder().setVer(-25).build());
|
||||
var dfs = assertDoesNotThrow(() -> deSer(bytes));
|
||||
assertEquals(5, readField(dfs, "serialVersionOnStream"));
|
||||
@@ -214,7 +187,7 @@ public class DFSSerializationTest {
|
||||
|
||||
// Should set currency from 4217 code when it is valid.
|
||||
@Test
|
||||
void validIntlCurrencyTest() {
|
||||
public void validIntlCurrencyTest() {
|
||||
var bytes = ser(new DFSBuilder().set("intlCurrencySymbol", "JPY").build());
|
||||
var dfs = assertDoesNotThrow(() -> deSer(bytes));
|
||||
assertEquals(Currency.getInstance("JPY"), dfs.getCurrency());
|
||||
@@ -222,7 +195,7 @@ public class DFSSerializationTest {
|
||||
|
||||
// Should not set currency when 4217 code is invalid, it remains null.
|
||||
@Test
|
||||
void invalidIntlCurrencyTest() {
|
||||
public void invalidIntlCurrencyTest() {
|
||||
var bytes = ser(new DFSBuilder()
|
||||
.set("intlCurrencySymbol", ">.,")
|
||||
.set("locale", Locale.JAPAN)
|
||||
@@ -232,26 +205,6 @@ public class DFSSerializationTest {
|
||||
assertNull(dfs.getCurrency());
|
||||
}
|
||||
|
||||
// Ensure the currency symbol is read properly
|
||||
@Test
|
||||
void currencySymbolTest() {
|
||||
var crafted = new DecimalFormatSymbols();
|
||||
crafted.setCurrencySymbol("*SpecialCurrencySymbol*");
|
||||
var bytes = ser(crafted);
|
||||
var dfs = assertDoesNotThrow(() -> deSer(bytes));
|
||||
assertEquals("*SpecialCurrencySymbol*", dfs.getCurrencySymbol());
|
||||
}
|
||||
|
||||
// Ensure the exponent separator is read properly
|
||||
@Test
|
||||
void exponentSeparatorTest() {
|
||||
var crafted = new DecimalFormatSymbols();
|
||||
crafted.setExponentSeparator("*SpecialExponentSeparator*");
|
||||
var bytes = ser(crafted);
|
||||
var dfs = assertDoesNotThrow(() -> deSer(bytes));
|
||||
assertEquals("*SpecialExponentSeparator*", dfs.getExponentSeparator());
|
||||
}
|
||||
|
||||
// Utilities ----
|
||||
|
||||
// Utility to serialize
|
||||
@@ -265,7 +218,7 @@ public class DFSSerializationTest {
|
||||
}, "Unexpected error during serialization");
|
||||
}
|
||||
|
||||
// Utility to deserialize from byte array
|
||||
// Utility to deserialize
|
||||
private static DecimalFormatSymbols deSer(byte[] bytes) throws IOException, ClassNotFoundException {
|
||||
try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
|
||||
ObjectInputStream ois = new ObjectInputStream(byteArrayInputStream)) {
|
||||
@@ -273,14 +226,6 @@ public class DFSSerializationTest {
|
||||
}
|
||||
}
|
||||
|
||||
// Utility to deserialize from file in hex format
|
||||
private static Object deSer(String file) throws IOException, ClassNotFoundException {
|
||||
try (InputStream stream = HexDumpReader.getStreamFromHexDump(file);
|
||||
ObjectInputStream ois = new ObjectInputStream(stream)) {
|
||||
return ois.readObject();
|
||||
}
|
||||
}
|
||||
|
||||
// Utility to read a private field
|
||||
private static Object readField(DecimalFormatSymbols dfs, String name) {
|
||||
return assertDoesNotThrow(() -> {
|
||||
@@ -317,12 +262,3 @@ public class DFSSerializationTest {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Not nested, so that it can be cast correctly for the 1.1.4 test
|
||||
class CheckDecimalFormatSymbols implements Serializable {
|
||||
DecimalFormatSymbols _decFormatSymbols = new DecimalFormatSymbols();
|
||||
public char Update()
|
||||
{
|
||||
return _decFormatSymbols.getDigit();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@@ -22,344 +22,65 @@
|
||||
*/
|
||||
/*
|
||||
* @test
|
||||
* @bug 4069754 4067878 4101150 4185761 8327640
|
||||
* @library /java/text/testlib
|
||||
* @build HexDumpReader
|
||||
* @summary Check de-serialization correctness for DecimalFormat. That is, ensure the
|
||||
* behavior for each stream version is correct during de-serialization.
|
||||
* @run junit/othervm --add-opens java.base/java.text=ALL-UNNAMED SerializationTest
|
||||
* @bug 8327640
|
||||
* @summary Check parseStrict correctness for DecimalFormat serialization
|
||||
* @run junit/othervm SerializationTest
|
||||
*/
|
||||
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InvalidObjectException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Field;
|
||||
import java.math.RoundingMode;
|
||||
import java.text.DateFormat;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.Random;
|
||||
import java.text.ParseException;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class SerializationTest {
|
||||
|
||||
@Nested // Test that rely on hex dump files that were written from older JDK versions
|
||||
class HexDumpTests {
|
||||
private static final NumberFormat FORMAT = NumberFormat.getInstance();
|
||||
|
||||
@Test // See 4101150 and CDF which is the serialized hex dump
|
||||
void JDK1_1_4Test() {
|
||||
// Reconstruct a 1.1.4 serializable class which has a DF holder
|
||||
var cdf = (CheckDecimalFormat) assertDoesNotThrow(
|
||||
() -> deSer("DecimalFormat.114.txt"));
|
||||
assertDoesNotThrow(cdf::Update); // Checks format call succeeds
|
||||
}
|
||||
|
||||
@Test // See 4185761
|
||||
void minMaxDigitsTest() {
|
||||
// Reconstructing a DFS stream from an older JDK version
|
||||
// The min digits are smaller than the max digits and should fail
|
||||
// minint maxint minfrac maxfrac
|
||||
// 0x122 0x121 0x124 0x123
|
||||
assertEquals("Digit count range invalid",
|
||||
assertThrows(InvalidObjectException.class,
|
||||
() -> deSer("NumberFormat4185761a.ser.txt")).getMessage());
|
||||
}
|
||||
|
||||
@Test // See 4185761
|
||||
void digitLimitTest() {
|
||||
// Reconstructing a DFS stream from an older JDK version
|
||||
// The digit values exceed the class invariant limits
|
||||
// minint maxint minfrac maxfrac
|
||||
// 0x311 0x312 0x313 0x314
|
||||
assertEquals("Digit count out of range",
|
||||
assertThrows(InvalidObjectException.class,
|
||||
() -> deSer("NumberFormat4185761b.ser.txt")).getMessage());
|
||||
}
|
||||
@BeforeAll
|
||||
public static void mutateFormat() {
|
||||
FORMAT.setStrict(true);
|
||||
}
|
||||
|
||||
@Nested
|
||||
class VersionTests {
|
||||
|
||||
// Version 0 did not have exponential fields and defaulted the value to false
|
||||
@Test
|
||||
void version0Test() {
|
||||
var crafted = new DFBuilder()
|
||||
.setVer(0)
|
||||
.set("useExponentialNotation", true)
|
||||
.build();
|
||||
var bytes = ser(crafted);
|
||||
var df = assertDoesNotThrow(() -> deSer(bytes));
|
||||
// Ensure we do not observe exponential notation form
|
||||
assertFalse(df.format(0).contains("E"));
|
||||
}
|
||||
|
||||
// Version 1 did not support the affix pattern Strings. Ensure when they
|
||||
// are read in from the stream they are not defaulted and remain null.
|
||||
@Test
|
||||
void version1Test() {
|
||||
var crafted = new DFBuilder()
|
||||
.setVer(1)
|
||||
.set("posPrefixPattern", null)
|
||||
.set("posSuffixPattern", null)
|
||||
.set("negPrefixPattern", null)
|
||||
.set("negSuffixPattern", null)
|
||||
.build();
|
||||
var bytes = ser(crafted);
|
||||
var df = assertDoesNotThrow(() -> deSer(bytes));
|
||||
assertNull(readField(df, "posPrefixPattern"));
|
||||
assertNull(readField(df, "posSuffixPattern"));
|
||||
assertNull(readField(df, "negPrefixPattern"));
|
||||
assertNull(readField(df, "negSuffixPattern"));
|
||||
}
|
||||
|
||||
// Version 2 did not support the min/max int and frac digits.
|
||||
// Ensure the proper defaults are set.
|
||||
@Test
|
||||
void version2Test() {
|
||||
var crafted = new DFBuilder()
|
||||
.setVer(2)
|
||||
.set("maximumIntegerDigits", -1)
|
||||
.set("maximumFractionDigits", -1)
|
||||
.set("minimumIntegerDigits", -1)
|
||||
.set("minimumFractionDigits", -1)
|
||||
.build();
|
||||
var bytes = ser(crafted);
|
||||
var df = assertDoesNotThrow(() -> deSer(bytes));
|
||||
assertEquals(1, df.getMinimumIntegerDigits());
|
||||
assertEquals(3, df.getMaximumFractionDigits());
|
||||
assertEquals(309, df.getMaximumIntegerDigits());
|
||||
assertEquals(0, df.getMinimumFractionDigits());
|
||||
}
|
||||
|
||||
// Version 3 did not support rounding mode. Should default to HALF_EVEN
|
||||
@Test
|
||||
void version3Test() {
|
||||
var crafted = new DFBuilder()
|
||||
.setVer(3)
|
||||
.set("roundingMode", RoundingMode.UNNECESSARY)
|
||||
.build();
|
||||
var bytes = ser(crafted);
|
||||
var df = assertDoesNotThrow(() -> deSer(bytes));
|
||||
assertEquals(RoundingMode.HALF_EVEN, df.getRoundingMode());
|
||||
}
|
||||
}
|
||||
|
||||
// Some invariant checking in DF relies on checking NF fields.
|
||||
// Either via NF.readObject() or through super calls in DF.readObject
|
||||
@Nested // For all these nested tests, see 4185761
|
||||
class NumberFormatTests {
|
||||
|
||||
// Ensure the max integer value invariant is not exceeded
|
||||
@Test
|
||||
void integerTest() {
|
||||
var crafted = new DFBuilder()
|
||||
.setSuper("maximumIntegerDigits", 786)
|
||||
.setSuper("minimumIntegerDigits", 785)
|
||||
.build();
|
||||
var bytes = ser(crafted);
|
||||
assertEquals("Digit count out of range",
|
||||
assertThrows(InvalidObjectException.class, () -> deSer(bytes)).getMessage());
|
||||
}
|
||||
|
||||
// Ensure the max fraction value invariant is not exceeded
|
||||
@Test
|
||||
void fractionTest() {
|
||||
var crafted = new DFBuilder()
|
||||
.setSuper("maximumFractionDigits", 788)
|
||||
.setSuper("minimumFractionDigits", 787)
|
||||
.build();
|
||||
var bytes = ser(crafted);
|
||||
assertEquals("Digit count out of range",
|
||||
assertThrows(InvalidObjectException.class, () -> deSer(bytes)).getMessage());
|
||||
}
|
||||
|
||||
// Ensure the minimum integer digits cannot be greater than the max
|
||||
@Test
|
||||
void maxMinIntegerTest() {
|
||||
var crafted = new DFBuilder()
|
||||
.setSuper("maximumIntegerDigits", 5)
|
||||
.setSuper("minimumIntegerDigits", 6)
|
||||
.build();
|
||||
var bytes = ser(crafted);
|
||||
assertEquals("Digit count range invalid",
|
||||
assertThrows(InvalidObjectException.class, () -> deSer(bytes)).getMessage());
|
||||
}
|
||||
|
||||
// Ensure the minimum fraction digits cannot be greater than the max
|
||||
@Test
|
||||
void maxMinFractionTest() {
|
||||
var crafted = new DFBuilder()
|
||||
.setSuper("maximumFractionDigits", 5)
|
||||
.setSuper("minimumFractionDigits", 6)
|
||||
.build();
|
||||
var bytes = ser(crafted);
|
||||
assertEquals("Digit count range invalid",
|
||||
assertThrows(InvalidObjectException.class, () -> deSer(bytes)).getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure the serial version is updated to the current after de-serialization.
|
||||
@Test
|
||||
void versionTest() {
|
||||
var bytes = ser(new DFBuilder().setVer(-25).build());
|
||||
var df = assertDoesNotThrow(() -> deSer(bytes));
|
||||
assertEquals(4, readField(df, "serialVersionOnStream"));
|
||||
public void testSerialization() throws IOException, ClassNotFoundException {
|
||||
// Serialize
|
||||
serialize("fmt.ser", FORMAT);
|
||||
// Deserialize
|
||||
deserialize("fmt.ser", FORMAT);
|
||||
}
|
||||
|
||||
// Ensure strictness value is read properly when it is set.
|
||||
@Test
|
||||
void strictnessTest() {
|
||||
var crafted = new DecimalFormat();
|
||||
crafted.setStrict(true);
|
||||
var bytes = ser(crafted);
|
||||
var df = assertDoesNotThrow(() -> deSer(bytes));
|
||||
assertTrue(df.isStrict());
|
||||
}
|
||||
|
||||
// Ensure invalid grouping sizes are corrected to the default invariant.
|
||||
@Test
|
||||
void groupingSizeTest() {
|
||||
var crafted = new DFBuilder()
|
||||
.set("groupingSize", (byte) -5)
|
||||
.build();
|
||||
var bytes = ser(crafted);
|
||||
var df = assertDoesNotThrow(() -> deSer(bytes));
|
||||
assertEquals(3, df.getGroupingSize());
|
||||
}
|
||||
|
||||
// Ensure a de-serialized dFmt does not throw NPE from missing digitList
|
||||
// later when formatting. i.e. re-construct the transient digitList field
|
||||
@Test // See 4069754, 4067878
|
||||
void digitListTest() {
|
||||
var crafted = new DecimalFormat();
|
||||
var bytes = ser(crafted);
|
||||
var df = assertDoesNotThrow(() -> deSer(bytes));
|
||||
assertDoesNotThrow(() -> df.format(1));
|
||||
assertNotNull(readField(df, "digitList"));
|
||||
}
|
||||
|
||||
// Similar to the previous test, but the original regression test
|
||||
// which was a failure in DateFormat due to DecimalFormat NPE
|
||||
@Test // See 4069754 and 4067878
|
||||
void digitListDateFormatTest() {
|
||||
var fmt = new FooFormat();
|
||||
fmt.now();
|
||||
var bytes = ser(fmt);
|
||||
var ff = (FooFormat) assertDoesNotThrow(() -> deSer0(bytes));
|
||||
assertDoesNotThrow(ff::now);
|
||||
}
|
||||
|
||||
static class FooFormat implements Serializable {
|
||||
DateFormat dateFormat = DateFormat.getDateInstance();
|
||||
|
||||
public String now() {
|
||||
GregorianCalendar calendar = new GregorianCalendar();
|
||||
Date t = calendar.getTime();
|
||||
return dateFormat.format(t);
|
||||
}
|
||||
}
|
||||
|
||||
// Utilities ----
|
||||
|
||||
// Utility to serialize
|
||||
private static byte[] ser(Object obj) {
|
||||
return assertDoesNotThrow(() -> {
|
||||
try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||
ObjectOutputStream oos = new ObjectOutputStream(byteArrayOutputStream)) {
|
||||
oos.writeObject(obj);
|
||||
return byteArrayOutputStream.toByteArray();
|
||||
private void serialize(String fileName, NumberFormat... formats)
|
||||
throws IOException {
|
||||
try (ObjectOutputStream os = new ObjectOutputStream(
|
||||
new FileOutputStream(fileName))) {
|
||||
for (NumberFormat fmt : formats) {
|
||||
os.writeObject(fmt);
|
||||
}
|
||||
}, "Unexpected error during serialization");
|
||||
}
|
||||
|
||||
// Utility to deserialize
|
||||
private static Object deSer0(byte[] bytes) throws IOException, ClassNotFoundException {
|
||||
try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
|
||||
ObjectInputStream ois = new ObjectInputStream(byteArrayInputStream)) {
|
||||
return ois.readObject();
|
||||
}
|
||||
}
|
||||
|
||||
// Convenience cast to DF
|
||||
private static DecimalFormat deSer(byte[] bytes) throws IOException, ClassNotFoundException {
|
||||
return (DecimalFormat) deSer0(bytes);
|
||||
}
|
||||
private static void deserialize(String fileName, NumberFormat... formats)
|
||||
throws IOException, ClassNotFoundException {
|
||||
try (ObjectInputStream os = new ObjectInputStream(
|
||||
new FileInputStream(fileName))) {
|
||||
for (NumberFormat fmt : formats) {
|
||||
NumberFormat obj = (NumberFormat) os.readObject();
|
||||
assertEquals(fmt, obj, "Serialized and deserialized"
|
||||
+ " objects do not match");
|
||||
|
||||
// Utility to deserialize from file in hex format
|
||||
private static Object deSer(String file) throws IOException, ClassNotFoundException {
|
||||
try (InputStream stream = HexDumpReader.getStreamFromHexDump(file);
|
||||
ObjectInputStream ois = new ObjectInputStream(stream)) {
|
||||
return ois.readObject();
|
||||
}
|
||||
}
|
||||
|
||||
// Utility to read a private field
|
||||
private static Object readField(DecimalFormat df, String name) {
|
||||
return assertDoesNotThrow(() -> {
|
||||
var field = DecimalFormat.class.getDeclaredField(name);
|
||||
field.setAccessible(true);
|
||||
return field.get(df);
|
||||
}, "Unexpected error during field reading");
|
||||
}
|
||||
|
||||
// Utility class to build instances of DF via reflection
|
||||
private static class DFBuilder {
|
||||
|
||||
private final DecimalFormat df;
|
||||
|
||||
private DFBuilder() {
|
||||
df = new DecimalFormat();
|
||||
}
|
||||
|
||||
private DFBuilder setVer(Object value) {
|
||||
return set("serialVersionOnStream", value);
|
||||
}
|
||||
|
||||
private DFBuilder setSuper(String field, Object value) {
|
||||
return set(df.getClass().getSuperclass(), field, value);
|
||||
}
|
||||
|
||||
private DFBuilder set(String field, Object value) {
|
||||
return set(df.getClass(), field, value);
|
||||
}
|
||||
|
||||
private DFBuilder set(Class<?> clzz, String field, Object value) {
|
||||
return assertDoesNotThrow(() -> {
|
||||
Field f = clzz.getDeclaredField(field);
|
||||
f.setAccessible(true);
|
||||
f.set(df, value);
|
||||
return this;
|
||||
}, "Unexpected error during reflection setting");
|
||||
}
|
||||
|
||||
private DecimalFormat build() {
|
||||
return df;
|
||||
String badNumber = "fooofooo23foo";
|
||||
assertThrows(ParseException.class, () -> fmt.parse(badNumber));
|
||||
assertThrows(ParseException.class, () -> obj.parse(badNumber));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Not nested, so that it can be recognized and cast correctly for the 1.1.4 test
|
||||
class CheckDecimalFormat implements Serializable {
|
||||
DecimalFormat _decFormat = (DecimalFormat) NumberFormat.getInstance();
|
||||
public String Update() {
|
||||
Random r = new Random();
|
||||
return _decFormat.format(r.nextDouble());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2016, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* No at-test for this test, because it needs to be run on older version JDK than 1.6 to test.
|
||||
* It was tested using 1.4.2. The file object was created using JDK1.6.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
import java.awt.*;
|
||||
import java.text.*;
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
|
||||
public class DFSDeserialization142{
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
try {
|
||||
|
||||
File file = new File("DecimalFormatSymbols.current");
|
||||
FileInputStream istream = new FileInputStream(file);
|
||||
ObjectInputStream p = new ObjectInputStream(istream);
|
||||
DecimalFormatSymbols dfs = (DecimalFormatSymbols)p.readObject();
|
||||
if (dfs.getCurrencySymbol().equals("*SpecialCurrencySymbol*")){
|
||||
System.out.println("Serialization/Deserialization Test Passed.");
|
||||
}else{
|
||||
throw new Exception("Serialization/Deserialization Test Failed:"+dfs.getCurrencySymbol());
|
||||
}
|
||||
istream.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* 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 4068067
|
||||
* @library /java/text/testlib
|
||||
* @build DFSSerialization HexDumpReader
|
||||
* @run junit DFSSerialization
|
||||
* @summary Three different tests are done.
|
||||
* 1. read from the object created using jdk1.4.2
|
||||
* 2. create a valid DecimalFormatSymbols object with current JDK, then read the object
|
||||
* 3. Try to create an valid DecimalFormatSymbols object by passing null to set null
|
||||
* for the exponent separator symbol. Expect the NullPointerException.
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.text.DecimalFormatSymbols;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
public class DFSSerialization{
|
||||
|
||||
@Test
|
||||
public void TestDFSSerialization(){
|
||||
/*
|
||||
* 1. read from the object created using jdk1.4.2
|
||||
*/
|
||||
File oldFile = new File(System.getProperty("test.src", "."), "DecimalFormatSymbols.142.txt");
|
||||
DecimalFormatSymbols dfs142 = readTestObject(oldFile);
|
||||
if (dfs142 != null){
|
||||
if (dfs142.getExponentSeparator().equals("E") && dfs142.getCurrencySymbol().equals("*SpecialCurrencySymbol*")){
|
||||
System.out.println("\n Deserialization of JDK1.4.2 Object from the current JDK: Passed.");
|
||||
System.out.println(" Deserialization of JDK1.4.2 Object from the current JDK: Passed.");
|
||||
} else {
|
||||
fail(" Deserialization of JDK1.4.2 Object from the current JDK was Failed:"
|
||||
+dfs142.getCurrencySymbol()+" "+dfs142.getExponentSeparator());
|
||||
/*
|
||||
* logically should not throw this exception as errln throws exception
|
||||
* if not thrown yet - but in case errln got changed
|
||||
*/
|
||||
throw new RuntimeException(" Deserialization of JDK1.4.2 Object from the current JDK was Failed:"
|
||||
+dfs142.getCurrencySymbol()+" "+dfs142.getExponentSeparator());
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 2. create a valid DecimalFormatSymbols object with current JDK, then read the object
|
||||
*/
|
||||
String validObject = "DecimalFormatSymbols.current";
|
||||
File currentFile = createTestObject(validObject, "*SpecialExponentSeparator*");
|
||||
|
||||
DecimalFormatSymbols dfsValid = readTestObject(currentFile);
|
||||
if (dfsValid != null){
|
||||
if (dfsValid.getExponentSeparator().equals("*SpecialExponentSeparator*") &&
|
||||
dfsValid.getCurrencySymbol().equals("*SpecialCurrencySymbol*")){
|
||||
System.out.println(" Deserialization of current JDK Object from the current JDK: Passed.");
|
||||
System.out.println(" Deserialization of current JDK Object from the current JDK: Passed.");
|
||||
} else {
|
||||
fail(" Deserialization of current JDK Object from the current JDK was Failed:"
|
||||
+dfsValid.getCurrencySymbol()+" "+dfsValid.getExponentSeparator());
|
||||
/*
|
||||
* logically should not throw this exception as errln throws exception
|
||||
* if not thrown yet - but in case errln got changed
|
||||
*/
|
||||
throw new RuntimeException(" Deserialization of current Object from the current JDK was Failed:"
|
||||
+dfsValid.getCurrencySymbol()+" "+dfsValid.getExponentSeparator());
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 3. Try to create an valid DecimalFormatSymbols object by passing null
|
||||
* to set null for the exponent separator symbol. Expect the NullPointerException.
|
||||
*/
|
||||
DecimalFormatSymbols symNPE = new DecimalFormatSymbols(Locale.US);
|
||||
boolean npePassed = false;
|
||||
try {
|
||||
symNPE.setExponentSeparator(null);
|
||||
} catch (NullPointerException npe){
|
||||
npePassed = true;
|
||||
System.out.println(" Trying to set exponent separator with null: Passed.");
|
||||
System.out.println(" Trying to set exponent separator with null: Passed.");
|
||||
}
|
||||
if (!npePassed){
|
||||
System.out.println(" Trying to set exponent separator with null:Failed.");
|
||||
fail(" Trying to set exponent separator with null:Failed.");
|
||||
/*
|
||||
* logically should not throw this exception as errln throws exception
|
||||
* if not thrown yet - but in case errln got changed
|
||||
*/
|
||||
throw new RuntimeException(" Trying to set exponent separator with null:Failed.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private DecimalFormatSymbols readTestObject(File inputFile){
|
||||
try (InputStream istream = inputFile.getName().endsWith(".txt") ?
|
||||
HexDumpReader.getStreamFromHexDump(inputFile) :
|
||||
new FileInputStream(inputFile)) {
|
||||
ObjectInputStream p = new ObjectInputStream(istream);
|
||||
DecimalFormatSymbols dfs = (DecimalFormatSymbols)p.readObject();
|
||||
return dfs;
|
||||
} catch (Exception e) {
|
||||
fail("Test Malfunction in DFSSerialization: Exception while reading the object");
|
||||
/*
|
||||
* logically should not throw this exception as errln throws exception
|
||||
* if not thrown yet - but in case errln got changed
|
||||
*/
|
||||
throw new RuntimeException("Test Malfunction: re-throwing the exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
private File createTestObject(String objectName, String expString){
|
||||
DecimalFormatSymbols dfs= new DecimalFormatSymbols();
|
||||
dfs.setExponentSeparator(expString);
|
||||
dfs.setCurrencySymbol("*SpecialCurrencySymbol*");
|
||||
System.out.println(" The special exponent separator is set : " + dfs.getExponentSeparator());
|
||||
System.out.println(" The special currency symbol is set : " + dfs.getCurrencySymbol());
|
||||
|
||||
// 6345659: create a test object in the test.class dir where test user has a write permission.
|
||||
File file = new File(System.getProperty("test.class", "."), objectName);
|
||||
try (FileOutputStream ostream = new FileOutputStream(file)) {
|
||||
ObjectOutputStream p = new ObjectOutputStream(ostream);
|
||||
p.writeObject(dfs);
|
||||
//System.out.println(" The special currency symbol is set : " + dfs.getCurrencySymbol());
|
||||
return file;
|
||||
} catch (Exception e){
|
||||
fail("Test Malfunction in DFSSerialization: Exception while creating an object");
|
||||
/*
|
||||
* logically should not throw this exception as errln throws exception
|
||||
* if not thrown yet - but in case errln got changed
|
||||
*/
|
||||
throw new RuntimeException("Test Malfunction: re-throwing the exception", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2016, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* No at-test for this test, because it needs to be run on JDK 1.4.2
|
||||
* Instead, the resulting serialized file
|
||||
* DecimalFormatSymbols.142 is archived.
|
||||
*/
|
||||
|
||||
import java.awt.*;
|
||||
import java.text.*;
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
|
||||
public class DFSSerialization142 {
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
try {
|
||||
|
||||
DecimalFormatSymbols dfs= new DecimalFormatSymbols();
|
||||
System.out.println("Default currency symbol in the default locale : " + dfs.getCurrencySymbol());
|
||||
dfs.setCurrencySymbol("*SpecialCurrencySymbol*");
|
||||
System.out.println("The special currency symbol is set : " + dfs.getCurrencySymbol());
|
||||
FileOutputStream ostream = new FileOutputStream("DecimalFormatSymbols.142");
|
||||
ObjectOutputStream p = new ObjectOutputStream(ostream);
|
||||
p.writeObject(dfs);
|
||||
ostream.close();
|
||||
System.out.println("DecimalFormatSymbols saved ok.");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@@ -28,8 +28,9 @@
|
||||
* 4087251 4087535 4088161 4088503 4090489 4090504 4092480 4092561 4095713
|
||||
* 4098741 4099404 4101481 4106658 4106662 4106664 4108738 4110936 4122840
|
||||
* 4125885 4134034 4134300 4140009 4141750 4145457 4147295 4147706 4162198
|
||||
* 4162852 4167494 4170798 4176114 4179818 4212072 4212073 4216742 4217661
|
||||
* 4243011 4243108 4330377 4233840 4241880 4833877 8008577 8227313 8174269
|
||||
* 4162852 4167494 4170798 4176114 4179818 4185761 4212072 4212073 4216742
|
||||
* 4217661 4243011 4243108 4330377 4233840 4241880 4833877 8008577 8227313
|
||||
* 8174269
|
||||
* @summary Regression tests for NumberFormat and associated classes
|
||||
* @library /java/text/testlib
|
||||
* @build HexDumpReader TestUtils
|
||||
@@ -306,6 +307,33 @@ public class NumberRegression {
|
||||
Locale.setDefault(savedLocale);
|
||||
}
|
||||
|
||||
/* bugs 4069754, 4067878
|
||||
* null pointer thrown when accessing a deserialized DecimalFormat
|
||||
* object.
|
||||
*/
|
||||
@Test
|
||||
public void Test4069754()
|
||||
{
|
||||
try {
|
||||
myformat it = new myformat();
|
||||
System.out.println(it.Now());
|
||||
FileOutputStream ostream = new FileOutputStream("t.tmp");
|
||||
ObjectOutputStream p = new ObjectOutputStream(ostream);
|
||||
p.writeObject(it);
|
||||
ostream.close();
|
||||
System.out.println("Saved ok.");
|
||||
|
||||
FileInputStream istream = new FileInputStream("t.tmp");
|
||||
ObjectInputStream p2 = new ObjectInputStream(istream);
|
||||
myformat it2 = (myformat)p2.readObject();
|
||||
System.out.println(it2.Now());
|
||||
istream.close();
|
||||
System.out.println("Loaded ok.");
|
||||
} catch (Exception foo) {
|
||||
fail("Test for bug 4069754 or 4057878 failed => Exception: " + foo.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DecimalFormat.applyPattern(String) allows illegal patterns
|
||||
*/
|
||||
@@ -1457,6 +1485,59 @@ public class NumberRegression {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void Test4185761() throws IOException, ClassNotFoundException {
|
||||
/* Code used to write out the initial files, which are
|
||||
* then edited manually:
|
||||
NumberFormat nf = NumberFormat.getInstance(Locale.US);
|
||||
nf.setMinimumIntegerDigits(0x111); // Keep under 309
|
||||
nf.setMaximumIntegerDigits(0x112); // Keep under 309
|
||||
nf.setMinimumFractionDigits(0x113); // Keep under 340
|
||||
nf.setMaximumFractionDigits(0x114); // Keep under 340
|
||||
FileOutputStream ostream =
|
||||
new FileOutputStream("NumberFormat4185761");
|
||||
ObjectOutputStream p = new ObjectOutputStream(ostream);
|
||||
p.writeObject(nf);
|
||||
ostream.close();
|
||||
*/
|
||||
|
||||
// File minint maxint minfrac maxfrac
|
||||
// NumberFormat4185761a 0x122 0x121 0x124 0x123
|
||||
// NumberFormat4185761b 0x311 0x312 0x313 0x314
|
||||
// File a is bad because the mins are smaller than the maxes.
|
||||
// File b is bad because the values are too big for a DecimalFormat.
|
||||
// These files have a sufix ".ser.txt".
|
||||
|
||||
InputStream istream = HexDumpReader.getStreamFromHexDump("NumberFormat4185761a.ser.txt");
|
||||
ObjectInputStream p = new ObjectInputStream(istream);
|
||||
try {
|
||||
NumberFormat nf = (NumberFormat) p.readObject();
|
||||
fail("FAIL: Deserialized bogus NumberFormat int:" +
|
||||
nf.getMinimumIntegerDigits() + ".." +
|
||||
nf.getMaximumIntegerDigits() + " frac:" +
|
||||
nf.getMinimumFractionDigits() + ".." +
|
||||
nf.getMaximumFractionDigits());
|
||||
} catch (InvalidObjectException e) {
|
||||
System.out.println("Ok: " + e.getMessage());
|
||||
}
|
||||
istream.close();
|
||||
|
||||
istream = HexDumpReader.getStreamFromHexDump("NumberFormat4185761b.ser.txt");
|
||||
p = new ObjectInputStream(istream);
|
||||
try {
|
||||
NumberFormat nf = (NumberFormat) p.readObject();
|
||||
fail("FAIL: Deserialized bogus DecimalFormat int:" +
|
||||
nf.getMinimumIntegerDigits() + ".." +
|
||||
nf.getMaximumIntegerDigits() + " frac:" +
|
||||
nf.getMinimumFractionDigits() + ".." +
|
||||
nf.getMaximumFractionDigits());
|
||||
} catch (InvalidObjectException e) {
|
||||
System.out.println("Ok: " + e.getMessage());
|
||||
}
|
||||
istream.close();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Some DecimalFormatSymbols changes are not picked up by DecimalFormat.
|
||||
* This includes the minus sign, currency symbol, international currency
|
||||
@@ -1849,6 +1930,20 @@ public class NumberRegression {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
class myformat implements Serializable
|
||||
{
|
||||
DateFormat _dateFormat = DateFormat.getDateInstance();
|
||||
|
||||
public String Now()
|
||||
{
|
||||
GregorianCalendar calendar = new GregorianCalendar();
|
||||
Date t = calendar.getTime();
|
||||
String nowStr = _dateFormat.format(t);
|
||||
return nowStr;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
class MyNumberFormatTest extends NumberFormat {
|
||||
public StringBuffer format(double number, StringBuffer toAppendTo, FieldPosition pos) {
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2016, 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 4101150
|
||||
* @library /java/text/testlib
|
||||
* @build SerializationLoadTest HexDumpReader
|
||||
* @run main SerializationLoadTest
|
||||
* @summary test serialization compatibility of DecimalFormat and DecimalFormatSymbols
|
||||
* @key randomness
|
||||
*/
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.Serializable;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.DecimalFormatSymbols;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.Random;
|
||||
|
||||
public class SerializationLoadTest {
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
try {
|
||||
InputStream istream1 = HexDumpReader.getStreamFromHexDump("DecimalFormat.114.txt");
|
||||
ObjectInputStream p = new ObjectInputStream(istream1);
|
||||
CheckDecimalFormat it = (CheckDecimalFormat)p.readObject();
|
||||
System.out.println("1.1.4 DecimalFormat Loaded ok.");
|
||||
System.out.println(it.Update());
|
||||
System.out.println("Called Update successfully.");
|
||||
istream1.close();
|
||||
|
||||
InputStream istream2 = HexDumpReader.getStreamFromHexDump("DecimalFormatSymbols.114.txt");
|
||||
ObjectInputStream p2 = new ObjectInputStream(istream2);
|
||||
CheckDecimalFormatSymbols it2 = (CheckDecimalFormatSymbols)p2.readObject();
|
||||
System.out.println("1.1.4 DecimalFormatSymbols Loaded ok.");
|
||||
System.out.println("getDigit : " + it2.Update());
|
||||
System.out.println("Called Update successfully.");
|
||||
istream2.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
class CheckDecimalFormat implements Serializable
|
||||
{
|
||||
DecimalFormat _decFormat = (DecimalFormat)NumberFormat.getInstance();
|
||||
|
||||
public String Update()
|
||||
{
|
||||
Random r = new Random();
|
||||
return _decFormat.format(r.nextDouble());
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
class CheckDecimalFormatSymbols implements Serializable
|
||||
{
|
||||
DecimalFormatSymbols _decFormatSymbols = new DecimalFormatSymbols();
|
||||
|
||||
public char Update()
|
||||
{
|
||||
return _decFormatSymbols.getDigit();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2016, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* No at-test for this test, because it needs to be run on JDK 1.1.4.
|
||||
* Instead, the resulting serialized files DecimalFormat.114 and
|
||||
* DecimalFormatSymbols.114 are archived.
|
||||
*/
|
||||
|
||||
import java.awt.*;
|
||||
import java.text.*;
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
|
||||
public class SerializationSaveTest {
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
try {
|
||||
CheckDecimalFormat it = new CheckDecimalFormat();
|
||||
System.out.println(it.Update());
|
||||
FileOutputStream ostream = new FileOutputStream("DecimalFormat.114");
|
||||
ObjectOutputStream p = new ObjectOutputStream(ostream);
|
||||
p.writeObject(it);
|
||||
ostream.close();
|
||||
System.out.println("DecimalFormat saved ok.");
|
||||
CheckDecimalFormatSymbols it2 = new CheckDecimalFormatSymbols();
|
||||
System.out.println("getDigit : " + it2.Update());
|
||||
FileOutputStream ostream2 = new FileOutputStream("DecimalFormatSymbols.114");
|
||||
ObjectOutputStream p2 = new ObjectOutputStream(ostream2);
|
||||
p2.writeObject(it2);
|
||||
ostream2.close();
|
||||
System.out.println("DecimalFormatSymbols saved ok.");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
class CheckDecimalFormat implements Serializable
|
||||
{
|
||||
DecimalFormat _decFormat = (DecimalFormat)NumberFormat.getInstance();
|
||||
|
||||
public String Update()
|
||||
{
|
||||
Random r = new Random();
|
||||
return _decFormat.format(r.nextDouble());
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
class CheckDecimalFormatSymbols implements Serializable
|
||||
{
|
||||
DecimalFormatSymbols _decFormatSymbols = new DecimalFormatSymbols();
|
||||
|
||||
public char Update()
|
||||
{
|
||||
return _decFormatSymbols.getDigit();
|
||||
}
|
||||
}
|
||||
@@ -39,15 +39,20 @@ import jdk.test.lib.jfr.EventNames;
|
||||
* @run main/timeout=480 jdk.jfr.event.profiling.TestCPUTimeSampleMultipleRecordings
|
||||
*/
|
||||
public class TestCPUTimeSampleMultipleRecordings {
|
||||
|
||||
static String nativeEvent = EventNames.CPUTimeSample;
|
||||
|
||||
static volatile boolean alive = true;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Thread t = new Thread(TestCPUTimeSampleMultipleRecordings::nativeMethod);
|
||||
t.setDaemon(true);
|
||||
t.start();
|
||||
for (int i = 0; i < 2; i++) {
|
||||
try (RecordingStream rs = new RecordingStream()) {
|
||||
rs.enable(EventNames.CPUTimeSample).with("throttle", "1ms");
|
||||
rs.onEvent(EventNames.CPUTimeSample, e -> {
|
||||
rs.enable(nativeEvent).with("throttle", "1ms");
|
||||
rs.onEvent(nativeEvent, e -> {
|
||||
alive = false;
|
||||
rs.close();
|
||||
});
|
||||
|
||||
@@ -55,7 +60,6 @@ public class TestCPUTimeSampleMultipleRecordings {
|
||||
}
|
||||
}
|
||||
alive = false;
|
||||
t.join();
|
||||
}
|
||||
|
||||
public static void nativeMethod() {
|
||||
|
||||
@@ -1,154 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2025 SAP SE. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package jdk.jfr.event.profiling;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import jdk.jfr.Recording;
|
||||
import jdk.jfr.consumer.RecordingStream;
|
||||
import jdk.jfr.consumer.RecordedEvent;
|
||||
import jdk.jfr.internal.JVM;
|
||||
import jdk.test.lib.Asserts;
|
||||
import jdk.test.lib.jfr.EventNames;
|
||||
import jdk.test.whitebox.WhiteBox;
|
||||
|
||||
|
||||
/*
|
||||
* Tests the sample queues increase in size as needed, when loss is recorded.
|
||||
* @test
|
||||
* @requires vm.hasJFR & os.family == "linux" & vm.debug
|
||||
* @library /test/lib
|
||||
* @modules jdk.jfr/jdk.jfr.internal
|
||||
* @build jdk.test.whitebox.WhiteBox
|
||||
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
|
||||
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
|
||||
* -Xbatch -XX:StartFlightRecording:dumponexit=true jdk.jfr.event.profiling.TestCPUTimeSampleQueueAutoSizes
|
||||
*/
|
||||
public class TestCPUTimeSampleQueueAutoSizes {
|
||||
|
||||
private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
|
||||
|
||||
private static final String BURST_THREAD_NAME = "Burst-Thread-1";
|
||||
|
||||
static volatile boolean alive = true;
|
||||
|
||||
record LossEvent(long relativeTimeMillis, long lostSamples) {}
|
||||
|
||||
/** A data collection from the CPUTimeSampleLost events for the burst thread */
|
||||
static class LossEventCollection {
|
||||
private final List<LossEvent> events = new ArrayList<>();
|
||||
|
||||
public synchronized void addEvent(LossEvent event) {
|
||||
events.add(event);
|
||||
}
|
||||
|
||||
public synchronized List<LossEvent> getSortedEvents() {
|
||||
return events.stream()
|
||||
.sorted(Comparator.comparingLong(e -> e.relativeTimeMillis))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public List<LossEvent> getEventsPerInterval(long widthMillis, long stopTimeMillis) {
|
||||
List<LossEvent> ret = new ArrayList<>();
|
||||
for (long start = 0; start < stopTimeMillis; start += widthMillis) {
|
||||
long actualStart = Math.min(start, stopTimeMillis - widthMillis);
|
||||
long lostSamples = events.stream()
|
||||
.filter(e -> e.relativeTimeMillis >= actualStart && e.relativeTimeMillis < actualStart + widthMillis)
|
||||
.mapToLong(e -> e.lostSamples)
|
||||
.sum();
|
||||
ret.add(new LossEvent(actualStart, lostSamples));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
try (RecordingStream rs = new RecordingStream()) {
|
||||
// setup recording
|
||||
AtomicLong firstSampleTimeMillis = new AtomicLong(0);
|
||||
AtomicLong lastSampleTimeMillis = new AtomicLong(0);
|
||||
LossEventCollection lossEvents = new LossEventCollection();
|
||||
rs.enable(EventNames.CPUTimeSample).with("throttle", "1ms");
|
||||
rs.onEvent(EventNames.CPUTimeSample, e -> {
|
||||
if (firstSampleTimeMillis.get() == 0 && e.getThread("eventThread").getJavaName().equals(BURST_THREAD_NAME)) {
|
||||
firstSampleTimeMillis.set(e.getStartTime().toEpochMilli());
|
||||
}
|
||||
if (e.getThread("eventThread").getJavaName().equals(BURST_THREAD_NAME)) {
|
||||
lastSampleTimeMillis.set(e.getStartTime().toEpochMilli());
|
||||
}
|
||||
});
|
||||
rs.enable(EventNames.CPUTimeSamplesLost);
|
||||
rs.onEvent(EventNames.CPUTimeSamplesLost, e -> {
|
||||
if (e.getThread("eventThread").getJavaName().equals(BURST_THREAD_NAME)) {
|
||||
long eventTime = e.getStartTime().toEpochMilli();
|
||||
long relativeTime = firstSampleTimeMillis.get() > 0 ? (eventTime - firstSampleTimeMillis.get()) : eventTime;
|
||||
System.out.println("Lost samples: " + e.getLong("lostSamples") + " at " + relativeTime);
|
||||
lossEvents.addEvent(new LossEvent(relativeTime, e.getLong("lostSamples")));
|
||||
}
|
||||
});
|
||||
WHITE_BOX.cpuSamplerSetOutOfStackWalking(false);
|
||||
rs.startAsync();
|
||||
// this thread runs all along
|
||||
Thread burstThread = new Thread(() -> WHITE_BOX.busyWait(11000));
|
||||
burstThread.setName(BURST_THREAD_NAME);
|
||||
burstThread.start();
|
||||
// now we toggle out-of-stack-walking off, wait 1 second and then turn it on for 500ms a few times
|
||||
for (int i = 0; i < 5; i++) {
|
||||
boolean supported = WHITE_BOX.cpuSamplerSetOutOfStackWalking(false);
|
||||
if (!supported) {
|
||||
System.out.println("Out-of-stack-walking not supported, skipping test");
|
||||
Asserts.assertFalse(true);
|
||||
return;
|
||||
}
|
||||
Thread.sleep(700);
|
||||
long iterations = WHITE_BOX.cpuSamplerOutOfStackWalkingIterations();
|
||||
WHITE_BOX.cpuSamplerSetOutOfStackWalking(true);
|
||||
Thread.sleep(300);
|
||||
while (WHITE_BOX.cpuSamplerOutOfStackWalkingIterations() == iterations) {
|
||||
Thread.sleep(50); // just to make sure the stack walking really ran
|
||||
}
|
||||
}
|
||||
rs.close();
|
||||
checkThatLossDecreased(lossEvents, lastSampleTimeMillis.get() - firstSampleTimeMillis.get());
|
||||
}
|
||||
}
|
||||
|
||||
static void checkThatLossDecreased(LossEventCollection lossEvents, long lastSampleTimeMillis) {
|
||||
List<LossEvent> intervalLosses = lossEvents.getEventsPerInterval(1000, lastSampleTimeMillis);
|
||||
for (LossEvent interval : intervalLosses) {
|
||||
System.out.println("Lost samples in interval " + interval.relativeTimeMillis + ": " + interval.lostSamples);
|
||||
}
|
||||
// check that there are at least 3 intervals
|
||||
Asserts.assertTrue(intervalLosses.size() > 2);
|
||||
// check that the second to last interval has far fewer lost samples than the first
|
||||
Asserts.assertTrue(intervalLosses.get(intervalLosses.size() - 2).lostSamples <
|
||||
intervalLosses.get(0).lostSamples / 2);
|
||||
}
|
||||
}
|
||||
@@ -841,13 +841,6 @@ public class WhiteBox {
|
||||
|
||||
public native void waitUnsafe(int time_ms);
|
||||
|
||||
public native void busyWait(int cpuTimeMs);
|
||||
|
||||
// returns true if supported, false if not
|
||||
public native boolean cpuSamplerSetOutOfStackWalking(boolean enable);
|
||||
|
||||
public native long cpuSamplerOutOfStackWalkingIterations();
|
||||
|
||||
public native void pinObject(Object o);
|
||||
|
||||
public native void unpinObject(Object o);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Arm Limited. All rights reserved.
|
||||
* Copyright (c) 2025, NVIDIA CORPORATION & 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
|
||||
@@ -29,9 +28,7 @@ import org.openjdk.jmh.annotations.*;
|
||||
|
||||
@OutputTimeUnit(TimeUnit.MILLISECONDS)
|
||||
@State(Scope.Thread)
|
||||
@Warmup(iterations = 5, time = 1)
|
||||
@Measurement(iterations = 5, time = 1)
|
||||
@Fork(value = 1, jvmArgs = {"--add-modules=jdk.incubator.vector"})
|
||||
@Fork(jvmArgs = {"--add-modules=jdk.incubator.vector"})
|
||||
public class VectorExtractBenchmark {
|
||||
private int idx = 0;
|
||||
private boolean[] res = new boolean[8];
|
||||
|
||||
Reference in New Issue
Block a user