diff --git a/make/langtools/test/crules/DefinedByAnalyzer/Test.java b/make/langtools/test/crules/DefinedByAnalyzer/Test.java index 901d7d9b1aee..9900504f7a58 100644 --- a/make/langtools/test/crules/DefinedByAnalyzer/Test.java +++ b/make/langtools/test/crules/DefinedByAnalyzer/Test.java @@ -12,14 +12,10 @@ public class Test implements SourcePositions, TaskListener { @Override @DefinedBy(Api.COMPILER_TREE) - public long getStartPosition(CompilationUnitTree file, Tree tree) { + public long getStartPosition(Tree tree) { return 0; } - @Override - public long getEndPosition(CompilationUnitTree file, Tree tree) { - return 0; - } - @DefinedBy(Api.COMPILER_TREE) + @Override @DefinedBy(Api.COMPILER_TREE) public long getEndPosition(Tree tree) { return 0; } diff --git a/src/hotspot/cpu/aarch64/aarch64.ad b/src/hotspot/cpu/aarch64/aarch64.ad index 37c8e0ae011f..366b1f94898c 100644 --- a/src/hotspot/cpu/aarch64/aarch64.ad +++ b/src/hotspot/cpu/aarch64/aarch64.ad @@ -1662,19 +1662,19 @@ bool needs_acquiring_load_exclusive(const Node *n) // from the start of the call to the point where the return address // will point. -int MachCallStaticJavaNode::ret_addr_offset() +int MachCallStaticJavaNode::ret_addr_offset() const { // call should be a simple bl int off = 4; return off; } -int MachCallDynamicJavaNode::ret_addr_offset() +int MachCallDynamicJavaNode::ret_addr_offset() const { return 16; // movz, movk, movk, bl } -int MachCallRuntimeNode::ret_addr_offset() { +int MachCallRuntimeNode::ret_addr_offset() const { // for generated stubs the call will be // bl(addr) // or with far branches diff --git a/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp index 7d490a99eaa9..1f76fa0778ad 100644 --- a/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp @@ -219,6 +219,10 @@ void C2_MacroAssembler::fast_lock(Register obj, Register box, Register t1, bind(inflated); const Register t1_monitor = t1; + // Offsets into the current thread's object monitor cache (omc). + const ByteSize thr_omc_offset = JavaThread::om_cache_offset(); + const ByteSize omc_monitor_offset = OMCache::monitor_offset(); + const ByteSize omc_obj_offset = OMCache::obj_offset(); if (!UseObjectMonitorTable) { assert(t1_monitor == t1_mark, "should be the same here"); @@ -229,18 +233,12 @@ void C2_MacroAssembler::fast_lock(Register obj, Register box, Register t1, // Save the mark, we might need it to extract the hash. mov(t3, t1_mark); - // Look for the monitor in the om_cache. - - ByteSize cache_offset = JavaThread::om_cache_oops_offset(); - ByteSize monitor_offset = OMCache::oop_to_monitor_difference(); - const int num_unrolled = OMCache::CAPACITY; - for (int i = 0; i < num_unrolled; i++) { - ldr(t1_monitor, Address(rthread, cache_offset + monitor_offset)); - ldr(t2, Address(rthread, cache_offset)); - cmp(obj, t2); - br(Assembler::EQ, monitor_found); - cache_offset = cache_offset + OMCache::oop_to_oop_difference(); - } + // Look for the monitor in the current thread's object monitor cache (omc). + + ldr(t1_monitor, Address(rthread, thr_omc_offset + omc_monitor_offset)); + ldr(t2, Address(rthread, thr_omc_offset + omc_obj_offset)); + cmp(obj, t2); + br(Assembler::EQ, monitor_found); // Look for the monitor in the table. @@ -268,6 +266,10 @@ void C2_MacroAssembler::fast_lock(Register obj, Register box, Register t1, cmp(t3, obj); br(Assembler::NE, slow_path); + // Store the monitor in the current thread's object monitor cache (omc). + str(t1_monitor, Address(rthread, thr_omc_offset + omc_monitor_offset)); + str(obj, Address(rthread, thr_omc_offset + omc_obj_offset)); + bind(monitor_found); } @@ -296,6 +298,7 @@ void C2_MacroAssembler::fast_lock(Register obj, Register box, Register t1, bind(monitor_locked); if (UseObjectMonitorTable) { + // Cache the monitor for unlock. str(t1_monitor, Address(box, BasicLock::object_monitor_cache_offset_in_bytes())); } } @@ -1506,9 +1509,9 @@ void C2_MacroAssembler::sve_vmask_fromlong(FloatRegister dst, Register src, // Expected: dst = 0x00 01 01 00 00 01 00 01 01 00 00 00 01 01 00 01 // Put long value from general purpose register into the first lane of vector. + // The higher lanes are set to zero. // vtmp = 0x0000000000000000 | 0x000000000000658D - sve_dup(vtmp, B, 0); - mov(vtmp, D, 0, src); + fmovd(vtmp, src); // Transform the value in the first lane which is mask in bit now to the mask in // byte, which can be done by SVE2's BDEP instruction. diff --git a/src/hotspot/cpu/aarch64/continuationFreezeThaw_aarch64.inline.hpp b/src/hotspot/cpu/aarch64/continuationFreezeThaw_aarch64.inline.hpp index a1a5209de7ab..d71288c1078f 100644 --- a/src/hotspot/cpu/aarch64/continuationFreezeThaw_aarch64.inline.hpp +++ b/src/hotspot/cpu/aarch64/continuationFreezeThaw_aarch64.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2026, 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 @@ -215,7 +215,8 @@ inline intptr_t* AnchorMark::anchor_mark_set_pd() { if (sp != _last_sp_from_frame) { // We need to move up return pc and fp. They will be read next in // set_anchor() and set as _last_Java_pc and _last_Java_fp respectively. - _last_sp_from_frame[-1] = (intptr_t)_top_frame.pc(); + ContinuationHelper::patch_return_address_at(&_last_sp_from_frame[-1], + _top_frame.pc()); _last_sp_from_frame[-2] = (intptr_t)_top_frame.fp(); } _is_interpreted = true; @@ -230,7 +231,7 @@ inline void AnchorMark::anchor_mark_clear_pd() { _top_frame.interpreter_frame_set_last_sp(_last_sp_from_frame); intptr_t* sp = _top_frame.sp(); if (sp != _last_sp_from_frame) { - sp[-1] = (intptr_t)_top_frame.pc(); + ContinuationHelper::patch_return_address_at(&sp[-1], _top_frame.pc()); } } } @@ -340,7 +341,8 @@ inline intptr_t* ThawBase::push_cleanup_continuation() { intptr_t* sp = enterSpecial.sp(); // We only need to set the return pc. rfp will be restored back in gen_continuation_enter(). - sp[-1] = (intptr_t)ContinuationEntry::cleanup_pc(); + ContinuationHelper::patch_return_address_at(&sp[-1], + ContinuationEntry::cleanup_pc()); return sp; } @@ -349,7 +351,8 @@ inline intptr_t* ThawBase::push_preempt_adapter() { intptr_t* sp = enterSpecial.sp(); // We only need to set the return pc. rfp will be restored back in generate_cont_preempt_stub(). - sp[-1] = (intptr_t)StubRoutines::cont_preempt_stub(); + ContinuationHelper::patch_return_address_at(&sp[-1], + StubRoutines::cont_preempt_stub()); return sp; } diff --git a/src/hotspot/cpu/aarch64/continuationHelper_aarch64.inline.hpp b/src/hotspot/cpu/aarch64/continuationHelper_aarch64.inline.hpp index 04a2d4e2bd57..ce218d71eb78 100644 --- a/src/hotspot/cpu/aarch64/continuationHelper_aarch64.inline.hpp +++ b/src/hotspot/cpu/aarch64/continuationHelper_aarch64.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,7 +47,8 @@ static inline void patch_return_pc_with_preempt_stub(frame& f) { // Instead, we will patch the return from the runtime stub back to the // compiled method so that the target returns to the preempt cleanup stub. intptr_t* caller_sp = f.sp() + f.cb()->frame_size(); - caller_sp[-1] = (intptr_t)StubRoutines::cont_preempt_stub(); + ContinuationHelper::patch_return_address_at(&caller_sp[-1], + StubRoutines::cont_preempt_stub()); } else { // The target will check for preemption once it returns to the interpreter // or the native wrapper code and will manually jump to the preempt stub. diff --git a/src/hotspot/cpu/arm/arm_32.ad b/src/hotspot/cpu/arm/arm_32.ad index 2af7e253a1a8..87ffc46e67a9 100644 --- a/src/hotspot/cpu/arm/arm_32.ad +++ b/src/hotspot/cpu/arm/arm_32.ad @@ -430,18 +430,18 @@ OptoRegPair c2::return_value(int ideal_reg) { // from the start of the call to the point where the return address // will point. -int MachCallStaticJavaNode::ret_addr_offset() { +int MachCallStaticJavaNode::ret_addr_offset() const { bool far = (_method == nullptr) ? maybe_far_call(this) : !cache_reachable(); return (far ? 3 : 1) * NativeInstruction::instruction_size; } -int MachCallDynamicJavaNode::ret_addr_offset() { +int MachCallDynamicJavaNode::ret_addr_offset() const { bool far = !cache_reachable(); // mov_oop is always 2 words return (2 + (far ? 3 : 1)) * NativeInstruction::instruction_size; } -int MachCallRuntimeNode::ret_addr_offset() { +int MachCallRuntimeNode::ret_addr_offset() const { // bl or movw; movt; blx bool far = maybe_far_call(this); return (far ? 3 : 1) * NativeInstruction::instruction_size; diff --git a/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp b/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp index 1501934d48f0..54327b738d64 100644 --- a/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp +++ b/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp @@ -2763,6 +2763,11 @@ void MacroAssembler::compiler_fast_lock_object(ConditionRegister flag, Register const Register monitor = UseObjectMonitorTable ? tmp1 : noreg; const Register owner_addr = tmp2; const Register thread_id = UseObjectMonitorTable ? tmp3 : tmp1; + // Offsets into the current thread's object monitor cache (omc). + const ByteSize thr_omc_offset = JavaThread::om_cache_offset(); + const ByteSize omc_monitor_offset = OMCache::monitor_offset(); + const ByteSize omc_obj_offset = OMCache::obj_offset(); + Label monitor_locked; if (!UseObjectMonitorTable) { @@ -2777,18 +2782,12 @@ void MacroAssembler::compiler_fast_lock_object(ConditionRegister flag, Register // Save the mark, we might need it to extract the hash. mr(tmp2_hash, mark); - // Look for the monitor in the om_cache. - - ByteSize cache_offset = JavaThread::om_cache_oops_offset(); - ByteSize monitor_offset = OMCache::oop_to_monitor_difference(); - const int num_unrolled = OMCache::CAPACITY; - for (int i = 0; i < num_unrolled; i++) { - ld(R0, in_bytes(cache_offset), R16_thread); - ld(monitor, in_bytes(cache_offset + monitor_offset), R16_thread); - cmpd(CR0, R0, obj); - beq(CR0, monitor_found); - cache_offset = cache_offset + OMCache::oop_to_oop_difference(); - } + // Look for the monitor in the current thread's object monitor cache (omc). + + ld(R0, in_bytes(thr_omc_offset + omc_obj_offset), R16_thread); + ld(monitor, in_bytes(thr_omc_offset + omc_monitor_offset), R16_thread); + cmpd(CR0, R0, obj); + beq(CR0, monitor_found); // Look for the monitor in the table. @@ -2817,6 +2816,10 @@ void MacroAssembler::compiler_fast_lock_object(ConditionRegister flag, Register cmpd(CR0, tmp3, obj); bne(CR0, slow_path); + // Store the monitor in the current thread's object monitor cache (omc). + std(monitor, in_bytes(thr_omc_offset + omc_monitor_offset), R16_thread); + std(obj, in_bytes(thr_omc_offset + omc_obj_offset), R16_thread); + bind(monitor_found); // Compute owner address. @@ -2854,6 +2857,7 @@ void MacroAssembler::compiler_fast_lock_object(ConditionRegister flag, Register bind(monitor_locked); if (UseObjectMonitorTable) { + // Cache the monitor for unlock. std(monitor, BasicLock::object_monitor_cache_offset_in_bytes(), box); } } diff --git a/src/hotspot/cpu/ppc/ppc.ad b/src/hotspot/cpu/ppc/ppc.ad index 2c0904a6b583..9428c0014e15 100644 --- a/src/hotspot/cpu/ppc/ppc.ad +++ b/src/hotspot/cpu/ppc/ppc.ad @@ -1171,16 +1171,16 @@ bool followed_by_acquire(const Node *load) { // PPC port: Removed use of lazy constant construct. -int MachCallStaticJavaNode::ret_addr_offset() { +int MachCallStaticJavaNode::ret_addr_offset() const { // It's only a single branch-and-link instruction. return 4; } -int MachCallDynamicJavaNode::ret_addr_offset() { +int MachCallDynamicJavaNode::ret_addr_offset() const { return 12; } -int MachCallRuntimeNode::ret_addr_offset() { +int MachCallRuntimeNode::ret_addr_offset() const { if (rule() == CallRuntimeDirect_rule) { // CallRuntimeDirectNode uses call_c. #if defined(ABI_ELFv2) diff --git a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp index 8d383f07c9ad..2dca5215aec1 100644 --- a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp @@ -121,6 +121,10 @@ void C2_MacroAssembler::fast_lock(Register obj, Register box, bind(inflated); const Register tmp1_monitor = tmp1; + // Offsets into the current thread's object monitor cache (omc). + const ByteSize thr_omc_offset = JavaThread::om_cache_offset(); + const ByteSize omc_monitor_offset = OMCache::monitor_offset(); + const ByteSize omc_obj_offset = OMCache::obj_offset(); if (!UseObjectMonitorTable) { assert(tmp1_monitor == tmp1_mark, "should be the same here"); @@ -132,17 +136,11 @@ void C2_MacroAssembler::fast_lock(Register obj, Register box, // Save the mark, we might need it to extract the hash. mv(tmp2_hash, tmp1_mark); - // Look for the monitor in the om_cache. + // Look for the monitor in the current thread's object monitor cache (omc). - ByteSize cache_offset = JavaThread::om_cache_oops_offset(); - ByteSize monitor_offset = OMCache::oop_to_monitor_difference(); - const int num_unrolled = OMCache::CAPACITY; - for (int i = 0; i < num_unrolled; i++) { - ld(tmp1_monitor, Address(xthread, cache_offset + monitor_offset)); - ld(tmp4, Address(xthread, cache_offset)); - beq(obj, tmp4, monitor_found); - cache_offset = cache_offset + OMCache::oop_to_oop_difference(); - } + ld(tmp1_monitor, Address(xthread, thr_omc_offset + omc_monitor_offset)); + ld(tmp4, Address(xthread, thr_omc_offset + omc_obj_offset)); + beq(obj, tmp4, monitor_found); // Look for the monitor in the table. @@ -170,6 +168,10 @@ void C2_MacroAssembler::fast_lock(Register obj, Register box, bs_asm->try_peek_weak_handle_in_nmethod(this, tmp3, tmp3, tmp2, slow_path); bne(tmp3, obj, slow_path); + // Store the monitor in the current thread's object monitor cache (omc). + sd(tmp1_monitor, Address(xthread, thr_omc_offset + omc_monitor_offset)); + sd(obj, Address(xthread, thr_omc_offset + omc_obj_offset)); + bind(monitor_found); } @@ -200,6 +202,7 @@ void C2_MacroAssembler::fast_lock(Register obj, Register box, bind(monitor_locked); if (UseObjectMonitorTable) { + // Cache the monitor for unlock. sd(tmp1_monitor, Address(box, BasicLock::object_monitor_cache_offset_in_bytes())); } } @@ -3295,6 +3298,17 @@ void C2_MacroAssembler::extract_v(Register dst, VectorRegister src, } } +// Extract a scalar element from a vector at position 'idx'. +// The input elements in src are expected to be of integral type. +void C2_MacroAssembler::extract_v(Register dst, VectorRegister src, + BasicType bt, Register idx, VectorRegister vtmp) { + assert(is_integral_type(bt), "unsupported element type"); + // Only need the first element after vector slidedown + vsetvli_helper(bt, 1); + vslidedown_vx(vtmp, src, idx); + vmv_x_s(dst, vtmp); +} + // Extract a scalar element from an vector at position 'idx'. // The input elements in src are expected to be of floating point type. void C2_MacroAssembler::extract_fp_v(FloatRegister dst, VectorRegister src, diff --git a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp index 468d53b1a540..d432e93b973e 100644 --- a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp @@ -299,6 +299,9 @@ void extract_v(Register dst, VectorRegister src, BasicType bt, int idx, VectorRegister vtmp); + void extract_v(Register dst, VectorRegister src, + BasicType bt, Register idx, VectorRegister vtmp); + void extract_fp_v(FloatRegister dst, VectorRegister src, BasicType bt, int idx, VectorRegister vtmp); diff --git a/src/hotspot/cpu/riscv/gc/g1/g1BarrierSetAssembler_riscv.cpp b/src/hotspot/cpu/riscv/gc/g1/g1BarrierSetAssembler_riscv.cpp index cf7cb98d2d4c..5ec01cfb4abe 100644 --- a/src/hotspot/cpu/riscv/gc/g1/g1BarrierSetAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/gc/g1/g1BarrierSetAssembler_riscv.cpp @@ -108,30 +108,29 @@ void G1BarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembler* mas __ srli(start, start, CardTable::card_shift()); __ srli(count, count, CardTable::card_shift()); - __ sub(count, count, start); // Number of bytes to mark - 1. - // Add card table base offset to start. + // Add card table base offset to get card addresses directly. Address card_table_address(xthread, G1ThreadLocalData::card_table_base_offset()); __ ld(tmp, card_table_address); - __ add(start, start, tmp); + __ add(start, start, tmp); // start := first card address + __ add(count, count, tmp); // count := last card address + // Iterate from start card to end card (inclusive). __ bind(loop); if (UseCondCardMark) { - __ add(tmp, start, count); - __ lbu(tmp, Address(tmp, 0)); + __ lbu(tmp, Address(start, 0)); static_assert((uint)G1CardTable::clean_card_val() == 0xff, "must be"); __ subi(tmp, tmp, G1CardTable::clean_card_val()); // Convert to clean_card_value() to a comparison // against zero to avoid use of an extra temp. __ bnez(tmp, next); } - __ add(tmp, start, count); static_assert(G1CardTable::dirty_card_val() == 0, "must be to use zr"); - __ sb(zr, Address(tmp, 0)); + __ sb(zr, Address(start, 0)); __ bind(next); - __ subi(count, count, 1); - __ bgez(count, loop); + __ addi(start, start, 1); + __ ble(start, count, loop); __ bind(done); } diff --git a/src/hotspot/cpu/riscv/riscv.ad b/src/hotspot/cpu/riscv/riscv.ad index e022dcb42628..714a00c1ce2b 100644 --- a/src/hotspot/cpu/riscv/riscv.ad +++ b/src/hotspot/cpu/riscv/riscv.ad @@ -1208,17 +1208,17 @@ bool needs_acquiring_load_reserved(const Node *n) // from the start of the call to the point where the return address // will point. -int MachCallStaticJavaNode::ret_addr_offset() +int MachCallStaticJavaNode::ret_addr_offset() const { return 3 * NativeInstruction::instruction_size; // auipc + ld + jalr } -int MachCallDynamicJavaNode::ret_addr_offset() +int MachCallDynamicJavaNode::ret_addr_offset() const { return NativeMovConstReg::movptr2_instruction_size + (3 * NativeInstruction::instruction_size); // movptr2, auipc + ld + jal } -int MachCallRuntimeNode::ret_addr_offset() { +int MachCallRuntimeNode::ret_addr_offset() const { // For address inside the code cache the call will be: // auipc + jalr // For real runtime callouts it will be 8 instructions @@ -10364,6 +10364,73 @@ instruct cmovI_cmpP(iRegINoSp dst, iRegI src, iRegP op1, iRegP op2, cmpOpU cop) ins_pipe(pipe_class_compare); %} +// Special cases where one arg is zero +// These are selected in preference to the rules above because they +// avoid loading constant 0 into a source register + +// CMoveI (signed compare) with zero as second operand +// Pattern: dst = cond ? dst : 0 (conditional clear) +instruct cmovI_cmpI_zero(iRegINoSp dst, immI0 src, iRegI op1, iRegI op2, cmpOp cop) %{ + match(Set dst (CMoveI (Binary cop (CmpI op1 op2)) (Binary dst src))); + ins_cost(ALU_COST + BRANCH_COST); + + format %{ "CMoveI $dst, ($op1 $cop $op2), $dst, zr\t#@cmovI_cmpI_zero" %} + + ins_encode %{ + __ enc_cmove($cop$$cmpcode, + as_Register($op1$$reg), as_Register($op2$$reg), + as_Register($dst$$reg), zr); + %} + + ins_pipe(pipe_class_compare); +%} + +// CMoveI (unsigned compare) with zero as second operand +instruct cmovI_cmpU_zero(iRegINoSp dst, immI0 src, iRegI op1, iRegI op2, cmpOpU cop) %{ + match(Set dst (CMoveI (Binary cop (CmpU op1 op2)) (Binary dst src))); + ins_cost(ALU_COST + BRANCH_COST); + + format %{ "CMoveI $dst, ($op1 $cop $op2), $dst, zr\t#@cmovI_cmpU_zero" %} + + ins_encode %{ + __ enc_cmove($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, + as_Register($op1$$reg), as_Register($op2$$reg), + as_Register($dst$$reg), zr); + %} + + ins_pipe(pipe_class_compare); +%} + +instruct cmovI_cmpN_zero(iRegINoSp dst, immI0 src, iRegN op1, iRegN op2, cmpOpU cop) %{ + match(Set dst (CMoveI (Binary cop (CmpN op1 op2)) (Binary dst src))); + ins_cost(ALU_COST + BRANCH_COST); + + format %{ "CMoveI $dst, ($op1 $cop $op2), $dst, zr\t#@cmovI_cmpN_zero" %} + + ins_encode %{ + __ enc_cmove($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, + as_Register($op1$$reg), as_Register($op2$$reg), + as_Register($dst$$reg), zr); + %} + + ins_pipe(pipe_class_compare); +%} + +instruct cmovI_cmpP_zero(iRegINoSp dst, immI0 src, iRegP op1, iRegP op2, cmpOpU cop) %{ + match(Set dst (CMoveI (Binary cop (CmpP op1 op2)) (Binary dst src))); + ins_cost(ALU_COST + BRANCH_COST); + + format %{ "CMoveI $dst, ($op1 $cop $op2), $dst, zr\t#@cmovI_cmpP_zero" %} + + ins_encode %{ + __ enc_cmove($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, + as_Register($op1$$reg), as_Register($op2$$reg), + as_Register($dst$$reg), zr); + %} + + ins_pipe(pipe_class_compare); +%} + // --------- CMoveL --------- instruct cmovL_cmpL(iRegLNoSp dst, iRegL src, iRegL op1, iRegL op2, cmpOp cop) %{ @@ -10502,6 +10569,38 @@ instruct cmovL_cmpP(iRegLNoSp dst, iRegL src, iRegP op1, iRegP op2, cmpOpU cop) ins_pipe(pipe_class_compare); %} +// CMoveL (signed compare) with zero as second operand +instruct cmovL_cmpL_zero(iRegLNoSp dst, immL0 src, iRegL op1, iRegL op2, cmpOp cop) %{ + match(Set dst (CMoveL (Binary cop (CmpL op1 op2)) (Binary dst src))); + ins_cost(ALU_COST + BRANCH_COST); + + format %{ "CMoveL $dst, ($op1 $cop $op2), $dst, zr\t#@cmovL_cmpL_zero" %} + + ins_encode %{ + __ enc_cmove($cop$$cmpcode, + as_Register($op1$$reg), as_Register($op2$$reg), + as_Register($dst$$reg), zr); + %} + + ins_pipe(pipe_class_compare); +%} + +// CMoveL (unsigned compare) with zero as second operand +instruct cmovL_cmpUL_zero(iRegLNoSp dst, immL0 src, iRegL op1, iRegL op2, cmpOpU cop) %{ + match(Set dst (CMoveL (Binary cop (CmpUL op1 op2)) (Binary dst src))); + ins_cost(ALU_COST + BRANCH_COST); + + format %{ "CMoveL $dst, ($op1 $cop $op2), $dst, zr\t#@cmovL_cmpUL_zero" %} + + ins_encode %{ + __ enc_cmove($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask, + as_Register($op1$$reg), as_Register($op2$$reg), + as_Register($dst$$reg), zr); + %} + + ins_pipe(pipe_class_compare); +%} + // --------- CMoveF --------- instruct cmovF_cmpI(fRegF dst, fRegF src, iRegI op1, iRegI op2, cmpOp cop) %{ diff --git a/src/hotspot/cpu/riscv/riscv_v.ad b/src/hotspot/cpu/riscv/riscv_v.ad index 2a63221de04d..7b3d40cc636c 100644 --- a/src/hotspot/cpu/riscv/riscv_v.ad +++ b/src/hotspot/cpu/riscv/riscv_v.ad @@ -5051,6 +5051,36 @@ instruct extractD(fRegD dst, vReg src, immI idx, vReg tmp) ins_pipe(pipe_slow); %} +instruct extractUB_index_imm(iRegINoSp dst, vReg src, immI idx, vReg tmp) +%{ + match(Set dst (ExtractUB src idx)); + effect(TEMP tmp); + format %{ "extractUB_index_imm $dst, $src, $idx\t# KILL $tmp" %} + ins_encode %{ + // Input "src" is a vector of boolean represented as + // bytes with 0x00/0x01 as element values. + // "idx" is expected to be in range. + __ extract_v($dst$$Register, as_VectorRegister($src$$reg), T_BOOLEAN, + (int)($idx$$constant), as_VectorRegister($tmp$$reg)); + %} + ins_pipe(pipe_slow); +%} + +instruct extractUB_index_reg(iRegINoSp dst, vReg src, iRegI idx, vReg tmp) +%{ + match(Set dst (ExtractUB src idx)); + effect(TEMP tmp); + format %{ "extractUB_index_reg $dst, $src, $idx\t# KILL $tmp" %} + ins_encode %{ + // Input "src" is a vector of boolean represented as + // bytes with 0x00/0x01 as element values. + // "idx" is expected to be in range. + __ extract_v($dst$$Register, as_VectorRegister($src$$reg), T_BOOLEAN, + $idx$$Register, as_VectorRegister($tmp$$reg)); + %} + ins_pipe(pipe_slow); +%} + // ------------------------------ Compress/Expand Operations ------------------- instruct mcompress(vRegMask dst, vRegMask src, vReg tmp) %{ diff --git a/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp b/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp index 06cf67e2486d..11ce5695b4d2 100644 --- a/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp +++ b/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp @@ -3065,6 +3065,130 @@ class StubGenerator: public StubCodeGenerator { return start; } + void gcm_counterMode_AESCrypt_blocks(int round, Register in, Register out, Register key, Register counter, + Register input_len, VectorRegister *working_vregs, Register blocks, + VectorRegister vtmp1, VectorRegister vtmp2, VectorRegister vtmp3) { + __ srli(blocks, input_len, 4); + + const unsigned int BLOCK_SIZE = 16; + const unsigned int MASK_VALUE = 0b1000; // we need {1, 0, 0, 0} mask value here + __ vsetivli(x0, 1, Assembler::e8, Assembler::m1); + __ vmv_v_i(v0, MASK_VALUE); + + __ vsetivli(x0, 4, Assembler::e32, Assembler::m1); + // load keys to working_vregs according to round + aes_load_keys(key, working_vregs, round); + + __ vle32_v(vtmp1, counter); + Label L_aes_ctr_loop; + __ bind(L_aes_ctr_loop); + __ vmv_v_v(vtmp2, vtmp1); + // encrypt counter according to round + aes_encrypt(vtmp2, working_vregs, round); + __ vle32_v(vtmp3, in); + __ vxor_vv(vtmp2, vtmp2, vtmp3); + __ vse32_v(vtmp2, out); + __ addi(out, out, BLOCK_SIZE); + __ addi(in, in, BLOCK_SIZE); + __ sub(blocks, blocks, 1); + __ vrev8_v(vtmp1, vtmp1, Assembler::VectorMask::v0_t); + __ vadd_vi(vtmp1, vtmp1, 0x1, Assembler::VectorMask::v0_t); + __ vrev8_v(vtmp1, vtmp1, Assembler::VectorMask::v0_t); + __ bnez(blocks, L_aes_ctr_loop); + + __ vse32_v(vtmp1, counter); + } + + void gcm_ghash_blocks(Register state, Register subkeyH, Register ct, Register input_len, Register blocks, + VectorRegister vtmp1, VectorRegister vtmp2, VectorRegister vtmp3) { + __ srli(blocks, input_len, 4); + + ghash_loop(state, subkeyH, ct, blocks, vtmp1, vtmp2, vtmp3); + + __ mv(x10, input_len); + __ leave(); + __ ret(); + } + + + // Vector AES Galois Counter Mode implementation. Parameters: + // + // in = c_rarg0 + // input_len = c_rarg1 + // ct = c_rarg2 - ciphertext that ghash will read (out for encrypt, in for decrypt) + // out = c_rarg3 + // key = c_rarg4 + // state = c_rarg5 - GHASH.state + // subkeyHtbl = c_rarg6 - powers of H + // counter = c_rarg7 - 16 bytes of CTR + // return - number of processed bytes + address generate_galoisCounterMode_AESCrypt() { + assert(UseGHASHIntrinsics, "need GHASH instructions (Zvkg extension) and Zvbb support"); + assert(UseAESCTRIntrinsics, "need AES instructions (Zvkned extension) and Zbb extension support"); + + __ align(CodeEntryAlignment); + StubId stub_id = StubId::stubgen_galoisCounterMode_AESCrypt_id; + StubCodeMark mark(this, stub_id); + + const Register in = c_rarg0; + const Register input_len = c_rarg1; + const Register ct = c_rarg2; + const Register out = c_rarg3; + const Register key = c_rarg4; + const Register state = c_rarg5; + const Register subkeyHtbl = c_rarg6; + const Register counter = c_rarg7; + + const Register keylen = x28; + const Register blocks = x29; + + VectorRegister working_vregs[] = { + v1, v2, v3, v4, v5, v6, v7, v8, + v9, v10, v11, v12, v13, v14, v15 + }; + + VectorRegister vtmp1 = v16; + VectorRegister vtmp2 = v17; + VectorRegister vtmp3 = v18; + + const address start = __ pc(); + __ enter(); + + Label L_exit; + // Requires input_len (512) bytes to efficiently use the intrinsic + __ andi(input_len, input_len, -512); + __ beqz(input_len, L_exit); + + Label L_aes128, L_aes192; + // Compute #rounds for AES based on the length of the key array + __ lwu(keylen, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT))); + __ mv(t0, 52); // key length could be only {11, 13, 15} * 4 = {44, 52, 60} + __ bltu(keylen, t0, L_aes128); + __ beq(keylen, t0, L_aes192); + // Else we fallthrough to the biggest case (256-bit key size) + + // Note: the following function performs crypt with key += 15*16 + gcm_counterMode_AESCrypt_blocks(15, in, out, key, counter, input_len, working_vregs, blocks, vtmp1, vtmp2, vtmp3); + gcm_ghash_blocks(state, subkeyHtbl, ct, input_len, blocks, vtmp1, vtmp2, vtmp3); + + // Note: the following function performs crypt with key += 13*16 + __ bind(L_aes192); + gcm_counterMode_AESCrypt_blocks(13, in, out, key, counter, input_len, working_vregs, blocks, vtmp1, vtmp2, vtmp3); + gcm_ghash_blocks(state, subkeyHtbl, ct, input_len, blocks, vtmp1, vtmp2, vtmp3); + + // Note: the following function performs crypt with key += 11*16 + __ bind(L_aes128); + gcm_counterMode_AESCrypt_blocks(11, in, out, key, counter, input_len, working_vregs, blocks, vtmp1, vtmp2, vtmp3); + gcm_ghash_blocks(state, subkeyHtbl, ct, input_len, blocks, vtmp1, vtmp2, vtmp3); + + __ bind(L_exit); + __ mv(x10, input_len); + __ leave(); + __ ret(); + + return start; + } + // code for comparing 8 characters of strings with Latin1 and Utf16 encoding void compare_string_8_x_LU(Register tmpL, Register tmpU, Register strL, Register strU, Label& DIFF) { @@ -7293,6 +7417,10 @@ static const int64_t right_3_bits = right_n_bits(3); StubRoutines::_ghash_processBlocks = generate_ghash_processBlocks(); } + if (UseAESCTRIntrinsics && UseGHASHIntrinsics) { + StubRoutines::_galoisCounterMode_AESCrypt = generate_galoisCounterMode_AESCrypt(); + } + if (UsePoly1305Intrinsics) { StubRoutines::_poly1305_processBlocks = generate_poly1305_processBlocks(); } diff --git a/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp b/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp index db3f2f6218fb..bb0d0602db4a 100644 --- a/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp @@ -31,6 +31,7 @@ #include "c1/c1_ValueStack.hpp" #include "ci/ciArrayKlass.hpp" #include "ci/ciInstance.hpp" +#include "gc/shared/barrierSetAssembler.hpp" #include "gc/shared/collectedHeap.hpp" #include "memory/universe.hpp" #include "nativeInst_s390.hpp" @@ -972,7 +973,6 @@ void LIR_Assembler::mem2reg(LIR_Opr src_opr, LIR_Opr dest, BasicType type, LIR_P } else { __ z_lg(dest->as_register(), disp_value, disp_reg, src); } - __ verify_oop(dest->as_register(), FILE_AND_LINE); break; } case T_FLOAT: @@ -1006,7 +1006,6 @@ void LIR_Assembler::stack2reg(LIR_Opr src, LIR_Opr dest, BasicType type) { if (dest->is_single_cpu()) { if (is_reference_type(type)) { __ mem2reg_opt(dest->as_register(), frame_map()->address_for_slot(src->single_stack_ix()), true); - __ verify_oop(dest->as_register(), FILE_AND_LINE); } else if (type == T_METADATA || type == T_ADDRESS) { __ mem2reg_opt(dest->as_register(), frame_map()->address_for_slot(src->single_stack_ix()), true); } else { @@ -1033,7 +1032,10 @@ void LIR_Assembler::reg2stack(LIR_Opr src, LIR_Opr dest, BasicType type) { if (src->is_single_cpu()) { const Address dst = frame_map()->address_for_slot(dest->single_stack_ix()); if (is_reference_type(type)) { - __ verify_oop(src->as_register(), FILE_AND_LINE); + if (VerifyOops) { + BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler(); + bs->check_oop(_masm, src->as_register(), FILE_AND_LINE); + } __ reg2mem_opt(src->as_register(), dst, true); } else if (type == T_METADATA || type == T_ADDRESS) { __ reg2mem_opt(src->as_register(), dst, true); @@ -1129,8 +1131,9 @@ void LIR_Assembler::reg2mem(LIR_Opr from, LIR_Opr dest_opr, BasicType type, assert(disp_reg != Z_R0 || Immediate::is_simm20(disp_value), "should have set this up"); - if (is_reference_type(type)) { - __ verify_oop(from->as_register(), FILE_AND_LINE); + if (is_reference_type(type) && VerifyOops) { + BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler(); + bs->check_oop(_masm, from->as_register(), FILE_AND_LINE); } bool short_disp = Immediate::is_uimm12(disp_value); diff --git a/src/hotspot/cpu/s390/compressedKlass_s390.cpp b/src/hotspot/cpu/s390/compressedKlass_s390.cpp index 06077b48f99a..1fa2c47ad21b 100644 --- a/src/hotspot/cpu/s390/compressedKlass_s390.cpp +++ b/src/hotspot/cpu/s390/compressedKlass_s390.cpp @@ -1,6 +1,7 @@ /* * Copyright (c) 2023, Red Hat, Inc. All rights reserved. - * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2026, IBM Corp. All rights reserved. + * Copyright (c) 2023, 2026, 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 @@ -24,14 +25,13 @@ */ #include "oops/compressedKlass.hpp" +#include "runtime/os.hpp" #include "utilities/globalDefinitions.hpp" char* CompressedKlassPointers::reserve_address_space_for_compressed_classes(size_t size, bool aslr, bool optimize_for_zero_base) { char* result = nullptr; - uintptr_t tried_below = 0; - // First, attempt to allocate < 4GB. We do this unconditionally: // - if optimize_for_zero_base, a <4GB mapping start allows us to use base=0 shift=0 // - if !optimize_for_zero_base, a <4GB mapping start allows us to use algfi @@ -44,7 +44,9 @@ char* CompressedKlassPointers::reserve_address_space_for_compressed_classes(size // Failing that, aim for a base that is 4G-aligned; such a base can be set with aih. if (result == nullptr) { - result = reserve_address_space_for_16bit_move(size, aslr); + constexpr uintptr_t from = nth_bit(32); + const uintptr_t to = os::vm_page_table_expansion_point(); // prevent accidentally expanding the page table + result = reserve_address_space_X(from, to, size, nth_bit(32), aslr); } return result; diff --git a/src/hotspot/cpu/s390/gc/shared/barrierSetAssembler_s390.cpp b/src/hotspot/cpu/s390/gc/shared/barrierSetAssembler_s390.cpp index d0f92cc129ac..b3ea74e18909 100644 --- a/src/hotspot/cpu/s390/gc/shared/barrierSetAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/gc/shared/barrierSetAssembler_s390.cpp @@ -197,6 +197,10 @@ void BarrierSetAssembler::nmethod_entry_barrier(MacroAssembler* masm) { __ block_comment("} nmethod_entry_barrier (nmethod_entry_barrier)"); } +void BarrierSetAssembler::check_oop(MacroAssembler* masm, Register oop, const char* msg) { + __ verify_oop(oop, msg); +} + #ifdef COMPILER2 OptoReg::Name BarrierSetAssembler::refine_register(const Node* node, OptoReg::Name opto_reg) const { diff --git a/src/hotspot/cpu/s390/gc/shared/barrierSetAssembler_s390.hpp b/src/hotspot/cpu/s390/gc/shared/barrierSetAssembler_s390.hpp index 6c729528a679..b9cb2e082b77 100644 --- a/src/hotspot/cpu/s390/gc/shared/barrierSetAssembler_s390.hpp +++ b/src/hotspot/cpu/s390/gc/shared/barrierSetAssembler_s390.hpp @@ -67,6 +67,8 @@ class BarrierSetAssembler: public CHeapObj { virtual void barrier_stubs_init() {} + virtual void check_oop(MacroAssembler* masm, Register oop, const char* msg); + #ifdef COMPILER2 OptoReg::Name refine_register(const Node* node, OptoReg::Name opto_reg) const; diff --git a/src/hotspot/cpu/s390/macroAssembler_s390.cpp b/src/hotspot/cpu/s390/macroAssembler_s390.cpp index 6eb144524016..a3a25e07197f 100644 --- a/src/hotspot/cpu/s390/macroAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/macroAssembler_s390.cpp @@ -6382,6 +6382,11 @@ void MacroAssembler::compiler_fast_lock_object(Register obj, Register box, Regis bind(inflated); const Register tmp1_monitor = tmp1; + // Offsets into the current thread's object monitor cache (omc). + const ByteSize thr_omc_offset = JavaThread::om_cache_offset(); + const ByteSize omc_monitor_offset = OMCache::monitor_offset(); + const ByteSize omc_obj_offset = OMCache::obj_offset(); + if (!UseObjectMonitorTable) { assert(tmp1_monitor == mark, "should be the same here"); } else { @@ -6392,17 +6397,11 @@ void MacroAssembler::compiler_fast_lock_object(Register obj, Register box, Regis // Save the mark, we might need it to extract the hash. z_lgr(hash, mark); - // Look for the monitor in the om_cache. + // Look for the monitor in the current thread's object monitor cache (omc). - ByteSize cache_offset = JavaThread::om_cache_oops_offset(); - ByteSize monitor_offset = OMCache::oop_to_monitor_difference(); - const int num_unrolled = OMCache::CAPACITY; - for (int i = 0; i < num_unrolled; i++) { - z_lg(tmp1_monitor, Address(Z_thread, cache_offset + monitor_offset)); - z_cg(obj, Address(Z_thread, cache_offset)); - z_bre(monitor_found); - cache_offset = cache_offset + OMCache::oop_to_oop_difference(); - } + z_lg(tmp1_monitor, Address(Z_thread, thr_omc_offset + omc_monitor_offset)); + z_cg(obj, Address(Z_thread, thr_omc_offset + omc_obj_offset)); + z_bre(monitor_found); // Get the hash code. z_srlg(hash, hash, markWord::hash_shift); @@ -6429,6 +6428,10 @@ void MacroAssembler::compiler_fast_lock_object(Register obj, Register box, Regis z_cgr(obj, tmp2); z_brne(slow_path); + // Store the monitor in the current thread's object monitor cache (omc). + z_stg(tmp1_monitor, Address(Z_thread, thr_omc_offset + omc_monitor_offset)); + z_stg(obj, Address(Z_thread, thr_omc_offset + omc_obj_offset)); + bind(monitor_found); } NearLabel monitor_locked; @@ -6458,7 +6461,7 @@ void MacroAssembler::compiler_fast_lock_object(Register obj, Register box, Regis bind(monitor_locked); if (UseObjectMonitorTable) { - // Cache the monitor for unlock + // Cache the monitor for unlock. z_stg(tmp1_monitor, Address(box, BasicLock::object_monitor_cache_offset_in_bytes())); } // set the CC now diff --git a/src/hotspot/cpu/s390/s390.ad b/src/hotspot/cpu/s390/s390.ad index 3d4abea75294..83898f3086ed 100644 --- a/src/hotspot/cpu/s390/s390.ad +++ b/src/hotspot/cpu/s390/s390.ad @@ -886,29 +886,59 @@ int MachNode::compute_padding(int current_offset) const { return 0; } -int MachCallStaticJavaNode::ret_addr_offset() { +int MachCallStaticJavaNode::ret_addr_offset() const { if (_method) { - return 8; + return MacroAssembler::call_far_pcrelative_size(); } else { return MacroAssembler::call_far_patchable_ret_addr_offset(); } } -int MachCallDynamicJavaNode::ret_addr_offset() { +int MachCallDynamicJavaNode::ret_addr_offset() const { // Consider size of receiver type profiling (C2 tiers). - int profile_receiver_type_size = 0; int vtable_index = this->_vtable_index; if (vtable_index == -4) { - return 14 + profile_receiver_type_size; + return MacroAssembler::load_const_from_toc_size() + + MacroAssembler::call_far_pcrelative_size(); } else { assert(!UseInlineCaches, "expect vtable calls only if not using ICs"); - return 36 + profile_receiver_type_size; + // This should return the size of instructions in vtable dispatch + // branch of z_enc_java_dynamic_call + int offset = 0; + + // __ load_klass(Z_method, Z_R2); + if (UseCompactObjectHeaders) { + // load_narrow_klass_compact (z_lg z_srlg) + offset += 6 // z_lg + + 6; // z_srlg; + } else { + offset += 6; // z_llgf + } + offset += MacroAssembler::instr_size_for_decode_klass_not_null(); + + // check if displacement is valid, as it will generate different + // instructions: + int entry_offset = in_bytes(Klass::vtable_start_offset()) + + vtable_index * vtableEntry::size_in_bytes(); + int v_off = entry_offset + in_bytes(vtableEntry::method_offset()); + if (!Displacement::is_validDisp(v_off)) { + offset += MacroAssembler::load_const_size(); // emits iihf + iilf + } + // both generate z_lg + offset += 6; // z_lg (z_method, v_off | Address(Z_method, Z_R1_scratch)) + // common footer + offset += 6; // z_lg(Z_R1_scratch, Method::from_compiled_offset()) + offset += 2; // z_basr + + return offset; } } -int MachCallRuntimeNode::ret_addr_offset() { - return 12 + MacroAssembler::call_far_patchable_ret_addr_offset(); +int MachCallRuntimeNode::ret_addr_offset() const { + return 6 // get_PC() (LARL) + + 6 // save_return_pc() (STG) + + MacroAssembler::call_far_patchable_ret_addr_offset(); } // Compute padding required for nodes which need alignment @@ -994,7 +1024,6 @@ static inline void z_assert_aligned(C2_MacroAssembler *masm, int disp, Register int emit_call_reloc(C2_MacroAssembler *masm, intptr_t entry_point, relocInfo::relocType rtype, PhaseRegAlloc* ra_, bool is_native_call = false) { __ set_inst_mark(); // Used in z_enc_java_static_call() and emit_java_to_interp(). - address old_mark = __ inst_mark(); unsigned int start_off = __ offset(); if (is_native_call) { @@ -1024,7 +1053,6 @@ int emit_call_reloc(C2_MacroAssembler *masm, intptr_t entry_point, relocInfo::re static int emit_call_reloc(C2_MacroAssembler *masm, intptr_t entry_point, RelocationHolder const& rspec) { __ set_inst_mark(); // Used in z_enc_java_static_call() and emit_java_to_interp(). - address old_mark = __ inst_mark(); unsigned int start_off = __ offset(); relocInfo::relocType rtype = rspec.type(); @@ -2344,8 +2372,7 @@ encode %{ // callee doesn't. unsigned int start_off = __ offset(); // Compute size of "larl + stg + call_c_opt". - const int size_of_code = 6 + 6 + MacroAssembler::call_far_patchable_size(); - __ get_PC(Z_R14, size_of_code); + __ get_PC(Z_R14, ret_addr_offset()); __ save_return_pc(); assert(__ offset() - start_off == 12, "bad prelude len: %d", __ offset() - start_off); @@ -2356,30 +2383,28 @@ encode %{ return; } -#ifdef ASSERT - // Plausibility check for size_of_code assumptions. - unsigned int actual_ret_off = __ offset(); - assert(start_off + size_of_code == actual_ret_off, "wrong return_pc"); -#endif + assert(__ offset() - start_off == (uint)ret_addr_offset(), + "z_enc_java_to_runtime_call return offset mismatch: emitted %d bytes, ret_addr_offset()=%d", + __ offset() - start_off, ret_addr_offset()); __ post_call_nop(); %} enc_class z_enc_java_static_call(method meth) %{ + unsigned int start_off = __ offset(); // Call to fixup routine. Fixup routine uses ScopeDesc info to determine // whom we intended to call. - int ret_offset = 0; if (!_method) { - ret_offset = emit_call_reloc(masm, $meth$$method, - relocInfo::runtime_call_w_cp_type, ra_); + emit_call_reloc(masm, $meth$$method, + relocInfo::runtime_call_w_cp_type, ra_); } else { int method_index = resolved_method_index(masm); if (_optimized_virtual) { - ret_offset = emit_call_reloc(masm, $meth$$method, - opt_virtual_call_Relocation::spec(method_index)); + emit_call_reloc(masm, $meth$$method, + opt_virtual_call_Relocation::spec(method_index)); } else { - ret_offset = emit_call_reloc(masm, $meth$$method, - static_call_Relocation::spec(method_index)); + emit_call_reloc(masm, $meth$$method, + static_call_Relocation::spec(method_index)); } } assert(__ inst_mark() != nullptr, "emit_call_reloc must set_inst_mark()"); @@ -2394,6 +2419,9 @@ encode %{ } __ clear_inst_mark(); + assert(__ offset() - start_off == (uint)ret_addr_offset(), + "z_enc_java_static_call return offset mismatch: emitted %d bytes, ret_addr_offset()=%d", + __ offset() - start_off, ret_addr_offset()); __ post_call_nop(); %} @@ -2418,9 +2446,8 @@ encode %{ // to determine who we intended to call. int method_index = resolved_method_index(masm); __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr, method_index)); - unsigned int ret_off = __ offset(); assert(__ offset() - start_off == 6, "bad prelude len: %d", __ offset() - start_off); - ret_off += emit_call_reloc(masm, $meth$$method, relocInfo::none, ra_); + emit_call_reloc(masm, $meth$$method, relocInfo::none, ra_); __ clear_inst_mark(); assert(_method, "lazy_constant may be wrong when _method==null"); } else { @@ -2449,8 +2476,11 @@ encode %{ __ z_lg(Z_R1_scratch, Address(Z_method, Method::from_compiled_offset())); // Call target. Either compiled code or C2I adapter. __ z_basr(Z_R14, Z_R1_scratch); - unsigned int ret_off = __ offset(); } + assert(__ offset() - start_off == (uint)ret_addr_offset(), + "z_enc_java_dynamic_call return offset mismatch: emitted %d bytes, ret_addr_offset()=%d", + __ offset() - start_off, ret_addr_offset()); + __ post_call_nop(); %} diff --git a/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp b/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp index 69308bb2a7e8..2e253ff142ce 100644 --- a/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp @@ -294,6 +294,10 @@ void C2_MacroAssembler::fast_lock(Register obj, Register box, Register rax_reg, bind(inflated); const Register monitor = t; + // Offsets into the current thread's object monitor cache (omc). + const ByteSize thr_omc_offset = JavaThread::om_cache_offset(); + const ByteSize omc_monitor_offset = OMCache::monitor_offset(); + const ByteSize omc_obj_offset = OMCache::obj_offset(); if (!UseObjectMonitorTable) { assert(mark == monitor, "should be the same here"); @@ -301,17 +305,11 @@ void C2_MacroAssembler::fast_lock(Register obj, Register box, Register rax_reg, const Register hash = t; Label monitor_found; - // Look for the monitor in the om_cache. + // Look for the monitor in the current thread's object monitor cache (omc). - ByteSize cache_offset = JavaThread::om_cache_oops_offset(); - ByteSize monitor_offset = OMCache::oop_to_monitor_difference(); - const int num_unrolled = OMCache::CAPACITY; - for (int i = 0; i < num_unrolled; i++) { - movptr(monitor, Address(thread, cache_offset + monitor_offset)); - cmpptr(obj, Address(thread, cache_offset)); - jccb(Assembler::equal, monitor_found); - cache_offset = cache_offset + OMCache::oop_to_oop_difference(); - } + movptr(monitor, Address(thread, thr_omc_offset + omc_monitor_offset)); + cmpptr(obj, Address(thread, thr_omc_offset + omc_obj_offset)); + jccb(Assembler::equal, monitor_found); // Look for the monitor in the table. @@ -340,6 +338,10 @@ void C2_MacroAssembler::fast_lock(Register obj, Register box, Register rax_reg, cmpptr(rax_reg, obj); jcc(Assembler::notEqual, slow_path); + // Store the monitor in the current thread's object monitor cache (omc). + movptr(Address(thread, thr_omc_offset + omc_monitor_offset), monitor); + movptr(Address(thread, thr_omc_offset + omc_obj_offset), obj); + bind(monitor_found); } const ByteSize monitor_tag = in_ByteSize(UseObjectMonitorTable ? 0 : checked_cast(markWord::monitor_value)); diff --git a/src/hotspot/cpu/x86/x86.ad b/src/hotspot/cpu/x86/x86.ad index 883fb0c6300b..a1bad907138f 100644 --- a/src/hotspot/cpu/x86/x86.ad +++ b/src/hotspot/cpu/x86/x86.ad @@ -1634,21 +1634,21 @@ static int clear_avx_size() { // !!!!! Special hack to get all types of calls to specify the byte offset // from the start of the call to the point where the return address // will point. -int MachCallStaticJavaNode::ret_addr_offset() +int MachCallStaticJavaNode::ret_addr_offset() const { int offset = 5; // 5 bytes from start of call to where return address points offset += clear_avx_size(); return offset; } -int MachCallDynamicJavaNode::ret_addr_offset() +int MachCallDynamicJavaNode::ret_addr_offset() const { int offset = 15; // 15 bytes from start of call to where return address points offset += clear_avx_size(); return offset; } -int MachCallRuntimeNode::ret_addr_offset() { +int MachCallRuntimeNode::ret_addr_offset() const { int offset = 13; // movq r10,#addr; callq (r10) if (this->ideal_Opcode() != Op_CallLeafVector) { offset += clear_avx_size(); @@ -2138,9 +2138,7 @@ uint MachSpillCopyNode::implementation(C2_MacroAssembler* masm, OptoReg::Name dst_second = ra_->get_reg_second(this); OptoReg::Name dst_first = ra_->get_reg_first(this); - enum RC src_second_rc = rc_class(src_second); enum RC src_first_rc = rc_class(src_first); - enum RC dst_second_rc = rc_class(dst_second); enum RC dst_first_rc = rc_class(dst_first); assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), diff --git a/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp b/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp index 749f6bec0325..4ad61e605fb1 100644 --- a/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp +++ b/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp @@ -477,3 +477,10 @@ int os::extra_bang_size_in_bytes() { } void os::setup_fpu() {} + +uintptr_t os::vm_page_table_expansion_point() { + // On s390x, page table will dynamically expand based on user demand + // (eg mmap probing with high addresses). First expansion happens + // at 2^42 (4TB). + return nth_bit(42); +} diff --git a/src/hotspot/os_cpu/windows_aarch64/vm_version_windows_aarch64.cpp b/src/hotspot/os_cpu/windows_aarch64/vm_version_windows_aarch64.cpp index e485ae6b8c27..9d7257ba297e 100644 --- a/src/hotspot/os_cpu/windows_aarch64/vm_version_windows_aarch64.cpp +++ b/src/hotspot/os_cpu/windows_aarch64/vm_version_windows_aarch64.cpp @@ -145,6 +145,20 @@ void VM_Version::get_os_cpu_info() { } { + DWORD key_type = 0; + uint64_t value = 0; + DWORD value_size = sizeof(value); + // Read registry value "CP 4000" which maps to MIDR_EL1. + if ((RegGetValueA(HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", "CP 4000", + RRF_RT_REG_QWORD, &key_type, &value, &value_size) == ERROR_SUCCESS) && (value_size == sizeof(value))) { + _cpu = value >> 24 & 0xFF; + _variant = value >> 20 & 0x0F; + _model = value >> 4 & 0x0FFF; + _revision = value & 0x0F; + } + } + + if (_cpu == 0) { char* buf = ::getenv("PROCESSOR_IDENTIFIER"); if (buf && strstr(buf, "Ampere(TM)") != nullptr) { _cpu = CPU_AMCC; diff --git a/src/hotspot/share/compiler/abstractDisassembler.cpp b/src/hotspot/share/compiler/abstractDisassembler.cpp index df7781e93d5d..5fecf2c866e5 100644 --- a/src/hotspot/share/compiler/abstractDisassembler.cpp +++ b/src/hotspot/share/compiler/abstractDisassembler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2026, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2019 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -345,9 +345,6 @@ void AbstractDisassembler::decode_range_abstract(address range_start, address ra // it respects the actual instruction length where possible. void AbstractDisassembler::decode_abstract(address start, address end, outputStream* ost, const int max_instr_size_in_bytes) { - int idx = 0; - address pos = start; - outputStream* st = (ost == nullptr) ? tty : ost; st->bol(); diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.cpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.cpp index 4dacd20d0c78..74b62003f86c 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.cpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.cpp @@ -290,9 +290,7 @@ void ShenandoahHeuristics::record_allocation_failure_gc() { } void ShenandoahHeuristics::record_requested_gc() { - // Assume users call System.gc() when external state changes significantly, - // which forces us to re-learn the GC timings and allocation rates. - _gc_times_learned = 0; + // Do nothing. } bool ShenandoahHeuristics::can_unload_classes() { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp b/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp index 3fefae58ef88..7549fe023168 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp @@ -306,22 +306,25 @@ void ShenandoahControlThread::service_concurrent_normal_cycle(GCCause::Cause cau } bool ShenandoahControlThread::check_cancellation_or_degen(ShenandoahGC::ShenandoahDegenPoint point) { + // Only read the cancellation cause once. Other threads may change it. ShenandoahHeap* heap = ShenandoahHeap::heap(); - if (heap->cancelled_gc()) { - if (heap->cancelled_cause() == GCCause::_shenandoah_stop_vm) { - return true; - } + const GCCause::Cause cancelled_cause = heap->cancelled_cause(); + if (cancelled_cause == GCCause::_no_gc) { + return false; + } - if (ShenandoahCollectorPolicy::is_allocation_failure(heap->cancelled_cause())) { - assert (_degen_point == ShenandoahGC::_degenerated_outside_cycle, - "Should not be set yet: %s", ShenandoahGC::degen_point_to_string(_degen_point)); - _degen_point = point; - return true; - } + if (cancelled_cause == GCCause::_shenandoah_stop_vm) { + return true; + } - fatal("Unexpected reason for cancellation: %s", GCCause::to_string(heap->cancelled_cause())); + if (ShenandoahCollectorPolicy::is_allocation_failure(cancelled_cause)) { + assert (_degen_point == ShenandoahGC::_degenerated_outside_cycle, + "Should not be set yet: %s", ShenandoahGC::degen_point_to_string(_degen_point)); + _degen_point = point; + return true; } - return false; + + fatal("Unexpected reason for cancellation: %s", GCCause::to_string(cancelled_cause)); } void ShenandoahControlThread::stop_service() { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahGenerationalControlThread.cpp b/src/hotspot/share/gc/shenandoah/shenandoahGenerationalControlThread.cpp index c01d82acbe24..5d2e58559eee 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahGenerationalControlThread.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahGenerationalControlThread.cpp @@ -576,11 +576,12 @@ void ShenandoahGenerationalControlThread::service_concurrent_cycle(ShenandoahGen } bool ShenandoahGenerationalControlThread::check_cancellation_or_degen(ShenandoahGC::ShenandoahDegenPoint point) { - if (!_heap->cancelled_gc()) { + // Only read the cancellation cause once. Other threads may change it. + const GCCause::Cause cancelled_cause = _heap->cancelled_cause(); + if (cancelled_cause == GCCause::_no_gc) { return false; } - const GCCause::Cause cancelled_cause = _heap->cancelled_cause(); if (cancelled_cause == GCCause::_shenandoah_stop_vm || cancelled_cause == GCCause::_shenandoah_concurrent_gc) { log_debug(gc, thread)("Cancellation detected, reason: %s", GCCause::to_string(cancelled_cause)); @@ -600,7 +601,6 @@ bool ShenandoahGenerationalControlThread::check_cancellation_or_degen(Shenandoah } fatal("Cancel GC either for alloc failure GC, or gracefully exiting, or to pause old generation marking"); - return false; } void ShenandoahGenerationalControlThread::service_stw_full_cycle(GCCause::Cause cause) { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahGenerationalFullGC.cpp b/src/hotspot/share/gc/shenandoah/shenandoahGenerationalFullGC.cpp index f2411702e35d..323453756838 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahGenerationalFullGC.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahGenerationalFullGC.cpp @@ -1,6 +1,6 @@ /* * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. - * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, 2026, 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 @@ -157,7 +157,9 @@ void ShenandoahGenerationalFullGC::compute_balances() { // Invoke this in case we are able to transfer memory from OLD to YOUNG size_t allocation_runway = heap->young_generation()->heuristics()->bytes_of_allocation_runway_before_gc_trigger(0L); - heap->compute_old_generation_balance(allocation_runway, 0, 0); + size_t max_transfer = MIN2(allocation_runway, + heap->young_generation()->free_unaffiliated_regions() * ShenandoahHeapRegion::region_size_bytes()); + heap->compute_old_generation_balance(max_transfer, 0, 0); } ShenandoahPrepareForGenerationalCompactionObjectClosure::ShenandoahPrepareForGenerationalCompactionObjectClosure(PreservedMarks* preserved_marks, diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp index 84add03f1bac..860988a2d7f9 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp @@ -448,7 +448,9 @@ jint ShenandoahHeap::initialize() { // gen_heap->young_generation()->heuristics()->bytes_of_allocation_runway_before_gc_trigger(young_cset_regions) // until after the heap is fully initialized. So we make up a safe value here. size_t allocation_runway = InitialHeapSize / 2; - gen_heap->compute_old_generation_balance(allocation_runway, old_trashed_regions, young_trashed_regions); + // We're initializing the heap. All regions within young are initially empty. + size_t max_transfer = allocation_runway; + gen_heap->compute_old_generation_balance(max_transfer, old_trashed_regions, young_trashed_regions); } _free_set->finish_rebuild(young_trashed_regions, old_trashed_regions, num_old); } @@ -2643,7 +2645,10 @@ void ShenandoahHeap::rebuild_free_set_within_phase() { ShenandoahGenerationalHeap* gen_heap = ShenandoahGenerationalHeap::heap(); size_t allocation_runway = gen_heap->young_generation()->heuristics()->bytes_of_allocation_runway_before_gc_trigger(young_trashed_regions); - gen_heap->compute_old_generation_balance(allocation_runway, old_trashed_regions, young_trashed_regions); + size_t max_transfer = MIN2(allocation_runway, + (gen_heap->young_generation()->free_unaffiliated_regions() + young_trashed_regions) * + ShenandoahHeapRegion::region_size_bytes()); + gen_heap->compute_old_generation_balance(max_transfer, old_trashed_regions, young_trashed_regions); } // Rebuild free set based on adjusted generation sizes. _free_set->finish_rebuild(young_trashed_regions, old_trashed_regions, old_region_count); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahOldGeneration.cpp b/src/hotspot/share/gc/shenandoah/shenandoahOldGeneration.cpp index c92f74364fbc..0f01795bb4ce 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahOldGeneration.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahOldGeneration.cpp @@ -1,7 +1,7 @@ /* * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. - * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, 2026, 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 @@ -491,7 +491,10 @@ void ShenandoahOldGeneration::prepare_regions_and_collection_set(bool concurrent ShenandoahGenerationalHeap* gen_heap = ShenandoahGenerationalHeap::heap(); size_t allocation_runway = gen_heap->young_generation()->heuristics()->bytes_of_allocation_runway_before_gc_trigger(young_trash_regions); - gen_heap->compute_old_generation_balance(allocation_runway, old_trash_regions, young_trash_regions); + size_t max_transfer = MIN2(allocation_runway, + (gen_heap->young_generation()->free_unaffiliated_regions() + young_trash_regions) * + ShenandoahHeapRegion::region_size_bytes()); + gen_heap->compute_old_generation_balance(max_transfer, old_trash_regions, young_trash_regions); heap->free_set()->finish_rebuild(young_trash_regions, old_trash_regions, num_old); } } diff --git a/src/hotspot/share/logging/logTag.hpp b/src/hotspot/share/logging/logTag.hpp index 0e31a371137d..6d49a23fe3b2 100644 --- a/src/hotspot/share/logging/logTag.hpp +++ b/src/hotspot/share/logging/logTag.hpp @@ -135,7 +135,6 @@ class outputStream; LOG_TAG(module) \ LOG_TAG(monitorinflation) \ LOG_TAG(monitormismatch) \ - LOG_TAG(monitortable) \ LOG_TAG(native) \ LOG_TAG(nestmates) \ LOG_TAG(nmethod) \ diff --git a/src/hotspot/share/memory/memoryReserver.cpp b/src/hotspot/share/memory/memoryReserver.cpp index 3bc9dc17f7d1..b6f151ead6c5 100644 --- a/src/hotspot/share/memory/memoryReserver.cpp +++ b/src/hotspot/share/memory/memoryReserver.cpp @@ -471,10 +471,13 @@ static char** get_attach_addresses_for_disjoint_mode() { } uint start = i; - // Avoid more steps than requested. + // Avoid more steps than requested, and avoid expanding the page table + // by over-eager probing. i = 0; while (addresses[start+i] != 0) { - if (i == HeapSearchSteps) { + if (i == HeapSearchSteps || + (addresses[start+i] >= os::vm_page_table_expansion_point())) + { addresses[start+i] = 0; break; } diff --git a/src/hotspot/share/oops/compressedKlass.cpp b/src/hotspot/share/oops/compressedKlass.cpp index 134f5a933658..4c79a858031a 100644 --- a/src/hotspot/share/oops/compressedKlass.cpp +++ b/src/hotspot/share/oops/compressedKlass.cpp @@ -241,12 +241,9 @@ void CompressedKlassPointers::initialize(address addr, size_t len) { // a cacheline size. _base = addr; + const int log2_len_to_cover = log2i_ceil(len); const int log_cacheline = exact_log2(DEFAULT_CACHE_LINE_SIZE); - int s = max_shift(); - while (s > log_cacheline && ((size_t)nth_bit(narrow_klass_pointer_bits() + s - 1) > len)) { - s--; - } - _shift = s; + _shift = MAX2(log_cacheline, log2_len_to_cover - narrow_klass_pointer_bits()); } else { diff --git a/src/hotspot/share/opto/compile.cpp b/src/hotspot/share/opto/compile.cpp index 93d8e4c425d5..81be5eede490 100644 --- a/src/hotspot/share/opto/compile.cpp +++ b/src/hotspot/share/opto/compile.cpp @@ -2950,7 +2950,7 @@ bool Compile::compute_logic_cone(Node* n, Unique_Node_List& partition, Unique_No Node* parent_pred = parent_is_predicated ? n->in(n->req()-1) : nullptr; Node* left_child_pred = left_child_predicated ? n->in(1)->in(n->in(1)->req()-1) : nullptr; - Node* right_child_pred = right_child_predicated ? n->in(1)->in(n->in(1)->req()-1) : nullptr; + Node* right_child_pred = right_child_predicated ? n->in(2)->in(n->in(2)->req()-1) : nullptr; do { if (pack_left_child && left_child_LOP && diff --git a/src/hotspot/share/opto/machnode.hpp b/src/hotspot/share/opto/machnode.hpp index 666fa2989bdb..ecca86ceae40 100644 --- a/src/hotspot/share/opto/machnode.hpp +++ b/src/hotspot/share/opto/machnode.hpp @@ -937,7 +937,7 @@ class MachCallNode : public MachSafePointNode { virtual bool pinned() const { return false; } virtual const Type* Value(PhaseGVN* phase) const; virtual const RegMask &in_RegMask(uint) const; - virtual int ret_addr_offset() { return 0; } + virtual int ret_addr_offset() const { return 0; } NOT_LP64(bool return_value_is_used() const;) @@ -998,7 +998,7 @@ class MachCallStaticJavaNode : public MachCallJavaNode { // If this is an uncommon trap, return the request code, else zero. int uncommon_trap_request() const; - virtual int ret_addr_offset(); + virtual int ret_addr_offset() const; #ifndef PRODUCT virtual void dump_spec(outputStream *st) const; void dump_trap_args(outputStream *st) const; @@ -1014,7 +1014,7 @@ class MachCallDynamicJavaNode : public MachCallJavaNode { init_class_id(Class_MachCallDynamicJava); DEBUG_ONLY(_vtable_index = -99); // throw an assert if uninitialized } - virtual int ret_addr_offset(); + virtual int ret_addr_offset() const; #ifndef PRODUCT virtual void dump_spec(outputStream *st) const; #endif @@ -1032,7 +1032,7 @@ class MachCallRuntimeNode : public MachCallNode { MachCallRuntimeNode() : MachCallNode() { init_class_id(Class_MachCallRuntime); } - virtual int ret_addr_offset(); + virtual int ret_addr_offset() const; #ifndef PRODUCT virtual void dump_spec(outputStream *st) const; #endif diff --git a/src/hotspot/share/opto/movenode.cpp b/src/hotspot/share/opto/movenode.cpp index 6b6becb434f0..28cc47077677 100644 --- a/src/hotspot/share/opto/movenode.cpp +++ b/src/hotspot/share/opto/movenode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -73,7 +73,7 @@ //------------------------------Ideal------------------------------------------ // Return a node which is more "ideal" than the current node. -// Move constants to the right. +// Move constants to the true-case input. Node *CMoveNode::Ideal(PhaseGVN *phase, bool can_reshape) { if (in(0) != nullptr && remove_dead_region(phase, can_reshape)) { return this; @@ -95,14 +95,14 @@ Node *CMoveNode::Ideal(PhaseGVN *phase, bool can_reshape) { return progress; } - // Check for Min/Max patterns. This is called before constants are pushed to the right input, as that transform can + // Check for Min/Max patterns. This is called before constants are pushed to the true-case input, as that transform can // make BoolTests non-canonical. Node* minmax = Ideal_minmax(phase, this); if (minmax != nullptr) { return minmax; } - // Canonicalize the node by moving constants to the right input. + // Canonicalize the node by moving constants to the true-case input. if (in(Condition)->is_Bool() && phase->type(in(IfFalse))->singleton() && !phase->type(in(IfTrue))->singleton()) { BoolNode* b = in(Condition)->as_Bool()->negate(phase); return make(phase->transform(b), in(IfTrue), in(IfFalse), _type); @@ -142,10 +142,10 @@ Node* CMoveNode::Identity(PhaseGVN* phase) { return in(IfFalse); // Then it doesn't matter } if (phase->type(in(Condition)) == TypeInt::ZERO) { - return in(IfFalse); // Always pick left(false) input + return in(IfFalse); // Always pick false value input } if (phase->type(in(Condition)) == TypeInt::ONE) { - return in(IfTrue); // Always pick right(true) input + return in(IfTrue); // Always pick true value input } // Check for CMove'ing a constant after comparing against the constant. @@ -176,10 +176,10 @@ const Type* CMoveNode::Value(PhaseGVN* phase) const { return Type::TOP; } if (phase->type(in(Condition)) == TypeInt::ZERO) { - return phase->type(in(IfFalse))->filter(_type); // Always pick left (false) input + return phase->type(in(IfFalse))->filter(_type); // Always pick false value input } if (phase->type(in(Condition)) == TypeInt::ONE) { - return phase->type(in(IfTrue))->filter(_type); // Always pick right (true) input + return phase->type(in(IfTrue))->filter(_type); // Always pick true value input } const Type* t = phase->type(in(IfFalse))->meet_speculative(phase->type(in(IfTrue))); @@ -189,15 +189,15 @@ const Type* CMoveNode::Value(PhaseGVN* phase) const { //------------------------------make------------------------------------------- // Make a correctly-flavored CMove. Since _type is directly determined // from the inputs we do not need to specify it here. -CMoveNode* CMoveNode::make(Node* bol, Node* left, Node* right, const Type* t) { +CMoveNode* CMoveNode::make(Node* bol, Node* false_value, Node* true_value, const Type* t) { switch (t->basic_type()) { - case T_INT: return new CMoveINode(bol, left, right, t->is_int()); - case T_FLOAT: return new CMoveFNode(bol, left, right, t); - case T_DOUBLE: return new CMoveDNode(bol, left, right, t); - case T_LONG: return new CMoveLNode(bol, left, right, t->is_long()); - case T_OBJECT: return new CMovePNode(bol, left, right, t->is_oopptr()); - case T_ADDRESS: return new CMovePNode(bol, left, right, t->is_ptr()); - case T_NARROWOOP: return new CMoveNNode(bol, left, right, t); + case T_INT: return new CMoveINode(bol, false_value, true_value, t->is_int()); + case T_FLOAT: return new CMoveFNode(bol, false_value, true_value, t); + case T_DOUBLE: return new CMoveDNode(bol, false_value, true_value, t); + case T_LONG: return new CMoveLNode(bol, false_value, true_value, t->is_long()); + case T_OBJECT: return new CMovePNode(bol, false_value, true_value, t->is_oopptr()); + case T_ADDRESS: return new CMovePNode(bol, false_value, true_value, t->is_ptr()); + case T_NARROWOOP: return new CMoveNNode(bol, false_value, true_value, t); default: ShouldNotReachHere(); return nullptr; @@ -286,9 +286,9 @@ Node *CMoveINode::Ideal(PhaseGVN *phase, bool can_reshape) { Node *x = CMoveNode::Ideal(phase, can_reshape); if( x ) return x; - // If zero is on the left (false-case, no-move-case) it must mean another - // constant is on the right (otherwise the shared CMove::Ideal code would - // have moved the constant to the right). This situation is bad for x86 because + // If zero is the false-case (no-move-case) it must mean another + // constant is on the true-case input (otherwise the shared CMove::Ideal code would + // have moved the constant to the true-case input). This situation is bad for x86 because // the zero has to be manifested in a register with a XOR which kills flags, // which are live on input to the CMoveI, leading to a situation which causes // excessive spilling. See bug 4677505. diff --git a/src/hotspot/share/opto/movenode.hpp b/src/hotspot/share/opto/movenode.hpp index 92c59b6f6b1d..e17b1ed33cce 100644 --- a/src/hotspot/share/opto/movenode.hpp +++ b/src/hotspot/share/opto/movenode.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, 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 @@ -30,24 +30,23 @@ //------------------------------CMoveNode-------------------------------------- // Conditional move class CMoveNode : public TypeNode { - public: + public: enum { Control, // When is it safe to do this cmove? Condition, // Condition controlling the cmove IfFalse, // Value if condition is false IfTrue }; // Value if condition is true - CMoveNode( Node *bol, Node *left, Node *right, const Type *t ) : TypeNode(t,4) - { + CMoveNode(Node* bol, Node* false_value, Node* true_value, const Type* t) : TypeNode(t, 4) { init_class_id(Class_CMove); // all inputs are nullified in Node::Node(int) // init_req(Control,nullptr); - init_req(Condition,bol); - init_req(IfFalse,left); - init_req(IfTrue,right); + init_req(Condition, bol); + init_req(IfFalse, false_value); + init_req(IfTrue, true_value); } - virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); - virtual const Type* Value(PhaseGVN* phase) const; - virtual Node* Identity(PhaseGVN* phase); - static CMoveNode* make(Node* bol, Node* left, Node* right, const Type* t); + Node* Ideal(PhaseGVN *phase, bool can_reshape) override; + const Type* Value(PhaseGVN* phase) const override; + Node* Identity(PhaseGVN* phase) override; + static CMoveNode* make(Node* bol, Node* false_value, Node* true_value, const Type* t); static bool supported(const Type* t); // Helper function to spot cmove graph shapes static Node* is_cmove_id(PhaseTransform* phase, Node* cmp, Node* t, Node* f, BoolNode* b); @@ -56,47 +55,47 @@ class CMoveNode : public TypeNode { //------------------------------CMoveDNode------------------------------------- class CMoveDNode : public CMoveNode { - public: - CMoveDNode( Node *bol, Node *left, Node *right, const Type* t) : CMoveNode(bol,left,right,t){} - virtual int Opcode() const; - virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); + public: + CMoveDNode(Node* bol, Node* false_value, Node* true_value, const Type* t) : CMoveNode(bol, false_value, true_value, t) {} + int Opcode() const override; + Node* Ideal(PhaseGVN *phase, bool can_reshape) override; }; //------------------------------CMoveFNode------------------------------------- class CMoveFNode : public CMoveNode { - public: - CMoveFNode( Node *bol, Node *left, Node *right, const Type* t ) : CMoveNode(bol,left,right,t) {} - virtual int Opcode() const; - virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); + public: + CMoveFNode(Node* bol, Node* false_value, Node* true_value, const Type* t) : CMoveNode(bol, false_value, true_value, t) {} + int Opcode() const override; + Node* Ideal(PhaseGVN *phase, bool can_reshape) override; }; //------------------------------CMoveINode------------------------------------- class CMoveINode : public CMoveNode { - public: - CMoveINode( Node *bol, Node *left, Node *right, const TypeInt *ti ) : CMoveNode(bol,left,right,ti){} - virtual int Opcode() const; - virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); + public: + CMoveINode(Node* bol, Node* false_value, Node* true_value, const TypeInt* ti) : CMoveNode(bol, false_value, true_value, ti) {} + int Opcode() const override; + Node *Ideal(PhaseGVN *phase, bool can_reshape) override; }; //------------------------------CMoveLNode------------------------------------- class CMoveLNode : public CMoveNode { - public: - CMoveLNode(Node *bol, Node *left, Node *right, const TypeLong *tl ) : CMoveNode(bol,left,right,tl){} - virtual int Opcode() const; + public: + CMoveLNode(Node* bol, Node* false_value, Node* true_value, const TypeLong* tl) : CMoveNode(bol, false_value, true_value, tl) {} + int Opcode() const override; }; //------------------------------CMovePNode------------------------------------- class CMovePNode : public CMoveNode { - public: - CMovePNode(Node* bol, Node* left, Node* right, const TypePtr* t) : CMoveNode(bol, left, right, t) {} - virtual int Opcode() const; + public: + CMovePNode(Node* bol, Node* false_value, Node* true_value, const TypePtr* t) : CMoveNode(bol, false_value, true_value, t) {} + int Opcode() const override; }; //------------------------------CMoveNNode------------------------------------- class CMoveNNode : public CMoveNode { - public: - CMoveNNode(Node* bol, Node* left, Node* right, const Type* t ) : CMoveNode(bol, left, right, t) {} - virtual int Opcode() const; + public: + CMoveNNode(Node* bol, Node* false_value, Node* true_value, const Type* t) : CMoveNode(bol, false_value, true_value, t) {} + int Opcode() const override; }; // diff --git a/src/hotspot/share/opto/regalloc.cpp b/src/hotspot/share/opto/regalloc.cpp index 644296715f57..b05a2f3cc6bc 100644 --- a/src/hotspot/share/opto/regalloc.cpp +++ b/src/hotspot/share/opto/regalloc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2026, 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 @@ -79,7 +79,7 @@ int PhaseRegAlloc::reg2offset( OptoReg::Name reg ) const { reg < _matcher._in_arg_limit) || reg >= OptoReg::add(_matcher._new_SP, C->out_preserve_stack_slots()) || // Allow return_addr in the out-preserve area. - reg == _matcher.return_addr(), + reg == _matcher.return_addr() LP64_ONLY(|| OptoReg::add(reg, -1) == _matcher.return_addr()), "register allocated in a preserve area" ); return reg2offset_unchecked( reg ); } diff --git a/src/hotspot/share/opto/regmask.hpp b/src/hotspot/share/opto/regmask.hpp index 99b10c1c557e..4ba891bcb5ae 100644 --- a/src/hotspot/share/opto/regmask.hpp +++ b/src/hotspot/share/opto/regmask.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2026, 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 @@ -793,8 +793,6 @@ class RegMask { int rm_index_diff = _offset - rm._offset; int rm_hwm_tr = (int)rm._hwm - rm_index_diff; int rm_lwm_tr = (int)rm._lwm - rm_index_diff; - int rm_rm_max_tr = (int)rm.rm_word_max_index() - rm_index_diff; - int rm_rm_size_tr = (int)rm._rm_size_in_words - rm_index_diff; int hwm = MIN2((int)_hwm, rm_hwm_tr); int lwm = MAX2((int)_lwm, rm_lwm_tr); for (int i = lwm; i <= hwm; i++) { diff --git a/src/hotspot/share/prims/jvmtiEventController.cpp b/src/hotspot/share/prims/jvmtiEventController.cpp index a0cec5ddc0e7..69b39828902e 100644 --- a/src/hotspot/share/prims/jvmtiEventController.cpp +++ b/src/hotspot/share/prims/jvmtiEventController.cpp @@ -34,6 +34,7 @@ #include "prims/jvmtiThreadState.inline.hpp" #include "runtime/deoptimization.hpp" #include "runtime/frame.inline.hpp" +#include "runtime/interfaceSupport.inline.hpp" #include "runtime/javaThread.inline.hpp" #include "runtime/stackFrameStream.inline.hpp" #include "runtime/threads.hpp" @@ -1245,6 +1246,9 @@ JvmtiEventController::vm_death() { // callbacks are complete. The count could rise again, but those "callbacks" // will immediately see `execution_finished()` and return (dropping the count). while (in_callback_count() > 0) { + // Ensure we are safepoint-safe else we may prevent progress of an active + // callback until the maximum wait time has passed. + ThreadBlockInVM tbivm(JavaThread::current()); os::naked_short_sleep(100); if (os::elapsedTime() - start > max_wait_time) { break; diff --git a/src/hotspot/share/runtime/continuationFreezeThaw.cpp b/src/hotspot/share/runtime/continuationFreezeThaw.cpp index e9b6325d03ba..89c4d1f1bd5c 100644 --- a/src/hotspot/share/runtime/continuationFreezeThaw.cpp +++ b/src/hotspot/share/runtime/continuationFreezeThaw.cpp @@ -2636,7 +2636,7 @@ void ThawBase::clear_bitmap_bits(address start, address end) { intptr_t* ThawBase::handle_preempted_continuation(intptr_t* sp, Continuation::preempt_kind preempt_kind, bool fast_case) { frame top(sp); - assert(top.pc() == *(address*)(sp - frame::sender_sp_ret_address_offset()), ""); + assert(top.pc() == ContinuationHelper::return_address_at(sp - frame::sender_sp_ret_address_offset()), ""); DEBUG_ONLY(verify_frame_kind(top, preempt_kind);) NOT_PRODUCT(int64_t tid = _thread->monitor_owner_id();) @@ -3246,8 +3246,6 @@ static void log_frames(JavaThread* thread) { static void log_frames_after_thaw(JavaThread* thread, ContinuationWrapper& cont, intptr_t* sp) { intptr_t* sp0 = sp; - address pc0 = *(address*)(sp - frame::sender_sp_ret_address_offset()); - bool preempted = false; stackChunkOop tail = cont.tail(); if (tail != nullptr && tail->preempted()) { diff --git a/src/hotspot/share/runtime/javaThread.hpp b/src/hotspot/share/runtime/javaThread.hpp index cd757ed8ec12..13e079f1be59 100644 --- a/src/hotspot/share/runtime/javaThread.hpp +++ b/src/hotspot/share/runtime/javaThread.hpp @@ -1238,7 +1238,6 @@ class JavaThread: public Thread { static ByteSize lock_stack_base_offset() { return lock_stack_offset() + LockStack::base_offset(); } static ByteSize om_cache_offset() { return byte_offset_of(JavaThread, _om_cache); } - static ByteSize om_cache_oops_offset() { return om_cache_offset() + OMCache::entries_offset(); } void om_set_monitor_cache(ObjectMonitor* monitor); void om_clear_monitor_cache(); diff --git a/src/hotspot/share/runtime/lockStack.cpp b/src/hotspot/share/runtime/lockStack.cpp index 58b9c58a3295..a0f20b4fd315 100644 --- a/src/hotspot/share/runtime/lockStack.cpp +++ b/src/hotspot/share/runtime/lockStack.cpp @@ -115,7 +115,6 @@ void LockStack::print_on(outputStream* st) { } } -OMCache::OMCache(JavaThread* jt) : _entries() { +OMCache::OMCache(JavaThread* jt) { STATIC_ASSERT(std::is_standard_layout::value); - STATIC_ASSERT(std::is_standard_layout::value); } diff --git a/src/hotspot/share/runtime/lockStack.hpp b/src/hotspot/share/runtime/lockStack.hpp index 8d7e3644efac..cc76005cf4c4 100644 --- a/src/hotspot/share/runtime/lockStack.hpp +++ b/src/hotspot/share/runtime/lockStack.hpp @@ -130,19 +130,14 @@ class LockStack { class OMCache { friend class VMStructs; - public: - static constexpr int CAPACITY = 2; private: - struct OMCacheEntry { - oop _oop = nullptr; - ObjectMonitor* _monitor = nullptr; - } _entries[CAPACITY]; + oop _obj = nullptr; + ObjectMonitor* _monitor = nullptr; public: - static ByteSize entries_offset() { return byte_offset_of(OMCache, _entries); } - static constexpr ByteSize oop_to_oop_difference() { return in_ByteSize(sizeof(OMCacheEntry)); } - static constexpr ByteSize oop_to_monitor_difference() { return in_ByteSize(sizeof(oop)); } + static constexpr ByteSize obj_offset() { return byte_offset_of(OMCache, _obj); } + static constexpr ByteSize monitor_offset() { return byte_offset_of(OMCache, _monitor); } explicit OMCache(JavaThread* jt); diff --git a/src/hotspot/share/runtime/lockStack.inline.hpp b/src/hotspot/share/runtime/lockStack.inline.hpp index a9ad3553db8f..cb5c4de90b5e 100644 --- a/src/hotspot/share/runtime/lockStack.inline.hpp +++ b/src/hotspot/share/runtime/lockStack.inline.hpp @@ -250,53 +250,30 @@ inline void LockStack::oops_do(OopClosure* cl) { } inline void OMCache::set_monitor(ObjectMonitor *monitor) { - const int end = OMCache::CAPACITY - 1; - oop obj = monitor->object_peek(); assert(obj != nullptr, "must be alive"); assert(monitor == ObjectSynchronizer::get_monitor_from_table(obj), "must exist in table"); - OMCacheEntry to_insert = {obj, monitor}; - - for (int i = 0; i < end; ++i) { - if (_entries[i]._oop == obj || - _entries[i]._monitor == nullptr || - _entries[i]._monitor->is_being_async_deflated()) { - // Use stale slot. - _entries[i] = to_insert; - return; - } - // Swap with the most recent value. - ::swap(to_insert, _entries[i]); - } - _entries[end] = to_insert; + _monitor = monitor; + _obj = obj; } inline ObjectMonitor* OMCache::get_monitor(oop o) { - for (int i = 0; i < CAPACITY; ++i) { - if (_entries[i]._oop == o) { - assert(_entries[i]._monitor != nullptr, "monitor must exist"); - if (_entries[i]._monitor->is_being_async_deflated()) { - // Bad monitor - // Shift down rest - for (; i < CAPACITY - 1; ++i) { - _entries[i] = _entries[i + 1]; - } - // Clear end - _entries[i] = {}; - return nullptr; - } - return _entries[i]._monitor; + if (_obj == o) { + assert(_monitor != nullptr, "monitor must exist"); + if (!_monitor->is_being_async_deflated()) { + return _monitor; } + // Bad monitor, so clear the cache. + _obj = nullptr; + _monitor = nullptr; } return nullptr; } inline void OMCache::clear() { - for (size_t i = 0; i < CAPACITY; ++i) { - // Clear - _entries[i] = {}; - } + _obj = nullptr; + _monitor = nullptr; } #endif // SHARE_RUNTIME_LOCKSTACK_INLINE_HPP diff --git a/src/hotspot/share/runtime/os.cpp b/src/hotspot/share/runtime/os.cpp index ae786bd86c5a..e3437a097efc 100644 --- a/src/hotspot/share/runtime/os.cpp +++ b/src/hotspot/share/runtime/os.cpp @@ -1994,6 +1994,13 @@ static void shuffle_fisher_yates(T* arr, unsigned num, FastRandom& frand) { } } +#ifndef S390 +// Default implementation: page table never expands. +uintptr_t os::vm_page_table_expansion_point() { + return align_down(UINTPTR_MAX, os::vm_allocation_granularity()); +} +#endif + // Helper for os::attempt_reserve_memory_between // Given an array of things, do a hemisphere split such that the resulting // order is: [first, last, first + 1, last - 1, ...] diff --git a/src/hotspot/share/runtime/os.hpp b/src/hotspot/share/runtime/os.hpp index 50e087dcc94c..452a7e05d948 100644 --- a/src/hotspot/share/runtime/os.hpp +++ b/src/hotspot/share/runtime/os.hpp @@ -503,6 +503,11 @@ class os: AllStatic { // Returns the lowest address the process is allowed to map against. static size_t vm_min_address(); + // Some kernels (e.g. s390x) can dynamically expand the page table. This function returns + // the lowest user space address that will expand the page table for the first time. + // We typically want to avoid expanding the page table unless it is really necessary. + static uintptr_t vm_page_table_expansion_point(); + // Returns an upper limit beyond which reserve_memory() calls are guaranteed // to fail. It is not guaranteed that reserving less memory than this will // succeed, however. diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/package-info.java b/src/java.base/share/classes/java/lang/classfile/attribute/package-info.java index 43bf1984a00a..2525b8c6bc39 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/package-info.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/package-info.java @@ -61,7 +61,7 @@ *

Writing Attributes

* Most attributes implement at least one of {@link ClassElement}, {@link FieldElement}, {@link MethodElement}, or * {@link CodeElement}, so they can be sent to the respective {@link ClassFileBuilder} to be written as part of those - * structure. Attributes define if they can {@linkplain AttributeMapper#allowMultiple() appear multiple times} in one + * structures. Attributes define if they can {@linkplain AttributeMapper#allowMultiple() appear multiple times} in one * structure; if they cannot, the last attribute instance supplied to the builder is the one written to the final * structure. Some attributes, such as {@link BootstrapMethodsAttribute}, implement none of those interfaces. They are * created through other means, specified in the modeling interface for each of the attributes. Attributes for a {@link @@ -69,7 +69,7 @@ *

* The attribute factories generally have two sets of factory methods: one that accepts symbolic information * representing the uses, and another that accepts constant pool entries. Most of time, the symbolic factories are - * sufficent, but the constant pool entry ones can be used for fine-grained control over {@code class} file generation; + * sufficient, but the constant pool entry ones can be used for fine-grained control over {@code class} file generation; * see "{@linkplain java.lang.classfile.constantpool##writing Writing the constant pool entries}" for more details. *

* Many attributes can be bulk-copied if the data it depends on does not change; this information is exposed in {@link diff --git a/src/java.base/share/classes/java/text/DecimalFormat.java b/src/java.base/share/classes/java/text/DecimalFormat.java index c803a97ad864..7d8297f42bc2 100644 --- a/src/java.base/share/classes/java/text/DecimalFormat.java +++ b/src/java.base/share/classes/java/text/DecimalFormat.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2026, 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 @@ -250,7 +250,7 @@ * {@link DecimalFormatSymbols#getExponentSeparator()} * Number * Separates mantissa and exponent in scientific notation. This value - * is case sensistive. Need not be quoted in prefix or suffix. + * is case sensitive. Need not be quoted in prefix or suffix. * * {@code ;} * {@link DecimalFormatSymbols#getPatternSeparator()} @@ -2059,8 +2059,7 @@ void subformatNumber(StringBuf result, FieldDelegate delegate, // Output grouping separator if necessary. Don't output a // grouping separator if i==0 though; that's at the end of // the integer part. - if (isGroupingUsed() && i>0 && (groupingSize != 0) && - (i % groupingSize == 0)) { + if (isGroupingEnabled() && i > 0 && i % groupingSize == 0) { int gStart = result.length(); result.append(grouping); delegate.formatted(Field.GROUPING_SEPARATOR, @@ -2242,8 +2241,14 @@ private void append(StringBuf result, String string, public Number parse(String text, ParsePosition pos) { // special case NaN if (text.regionMatches(pos.index, symbols.getNaN(), 0, symbols.getNaN().length())) { - pos.index = pos.index + symbols.getNaN().length(); - return Double.valueOf(Double.NaN); + var nanEnd = pos.index + symbols.getNaN().length(); + // When strict, parsing NaN must be exact + if (parseStrict && nanEnd != text.length()) { + pos.errorIndex = nanEnd; + return null; + } + pos.index = nanEnd; + return Double.NaN; } boolean[] status = new boolean[STATUS_LENGTH]; @@ -2568,7 +2573,8 @@ NumericPosition subparseNumber(String text, int position, } // Enforce the grouping size on the first group - if (parseStrict && isGroupingUsed() && position == startPos + groupingSize + if (parseStrict && isGroupingEnabled() + && position == startPos + groupingSize && prevSeparatorIndex == -groupingSize && !sawDecimal && digit >= 0 && digit <= 9) { return new NumericPosition(position, intIndex); @@ -2612,7 +2618,8 @@ NumericPosition subparseNumber(String text, int position, return new NumericPosition(-1, intIndex); } // Check grouping size on decimal separator - if (parseStrict && isGroupingViolation(position, prevSeparatorIndex)) { + if (parseStrict && isGroupingEnabled() + && isGroupingViolation(position, prevSeparatorIndex)) { return new NumericPosition( groupingViolationIndex(position, prevSeparatorIndex), intIndex); } @@ -2624,7 +2631,8 @@ NumericPosition subparseNumber(String text, int position, intIndex = position; digits.decimalAt = digitCount; // Not digits.count! sawDecimal = true; - } else if (!isExponent && ch == grouping && isGroupingUsed()) { + } else if (!isExponent && ch == grouping && + (parseStrict ? isGroupingEnabled() : isGroupingUsed())) { if (parseStrict) { // text should not start with grouping when strict if (position == startPos) { @@ -2679,10 +2687,11 @@ NumericPosition subparseNumber(String text, int position, // (When strict), within the loop we enforce grouping when encountering // decimal/grouping symbols. Once outside loop, we need to check // the final grouping, ex: "1,234". Only check the final grouping - // if we have not seen a decimal separator, to prevent a non needed check, - // for ex: "1,234.", "1,234.12" + // if we have not seen a decimal separator, to prevent a grouping check in the + // fraction portion for ex: "1,234.", "1,234.12" if (parseStrict) { - if (!sawDecimal && isGroupingViolation(position, prevSeparatorIndex)) { + if (!sawDecimal && isGroupingEnabled() + && isGroupingViolation(position, prevSeparatorIndex)) { // -1, since position is incremented by one too many when loop is finished // "1,234%" and "1,234" both end with pos = 5, since '%' breaks // the loop before incrementing position. In both cases, check @@ -2743,12 +2752,23 @@ private int shiftDecimalAt(int decimalAt, long exponent) { return decimalAt; } + /* + * DecimalFormat defines both setGroupingUsed(boolean) and setGroupingSize(int). + * These operate independently, and setting a grouping size of 0 does not mean that + * isGroupingUsed() returns false. As a result, to effectively check whether grouping is used + * for strict parsing, both values need to be verified. Lenient parsing, which preserves the + * legacy parsing behavior, does not require this exhaustive check because grouping size positioning + * is not checked. + */ + private boolean isGroupingEnabled() { + return isGroupingUsed() && groupingSize > 0; + } + // Checks to make sure grouping size is not violated. Used when strict. private boolean isGroupingViolation(int pos, int prevGroupingPos) { assert parseStrict : "Grouping violations should only occur when strict"; - return isGroupingUsed() && // Only violates if using grouping - // Checks if a previous grouping symbol was seen. - prevGroupingPos != -groupingSize && + // Checks if a previous grouping symbol was seen. + return prevGroupingPos != -groupingSize && // The check itself, - 1 to account for grouping/decimal symbol pos - 1 != prevGroupingPos + groupingSize; } @@ -3586,7 +3606,7 @@ private String toPattern(boolean localized) { int digitCount = useExponentialNotation ? getMaximumIntegerDigits() : Math.max(groupingSize, getMinimumIntegerDigits()) + 1; for (int i = digitCount; i > 0; --i) { - if (i != digitCount && isGroupingUsed() && groupingSize != 0 && + if (i != digitCount && isGroupingEnabled() && i % groupingSize == 0) { result.append(groupingSymbol); } diff --git a/src/java.base/share/classes/java/util/LazyCollections.java b/src/java.base/share/classes/java/util/LazyCollections.java index e15721db2ce2..f74fbad358b4 100644 --- a/src/java.base/share/classes/java/util/LazyCollections.java +++ b/src/java.base/share/classes/java/util/LazyCollections.java @@ -675,6 +675,12 @@ private static T orElseComputeSlowPath(final T[] array, final long offset = offsetFor(index); final Object mutex = mutexes.acquireMutex(offset); if (mutex == null) { + // There might be a race where the value is already computed and + // the mutex is cleared, so we need to re-check the value again + final T t = (T) UNSAFE.getReferenceAcquire(array, offset); + if (t != null) { + return t; + } throwIfPreviousException(index, throwables, input); // There must be an exception throw cannotReachHere(functionHolder, input); diff --git a/src/java.base/windows/native/launcher/relauncher.c b/src/java.base/windows/native/launcher/relauncher.c index 77b9dfa99ad7..50d9ddce5acd 100644 --- a/src/java.base/windows/native/launcher/relauncher.c +++ b/src/java.base/windows/native/launcher/relauncher.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2026, 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 @@ -182,7 +182,6 @@ int main(int argc, char* argv[]) { // Windows needs the command line as a single string, not as an array of char* size_t total_length = 0; for (int i = 0; java_args[i] != NULL; i++) { - char* arg = java_args[i]; total_length += strlen(java_args[i]) + 1; } @@ -220,6 +219,7 @@ int main(int argc, char* argv[]) { PROCESS_INFORMATION pi; memset(&si, 0, sizeof(si)); + si.cb = sizeof(si); memset(&pi, 0, sizeof(pi)); // Windows has no equivalent of exec, so start the process and wait for it diff --git a/src/java.desktop/windows/native/libawt/windows/ComCtl32Util.cpp b/src/java.desktop/windows/native/libawt/windows/ComCtl32Util.cpp index 66e9d0c1a897..773466477ded 100644 --- a/src/java.desktop/windows/native/libawt/windows/ComCtl32Util.cpp +++ b/src/java.desktop/windows/native/libawt/windows/ComCtl32Util.cpp @@ -41,18 +41,17 @@ void ComCtl32Util::InitLibraries() { m_bToolTipControlInitialized = ::InitCommonControlsEx(&iccex); } -WNDPROC ComCtl32Util::SubclassHWND(HWND hwnd, WNDPROC _WindowProc) { +void ComCtl32Util::SubclassHWND(HWND hwnd, WNDPROC _WindowProc) { const SUBCLASSPROC p = SharedWindowProc; // let compiler check type of SharedWindowProc ::SetWindowSubclass(hwnd, p, (UINT_PTR)_WindowProc, NULL); // _WindowProc is used as subclass ID - return NULL; } -void ComCtl32Util::UnsubclassHWND(HWND hwnd, WNDPROC _WindowProc, WNDPROC _DefWindowProc) { +void ComCtl32Util::UnsubclassHWND(HWND hwnd, WNDPROC _WindowProc) { const SUBCLASSPROC p = SharedWindowProc; // let compiler check type of SharedWindowProc ::RemoveWindowSubclass(hwnd, p, (UINT_PTR)_WindowProc); // _WindowProc is used as subclass ID } -LRESULT ComCtl32Util::DefWindowProc(WNDPROC _DefWindowProc, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { +LRESULT ComCtl32Util::DefWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { return ::DefSubclassProc(hwnd, msg, wParam, lParam); } diff --git a/src/java.desktop/windows/native/libawt/windows/ComCtl32Util.h b/src/java.desktop/windows/native/libawt/windows/ComCtl32Util.h index a3806bcc4ed5..ced96a605e78 100644 --- a/src/java.desktop/windows/native/libawt/windows/ComCtl32Util.h +++ b/src/java.desktop/windows/native/libawt/windows/ComCtl32Util.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2026, 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 @@ -44,11 +44,9 @@ class ComCtl32Util return m_bToolTipControlInitialized; } - WNDPROC SubclassHWND(HWND hwnd, WNDPROC _WindowProc); - // DefWindowProc is the same as returned from SubclassHWND - void UnsubclassHWND(HWND hwnd, WNDPROC _WindowProc, WNDPROC _DefWindowProc); - // DefWindowProc is the same as returned from SubclassHWND or NULL - LRESULT DefWindowProc(WNDPROC _DefWindowProc, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); + void SubclassHWND(HWND hwnd, WNDPROC _WindowProc); + void UnsubclassHWND(HWND hwnd, WNDPROC _WindowProc); + LRESULT DefWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); private: ComCtl32Util(); diff --git a/src/java.desktop/windows/native/libawt/windows/WPrinterJob.cpp b/src/java.desktop/windows/native/libawt/windows/WPrinterJob.cpp index 245a47499507..bd7dc6367fdf 100644 --- a/src/java.desktop/windows/native/libawt/windows/WPrinterJob.cpp +++ b/src/java.desktop/windows/native/libawt/windows/WPrinterJob.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,45 +53,33 @@ Java_sun_print_PrintServiceLookupProvider_getDefaultPrinterName(JNIEnv *env, TRY; TCHAR cBuffer[250]; - OSVERSIONINFO osv; - PRINTER_INFO_2 *ppi2 = NULL; - DWORD dwNeeded = 0; - DWORD dwReturned = 0; LPTSTR pPrinterName = NULL; jstring jPrinterName; - // What version of Windows are you running? - osv.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - GetVersionEx(&osv); - - // If Windows 2000, XP, Vista - if (osv.dwPlatformId == VER_PLATFORM_WIN32_NT) { - - // Retrieve the default string from Win.ini (the registry). - // String will be in form "printername,drivername,portname". - - if (GetProfileString(TEXT("windows"), TEXT("device"), TEXT(",,,"), - cBuffer, 250) <= 0) { - return NULL; - } - // Copy printer name into passed-in buffer... - int index = 0; - int len = lstrlen(cBuffer); - while ((index < len) && cBuffer[index] != _T(',')) { - index++; - } - if (index==0) { - return NULL; - } - - pPrinterName = (LPTSTR)GlobalAlloc(GPTR, (index+1)*sizeof(TCHAR)); - lstrcpyn(pPrinterName, cBuffer, index+1); - jPrinterName = JNU_NewStringPlatform(env, pPrinterName); - GlobalFree(pPrinterName); - return jPrinterName; - } else { + // Retrieve the default string from Win.ini (the registry). + // String will be in form "printername,drivername,portname". + if (GetProfileString(TEXT("windows"), TEXT("device"), TEXT(",,,"), + cBuffer, 250) <= 0) { return NULL; } + // Copy printer name into passed-in buffer... + int index = 0; + int len = lstrlen(cBuffer); + while ((index < len) && cBuffer[index] != _T(',')) { + index++; + } + if (index==0) { + return NULL; + } + + pPrinterName = (LPTSTR)GlobalAlloc(GPTR, (index+1)*sizeof(TCHAR)); + if (pPrinterName == NULL) { + return NULL; + } + lstrcpyn(pPrinterName, cBuffer, index+1); + jPrinterName = JNU_NewStringPlatform(env, pPrinterName); + GlobalFree(pPrinterName); + return jPrinterName; CATCH_BAD_ALLOC_RET(NULL); } diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Choice.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Choice.cpp index b7c45463c5a1..0c237a483cd9 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Choice.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_Choice.cpp @@ -89,7 +89,6 @@ namespace { AwtChoice::AwtChoice() { m_hList = NULL; - m_listDefWindowProc = NULL; } LPCTSTR AwtChoice::GetClassName() { @@ -97,8 +96,8 @@ LPCTSTR AwtChoice::GetClassName() { } void AwtChoice::Dispose() { - if (m_hList != NULL && m_listDefWindowProc != NULL) { - ComCtl32Util::GetInstance().UnsubclassHWND(m_hList, ListWindowProc, m_listDefWindowProc); + if (m_hList != NULL) { + ComCtl32Util::GetInstance().UnsubclassHWND(m_hList, ListWindowProc); } AwtComponent::Dispose(); } @@ -424,7 +423,7 @@ LRESULT CALLBACK AwtChoice::ListWindowProc(HWND hwnd, UINT message, } } } - return ComCtl32Util::GetInstance().DefWindowProc(NULL, hwnd, message, wParam, lParam); + return ComCtl32Util::GetInstance().DefWindowProc(hwnd, message, wParam, lParam); CATCH_BAD_ALLOC_RET(0); } @@ -449,7 +448,7 @@ MsgRouting AwtChoice::WmNotify(UINT notifyCode) cbi.cbSize = sizeof(COMBOBOXINFO); ::GetComboBoxInfo(GetHWnd(), &cbi); m_hList = cbi.hwndList; - m_listDefWindowProc = ComCtl32Util::GetInstance().SubclassHWND(m_hList, ListWindowProc); + ComCtl32Util::GetInstance().SubclassHWND(m_hList, ListWindowProc); DASSERT(::GetWindowLongPtr(m_hList, GWLP_USERDATA) == NULL); ::SetWindowLongPtr(m_hList, GWLP_USERDATA, (LONG_PTR)this); } diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Choice.h b/src/java.desktop/windows/native/libawt/windows/awt_Choice.h index b3aa3ea4e599..4340dfd3460f 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Choice.h +++ b/src/java.desktop/windows/native/libawt/windows/awt_Choice.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2026, 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 @@ -93,7 +93,6 @@ class AwtChoice : public AwtComponent { int GetTotalHeight(); static BOOL sm_isMouseMoveInList; HWND m_hList; - WNDPROC m_listDefWindowProc; static LRESULT CALLBACK ListWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); }; diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp index eca8290a1aa8..9d49172262f8 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp @@ -229,7 +229,6 @@ AwtComponent::AwtComponent() m_backgroundColorSet = FALSE; m_penForeground = NULL; m_brushBackground = NULL; - m_DefWindowProc = NULL; m_nextControlID = 1; m_childList = NULL; m_myControlID = 0; @@ -394,7 +393,7 @@ LRESULT CALLBACK AwtComponent::WndProc(HWND hWnd, UINT message, if (self == NULL || self->GetHWnd() != hWnd || message == WM_UNDOCUMENTED_CLIENTSHUTDOWN) // handle log-off gracefully { - return ComCtl32Util::GetInstance().DefWindowProc(NULL, hWnd, message, wParam, lParam); + return ComCtl32Util::GetInstance().DefWindowProc(hWnd, message, wParam, lParam); } else { return self->WindowProc(message, wParam, lParam); } @@ -682,7 +681,7 @@ void AwtComponent::SubclassHWND() return; } const WNDPROC wndproc = WndProc; // let compiler type check WndProc - m_DefWindowProc = ComCtl32Util::GetInstance().SubclassHWND(GetHWnd(), wndproc); + ComCtl32Util::GetInstance().SubclassHWND(GetHWnd(), wndproc); m_bSubclassed = TRUE; } @@ -694,7 +693,7 @@ void AwtComponent::UnsubclassHWND() if (!m_bSubclassed) { return; } - ComCtl32Util::GetInstance().UnsubclassHWND(GetHWnd(), WndProc, m_DefWindowProc); + ComCtl32Util::GetInstance().UnsubclassHWND(GetHWnd(), WndProc); m_bSubclassed = FALSE; } @@ -1981,7 +1980,7 @@ LRESULT AwtComponent::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) */ LRESULT AwtComponent::DefWindowProc(UINT msg, WPARAM wParam, LPARAM lParam) { - return ComCtl32Util::GetInstance().DefWindowProc(m_DefWindowProc, GetHWnd(), msg, wParam, lParam); + return ComCtl32Util::GetInstance().DefWindowProc(GetHWnd(), msg, wParam, lParam); } /* diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Component.h b/src/java.desktop/windows/native/libawt/windows/awt_Component.h index 1246f6cb06e7..42a88c24f8c8 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Component.h +++ b/src/java.desktop/windows/native/libawt/windows/awt_Component.h @@ -780,7 +780,6 @@ class AwtComponent : public AwtObject { AwtPen* m_penForeground; AwtBrush* m_brushBackground; - WNDPROC m_DefWindowProc; // counter for messages being processed by this component UINT m_MessagesProcessing; diff --git a/src/java.desktop/windows/native/libawt/windows/awt_FileDialog.cpp b/src/java.desktop/windows/native/libawt/windows/awt_FileDialog.cpp index 520097e07fb1..fc85995c8a84 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_FileDialog.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_FileDialog.cpp @@ -111,9 +111,7 @@ LRESULT CALLBACK FileDialogWndProc(HWND hWnd, UINT message, return 0; } } - - WNDPROC lpfnWndProc = (WNDPROC)(::GetProp(hWnd, NativeDialogWndProcProp)); - return ComCtl32Util::GetInstance().DefWindowProc(lpfnWndProc, hWnd, message, wParam, lParam); + return ComCtl32Util::GetInstance().DefWindowProc(hWnd, message, wParam, lParam); } static UINT_PTR CALLBACK @@ -152,10 +150,7 @@ FileDialogHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam) } // subclass dialog's parent to receive additional messages - WNDPROC lpfnWndProc = ComCtl32Util::GetInstance().SubclassHWND(parent, - FileDialogWndProc); - ::SetProp(parent, NativeDialogWndProcProp, reinterpret_cast(lpfnWndProc)); - + ComCtl32Util::GetInstance().SubclassHWND(parent, FileDialogWndProc); ::SetProp(parent, OpenFileNameProp, (void *)lParam); break; @@ -167,12 +162,8 @@ FileDialogHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam) ::ImmReleaseContext(hdlg, hIMC); } - WNDPROC lpfnWndProc = (WNDPROC)(::GetProp(parent, NativeDialogWndProcProp)); - ComCtl32Util::GetInstance().UnsubclassHWND(parent, - FileDialogWndProc, - lpfnWndProc); + ComCtl32Util::GetInstance().UnsubclassHWND(parent, FileDialogWndProc); ::RemoveProp(parent, ModalDialogPeerProp); - ::RemoveProp(parent, NativeDialogWndProcProp); ::RemoveProp(parent, OpenFileNameProp); break; } diff --git a/src/java.desktop/windows/native/libawt/windows/awt_PrintDialog.cpp b/src/java.desktop/windows/native/libawt/windows/awt_PrintDialog.cpp index 4e546cb23dbd..32174af78d01 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_PrintDialog.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_PrintDialog.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2026, 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 @@ -64,9 +64,7 @@ LRESULT CALLBACK PrintDialogWndProc(HWND hWnd, UINT message, break; } } - - WNDPROC lpfnWndProc = (WNDPROC)(::GetProp(hWnd, NativeDialogWndProcProp)); - return ComCtl32Util::GetInstance().DefWindowProc(lpfnWndProc, hWnd, message, wParam, lParam); + return ComCtl32Util::GetInstance().DefWindowProc(hWnd, message, wParam, lParam); } static UINT_PTR CALLBACK @@ -100,19 +98,12 @@ PrintDialogHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam) } // subclass dialog's parent to receive additional messages - WNDPROC lpfnWndProc = ComCtl32Util::GetInstance().SubclassHWND(hdlg, - PrintDialogWndProc); - ::SetProp(hdlg, NativeDialogWndProcProp, reinterpret_cast(lpfnWndProc)); - + ComCtl32Util::GetInstance().SubclassHWND(hdlg, PrintDialogWndProc); break; } case WM_DESTROY: { - WNDPROC lpfnWndProc = (WNDPROC)(::GetProp(hdlg, NativeDialogWndProcProp)); - ComCtl32Util::GetInstance().UnsubclassHWND(hdlg, - PrintDialogWndProc, - lpfnWndProc); + ComCtl32Util::GetInstance().UnsubclassHWND(hdlg, PrintDialogWndProc); ::RemoveProp(hdlg, ModalDialogPeerProp); - ::RemoveProp(hdlg, NativeDialogWndProcProp); break; } } diff --git a/src/java.desktop/windows/native/libawt/windows/awt_PrintJob.cpp b/src/java.desktop/windows/native/libawt/windows/awt_PrintJob.cpp index b18fa5a7e2ce..0381e828c260 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_PrintJob.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_PrintJob.cpp @@ -3203,9 +3203,7 @@ LRESULT CALLBACK PageDialogWndProc(HWND hWnd, UINT message, break; } } - - WNDPROC lpfnWndProc = (WNDPROC)(::GetProp(hWnd, NativeDialogWndProcProp)); - return ComCtl32Util::GetInstance().DefWindowProc(lpfnWndProc, hWnd, message, wParam, lParam); + return ComCtl32Util::GetInstance().DefWindowProc(hWnd, message, wParam, lParam); } /** @@ -3239,19 +3237,12 @@ static UINT CALLBACK pageDlgHook(HWND hDlg, UINT msg, } // subclass dialog's parent to receive additional messages - WNDPROC lpfnWndProc = ComCtl32Util::GetInstance().SubclassHWND(hDlg, - PageDialogWndProc); - ::SetProp(hDlg, NativeDialogWndProcProp, reinterpret_cast(lpfnWndProc)); - + ComCtl32Util::GetInstance().SubclassHWND(hDlg, PageDialogWndProc); break; } case WM_DESTROY: { - WNDPROC lpfnWndProc = (WNDPROC)(::GetProp(hDlg, NativeDialogWndProcProp)); - ComCtl32Util::GetInstance().UnsubclassHWND(hDlg, - PageDialogWndProc, - lpfnWndProc); + ComCtl32Util::GetInstance().UnsubclassHWND(hDlg, PageDialogWndProc); ::RemoveProp(hDlg, ModalDialogPeerProp); - ::RemoveProp(hDlg, NativeDialogWndProcProp); break; } } diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Window.h b/src/java.desktop/windows/native/libawt/windows/awt_Window.h index f1eacc35a5e3..bae8f408a731 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Window.h +++ b/src/java.desktop/windows/native/libawt/windows/awt_Window.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,6 @@ // property name tagging windows disabled by modality static LPCTSTR ModalBlockerProp = TEXT("SunAwtModalBlockerProp"); static LPCTSTR ModalDialogPeerProp = TEXT("SunAwtModalDialogPeerProp"); -static LPCTSTR NativeDialogWndProcProp = TEXT("SunAwtNativeDialogWndProcProp"); #ifndef WH_MOUSE_LL #define WH_MOUSE_LL 14 diff --git a/src/java.sql.rowset/share/classes/com/sun/rowset/CachedRowSetImpl.java b/src/java.sql.rowset/share/classes/com/sun/rowset/CachedRowSetImpl.java index f5bf8df6a4af..ad8638cf6cec 100644 --- a/src/java.sql.rowset/share/classes/com/sun/rowset/CachedRowSetImpl.java +++ b/src/java.sql.rowset/share/classes/com/sun/rowset/CachedRowSetImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2026, 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 @@ -321,6 +321,9 @@ public class CachedRowSetImpl extends BaseRowSet implements RowSet, RowSetIntern private boolean updateOnInsert; + private static final String MAX_ROW_WARNING = + "Populating rows setting has exceeded max row setting"; + /** @@ -382,11 +385,6 @@ public CachedRowSetImpl() throws SQLException { // insert row setup onInsertRow = false; insertRow = null; - - // set the warnings - sqlwarn = new SQLWarning(); - rowsetWarning = new RowSetWarning(); - } /** @@ -648,14 +646,15 @@ public void populate(ResultSet data) throws SQLException { mRows = this.getMaxRows(); rowsFetched = 0; currentRow = null; + boolean exceededMax = false; while ( data.next()) { currentRow = new Row(numCols); - if ( rowsFetched > mRows && mRows > 0) { - rowsetWarning.setNextWarning(new RowSetWarning("Populating rows " - + "setting has exceeded max row setting")); + if (rowsFetched > mRows && mRows > 0 && !exceededMax) { + exceededMax = true; + addRowSetWarning(MAX_ROW_WARNING); } for ( i = 1; i <= numCols; i++) { /* @@ -6809,6 +6808,18 @@ public RowSetWarning getRowSetWarnings() { return rowsetWarning; } + /** + * Adds a RowSetWarning with the specified reason. + * If there is no root warning yet, one is created, otherwise the warning + * is chained to an existing warning chain. + */ + private void addRowSetWarning(String reason) { + if (rowsetWarning == null) { + rowsetWarning = new RowSetWarning(reason); + } else { + rowsetWarning.setNextWarning(new RowSetWarning(reason)); + } + } /** * The function tries to isolate the tablename when only setCommand @@ -7322,16 +7333,14 @@ public void populate(ResultSet data, int start) throws SQLException{ currentRow = new Row(numCols); if(pageSize == 0){ - if ( rowsFetched >= mRows && mRows > 0) { - rowsetWarning.setNextException(new SQLException("Populating rows " - + "setting has exceeded max row setting")); + if (rowsFetched >= mRows && mRows > 0) { + addRowSetWarning(MAX_ROW_WARNING); break; } } else { - if ( (rowsFetched >= pageSize) ||( maxRowsreached >= mRows && mRows > 0)) { - rowsetWarning.setNextException(new SQLException("Populating rows " - + "setting has exceeded max row setting")); + if ((rowsFetched >= pageSize) || ( maxRowsreached >= mRows && mRows > 0)) { + addRowSetWarning(MAX_ROW_WARNING); break; } } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java index 0b111e07c75f..91493776cccf 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java @@ -903,13 +903,6 @@ public void genArgs(List trees, List pts) { * Visitor methods for statements and definitions *************************************************************************/ - /** Thrown when the byte code size exceeds limit. - */ - public static class CodeSizeOverflow extends RuntimeException { - private static final long serialVersionUID = 0; - public CodeSizeOverflow() {} - } - public void visitMethodDef(JCMethodDecl tree) { // Create a new local environment that points pack at method // definition. @@ -956,13 +949,7 @@ else if (tree.body != null) { // Create a new code structure and initialize it. int startpcCrt = initCode(tree, env, fatcode); - try { - genStat(tree.body, env); - } catch (CodeSizeOverflow e) { - // Failed due to code limit, try again with jsr/ret - startpcCrt = initCode(tree, env, fatcode); - genStat(tree.body, env); - } + genStat(tree.body, env); if (code.state.stacksize != 0) { log.error(tree.body.pos(), Errors.StackSimError(tree.sym)); diff --git a/src/jdk.compiler/share/classes/module-info.java b/src/jdk.compiler/share/classes/module-info.java index 4aa60a3dffee..c839f23cbf25 100644 --- a/src/jdk.compiler/share/classes/module-info.java +++ b/src/jdk.compiler/share/classes/module-info.java @@ -204,7 +204,7 @@ * * * - * All of the non-{@code docllint:} strings listed above may also be used with the {@code -Xlint} command line flag. + * All of the non-{@code doclint:} strings listed above may also be used with the {@code -Xlint} command line flag. * The {@code -Xlint} flag also supports these strings not supported by {@code @SuppressWarnings}: * * diff --git a/src/jdk.crypto.cryptoki/share/legal/pkcs11cryptotoken.md b/src/jdk.crypto.cryptoki/share/legal/pkcs11cryptotoken.md index 7877f54fe6e3..33a2b5952ca9 100644 --- a/src/jdk.crypto.cryptoki/share/legal/pkcs11cryptotoken.md +++ b/src/jdk.crypto.cryptoki/share/legal/pkcs11cryptotoken.md @@ -1,76 +1,77 @@ -## OASIS PKCS #11 Cryptographic Token Interface v3.1 +## OASIS PKCS #11 Cryptographic Token Interface v3.2 ### OASIS PKCS #11 Cryptographic Token Interface License
 
-Copyright © OASIS Open 2023. All Rights Reserved.
+Copyright © OASIS Open 2026. All Rights Reserved.
 
-All capitalized terms in the following text have the meanings
-assigned to them in the OASIS Intellectual Property Rights Policy (the
-"OASIS IPR Policy"). The full Policy may be found at the OASIS website:
-[https://www.oasis-open.org/policies-guidelines/ipr/].
+All capitalized terms in the following text have the meanings assigned to them
+in the OASIS Intellectual Property Rights Policy (the "OASIS IPR Policy"). The
+full Policy may be found at the OASIS website:
+.
 
-This document and translations of it may be copied and furnished to
-others, and derivative works that comment on or otherwise explain it or
-assist in its implementation may be prepared, copied, published, and
-distributed, in whole or in part, without restriction of any kind,
-provided that the above copyright notice and this section are included
-on all such copies and derivative works. However, this document itself
-may not be modified in any way, including by removing the copyright
-notice or references to OASIS, except as needed for the purpose of
-developing any document or deliverable produced by an OASIS Technical
-Committee (in which case the rules applicable to copyrights, as set
-forth in the OASIS IPR Policy, must be followed) or as required to
-translate it into languages other than English.
+This document and translations of it may be copied and furnished to others, and
+derivative works that comment on or otherwise explain it or assist in its
+implementation may be prepared, copied, published, and distributed, in whole or
+in part, without restriction of any kind, provided that the above copyright
+notice and this section are included on all such copies and derivative works.
+However, this document itself may not be modified in any way, including by
+removing the copyright notice or references to OASIS, except as needed for the
+purpose of developing any document or deliverable produced by an OASIS Technical
+Committee (in which case the rules applicable to copyrights, as set forth in the
+OASIS IPR Policy, must be followed) or as required to translate it into
+languages other than English.
 
-The limited permissions granted above are perpetual and will not be
-revoked by OASIS or its successors or assigns.
+The limited permissions granted above are perpetual and will not be revoked by
+OASIS or its successors or assigns.
 
-This document and the information contained herein is provided on an
-"AS IS" basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED,
-INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE
-INFORMATION HEREIN WILL NOT INFRINGE ANY OWNERSHIP RIGHTS OR ANY IMPLIED
-WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. OASIS
-AND ITS MEMBERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THIS DOCUMENT OR ANY
-PART THEREOF.
+This document and the information contained herein is provided on an "AS IS"
+basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE
+ANY OWNERSHIP RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR
+A PARTICULAR PURPOSE. OASIS AND ITS MEMBERS WILL NOT BE LIABLE FOR ANY DIRECT,
+INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THIS
+DOCUMENT OR ANY PART THEREOF.
 
-As stated in the OASIS IPR Policy, the following three paragraphs in
-brackets apply to OASIS Standards Final Deliverable documents (Committee
-Specifications, OASIS Standards, or Approved Errata).
+As stated in the OASIS IPR Policy, the following three paragraphs in brackets
+apply to OASIS Standards Final Deliverable documents (Committee Specifications,
+OASIS Standards, or Approved Errata).
 
-[OASIS requests that any OASIS Party or any other party that
-believes it has patent claims that would necessarily be infringed by
-implementations of this OASIS Standards Final Deliverable, to notify
-OASIS TC Administrator and provide an indication of its willingness to
-grant patent licenses to such patent claims in a manner consistent with
-the IPR Mode of the OASIS Technical Committee that produced this
-deliverable.]
+[OASIS requests that any OASIS Party or any other party that believes it has
+patent claims that would necessarily be infringed by implementations of this
+OASIS Standards Final Deliverable, to notify OASIS TC Administrator and provide
+an indication of its willingness to grant patent licenses to such patent claims
+in a manner consistent with the IPR Mode of the OASIS Technical Committee that
+produced this deliverable.]
 
-[OASIS invites any party to contact the OASIS TC Administrator if it
-is aware of a claim of ownership of any patent claims that would
-necessarily be infringed by implementations of this OASIS Standards
-Final Deliverable by a patent holder that is not willing to provide a
-license to such patent claims in a manner consistent with the IPR Mode
-of the OASIS Technical Committee that produced this OASIS Standards
-Final Deliverable. OASIS may include such claims on its website, but
-disclaims any obligation to do so.]
+[OASIS invites any party to contact the OASIS TC Administrator if it is aware of
+a claim of ownership of any patent claims that would necessarily be infringed by
+implementations of this OASIS Standards Final Deliverable by a patent holder
+that is not willing to provide a license to such patent claims in a manner
+consistent with the IPR Mode of the OASIS Technical Committee that produced this
+OASIS Standards Final Deliverable. OASIS may include such claims on its website,
+but disclaims any obligation to do so.]
 
-[OASIS takes no position regarding the validity or scope of any
-intellectual property or other rights that might be claimed to pertain
-to the implementation or use of the technology described in this OASIS
-Standards Final Deliverable or the extent to which any license under
-such rights might or might not be available; neither does it represent
-that it has made any effort to identify any such rights. Information on
-OASIS' procedures with respect to rights in any document or deliverable
-produced by an OASIS Technical Committee can be found on the OASIS
-website. Copies of claims of rights made available for publication and
-any assurances of licenses to be made available, or the result of an
-attempt made to obtain a general license or permission for the use of
-such proprietary rights by implementers or users of this OASIS Standards
-Final Deliverable, can be obtained from the OASIS TC Administrator.
-OASIS makes no representation that any information or list of
-intellectual property rights will at any time be complete, or that any
-claims in such list are, in fact, Essential Claims.]
+[OASIS takes no position regarding the validity or scope of any intellectual
+property or other rights that might be claimed to pertain to the implementation
+or use of the technology described in this OASIS Standards Final Deliverable or
+the extent to which any license under such rights might or might not be
+available; neither does it represent that it has made any effort to identify any
+such rights. Information on OASIS' procedures with respect to rights in any
+document or deliverable produced by an OASIS Technical Committee can be found on
+the OASIS website. Copies of claims of rights made available for publication and
+any assurances of licenses to be made available, or the result of an attempt
+made to obtain a general license or permission for the use of such proprietary
+rights by implementers or users of this OASIS Standards Final Deliverable, can
+be obtained from the OASIS TC Administrator. OASIS makes no representation that
+any information or list of intellectual property rights will at any time be
+complete, or that any claims in such list are, in fact, Essential Claims.]
+
+The name "OASIS" is a trademark of OASIS, the owner and developer of this
+document, and should be used only to refer to the organization and its official
+outputs. OASIS welcomes reference to, and implementation and use of, documents,
+while reserving the right to enforce its marks against misleading uses. Please
+see  for above
+guidance.
 
 
diff --git a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11.h b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11.h index 5933da0e3b75..cb553fe9d37b 100644 --- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11.h +++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11.h @@ -1,11 +1,12 @@ -/* - * PKCS #11 Specification Version 3.1 - * OASIS Standard - * 23 July 2023 - * Copyright (c) OASIS Open 2023. All Rights Reserved. - * Source: https://docs.oasis-open.org/pkcs11/pkcs11-spec/v3.1/os/include/pkcs11-v3.1/ - * Latest stage of narrative specification: https://docs.oasis-open.org/pkcs11/pkcs11-spec/v3.1/pkcs11-spec-v3.1.html - * TC IPR Statement: https://www.oasis-open.org/committees/pkcs11/ipr.php +/* Copyright (c) OASIS Open 2016,2019,2024. All Rights Reserved./ + * /Distributed under the terms of the OASIS IPR Policy, + * [http://www.oasis-open.org/policies-guidelines/ipr], AS-IS, WITHOUT ANY + * IMPLIED OR EXPRESS WARRANTY; there is no warranty of MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE or NONINFRINGEMENT of the rights of others. + */ + +/* Latest version of the specification: + * http://docs.oasis-open.org/pkcs11/pkcs11-base/v3.2/pkcs11-base-v3.2.html */ #ifndef _PKCS11_H_ @@ -204,6 +205,21 @@ extern "C" { #define CK_PKCS11_FUNCTION_INFO(name) \ __PASTE(CK_,name) name; +/* Create the 3.2 Function list */ +struct CK_FUNCTION_LIST_3_2 { + + CK_VERSION version; /* Cryptoki version */ + +/* Pile all the function pointers into the CK_FUNCTION_LIST. */ +/* pkcs11f.h has all the information about the Cryptoki + * function prototypes. + */ +#include "pkcs11f.h" + +}; + +#define CK_PKCS11_3_0_ONLY 1 /* don't include the 3.2 and later functions */ + /* Create the 3.0 Function list */ struct CK_FUNCTION_LIST_3_0 { @@ -217,7 +233,9 @@ struct CK_FUNCTION_LIST_3_0 { }; -#define CK_PKCS11_2_0_ONLY 1 +#undef CK_PKCS11_3_0_ONLY + +#define CK_PKCS11_2_0_ONLY 1 /* don't include the 3.0 and later functions */ /* Continue to define the old CK_FUNCTION_LIST */ struct CK_FUNCTION_LIST { diff --git a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11f.h b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11f.h index 80c43400d05f..6f44b4aa7849 100644 --- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11f.h +++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11f.h @@ -1,11 +1,12 @@ -/* - * PKCS #11 Specification Version 3.1 - * OASIS Standard - * 23 July 2023 - * Copyright (c) OASIS Open 2023. All Rights Reserved. - * Source: https://docs.oasis-open.org/pkcs11/pkcs11-spec/v3.1/os/include/pkcs11-v3.1/ - * Latest stage of narrative specification: https://docs.oasis-open.org/pkcs11/pkcs11-spec/v3.1/pkcs11-spec-v3.1.html - * TC IPR Statement: https://www.oasis-open.org/committees/pkcs11/ipr.php +/* Copyright (c) OASIS Open 2016, 2019, 2024. All Rights Reserved./ + * /Distributed under the terms of the OASIS IPR Policy, + * [http://www.oasis-open.org/policies-guidelines/ipr], AS-IS, WITHOUT ANY + * IMPLIED OR EXPRESS WARRANTY; there is no warranty of MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE or NONINFRINGEMENT of the rights of others. + */ + +/* Latest version of the specification: + * http://docs.oasis-open.org/pkcs11/pkcs11-spec/v3.2/pkcs11-spec-v3.2.html */ /* This header file contains pretty much everything about all the @@ -953,7 +954,7 @@ CK_PKCS11_FUNCTION_INFO(C_GetInterface) CK_UTF8CHAR_PTR pInterfaceName, /* name of the interface */ CK_VERSION_PTR pVersion, /* version of the interface */ CK_INTERFACE_PTR_PTR ppInterface, /* returned interface */ - CK_FLAGS flags /* flags controlling the semantics + CK_FLAGS flags /* flags controlling the semantics * of the interface */ ); #endif @@ -1192,5 +1193,138 @@ CK_PKCS11_FUNCTION_INFO(C_MessageVerifyFinal) ); #endif -#endif /* CK_PKCS11_2_0_ONLY */ +#ifndef CK_PKCS11_3_0_ONLY +CK_PKCS11_FUNCTION_INFO(C_EncapsulateKey) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_MECHANISM_PTR pMechanism, /* the encapsulation mechanism */ + CK_OBJECT_HANDLE hPublicKey, /* the encapsulating key */ + CK_ATTRIBUTE_PTR pTemplate, /* new key template */ + CK_ULONG ulAttributeCount, /* template length */ + CK_BYTE_PTR pCiphertext, /* the wrapped key */ + CK_ULONG_PTR pulCiphertextLen, /* the wrapped key size */ + CK_OBJECT_HANDLE_PTR phKey /* the encapsulated key */ +); +#endif + +CK_PKCS11_FUNCTION_INFO(C_DecapsulateKey) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_MECHANISM_PTR pMechanism, /* the decapsulation mechanism */ + CK_OBJECT_HANDLE hPrivateKey, /* the decapsulating key */ + CK_ATTRIBUTE_PTR pTemplate, /* new key template */ + CK_ULONG ulAttributeCount, /* template length */ + CK_BYTE_PTR pCiphertext, /* the wrapped key */ + CK_ULONG ulCiphertextLen, /* the wrapped key size */ + CK_OBJECT_HANDLE_PTR phKey /* the decapsulated key */ +); +#endif + +CK_PKCS11_FUNCTION_INFO(C_VerifySignatureInit) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_MECHANISM_PTR pMechanism, /* the verification mechanism */ + CK_OBJECT_HANDLE hKey, /* verification key */ + CK_BYTE_PTR pSignature, /* signature */ + CK_ULONG ulSignatureLen /* signature length */ +); +#endif + +CK_PKCS11_FUNCTION_INFO(C_VerifySignature) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pData, /* signed data */ + CK_ULONG ulDataLen /* length of signed data */ +); +#endif + +CK_PKCS11_FUNCTION_INFO(C_VerifySignatureUpdate) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pPart, /* signed data */ + CK_ULONG ulPartLen /* length of signed data */ +); +#endif + +CK_PKCS11_FUNCTION_INFO(C_VerifySignatureFinal) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession /* the session's handle */ +); +#endif + +CK_PKCS11_FUNCTION_INFO(C_GetSessionValidationFlags) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_SESSION_VALIDATION_FLAGS_TYPE type, /* which state of flags */ + CK_FLAGS_PTR pFlags /* validation flags */ +); +#endif + +CK_PKCS11_FUNCTION_INFO(C_AsyncComplete) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_UTF8CHAR_PTR pFunctionName, /* pkcs11 function name */ + CK_ASYNC_DATA_PTR pResult /* operation result */ +); +#endif + +CK_PKCS11_FUNCTION_INFO(C_AsyncGetID) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_UTF8CHAR_PTR pFunctionName, /* pkcs11 function name */ + CK_ULONG_PTR pulID /* persistent operation id */ +); +#endif +CK_PKCS11_FUNCTION_INFO(C_AsyncJoin) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_UTF8CHAR_PTR pFunctionName, /* pkcs11 function name */ + CK_ULONG ulID, /* persistent operation id */ + CK_BYTE_PTR pData, /* location for the data */ + CK_ULONG ulData +); +#endif + +CK_PKCS11_FUNCTION_INFO(C_WrapKeyAuthenticated) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hWrappingKey, + CK_OBJECT_HANDLE hKey, + CK_BYTE_PTR pAssociatedData, + CK_ULONG ulAssociatedDataLen, + CK_BYTE_PTR pWrappedKey, + CK_ULONG_PTR pulWrappedKeyLen +); +#endif + +CK_PKCS11_FUNCTION_INFO(C_UnwrapKeyAuthenticated) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hUnwrappingKey, + CK_BYTE_PTR pWrappedKey, + CK_ULONG ulWrappedKeyLen, + CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulAttributeCount, + CK_BYTE_PTR pAssociatedData, + CK_ULONG ulAssociatedDataLen, + CK_OBJECT_HANDLE_PTR phKey +); +#endif + +#endif /* CK_PKCS11_3_0_ONLY */ +#endif /* CK_PKCS11_2_0_ONLY */ diff --git a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11t.h b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11t.h index 79d7cf7d7dae..379cebd2b493 100644 --- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11t.h +++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11t.h @@ -1,11 +1,12 @@ -/* - * PKCS #11 Specification Version 3.1 - * OASIS Standard - * 23 July 2023 - * Copyright (c) OASIS Open 2023. All Rights Reserved. - * Source: https://docs.oasis-open.org/pkcs11/pkcs11-spec/v3.1/os/include/pkcs11-v3.1/ - * Latest stage of narrative specification: https://docs.oasis-open.org/pkcs11/pkcs11-spec/v3.1/pkcs11-spec-v3.1.html - * TC IPR Statement: https://www.oasis-open.org/committees/pkcs11/ipr.php +/* Copyright (c) OASIS Open 2016, 2019, 2024. All Rights Reserved./ + * /Distributed under the terms of the OASIS IPR Policy, + * [http://www.oasis-open.org/policies-guidelines/ipr], AS-IS, WITHOUT ANY + * IMPLIED OR EXPRESS WARRANTY; there is no warranty of MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE or NONINFRINGEMENT of the rights of others. + */ + +/* Latest version of the specification: + * http://docs.oasis-open.org/pkcs11/pkcs11-spec/v3.2/pkcs11-spec-v3.2.html */ /* See top of pkcs11.h for information about the macros that @@ -17,7 +18,7 @@ #define _PKCS11T_H_ 1 #define CRYPTOKI_VERSION_MAJOR 3 -#define CRYPTOKI_VERSION_MINOR 1 +#define CRYPTOKI_VERSION_MINOR 2 #define CRYPTOKI_VERSION_AMENDMENT 0 #define CK_TRUE 1 @@ -64,6 +65,7 @@ typedef CK_CHAR CK_PTR CK_CHAR_PTR; typedef CK_UTF8CHAR CK_PTR CK_UTF8CHAR_PTR; typedef CK_ULONG CK_PTR CK_ULONG_PTR; typedef void CK_PTR CK_VOID_PTR; +typedef CK_ULONG CK_PTR CK_FLAGS_PTR; /* Pointer to a CK_VOID_PTR-- i.e., pointer to pointer to void */ typedef CK_VOID_PTR CK_PTR CK_VOID_PTR_PTR; @@ -76,19 +78,19 @@ typedef CK_VOID_PTR CK_PTR CK_VOID_PTR_PTR; typedef struct CK_VERSION { - CK_BYTE major; /* integer portion of version number */ - CK_BYTE minor; /* 1/100ths portion of version number */ + CK_BYTE major; /* integer portion of version number */ + CK_BYTE minor; /* 1/100ths portion of version number */ } CK_VERSION; typedef CK_VERSION CK_PTR CK_VERSION_PTR; typedef struct CK_INFO { - CK_VERSION cryptokiVersion; /* Cryptoki interface ver */ - CK_UTF8CHAR manufacturerID[32]; /* blank padded */ - CK_FLAGS flags; /* must be zero */ - CK_UTF8CHAR libraryDescription[32]; /* blank padded */ - CK_VERSION libraryVersion; /* version of library */ + CK_VERSION cryptokiVersion; /* Cryptoki interface ver */ + CK_UTF8CHAR manufacturerID[32]; /* blank padded */ + CK_FLAGS flags; /* must be zero */ + CK_UTF8CHAR libraryDescription[32]; /* blank padded */ + CK_VERSION libraryVersion; /* version of library */ } CK_INFO; typedef CK_INFO CK_PTR CK_INFO_PTR; @@ -108,12 +110,12 @@ typedef CK_SLOT_ID CK_PTR CK_SLOT_ID_PTR; /* CK_SLOT_INFO provides information about a slot */ typedef struct CK_SLOT_INFO { - CK_UTF8CHAR slotDescription[64]; /* blank padded */ - CK_UTF8CHAR manufacturerID[32]; /* blank padded */ - CK_FLAGS flags; + CK_UTF8CHAR slotDescription[64]; /* blank padded */ + CK_UTF8CHAR manufacturerID[32]; /* blank padded */ + CK_FLAGS flags; - CK_VERSION hardwareVersion; /* version of hardware */ - CK_VERSION firmwareVersion; /* version of firmware */ + CK_VERSION hardwareVersion; /* version of hardware */ + CK_VERSION firmwareVersion; /* version of firmware */ } CK_SLOT_INFO; /* flags: bit flags that provide capabilities of the slot @@ -128,25 +130,25 @@ typedef CK_SLOT_INFO CK_PTR CK_SLOT_INFO_PTR; /* CK_TOKEN_INFO provides information about a token */ typedef struct CK_TOKEN_INFO { - CK_UTF8CHAR label[32]; /* blank padded */ - CK_UTF8CHAR manufacturerID[32]; /* blank padded */ - CK_UTF8CHAR model[16]; /* blank padded */ - CK_CHAR serialNumber[16]; /* blank padded */ - CK_FLAGS flags; /* see below */ - - CK_ULONG ulMaxSessionCount; /* max open sessions */ - CK_ULONG ulSessionCount; /* sess. now open */ - CK_ULONG ulMaxRwSessionCount; /* max R/W sessions */ - CK_ULONG ulRwSessionCount; /* R/W sess. now open */ - CK_ULONG ulMaxPinLen; /* in bytes */ - CK_ULONG ulMinPinLen; /* in bytes */ - CK_ULONG ulTotalPublicMemory; /* in bytes */ - CK_ULONG ulFreePublicMemory; /* in bytes */ - CK_ULONG ulTotalPrivateMemory; /* in bytes */ - CK_ULONG ulFreePrivateMemory; /* in bytes */ - CK_VERSION hardwareVersion; /* version of hardware */ - CK_VERSION firmwareVersion; /* version of firmware */ - CK_CHAR utcTime[16]; /* time */ + CK_UTF8CHAR label[32]; /* blank padded */ + CK_UTF8CHAR manufacturerID[32]; /* blank padded */ + CK_UTF8CHAR model[16]; /* blank padded */ + CK_CHAR serialNumber[16]; /* blank padded */ + CK_FLAGS flags; /* see below */ + + CK_ULONG ulMaxSessionCount; /* max open sessions */ + CK_ULONG ulSessionCount; /* sess. now open */ + CK_ULONG ulMaxRwSessionCount; /* max R/W sessions */ + CK_ULONG ulRwSessionCount; /* R/W sess. now open */ + CK_ULONG ulMaxPinLen; /* in bytes */ + CK_ULONG ulMinPinLen; /* in bytes */ + CK_ULONG ulTotalPublicMemory; /* in bytes */ + CK_ULONG ulFreePublicMemory; /* in bytes */ + CK_ULONG ulTotalPrivateMemory; /* in bytes */ + CK_ULONG ulFreePrivateMemory; /* in bytes */ + CK_VERSION hardwareVersion; /* version of hardware */ + CK_VERSION firmwareVersion; /* version of firmware */ + CK_CHAR utcTime[16]; /* time */ } CK_TOKEN_INFO; /* The flags parameter is defined as follows: @@ -245,8 +247,20 @@ typedef struct CK_TOKEN_INFO { */ #define CKF_SO_PIN_TO_BE_CHANGED 0x00800000UL +/* CKF_ERROR_STATE. If it is true, the token failed a FIPS 140 + * self-test and entered an error state. */ #define CKF_ERROR_STATE 0x01000000UL +/* + * CKF_SEED_RANDOM_REQUIRED. If this is true the token’s + * random number generator must be seeded or re-seeded using + * C_SeedRandom. */ +#define CKF_SEED_RANDOM_REQUIRED 0x02000000UL + +/* CKF_ASYNC_SESSION_SUPPORTED. If this is true the token + * supports asynchronous sessions. */ +#define CKF_ASYNC_SESSION_SUPPORTED 0x04000000UL + typedef CK_TOKEN_INFO CK_PTR CK_TOKEN_INFO_PTR; @@ -277,17 +291,18 @@ typedef CK_ULONG CK_STATE; /* CK_SESSION_INFO provides information about a session */ typedef struct CK_SESSION_INFO { - CK_SLOT_ID slotID; - CK_STATE state; - CK_FLAGS flags; /* see below */ - CK_ULONG ulDeviceError; /* device-dependent error code */ + CK_SLOT_ID slotID; + CK_STATE state; + CK_FLAGS flags; /* see below */ + CK_ULONG ulDeviceError; /* device-dependent error code */ } CK_SESSION_INFO; /* The flags are defined in the following table: - * Bit Flag Mask Meaning + * Bit Flag Mask Meaning */ -#define CKF_RW_SESSION 0x00000002UL /* session is r/w */ -#define CKF_SERIAL_SESSION 0x00000004UL /* no parallel */ +#define CKF_RW_SESSION 0x00000002UL /* session is r/w */ +#define CKF_SERIAL_SESSION 0x00000004UL /* no parallel */ +#define CKF_ASYNC_SESSION 0x00000008UL /* session is async */ typedef CK_SESSION_INFO CK_PTR CK_SESSION_INFO_PTR; @@ -317,20 +332,22 @@ typedef CK_ULONG CK_OBJECT_CLASS; #define CKO_MECHANISM 0x00000007UL #define CKO_OTP_KEY 0x00000008UL #define CKO_PROFILE 0x00000009UL +#define CKO_VALIDATION 0x0000000aUL +#define CKO_TRUST 0x0000000bUL #define CKO_VENDOR_DEFINED 0x80000000UL typedef CK_OBJECT_CLASS CK_PTR CK_OBJECT_CLASS_PTR; /* Profile ID's */ -#define CKP_INVALID_ID 0x00000000UL -#define CKP_BASELINE_PROVIDER 0x00000001UL -#define CKP_EXTENDED_PROVIDER 0x00000002UL -#define CKP_AUTHENTICATION_TOKEN 0x00000003UL -#define CKP_PUBLIC_CERTIFICATES_TOKEN 0x00000004UL -#define CKP_COMPLETE_PROVIDER 0x00000005UL -#define CKP_HKDF_TLS_TOKEN 0x00000006UL -#define CKP_VENDOR_DEFINED 0x80000000UL +#define CKP_INVALID_ID 0x00000000UL /* Profile */ +#define CKP_BASELINE_PROVIDER 0x00000001UL /* Profile */ +#define CKP_EXTENDED_PROVIDER 0x00000002UL /* Profile */ +#define CKP_AUTHENTICATION_TOKEN 0x00000003UL /* Profile */ +#define CKP_PUBLIC_CERTIFICATES_TOKEN 0x00000004UL /* Profile */ +#define CKP_COMPLETE_PROVIDER 0x00000005UL /* Profile */ +#define CKP_HKDF_TLS_TOKEN 0x00000006UL /* Profile */ +#define CKP_VENDOR_DEFINED 0x80000000UL /* Profile */ /* CK_HW_FEATURE_TYPE is a value that identifies the hardware feature type @@ -354,38 +371,38 @@ typedef CK_ULONG CK_KEY_TYPE; #define CKK_ECDSA 0x00000003UL /* Deprecated */ #define CKK_EC 0x00000003UL #define CKK_X9_42_DH 0x00000004UL -#define CKK_KEA 0x00000005UL +#define CKK_KEA 0x00000005UL /* Historical */ #define CKK_GENERIC_SECRET 0x00000010UL -#define CKK_RC2 0x00000011UL -#define CKK_RC4 0x00000012UL -#define CKK_DES 0x00000013UL +#define CKK_RC2 0x00000011UL /* Historical */ +#define CKK_RC4 0x00000012UL /* Historical */ +#define CKK_DES 0x00000013UL /* Historical */ #define CKK_DES2 0x00000014UL #define CKK_DES3 0x00000015UL -#define CKK_CAST 0x00000016UL -#define CKK_CAST3 0x00000017UL +#define CKK_CAST 0x00000016UL /* Historical */ +#define CKK_CAST3 0x00000017UL /* Historical */ #define CKK_CAST5 0x00000018UL /* Deprecated */ -#define CKK_CAST128 0x00000018UL -#define CKK_RC5 0x00000019UL -#define CKK_IDEA 0x0000001AUL -#define CKK_SKIPJACK 0x0000001BUL -#define CKK_BATON 0x0000001CUL -#define CKK_JUNIPER 0x0000001DUL -#define CKK_CDMF 0x0000001EUL +#define CKK_CAST128 0x00000018UL /* Historical */ +#define CKK_RC5 0x00000019UL /* Historical */ +#define CKK_IDEA 0x0000001AUL /* Historical */ +#define CKK_SKIPJACK 0x0000001BUL /* Historical */ +#define CKK_BATON 0x0000001CUL /* Historical */ +#define CKK_JUNIPER 0x0000001DUL /* Historical */ +#define CKK_CDMF 0x0000001EUL /* Historical */ #define CKK_AES 0x0000001FUL #define CKK_BLOWFISH 0x00000020UL #define CKK_TWOFISH 0x00000021UL #define CKK_SECURID 0x00000022UL -#define CKK_HOTP 0x00000023UL -#define CKK_ACTI 0x00000024UL +#define CKK_HOTP 0x00000023UL /* Historical */ +#define CKK_ACTI 0x00000024UL /* Historical */ #define CKK_CAMELLIA 0x00000025UL #define CKK_ARIA 0x00000026UL /* the following definitions were added in the 2.30 header file, * but never defined in the spec. */ -#define CKK_MD5_HMAC 0x00000027UL +#define CKK_MD5_HMAC 0x00000027UL /* Historical */ #define CKK_SHA_1_HMAC 0x00000028UL -#define CKK_RIPEMD128_HMAC 0x00000029UL -#define CKK_RIPEMD160_HMAC 0x0000002AUL +#define CKK_RIPEMD128_HMAC 0x00000029UL /* Historical */ +#define CKK_RIPEMD160_HMAC 0x0000002AUL /* Historical */ #define CKK_SHA256_HMAC 0x0000002BUL #define CKK_SHA384_HMAC 0x0000002CUL #define CKK_SHA512_HMAC 0x0000002DUL @@ -417,6 +434,13 @@ typedef CK_ULONG CK_KEY_TYPE; #define CKK_SHA512_T_HMAC 0x00000045UL #define CKK_HSS 0x00000046UL +#define CKK_XMSS 0x00000047UL +#define CKK_XMSSMT 0x00000048UL +#define CKK_ML_KEM 0x00000049UL +#define CKK_ML_DSA 0x0000004aUL +#define CKK_SLH_DSA 0x0000004bUL + + #define CKK_VENDOR_DEFINED 0x80000000UL @@ -615,6 +639,39 @@ typedef CK_ULONG CK_ATTRIBUTE_TYPE; #define CKA_HSS_LMS_TYPES 0x0000061aUL #define CKA_HSS_LMOTS_TYPES 0x0000061bUL #define CKA_HSS_KEYS_REMAINING 0x0000061cUL +/* new post-quantum (general) */ +#define CKA_PARAMETER_SET 0x0000061dUL +/* validation objects */ +#define CKA_OBJECT_VALIDATION_FLAGS 0x0000061eUL +#define CKA_VALIDATION_TYPE 0x0000061fUL +#define CKA_VALIDATION_VERSION 0x00000620UL +#define CKA_VALIDATION_LEVEL 0x00000621UL +#define CKA_VALIDATION_MODULE_ID 0x00000622UL +#define CKA_VALIDATION_FLAG 0x00000623UL +#define CKA_VALIDATION_AUTHORITY_TYPE 0x00000624UL +#define CKA_VALIDATION_COUNTRY 0x00000625UL +#define CKA_VALIDATION_CERTIFICATE_IDENTIFIER 0x00000626UL +#define CKA_VALIDATION_CERTIFICATE_URI 0x00000627UL +#define CKA_VALIDATION_VENDOR_URI 0x00000628UL +#define CKA_VALIDATION_PROFILE 0x00000629UL +/* KEM */ +#define CKA_ENCAPSULATE_TEMPLATE 0x0000062aUL +#define CKA_DECAPSULATE_TEMPLATE 0x0000062bUL +/* trust objects */ +#define CKA_TRUST_SERVER_AUTH 0x0000062cUL +#define CKA_TRUST_CLIENT_AUTH 0x0000062dUL +#define CKA_TRUST_CODE_SIGNING 0x0000062eUL +#define CKA_TRUST_EMAIL_PROTECTION 0x0000062fUL +#define CKA_TRUST_IPSEC_IKE 0x00000630UL +#define CKA_TRUST_TIME_STAMPING 0x00000631UL +#define CKA_TRUST_OCSP_SIGNING 0x00000632UL +#define CKA_ENCAPSULATE 0x00000633UL +#define CKA_DECAPSULATE 0x00000634UL +#define CKA_HASH_OF_CERTIFICATE 0x00000635UL +/* linking pubic and private keys */ +#define CKA_PUBLIC_CRC64_VALUE 0x00000636UL +/* new post-quantum (general) */ +#define CKA_SEED 0x00000637UL #define CKA_VENDOR_DEFINED 0x80000000UL @@ -622,18 +679,18 @@ typedef CK_ULONG CK_ATTRIBUTE_TYPE; * and value of an attribute */ typedef struct CK_ATTRIBUTE { - CK_ATTRIBUTE_TYPE type; - CK_VOID_PTR pValue; - CK_ULONG ulValueLen; /* in bytes */ + CK_ATTRIBUTE_TYPE type; + CK_VOID_PTR pValue; + CK_ULONG ulValueLen; /* in bytes */ } CK_ATTRIBUTE; typedef CK_ATTRIBUTE CK_PTR CK_ATTRIBUTE_PTR; /* CK_DATE is a structure that defines a date */ typedef struct CK_DATE{ - CK_CHAR year[4]; /* the year ("1900" - "9999") */ - CK_CHAR month[2]; /* the month ("01" - "12") */ - CK_CHAR day[2]; /* the day ("01" - "31") */ + CK_CHAR year[4]; /* the year ("1900" - "9999") */ + CK_CHAR month[2]; /* the month ("01" - "12") */ + CK_CHAR day[2]; /* the day ("01" - "31") */ } CK_DATE; @@ -715,23 +772,23 @@ typedef CK_ULONG CK_MECHANISM_TYPE; #define CKM_SHA3_224_RSA_PKCS 0x00000066UL #define CKM_SHA3_224_RSA_PKCS_PSS 0x00000067UL -#define CKM_RC2_KEY_GEN 0x00000100UL -#define CKM_RC2_ECB 0x00000101UL -#define CKM_RC2_CBC 0x00000102UL -#define CKM_RC2_MAC 0x00000103UL +#define CKM_RC2_KEY_GEN 0x00000100UL /* Historical */ +#define CKM_RC2_ECB 0x00000101UL /* Historical */ +#define CKM_RC2_CBC 0x00000102UL /* Historical */ +#define CKM_RC2_MAC 0x00000103UL /* Historical */ -#define CKM_RC2_MAC_GENERAL 0x00000104UL -#define CKM_RC2_CBC_PAD 0x00000105UL +#define CKM_RC2_MAC_GENERAL 0x00000104UL /* Historical */ +#define CKM_RC2_CBC_PAD 0x00000105UL /* Historical */ -#define CKM_RC4_KEY_GEN 0x00000110UL -#define CKM_RC4 0x00000111UL -#define CKM_DES_KEY_GEN 0x00000120UL -#define CKM_DES_ECB 0x00000121UL -#define CKM_DES_CBC 0x00000122UL -#define CKM_DES_MAC 0x00000123UL +#define CKM_RC4_KEY_GEN 0x00000110UL /* Historical */ +#define CKM_RC4 0x00000111UL /* Historical */ +#define CKM_DES_KEY_GEN 0x00000120UL /* Historical */ +#define CKM_DES_ECB 0x00000121UL /* Historical */ +#define CKM_DES_CBC 0x00000122UL /* Historical */ +#define CKM_DES_MAC 0x00000123UL /* Historical */ -#define CKM_DES_MAC_GENERAL 0x00000124UL -#define CKM_DES_CBC_PAD 0x00000125UL +#define CKM_DES_MAC_GENERAL 0x00000124UL /* Historical */ +#define CKM_DES_CBC_PAD 0x00000125UL /* Historical */ #define CKM_DES2_KEY_GEN 0x00000130UL #define CKM_DES3_KEY_GEN 0x00000131UL @@ -743,39 +800,39 @@ typedef CK_ULONG CK_MECHANISM_TYPE; #define CKM_DES3_CBC_PAD 0x00000136UL #define CKM_DES3_CMAC_GENERAL 0x00000137UL #define CKM_DES3_CMAC 0x00000138UL -#define CKM_CDMF_KEY_GEN 0x00000140UL -#define CKM_CDMF_ECB 0x00000141UL -#define CKM_CDMF_CBC 0x00000142UL -#define CKM_CDMF_MAC 0x00000143UL -#define CKM_CDMF_MAC_GENERAL 0x00000144UL -#define CKM_CDMF_CBC_PAD 0x00000145UL +#define CKM_CDMF_KEY_GEN 0x00000140UL /* Historical */ +#define CKM_CDMF_ECB 0x00000141UL /* Historical */ +#define CKM_CDMF_CBC 0x00000142UL /* Historical */ +#define CKM_CDMF_MAC 0x00000143UL /* Historical */ +#define CKM_CDMF_MAC_GENERAL 0x00000144UL /* Historical */ +#define CKM_CDMF_CBC_PAD 0x00000145UL /* Historical */ #define CKM_DES_OFB64 0x00000150UL #define CKM_DES_OFB8 0x00000151UL #define CKM_DES_CFB64 0x00000152UL #define CKM_DES_CFB8 0x00000153UL -#define CKM_MD2 0x00000200UL +#define CKM_MD2 0x00000200UL /* Historical */ -#define CKM_MD2_HMAC 0x00000201UL -#define CKM_MD2_HMAC_GENERAL 0x00000202UL +#define CKM_MD2_HMAC 0x00000201UL /* Historical */ +#define CKM_MD2_HMAC_GENERAL 0x00000202UL /* Historical */ -#define CKM_MD5 0x00000210UL +#define CKM_MD5 0x00000210UL /* Historical */ -#define CKM_MD5_HMAC 0x00000211UL -#define CKM_MD5_HMAC_GENERAL 0x00000212UL +#define CKM_MD5_HMAC 0x00000211UL /* Historical */ +#define CKM_MD5_HMAC_GENERAL 0x00000212UL /* Historical */ #define CKM_SHA_1 0x00000220UL #define CKM_SHA_1_HMAC 0x00000221UL #define CKM_SHA_1_HMAC_GENERAL 0x00000222UL -#define CKM_RIPEMD128 0x00000230UL -#define CKM_RIPEMD128_HMAC 0x00000231UL -#define CKM_RIPEMD128_HMAC_GENERAL 0x00000232UL -#define CKM_RIPEMD160 0x00000240UL -#define CKM_RIPEMD160_HMAC 0x00000241UL -#define CKM_RIPEMD160_HMAC_GENERAL 0x00000242UL +#define CKM_RIPEMD128 0x00000230UL /* Historical */ +#define CKM_RIPEMD128_HMAC 0x00000231UL /* Historical */ +#define CKM_RIPEMD128_HMAC_GENERAL 0x00000232UL /* Historical */ +#define CKM_RIPEMD160 0x00000240UL /* Historical */ +#define CKM_RIPEMD160_HMAC 0x00000241UL /* Historical */ +#define CKM_RIPEMD160_HMAC_GENERAL 0x00000242UL /* Historical */ #define CKM_SHA256 0x00000250UL #define CKM_SHA256_HMAC 0x00000251UL @@ -814,43 +871,43 @@ typedef CK_ULONG CK_MECHANISM_TYPE; #define CKM_SHA3_512_KEY_GEN 0x000002d3UL -#define CKM_CAST_KEY_GEN 0x00000300UL -#define CKM_CAST_ECB 0x00000301UL -#define CKM_CAST_CBC 0x00000302UL -#define CKM_CAST_MAC 0x00000303UL -#define CKM_CAST_MAC_GENERAL 0x00000304UL -#define CKM_CAST_CBC_PAD 0x00000305UL -#define CKM_CAST3_KEY_GEN 0x00000310UL -#define CKM_CAST3_ECB 0x00000311UL -#define CKM_CAST3_CBC 0x00000312UL -#define CKM_CAST3_MAC 0x00000313UL -#define CKM_CAST3_MAC_GENERAL 0x00000314UL -#define CKM_CAST3_CBC_PAD 0x00000315UL +#define CKM_CAST_KEY_GEN 0x00000300UL /* Historical */ +#define CKM_CAST_ECB 0x00000301UL /* Historical */ +#define CKM_CAST_CBC 0x00000302UL /* Historical */ +#define CKM_CAST_MAC 0x00000303UL /* Historical */ +#define CKM_CAST_MAC_GENERAL 0x00000304UL /* Historical */ +#define CKM_CAST_CBC_PAD 0x00000305UL /* Historical */ +#define CKM_CAST3_KEY_GEN 0x00000310UL /* Historical */ +#define CKM_CAST3_ECB 0x00000311UL /* Historical */ +#define CKM_CAST3_CBC 0x00000312UL /* Historical */ +#define CKM_CAST3_MAC 0x00000313UL /* Historical */ +#define CKM_CAST3_MAC_GENERAL 0x00000314UL /* Historical */ +#define CKM_CAST3_CBC_PAD 0x00000315UL /* Historical */ /* Note that CAST128 and CAST5 are the same algorithm */ -#define CKM_CAST5_KEY_GEN 0x00000320UL -#define CKM_CAST128_KEY_GEN 0x00000320UL -#define CKM_CAST5_ECB 0x00000321UL -#define CKM_CAST128_ECB 0x00000321UL +#define CKM_CAST5_KEY_GEN 0x00000320UL /* Historical */ +#define CKM_CAST128_KEY_GEN 0x00000320UL /* Historical */ +#define CKM_CAST5_ECB 0x00000321UL /* Historical */ +#define CKM_CAST128_ECB 0x00000321UL /* Historical */ #define CKM_CAST5_CBC 0x00000322UL /* Deprecated */ -#define CKM_CAST128_CBC 0x00000322UL +#define CKM_CAST128_CBC 0x00000322UL /* Historical */ #define CKM_CAST5_MAC 0x00000323UL /* Deprecated */ -#define CKM_CAST128_MAC 0x00000323UL +#define CKM_CAST128_MAC 0x00000323UL /* Historical */ #define CKM_CAST5_MAC_GENERAL 0x00000324UL /* Deprecated */ -#define CKM_CAST128_MAC_GENERAL 0x00000324UL +#define CKM_CAST128_MAC_GENERAL 0x00000324UL /* Historical */ #define CKM_CAST5_CBC_PAD 0x00000325UL /* Deprecated */ -#define CKM_CAST128_CBC_PAD 0x00000325UL -#define CKM_RC5_KEY_GEN 0x00000330UL -#define CKM_RC5_ECB 0x00000331UL -#define CKM_RC5_CBC 0x00000332UL -#define CKM_RC5_MAC 0x00000333UL -#define CKM_RC5_MAC_GENERAL 0x00000334UL -#define CKM_RC5_CBC_PAD 0x00000335UL -#define CKM_IDEA_KEY_GEN 0x00000340UL -#define CKM_IDEA_ECB 0x00000341UL -#define CKM_IDEA_CBC 0x00000342UL -#define CKM_IDEA_MAC 0x00000343UL -#define CKM_IDEA_MAC_GENERAL 0x00000344UL -#define CKM_IDEA_CBC_PAD 0x00000345UL +#define CKM_CAST128_CBC_PAD 0x00000325UL /* Historical */ +#define CKM_RC5_KEY_GEN 0x00000330UL /* Historical */ +#define CKM_RC5_ECB 0x00000331UL /* Historical */ +#define CKM_RC5_CBC 0x00000332UL /* Historical */ +#define CKM_RC5_MAC 0x00000333UL /* Historical */ +#define CKM_RC5_MAC_GENERAL 0x00000334UL /* Historical */ +#define CKM_RC5_CBC_PAD 0x00000335UL /* Historical */ +#define CKM_IDEA_KEY_GEN 0x00000340UL /* Historical */ +#define CKM_IDEA_ECB 0x00000341UL /* Historical */ +#define CKM_IDEA_CBC 0x00000342UL /* Historical */ +#define CKM_IDEA_MAC 0x00000343UL /* Historical */ +#define CKM_IDEA_MAC_GENERAL 0x00000344UL /* Historical */ +#define CKM_IDEA_CBC_PAD 0x00000345UL /* Historical */ #define CKM_GENERIC_SECRET_KEY_GEN 0x00000350UL #define CKM_CONCATENATE_BASE_AND_KEY 0x00000360UL #define CKM_CONCATENATE_BASE_AND_DATA 0x00000362UL @@ -871,8 +928,8 @@ typedef CK_ULONG CK_MECHANISM_TYPE; #define CKM_SSL3_MD5_MAC 0x00000380UL #define CKM_SSL3_SHA1_MAC 0x00000381UL -#define CKM_MD5_KEY_DERIVATION 0x00000390UL -#define CKM_MD2_KEY_DERIVATION 0x00000391UL +#define CKM_MD5_KEY_DERIVATION 0x00000390UL /* Historical */ +#define CKM_MD2_KEY_DERIVATION 0x00000391UL /* Historical */ #define CKM_SHA1_KEY_DERIVATION 0x00000392UL #define CKM_SHA256_KEY_DERIVATION 0x00000393UL @@ -892,16 +949,16 @@ typedef CK_ULONG CK_MECHANISM_TYPE; #define CKM_SHAKE_128_KEY_DERIVE CKM_SHAKE_128_KEY_DERIVATION #define CKM_SHAKE_256_KEY_DERIVE CKM_SHAKE_256_KEY_DERIVATION -#define CKM_PBE_MD2_DES_CBC 0x000003a0UL -#define CKM_PBE_MD5_DES_CBC 0x000003a1UL -#define CKM_PBE_MD5_CAST_CBC 0x000003a2UL -#define CKM_PBE_MD5_CAST3_CBC 0x000003a3UL +#define CKM_PBE_MD2_DES_CBC 0x000003a0UL /* Historical */ +#define CKM_PBE_MD5_DES_CBC 0x000003a1UL /* Historical */ +#define CKM_PBE_MD5_CAST_CBC 0x000003a2UL /* Historical */ +#define CKM_PBE_MD5_CAST3_CBC 0x000003a3UL /* Historical */ #define CKM_PBE_MD5_CAST5_CBC 0x000003a4UL /* Deprecated */ -#define CKM_PBE_MD5_CAST128_CBC 0x000003a4UL +#define CKM_PBE_MD5_CAST128_CBC 0x000003a4UL /* Historical */ #define CKM_PBE_SHA1_CAST5_CBC 0x000003a5UL /* Deprecated */ -#define CKM_PBE_SHA1_CAST128_CBC 0x000003a5UL -#define CKM_PBE_SHA1_RC4_128 0x000003a6UL -#define CKM_PBE_SHA1_RC4_40 0x000003a7UL +#define CKM_PBE_SHA1_CAST128_CBC 0x000003a5UL /* Historical */ +#define CKM_PBE_SHA1_RC4_128 0x000003a6UL /* Historical */ +#define CKM_PBE_SHA1_RC4_40 0x000003a7UL /* Historical */ #define CKM_PBE_SHA1_DES3_EDE_CBC 0x000003a8UL #define CKM_PBE_SHA1_DES2_EDE_CBC 0x000003a9UL #define CKM_PBE_SHA1_RC2_128_CBC 0x000003aaUL @@ -945,7 +1002,7 @@ typedef CK_ULONG CK_MECHANISM_TYPE; #define CKM_CAMELLIA_CBC_PAD 0x00000555UL #define CKM_CAMELLIA_ECB_ENCRYPT_DATA 0x00000556UL #define CKM_CAMELLIA_CBC_ENCRYPT_DATA 0x00000557UL -#define CKM_CAMELLIA_CTR 0x00000558UL +#define CKM_CAMELLIA_CTR 0x00000558UL /* Historical */ #define CKM_ARIA_KEY_GEN 0x00000560UL #define CKM_ARIA_ECB 0x00000561UL @@ -965,28 +1022,28 @@ typedef CK_ULONG CK_MECHANISM_TYPE; #define CKM_SEED_ECB_ENCRYPT_DATA 0x00000656UL #define CKM_SEED_CBC_ENCRYPT_DATA 0x00000657UL -#define CKM_SKIPJACK_KEY_GEN 0x00001000UL -#define CKM_SKIPJACK_ECB64 0x00001001UL -#define CKM_SKIPJACK_CBC64 0x00001002UL -#define CKM_SKIPJACK_OFB64 0x00001003UL -#define CKM_SKIPJACK_CFB64 0x00001004UL -#define CKM_SKIPJACK_CFB32 0x00001005UL -#define CKM_SKIPJACK_CFB16 0x00001006UL -#define CKM_SKIPJACK_CFB8 0x00001007UL -#define CKM_SKIPJACK_WRAP 0x00001008UL -#define CKM_SKIPJACK_PRIVATE_WRAP 0x00001009UL -#define CKM_SKIPJACK_RELAYX 0x0000100aUL -#define CKM_KEA_KEY_PAIR_GEN 0x00001010UL -#define CKM_KEA_KEY_DERIVE 0x00001011UL -#define CKM_KEA_DERIVE 0x00001012UL -#define CKM_FORTEZZA_TIMESTAMP 0x00001020UL -#define CKM_BATON_KEY_GEN 0x00001030UL -#define CKM_BATON_ECB128 0x00001031UL -#define CKM_BATON_ECB96 0x00001032UL -#define CKM_BATON_CBC128 0x00001033UL -#define CKM_BATON_COUNTER 0x00001034UL -#define CKM_BATON_SHUFFLE 0x00001035UL -#define CKM_BATON_WRAP 0x00001036UL +#define CKM_SKIPJACK_KEY_GEN 0x00001000UL /* Historical */ +#define CKM_SKIPJACK_ECB64 0x00001001UL /* Historical */ +#define CKM_SKIPJACK_CBC64 0x00001002UL /* Historical */ +#define CKM_SKIPJACK_OFB64 0x00001003UL /* Historical */ +#define CKM_SKIPJACK_CFB64 0x00001004UL /* Historical */ +#define CKM_SKIPJACK_CFB32 0x00001005UL /* Historical */ +#define CKM_SKIPJACK_CFB16 0x00001006UL /* Historical */ +#define CKM_SKIPJACK_CFB8 0x00001007UL /* Historical */ +#define CKM_SKIPJACK_WRAP 0x00001008UL /* Historical */ +#define CKM_SKIPJACK_PRIVATE_WRAP 0x00001009UL /* Historical */ +#define CKM_SKIPJACK_RELAYX 0x0000100aUL /* Historical */ +#define CKM_KEA_KEY_PAIR_GEN 0x00001010UL /* Historical */ +#define CKM_KEA_KEY_DERIVE 0x00001011UL /* Historical */ +#define CKM_KEA_DERIVE 0x00001012UL /* Historical */ +#define CKM_FORTEZZA_TIMESTAMP 0x00001020UL /* Historical */ +#define CKM_BATON_KEY_GEN 0x00001030UL /* Historical */ +#define CKM_BATON_ECB128 0x00001031UL /* Historical */ +#define CKM_BATON_ECB96 0x00001032UL /* Historical */ +#define CKM_BATON_CBC128 0x00001033UL /* Historical */ +#define CKM_BATON_COUNTER 0x00001034UL /* Historical */ +#define CKM_BATON_SHUFFLE 0x00001035UL /* Historical */ +#define CKM_BATON_WRAP 0x00001036UL /* Historical */ #define CKM_ECDSA_KEY_PAIR_GEN 0x00001040UL /* Deprecated */ #define CKM_EC_KEY_PAIR_GEN 0x00001040UL @@ -1006,12 +1063,12 @@ typedef CK_ULONG CK_MECHANISM_TYPE; #define CKM_ECDH_AES_KEY_WRAP 0x00001053UL #define CKM_RSA_AES_KEY_WRAP 0x00001054UL -#define CKM_JUNIPER_KEY_GEN 0x00001060UL -#define CKM_JUNIPER_ECB128 0x00001061UL -#define CKM_JUNIPER_CBC128 0x00001062UL -#define CKM_JUNIPER_COUNTER 0x00001063UL -#define CKM_JUNIPER_SHUFFLE 0x00001064UL -#define CKM_JUNIPER_WRAP 0x00001065UL +#define CKM_JUNIPER_KEY_GEN 0x00001060UL /* Historical */ +#define CKM_JUNIPER_ECB128 0x00001061UL /* Historical */ +#define CKM_JUNIPER_CBC128 0x00001062UL /* Historical */ +#define CKM_JUNIPER_COUNTER 0x00001063UL /* Historical */ +#define CKM_JUNIPER_SHUFFLE 0x00001064UL /* Historical */ +#define CKM_JUNIPER_WRAP 0x00001065UL /* Historical */ #define CKM_FASTHASH 0x00001070UL #define CKM_AES_XTS 0x00001071UL @@ -1067,7 +1124,7 @@ typedef CK_ULONG CK_MECHANISM_TYPE; #define CKM_DH_PKCS_PARAMETER_GEN 0x00002001UL #define CKM_X9_42_DH_PARAMETER_GEN 0x00002002UL #define CKM_DSA_PROBABILISTIC_PARAMETER_GEN 0x00002003UL -#define CKM_DSA_PROBABLISTIC_PARAMETER_GEN CKM_DSA_PROBABILISTIC_PARAMETER_GEN +#define CKM_DSA_PROBABLISTIC_PARAMETER_GEN CKM_DSA_PROBABILISTIC_PARAMETER_GEN /* Depricated */ #define CKM_DSA_SHAWE_TAYLOR_PARAMETER_GEN 0x00002004UL #define CKM_DSA_FIPS_G_GEN 0x00002005UL @@ -1147,6 +1204,48 @@ typedef CK_ULONG CK_MECHANISM_TYPE; #define CKM_HSS_KEY_PAIR_GEN 0x00004032UL #define CKM_HSS 0x00004033UL +#define CKM_XMSS_KEY_PAIR_GEN 0x00004034UL +#define CKM_XMSSMT_KEY_PAIR_GEN 0x00004035UL +#define CKM_XMSS 0x00004036UL +#define CKM_XMSSMT 0x00004037UL + +#define CKM_ECDH_X_AES_KEY_WRAP 0x00004038UL +#define CKM_ECDH_COF_AES_KEY_WRAP 0x00004039UL +#define CKM_PUB_KEY_FROM_PRIV_KEY 0x0000403aUL + +#define CKM_ML_KEM_KEY_PAIR_GEN 0x0000000fUL +#define CKM_ML_KEM 0x00000017UL + +#define CKM_ML_DSA_KEY_PAIR_GEN 0x0000001cUL +#define CKM_ML_DSA 0x0000001dUL +#define CKM_HASH_ML_DSA 0x0000001fUL +#define CKM_HASH_ML_DSA_SHA224 0x00000023UL +#define CKM_HASH_ML_DSA_SHA256 0x00000024UL +#define CKM_HASH_ML_DSA_SHA384 0x00000025UL +#define CKM_HASH_ML_DSA_SHA512 0x00000026UL +#define CKM_HASH_ML_DSA_SHA3_224 0x00000027UL +#define CKM_HASH_ML_DSA_SHA3_256 0x00000028UL +#define CKM_HASH_ML_DSA_SHA3_384 0x00000029UL +#define CKM_HASH_ML_DSA_SHA3_512 0x0000002aUL +#define CKM_HASH_ML_DSA_SHAKE128 0x0000002bUL +#define CKM_HASH_ML_DSA_SHAKE256 0x0000002cUL + +#define CKM_SLH_DSA_KEY_PAIR_GEN 0x0000002dUL +#define CKM_SLH_DSA 0x0000002eUL +#define CKM_HASH_SLH_DSA 0x00000034UL +#define CKM_HASH_SLH_DSA_SHA224 0x00000036UL +#define CKM_HASH_SLH_DSA_SHA256 0x00000037UL +#define CKM_HASH_SLH_DSA_SHA384 0x00000038UL +#define CKM_HASH_SLH_DSA_SHA512 0x00000039UL +#define CKM_HASH_SLH_DSA_SHA3_224 0x0000003aUL +#define CKM_HASH_SLH_DSA_SHA3_256 0x0000003bUL +#define CKM_HASH_SLH_DSA_SHA3_384 0x0000003cUL +#define CKM_HASH_SLH_DSA_SHA3_512 0x0000003dUL +#define CKM_HASH_SLH_DSA_SHAKE128 0x0000003eUL +#define CKM_HASH_SLH_DSA_SHAKE256 0x0000003fUL + +#define CKM_TLS12_EXTENDED_MASTER_KEY_DERIVE 0x00000056UL +#define CKM_TLS12_EXTENDED_MASTER_KEY_DERIVE_DH 0x00000057UL #define CKM_VENDOR_DEFINED 0x80000000UL @@ -1157,9 +1256,9 @@ typedef CK_MECHANISM_TYPE CK_PTR CK_MECHANISM_TYPE_PTR; * mechanism */ typedef struct CK_MECHANISM { - CK_MECHANISM_TYPE mechanism; - CK_VOID_PTR pParameter; - CK_ULONG ulParameterLen; /* in bytes */ + CK_MECHANISM_TYPE mechanism; + CK_VOID_PTR pParameter; + CK_ULONG ulParameterLen; /* in bytes */ } CK_MECHANISM; typedef CK_MECHANISM CK_PTR CK_MECHANISM_PTR; @@ -1169,9 +1268,9 @@ typedef CK_MECHANISM CK_PTR CK_MECHANISM_PTR; * mechanism */ typedef struct CK_MECHANISM_INFO { - CK_ULONG ulMinKeySize; - CK_ULONG ulMaxKeySize; - CK_FLAGS flags; + CK_ULONG ulMinKeySize; + CK_ULONG ulMaxKeySize; + CK_FLAGS flags; } CK_MECHANISM_INFO; /* The flags are defined as follows: @@ -1212,6 +1311,9 @@ typedef struct CK_MECHANISM_INFO { #define CKF_EC_COMPRESS 0x02000000UL #define CKF_EC_CURVENAME 0x04000000UL +#define CKF_ENCAPSULATE 0x10000000UL +#define CKF_DECAPSULATE 0x20000000UL + #define CKF_EXTENSION 0x80000000UL typedef CK_MECHANISM_INFO CK_PTR CK_MECHANISM_INFO_PTR; @@ -1345,14 +1447,21 @@ typedef CK_ULONG CK_RV; #define CKR_OPERATION_CANCEL_FAILED 0x00000202UL #define CKR_KEY_EXHAUSTED 0x00000203UL +#define CKR_PENDING 0x00000204UL +#define CKR_SESSION_ASYNC_NOT_SUPPORTED 0x00000205UL +#define CKR_SEED_RANDOM_REQUIRED 0x00000206UL +#define CKR_OPERATION_NOT_VALIDATED 0x00000207UL +#define CKR_TOKEN_NOT_INITIALIZED 0x00000208UL +#define CKR_PARAMETER_SET_NOT_SUPPORTED 0x00000209UL + #define CKR_VENDOR_DEFINED 0x80000000UL /* CK_NOTIFY is an application callback that processes events */ typedef CK_CALLBACK_FUNCTION(CK_RV, CK_NOTIFY)( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_NOTIFICATION event, - CK_VOID_PTR pApplication /* passed to C_OpenSession */ + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_NOTIFICATION event, + CK_VOID_PTR pApplication /* passed to C_OpenSession */ ); @@ -1362,17 +1471,20 @@ typedef CK_CALLBACK_FUNCTION(CK_RV, CK_NOTIFY)( */ typedef struct CK_FUNCTION_LIST CK_FUNCTION_LIST; typedef struct CK_FUNCTION_LIST_3_0 CK_FUNCTION_LIST_3_0; +typedef struct CK_FUNCTION_LIST_3_2 CK_FUNCTION_LIST_3_2; typedef CK_FUNCTION_LIST CK_PTR CK_FUNCTION_LIST_PTR; typedef CK_FUNCTION_LIST_3_0 CK_PTR CK_FUNCTION_LIST_3_0_PTR; +typedef CK_FUNCTION_LIST_3_2 CK_PTR CK_FUNCTION_LIST_3_2_PTR; typedef CK_FUNCTION_LIST_PTR CK_PTR CK_FUNCTION_LIST_PTR_PTR; typedef CK_FUNCTION_LIST_3_0_PTR CK_PTR CK_FUNCTION_LIST_3_0_PTR_PTR; +typedef CK_FUNCTION_LIST_3_2_PTR CK_PTR CK_FUNCTION_LIST_3_2_PTR_PTR; typedef struct CK_INTERFACE { - CK_CHAR *pInterfaceName; - CK_VOID_PTR pFunctionList; - CK_FLAGS flags; + CK_UTF8CHAR_PTR pInterfaceName; + CK_VOID_PTR pFunctionList; + CK_FLAGS flags; } CK_INTERFACE; typedef CK_INTERFACE CK_PTR CK_INTERFACE_PTR; @@ -1385,7 +1497,7 @@ typedef CK_INTERFACE_PTR CK_PTR CK_INTERFACE_PTR_PTR; * mutex object */ typedef CK_CALLBACK_FUNCTION(CK_RV, CK_CREATEMUTEX)( - CK_VOID_PTR_PTR ppMutex /* location to receive ptr to mutex */ + CK_VOID_PTR_PTR ppMutex /* location to receive ptr to mutex */ ); @@ -1393,13 +1505,13 @@ typedef CK_CALLBACK_FUNCTION(CK_RV, CK_CREATEMUTEX)( * mutex object */ typedef CK_CALLBACK_FUNCTION(CK_RV, CK_DESTROYMUTEX)( - CK_VOID_PTR pMutex /* pointer to mutex */ + CK_VOID_PTR pMutex /* pointer to mutex */ ); /* CK_LOCKMUTEX is an application callback for locking a mutex */ typedef CK_CALLBACK_FUNCTION(CK_RV, CK_LOCKMUTEX)( - CK_VOID_PTR pMutex /* pointer to mutex */ + CK_VOID_PTR pMutex /* pointer to mutex */ ); @@ -1407,7 +1519,7 @@ typedef CK_CALLBACK_FUNCTION(CK_RV, CK_LOCKMUTEX)( * mutex */ typedef CK_CALLBACK_FUNCTION(CK_RV, CK_UNLOCKMUTEX)( - CK_VOID_PTR pMutex /* pointer to mutex */ + CK_VOID_PTR pMutex /* pointer to mutex */ ); /* Get functionlist flags */ @@ -1417,12 +1529,12 @@ typedef CK_CALLBACK_FUNCTION(CK_RV, CK_UNLOCKMUTEX)( * C_Initialize */ typedef struct CK_C_INITIALIZE_ARGS { - CK_CREATEMUTEX CreateMutex; - CK_DESTROYMUTEX DestroyMutex; - CK_LOCKMUTEX LockMutex; - CK_UNLOCKMUTEX UnlockMutex; - CK_FLAGS flags; - CK_VOID_PTR pReserved; + CK_CREATEMUTEX CreateMutex; + CK_DESTROYMUTEX DestroyMutex; + CK_LOCKMUTEX LockMutex; + CK_UNLOCKMUTEX UnlockMutex; + CK_FLAGS flags; + CK_VOID_PTR pReserved; } CK_C_INITIALIZE_ARGS; /* flags: bit flags that provide capabilities of the slot @@ -1476,11 +1588,11 @@ typedef CK_RSA_PKCS_OAEP_SOURCE_TYPE CK_PTR CK_RSA_PKCS_OAEP_SOURCE_TYPE_PTR; * CKM_RSA_PKCS_OAEP mechanism. */ typedef struct CK_RSA_PKCS_OAEP_PARAMS { - CK_MECHANISM_TYPE hashAlg; - CK_RSA_PKCS_MGF_TYPE mgf; - CK_RSA_PKCS_OAEP_SOURCE_TYPE source; - CK_VOID_PTR pSourceData; - CK_ULONG ulSourceDataLen; + CK_MECHANISM_TYPE hashAlg; + CK_RSA_PKCS_MGF_TYPE mgf; + CK_RSA_PKCS_OAEP_SOURCE_TYPE source; + CK_VOID_PTR pSourceData; + CK_ULONG ulSourceDataLen; } CK_RSA_PKCS_OAEP_PARAMS; typedef CK_RSA_PKCS_OAEP_PARAMS CK_PTR CK_RSA_PKCS_OAEP_PARAMS_PTR; @@ -1489,9 +1601,9 @@ typedef CK_RSA_PKCS_OAEP_PARAMS CK_PTR CK_RSA_PKCS_OAEP_PARAMS_PTR; * CKM_RSA_PKCS_PSS mechanism(s). */ typedef struct CK_RSA_PKCS_PSS_PARAMS { - CK_MECHANISM_TYPE hashAlg; - CK_RSA_PKCS_MGF_TYPE mgf; - CK_ULONG sLen; + CK_MECHANISM_TYPE hashAlg; + CK_RSA_PKCS_MGF_TYPE mgf; + CK_ULONG sLen; } CK_RSA_PKCS_PSS_PARAMS; typedef CK_RSA_PKCS_PSS_PARAMS CK_PTR CK_RSA_PKCS_PSS_PARAMS_PTR; @@ -1534,11 +1646,11 @@ typedef CK_EC_KDF_TYPE CK_PTR CK_EC_KDF_TYPE_PTR; * where each party contributes one key pair. */ typedef struct CK_ECDH1_DERIVE_PARAMS { - CK_EC_KDF_TYPE kdf; - CK_ULONG ulSharedDataLen; - CK_BYTE_PTR pSharedData; - CK_ULONG ulPublicDataLen; - CK_BYTE_PTR pPublicData; + CK_EC_KDF_TYPE kdf; + CK_ULONG ulSharedDataLen; + CK_BYTE_PTR pSharedData; + CK_ULONG ulPublicDataLen; + CK_BYTE_PTR pPublicData; } CK_ECDH1_DERIVE_PARAMS; typedef CK_ECDH1_DERIVE_PARAMS CK_PTR CK_ECDH1_DERIVE_PARAMS_PTR; @@ -1548,30 +1660,30 @@ typedef CK_ECDH1_DERIVE_PARAMS CK_PTR CK_ECDH1_DERIVE_PARAMS_PTR; * CKM_ECMQV_DERIVE mechanism, where each party contributes two key pairs. */ typedef struct CK_ECDH2_DERIVE_PARAMS { - CK_EC_KDF_TYPE kdf; - CK_ULONG ulSharedDataLen; - CK_BYTE_PTR pSharedData; - CK_ULONG ulPublicDataLen; - CK_BYTE_PTR pPublicData; - CK_ULONG ulPrivateDataLen; - CK_OBJECT_HANDLE hPrivateData; - CK_ULONG ulPublicDataLen2; - CK_BYTE_PTR pPublicData2; + CK_EC_KDF_TYPE kdf; + CK_ULONG ulSharedDataLen; + CK_BYTE_PTR pSharedData; + CK_ULONG ulPublicDataLen; + CK_BYTE_PTR pPublicData; + CK_ULONG ulPrivateDataLen; + CK_OBJECT_HANDLE hPrivateData; + CK_ULONG ulPublicDataLen2; + CK_BYTE_PTR pPublicData2; } CK_ECDH2_DERIVE_PARAMS; typedef CK_ECDH2_DERIVE_PARAMS CK_PTR CK_ECDH2_DERIVE_PARAMS_PTR; typedef struct CK_ECMQV_DERIVE_PARAMS { - CK_EC_KDF_TYPE kdf; - CK_ULONG ulSharedDataLen; - CK_BYTE_PTR pSharedData; - CK_ULONG ulPublicDataLen; - CK_BYTE_PTR pPublicData; - CK_ULONG ulPrivateDataLen; - CK_OBJECT_HANDLE hPrivateData; - CK_ULONG ulPublicDataLen2; - CK_BYTE_PTR pPublicData2; - CK_OBJECT_HANDLE publicKey; + CK_EC_KDF_TYPE kdf; + CK_ULONG ulSharedDataLen; + CK_BYTE_PTR pSharedData; + CK_ULONG ulPublicDataLen; + CK_BYTE_PTR pPublicData; + CK_ULONG ulPrivateDataLen; + CK_OBJECT_HANDLE hPrivateData; + CK_ULONG ulPublicDataLen2; + CK_BYTE_PTR pPublicData2; + CK_OBJECT_HANDLE publicKey; } CK_ECMQV_DERIVE_PARAMS; typedef CK_ECMQV_DERIVE_PARAMS CK_PTR CK_ECMQV_DERIVE_PARAMS_PTR; @@ -1587,11 +1699,11 @@ typedef CK_X9_42_DH_KDF_TYPE CK_PTR CK_X9_42_DH_KDF_TYPE_PTR; * contributes one key pair */ typedef struct CK_X9_42_DH1_DERIVE_PARAMS { - CK_X9_42_DH_KDF_TYPE kdf; - CK_ULONG ulOtherInfoLen; - CK_BYTE_PTR pOtherInfo; - CK_ULONG ulPublicDataLen; - CK_BYTE_PTR pPublicData; + CK_X9_42_DH_KDF_TYPE kdf; + CK_ULONG ulOtherInfoLen; + CK_BYTE_PTR pOtherInfo; + CK_ULONG ulPublicDataLen; + CK_BYTE_PTR pPublicData; } CK_X9_42_DH1_DERIVE_PARAMS; typedef struct CK_X9_42_DH1_DERIVE_PARAMS CK_PTR CK_X9_42_DH1_DERIVE_PARAMS_PTR; @@ -1601,30 +1713,30 @@ typedef struct CK_X9_42_DH1_DERIVE_PARAMS CK_PTR CK_X9_42_DH1_DERIVE_PARAMS_PTR; * mechanisms, where each party contributes two key pairs */ typedef struct CK_X9_42_DH2_DERIVE_PARAMS { - CK_X9_42_DH_KDF_TYPE kdf; - CK_ULONG ulOtherInfoLen; - CK_BYTE_PTR pOtherInfo; - CK_ULONG ulPublicDataLen; - CK_BYTE_PTR pPublicData; - CK_ULONG ulPrivateDataLen; - CK_OBJECT_HANDLE hPrivateData; - CK_ULONG ulPublicDataLen2; - CK_BYTE_PTR pPublicData2; + CK_X9_42_DH_KDF_TYPE kdf; + CK_ULONG ulOtherInfoLen; + CK_BYTE_PTR pOtherInfo; + CK_ULONG ulPublicDataLen; + CK_BYTE_PTR pPublicData; + CK_ULONG ulPrivateDataLen; + CK_OBJECT_HANDLE hPrivateData; + CK_ULONG ulPublicDataLen2; + CK_BYTE_PTR pPublicData2; } CK_X9_42_DH2_DERIVE_PARAMS; typedef CK_X9_42_DH2_DERIVE_PARAMS CK_PTR CK_X9_42_DH2_DERIVE_PARAMS_PTR; typedef struct CK_X9_42_MQV_DERIVE_PARAMS { - CK_X9_42_DH_KDF_TYPE kdf; - CK_ULONG ulOtherInfoLen; - CK_BYTE_PTR pOtherInfo; - CK_ULONG ulPublicDataLen; - CK_BYTE_PTR pPublicData; - CK_ULONG ulPrivateDataLen; - CK_OBJECT_HANDLE hPrivateData; - CK_ULONG ulPublicDataLen2; - CK_BYTE_PTR pPublicData2; - CK_OBJECT_HANDLE publicKey; + CK_X9_42_DH_KDF_TYPE kdf; + CK_ULONG ulOtherInfoLen; + CK_BYTE_PTR pOtherInfo; + CK_ULONG ulPublicDataLen; + CK_BYTE_PTR pPublicData; + CK_ULONG ulPrivateDataLen; + CK_OBJECT_HANDLE hPrivateData; + CK_ULONG ulPublicDataLen2; + CK_BYTE_PTR pPublicData2; + CK_OBJECT_HANDLE publicKey; } CK_X9_42_MQV_DERIVE_PARAMS; typedef CK_X9_42_MQV_DERIVE_PARAMS CK_PTR CK_X9_42_MQV_DERIVE_PARAMS_PTR; @@ -1633,12 +1745,12 @@ typedef CK_X9_42_MQV_DERIVE_PARAMS CK_PTR CK_X9_42_MQV_DERIVE_PARAMS_PTR; * CKM_KEA_DERIVE mechanism */ typedef struct CK_KEA_DERIVE_PARAMS { - CK_BBOOL isSender; - CK_ULONG ulRandomLen; - CK_BYTE_PTR pRandomA; - CK_BYTE_PTR pRandomB; - CK_ULONG ulPublicDataLen; - CK_BYTE_PTR pPublicData; + CK_BBOOL isSender; + CK_ULONG ulRandomLen; + CK_BYTE_PTR pRandomA; + CK_BYTE_PTR pRandomB; + CK_ULONG ulPublicDataLen; + CK_BYTE_PTR pPublicData; } CK_KEA_DERIVE_PARAMS; typedef CK_KEA_DERIVE_PARAMS CK_PTR CK_KEA_DERIVE_PARAMS_PTR; @@ -1657,8 +1769,8 @@ typedef CK_RC2_PARAMS CK_PTR CK_RC2_PARAMS_PTR; * mechanism */ typedef struct CK_RC2_CBC_PARAMS { - CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */ - CK_BYTE iv[8]; /* IV for CBC mode */ + CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */ + CK_BYTE iv[8]; /* IV for CBC mode */ } CK_RC2_CBC_PARAMS; typedef CK_RC2_CBC_PARAMS CK_PTR CK_RC2_CBC_PARAMS_PTR; @@ -1668,20 +1780,20 @@ typedef CK_RC2_CBC_PARAMS CK_PTR CK_RC2_CBC_PARAMS_PTR; * CKM_RC2_MAC_GENERAL mechanism */ typedef struct CK_RC2_MAC_GENERAL_PARAMS { - CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */ - CK_ULONG ulMacLength; /* Length of MAC in bytes */ + CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */ + CK_ULONG ulMacLength; /* Length of MAC in bytes */ } CK_RC2_MAC_GENERAL_PARAMS; typedef CK_RC2_MAC_GENERAL_PARAMS CK_PTR \ - CK_RC2_MAC_GENERAL_PARAMS_PTR; + CK_RC2_MAC_GENERAL_PARAMS_PTR; /* CK_RC5_PARAMS provides the parameters to the CKM_RC5_ECB and * CKM_RC5_MAC mechanisms */ typedef struct CK_RC5_PARAMS { - CK_ULONG ulWordsize; /* wordsize in bits */ - CK_ULONG ulRounds; /* number of rounds */ + CK_ULONG ulWordsize; /* wordsize in bits */ + CK_ULONG ulRounds; /* number of rounds */ } CK_RC5_PARAMS; typedef CK_RC5_PARAMS CK_PTR CK_RC5_PARAMS_PTR; @@ -1691,10 +1803,10 @@ typedef CK_RC5_PARAMS CK_PTR CK_RC5_PARAMS_PTR; * mechanism */ typedef struct CK_RC5_CBC_PARAMS { - CK_ULONG ulWordsize; /* wordsize in bits */ - CK_ULONG ulRounds; /* number of rounds */ - CK_BYTE_PTR pIv; /* pointer to IV */ - CK_ULONG ulIvLen; /* length of IV in bytes */ + CK_ULONG ulWordsize; /* wordsize in bits */ + CK_ULONG ulRounds; /* number of rounds */ + CK_BYTE_PTR pIv; /* pointer to IV */ + CK_ULONG ulIvLen; /* length of IV in bytes */ } CK_RC5_CBC_PARAMS; typedef CK_RC5_CBC_PARAMS CK_PTR CK_RC5_CBC_PARAMS_PTR; @@ -1704,13 +1816,13 @@ typedef CK_RC5_CBC_PARAMS CK_PTR CK_RC5_CBC_PARAMS_PTR; * CKM_RC5_MAC_GENERAL mechanism */ typedef struct CK_RC5_MAC_GENERAL_PARAMS { - CK_ULONG ulWordsize; /* wordsize in bits */ - CK_ULONG ulRounds; /* number of rounds */ - CK_ULONG ulMacLength; /* Length of MAC in bytes */ + CK_ULONG ulWordsize; /* wordsize in bits */ + CK_ULONG ulRounds; /* number of rounds */ + CK_ULONG ulMacLength; /* Length of MAC in bytes */ } CK_RC5_MAC_GENERAL_PARAMS; typedef CK_RC5_MAC_GENERAL_PARAMS CK_PTR \ - CK_RC5_MAC_GENERAL_PARAMS_PTR; + CK_RC5_MAC_GENERAL_PARAMS_PTR; /* CK_MAC_GENERAL_PARAMS provides the parameters to most block * ciphers' MAC_GENERAL mechanisms. Its value is the length of @@ -1721,17 +1833,17 @@ typedef CK_ULONG CK_MAC_GENERAL_PARAMS; typedef CK_MAC_GENERAL_PARAMS CK_PTR CK_MAC_GENERAL_PARAMS_PTR; typedef struct CK_DES_CBC_ENCRYPT_DATA_PARAMS { - CK_BYTE iv[8]; - CK_BYTE_PTR pData; - CK_ULONG length; + CK_BYTE iv[8]; + CK_BYTE_PTR pData; + CK_ULONG length; } CK_DES_CBC_ENCRYPT_DATA_PARAMS; typedef CK_DES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_DES_CBC_ENCRYPT_DATA_PARAMS_PTR; typedef struct CK_AES_CBC_ENCRYPT_DATA_PARAMS { - CK_BYTE iv[16]; - CK_BYTE_PTR pData; - CK_ULONG length; + CK_BYTE iv[16]; + CK_BYTE_PTR pData; + CK_ULONG length; } CK_AES_CBC_ENCRYPT_DATA_PARAMS; typedef CK_AES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR; @@ -1740,54 +1852,54 @@ typedef CK_AES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR * CKM_SKIPJACK_PRIVATE_WRAP mechanism */ typedef struct CK_SKIPJACK_PRIVATE_WRAP_PARAMS { - CK_ULONG ulPasswordLen; - CK_BYTE_PTR pPassword; - CK_ULONG ulPublicDataLen; - CK_BYTE_PTR pPublicData; - CK_ULONG ulPAndGLen; - CK_ULONG ulQLen; - CK_ULONG ulRandomLen; - CK_BYTE_PTR pRandomA; - CK_BYTE_PTR pPrimeP; - CK_BYTE_PTR pBaseG; - CK_BYTE_PTR pSubprimeQ; + CK_ULONG ulPasswordLen; + CK_BYTE_PTR pPassword; + CK_ULONG ulPublicDataLen; + CK_BYTE_PTR pPublicData; + CK_ULONG ulPAndGLen; + CK_ULONG ulQLen; + CK_ULONG ulRandomLen; + CK_BYTE_PTR pRandomA; + CK_BYTE_PTR pPrimeP; + CK_BYTE_PTR pBaseG; + CK_BYTE_PTR pSubprimeQ; } CK_SKIPJACK_PRIVATE_WRAP_PARAMS; typedef CK_SKIPJACK_PRIVATE_WRAP_PARAMS CK_PTR \ - CK_SKIPJACK_PRIVATE_WRAP_PARAMS_PTR; + CK_SKIPJACK_PRIVATE_WRAP_PARAMS_PTR; /* CK_SKIPJACK_RELAYX_PARAMS provides the parameters to the * CKM_SKIPJACK_RELAYX mechanism */ typedef struct CK_SKIPJACK_RELAYX_PARAMS { - CK_ULONG ulOldWrappedXLen; - CK_BYTE_PTR pOldWrappedX; - CK_ULONG ulOldPasswordLen; - CK_BYTE_PTR pOldPassword; - CK_ULONG ulOldPublicDataLen; - CK_BYTE_PTR pOldPublicData; - CK_ULONG ulOldRandomLen; - CK_BYTE_PTR pOldRandomA; - CK_ULONG ulNewPasswordLen; - CK_BYTE_PTR pNewPassword; - CK_ULONG ulNewPublicDataLen; - CK_BYTE_PTR pNewPublicData; - CK_ULONG ulNewRandomLen; - CK_BYTE_PTR pNewRandomA; + CK_ULONG ulOldWrappedXLen; + CK_BYTE_PTR pOldWrappedX; + CK_ULONG ulOldPasswordLen; + CK_BYTE_PTR pOldPassword; + CK_ULONG ulOldPublicDataLen; + CK_BYTE_PTR pOldPublicData; + CK_ULONG ulOldRandomLen; + CK_BYTE_PTR pOldRandomA; + CK_ULONG ulNewPasswordLen; + CK_BYTE_PTR pNewPassword; + CK_ULONG ulNewPublicDataLen; + CK_BYTE_PTR pNewPublicData; + CK_ULONG ulNewRandomLen; + CK_BYTE_PTR pNewRandomA; } CK_SKIPJACK_RELAYX_PARAMS; typedef CK_SKIPJACK_RELAYX_PARAMS CK_PTR \ - CK_SKIPJACK_RELAYX_PARAMS_PTR; + CK_SKIPJACK_RELAYX_PARAMS_PTR; typedef struct CK_PBE_PARAMS { - CK_BYTE_PTR pInitVector; - CK_UTF8CHAR_PTR pPassword; - CK_ULONG ulPasswordLen; - CK_BYTE_PTR pSalt; - CK_ULONG ulSaltLen; - CK_ULONG ulIteration; + CK_BYTE_PTR pInitVector; + CK_UTF8CHAR_PTR pPassword; + CK_ULONG ulPasswordLen; + CK_BYTE_PTR pSalt; + CK_ULONG ulSaltLen; + CK_ULONG ulIteration; } CK_PBE_PARAMS; typedef CK_PBE_PARAMS CK_PTR CK_PBE_PARAMS_PTR; @@ -1797,134 +1909,134 @@ typedef CK_PBE_PARAMS CK_PTR CK_PBE_PARAMS_PTR; * CKM_KEY_WRAP_SET_OAEP mechanism */ typedef struct CK_KEY_WRAP_SET_OAEP_PARAMS { - CK_BYTE bBC; /* block contents byte */ - CK_BYTE_PTR pX; /* extra data */ - CK_ULONG ulXLen; /* length of extra data in bytes */ + CK_BYTE bBC; /* block contents byte */ + CK_BYTE_PTR pX; /* extra data */ + CK_ULONG ulXLen; /* length of extra data in bytes */ } CK_KEY_WRAP_SET_OAEP_PARAMS; typedef CK_KEY_WRAP_SET_OAEP_PARAMS CK_PTR CK_KEY_WRAP_SET_OAEP_PARAMS_PTR; typedef struct CK_SSL3_RANDOM_DATA { - CK_BYTE_PTR pClientRandom; - CK_ULONG ulClientRandomLen; - CK_BYTE_PTR pServerRandom; - CK_ULONG ulServerRandomLen; + CK_BYTE_PTR pClientRandom; + CK_ULONG ulClientRandomLen; + CK_BYTE_PTR pServerRandom; + CK_ULONG ulServerRandomLen; } CK_SSL3_RANDOM_DATA; typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS { - CK_SSL3_RANDOM_DATA RandomInfo; - CK_VERSION_PTR pVersion; + CK_SSL3_RANDOM_DATA RandomInfo; + CK_VERSION_PTR pVersion; } CK_SSL3_MASTER_KEY_DERIVE_PARAMS; typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS CK_PTR \ - CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR; + CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR; typedef struct CK_SSL3_KEY_MAT_OUT { - CK_OBJECT_HANDLE hClientMacSecret; - CK_OBJECT_HANDLE hServerMacSecret; - CK_OBJECT_HANDLE hClientKey; - CK_OBJECT_HANDLE hServerKey; - CK_BYTE_PTR pIVClient; - CK_BYTE_PTR pIVServer; + CK_OBJECT_HANDLE hClientMacSecret; + CK_OBJECT_HANDLE hServerMacSecret; + CK_OBJECT_HANDLE hClientKey; + CK_OBJECT_HANDLE hServerKey; + CK_BYTE_PTR pIVClient; + CK_BYTE_PTR pIVServer; } CK_SSL3_KEY_MAT_OUT; typedef CK_SSL3_KEY_MAT_OUT CK_PTR CK_SSL3_KEY_MAT_OUT_PTR; typedef struct CK_SSL3_KEY_MAT_PARAMS { - CK_ULONG ulMacSizeInBits; - CK_ULONG ulKeySizeInBits; - CK_ULONG ulIVSizeInBits; - CK_BBOOL bIsExport; - CK_SSL3_RANDOM_DATA RandomInfo; - CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial; + CK_ULONG ulMacSizeInBits; + CK_ULONG ulKeySizeInBits; + CK_ULONG ulIVSizeInBits; + CK_BBOOL bIsExport; + CK_SSL3_RANDOM_DATA RandomInfo; + CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial; } CK_SSL3_KEY_MAT_PARAMS; typedef CK_SSL3_KEY_MAT_PARAMS CK_PTR CK_SSL3_KEY_MAT_PARAMS_PTR; typedef struct CK_TLS_PRF_PARAMS { - CK_BYTE_PTR pSeed; - CK_ULONG ulSeedLen; - CK_BYTE_PTR pLabel; - CK_ULONG ulLabelLen; - CK_BYTE_PTR pOutput; - CK_ULONG_PTR pulOutputLen; + CK_BYTE_PTR pSeed; + CK_ULONG ulSeedLen; + CK_BYTE_PTR pLabel; + CK_ULONG ulLabelLen; + CK_BYTE_PTR pOutput; + CK_ULONG_PTR pulOutputLen; } CK_TLS_PRF_PARAMS; typedef CK_TLS_PRF_PARAMS CK_PTR CK_TLS_PRF_PARAMS_PTR; typedef struct CK_WTLS_RANDOM_DATA { - CK_BYTE_PTR pClientRandom; - CK_ULONG ulClientRandomLen; - CK_BYTE_PTR pServerRandom; - CK_ULONG ulServerRandomLen; + CK_BYTE_PTR pClientRandom; + CK_ULONG ulClientRandomLen; + CK_BYTE_PTR pServerRandom; + CK_ULONG ulServerRandomLen; } CK_WTLS_RANDOM_DATA; typedef CK_WTLS_RANDOM_DATA CK_PTR CK_WTLS_RANDOM_DATA_PTR; typedef struct CK_WTLS_MASTER_KEY_DERIVE_PARAMS { - CK_MECHANISM_TYPE DigestMechanism; - CK_WTLS_RANDOM_DATA RandomInfo; - CK_BYTE_PTR pVersion; + CK_MECHANISM_TYPE DigestMechanism; + CK_WTLS_RANDOM_DATA RandomInfo; + CK_BYTE_PTR pVersion; } CK_WTLS_MASTER_KEY_DERIVE_PARAMS; typedef CK_WTLS_MASTER_KEY_DERIVE_PARAMS CK_PTR \ - CK_WTLS_MASTER_KEY_DERIVE_PARAMS_PTR; + CK_WTLS_MASTER_KEY_DERIVE_PARAMS_PTR; typedef struct CK_WTLS_PRF_PARAMS { - CK_MECHANISM_TYPE DigestMechanism; - CK_BYTE_PTR pSeed; - CK_ULONG ulSeedLen; - CK_BYTE_PTR pLabel; - CK_ULONG ulLabelLen; - CK_BYTE_PTR pOutput; - CK_ULONG_PTR pulOutputLen; + CK_MECHANISM_TYPE DigestMechanism; + CK_BYTE_PTR pSeed; + CK_ULONG ulSeedLen; + CK_BYTE_PTR pLabel; + CK_ULONG ulLabelLen; + CK_BYTE_PTR pOutput; + CK_ULONG_PTR pulOutputLen; } CK_WTLS_PRF_PARAMS; typedef CK_WTLS_PRF_PARAMS CK_PTR CK_WTLS_PRF_PARAMS_PTR; typedef struct CK_WTLS_KEY_MAT_OUT { - CK_OBJECT_HANDLE hMacSecret; - CK_OBJECT_HANDLE hKey; - CK_BYTE_PTR pIV; + CK_OBJECT_HANDLE hMacSecret; + CK_OBJECT_HANDLE hKey; + CK_BYTE_PTR pIV; } CK_WTLS_KEY_MAT_OUT; typedef CK_WTLS_KEY_MAT_OUT CK_PTR CK_WTLS_KEY_MAT_OUT_PTR; typedef struct CK_WTLS_KEY_MAT_PARAMS { - CK_MECHANISM_TYPE DigestMechanism; - CK_ULONG ulMacSizeInBits; - CK_ULONG ulKeySizeInBits; - CK_ULONG ulIVSizeInBits; - CK_ULONG ulSequenceNumber; - CK_BBOOL bIsExport; - CK_WTLS_RANDOM_DATA RandomInfo; - CK_WTLS_KEY_MAT_OUT_PTR pReturnedKeyMaterial; + CK_MECHANISM_TYPE DigestMechanism; + CK_ULONG ulMacSizeInBits; + CK_ULONG ulKeySizeInBits; + CK_ULONG ulIVSizeInBits; + CK_ULONG ulSequenceNumber; + CK_BBOOL bIsExport; + CK_WTLS_RANDOM_DATA RandomInfo; + CK_WTLS_KEY_MAT_OUT_PTR pReturnedKeyMaterial; } CK_WTLS_KEY_MAT_PARAMS; typedef CK_WTLS_KEY_MAT_PARAMS CK_PTR CK_WTLS_KEY_MAT_PARAMS_PTR; typedef struct CK_CMS_SIG_PARAMS { - CK_OBJECT_HANDLE certificateHandle; - CK_MECHANISM_PTR pSigningMechanism; - CK_MECHANISM_PTR pDigestMechanism; - CK_UTF8CHAR_PTR pContentType; - CK_BYTE_PTR pRequestedAttributes; - CK_ULONG ulRequestedAttributesLen; - CK_BYTE_PTR pRequiredAttributes; - CK_ULONG ulRequiredAttributesLen; + CK_OBJECT_HANDLE certificateHandle; + CK_MECHANISM_PTR pSigningMechanism; + CK_MECHANISM_PTR pDigestMechanism; + CK_UTF8CHAR_PTR pContentType; + CK_BYTE_PTR pRequestedAttributes; + CK_ULONG ulRequestedAttributesLen; + CK_BYTE_PTR pRequiredAttributes; + CK_ULONG ulRequiredAttributesLen; } CK_CMS_SIG_PARAMS; typedef CK_CMS_SIG_PARAMS CK_PTR CK_CMS_SIG_PARAMS_PTR; typedef struct CK_KEY_DERIVATION_STRING_DATA { - CK_BYTE_PTR pData; - CK_ULONG ulLen; + CK_BYTE_PTR pData; + CK_ULONG ulLen; } CK_KEY_DERIVATION_STRING_DATA; typedef CK_KEY_DERIVATION_STRING_DATA CK_PTR \ - CK_KEY_DERIVATION_STRING_DATA_PTR; + CK_KEY_DERIVATION_STRING_DATA_PTR; /* The CK_EXTRACT_PARAMS is used for the @@ -1943,7 +2055,7 @@ typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR; typedef CK_ULONG CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE; typedef CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE CK_PTR \ - CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE_PTR; + CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE_PTR; #define CKP_PKCS5_PBKD2_HMAC_SHA1 0x00000001UL #define CKP_PKCS5_PBKD2_HMAC_GOSTR3411 0x00000002UL @@ -1961,7 +2073,7 @@ typedef CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE CK_PTR \ typedef CK_ULONG CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE; typedef CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE CK_PTR \ - CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE_PTR; + CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE_PTR; /* The following salt value sources are defined in PKCS #5 v2.0. */ #define CKZ_SALT_SPECIFIED 0x00000001UL @@ -1970,15 +2082,15 @@ typedef CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE CK_PTR \ * parameters to the CKM_PKCS5_PBKD2 mechanism. */ typedef struct CK_PKCS5_PBKD2_PARAMS { - CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource; - CK_VOID_PTR pSaltSourceData; - CK_ULONG ulSaltSourceDataLen; - CK_ULONG iterations; - CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf; - CK_VOID_PTR pPrfData; - CK_ULONG ulPrfDataLen; - CK_UTF8CHAR_PTR pPassword; - CK_ULONG_PTR ulPasswordLen; + CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource; + CK_VOID_PTR pSaltSourceData; + CK_ULONG ulSaltSourceDataLen; + CK_ULONG iterations; + CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf; + CK_VOID_PTR pPrfData; + CK_ULONG ulPrfDataLen; + CK_UTF8CHAR_PTR pPassword; + CK_ULONG_PTR ulPasswordLen; } CK_PKCS5_PBKD2_PARAMS; typedef CK_PKCS5_PBKD2_PARAMS CK_PTR CK_PKCS5_PBKD2_PARAMS_PTR; @@ -1988,15 +2100,15 @@ typedef CK_PKCS5_PBKD2_PARAMS CK_PTR CK_PKCS5_PBKD2_PARAMS_PTR; * noting that the ulPasswordLen field is a CK_ULONG and not a CK_ULONG_PTR. */ typedef struct CK_PKCS5_PBKD2_PARAMS2 { - CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource; - CK_VOID_PTR pSaltSourceData; - CK_ULONG ulSaltSourceDataLen; - CK_ULONG iterations; - CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf; - CK_VOID_PTR pPrfData; - CK_ULONG ulPrfDataLen; - CK_UTF8CHAR_PTR pPassword; - CK_ULONG ulPasswordLen; + CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource; + CK_VOID_PTR pSaltSourceData; + CK_ULONG ulSaltSourceDataLen; + CK_ULONG iterations; + CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf; + CK_VOID_PTR pPrfData; + CK_ULONG ulPrfDataLen; + CK_UTF8CHAR_PTR pPassword; + CK_ULONG ulPasswordLen; } CK_PKCS5_PBKD2_PARAMS2; typedef CK_PKCS5_PBKD2_PARAMS2 CK_PTR CK_PKCS5_PBKD2_PARAMS2_PTR; @@ -2006,22 +2118,22 @@ typedef CK_OTP_PARAM_TYPE CK_PARAM_TYPE; /* backward compatibility */ typedef struct CK_OTP_PARAM { CK_OTP_PARAM_TYPE type; - CK_VOID_PTR pValue; - CK_ULONG ulValueLen; + CK_VOID_PTR pValue; + CK_ULONG ulValueLen; } CK_OTP_PARAM; typedef CK_OTP_PARAM CK_PTR CK_OTP_PARAM_PTR; typedef struct CK_OTP_PARAMS { CK_OTP_PARAM_PTR pParams; - CK_ULONG ulCount; + CK_ULONG ulCount; } CK_OTP_PARAMS; typedef CK_OTP_PARAMS CK_PTR CK_OTP_PARAMS_PTR; typedef struct CK_OTP_SIGNATURE_INFO { CK_OTP_PARAM_PTR pParams; - CK_ULONG ulCount; + CK_ULONG ulCount; } CK_OTP_SIGNATURE_INFO; typedef CK_OTP_SIGNATURE_INFO CK_PTR CK_OTP_SIGNATURE_INFO_PTR; @@ -2043,28 +2155,28 @@ typedef CK_OTP_SIGNATURE_INFO CK_PTR CK_OTP_SIGNATURE_INFO_PTR; #define CKF_USER_FRIENDLY_OTP 0x00000020UL typedef struct CK_KIP_PARAMS { - CK_MECHANISM_PTR pMechanism; - CK_OBJECT_HANDLE hKey; - CK_BYTE_PTR pSeed; - CK_ULONG ulSeedLen; + CK_MECHANISM_PTR pMechanism; + CK_OBJECT_HANDLE hKey; + CK_BYTE_PTR pSeed; + CK_ULONG ulSeedLen; } CK_KIP_PARAMS; typedef CK_KIP_PARAMS CK_PTR CK_KIP_PARAMS_PTR; typedef struct CK_AES_CTR_PARAMS { CK_ULONG ulCounterBits; - CK_BYTE cb[16]; + CK_BYTE cb[16]; } CK_AES_CTR_PARAMS; typedef CK_AES_CTR_PARAMS CK_PTR CK_AES_CTR_PARAMS_PTR; typedef struct CK_GCM_PARAMS { - CK_BYTE_PTR pIv; - CK_ULONG ulIvLen; - CK_ULONG ulIvBits; - CK_BYTE_PTR pAAD; - CK_ULONG ulAADLen; - CK_ULONG ulTagBits; + CK_BYTE_PTR pIv; + CK_ULONG ulIvLen; + CK_ULONG ulIvBits; + CK_BYTE_PTR pAAD; + CK_ULONG ulAADLen; + CK_ULONG ulTagBits; } CK_GCM_PARAMS; typedef CK_GCM_PARAMS CK_PTR CK_GCM_PARAMS_PTR; @@ -2077,102 +2189,127 @@ typedef CK_ULONG CK_GENERATOR_FUNCTION; #define CKG_GENERATE_COUNTER_XOR 0x00000004UL typedef struct CK_GCM_MESSAGE_PARAMS { - CK_BYTE_PTR pIv; - CK_ULONG ulIvLen; - CK_ULONG ulIvFixedBits; + CK_BYTE_PTR pIv; + CK_ULONG ulIvLen; + CK_ULONG ulIvFixedBits; CK_GENERATOR_FUNCTION ivGenerator; - CK_BYTE_PTR pTag; - CK_ULONG ulTagBits; + CK_BYTE_PTR pTag; + CK_ULONG ulTagBits; } CK_GCM_MESSAGE_PARAMS; typedef CK_GCM_MESSAGE_PARAMS CK_PTR CK_GCM_MESSAGE_PARAMS_PTR; +typedef struct CK_GCM_WRAP_PARAMS { + CK_BYTE_PTR pIv; + CK_ULONG ulIvLen; + CK_ULONG ulIvFixedBits; + CK_GENERATOR_FUNCTION ivGenerator; + CK_BYTE_PTR pAAD; + CK_ULONG ulAADLen; + CK_ULONG ulTagBits; +} CK_GCM_WRAP_PARAMS; + +typedef CK_GCM_WRAP_PARAMS CK_PTR CK_GCM_WRAP_PARAMS_PTR; + typedef struct CK_CCM_PARAMS { - CK_ULONG ulDataLen; - CK_BYTE_PTR pNonce; - CK_ULONG ulNonceLen; - CK_BYTE_PTR pAAD; - CK_ULONG ulAADLen; - CK_ULONG ulMACLen; + CK_ULONG ulDataLen; + CK_BYTE_PTR pNonce; + CK_ULONG ulNonceLen; + CK_BYTE_PTR pAAD; + CK_ULONG ulAADLen; + CK_ULONG ulMACLen; } CK_CCM_PARAMS; typedef CK_CCM_PARAMS CK_PTR CK_CCM_PARAMS_PTR; typedef struct CK_CCM_MESSAGE_PARAMS { - CK_ULONG ulDataLen; /*plaintext or ciphertext*/ - CK_BYTE_PTR pNonce; - CK_ULONG ulNonceLen; - CK_ULONG ulNonceFixedBits; + CK_ULONG ulDataLen; /*plaintext or ciphertext*/ + CK_BYTE_PTR pNonce; + CK_ULONG ulNonceLen; + CK_ULONG ulNonceFixedBits; CK_GENERATOR_FUNCTION nonceGenerator; - CK_BYTE_PTR pMAC; - CK_ULONG ulMACLen; + CK_BYTE_PTR pMAC; + CK_ULONG ulMACLen; } CK_CCM_MESSAGE_PARAMS; typedef CK_CCM_MESSAGE_PARAMS CK_PTR CK_CCM_MESSAGE_PARAMS_PTR; +typedef struct CK_CCM_WRAP_PARAMS { + CK_ULONG ulDataLen; /*wrappedkey data*/ + CK_BYTE_PTR pNonce; + CK_ULONG ulNonceLen; + CK_ULONG ulNonceFixedBits; + CK_GENERATOR_FUNCTION nonceGenerator; + CK_BYTE_PTR pAAD; + CK_ULONG ulAADLen; + CK_ULONG ulMACLen; +} CK_CCM_WRAP_PARAMS; + +typedef CK_CCM_WRAP_PARAMS CK_PTR CK_CCM_WRAP_PARAMS_PTR; + /* Deprecated. Use CK_GCM_PARAMS */ typedef struct CK_AES_GCM_PARAMS { - CK_BYTE_PTR pIv; - CK_ULONG ulIvLen; - CK_ULONG ulIvBits; - CK_BYTE_PTR pAAD; - CK_ULONG ulAADLen; - CK_ULONG ulTagBits; + CK_BYTE_PTR pIv; + CK_ULONG ulIvLen; + CK_ULONG ulIvBits; + CK_BYTE_PTR pAAD; + CK_ULONG ulAADLen; + CK_ULONG ulTagBits; } CK_AES_GCM_PARAMS; typedef CK_AES_GCM_PARAMS CK_PTR CK_AES_GCM_PARAMS_PTR; /* Deprecated. Use CK_CCM_PARAMS */ typedef struct CK_AES_CCM_PARAMS { - CK_ULONG ulDataLen; - CK_BYTE_PTR pNonce; - CK_ULONG ulNonceLen; - CK_BYTE_PTR pAAD; - CK_ULONG ulAADLen; - CK_ULONG ulMACLen; + CK_ULONG ulDataLen; + CK_BYTE_PTR pNonce; + CK_ULONG ulNonceLen; + CK_BYTE_PTR pAAD; + CK_ULONG ulAADLen; + CK_ULONG ulMACLen; } CK_AES_CCM_PARAMS; typedef CK_AES_CCM_PARAMS CK_PTR CK_AES_CCM_PARAMS_PTR; typedef struct CK_CAMELLIA_CTR_PARAMS { - CK_ULONG ulCounterBits; - CK_BYTE cb[16]; + CK_ULONG ulCounterBits; + CK_BYTE cb[16]; } CK_CAMELLIA_CTR_PARAMS; typedef CK_CAMELLIA_CTR_PARAMS CK_PTR CK_CAMELLIA_CTR_PARAMS_PTR; typedef struct CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS { - CK_BYTE iv[16]; - CK_BYTE_PTR pData; - CK_ULONG length; + CK_BYTE iv[16]; + CK_BYTE_PTR pData; + CK_ULONG length; } CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS; typedef CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR \ - CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS_PTR; + CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS_PTR; typedef struct CK_ARIA_CBC_ENCRYPT_DATA_PARAMS { - CK_BYTE iv[16]; - CK_BYTE_PTR pData; - CK_ULONG length; + CK_BYTE iv[16]; + CK_BYTE_PTR pData; + CK_ULONG length; } CK_ARIA_CBC_ENCRYPT_DATA_PARAMS; typedef CK_ARIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR \ - CK_ARIA_CBC_ENCRYPT_DATA_PARAMS_PTR; + CK_ARIA_CBC_ENCRYPT_DATA_PARAMS_PTR; typedef struct CK_DSA_PARAMETER_GEN_PARAM { - CK_MECHANISM_TYPE hash; - CK_BYTE_PTR pSeed; - CK_ULONG ulSeedLen; - CK_ULONG ulIndex; + CK_MECHANISM_TYPE hash; + CK_BYTE_PTR pSeed; + CK_ULONG ulSeedLen; + CK_ULONG ulIndex; } CK_DSA_PARAMETER_GEN_PARAM; typedef CK_DSA_PARAMETER_GEN_PARAM CK_PTR CK_DSA_PARAMETER_GEN_PARAM_PTR; typedef struct CK_ECDH_AES_KEY_WRAP_PARAMS { - CK_ULONG ulAESKeyBits; - CK_EC_KDF_TYPE kdf; - CK_ULONG ulSharedDataLen; - CK_BYTE_PTR pSharedData; + CK_ULONG ulAESKeyBits; + CK_EC_KDF_TYPE kdf; + CK_ULONG ulSharedDataLen; + CK_BYTE_PTR pSharedData; } CK_ECDH_AES_KEY_WRAP_PARAMS; typedef CK_ECDH_AES_KEY_WRAP_PARAMS CK_PTR CK_ECDH_AES_KEY_WRAP_PARAMS_PTR; @@ -2182,80 +2319,90 @@ typedef CK_ULONG CK_JAVA_MIDP_SECURITY_DOMAIN; typedef CK_ULONG CK_CERTIFICATE_CATEGORY; typedef struct CK_RSA_AES_KEY_WRAP_PARAMS { - CK_ULONG ulAESKeyBits; - CK_RSA_PKCS_OAEP_PARAMS_PTR pOAEPParams; + CK_ULONG ulAESKeyBits; + CK_RSA_PKCS_OAEP_PARAMS_PTR pOAEPParams; } CK_RSA_AES_KEY_WRAP_PARAMS; typedef CK_RSA_AES_KEY_WRAP_PARAMS CK_PTR CK_RSA_AES_KEY_WRAP_PARAMS_PTR; typedef struct CK_TLS12_MASTER_KEY_DERIVE_PARAMS { - CK_SSL3_RANDOM_DATA RandomInfo; - CK_VERSION_PTR pVersion; - CK_MECHANISM_TYPE prfHashMechanism; + CK_SSL3_RANDOM_DATA RandomInfo; + CK_VERSION_PTR pVersion; + CK_MECHANISM_TYPE prfHashMechanism; } CK_TLS12_MASTER_KEY_DERIVE_PARAMS; typedef CK_TLS12_MASTER_KEY_DERIVE_PARAMS CK_PTR \ - CK_TLS12_MASTER_KEY_DERIVE_PARAMS_PTR; + CK_TLS12_MASTER_KEY_DERIVE_PARAMS_PTR; typedef struct CK_TLS12_KEY_MAT_PARAMS { - CK_ULONG ulMacSizeInBits; - CK_ULONG ulKeySizeInBits; - CK_ULONG ulIVSizeInBits; - CK_BBOOL bIsExport; - CK_SSL3_RANDOM_DATA RandomInfo; - CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial; - CK_MECHANISM_TYPE prfHashMechanism; + CK_ULONG ulMacSizeInBits; + CK_ULONG ulKeySizeInBits; + CK_ULONG ulIVSizeInBits; + CK_BBOOL bIsExport; + CK_SSL3_RANDOM_DATA RandomInfo; + CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial; + CK_MECHANISM_TYPE prfHashMechanism; } CK_TLS12_KEY_MAT_PARAMS; typedef CK_TLS12_KEY_MAT_PARAMS CK_PTR CK_TLS12_KEY_MAT_PARAMS_PTR; typedef struct CK_TLS_KDF_PARAMS { - CK_MECHANISM_TYPE prfMechanism; - CK_BYTE_PTR pLabel; - CK_ULONG ulLabelLength; - CK_SSL3_RANDOM_DATA RandomInfo; - CK_BYTE_PTR pContextData; - CK_ULONG ulContextDataLength; + CK_MECHANISM_TYPE prfMechanism; + CK_BYTE_PTR pLabel; + CK_ULONG ulLabelLength; + CK_SSL3_RANDOM_DATA RandomInfo; + CK_BYTE_PTR pContextData; + CK_ULONG ulContextDataLength; } CK_TLS_KDF_PARAMS; typedef CK_TLS_KDF_PARAMS CK_PTR CK_TLS_KDF_PARAMS_PTR; typedef struct CK_TLS_MAC_PARAMS { - CK_MECHANISM_TYPE prfHashMechanism; - CK_ULONG ulMacLength; - CK_ULONG ulServerOrClient; + CK_MECHANISM_TYPE prfHashMechanism; + CK_ULONG ulMacLength; + CK_ULONG ulServerOrClient; } CK_TLS_MAC_PARAMS; typedef CK_TLS_MAC_PARAMS CK_PTR CK_TLS_MAC_PARAMS_PTR; +typedef struct CK_TLS12_EXTENDED_MASTER_KEY_DERIVE_PARAMS { + CK_MECHANISM_TYPE prfHashMechanism; + CK_BYTE_PTR pSessionHash; + CK_ULONG ulSessionHashLen; + CK_VERSION_PTR pVersion; +} CK_TLS12_EXTENDED_MASTER_KEY_DERIVE_PARAMS; + +typedef CK_TLS12_EXTENDED_MASTER_KEY_DERIVE_PARAMS CK_PTR + CK_TLS12_EXTENDED_MASTER_KEY_DERIVE_PARAMS_PTR; + typedef struct CK_GOSTR3410_DERIVE_PARAMS { - CK_EC_KDF_TYPE kdf; - CK_BYTE_PTR pPublicData; - CK_ULONG ulPublicDataLen; - CK_BYTE_PTR pUKM; - CK_ULONG ulUKMLen; + CK_EC_KDF_TYPE kdf; + CK_BYTE_PTR pPublicData; + CK_ULONG ulPublicDataLen; + CK_BYTE_PTR pUKM; + CK_ULONG ulUKMLen; } CK_GOSTR3410_DERIVE_PARAMS; typedef CK_GOSTR3410_DERIVE_PARAMS CK_PTR CK_GOSTR3410_DERIVE_PARAMS_PTR; typedef struct CK_GOSTR3410_KEY_WRAP_PARAMS { - CK_BYTE_PTR pWrapOID; - CK_ULONG ulWrapOIDLen; - CK_BYTE_PTR pUKM; - CK_ULONG ulUKMLen; - CK_OBJECT_HANDLE hKey; + CK_BYTE_PTR pWrapOID; + CK_ULONG ulWrapOIDLen; + CK_BYTE_PTR pUKM; + CK_ULONG ulUKMLen; + CK_OBJECT_HANDLE hKey; } CK_GOSTR3410_KEY_WRAP_PARAMS; typedef CK_GOSTR3410_KEY_WRAP_PARAMS CK_PTR CK_GOSTR3410_KEY_WRAP_PARAMS_PTR; typedef struct CK_SEED_CBC_ENCRYPT_DATA_PARAMS { - CK_BYTE iv[16]; - CK_BYTE_PTR pData; - CK_ULONG length; + CK_BYTE iv[16]; + CK_BYTE_PTR pData; + CK_ULONG length; } CK_SEED_CBC_ENCRYPT_DATA_PARAMS; typedef CK_SEED_CBC_ENCRYPT_DATA_PARAMS CK_PTR \ - CK_SEED_CBC_ENCRYPT_DATA_PARAMS_PTR; + CK_SEED_CBC_ENCRYPT_DATA_PARAMS_PTR; /* * New PKCS 11 v3.0 data structures. @@ -2272,12 +2419,13 @@ typedef CK_MECHANISM_TYPE CK_SP800_108_PRF_TYPE; #define CK_SP800_108_DKM_LENGTH 0x00000003UL #define CK_SP800_108_BYTE_ARRAY 0x00000004UL #define CK_SP800_108_COUNTER CK_SP800_108_OPTIONAL_COUNTER +#define CK_SP800_108_KEY_HANDLE 0x00000005UL typedef struct CK_PRF_DATA_PARAM { - CK_PRF_DATA_TYPE type; - CK_VOID_PTR pValue; - CK_ULONG ulValueLen; + CK_PRF_DATA_TYPE type; + CK_VOID_PTR pValue; + CK_ULONG ulValueLen; } CK_PRF_DATA_PARAM; typedef CK_PRF_DATA_PARAM CK_PTR CK_PRF_DATA_PARAM_PTR; @@ -2285,8 +2433,8 @@ typedef CK_PRF_DATA_PARAM CK_PTR CK_PRF_DATA_PARAM_PTR; typedef struct CK_SP800_108_COUNTER_FORMAT { - CK_BBOOL bLittleEndian; - CK_ULONG ulWidthInBits; + CK_BBOOL bLittleEndian; + CK_ULONG ulWidthInBits; } CK_SP800_108_COUNTER_FORMAT; typedef CK_SP800_108_COUNTER_FORMAT CK_PTR CK_SP800_108_COUNTER_FORMAT_PTR; @@ -2297,52 +2445,52 @@ typedef CK_ULONG CK_SP800_108_DKM_LENGTH_METHOD; typedef struct CK_SP800_108_DKM_LENGTH_FORMAT { - CK_SP800_108_DKM_LENGTH_METHOD dkmLengthMethod; - CK_BBOOL bLittleEndian; - CK_ULONG ulWidthInBits; + CK_SP800_108_DKM_LENGTH_METHOD dkmLengthMethod; + CK_BBOOL bLittleEndian; + CK_ULONG ulWidthInBits; } CK_SP800_108_DKM_LENGTH_FORMAT; typedef CK_SP800_108_DKM_LENGTH_FORMAT \ - CK_PTR CK_SP800_108_DKM_LENGTH_FORMAT_PTR; + CK_PTR CK_SP800_108_DKM_LENGTH_FORMAT_PTR; typedef struct CK_DERIVED_KEY { - CK_ATTRIBUTE_PTR pTemplate; - CK_ULONG ulAttributeCount; - CK_OBJECT_HANDLE_PTR phKey; + CK_ATTRIBUTE_PTR pTemplate; + CK_ULONG ulAttributeCount; + CK_OBJECT_HANDLE_PTR phKey; } CK_DERIVED_KEY; typedef CK_DERIVED_KEY CK_PTR CK_DERIVED_KEY_PTR; typedef struct CK_SP800_108_KDF_PARAMS { - CK_SP800_108_PRF_TYPE prfType; - CK_ULONG ulNumberOfDataParams; - CK_PRF_DATA_PARAM_PTR pDataParams; - CK_ULONG ulAdditionalDerivedKeys; - CK_DERIVED_KEY_PTR pAdditionalDerivedKeys; + CK_SP800_108_PRF_TYPE prfType; + CK_ULONG ulNumberOfDataParams; + CK_PRF_DATA_PARAM_PTR pDataParams; + CK_ULONG ulAdditionalDerivedKeys; + CK_DERIVED_KEY_PTR pAdditionalDerivedKeys; } CK_SP800_108_KDF_PARAMS; typedef CK_SP800_108_KDF_PARAMS CK_PTR CK_SP800_108_KDF_PARAMS_PTR; typedef struct CK_SP800_108_FEEDBACK_KDF_PARAMS { - CK_SP800_108_PRF_TYPE prfType; - CK_ULONG ulNumberOfDataParams; - CK_PRF_DATA_PARAM_PTR pDataParams; - CK_ULONG ulIVLen; - CK_BYTE_PTR pIV; - CK_ULONG ulAdditionalDerivedKeys; - CK_DERIVED_KEY_PTR pAdditionalDerivedKeys; + CK_SP800_108_PRF_TYPE prfType; + CK_ULONG ulNumberOfDataParams; + CK_PRF_DATA_PARAM_PTR pDataParams; + CK_ULONG ulIVLen; + CK_BYTE_PTR pIV; + CK_ULONG ulAdditionalDerivedKeys; + CK_DERIVED_KEY_PTR pAdditionalDerivedKeys; } CK_SP800_108_FEEDBACK_KDF_PARAMS; typedef CK_SP800_108_FEEDBACK_KDF_PARAMS \ - CK_PTR CK_SP800_108_FEEDBACK_KDF_PARAMS_PTR; + CK_PTR CK_SP800_108_FEEDBACK_KDF_PARAMS_PTR; /* EDDSA */ typedef struct CK_EDDSA_PARAMS { - CK_BBOOL phFlag; - CK_ULONG ulContextDataLen; + CK_BBOOL phFlag; + CK_ULONG ulContextDataLen; CK_BYTE_PTR pContextData; } CK_EDDSA_PARAMS; @@ -2366,23 +2514,23 @@ typedef struct CK_SALSA20_PARAMS { typedef CK_SALSA20_PARAMS CK_PTR CK_SALSA20_PARAMS_PTR; typedef struct CK_SALSA20_CHACHA20_POLY1305_PARAMS { - CK_BYTE_PTR pNonce; - CK_ULONG ulNonceLen; - CK_BYTE_PTR pAAD; - CK_ULONG ulAADLen; + CK_BYTE_PTR pNonce; + CK_ULONG ulNonceLen; + CK_BYTE_PTR pAAD; + CK_ULONG ulAADLen; } CK_SALSA20_CHACHA20_POLY1305_PARAMS; typedef CK_SALSA20_CHACHA20_POLY1305_PARAMS \ - CK_PTR CK_SALSA20_CHACHA20_POLY1305_PARAMS_PTR; + CK_PTR CK_SALSA20_CHACHA20_POLY1305_PARAMS_PTR; typedef struct CK_SALSA20_CHACHA20_POLY1305_MSG_PARAMS { - CK_BYTE_PTR pNonce; - CK_ULONG ulNonceLen; - CK_BYTE_PTR pTag; + CK_BYTE_PTR pNonce; + CK_ULONG ulNonceLen; + CK_BYTE_PTR pTag; } CK_SALSA20_CHACHA20_POLY1305_MSG_PARAMS; typedef CK_SALSA20_CHACHA20_POLY1305_MSG_PARAMS \ - CK_PTR CK_SALSA20_CHACHA20_POLY1305_MSG_PARAMS_PTR; + CK_PTR CK_SALSA20_CHACHA20_POLY1305_MSG_PARAMS_PTR; typedef CK_ULONG CK_X3DH_KDF_TYPE; typedef CK_X3DH_KDF_TYPE CK_PTR CK_X3DH_KDF_TYPE_PTR; @@ -2392,50 +2540,50 @@ typedef struct CK_X3DH_INITIATE_PARAMS { CK_X3DH_KDF_TYPE kdf; CK_OBJECT_HANDLE pPeer_identity; CK_OBJECT_HANDLE pPeer_prekey; - CK_BYTE_PTR pPrekey_signature; - CK_BYTE_PTR pOnetime_key; + CK_BYTE_PTR pPrekey_signature; + CK_BYTE_PTR pOnetime_key; CK_OBJECT_HANDLE pOwn_identity; CK_OBJECT_HANDLE pOwn_ephemeral; } CK_X3DH_INITIATE_PARAMS; typedef struct CK_X3DH_RESPOND_PARAMS { CK_X3DH_KDF_TYPE kdf; - CK_BYTE_PTR pIdentity_id; - CK_BYTE_PTR pPrekey_id; - CK_BYTE_PTR pOnetime_id; + CK_BYTE_PTR pIdentity_id; + CK_BYTE_PTR pPrekey_id; + CK_BYTE_PTR pOnetime_id; CK_OBJECT_HANDLE pInitiator_identity; - CK_BYTE_PTR pInitiator_ephemeral; + CK_BYTE_PTR pInitiator_ephemeral; } CK_X3DH_RESPOND_PARAMS; typedef CK_ULONG CK_X2RATCHET_KDF_TYPE; typedef CK_X2RATCHET_KDF_TYPE CK_PTR CK_X2RATCHET_KDF_TYPE_PTR; typedef struct CK_X2RATCHET_INITIALIZE_PARAMS { - CK_BYTE_PTR sk; - CK_OBJECT_HANDLE peer_public_prekey; - CK_OBJECT_HANDLE peer_public_identity; - CK_OBJECT_HANDLE own_public_identity; - CK_BBOOL bEncryptedHeader; - CK_ULONG eCurve; - CK_MECHANISM_TYPE aeadMechanism; - CK_X2RATCHET_KDF_TYPE kdfMechanism; + CK_BYTE_PTR sk; + CK_OBJECT_HANDLE peer_public_prekey; + CK_OBJECT_HANDLE peer_public_identity; + CK_OBJECT_HANDLE own_public_identity; + CK_BBOOL bEncryptedHeader; + CK_ULONG eCurve; + CK_MECHANISM_TYPE aeadMechanism; + CK_X2RATCHET_KDF_TYPE kdfMechanism; } CK_X2RATCHET_INITIALIZE_PARAMS; typedef CK_X2RATCHET_INITIALIZE_PARAMS \ - CK_PTR CK_X2RATCHET_INITIALIZE_PARAMS_PTR; + CK_PTR CK_X2RATCHET_INITIALIZE_PARAMS_PTR; typedef struct CK_X2RATCHET_RESPOND_PARAMS { - CK_BYTE_PTR sk; - CK_OBJECT_HANDLE own_prekey; - CK_OBJECT_HANDLE initiator_identity; - CK_OBJECT_HANDLE own_public_identity; - CK_BBOOL bEncryptedHeader; - CK_ULONG eCurve; - CK_MECHANISM_TYPE aeadMechanism; - CK_X2RATCHET_KDF_TYPE kdfMechanism; + CK_BYTE_PTR sk; + CK_OBJECT_HANDLE own_prekey; + CK_OBJECT_HANDLE initiator_identity; + CK_OBJECT_HANDLE own_public_identity; + CK_BBOOL bEncryptedHeader; + CK_ULONG eCurve; + CK_MECHANISM_TYPE aeadMechanism; + CK_X2RATCHET_KDF_TYPE kdfMechanism; } CK_X2RATCHET_RESPOND_PARAMS; typedef CK_X2RATCHET_RESPOND_PARAMS \ - CK_PTR CK_X2RATCHET_RESPOND_PARAMS_PTR; + CK_PTR CK_X2RATCHET_RESPOND_PARAMS_PTR; typedef CK_ULONG CK_XEDDSA_HASH_TYPE; typedef CK_XEDDSA_HASH_TYPE CK_PTR CK_XEDDSA_HASH_TYPE_PTR; @@ -2448,15 +2596,15 @@ typedef CK_XEDDSA_PARAMS CK_PTR CK_XEDDSA_PARAMS_PTR; /* HKDF params */ typedef struct CK_HKDF_PARAMS { - CK_BBOOL bExtract; - CK_BBOOL bExpand; - CK_MECHANISM_TYPE prfHashMechanism; - CK_ULONG ulSaltType; - CK_BYTE_PTR pSalt; - CK_ULONG ulSaltLen; - CK_OBJECT_HANDLE hSaltKey; - CK_BYTE_PTR pInfo; - CK_ULONG ulInfoLen; + CK_BBOOL bExtract; + CK_BBOOL bExpand; + CK_MECHANISM_TYPE prfHashMechanism; + CK_ULONG ulSaltType; + CK_BYTE_PTR pSalt; + CK_ULONG ulSaltLen; + CK_OBJECT_HANDLE hSaltKey; + CK_BYTE_PTR pInfo; + CK_ULONG ulInfoLen; } CK_HKDF_PARAMS; typedef CK_HKDF_PARAMS CK_PTR CK_HKDF_PARAMS_PTR; @@ -2470,54 +2618,142 @@ typedef CK_ULONG CK_LMS_TYPE; typedef CK_ULONG CK_LMOTS_TYPE; typedef struct specifiedParams { - CK_HSS_LEVELS levels; - CK_LMS_TYPE lm_type[8]; - CK_LMOTS_TYPE lm_ots_type[8]; + CK_HSS_LEVELS levels; + CK_LMS_TYPE lm_type[8]; + CK_LMOTS_TYPE lm_ots_type[8]; } specifiedParams; /* IKE Params */ typedef struct CK_IKE2_PRF_PLUS_DERIVE_PARAMS { - CK_MECHANISM_TYPE prfMechanism; - CK_BBOOL bHasSeedKey; - CK_OBJECT_HANDLE hSeedKey; - CK_BYTE_PTR pSeedData; - CK_ULONG ulSeedDataLen; + CK_MECHANISM_TYPE prfMechanism; + CK_BBOOL bHasSeedKey; + CK_OBJECT_HANDLE hSeedKey; + CK_BYTE_PTR pSeedData; + CK_ULONG ulSeedDataLen; } CK_IKE2_PRF_PLUS_DERIVE_PARAMS; typedef CK_IKE2_PRF_PLUS_DERIVE_PARAMS CK_PTR CK_IKE2_PRF_PLUS_DERIVE_PARAMS_PTR; typedef struct CK_IKE_PRF_DERIVE_PARAMS { - CK_MECHANISM_TYPE prfMechanism; - CK_BBOOL bDataAsKey; - CK_BBOOL bRekey; - CK_BYTE_PTR pNi; - CK_ULONG ulNiLen; - CK_BYTE_PTR pNr; - CK_ULONG ulNrLen; - CK_OBJECT_HANDLE hNewKey; + CK_MECHANISM_TYPE prfMechanism; + CK_BBOOL bDataAsKey; + CK_BBOOL bRekey; + CK_BYTE_PTR pNi; + CK_ULONG ulNiLen; + CK_BYTE_PTR pNr; + CK_ULONG ulNrLen; + CK_OBJECT_HANDLE hNewKey; } CK_IKE_PRF_DERIVE_PARAMS; typedef CK_IKE_PRF_DERIVE_PARAMS CK_PTR CK_IKE_PRF_DERIVE_PARAMS_PTR; typedef struct CK_IKE1_PRF_DERIVE_PARAMS { - CK_MECHANISM_TYPE prfMechanism; - CK_BBOOL bHasPrevKey; - CK_OBJECT_HANDLE hKeygxy; - CK_OBJECT_HANDLE hPrevKey; - CK_BYTE_PTR pCKYi; - CK_ULONG ulCKYiLen; - CK_BYTE_PTR pCKYr; - CK_ULONG ulCKYrLen; - CK_BYTE keyNumber; + CK_MECHANISM_TYPE prfMechanism; + CK_BBOOL bHasPrevKey; + CK_OBJECT_HANDLE hKeygxy; + CK_OBJECT_HANDLE hPrevKey; + CK_BYTE_PTR pCKYi; + CK_ULONG ulCKYiLen; + CK_BYTE_PTR pCKYr; + CK_ULONG ulCKYrLen; + CK_BYTE keyNumber; } CK_IKE1_PRF_DERIVE_PARAMS; typedef CK_IKE1_PRF_DERIVE_PARAMS CK_PTR CK_IKE1_PRF_DERIVE_PARAMS_PTR; typedef struct CK_IKE1_EXTENDED_DERIVE_PARAMS { CK_MECHANISM_TYPE prfMechanism; - CK_BBOOL bHasKeygxy; - CK_OBJECT_HANDLE hKeygxy; - CK_BYTE_PTR pExtraData; - CK_ULONG ulExtraDataLen; + CK_BBOOL bHasKeygxy; + CK_OBJECT_HANDLE hKeygxy; + CK_BYTE_PTR pExtraData; + CK_ULONG ulExtraDataLen; } CK_IKE1_EXTENDED_DERIVE_PARAMS; typedef CK_IKE1_EXTENDED_DERIVE_PARAMS CK_PTR CK_IKE1_EXTENDED_DERIVE_PARAMS_PTR; +/* async */ +typedef struct CK_ASYNC_DATA { + CK_ULONG ulVersion; + CK_BYTE_PTR pValue; + CK_ULONG ulValue; + CK_OBJECT_HANDLE hObject; + CK_OBJECT_HANDLE hAdditionalObject; +} CK_ASYNC_DATA; +typedef CK_ASYNC_DATA CK_PTR CK_ASYNC_DATA_PTR; + +/* validation */ +typedef CK_ULONG CK_SESSION_VALIDATION_FLAGS_TYPE; +#define CKS_LAST_VALIDATION_OK 0x00000001UL + +typedef CK_ULONG CK_VALIDATION_TYPE; +typedef CK_VALIDATION_TYPE CK_PTR CK_VALIDATION_TYPE_PTR; +#define CKV_AUTHORITY_TYPE_UNSPECIFIED 0x00000000UL +#define CKV_AUTHORITY_TYPE_NIST_CMVP 0x00000001UL +#define CKV_AUTHORITY_TYPE_COMMON_CRITERIA 0x00000002UL + +typedef CK_ULONG CK_VALIDATION_AUTHORITY_TYPE; +typedef CK_VALIDATION_AUTHORITY_TYPE CK_PTR CK_VALIDATION_AUTHORITY_TYPE_PTR; +#define CKV_TYPE_UNSPECIFIED 0x00000000UL +#define CKV_TYPE_SOFTWARE 0x00000001UL +#define CKV_TYPE_HARDWARE 0x00000002UL +#define CKV_TYPE_FIRMWARE 0x00000003UL +#define CKV_TYPE_HYBRID 0x00000004UL + +/* XMSS */ +typedef CK_ULONG CK_XMSSMT_PARAMETER_SET_TYPE; +typedef CK_ULONG CK_XMSS_PARAMETER_SET_TYPE; + +/* generic PQ mechanism parameters */ +typedef CK_ULONG CK_HEDGE_TYPE; +#define CKH_HEDGE_PREFERRED 0x00000000UL +#define CKH_HEDGE_REQUIRED 0x00000001UL +#define CKH_DETERMINISTIC_REQUIRED 0x00000002UL + +typedef struct CK_SIGN_ADDITIONAL_CONTEXT { + CK_HEDGE_TYPE hedgeVariant; + CK_BYTE_PTR pContext; + CK_ULONG ulContextLen; +} CK_SIGN_ADDITIONAL_CONTEXT; + +typedef struct CK_HASH_SIGN_ADDITIONAL_CONTEXT { + CK_HEDGE_TYPE hedgeVariant; + CK_BYTE_PTR pContext; + CK_ULONG ulContextLen; + CK_MECHANISM_TYPE hash; +} CK_HASH_SIGN_ADDITIONAL_CONTEXT; + + +/* ML-DSA values for CKA_PARAMETER_SETS */ +typedef CK_ULONG CK_ML_DSA_PARAMETER_SET_TYPE; +#define CKP_ML_DSA_44 0x00000001UL +#define CKP_ML_DSA_65 0x00000002UL +#define CKP_ML_DSA_87 0x00000003UL + +/* SLH-DSA values for CKA_PARAMETER_SETS */ +typedef CK_ULONG CK_SLH_DSA_PARAMETER_SET_TYPE; +#define CKP_SLH_DSA_SHA2_128S 0x00000001UL +#define CKP_SLH_DSA_SHAKE_128S 0x00000002UL +#define CKP_SLH_DSA_SHA2_128F 0x00000003UL +#define CKP_SLH_DSA_SHAKE_128F 0x00000004UL +#define CKP_SLH_DSA_SHA2_192S 0x00000005UL +#define CKP_SLH_DSA_SHAKE_192S 0x00000006UL +#define CKP_SLH_DSA_SHA2_192F 0x00000007UL +#define CKP_SLH_DSA_SHAKE_192F 0x00000008UL +#define CKP_SLH_DSA_SHA2_256S 0x00000009UL +#define CKP_SLH_DSA_SHAKE_256S 0x0000000aUL +#define CKP_SLH_DSA_SHA2_256F 0x0000000bUL +#define CKP_SLH_DSA_SHAKE_256F 0x0000000cUL + +/* ML-KEM values for CKA_PARAMETER_SETS */ +typedef CK_ULONG CK_ML_KEM_PARAMETER_SET_TYPE; +#define CKP_ML_KEM_512 0x00000001UL +#define CKP_ML_KEM_768 0x00000002UL +#define CKP_ML_KEM_1024 0x00000003UL + +/* Trust values for CKA_TRUST_* */ +typedef CK_ULONG CK_TRUST; +#define CKT_TRUST_UNKNOWN 0x00000000UL +#define CKT_TRUSTED 0x00000001UL +#define CKT_TRUST_ANCHOR 0x00000002UL +#define CKT_NOT_TRUSTED 0x00000003UL +#define CKT_TRUST_MUST_VERIFY_TRUST 0x00000004UL + + #endif /* _PKCS11T_H_ */ diff --git a/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/p11_md.c b/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/p11_md.c index ca0fd3172300..6892e6f93fc3 100644 --- a/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/p11_md.c +++ b/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/p11_md.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved. */ /* Copyright (c) 2002 Graz University of Technology. All rights reserved. @@ -79,10 +79,6 @@ JNIEXPORT jobject JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_connect jstring jGetFunctionList) { HINSTANCE hModule; - int i = 0; - CK_ULONG ulCount = 0; - CK_C_GetInterfaceList C_GetInterfaceList = NULL; - CK_INTERFACE_PTR iList = NULL; CK_C_GetInterface C_GetInterface = NULL; CK_INTERFACE_PTR interface = NULL; CK_C_GetFunctionList C_GetFunctionList = NULL; @@ -129,22 +125,27 @@ JNIEXPORT jobject JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_connect /* * Get function pointer to C_GetInterfaceList */ - C_GetInterfaceList = (CK_C_GetInterfaceList) GetProcAddress(hModule, + CK_C_GetInterfaceList C_GetInterfaceList = (CK_C_GetInterfaceList) GetProcAddress(hModule, "C_GetInterfaceList"); if (C_GetInterfaceList != NULL) { + CK_ULONG ulCount = 0; TRACE0("Found C_GetInterfaceList func\n"); rv = (C_GetInterfaceList)(NULL, &ulCount); if (rv == CKR_OK) { /* get copy of interfaces */ - iList = (CK_INTERFACE_PTR) - malloc(ulCount*sizeof(CK_INTERFACE)); - rv = C_GetInterfaceList(iList, &ulCount); - for (i=0; i < (int)ulCount; i++) { - printf("interface %s version %d.%d funcs %p flags 0x%lu\n", - iList[i].pInterfaceName, - ((CK_VERSION *)iList[i].pFunctionList)->major, - ((CK_VERSION *)iList[i].pFunctionList)->minor, - iList[i].pFunctionList, iList[i].flags); + CK_INTERFACE_PTR iList = (CK_INTERFACE_PTR) malloc(ulCount*sizeof(CK_INTERFACE)); + if (iList == NULL) { + TRACE0("Connect: error allocating interface list\n"); + } else { + rv = C_GetInterfaceList(iList, &ulCount); + for (int i=0; i < (int)ulCount; i++) { + printf("interface %s version %d.%d funcs %p flags 0x%lu\n", + iList[i].pInterfaceName, + ((CK_VERSION *)iList[i].pFunctionList)->major, + ((CK_VERSION *)iList[i].pFunctionList)->minor, + iList[i].pFunctionList, iList[i].flags); + } + free(iList); } } else { TRACE0("Connect: error polling interface list size\n"); diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/DwarfCFrame.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/DwarfCFrame.java index bc789586388b..886215e051e1 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/DwarfCFrame.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/DwarfCFrame.java @@ -44,6 +44,7 @@ public class DwarfCFrame extends BasicCFrame { private LinuxDebugger linuxDbg; private DwarfParser dwarf; private boolean use1ByteBeforeToLookup; + private boolean hasNativeLibrary; /** * @return DwarfParser instance for the PC, null if native library relates to the pc not found. @@ -75,6 +76,7 @@ protected DwarfCFrame(LinuxDebugger linuxDbg, Address sp, Address fp, Address cf this.linuxDbg = linuxDbg; this.dwarf = dwarf; this.use1ByteBeforeToLookup = use1ByteBeforeToLookup; + this.hasNativeLibrary = linuxDbg.findLibPtrByAddress(pc) != null; } public Address sp() { @@ -97,6 +99,10 @@ public DwarfParser dwarf() { return dwarf; } + public boolean hasNativeLibrary() { + return hasNativeLibrary; + } + // override base class impl to avoid ELF parsing @Override public ClosestSymbol closestSymbolToPC() { diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/aarch64/LinuxAARCH64CFrame.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/aarch64/LinuxAARCH64CFrame.java index fe05fd13dee5..f3a1d2d80a2d 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/aarch64/LinuxAARCH64CFrame.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/aarch64/LinuxAARCH64CFrame.java @@ -135,6 +135,11 @@ public CFrame sender(ThreadProxy thread, Address senderSP, Address senderFP, Add return getFrameFromReg(linuxDbg(), r -> LinuxAARCH64ThreadContext.getRegFromSignalTrampoline(sp(), r.intValue())); } + if (hasNativeLibrary() && dwarf() == null) { + // Cannot find a sender frame if DWARF is missing even though PC in native library. + return null; + } + if (senderPC == null) { // Use getSenderPC() if current frame is Java because we cannot rely on lr in this case. senderPC = dwarf() == null ? getSenderPC(null) : lr; @@ -198,8 +203,11 @@ public CFrame sender(ThreadProxy thread, Address senderSP, Address senderFP, Add return new LinuxAARCH64CFrame(linuxDbg(), senderSP, senderFP, null, senderPC, senderDwarf); } - // We cannot unwind anymore without appropriate DWARF. - return null; + // Returns CFrame if the sender is native frame even though it does not have DWARF, + // otherwise returns null because we cannot unwind anymore. + return linuxDbg().findLibPtrByAddress(senderPC) != null + ? new LinuxAARCH64CFrame(linuxDbg(), senderSP, senderFP, null /* no CFA */, senderPC, null /* no DWARF */) + : null; } } diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/amd64/LinuxAMD64CFrame.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/amd64/LinuxAMD64CFrame.java index c7cba470a049..ece221e9ef3d 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/amd64/LinuxAMD64CFrame.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/amd64/LinuxAMD64CFrame.java @@ -87,6 +87,11 @@ public CFrame sender(ThreadProxy th, Address senderSP, Address senderFP, Address return getFrameFromReg(linuxDbg(), r -> LinuxAMD64ThreadContext.getRegFromSignalTrampoline(sp(), r.intValue())); } + if (hasNativeLibrary() && dwarf() == null) { + // Cannot find a sender frame if DWARF is missing even though PC in native library. + return null; + } + senderSP = getSenderSP(senderSP); if (senderSP == null) { return null; @@ -96,6 +101,8 @@ public CFrame sender(ThreadProxy th, Address senderSP, Address senderFP, Address return null; } + senderFP = getSenderFP(senderFP); + DwarfParser senderDwarf = null; boolean fallback = false; try { @@ -107,13 +114,14 @@ public CFrame sender(ThreadProxy th, Address senderSP, Address senderFP, Address senderDwarf = createDwarfParser(linuxDbg(), senderPC.addOffsetTo(-1)); fallback = true; } catch (DebuggerException _) { - // We cannot unwind anymore without appropriate DWARF. - return null; + // Returns CFrame if the sender is native frame even though it does not have DWARF, + // otherwise returns null because we cannot unwind anymore. + return linuxDbg().findLibPtrByAddress(senderPC) != null + ? new LinuxAMD64CFrame(linuxDbg(), senderSP, senderFP, null /* no CFA */, senderPC, null /* no DWARF */) + : null; } } - senderFP = getSenderFP(senderFP); - try { Address senderCFA = getSenderCFA(senderDwarf, senderSP, senderFP); return isValidFrame(senderCFA, senderFP) diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSans-Bold.woff b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSans-Bold.woff deleted file mode 100644 index 63a79c041a25..000000000000 Binary files a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSans-Bold.woff and /dev/null differ diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSans-Bold.woff2 b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSans-Bold.woff2 index 06655540c222..ca477d57d3e0 100644 Binary files a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSans-Bold.woff2 and b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSans-Bold.woff2 differ diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSans-BoldOblique.woff b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSans-BoldOblique.woff deleted file mode 100644 index dead29087fbb..000000000000 Binary files a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSans-BoldOblique.woff and /dev/null differ diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSans-BoldOblique.woff2 b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSans-BoldOblique.woff2 index 89328f3c47bb..c9ef30a805e9 100644 Binary files a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSans-BoldOblique.woff2 and b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSans-BoldOblique.woff2 differ diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSans-Oblique.woff b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSans-Oblique.woff deleted file mode 100644 index 6c62443d0c8e..000000000000 Binary files a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSans-Oblique.woff and /dev/null differ diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSans-Oblique.woff2 b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSans-Oblique.woff2 index 8a50fa152924..ec38f7fd033f 100644 Binary files a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSans-Oblique.woff2 and b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSans-Oblique.woff2 differ diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSans.woff b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSans.woff deleted file mode 100644 index a0f1efa91c2a..000000000000 Binary files a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSans.woff and /dev/null differ diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSans.woff2 b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSans.woff2 index fecdbd87ebc7..9d522177000e 100644 Binary files a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSans.woff2 and b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSans.woff2 differ diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSansMono-Bold.woff b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSansMono-Bold.woff deleted file mode 100644 index 9f646ba06b57..000000000000 Binary files a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSansMono-Bold.woff and /dev/null differ diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSansMono-Bold.woff2 b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSansMono-Bold.woff2 index 346de2da4f3a..32b83e4dae01 100644 Binary files a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSansMono-Bold.woff2 and b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSansMono-Bold.woff2 differ diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSansMono-BoldOblique.woff b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSansMono-BoldOblique.woff deleted file mode 100644 index 7a6b3ac04338..000000000000 Binary files a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSansMono-BoldOblique.woff and /dev/null differ diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSansMono-BoldOblique.woff2 b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSansMono-BoldOblique.woff2 index ede24ef6a307..5c3836d795f9 100644 Binary files a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSansMono-BoldOblique.woff2 and b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSansMono-BoldOblique.woff2 differ diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSansMono-Oblique.woff b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSansMono-Oblique.woff deleted file mode 100644 index 892833b94a91..000000000000 Binary files a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSansMono-Oblique.woff and /dev/null differ diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSansMono-Oblique.woff2 b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSansMono-Oblique.woff2 index 9e9051434717..384551ec4ba6 100644 Binary files a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSansMono-Oblique.woff2 and b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSansMono-Oblique.woff2 differ diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSansMono.woff b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSansMono.woff deleted file mode 100644 index e94e844d16fb..000000000000 Binary files a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSansMono.woff and /dev/null differ diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSansMono.woff2 b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSansMono.woff2 index 9460c050f9f1..ba0fb9ce61c8 100644 Binary files a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSansMono.woff2 and b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSansMono.woff2 differ diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSerif-Bold.woff b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSerif-Bold.woff deleted file mode 100644 index 0f38846c5a05..000000000000 Binary files a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSerif-Bold.woff and /dev/null differ diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSerif-Bold.woff2 b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSerif-Bold.woff2 index d65a5e9566b4..dd86f4850e90 100644 Binary files a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSerif-Bold.woff2 and b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSerif-Bold.woff2 differ diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSerif-BoldItalic.woff b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSerif-BoldItalic.woff deleted file mode 100644 index 63fd5e38d892..000000000000 Binary files a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSerif-BoldItalic.woff and /dev/null differ diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSerif-BoldItalic.woff2 b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSerif-BoldItalic.woff2 index e29307ea2125..04007d4a5309 100644 Binary files a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSerif-BoldItalic.woff2 and b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSerif-BoldItalic.woff2 differ diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSerif-Italic.woff b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSerif-Italic.woff deleted file mode 100644 index 5df6d001523f..000000000000 Binary files a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSerif-Italic.woff and /dev/null differ diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSerif-Italic.woff2 b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSerif-Italic.woff2 index 61ff1463c6f1..7202f5de872d 100644 Binary files a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSerif-Italic.woff2 and b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSerif-Italic.woff2 differ diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSerif.woff b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSerif.woff deleted file mode 100644 index 280e3783cce1..000000000000 Binary files a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSerif.woff and /dev/null differ diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSerif.woff2 b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSerif.woff2 index bbd32cdec41e..6576521d5df9 100644 Binary files a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSerif.woff2 and b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/DejaVuLGCSerif.woff2 differ diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/dejavu.css b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/dejavu.css index b450caa32d72..178d5c71ae3f 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/dejavu.css +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/fonts/dejavu.css @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/ @@ -9,96 +9,84 @@ @font-face { font-family: 'DejaVu Sans Mono'; - src: url('DejaVuLGCSansMono.woff2') format('woff2'), - url('DejaVuLGCSansMono.woff') format('woff'); + src: url('DejaVuLGCSansMono.woff2') format('woff2'); font-weight: normal; font-style: normal; } @font-face { font-family: 'DejaVu Sans Mono'; - src: url('DejaVuLGCSansMono-Oblique.woff2') format('woff2'), - url('DejaVuLGCSansMono-Oblique.woff') format('woff'); + src: url('DejaVuLGCSansMono-Oblique.woff2') format('woff2'); font-weight: normal; font-style: italic; } @font-face { font-family: 'DejaVu Sans Mono'; - src: url('DejaVuLGCSansMono-Bold.woff2') format('woff2'), - url('DejaVuLGCSansMono-Bold.woff') format('woff'); + src: url('DejaVuLGCSansMono-Bold.woff2') format('woff2'); font-weight: bold; font-style: normal; } @font-face { font-family: 'DejaVu Sans Mono'; - src: url('DejaVuLGCSansMono-BoldOblique.woff2') format('woff2'), - url('DejaVuLGCSansMono-BoldOblique.woff') format('woff'); + src: url('DejaVuLGCSansMono-BoldOblique.woff2') format('woff2'); font-weight: bold; font-style: italic; } @font-face { font-family: 'DejaVu Sans'; - src: url('DejaVuLGCSans.woff2') format('woff2'), - url('DejaVuLGCSans.woff') format('woff'); + src: url('DejaVuLGCSans.woff2') format('woff2'); font-weight: normal; font-style: normal; } @font-face { font-family: 'DejaVu Sans'; - src: url('DejaVuLGCSans-Oblique.woff2') format('woff2'), - url('DejaVuLGCSans-Oblique.woff') format('woff'); + src: url('DejaVuLGCSans-Oblique.woff2') format('woff2'); font-weight: normal; font-style: italic; } @font-face { font-family: 'DejaVu Sans'; - src: url('DejaVuLGCSans-Bold.woff2') format('woff2'), - url('DejaVuLGCSans-Bold.woff') format('woff'); + src: url('DejaVuLGCSans-Bold.woff2') format('woff2'); font-weight: bold; font-style: normal; } @font-face { font-family: 'DejaVu Sans'; - src: url('DejaVuLGCSans-BoldOblique.woff2') format('woff2'), - url('DejaVuLGCSans-BoldOblique.woff') format('woff'); + src: url('DejaVuLGCSans-BoldOblique.woff2') format('woff2'); font-weight: bold; font-style: italic; } @font-face { font-family: 'DejaVu Serif'; - src: url('DejaVuLGCSerif.woff2') format('woff2'), - url('DejaVuLGCSerif.woff') format('woff'); + src: url('DejaVuLGCSerif.woff2') format('woff2'); font-weight: normal; font-style: normal; } @font-face { font-family: 'DejaVu Serif'; - src: url('DejaVuLGCSerif-Italic.woff2') format('woff2'), - url('DejaVuLGCSerif-Italic.woff') format('woff'); + src: url('DejaVuLGCSerif-Italic.woff2') format('woff2'); font-weight: normal; font-style: italic; } @font-face { font-family: 'DejaVu Serif'; - src: url('DejaVuLGCSerif-Bold.woff2') format('woff2'), - url('DejaVuLGCSerif-Bold.woff') format('woff'); + src: url('DejaVuLGCSerif-Bold.woff2') format('woff2'); font-weight: bold; font-style: normal; } @font-face { font-family: 'DejaVu Serif'; - src: url('DejaVuLGCSerif-BoldItalic.woff2') format('woff2'), - url('DejaVuLGCSerif-BoldItalic.woff') format('woff'); + src: url('DejaVuLGCSerif-BoldItalic.woff2') format('woff2'); font-weight: bold; font-style: italic; } diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/DefaultStripDebugPlugin.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/DefaultStripDebugPlugin.java index b3644bdde857..283ca11deccb 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/DefaultStripDebugPlugin.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/DefaultStripDebugPlugin.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2019, 2026, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2019, Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -27,12 +28,13 @@ import java.util.Map; +import jdk.tools.jlink.internal.Platform; import jdk.tools.jlink.internal.PluginRepository; import jdk.tools.jlink.internal.ResourcePoolManager; -import jdk.tools.jlink.internal.ResourcePoolManager.ResourcePoolImpl; import jdk.tools.jlink.plugin.Plugin; import jdk.tools.jlink.plugin.ResourcePool; import jdk.tools.jlink.plugin.ResourcePoolBuilder; +import jdk.tools.jlink.plugin.ResourcePoolModule; /** * Combined debug stripping plugin: Java debug attributes and native debug @@ -43,6 +45,7 @@ public final class DefaultStripDebugPlugin extends AbstractPlugin { private static final String STRIP_NATIVE_DEBUG_PLUGIN = "strip-native-debug-symbols"; private static final String EXCLUDE_DEBUGINFO = "exclude-debuginfo-files"; + private static final String EXCLUDE_FILES_PLUGIN = "exclude-files"; private final Plugin javaStripPlugin; private final NativePluginFactory stripNativePluginFactory; @@ -68,26 +71,46 @@ public void enableJavaStripPlugin(boolean enableJavaStripPlugin) { @Override public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) { Plugin stripNativePlugin = stripNativePluginFactory.create(); + + String pattern = debugFilePattern(in); + ExcludeFilesPlugin excludeFilesPlugin = new ExcludeFilesPlugin(); + excludeFilesPlugin.configure(Map.of(EXCLUDE_FILES_PLUGIN, pattern)); + + ResourcePool result = in; + if (isJavaStripPluginEnabled) { + result = pipe(result, javaStripPlugin); + } if (stripNativePlugin != null) { - Map stripNativeConfig = Map.of( - STRIP_NATIVE_DEBUG_PLUGIN, EXCLUDE_DEBUGINFO); - stripNativePlugin.configure(stripNativeConfig); - - if (!isJavaStripPluginEnabled) { - return stripNativePlugin.transform(in, out); - } - - ResourcePoolManager outRes = - new ResourcePoolManager(in.byteOrder(), - ((ResourcePoolImpl)in).getStringTable()); - ResourcePool strippedJava = javaStripPlugin.transform(in, - outRes.resourcePoolBuilder()); - return stripNativePlugin.transform(strippedJava, out); - } else if (isJavaStripPluginEnabled) { - return javaStripPlugin.transform(in, out); - } else { - return in; + stripNativePlugin.configure(Map.of(STRIP_NATIVE_DEBUG_PLUGIN, EXCLUDE_DEBUGINFO)); + result = pipe(result, stripNativePlugin); + } + return excludeFilesPlugin.transform(result, out); + } + + // Returns the glob pattern for debug files matching the target platform. + // Mirrors the per-OS exclusion logic in make/CreateJmods.gmk. + private static String debugFilePattern(ResourcePool in) { + Platform platform; + try { + String tp = in.moduleView() + .findModule("java.base") + .map(ResourcePoolModule::targetPlatform) + .orElse(null); + platform = tp != null ? Platform.parsePlatform(tp) : Platform.runtime(); + } catch (IllegalArgumentException e) { + platform = Platform.runtime(); } + return switch (platform.os()) { + case WINDOWS -> "**.pdb,**.map,**.diz"; + case MACOS -> "**.dSYM/**,**.diz"; + default -> "**.debuginfo,**.diz"; // Linux, AIX + }; + } + + private ResourcePool pipe(ResourcePool pool, Plugin plugin) { + ResourcePoolManager mgr = new ResourcePoolManager( + pool.byteOrder(), ((ResourcePoolManager.ResourcePoolImpl)pool).getStringTable()); + return plugin.transform(pool, mgr.resourcePoolBuilder()); } public interface NativePluginFactory { diff --git a/test/hotspot/jtreg/TEST.groups b/test/hotspot/jtreg/TEST.groups index 074bc514b35e..be35aeec3b3e 100644 --- a/test/hotspot/jtreg/TEST.groups +++ b/test/hotspot/jtreg/TEST.groups @@ -436,6 +436,7 @@ hotspot_appcds_dynamic = \ -runtime/cds/appcds/ArchiveRelocationTest.java \ -runtime/cds/appcds/BadBSM.java \ -runtime/cds/appcds/CommandLineFlagCombo.java \ + -runtime/cds/appcds/CommandLineFlagComboNegative.java \ -runtime/cds/appcds/DumpClassList.java \ -runtime/cds/appcds/DumpClassListWithLF.java \ -runtime/cds/appcds/DumpRuntimeClassesTest.java \ diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/IR.java b/test/hotspot/jtreg/compiler/lib/ir_framework/IR.java index 96df71dacd7d..3545c33820b1 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/IR.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/IR.java @@ -57,7 +57,7 @@ * To restrict the application of IR rules when certain flags are present that could change the IR, each {@code @IR} * annotation can specify additional preconditions on the allowed Test VM flags that must hold when an IR rule is applied. * If the specified preconditions fail, then the framework does not apply the IR rule. These preconditions can be - * set with {@link #applyIf()}, {@link #applyIfNot()}, {@link #applyIfAnd()}, or {@link #applyIfOr()}. + * set with {@link #applyIf()}, {@link #applyIfAnd()}, or {@link #applyIfOr()}. *

* Examples on how to write tests with IR rules can be found in {@link ir_framework.examples.IRExample} * and also as part of the internal testing in {@link ir_framework.tests.TestIRMatching}. @@ -103,94 +103,78 @@ * with the type of the VM flag. A number based flag value can be proceeded with an additional comparator * ({@code =, !=, <, <=, =>, >}) where the equality operator is optional (default if no comparator is specified). *

- * This is the inverse of {@link #applyIfNot()}. For multiple preconditions, use {@link #applyIfAnd()} or - * {@link #applyIfOr()} depending on the use case. + * For multiple preconditions, use {@link #applyIfAnd()} or {@link #applyIfOr()} depending on the use case. */ String[] applyIf() default {}; + + /** + * Define a list of at least two VM flag precondition which all must hold when applying the IR rule. + * If the one of the VM flag preconditions does not hold, then the IR rule is not applied. This is useful if + * commonly used flags alter the IR in such a way that an IR rule would fail. This can also be defined as conjunction + * of preconditions. + *

+ * A precondition is a (flag, value) string pair where the flag must be a valid VM flag and the value must conform + * with the type of the VM flag. A number based flag value can be proceeded with an additional comparator + * ({@code =, !=, <, <=, =>, >}) where the equality operator is optional (default if no comparator is specified). + *

+ * Use {@link #applyIfOr()} for disjunction and for single precondition constraints use {@link #applyIf()}. + */ + String[] applyIfAnd() default {}; + + /** + * Define a list of at least two VM flag precondition from which at least one must hold when applying + * the IR rule. If none of the VM flag preconditions holds, then the IR rule is not applied. This is useful if + * commonly used flags alter the IR in such a way that an IR rule would fail. This can also be defined as disjunction + * of preconditions. + *

+ * A precondition is a (flag, value) string pair where the flag must be a valid VM flag and the value must conform + * with the type of the VM flag. A number based flag value can be proceeded with an additional comparator + * ({@code =, !=, <, <=, =>, >}) where the equality operator is optional (default if no comparator is specified). + *

+ * Use {@link #applyIfAnd()} for conjunction and for single precondition constraints use {@link #applyIf()}. + */ + String[] applyIfOr() default {}; + /** * Accepts a single pair composed of a platform string followed by a true/false - * value where a true value necessitates that we are currently testing on that platform and vice-versa. + * value where a true value necessitates that we are currently testing on that platform and vice versa. * IR checks are enforced only if the specified platform constraint is met. */ String[] applyIfPlatform() default {}; /** * Accepts a list of pairs where each pair is composed of a platform string followed by a true/false - * value where a true value necessitates that we are currently testing on that platform and vice-versa. + * value where a true value necessitates that we are currently testing on that platform and vice versa. * IR checks are enforced only if all the specified platform constraints are met. */ String[] applyIfPlatformAnd() default {}; /** * Accepts a list of pairs where each pair is composed of a platform string followed by a true/false - * value where a true value necessitates that we are currently testing on that platform and vice-versa. + * value where a true value necessitates that we are currently testing on that platform and vice versa. * IR checks are enforced if any of the specified platform constraints are met. */ String[] applyIfPlatformOr() default {}; /** * Accepts a single feature pair which is composed of CPU feature string followed by a true/false - * value where a true value necessitates existence of CPU feature and vice-versa. + * value where a true value necessitates existence of CPU feature and vice versa. * IR verifications checks are enforced only if the specified feature constraint is met. */ String[] applyIfCPUFeature() default {}; /** * Accepts a list of feature pairs where each pair is composed of target feature string followed by a true/false - * value where a true value necessitates existence of target feature and vice-versa. + * value where a true value necessitates existence of target feature and vice versa. * IR verifications checks are enforced only if all the specified feature constraints are met. */ String[] applyIfCPUFeatureAnd() default {}; /** * Accepts a list of feature pairs where each pair is composed of target feature string followed by a true/false - * value where a true value necessitates existence of target feature and vice-versa. + * value where a true value necessitates existence of target feature and vice versa. * IR verifications checks are enforced if any of the specified feature constraint is met. */ String[] applyIfCPUFeatureOr() default {}; - - /** - * Define a single VM flag precondition which must not hold when applying the IR rule. If, however, - * the VM flag precondition holds, then the IR rule is not applied. This could also be defined as negative - * precondition. This is useful if a commonly used flag alters the IR in such a way that an IR rule would fail. - *

- * The precondition is a (flag, value) string pair where the flag must be a valid VM flag and the value must conform - * with the type of the VM flag. A number based flag value can be proceeded with an additional comparator - * ({@code =, !=, <, <=, =>, >}) where the equality operator is optional (default if no comparator is specified). - *

- * This is the inverse of {@link #applyIf()}. For multiple preconditions, use {@link #applyIfAnd()} or - * {@link #applyIfOr()} depending on the use case. - */ - String[] applyIfNot() default {}; - - /** - * Define a list of at least two VM flag precondition which all must hold when applying the IR rule. - * If the one of the VM flag preconditions does not hold, then the IR rule is not applied. This is useful if - * commonly used flags alter the IR in such a way that an IR rule would fail. This can also be defined as conjunction - * of preconditions. - *

- * A precondition is a (flag, value) string pair where the flag must be a valid VM flag and the value must conform - * with the type of the VM flag. A number based flag value can be proceeded with an additional comparator - * ({@code =, !=, <, <=, =>, >}) where the equality operator is optional (default if no comparator is specified). - *

- * Use {@link #applyIfOr()} for disjunction and for single precondition constraints use {@link #applyIf()} or - * {@link #applyIfNot()} depending on the use case. - */ - String[] applyIfAnd() default {}; - - /** - * Define a list of at least two VM flag precondition from which at least one must hold when applying - * the IR rule. If none of the VM flag preconditions holds, then the IR rule is not applied. This is useful if - * commonly used flags alter the IR in such a way that an IR rule would fail. This can also be defined as disjunction - * of preconditions. - *

- * A precondition is a (flag, value) string pair where the flag must be a valid VM flag and the value must conform - * with the type of the VM flag. A number based flag value can be proceeded with an additional comparator - * ({@code =, !=, <, <=, =>, >}) where the equality operator is optional (default if no comparator is specified). - *

- * Use {@link #applyIfAnd()} for conjunction and for single precondition constraints use {@link #applyIf()} or - * {@link #applyIfNot()} depending on the use case. - */ - String[] applyIfOr() default {}; } diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/README.md b/test/hotspot/jtreg/compiler/lib/ir_framework/README.md index da59bd61b13c..860e2d02969d 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/README.md +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/README.md @@ -118,8 +118,6 @@ The [@IR](./IR.java) annotation provides two kinds of checks: One might also want to restrict the application of certain `@IR` rules depending on the used flags in the Test VM. These could be flags defined by the user or by JTreg. In the latter case, the flags must be whitelisted in `JTREG_WHITELIST_FLAGS` in [TestFramework](./TestFramework.java) (i.e. have no unexpected impact on the IR except if the flag simulates a specific machine setup like `UseAVX={1,2,3}` etc.) to enable an IR verification by the framework. The `@IR` rules thus have an option to restrict their application: - `applyIf`: Only apply a rule if a flag has the specified value/range of values. -- `applyIfNot`: Only apply a rule if a flag has **not** a specified value/range of values - (inverse of `applyIf`). - `applyIfAnd`: Only apply a rule if **all** flags have the specified value/range of values. - `applyIfOr`: Only apply a rule if **at least one** flag has the specified value/range of values. diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/visitor/AcceptChildren.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/LeafMatchResult.java similarity index 53% rename from test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/visitor/AcceptChildren.java rename to test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/LeafMatchResult.java index 7da6e10ab98f..cc6e406c6e7e 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/visitor/AcceptChildren.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/LeafMatchResult.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2026, 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 @@ -21,31 +21,18 @@ * questions. */ -package compiler.lib.ir_framework.driver.irmatching.visitor; - -import compiler.lib.ir_framework.driver.irmatching.MatchResult; - -import java.util.Collection; -import java.util.List; -import java.util.function.Consumer; +package compiler.lib.ir_framework.driver.irmatching; /** - * This class invokes {@link MatchResult#accept(MatchResultVisitor)} on all failed match results (i.e. children) inside - * a {@link MatchResult} object to visit them. + * This interface represents a special leaf match result that does not have any further sub results. */ -public class AcceptChildren implements Consumer { - private final Collection matchResults; - - public AcceptChildren(List matchResults) { - this.matchResults = matchResults; - } +public interface LeafMatchResult extends MatchResult { + /** + * A leaf result does not have sub results and thus returns an empty {@link SubResults} object. + */ @Override - public void accept(MatchResultVisitor visitor) { - for (MatchResult result : matchResults) { - if (result.fail()) { - result.accept(visitor); - } - } + default SubResults subResults() { + return SubResults.createEmpty(); } } diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/MatchResult.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/MatchResult.java index 84a2eeb2f0e5..b1bc840ce9fb 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/MatchResult.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/MatchResult.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,14 +23,12 @@ package compiler.lib.ir_framework.driver.irmatching; -import compiler.lib.ir_framework.driver.irmatching.visitor.AcceptChildren; import compiler.lib.ir_framework.driver.irmatching.visitor.MatchResultVisitor; /** * This interface is implemented by all classes which represent an IR match result of a {@link Matchable} class. * A match result class accepts a {@link MatchResultVisitor} to visit the result (i.e. for reporting etc.). - * The visitor is responsible to call {@link #accept(MatchResultVisitor)} of the children match results by using - * {@link AcceptChildren#accept(MatchResultVisitor)}. + * The visitor is responsible to call {@link #accept(MatchResultVisitor)} on the sub results. */ public interface MatchResult { /** @@ -43,4 +41,9 @@ public interface MatchResult { * visitor. */ void accept(MatchResultVisitor visitor); + + /** + * Returns the sub results of this {@link MatchResult}. + */ + SubResults subResults(); } diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/MatchableMatcher.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/MatchableMatcher.java index 6992cd22184d..507df546e4ad 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/MatchableMatcher.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/MatchableMatcher.java @@ -38,14 +38,11 @@ public MatchableMatcher(Collection matchables) { this.matchables = matchables; } - public List match() { + public SubResults match() { List results = new ArrayList<>(); for (Matchable matchable : matchables) { - MatchResult matchResult = matchable.match(); - if (matchResult.fail()) { - results.add(matchResult); - } + results.add(matchable.match()); } - return results; + return new SubResults(results); } } diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/SubResults.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/SubResults.java new file mode 100644 index 000000000000..aa144b91cb8b --- /dev/null +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/SubResults.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2026, 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. + */ + +package compiler.lib.ir_framework.driver.irmatching; + +import java.util.Iterator; +import java.util.List; + +/** + * Class to represent sub results as part of a {@link MatchResult}. A {@link LeafMatchResult} use an empty sub results + * object. + */ +public class SubResults implements Iterable { + private final List subResults; + private final int failCount; + + public SubResults(List subResults) { + this.failCount = (int)subResults.stream().filter(MatchResult::fail).count(); + this.subResults = subResults; + } + + /** + * Used for {@link LeafMatchResult} objects with no sub results. + */ + public static SubResults createEmpty() { + return new SubResults(List.of()); + } + + /** + * Is there a sub result with a failure? + */ + public boolean hasFailure() { + return failCount > 0; + } + + public int failCount() { + return failCount; + } + + public Iterator iterator() { + return subResults.iterator(); + } +} diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/TestClassMatchResult.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/TestClassMatchResult.java index db043643daf4..8ee9bef557c8 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/TestClassMatchResult.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/TestClassMatchResult.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,33 +23,22 @@ package compiler.lib.ir_framework.driver.irmatching; -import compiler.lib.ir_framework.driver.irmatching.visitor.AcceptChildren; import compiler.lib.ir_framework.driver.irmatching.visitor.MatchResultVisitor; -import java.util.List; - /** * This class represents a matching result of a {@link TestClass}. It contains all IR method results, sorted by * method names. * * @see TestClass */ -public class TestClassMatchResult implements MatchResult { - private final AcceptChildren acceptChildren; - private final boolean failed; - - public TestClassMatchResult(List matchResults) { - this.acceptChildren = new AcceptChildren(matchResults); - this.failed = !matchResults.isEmpty(); - } - +public record TestClassMatchResult(SubResults subResults) implements MatchResult { @Override public boolean fail() { - return failed; + return subResults.hasFailure(); } @Override public void accept(MatchResultVisitor visitor) { - visitor.visitTestClass(acceptChildren); + visitor.visit(this); } } diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irmethod/IRMethod.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irmethod/IRMethod.java index 137766b00115..fa6ea9eef50b 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irmethod/IRMethod.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irmethod/IRMethod.java @@ -26,10 +26,7 @@ import compiler.lib.ir_framework.CompilePhase; import compiler.lib.ir_framework.IR; import compiler.lib.ir_framework.Test; -import compiler.lib.ir_framework.driver.irmatching.Compilation; -import compiler.lib.ir_framework.driver.irmatching.MatchResult; -import compiler.lib.ir_framework.driver.irmatching.Matchable; -import compiler.lib.ir_framework.driver.irmatching.MatchableMatcher; +import compiler.lib.ir_framework.driver.irmatching.*; import compiler.lib.ir_framework.driver.irmatching.irrule.IRRule; import compiler.lib.ir_framework.driver.network.testvm.java.IRRuleIds; import compiler.lib.ir_framework.driver.network.testvm.java.VMInfo; @@ -95,10 +92,10 @@ public MatchResult match() { } long startTime = System.nanoTime(); - List match = matcher.match(); + SubResults subResults = matcher.match(); long endTime = System.nanoTime(); long duration = (endTime - startTime); System.out.println("Verifying IR rules for " + name() + ": " + duration + " ns = " + (duration / 1_000_000) + " ms"); - return new IRMethodMatchResult(method, match); + return new IRMethodMatchResult(method, subResults); } } diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irmethod/IRMethodMatchResult.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irmethod/IRMethodMatchResult.java index 1c86f9ff1e1f..dad67cd9447a 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irmethod/IRMethodMatchResult.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irmethod/IRMethodMatchResult.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2026, 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 @@ -24,11 +24,10 @@ package compiler.lib.ir_framework.driver.irmatching.irmethod; import compiler.lib.ir_framework.driver.irmatching.MatchResult; -import compiler.lib.ir_framework.driver.irmatching.visitor.AcceptChildren; +import compiler.lib.ir_framework.driver.irmatching.SubResults; import compiler.lib.ir_framework.driver.irmatching.visitor.MatchResultVisitor; import java.lang.reflect.Method; -import java.util.List; /** * This class represents a matching result of an {@link IRMethod}. It contains a list of all IR rule match results @@ -36,26 +35,14 @@ * * @see IRMethod */ -public class IRMethodMatchResult implements MatchResult { - private final AcceptChildren acceptChildren; - private final boolean failed; - private final Method method; - private final int failedIRRules; - - public IRMethodMatchResult(Method method, List matchResults) { - this.acceptChildren = new AcceptChildren(matchResults); - this.failed = !matchResults.isEmpty(); - this.method = method; - this.failedIRRules = matchResults.size(); - } - +public record IRMethodMatchResult(Method method, SubResults subResults) implements MatchResult { @Override public boolean fail() { - return failed; + return subResults.hasFailure(); } @Override public void accept(MatchResultVisitor visitor) { - visitor.visitIRMethod(acceptChildren, method, failedIRRules); + visitor.visit(this); } } diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irmethod/NotCompilableIRMethod.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irmethod/NotCompilableIRMethod.java index cb99ea219fe7..27b0c709e437 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irmethod/NotCompilableIRMethod.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irmethod/NotCompilableIRMethod.java @@ -38,11 +38,11 @@ */ public class NotCompilableIRMethod implements IRMethodMatchable { private final Method method; - private final int ruleCount; + private final int irRuleCount; - public NotCompilableIRMethod(Method method, int ruleCount) { + public NotCompilableIRMethod(Method method, int irRuleCount) { this.method = method; - this.ruleCount = ruleCount; + this.irRuleCount = irRuleCount; } @Override @@ -55,6 +55,6 @@ public String name() { */ @Override public NotCompilableIRMethodMatchResult match() { - return new NotCompilableIRMethodMatchResult(method, ruleCount); + return new NotCompilableIRMethodMatchResult(method, irRuleCount); } } diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irmethod/NotCompilableIRMethodMatchResult.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irmethod/NotCompilableIRMethodMatchResult.java index bea8dc3ab27e..01ac82a1dc5b 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irmethod/NotCompilableIRMethodMatchResult.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irmethod/NotCompilableIRMethodMatchResult.java @@ -24,7 +24,7 @@ package compiler.lib.ir_framework.driver.irmatching.irmethod; import compiler.lib.ir_framework.Test; -import compiler.lib.ir_framework.driver.irmatching.MatchResult; +import compiler.lib.ir_framework.driver.irmatching.LeafMatchResult; import compiler.lib.ir_framework.driver.irmatching.visitor.MatchResultVisitor; import java.lang.reflect.Method; @@ -37,14 +37,7 @@ * @see NotCompilableIRMethod * @see Test */ -public class NotCompilableIRMethodMatchResult implements MatchResult { - private final Method method; - private final int failedIRRules; - - public NotCompilableIRMethodMatchResult(Method method, int failedIRRules) { - this.method = method; - this.failedIRRules = failedIRRules; - } +public record NotCompilableIRMethodMatchResult(Method method, int irRuleCount) implements LeafMatchResult { @Override public boolean fail() { @@ -53,7 +46,7 @@ public boolean fail() { @Override public void accept(MatchResultVisitor visitor) { - visitor.visitMethodNotCompilable(method, failedIRRules); + visitor.visitLeaf(this); } } diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irmethod/NotCompiledIRMethod.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irmethod/NotCompiledIRMethod.java index c3737bc8a47d..724df531a0fa 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irmethod/NotCompiledIRMethod.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irmethod/NotCompiledIRMethod.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,11 +38,11 @@ */ public class NotCompiledIRMethod implements IRMethodMatchable { private final Method method; - private final int ruleCount; + private final int irRuleCount; - public NotCompiledIRMethod(Method method, int ruleCount) { + public NotCompiledIRMethod(Method method, int irRuleCount) { this.method = method; - this.ruleCount = ruleCount; + this.irRuleCount = irRuleCount; } @Override @@ -55,6 +55,6 @@ public String name() { */ @Override public NotCompiledIRMethodMatchResult match() { - return new NotCompiledIRMethodMatchResult(method, ruleCount); + return new NotCompiledIRMethodMatchResult(method, irRuleCount); } } diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irmethod/NotCompiledIRMethodMatchResult.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irmethod/NotCompiledIRMethodMatchResult.java index 0f7bd5760129..8c77fee88511 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irmethod/NotCompiledIRMethodMatchResult.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irmethod/NotCompiledIRMethodMatchResult.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ import compiler.lib.ir_framework.Run; import compiler.lib.ir_framework.RunMode; -import compiler.lib.ir_framework.driver.irmatching.MatchResult; +import compiler.lib.ir_framework.driver.irmatching.LeafMatchResult; import compiler.lib.ir_framework.driver.irmatching.visitor.MatchResultVisitor; import java.lang.reflect.Method; @@ -37,14 +37,7 @@ * @see NotCompiledIRMethod * @see Run */ -public class NotCompiledIRMethodMatchResult implements MatchResult { - private final Method method; - private final int failedIRRules; - - public NotCompiledIRMethodMatchResult(Method method, int failedIRRules) { - this.method = method; - this.failedIRRules = failedIRRules; - } +public record NotCompiledIRMethodMatchResult(Method method, int irRuleCount) implements LeafMatchResult { @Override public boolean fail() { @@ -53,7 +46,7 @@ public boolean fail() { @Override public void accept(MatchResultVisitor visitor) { - visitor.visitMethodNotCompiled(method, failedIRRules); + visitor.visitLeaf(this); } } diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/IRRuleMatchResult.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/IRRuleMatchResult.java index c031764ea84e..6af09a89f693 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/IRRuleMatchResult.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/IRRuleMatchResult.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2026, 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 @@ -26,12 +26,10 @@ import compiler.lib.ir_framework.CompilePhase; import compiler.lib.ir_framework.IR; import compiler.lib.ir_framework.driver.irmatching.MatchResult; +import compiler.lib.ir_framework.driver.irmatching.SubResults; import compiler.lib.ir_framework.driver.irmatching.irrule.phase.CompilePhaseIRRuleMatchResult; -import compiler.lib.ir_framework.driver.irmatching.visitor.AcceptChildren; import compiler.lib.ir_framework.driver.irmatching.visitor.MatchResultVisitor; -import java.util.List; - /** * This class represents a match result of an {@link IRRule} (applied to all compile phases specified in * {@link IR#phase()}). The {@link CompilePhaseIRRuleMatchResult} are kept in the definition order of the compile phases @@ -39,26 +37,14 @@ * * @see IRRule */ -public class IRRuleMatchResult implements MatchResult { - private final AcceptChildren acceptChildren; - private final boolean failed; - private final int irRuleId; - private final IR irAnno; - - public IRRuleMatchResult(int irRuleId, IR irAnno, List matchResults) { - this.acceptChildren = new AcceptChildren(matchResults); - this.failed = !matchResults.isEmpty(); - this.irRuleId = irRuleId; - this.irAnno = irAnno; - } - +public record IRRuleMatchResult(int irRuleId, IR irAnno, SubResults subResults) implements MatchResult { @Override public boolean fail() { - return failed; + return subResults.hasFailure(); } @Override public void accept(MatchResultVisitor visitor) { - visitor.visitIRRule(acceptChildren, irRuleId, irAnno); + visitor.visit(this); } } diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/checkattribute/CheckAttributeMatchResult.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/checkattribute/CheckAttributeMatchResult.java index 77febd8dcdab..b637e08117d5 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/checkattribute/CheckAttributeMatchResult.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/checkattribute/CheckAttributeMatchResult.java @@ -25,11 +25,9 @@ import compiler.lib.ir_framework.IR; import compiler.lib.ir_framework.driver.irmatching.MatchResult; -import compiler.lib.ir_framework.driver.irmatching.visitor.AcceptChildren; +import compiler.lib.ir_framework.driver.irmatching.SubResults; import compiler.lib.ir_framework.driver.irmatching.visitor.MatchResultVisitor; -import java.util.List; - /** * This class represents a match result of a {@link CheckAttribute} (i.e. either from {@link IR#failOn} or * {@link IR#counts}). The type of check attribute is defined by {@link CheckAttributeType}. @@ -37,24 +35,15 @@ * @see CheckAttribute * @see CheckAttributeType */ -public class CheckAttributeMatchResult implements MatchResult { - private final AcceptChildren acceptChildren; - private final boolean failed; - private final CheckAttributeType checkAttributeType; - - CheckAttributeMatchResult(CheckAttributeType checkAttributeType, List matchResults) { - this.acceptChildren = new AcceptChildren(matchResults); - this.failed = !matchResults.isEmpty(); - this.checkAttributeType = checkAttributeType; - } - +public record CheckAttributeMatchResult(CheckAttributeType checkAttributeType, + SubResults subResults) implements MatchResult { @Override public boolean fail() { - return failed; + return subResults.hasFailure(); } @Override public void accept(MatchResultVisitor visitor) { - visitor.visitCheckAttribute(acceptChildren, checkAttributeType); + visitor.visit(this); } } diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/constraint/ConstraintFailure.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/constraint/ConstraintFailure.java index b775df7c439a..c5249359e51f 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/constraint/ConstraintFailure.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/constraint/ConstraintFailure.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ package compiler.lib.ir_framework.driver.irmatching.irrule.constraint; -import compiler.lib.ir_framework.driver.irmatching.MatchResult; +import compiler.lib.ir_framework.driver.irmatching.LeafMatchResult; import java.util.List; @@ -32,7 +32,7 @@ * * @see Constraint */ -public interface ConstraintFailure extends MatchResult { +public interface ConstraintFailure extends LeafMatchResult { @Override default boolean fail() { return true; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/constraint/CountsConstraintFailure.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/constraint/CountsConstraintFailure.java index 0a955f465859..d91bae452a8e 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/constraint/CountsConstraintFailure.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/constraint/CountsConstraintFailure.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2026, 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 @@ -39,6 +39,6 @@ public record CountsConstraintFailure(String nodeRegex, int constraintId, List comparison) implements ConstraintFailure { @Override public void accept(MatchResultVisitor visitor) { - visitor.visitCountsConstraint(this); + visitor.visitLeaf(this); } } diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/constraint/FailOnConstraintFailure.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/constraint/FailOnConstraintFailure.java index bce7c418cb42..7f8cff3da5f5 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/constraint/FailOnConstraintFailure.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/constraint/FailOnConstraintFailure.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2026, 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 @@ -43,6 +43,6 @@ public record FailOnConstraintFailure(String nodeRegex, int constraintId, List matchResults) { - this.acceptChildren = new AcceptChildren(matchResults); - this.failed = !matchResults.isEmpty(); - this.compilePhase = compilePhase; - this.compilationOutput = compilationOutput; - } - +public record CompilePhaseIRRuleMatchResult(CompilePhase compilePhase, String compilationOutput, + SubResults subResults) implements MatchResult { @Override public boolean fail() { - return failed; + return subResults.hasFailure(); } @Override public void accept(MatchResultVisitor visitor) { - visitor.visitCompilePhaseIRRule(acceptChildren, compilePhase, compilationOutput); + visitor.visit(this); } } diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/phase/CompilePhaseNoCompilationIRRuleMatchResult.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/phase/CompilePhaseNoCompilationIRRuleMatchResult.java index def040322409..21302cb1d703 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/phase/CompilePhaseNoCompilationIRRuleMatchResult.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/irrule/phase/CompilePhaseNoCompilationIRRuleMatchResult.java @@ -24,7 +24,7 @@ package compiler.lib.ir_framework.driver.irmatching.irrule.phase; import compiler.lib.ir_framework.CompilePhase; -import compiler.lib.ir_framework.driver.irmatching.MatchResult; +import compiler.lib.ir_framework.driver.irmatching.LeafMatchResult; import compiler.lib.ir_framework.driver.irmatching.visitor.MatchResultVisitor; /** @@ -33,7 +33,7 @@ * * @see CompilePhaseNoCompilationIRRule */ -public record CompilePhaseNoCompilationIRRuleMatchResult(CompilePhase compilePhase) implements MatchResult { +public record CompilePhaseNoCompilationIRRuleMatchResult(CompilePhase compilePhase) implements LeafMatchResult { @Override public boolean fail() { @@ -42,6 +42,6 @@ public boolean fail() { @Override public void accept(MatchResultVisitor visitor) { - visitor.visitNoCompilePhaseCompilation(compilePhase); + visitor.visitLeaf(this); } } diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/report/CompilationOutputBuilder.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/report/CompilationOutputBuilder.java index 037da604f4cf..87275851069a 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/report/CompilationOutputBuilder.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/report/CompilationOutputBuilder.java @@ -24,13 +24,14 @@ package compiler.lib.ir_framework.driver.irmatching.report; import compiler.lib.ir_framework.CompilePhase; -import compiler.lib.ir_framework.IR; +import compiler.lib.ir_framework.driver.irmatching.TestClassMatchResult; +import compiler.lib.ir_framework.driver.irmatching.irmethod.IRMethodMatchResult; +import compiler.lib.ir_framework.driver.irmatching.irmethod.NotCompilableIRMethodMatchResult; +import compiler.lib.ir_framework.driver.irmatching.irmethod.NotCompiledIRMethodMatchResult; +import compiler.lib.ir_framework.driver.irmatching.irrule.phase.CompilePhaseIRRuleMatchResult; +import compiler.lib.ir_framework.driver.irmatching.irrule.phase.CompilePhaseNoCompilationIRRuleMatchResult; import compiler.lib.ir_framework.shared.TestFrameworkException; import compiler.lib.ir_framework.driver.irmatching.MatchResult; -import compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.CheckAttributeType; -import compiler.lib.ir_framework.driver.irmatching.irrule.constraint.CountsConstraintFailure; -import compiler.lib.ir_framework.driver.irmatching.irrule.constraint.FailOnConstraintFailure; -import compiler.lib.ir_framework.driver.irmatching.visitor.AcceptChildren; import compiler.lib.ir_framework.driver.irmatching.visitor.MatchResultVisitor; import java.lang.reflect.Method; @@ -59,8 +60,7 @@ public CompilationOutputBuilder(MatchResult testClassMatchResult) { } @Override - public void visitTestClass(AcceptChildren acceptChildren) { - acceptChildren.accept(this); + public void leave(TestClassMatchResult matchResult) { StringBuilder builder = new StringBuilder(); builder.append("Compilation"); if (compilePhaseCount > 1) { @@ -77,16 +77,15 @@ public void visitTestClass(AcceptChildren acceptChildren) { output.insert(0, builder); } - private String getTitleSeparator(int failedIRMethods) { - int failedMethodDashes = failedIRMethods > 1 ? digitCount(failedIRMethods) + 4 : 0; + private String getTitleSeparator(int failedIrMethodCount) { + int failedMethodDashes = failedIrMethodCount > 1 ? digitCount(failedIrMethodCount) + 4 : 0; int compilePhaseDashes = compilePhaseCount > 1 ? digitCount(compilePhaseCount) + 4 : 0; return "-".repeat(28 + compilePhaseDashes + failedMethodDashes); } @Override - public void visitIRMethod(AcceptChildren acceptChildren, Method method, int failedIRRules) { - acceptChildren.accept(this); - appendIRMethodHeader(method); + public void leave(IRMethodMatchResult result) { + appendIRMethodHeader(result.method()); appendMatchedCompilationOutputOfPhases(); failedCompilePhases.clear(); } @@ -116,33 +115,32 @@ private void appendMatchedCompilationOutputOfPhases() { } @Override - public void visitMethodNotCompiled(Method method, int failedIRRules) { - appendIRMethodHeader(method); + public void visitLeaf(NotCompiledIRMethodMatchResult result) { + appendIRMethodHeader(result.method()); compilePhaseCount++; // Count this as one phase output.append("").append(System.lineSeparator()); } @Override - public void visitMethodNotCompilable(Method method, int failedIRRules) { - throw new TestFrameworkException("Sould not reach here"); - } - - @Override - public void visitIRRule(AcceptChildren acceptChildren, int irRuleId, IR irAnno) { - acceptChildren.accept(this); + public void visitLeaf(NotCompilableIRMethodMatchResult result) { + throw new TestFrameworkException("Should not reach here"); } + /** + * We directly override this method to stop visiting check attribute sub results. + */ @Override - public void visitCompilePhaseIRRule(AcceptChildren acceptChildren, CompilePhase compilePhase, String compilationOutput) { + public void visit(CompilePhaseIRRuleMatchResult result) { + CompilePhase compilePhase = result.compilePhase(); if (!failedCompilePhases.containsKey(compilePhase)) { - failedCompilePhases.put(compilePhase, compilationOutput); + failedCompilePhases.put(compilePhase, result.compilationOutput()); compilePhaseCount++; } - // No need to visit check attributes } @Override - public void visitNoCompilePhaseCompilation(CompilePhase compilePhase) { + public void visitLeaf(CompilePhaseNoCompilationIRRuleMatchResult result) { + CompilePhase compilePhase = result.compilePhase(); if (!failedCompilePhases.containsKey(compilePhase)) { failedCompilePhases.put(compilePhase, "> Phase \"" + compilePhase.getName() + "\":" + System.lineSeparator() + "" + @@ -151,15 +149,6 @@ public void visitNoCompilePhaseCompilation(CompilePhase compilePhase) { } } - @Override - public void visitCheckAttribute(AcceptChildren acceptChildren, CheckAttributeType checkAttributeType) {} - - @Override - public void visitFailOnConstraint(FailOnConstraintFailure failOnConstraintFailure) {} - - @Override - public void visitCountsConstraint(CountsConstraintFailure countsConstraintFailure) {} - public String build() { testClassMatchResult.accept(this); return output.toString(); diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/report/FailCountVisitor.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/report/FailCountVisitor.java index 9d1ea6fc4085..e72ae507280c 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/report/FailCountVisitor.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/report/FailCountVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,16 +23,12 @@ package compiler.lib.ir_framework.driver.irmatching.report; -import compiler.lib.ir_framework.CompilePhase; -import compiler.lib.ir_framework.IR; -import compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.CheckAttributeType; -import compiler.lib.ir_framework.driver.irmatching.irrule.constraint.CountsConstraintFailure; -import compiler.lib.ir_framework.driver.irmatching.irrule.constraint.FailOnConstraintFailure; -import compiler.lib.ir_framework.driver.irmatching.visitor.AcceptChildren; +import compiler.lib.ir_framework.driver.irmatching.irmethod.IRMethodMatchResult; +import compiler.lib.ir_framework.driver.irmatching.irmethod.NotCompilableIRMethodMatchResult; +import compiler.lib.ir_framework.driver.irmatching.irmethod.NotCompiledIRMethodMatchResult; +import compiler.lib.ir_framework.driver.irmatching.irrule.IRRuleMatchResult; import compiler.lib.ir_framework.driver.irmatching.visitor.MatchResultVisitor; -import java.lang.reflect.Method; - /** * Visitor to collect the number of IR method and IR rule failures. */ @@ -40,54 +36,36 @@ class FailCountVisitor implements MatchResultVisitor { private int irMethodCount; private int irRuleCount; - @Override - public void visitTestClass(AcceptChildren acceptChildren) { - acceptChildren.accept(this); - } @Override - public void visitIRMethod(AcceptChildren acceptChildren, Method method, int failedIRRules) { + public void enter(IRMethodMatchResult result) { irMethodCount++; - acceptChildren.accept(this); } + /** + * We directly override this method to stop visiting compile phase IR rule sub results. + */ @Override - public void visitIRRule(AcceptChildren acceptChildren, int irRuleId, IR irAnno) { + public void visit(IRRuleMatchResult result) { irRuleCount++; - // Do not need to visit compile phase IR rules } @Override - public void visitMethodNotCompiled(Method method, int failedIRRules) { + public void visitLeaf(NotCompiledIRMethodMatchResult result) { irMethodCount++; - irRuleCount += failedIRRules; + irRuleCount += result.irRuleCount(); } @Override - public void visitMethodNotCompilable(Method method, int failedIRRules) { + public void visitLeaf(NotCompilableIRMethodMatchResult result) { irMethodCount++; } - public int getIrRuleCount() { + public int irRuleCount() { return irRuleCount; } - public int getIrMethodCount() { + public int irMethodCount() { return irMethodCount; } - - @Override - public void visitCompilePhaseIRRule(AcceptChildren acceptChildren, CompilePhase compilePhase, String compilationOutput) {} - - @Override - public void visitNoCompilePhaseCompilation(CompilePhase compilePhase) {} - - @Override - public void visitCheckAttribute(AcceptChildren acceptChildren, CheckAttributeType checkAttributeType) {} - - @Override - public void visitFailOnConstraint(FailOnConstraintFailure failOnConstraintFailure) {} - - @Override - public void visitCountsConstraint(CountsConstraintFailure countsConstraintFailure) {} } diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/report/FailureMessageBuilder.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/report/FailureMessageBuilder.java index f52c5f8fb5fc..e4dd98959a09 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/report/FailureMessageBuilder.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/report/FailureMessageBuilder.java @@ -24,13 +24,19 @@ package compiler.lib.ir_framework.driver.irmatching.report; import compiler.lib.ir_framework.CompilePhase; -import compiler.lib.ir_framework.IR; +import compiler.lib.ir_framework.driver.irmatching.TestClassMatchResult; +import compiler.lib.ir_framework.driver.irmatching.irmethod.IRMethodMatchResult; +import compiler.lib.ir_framework.driver.irmatching.irmethod.NotCompilableIRMethodMatchResult; +import compiler.lib.ir_framework.driver.irmatching.irmethod.NotCompiledIRMethodMatchResult; +import compiler.lib.ir_framework.driver.irmatching.irrule.IRRuleMatchResult; +import compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.CheckAttributeMatchResult; +import compiler.lib.ir_framework.driver.irmatching.irrule.phase.CompilePhaseIRRuleMatchResult; +import compiler.lib.ir_framework.driver.irmatching.irrule.phase.CompilePhaseNoCompilationIRRuleMatchResult; import compiler.lib.ir_framework.shared.TestFrameworkException; import compiler.lib.ir_framework.driver.irmatching.MatchResult; import compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.CheckAttributeType; import compiler.lib.ir_framework.driver.irmatching.irrule.constraint.CountsConstraintFailure; import compiler.lib.ir_framework.driver.irmatching.irrule.constraint.FailOnConstraintFailure; -import compiler.lib.ir_framework.driver.irmatching.visitor.AcceptChildren; import compiler.lib.ir_framework.driver.irmatching.visitor.MatchResultVisitor; import java.lang.reflect.Method; @@ -50,11 +56,11 @@ public FailureMessageBuilder(MatchResult testClassMatchResult) { } @Override - public void visitTestClass(AcceptChildren acceptChildren) { + public void enter(TestClassMatchResult result) { FailCountVisitor failCountVisitor = new FailCountVisitor(); testClassMatchResult.accept(failCountVisitor); - int failedMethodCount = failCountVisitor.getIrMethodCount(); - int failedIRRulesCount = failCountVisitor.getIrRuleCount(); + int failedMethodCount = failCountVisitor.irMethodCount(); + int failedIRRulesCount = failCountVisitor.irRuleCount(); msg.append("One or more @IR rules failed:") .append(System.lineSeparator()) .append(System.lineSeparator()) @@ -62,7 +68,6 @@ public void visitTestClass(AcceptChildren acceptChildren) { .append(")").append(System.lineSeparator()) .append(getTitleSeparator(failedMethodCount, failedIRRulesCount)) .append(System.lineSeparator()); - acceptChildren.accept(this); } private static String getTitleSeparator(int failedMethodCount, int failedIRRulesCount) { @@ -70,12 +75,22 @@ private static String getTitleSeparator(int failedMethodCount, int failedIRRules } @Override - public void visitIRMethod(AcceptChildren acceptChildren, Method method, int failedIRRules) { - appendIRMethodHeader(method, failedIRRules); - acceptChildren.accept(this); + public void enter(IRMethodMatchResult result) { + appendIRMethodHeader(result.method(), result.subResults().failCount()); } - private void appendIRMethodHeader(Method method, int failedIRRules) { + @Override + public void visitLeaf(NotCompiledIRMethodMatchResult result) { + appendIRMethodHeader(result.method(), result.irRuleCount()); + indentation.add(); + msg.append(indentation) + .append("* Method was not compiled. Did you specify a @Run method in STANDALONE mode? In this case, make " + + "sure to always trigger a C2 compilation by invoking the test enough times.") + .append(System.lineSeparator()); + indentation.sub(); + } + + private void appendIRMethodHeader(Method method, int failedIrRuleCount) { methodIndex++; indentation = new Indentation(digitCount(methodIndex)); if (methodIndex > 1) { @@ -84,52 +99,42 @@ private void appendIRMethodHeader(Method method, int failedIRRules) { msg.append(methodIndex).append(") "); msg.append("Method \"") .append(method.getDeclaringClass().getTypeName()).append("::").append(method.getName()) - .append("\" - [Failed IR rules: ").append(failedIRRules).append("]:") + .append("\" - [Failed IR rules: ").append(failedIrRuleCount).append("]:") .append(System.lineSeparator()); } @Override - public void visitMethodNotCompiled(Method method, int failedIRRules) { - appendIRMethodHeader(method, failedIRRules); - indentation.add(); - msg.append(indentation) - .append("* Method was not compiled. Did you specify a @Run method in STANDALONE mode? In this case, make " + - "sure to always trigger a C2 compilation by invoking the test enough times.") - .append(System.lineSeparator()); - indentation.sub(); + public void visitLeaf(NotCompilableIRMethodMatchResult result) { + throw new TestFrameworkException("Should not reach here"); } - public void visitMethodNotCompilable(Method method, int failedIRRules) { - throw new TestFrameworkException("Sould not reach here"); + @Override + public void enter(IRRuleMatchResult result) { + indentation.add(); + msg.append(indentation).append("* @IR rule ").append(result.irRuleId()).append(": \"") + .append(result.irAnno()).append("\"").append(System.lineSeparator()); } @Override - public void visitIRRule(AcceptChildren acceptChildren, int irRuleId, IR irAnno) { - indentation.add(); - msg.append(indentation).append("* @IR rule ").append(irRuleId).append(": \"") - .append(irAnno).append("\"").append(System.lineSeparator()); - acceptChildren.accept(this); + public void leave(IRRuleMatchResult result) { indentation.sub(); } @Override - public void visitCompilePhaseIRRule(AcceptChildren acceptChildren, CompilePhase compilePhase, String compilationOutput) { + public void enter(CompilePhaseIRRuleMatchResult result) { indentation.add(); - appendCompilePhaseIRRule(compilePhase); - acceptChildren.accept(this); - indentation.sub(); + appendCompilePhaseIRRule(result.compilePhase()); } - private void appendCompilePhaseIRRule(CompilePhase compilePhase) { - msg.append(indentation) - .append("> Phase \"").append(compilePhase.getName()).append("\":") - .append(System.lineSeparator()); + @Override + public void leave(CompilePhaseIRRuleMatchResult result) { + indentation.sub(); } @Override - public void visitNoCompilePhaseCompilation(CompilePhase compilePhase) { + public void visitLeaf(CompilePhaseNoCompilationIRRuleMatchResult result) { indentation.add(); - appendCompilePhaseIRRule(compilePhase); + appendCompilePhaseIRRule(result.compilePhase()); indentation.add(); msg.append(indentation) .append("- NO compilation output found for this phase! Make sure this phase is emitted or remove it from ") @@ -139,8 +144,15 @@ public void visitNoCompilePhaseCompilation(CompilePhase compilePhase) { indentation.sub(); } + private void appendCompilePhaseIRRule(CompilePhase compilePhase) { + msg.append(indentation) + .append("> Phase \"").append(compilePhase.getName()).append("\":") + .append(System.lineSeparator()); + } + @Override - public void visitCheckAttribute(AcceptChildren acceptChildren, CheckAttributeType checkAttributeType) { + public void enter(CheckAttributeMatchResult result) { + CheckAttributeType checkAttributeType = result.checkAttributeType(); indentation.add(); String checkAttributeFailureMsg; switch (checkAttributeType) { @@ -151,15 +163,18 @@ public void visitCheckAttribute(AcceptChildren acceptChildren, CheckAttributeTyp } msg.append(indentation).append("- ").append(checkAttributeFailureMsg) .append(":").append(System.lineSeparator()); - acceptChildren.accept(this); + } + + @Override + public void leave(CheckAttributeMatchResult result) { indentation.sub(); } @Override - public void visitFailOnConstraint(FailOnConstraintFailure matchResult) { + public void visitLeaf(FailOnConstraintFailure result) { indentation.add(); ConstraintFailureMessageBuilder constrainFailureMessageBuilder = - new ConstraintFailureMessageBuilder(matchResult, indentation); + new ConstraintFailureMessageBuilder(result, indentation); String failureMessage = constrainFailureMessageBuilder.buildConstraintHeader() + constrainFailureMessageBuilder.buildMatchedNodesMessage("Matched forbidden"); msg.append(failureMessage); @@ -167,9 +182,9 @@ public void visitFailOnConstraint(FailOnConstraintFailure matchResult) { } @Override - public void visitCountsConstraint(CountsConstraintFailure matchResult) { + public void visitLeaf(CountsConstraintFailure result) { indentation.add(); - msg.append(new CountsConstraintFailureMessageBuilder(matchResult, indentation).build()); + msg.append(new CountsConstraintFailureMessageBuilder(result, indentation).build()); indentation.sub(); } diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/visitor/MatchResultVisitor.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/visitor/MatchResultVisitor.java index 8191cfd55c0c..87073a27d0e3 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/visitor/MatchResultVisitor.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/irmatching/visitor/MatchResultVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,28 +23,133 @@ package compiler.lib.ir_framework.driver.irmatching.visitor; -import compiler.lib.ir_framework.CompilePhase; -import compiler.lib.ir_framework.IR; +import compiler.lib.ir_framework.driver.irmatching.LeafMatchResult; import compiler.lib.ir_framework.driver.irmatching.MatchResult; -import compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.CheckAttributeType; +import compiler.lib.ir_framework.driver.irmatching.TestClassMatchResult; +import compiler.lib.ir_framework.driver.irmatching.irmethod.IRMethodMatchResult; +import compiler.lib.ir_framework.driver.irmatching.irmethod.NotCompilableIRMethodMatchResult; +import compiler.lib.ir_framework.driver.irmatching.irmethod.NotCompiledIRMethodMatchResult; +import compiler.lib.ir_framework.driver.irmatching.irrule.IRRuleMatchResult; +import compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.CheckAttributeMatchResult; import compiler.lib.ir_framework.driver.irmatching.irrule.constraint.CountsConstraintFailure; import compiler.lib.ir_framework.driver.irmatching.irrule.constraint.FailOnConstraintFailure; +import compiler.lib.ir_framework.driver.irmatching.irrule.phase.CompilePhaseIRRuleMatchResult; +import compiler.lib.ir_framework.driver.irmatching.irrule.phase.CompilePhaseNoCompilationIRRuleMatchResult; -import java.lang.reflect.Method; +import java.util.function.Consumer; /** * This interface specifies visit methods for each {@link MatchResult} class must be implemented a by a concrete visitor. + * + *

+ * There are two kinds of visits: + * + *

    + *
  1. + * {@link #visit} on {@link MatchResult}s that can have one or more sub results. This interface provides the following + * default implementation for them (directly override this method when you do not want to visit sub results later): + *
      + *
    1. + * {@link #enter}: First called to visit the current {@link MatchResult} before visiting sub results. Override + * this method to specify behavior at this stage. Afterward, the sub results will be visited. + * By default, this method does nothing. + *
    2. + *
    3. + * {@link #visitSubResults}: Called after {@link #enter} to visit the sub results. This should not be overridden. + *
    4. + *
    5. + * {@link #leave}: After visiting the sub results, this method is called to visit the current {@link MatchResult} + * again to do some post work. Override this method to specify behavior at this stage. + * By default, this method does nothing. + *
    6. + *
    + *
  2. + *
  3. + * {@link #visitLeaf} on {@link LeafMatchResult}s that do not have any sub results. This interface provides + * an empty default implementation. Override {@link #visitLeaf} to specify a different behavior. + *
  4. + *
*/ public interface MatchResultVisitor { - void visitTestClass(AcceptChildren acceptChildren); - void visitIRMethod(AcceptChildren acceptChildren, Method method, int failedIRRules); - void visitMethodNotCompiled(Method method, int failedIRRules); - void visitMethodNotCompilable(Method method, int failedIRRules); - void visitIRRule(AcceptChildren acceptChildren, int irRuleId, IR irAnno); - void visitCompilePhaseIRRule(AcceptChildren acceptChildren, CompilePhase compilePhase, String compilationOutput); - void visitNoCompilePhaseCompilation(CompilePhase compilePhase); - void visitCheckAttribute(AcceptChildren acceptChildren, CheckAttributeType checkAttributeType); - void visitFailOnConstraint(FailOnConstraintFailure failOnConstraintFailure); - void visitCountsConstraint(CountsConstraintFailure countsConstraintFailure); -} + /** + * Should a result be visited? By default, we only visit failing results. Override this method to change this behavior. + */ + default boolean shouldVisit(MatchResult result) { + return result.fail(); + } + + default void visit(TestClassMatchResult result) { + doVisit(result, this::enter, this::leave); + } + + default void enter(TestClassMatchResult result) {} + default void leave(TestClassMatchResult result) {} + + default void visit(IRMethodMatchResult result) { + doVisit(result, this::enter, this::leave); + } + + default void enter(IRMethodMatchResult result) {} + default void leave(IRMethodMatchResult result) {} + + default void visit(IRRuleMatchResult result) { + doVisit(result, this::enter, this::leave); + } + + default void enter(IRRuleMatchResult result) {} + default void leave(IRRuleMatchResult result) {} + + default void visit(CompilePhaseIRRuleMatchResult result) { + doVisit(result, this::enter, this::leave); + } + + default void enter(CompilePhaseIRRuleMatchResult result) {} + default void leave(CompilePhaseIRRuleMatchResult result) {} + + default void visit(CheckAttributeMatchResult result) { + doVisit(result, this::enter, this::leave); + } + + default void enter(CheckAttributeMatchResult result) {} + default void leave(CheckAttributeMatchResult result) {} + + /** + * Default visit when {@link #visit} is not overridden. + * + *

+ * Note: Do not override this method. + */ + default void doVisit(R result, Consumer enter, Consumer leave) { + if (!shouldVisit(result)) { + return; + } + enter.accept(result); + visitSubResults(result); + leave.accept(result); + } + + /** + * Visit children of {@code result}. This is called when {@link #visit} is not overridden. + * + *

+ * Note: Do not override this method. + */ + default void visitSubResults(MatchResult result) { + for (MatchResult subResult : result.subResults()) { + if (shouldVisit(subResult)) { + subResult.accept(this); + } + } + } + + /* + * Visit methods for LeafMatchResults without sub results. + */ + + default void visitLeaf(CompilePhaseNoCompilationIRRuleMatchResult result) {} + default void visitLeaf(NotCompiledIRMethodMatchResult result) {} + default void visitLeaf(NotCompilableIRMethodMatchResult result) {} + default void visitLeaf(FailOnConstraintFailure result) {} + default void visitLeaf(CountsConstraintFailure result) {} +} diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/test/ApplicableIRRulesPrinter.java b/test/hotspot/jtreg/compiler/lib/ir_framework/test/ApplicableIRRulesPrinter.java index a4797a29dc78..71f719284425 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/test/ApplicableIRRulesPrinter.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/test/ApplicableIRRulesPrinter.java @@ -196,9 +196,6 @@ private boolean shouldApplyIrRule(IR irAnno, String m, int ruleIndex, int ruleMa } else if (irAnno.applyIf().length != 0 && !hasAllRequiredFlags(irAnno.applyIf(), "applyIf")) { printDisableReason(m, "Flag constraint not met (applyIf)", irAnno.applyIf(), ruleIndex, ruleMax); return false; - } else if (irAnno.applyIfNot().length != 0 && !hasNoRequiredFlags(irAnno.applyIfNot(), "applyIfNot")) { - printDisableReason(m, "Flag constraint not met (applyIfNot)", irAnno.applyIfNot(), ruleIndex, ruleMax); - return false; } else if (irAnno.applyIfAnd().length != 0 && !hasAllRequiredFlags(irAnno.applyIfAnd(), "applyIfAnd")) { printDisableReason(m, "Not all flag constraints are met (applyIfAnd)", irAnno.applyIfAnd(), ruleIndex, ruleMax); return false; @@ -220,12 +217,12 @@ private void checkIRAnnotations(IR irAnno) { if (irAnno.applyIfAnd().length != 0) { flagConstraints++; TestFormat.checkNoThrow(irAnno.applyIfAnd().length > 2, - "Use applyIf or applyIfNot or at least 2 conditions for applyIfAnd" + failAt()); + "Use applyIf or at least 2 conditions for applyIfAnd" + failAt()); } if (irAnno.applyIfOr().length != 0) { flagConstraints++; TestFormat.checkNoThrow(irAnno.applyIfOr().length > 2, - "Use applyIf or applyIfNot or at least 2 conditions for applyIfOr" + failAt()); + "Use applyIf or at least 2 conditions for applyIfOr" + failAt()); } if (irAnno.applyIf().length != 0) { flagConstraints++; @@ -262,11 +259,6 @@ private void checkIRAnnotations(IR irAnno) { TestFormat.checkNoThrow(irAnno.applyIfCPUFeatureOr().length % 2 == 0, "applyIfCPUFeatureOr expects more than one CPU feature pair" + failAt()); } - if (irAnno.applyIfNot().length != 0) { - flagConstraints++; - TestFormat.checkNoThrow(irAnno.applyIfNot().length <= 2, - "Use applyIfAnd or applyIfOr or only 1 condition for applyIfNot" + failAt()); - } TestFormat.checkNoThrow(flagConstraints <= 1, "Can only specify one flag constraint" + failAt()); TestFormat.checkNoThrow(platformConstraints <= 1, "Can only specify one platform constraint" + failAt()); TestFormat.checkNoThrow(cpuFeatureConstraints <= 1, "Can only specify one CPU feature constraint" + failAt()); diff --git a/test/hotspot/jtreg/compiler/vectorapi/TestMaskedMacroLogicVector.java b/test/hotspot/jtreg/compiler/vectorapi/TestMaskedMacroLogicVector.java index 69473ff72b3e..22c35d80c70c 100644 --- a/test/hotspot/jtreg/compiler/vectorapi/TestMaskedMacroLogicVector.java +++ b/test/hotspot/jtreg/compiler/vectorapi/TestMaskedMacroLogicVector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /** * @test - * @bug 8273322 + * @bug 8273322 8387145 * @key randomness * @summary Enhance macro logic optimization for masked logic operations. * @modules jdk.incubator.vector @@ -65,6 +65,7 @@ public class TestMaskedMacroLogicVector { long [] cl; boolean [] mask; + boolean [] mask2; static boolean booleanFunc1(boolean a, boolean b) { return a & b; @@ -504,6 +505,147 @@ public void verifyInt8(int[] r, int[] a, int[] b, int[] c, boolean [] mask) { } } + static int intFunc9(int a, int b, int c, boolean mask, boolean mask2) { + int left = mask ? (b & a) : b; + int right = mask2 ? (c & a) : c; + return mask ? (left ^ right) : left; + } + + @ForceInline + public void testInt9Kernel(VectorSpecies SPECIES, int[] r, int[] a, int[] b, int[] c, boolean [] mask, boolean [] mask2) { + for (int i = 0; i < SPECIES.loopBound(r.length); i += SPECIES.length()) { + VectorMask vmask = VectorMask.fromArray(SPECIES, mask , i); + VectorMask vmask2 = VectorMask.fromArray(SPECIES, mask2, i); + IntVector va = IntVector.fromArray(SPECIES, a, i); + IntVector vb = IntVector.fromArray(SPECIES, b, i); + IntVector vc = IntVector.fromArray(SPECIES, c, i); + vb.lanewise(VectorOperators.AND, va, vmask) + .lanewise(VectorOperators.XOR, + vc.lanewise(VectorOperators.AND, va, vmask2), vmask) + .intoArray(r, i); + } + } + + @Test + @IR(applyIf = {"UseAVX", "3"}, counts = {IRNode.MACRO_LOGIC_V, " > 0 "}) + public void testInt9_Int128(int[] r, int[] a, int[] b, int[] c, boolean [] mask, boolean [] mask2) { + testInt9Kernel(IntVector.SPECIES_128, r, a, b, c, mask, mask2); + } + @Test + @IR(applyIf = {"UseAVX", "3"}, counts = {IRNode.MACRO_LOGIC_V, " > 0 "}) + public void testInt9_Int256(int[] r, int[] a, int[] b, int[] c, boolean [] mask, boolean [] mask2) { + testInt9Kernel(IntVector.SPECIES_256, r, a, b, c, mask, mask2); + } + @Test + @IR(applyIf = {"UseAVX", "3"}, counts = {IRNode.MACRO_LOGIC_V, " > 0 "}) + public void testInt9_Int512(int[] r, int[] a, int[] b, int[] c, boolean [] mask, boolean [] mask2) { + testInt9Kernel(IntVector.SPECIES_512, r, a, b, c, mask, mask2); + } + + public void verifyInt9(int[] r, int[] a, int[] b, int[] c, boolean [] mask, boolean [] mask2) { + for (int i = 0; i < r.length; i++) { + int expected = intFunc9(a[i], b[i], c[i], mask[i], mask2[i]); + if (r[i] != expected) { + throw new AssertionError(String.format("testInt9: at #%d: r=%d, expected = %d = intFunc9(%d,%d,%d,%b,%b)", + i, r[i], expected, a[i], b[i], c[i], mask[i], mask2[i])); + } + } + } + + static int intFunc10(int a, int b, int c, boolean mask, boolean mask2) { + int left = mask ? (a & b) : a; + int right = mask2 ? (a | c) : a; + return mask ? (left | right) : left; + } + + @ForceInline + public void testInt10Kernel(VectorSpecies SPECIES, int[] r, int[] a, int[] b, int[] c, boolean [] mask, boolean [] mask2) { + for (int i = 0; i < SPECIES.loopBound(r.length); i += SPECIES.length()) { + VectorMask vmask = VectorMask.fromArray(SPECIES, mask , i); + VectorMask vmask2 = VectorMask.fromArray(SPECIES, mask2, i); + IntVector va = IntVector.fromArray(SPECIES, a, i); + IntVector vb = IntVector.fromArray(SPECIES, b, i); + IntVector vc = IntVector.fromArray(SPECIES, c, i); + va.lanewise(VectorOperators.AND, vb, vmask) + .lanewise(VectorOperators.OR, + va.lanewise(VectorOperators.OR, vc, vmask2), vmask) + .intoArray(r, i); + } + } + + @Test + @IR(applyIf = {"UseAVX", "3"}, counts = {IRNode.MACRO_LOGIC_V, " > 0 "}) + public void testInt10_Int128(int[] r, int[] a, int[] b, int[] c, boolean [] mask, boolean [] mask2) { + testInt10Kernel(IntVector.SPECIES_128, r, a, b, c, mask, mask2); + } + @Test + @IR(applyIf = {"UseAVX", "3"}, counts = {IRNode.MACRO_LOGIC_V, " > 0 "}) + public void testInt10_Int256(int[] r, int[] a, int[] b, int[] c, boolean [] mask, boolean [] mask2) { + testInt10Kernel(IntVector.SPECIES_256, r, a, b, c, mask, mask2); + } + @Test + @IR(applyIf = {"UseAVX", "3"}, counts = {IRNode.MACRO_LOGIC_V, " > 0 "}) + public void testInt10_Int512(int[] r, int[] a, int[] b, int[] c, boolean [] mask, boolean [] mask2) { + testInt10Kernel(IntVector.SPECIES_512, r, a, b, c, mask, mask2); + } + + public void verifyInt10(int[] r, int[] a, int[] b, int[] c, boolean [] mask, boolean [] mask2) { + for (int i = 0; i < r.length; i++) { + int expected = intFunc10(a[i], b[i], c[i], mask[i], mask2[i]); + if (r[i] != expected) { + throw new AssertionError(String.format("testInt10: at #%d: r=%d, expected = %d = intFunc10(%d,%d,%d,%b,%b)", + i, r[i], expected, a[i], b[i], c[i], mask[i], mask2[i])); + } + } + } + + static int intFunc11(int a, int b, int c, boolean mask, boolean mask2) { + int left = mask ? (a ^ b) : a; + int right = mask2 ? (a & c) : a; + return mask ? (left & right) : left; + } + + @ForceInline + public void testInt11Kernel(VectorSpecies SPECIES, int[] r, int[] a, int[] b, int[] c, boolean [] mask, boolean [] mask2) { + for (int i = 0; i < SPECIES.loopBound(r.length); i += SPECIES.length()) { + VectorMask vmask = VectorMask.fromArray(SPECIES, mask , i); + VectorMask vmask2 = VectorMask.fromArray(SPECIES, mask2, i); + IntVector va = IntVector.fromArray(SPECIES, a, i); + IntVector vb = IntVector.fromArray(SPECIES, b, i); + IntVector vc = IntVector.fromArray(SPECIES, c, i); + va.lanewise(VectorOperators.XOR, vb, vmask) + .lanewise(VectorOperators.AND, + va.lanewise(VectorOperators.AND, vc, vmask2), vmask) + .intoArray(r, i); + } + } + + @Test + @IR(applyIf = {"UseAVX", "3"}, counts = {IRNode.MACRO_LOGIC_V, " > 0 "}) + public void testInt11_Int128(int[] r, int[] a, int[] b, int[] c, boolean [] mask, boolean [] mask2) { + testInt11Kernel(IntVector.SPECIES_128, r, a, b, c, mask, mask2); + } + @Test + @IR(applyIf = {"UseAVX", "3"}, counts = {IRNode.MACRO_LOGIC_V, " > 0 "}) + public void testInt11_Int256(int[] r, int[] a, int[] b, int[] c, boolean [] mask, boolean [] mask2) { + testInt11Kernel(IntVector.SPECIES_256, r, a, b, c, mask, mask2); + } + @Test + @IR(applyIf = {"UseAVX", "3"}, counts = {IRNode.MACRO_LOGIC_V, " > 0 "}) + public void testInt11_Int512(int[] r, int[] a, int[] b, int[] c, boolean [] mask, boolean [] mask2) { + testInt11Kernel(IntVector.SPECIES_512, r, a, b, c, mask, mask2); + } + + public void verifyInt11(int[] r, int[] a, int[] b, int[] c, boolean [] mask, boolean [] mask2) { + for (int i = 0; i < r.length; i++) { + int expected = intFunc11(a[i], b[i], c[i], mask[i], mask2[i]); + if (r[i] != expected) { + throw new AssertionError(String.format("testInt11: at #%d: r=%d, expected = %d = intFunc11(%d,%d,%d,%b,%b)", + i, r[i], expected, a[i], b[i], c[i], mask[i], mask2[i])); + } + } + } + // ===================================================== // @@ -798,6 +940,72 @@ public void kernel_testInt8_Int512() { } } + @Run(test = {"testInt9_Int128"}, mode = RunMode.STANDALONE) + public void kernel_testInt9_Int128() { + for (int i = 0; i < 10000; i++) { + testInt9_Int128(r, a, b, c, mask, mask2); + verifyInt9(r, a, b, c, mask, mask2); + } + } + @Run(test = {"testInt9_Int256"}, mode = RunMode.STANDALONE) + public void kernel_testInt9_Int256() { + for (int i = 0; i < 10000; i++) { + testInt9_Int256(r, a, b, c, mask, mask2); + verifyInt9(r, a, b, c, mask, mask2); + } + } + @Run(test = {"testInt9_Int512"}, mode = RunMode.STANDALONE) + public void kernel_testInt9_Int512() { + for (int i = 0; i < 10000; i++) { + testInt9_Int512(r, a, b, c, mask, mask2); + verifyInt9(r, a, b, c, mask, mask2); + } + } + + @Run(test = {"testInt10_Int128"}, mode = RunMode.STANDALONE) + public void kernel_testInt10_Int128() { + for (int i = 0; i < 10000; i++) { + testInt10_Int128(r, a, b, c, mask, mask2); + verifyInt10(r, a, b, c, mask, mask2); + } + } + @Run(test = {"testInt10_Int256"}, mode = RunMode.STANDALONE) + public void kernel_testInt10_Int256() { + for (int i = 0; i < 10000; i++) { + testInt10_Int256(r, a, b, c, mask, mask2); + verifyInt10(r, a, b, c, mask, mask2); + } + } + @Run(test = {"testInt10_Int512"}, mode = RunMode.STANDALONE) + public void kernel_testInt10_Int512() { + for (int i = 0; i < 10000; i++) { + testInt10_Int512(r, a, b, c, mask, mask2); + verifyInt10(r, a, b, c, mask, mask2); + } + } + + @Run(test = {"testInt11_Int128"}, mode = RunMode.STANDALONE) + public void kernel_testInt11_Int128() { + for (int i = 0; i < 10000; i++) { + testInt11_Int128(r, a, b, c, mask, mask2); + verifyInt11(r, a, b, c, mask, mask2); + } + } + @Run(test = {"testInt11_Int256"}, mode = RunMode.STANDALONE) + public void kernel_testInt11_Int256() { + for (int i = 0; i < 10000; i++) { + testInt11_Int256(r, a, b, c, mask, mask2); + verifyInt11(r, a, b, c, mask, mask2); + } + } + @Run(test = {"testInt11_Int512"}, mode = RunMode.STANDALONE) + public void kernel_testInt11_Int512() { + for (int i = 0; i < 10000; i++) { + testInt11_Int512(r, a, b, c, mask, mask2); + verifyInt11(r, a, b, c, mask, mask2); + } + } + @Run(test = {"testLong_Long256"}, mode = RunMode.STANDALONE) public void kernel_testLong_Long256() { for (int i = 0; i < 10000; i++) { @@ -836,6 +1044,7 @@ public TestMaskedMacroLogicVector() { cl = fillLongRandom(() -> new long[SIZE]); mask = fillBooleanRandom((()-> new boolean[SIZE])); + mask2 = fillBooleanRandom((()-> new boolean[SIZE])); } public static void main(String[] args) { diff --git a/test/hotspot/jtreg/compiler/vectorapi/VectorMaskLaneIsSetTest.java b/test/hotspot/jtreg/compiler/vectorapi/VectorMaskLaneIsSetTest.java index 17d483f1b16d..f318f01ebace 100644 --- a/test/hotspot/jtreg/compiler/vectorapi/VectorMaskLaneIsSetTest.java +++ b/test/hotspot/jtreg/compiler/vectorapi/VectorMaskLaneIsSetTest.java @@ -68,8 +68,8 @@ public class VectorMaskLaneIsSetTest { } @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" }) + @IR(counts = { IRNode.VECTOR_MASK_LANE_IS_SET, "= 6" }, applyIfCPUFeatureOr = { "asimd", "true", "rvv", "true" }) + @IR(counts = { IRNode.VECTOR_MASK_TO_LONG, "= 6" }, applyIfCPUFeature = { "avx2", "true" }) public static void testVectorMaskLaneIsSetByte_const() { Asserts.assertEquals(ma[0], mask_b.laneIsSet(0)); Asserts.assertEquals(ma[0], mask_s.laneIsSet(0)); @@ -80,8 +80,8 @@ public static void testVectorMaskLaneIsSetByte_const() { } @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" }) + @IR(counts = { IRNode.VECTOR_MASK_LANE_IS_SET, "= 1" }, applyIfCPUFeatureOr = { "asimd", "true", "rvv", "true" }) + @IR(counts = { IRNode.VECTOR_MASK_TO_LONG, "= 1" }, applyIfCPUFeature = { "avx", "true" }) public static boolean testVectorMaskLaneIsSet_Byte_variable(int i) { return mask_b.laneIsSet(i); } @@ -92,8 +92,8 @@ public static void testVectorMaskLaneIsSet_Byte_variable_runner() { } @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" }) + @IR(counts = { IRNode.VECTOR_MASK_LANE_IS_SET, "= 1" }, applyIfCPUFeatureOr = { "asimd", "true", "rvv", "true" }) + @IR(counts = { IRNode.VECTOR_MASK_TO_LONG, "= 1" }, applyIfCPUFeature = { "avx", "true" }) public static boolean testVectorMaskLaneIsSet_Short_variable(int i) { return mask_s.laneIsSet(i); } @@ -104,8 +104,8 @@ public static void testVectorMaskLaneIsSet_Short_variable_runner() { } @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" }) + @IR(counts = { IRNode.VECTOR_MASK_LANE_IS_SET, "= 1" }, applyIfCPUFeatureOr = { "asimd", "true", "rvv", "true" }) + @IR(counts = { IRNode.VECTOR_MASK_TO_LONG, "= 1" }, applyIfCPUFeature = { "avx", "true" }) public static boolean testVectorMaskLaneIsSet_Int_variable(int i) { return mask_i.laneIsSet(i); } @@ -116,8 +116,8 @@ public static void testVectorMaskLaneIsSet_Int_variable_runner() { } @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" }) + @IR(counts = { IRNode.VECTOR_MASK_LANE_IS_SET, "= 1" }, applyIfCPUFeatureOr = { "asimd", "true", "rvv", "true" }) + @IR(counts = { IRNode.VECTOR_MASK_TO_LONG, "= 1" }, applyIfCPUFeature = { "avx2", "true" }) public static boolean testVectorMaskLaneIsSet_Long_variable(int i) { return mask_l.laneIsSet(i); } @@ -128,8 +128,8 @@ public static void testVectorMaskLaneIsSet_Long_variable_runner() { } @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" }) + @IR(counts = { IRNode.VECTOR_MASK_LANE_IS_SET, "= 1" }, applyIfCPUFeatureOr = { "asimd", "true", "rvv", "true" }) + @IR(counts = { IRNode.VECTOR_MASK_TO_LONG, "= 1" }, applyIfCPUFeature = { "avx", "true" }) public static boolean testVectorMaskLaneIsSet_Float_variable(int i) { return mask_f.laneIsSet(i); } @@ -140,8 +140,8 @@ public static void testVectorMaskLaneIsSet_Float_variable_runner() { } @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" }) + @IR(counts = { IRNode.VECTOR_MASK_LANE_IS_SET, "= 1" }, applyIfCPUFeatureOr = { "asimd", "true", "rvv", "true" }) + @IR(counts = { IRNode.VECTOR_MASK_TO_LONG, "= 1" }, applyIfCPUFeature = { "avx2", "true" }) public static boolean testVectorMaskLaneIsSet_Double_variable(int i) { return mask_d.laneIsSet(i); } diff --git a/test/hotspot/jtreg/containers/docker/TestMemoryAwareness.java b/test/hotspot/jtreg/containers/docker/TestMemoryAwareness.java index 522b2904c43f..c30917854d90 100644 --- a/test/hotspot/jtreg/containers/docker/TestMemoryAwareness.java +++ b/test/hotspot/jtreg/containers/docker/TestMemoryAwareness.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, 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 @@ -213,6 +213,9 @@ private static void testOOM(String dockerMemLimit, int sizeToAllocInMb) throws E System.out.println("sizeToAllocInMb is:" + sizeToAllocInMb + " sizeToAllocInMb/2 is:" + sizeToAllocInMb/2); String javaHeapSize = sizeToAllocInMb/2 + "m"; opts.addJavaOptsAppended("-Xmx" + javaHeapSize); + // reduce the number of CPUs to 2, so that the number of GC threads is not too + // high for the small memory limit (each thread reserves 2MB stacksize). + opts.addJavaOptsAppended("-XX:ActiveProcessorCount=2"); OutputAnalyzer out = DockerTestUtils.dockerRunJava(opts); diff --git a/test/hotspot/jtreg/gc/shenandoah/generational/TestTransferOfAffiliated.java b/test/hotspot/jtreg/gc/shenandoah/generational/TestTransferOfAffiliated.java new file mode 100644 index 000000000000..857dfc1d1eba --- /dev/null +++ b/test/hotspot/jtreg/gc/shenandoah/generational/TestTransferOfAffiliated.java @@ -0,0 +1,229 @@ +/* + * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package gc.shenandoah.generational; +/* + * @test id=generational + * @summary Test that we do not attempt to transfer to the old + * generation regions that are affiliated with young + * @bug 8382085 + * @key stress + * @requires vm.gc.Shenandoah + * @requires vm.flagless + * @requires os.maxMemory >= 2g + * @library /test/lib + * + * @run main/othervm/timeout=960 -Xms1g -Xmx1g + * -XX:+UnlockExperimentalVMOptions + * -XX:ShenandoahRegionSize=512K + * -XX:+AlwaysPreTouch + * -XX:+UseShenandoahGC + * -XX:ShenandoahGCMode=generational + * -XX:ShenandoahMinFreeThreshold=5 + * -XX:ShenandoahGuaranteedYoungGCInterval=0 + * -XX:ShenandoahGuaranteedOldGCInterval=0 + * -XX:ShenandoahOldEvacPercent=95 + * -XX:ShenandoahPromoEvacWaste=3.0 + * gc.shenandoah.generational.TestTransferOfAffiliated + */ + +import java.util.Random; + +import jdk.test.lib.Asserts; + +public class TestTransferOfAffiliated { + // Heap size is 1 GB. HeapRegionSize is 512KB of memory. + // Note: 512KB/region * 2048 regions = 1 GB. + // + // Size calculations below ignore the overhead of array headers, + // except to acknowledge that array header causes that only 1 + // inner array fits per heap region. Size calculations also + // assume the rootArray is negligible. + private static Integer[][] rootArray; + + // Each inner array spans 256K of memory plus a small number of + // bytes for the array header. Only 1 inner array fits within each + // HeapRegion, causing a large amount of fragmentation. The number + // of elements in an array is 256K divided by 4 bytes per + // (compressed) oop + private static final int INNER_ARRAY_SLOTS = (256 * 1024) / 4; + + // Integer objects are referenced from the inner array. We want + // each InnerArray to consume a full HeapRegion after we account + // for the InnerIntegers referenced from the array. We cannot fill + // the entire array as that would consume more than a HeapRegion's + // worth of memory. We assign Integer objects to random elements + // of the inner array. In the case that two Integer objects are + // randomly assigned to the same array element, one of the two + // will immediately become garbage. The expectation is that the + // rare collision on array slots is sufficient to allow the + // "Inner Array", including its array header and all of its + // Integer elements to pack within a single heap region. + // + // Assume each Integer object consists of 4 bytes for int value, + // plus 8 bytes for compressed Lilliput 1 header, plus 4 bytes for + // alignment. Alternatively, if we don't use Lilliput 1, each + // Integer consumes the same 16 bytes: 12 bytes for non-compact + // object header plus 4 bytes for int value. + // + // The number of InnerIntegers for each InnerArray is 256K (half + // the region size) / 16 bytes / Integer + private static final int INNER_INTEGERS = (256 * 1024) / 16; + + // Assume heap size is 1 GB. We want to consume approximately + // 384MB of live data. Each InnerArray, including its referenced + // Integer objects, consumes approximately 512KB. 768 array + // elements * 512KB/array element = 384MB. + private static final int OUTER_ARRAY_SLOTS = 768; + + private static final Random r = new Random(42); + + private static int absolute(int arg) { + if (arg < 0) { + arg = -arg; + } + if (arg < 0) { + // negative of Integer.min_value EQUALS Integer.MIN_VALUE + arg = 0; + } + return arg; + } + + private static int truncateAbsolute(int i) { + return absolute(i) % INNER_ARRAY_SLOTS; + } + + private static long cpuIntensive(int n) { + long result = 1; + while (n >= 4) { + // arithmetic may overflow + result *= n; + n /= 4; + } + if (n > 0) { + result *= n; + } + return result; + } + + private static Integer[] allocateEmptyInnerArray() { + Integer[] result = new Integer[INNER_ARRAY_SLOTS]; + return result; + } + + private static void fillArrayIntegersWithProbe(Integer[] array, + int spotCheckCount) { + for (int i = 0; i < INNER_INTEGERS; i++) { + int index = truncateAbsolute(r.nextInt()); + int newValue = absolute(r.nextInt()); + long newValueCPUIntensive = cpuIntensive(newValue); + boolean rejectThisValue = false; + // We just do a "spot check", because it consumes too much + // CPU time if we check all previous values. + for (int j = 0; j < spotCheckCount; j++) { + int spotIndex = truncateAbsolute(r.nextInt()); + if ((array[spotIndex] != null) && + (newValueCPUIntensive == + cpuIntensive(array[spotIndex].intValue()))) { + rejectThisValue = true; + break; + } + } + if (rejectThisValue) { + i--; + } else { + // The same index value may be randomly generated + // multiple times, resulting in overwrite and garbage. + array[index] = Integer.valueOf(newValue); + } + } + } + + // How much memory is represented by this array? + private static long doInventory(Integer[] array) { + int integerCount = 0; + if (array != null) { + for (int i = 0; i < INNER_ARRAY_SLOTS; i++) { + if (array[i] != null) { + integerCount++; + } + } + } + if (array == null) { + return 0; + } else { + return (INNER_ARRAY_SLOTS * 4L) + 16 + integerCount * 16L; + } + } + + public static void main(String[] args) { + rootArray = new Integer[OUTER_ARRAY_SLOTS][]; + long accumulator = 0; + + // Fragment young, slowly so we don't do GC cycles here. We + // want the fragmented memory to accumulate in young. + // We don't want this memory to get promoted until last + // possible moment. + for (int index = 0; index < OUTER_ARRAY_SLOTS; index++) { + rootArray[index] = allocateEmptyInnerArray(); + // Accumulate results to slow the allocation, so we have + // rare GC, long allocation runway. + accumulator += doInventory(rootArray[index]); + int inventoryIndex = + (index + OUTER_ARRAY_SLOTS - 16) % OUTER_ARRAY_SLOTS; + accumulator += doInventory(rootArray[inventoryIndex]); + inventoryIndex = + (index + OUTER_ARRAY_SLOTS - 32) % OUTER_ARRAY_SLOTS; + accumulator += doInventory(rootArray[inventoryIndex]); + inventoryIndex = + (index + OUTER_ARRAY_SLOTS - 64) % OUTER_ARRAY_SLOTS; + accumulator += doInventory(rootArray[inventoryIndex]); + } + + // Fill the arrays slowly. We do this as slowly as possible to + // maximize allocation runway, separate GC cycles, accumulate + // promo potential. We want a big promo potential when we have + // highly fragmented young memory. This big promo potential + // must be paired with a large runway. + for (int j = 0; j < OUTER_ARRAY_SLOTS; j++) { + if (rootArray[j] != null) { + fillArrayIntegersWithProbe(rootArray[j], 2048); + accumulator += doInventory(rootArray[j]); + } + } + // The following assert simply confirms that the program ran + // correctly and prevents optimizers from removing what might + // appear to be dead code in the loops above. The + // expected regression failure consists of an assert failure + // observed with fast-debug builds of the JVM before resolution + // of JDK-8382085. The expected value of accumulator is + // determined empirically. The value may depend on the initial + // seed for random number generator and on various constants + // defined above which determine loop iterations. + Asserts.assertNotEquals(0L, accumulator, + "Proper execution is demonstrated by matching " + + "expected accumulator value with no JVM " + + "assert failures"); + } +} diff --git a/test/hotspot/jtreg/runtime/CompressedOops/CompressedCPUSpecificClassSpaceReservation.java b/test/hotspot/jtreg/runtime/CompressedOops/CompressedCPUSpecificClassSpaceReservation.java index ff4fb2655286..e9bdbe308077 100644 --- a/test/hotspot/jtreg/runtime/CompressedOops/CompressedCPUSpecificClassSpaceReservation.java +++ b/test/hotspot/jtreg/runtime/CompressedOops/CompressedCPUSpecificClassSpaceReservation.java @@ -43,6 +43,9 @@ import jtreg.SkippedException; import java.io.IOException; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class CompressedCPUSpecificClassSpaceReservation { // Note: windows: On windows, we currently have the issue that os::reserve_memory_aligned relies on @@ -68,7 +71,11 @@ private static void do_test(boolean CDS) throws IOException { final String tryReserveForUnscaled = "reserve_between (range [0x0000000000000000-0x0000000100000000)"; final String tryReserveBelow4G = "reserve_between (range [0x0000000000000000-0x0000000100000000)"; final String tryReserveForZeroBased = "reserve_between (range [0x0000000100000000-0x0000000800000000)"; - final String tryReserveFor16bitMoveIntoQ3 = "reserve_between (range [0x0000000100000000-0x0001000000000000)"; + // Failing zero-based allocation, platforms will often attempt allocation suitable for a disjointed move: + // an insert of the base address bits into the register holding the nK. That requires the base to not + // intersect with nK bits (for simplicity, we always assume nK range of 32bits). + // The upper limit of this reservation attempt is platform-dependent, though. + final String tryReserveFor16bitMoveIntoQ3Regex = "reserve_between.*0x0000000100000000-0x\\d{8}00000000.*alignment 0x100000000"; if (Platform.isAArch64()) { if (CDS) { output.shouldNotContain(tryReserveForUnscaled); @@ -77,7 +84,7 @@ private static void do_test(boolean CDS) throws IOException { } output.shouldContain("Trying to reserve at an EOR-compatible address"); output.shouldNotContain(tryReserveForZeroBased); - output.shouldContain(tryReserveFor16bitMoveIntoQ3); + output.shouldMatch(tryReserveFor16bitMoveIntoQ3Regex); } else if (Platform.isPPC()) { if (CDS) { output.shouldNotContain(tryReserveForUnscaled); @@ -86,7 +93,7 @@ private static void do_test(boolean CDS) throws IOException { output.shouldContain(tryReserveForUnscaled); output.shouldContain(tryReserveForZeroBased); } - output.shouldContain(tryReserveFor16bitMoveIntoQ3); + output.shouldMatch(tryReserveFor16bitMoveIntoQ3Regex); } else if (Platform.isRISCV64()) { output.shouldContain(tryReserveForUnscaled); // unconditionally // bits 32..44 @@ -100,7 +107,7 @@ private static void do_test(boolean CDS) throws IOException { } else { output.shouldContain(tryReserveForZeroBased); } - output.shouldContain(tryReserveFor16bitMoveIntoQ3); + output.shouldMatch(tryReserveFor16bitMoveIntoQ3Regex); } else if (Platform.isX64()) { output.shouldContain(tryReserveBelow4G); if (CDS) { @@ -119,6 +126,24 @@ private static void do_test(boolean CDS) throws IOException { output.shouldContain("CDS archive(s) not mapped"); } output.shouldContain("Compressed class space mapped at:"); + + // S390: Make very sure every reserve_between attempt we do (which we do + // for class space only, currently) never probes beyond 2^42 to avoid + // page table expansion + if (Platform.isS390x()) { + Pattern pat = Pattern.compile(".*reserve_between \\(range \\[0x[0-9a-f]{16}-0x([0-9a-f]{16})\\).*"); + List matches = output.matchersForAllMatchingLinesStdout(pat); + if (matches.size() == 0) { + throw new RuntimeException("Expected matches"); + } + for (Matcher mat : matches) { + long address_to = Long.parseLong(mat.group(1), 16); + if (address_to > Math.powExact(2L, 42)) { + System.out.println(mat.group(0)); + throw new RuntimeException("Address space probing beyond 2^42?"); + } + } + } } public static void main(String[] args) throws Exception { diff --git a/test/hotspot/jtreg/runtime/CompressedOops/CompressedClassPointersEncodingScheme.java b/test/hotspot/jtreg/runtime/CompressedOops/CompressedClassPointersEncodingScheme.java index f4ef0800a73b..a8c03e259fc8 100644 --- a/test/hotspot/jtreg/runtime/CompressedOops/CompressedClassPointersEncodingScheme.java +++ b/test/hotspot/jtreg/runtime/CompressedOops/CompressedClassPointersEncodingScheme.java @@ -36,7 +36,6 @@ import jdk.test.lib.Platform; import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; -import jtreg.SkippedException; import java.io.IOException; @@ -102,14 +101,18 @@ public static void main(String[] args) throws Exception { // Compact Object Header Mode: // We expect the VM to chose the smallest possible shift value needed to cover the encoding range. // We expect the encoding Base to start at the class space start - but to enforce that, - // we choose unsuited to even shift-extended zero-based mode. + // we choose a base unsuited to even shift-extended zero-based mode. forceAddress = 32 * G; + int minShift = 6; + if (Platform.isPPC()) minShift = 7; + if (Platform.isS390x()) minShift = 8; - test(forceAddress, true, 128 * M, forceAddress, 6); - test(forceAddress, true, 256 * M, forceAddress, 7); - test(forceAddress, true, 512 * M, forceAddress, 8); - test(forceAddress, true, G, forceAddress, 9); - test(forceAddress, true, 3 * G, forceAddress, 10); + test(forceAddress, true, 128 * M, forceAddress, Math.max(minShift, 5)); + test(forceAddress, true, 256 * M, forceAddress, Math.max(minShift, 6)); + test(forceAddress, true, 512 * M, forceAddress, Math.max(minShift, 7)); + test(forceAddress, true, G, forceAddress, Math.max(minShift, 8)); + test(forceAddress, true, 2 * G, forceAddress, Math.max(minShift, 9)); + test(forceAddress, true, 4 * G, forceAddress, 10); // Test a "crooked" base address: // - just aligned enough to pass metaspace reserve alignment test of 16MB. @@ -118,8 +121,8 @@ public static void main(String[] args) throws Exception { // - small enough to not cause test errors on small devices (e.g. arm64 39bit address space) // - large enough to not end up with zero-based encoding forceAddress = 0x0000000d55000000L; - test(forceAddress, true, 32 * M, forceAddress, 6); - test(forceAddress, false, 32 * M, forceAddress, 0); + test(forceAddress, true, 4 * G, forceAddress, 10); + test(forceAddress, false, 4 * G, forceAddress, 0); } } diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotCode/AOTCodeCompressedOopsTest.java b/test/hotspot/jtreg/runtime/cds/appcds/aotCode/AOTCodeCompressedOopsTest.java index aea4f7e9f8f0..29b0f59b2380 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotCode/AOTCodeCompressedOopsTest.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotCode/AOTCodeCompressedOopsTest.java @@ -125,7 +125,10 @@ public String[] vmArgs(RunMode runMode) { switch (runMode) { case RunMode.ASSEMBLY: { List args = getVMArgsForHeapConfig(zeroBaseInAsmPhase, zeroShiftInAsmPhase); + // By default CDSAppTester adds -XX:+AOTCompatibleOopCompression option, + // which defeats the purpose of this test. So disable this option. args.addAll(List.of("-XX:+UnlockDiagnosticVMOptions", + "-XX:-AOTCompatibleOopCompression", "-Xlog:aot=info", "-Xlog:aot+codecache+init=debug", "-Xlog:aot+codecache+exit=debug")); diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotFlags/AOTFlags.java b/test/hotspot/jtreg/runtime/cds/appcds/aotFlags/AOTFlags.java index dcb2b5952434..56c31dcdbdaa 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotFlags/AOTFlags.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotFlags/AOTFlags.java @@ -72,6 +72,8 @@ static void positiveTests() throws Exception { "-XX:AOTConfiguration=" + aotConfigFile, "-XX:AOTCache=" + aotCacheFile, "-Xlog:aot", + "-XX:+UnlockDiagnosticVMOptions", + "-XX:+AOTCompatibleOopCompression", // avoid production run failure due to incompatible CompressedOops::base "-cp", appJar); out = CDSTestUtils.executeAndLog(pb, "asm"); out.shouldContain("AOTCache creation is complete"); @@ -142,6 +144,8 @@ static void positiveTests() throws Exception { "-XX:AOTConfiguration=" + aotConfigFile, "-XX:AOTCache=" + aotCacheFile, "-Xlog:aot", + "-XX:+UnlockDiagnosticVMOptions", + "-XX:+AOTCompatibleOopCompression", // avoid production run failure due to incompatible CompressedOops::base "-cp", appJar); out = CDSTestUtils.executeAndLog(pb, "asm"); out.shouldContain("AOTCache creation is complete"); diff --git a/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/TransformerShutdownDeadlockTest.java b/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/TransformerShutdownDeadlockTest.java new file mode 100644 index 000000000000..e8e14a85d01f --- /dev/null +++ b/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/TransformerShutdownDeadlockTest.java @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2026, 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 8387045 + * @summary Transforming during VM shutdown could lead to deadlock + * @requires vm.jvmti + * @requires vm.flagless + * @library /test/lib + * @modules java.instrument + * @run driver TransformerShutdownDeadlockTest + */ + +import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.helpers.ClassFileInstaller; + +import java.lang.instrument.ClassFileTransformer; +import java.lang.instrument.IllegalClassFormatException; +import java.lang.instrument.Instrumentation; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.ProtectionDomain; + +import java.net.URI; +import java.net.URL; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.util.Collections; + +public class TransformerShutdownDeadlockTest { + + private static String manifest = "Premain-Class: " + + TransformerShutdownDeadlockTest.Agent.class.getName() + "\n" + + "Can-Retransform-Classes: true\n"; + + public static void main(String args[]) throws Throwable { + // The JVMTI vm_death spin loop lasts 60 seconds. Set up a 30 + // second deadline to detect excessive spinning. + long deadline_ns = 30L * 1000 * 1000 * 1000; + + String agentJar = buildAgent(); + ProcessBuilder pb = + ProcessTools.createLimitedTestJavaProcessBuilder("-javaagent:" + agentJar, + "-Xlog:class+load=info", + TransformerShutdownDeadlockTest.Agent.class.getName()); + long start = System.nanoTime(); + ProcessTools.executeProcess(pb).shouldHaveExitValue(0); + long end = System.nanoTime(); + if (end - start > deadline_ns) { + throw new Error("VM exit deadlock potentially detected: " + (end - start)); + } + } + + private static String buildAgent() throws Exception { + Path jar = Files.createTempFile(Paths.get("."), null, ".jar"); + String jarPath = jar.toAbsolutePath().toString(); + ClassFileInstaller.writeJar(jarPath, + ClassFileInstaller.Manifest.fromString(manifest), + TransformerShutdownDeadlockTest.class.getName()); + return jarPath; + } + + // The class to retransform when loaded. + static class Transform { + static { + System.out.println(Thread.currentThread().getName() + " doing init for Transform"); + } + } + + public static class Agent implements ClassFileTransformer { + private static Instrumentation instrumentation; + + public static void premain(String agentArgs, Instrumentation inst) { + instrumentation = inst; + } + + private static volatile boolean transform_running = false; + private static volatile boolean starting_exit = false; + + @Override + public byte[] transform(ClassLoader loader, + String className, + Class classBeingRedefined, + ProtectionDomain protectionDomain, + byte[] classfileBuffer) + throws IllegalClassFormatException { + + if (!"TransformerShutdownDeadlockTest$Transform".equals(className)) { + return null; + } + + String name = Thread.currentThread().getName(); + System.out.println(name + " in transform()"); + transform_running = true; // Release main thread + try { + while (!starting_exit); // Wait for main thread to be ready + Thread.sleep(200); // Give main thread a chance to hit vm_death + // Force-load some new classes and do some active work. The deadlock is + // triggered by a deopt request. + System.out.println(name + " creating FileSystem"); + URL jarUrl = Agent.class.getProtectionDomain().getCodeSource().getLocation(); + URI jarUri = URI.create("jar:" + jarUrl.toURI()); + try (FileSystem jar = FileSystems.newFileSystem(jarUri, Collections.emptyMap())) { + } + } + catch (Throwable t) { + throw new Error("Unexpected exception: ", t); + } + System.out.println(name + " done retransform"); + return null; + + } + + public static void main(String[] args) throws Exception { + instrumentation.addTransformer(new TransformerShutdownDeadlockTest.Agent(), true); + + // Start a daemon thread to load the class that will be transformed + final Thread t = new Thread() { + public void run() { + System.out.println("TransformerThread about to load Transform"); + Transform tr = new Transform(); + System.out.println("TransformerThread done"); + } + }; + t.setName("TransformerThread"); + t.setDaemon(true); + System.out.println("Main thread about to start TransformerThread"); + t.start(); + + while (!transform_running); // Wait for transform to start + System.out.println("Main thread calling exit"); + starting_exit = true; // Release transform thread + System.exit(0); + } + } +} diff --git a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestBadFormat.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestBadFormat.java index da8fd6489b8a..effb18611962 100644 --- a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestBadFormat.java +++ b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestBadFormat.java @@ -844,12 +844,11 @@ public void mustSpecifyAtLeastOneConstraint2() { public void mustSpecifyAtLeastOneConstraint3() { } - @FailCount(3) + @FailCount(2) @Test - @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "50"}, applyIfNot = {"UseTLAB", "true"}) @IR(failOn = IRNode.CALL, applyIfAnd = {"TLABRefillWasteFraction", "50", "UseTLAB", "true"}, applyIfOr = {"TLABRefillWasteFraction", "50", "UseTLAB", "true"}) - @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "50"}, applyIfNot = {"TLABRefillWasteFraction", "50"}, + @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "50"}, applyIfAnd = {"TLABRefillWasteFraction", "50", "UseTLAB", "true"}, applyIfOr = {"TLABRefillWasteFraction", "50", "UseTLAB", "true"}) public void onlyOneApply() {} @@ -890,43 +889,6 @@ public void applyIfEmptyValue() {} @IR(failOn = IRNode.CALL, applyIf = {"TLABRefillWasteFraction", "<"}) public void applyIfFaultyComparator() {} - @FailCount(3) - @Test - @IR(failOn = IRNode.CALL, applyIfNot = {"TLABRefillWasteFraction", "50", "UseTLAB", "true"}) - @IR(failOn = IRNode.CALL, applyIfNot = {"TLABRefillWasteFraction", "50", "UseTLAB"}) - public void applyIfNotTooManyFlags() {} - - @FailCount(2) - @Test - @IR(failOn = IRNode.CALL, applyIfNot = {"TLABRefillWasteFraction"}) - @IR(failOn = IRNode.CALL, applyIfNot = {"Bla"}) - public void applyIfNotMissingValue() {} - - @FailCount(2) - @Test - @IR(failOn = IRNode.CALL, applyIfNot = {"PrintIdealGraphFilee", "true"}) - @IR(failOn = IRNode.CALL, applyIfNot = {"Bla", "foo"}) - public void applyIfNotUnknownFlag() {} - - @FailCount(5) - @Test - @IR(failOn = IRNode.CALL, applyIfNot = {"PrintIdealGraphFile", ""}) - @IR(failOn = IRNode.CALL, applyIfNot = {"UseTLAB", ""}) - @IR(failOn = IRNode.CALL, applyIfNot = {"", "true"}) - @IR(failOn = IRNode.CALL, applyIfNot = {"", ""}) - @IR(failOn = IRNode.CALL, applyIfNot = {" ", " "}) - public void applyIfNotEmptyValue() {} - - @FailCount(5) - @Test - @IR(failOn = IRNode.CALL, applyIfNot = {"TLABRefillWasteFraction", "! 34"}) - @IR(failOn = IRNode.CALL, applyIfNot = {"TLABRefillWasteFraction", "!== 34"}) - @IR(failOn = IRNode.CALL, applyIfNot = {"TLABRefillWasteFraction", "<<= 34"}) - @IR(failOn = IRNode.CALL, applyIfNot = {"TLABRefillWasteFraction", "=<34"}) - @IR(failOn = IRNode.CALL, applyIfNot = {"TLABRefillWasteFraction", "<"}) - public void applyIfNotFaultyComparator() {} - - @FailCount(2) @Test @IR(failOn = IRNode.CALL, applyIfAnd = {"TLABRefillWasteFraction", "50"}) diff --git a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestIRMatching.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestIRMatching.java index cb5f43b3fb9c..07fb7fb56f2b 100644 --- a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestIRMatching.java +++ b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestIRMatching.java @@ -467,16 +467,16 @@ public void good1() { @Test @IR(failOn = {IRNode.STORE, IRNode.CALL}) - @IR(applyIfNot = {"TLABRefillWasteFraction", "20"}, failOn = {IRNode.ALLOC}) - @IR(applyIfNot = {"TLABRefillWasteFraction", "< 100"}, failOn = {IRNode.ALLOC_OF, "Test"}) + @IR(applyIf = {"TLABRefillWasteFraction", "!= 20"}, failOn = {IRNode.ALLOC}) + @IR(applyIf = {"TLABRefillWasteFraction", ">= 100"}, failOn = {IRNode.ALLOC_OF, "Test"}) public void good2() { forceInline(); } @Test @IR(failOn = {IRNode.STORE_OF_CLASS, "Test", IRNode.CALL}) - @IR(applyIfNot = {"TLABRefillWasteFraction", "20"}, failOn = {IRNode.ALLOC}) - @IR(applyIfNot = {"TLABRefillWasteFraction", "< 100"}, failOn = {IRNode.ALLOC_OF, "Test"}) + @IR(applyIf = {"TLABRefillWasteFraction", "!= 20"}, failOn = {IRNode.ALLOC}) + @IR(applyIf = {"TLABRefillWasteFraction", ">= 100"}, failOn = {IRNode.ALLOC_OF, "Test"}) public void good3() { forceInline(); } diff --git a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestPhaseIRMatching.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestPhaseIRMatching.java index 8bec7c03bfe9..c95f749afdf6 100644 --- a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestPhaseIRMatching.java +++ b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestPhaseIRMatching.java @@ -28,11 +28,16 @@ import compiler.lib.ir_framework.driver.TestVMProcess; import compiler.lib.ir_framework.driver.irmatching.MatchResult; import compiler.lib.ir_framework.driver.irmatching.Matchable; +import compiler.lib.ir_framework.driver.irmatching.irmethod.IRMethodMatchResult; +import compiler.lib.ir_framework.driver.irmatching.irmethod.NotCompilableIRMethodMatchResult; +import compiler.lib.ir_framework.driver.irmatching.irmethod.NotCompiledIRMethodMatchResult; +import compiler.lib.ir_framework.driver.irmatching.irrule.IRRuleMatchResult; import compiler.lib.ir_framework.driver.irmatching.irrule.checkattribute.CheckAttributeType; import compiler.lib.ir_framework.driver.irmatching.irrule.constraint.CountsConstraintFailure; import compiler.lib.ir_framework.driver.irmatching.irrule.constraint.FailOnConstraintFailure; +import compiler.lib.ir_framework.driver.irmatching.irrule.phase.CompilePhaseIRRuleMatchResult; +import compiler.lib.ir_framework.driver.irmatching.irrule.phase.CompilePhaseNoCompilationIRRuleMatchResult; import compiler.lib.ir_framework.driver.irmatching.parser.TestClassParser; -import compiler.lib.ir_framework.driver.irmatching.visitor.AcceptChildren; import compiler.lib.ir_framework.driver.irmatching.visitor.MatchResultVisitor; import jdk.test.lib.Asserts; @@ -406,59 +411,46 @@ public List build(MatchResult testClassResult) { } @Override - public void visitTestClass(AcceptChildren acceptChildren) { - acceptChildren.accept(this); + public void enter(IRMethodMatchResult result) { + methodName = result.method().getName(); } @Override - public void visitIRMethod(AcceptChildren acceptChildren, Method method, int failedIRRules) { - methodName = method.getName(); - acceptChildren.accept(this); - } - - @Override - public void visitMethodNotCompiled(Method method, int failedIRRules) { - methodName = method.getName(); + public void visitLeaf(NotCompiledIRMethodMatchResult result) { + methodName = result.method().getName(); failures.add(new Failure(methodName, -1, CompilePhase.DEFAULT, CheckAttributeType.FAIL_ON, -1)); } @Override - public void visitMethodNotCompilable(Method method, int failedIRRules) { + public void visitLeaf(NotCompilableIRMethodMatchResult result) { throw new RuntimeException("No test should bailout from compilation"); } @Override - public void visitIRRule(AcceptChildren acceptChildren, int irRuleId, IR irAnno) { - ruleId = irRuleId; - acceptChildren.accept(this); - } - - @Override - public void visitCompilePhaseIRRule(AcceptChildren acceptChildren, CompilePhase compilePhase, String compilationOutput) { - this.compilePhase = compilePhase; - acceptChildren.accept(this); + public void enter(IRRuleMatchResult result) { + ruleId = result.irRuleId(); } @Override - public void visitNoCompilePhaseCompilation(CompilePhase compilePhase) { - failures.add(new Failure(methodName, ruleId, compilePhase, CheckAttributeType.FAIL_ON, -1)); + public void enter(CompilePhaseIRRuleMatchResult result) { + this.compilePhase = result.compilePhase(); } @Override - public void visitCheckAttribute(AcceptChildren acceptChildren, CheckAttributeType checkAttributeType) { - acceptChildren.accept(this); + public void visitLeaf(CompilePhaseNoCompilationIRRuleMatchResult result) { + failures.add(new Failure(methodName, ruleId, result.compilePhase(), CheckAttributeType.FAIL_ON, -1)); } @Override - public void visitFailOnConstraint(FailOnConstraintFailure matchResult) { + public void visitLeaf(FailOnConstraintFailure result) { failures.add(new Failure(methodName, ruleId, compilePhase, CheckAttributeType.FAIL_ON, - matchResult.constraintId())); + result.constraintId())); } @Override - public void visitCountsConstraint(CountsConstraintFailure matchResult) { + public void visitLeaf(CountsConstraintFailure result) { failures.add(new Failure(methodName, ruleId, compilePhase, CheckAttributeType.COUNTS, - matchResult.constraintId())); + result.constraintId())); } } diff --git a/test/jdk/java/awt/FullScreen/DisplayModeNoRefreshTest.java b/test/jdk/java/awt/FullScreen/DisplayModeNoRefreshTest.java index a52990371221..b8cdd2d428b0 100644 --- a/test/jdk/java/awt/FullScreen/DisplayModeNoRefreshTest.java +++ b/test/jdk/java/awt/FullScreen/DisplayModeNoRefreshTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2026, 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 @@ -100,7 +100,7 @@ public DisplayMode getNoRefreshDisplayMode(DisplayMode dm[]) { public static void main(String[] args) throws Exception { try { EventQueue.invokeAndWait(() -> { - System.setProperty("sun.java2d.noddraw", "true"); + System.setProperty("sun.java2d.d3d", "false"); fs = new DisplayModeNoRefreshTest(); }); } finally { diff --git a/test/jdk/java/awt/FullScreen/MultimonFullscreenTest/MultimonFullscreenTest.java b/test/jdk/java/awt/FullScreen/MultimonFullscreenTest/MultimonFullscreenTest.java index cd735165caf1..8294a081eee3 100644 --- a/test/jdk/java/awt/FullScreen/MultimonFullscreenTest/MultimonFullscreenTest.java +++ b/test/jdk/java/awt/FullScreen/MultimonFullscreenTest/MultimonFullscreenTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,18 +32,18 @@ * You could, however, alt+tab out of a fullscreen window, or at least * minimize it (if you've entered the fs mode with a Window, you'll need * to minimize the owner frame). - * Note that there may be issues with FS exclusive mode with ddraw and + * Note that there may be issues with FS exclusive mode with d3d draw and * multiple fullscreen windows (one per device). * - if display mode is supported that it did change * - that the original display mode is restored once * the ws window is disposed * All of the above should work with and w/o DirectDraw - * (-Dsun.java2d.noddraw=true) on windows, and w/ and w/o opengl on X11 + * (-Dsun.java2d.d3d=false) on windows, and w/ and w/o opengl on X11 * (-Dsun.java2d.opengl=True). * @run main/manual/othervm -Dsun.java2d.pmoffscreen=true MultimonFullscreenTest * @run main/manual/othervm -Dsun.java2d.pmoffscreen=false MultimonFullscreenTest * @run main/manual/othervm -Dsun.java2d.d3d=True MultimonFullscreenTest - * @run main/manual/othervm -Dsun.java2d.noddraw=true MultimonFullscreenTest + * @run main/manual/othervm -Dsun.java2d.d3d=false MultimonFullscreenTest * @run main/manual/othervm MultimonFullscreenTest */ diff --git a/test/jdk/java/awt/FullScreen/NonExistentDisplayModeTest/NonExistentDisplayModeTest.java b/test/jdk/java/awt/FullScreen/NonExistentDisplayModeTest/NonExistentDisplayModeTest.java index 286d4324e304..c8f9d4a70ed7 100644 --- a/test/jdk/java/awt/FullScreen/NonExistentDisplayModeTest/NonExistentDisplayModeTest.java +++ b/test/jdk/java/awt/FullScreen/NonExistentDisplayModeTest/NonExistentDisplayModeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ * @summary Test that we throw an exception for incorrect display modes * @author Dmitri.Trembovetski@Sun.COM area=FullScreen * @run main/othervm NonExistentDisplayModeTest - * @run main/othervm -Dsun.java2d.noddraw=true NonExistentDisplayModeTest + * @run main/othervm -Dsun.java2d.d3d=false NonExistentDisplayModeTest */ public class NonExistentDisplayModeTest { diff --git a/test/jdk/java/awt/FullScreen/SetFSWindow/FSFrame.java b/test/jdk/java/awt/FullScreen/SetFSWindow/FSFrame.java index adc62fa3e4c3..d2d8718622f2 100644 --- a/test/jdk/java/awt/FullScreen/SetFSWindow/FSFrame.java +++ b/test/jdk/java/awt/FullScreen/SetFSWindow/FSFrame.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2026, 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,7 +28,7 @@ * @summary verify that isFullScreenSupported and getFullScreenWindow work * correctly. Note that the test may fail on older Gnome versions (see bug 6500686). * @run main FSFrame - * @run main/othervm -Dsun.java2d.noddraw=true FSFrame + * @run main/othervm -Dsun.java2d.d3d=false FSFrame */ import java.awt.Color; diff --git a/test/jdk/java/awt/GraphicsDevice/CloneConfigsTest.java b/test/jdk/java/awt/GraphicsDevice/CloneConfigsTest.java index aac55d991cf5..3b455079a06c 100644 --- a/test/jdk/java/awt/GraphicsDevice/CloneConfigsTest.java +++ b/test/jdk/java/awt/GraphicsDevice/CloneConfigsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ * * @run main CloneConfigsTest * @run main/othervm -Dsun.java2d.d3d=true CloneConfigsTest - * @run main/othervm -Dsun.java2d.noddraw=true CloneConfigsTest + * @run main/othervm -Dsun.java2d.d3d=false CloneConfigsTest */ import java.awt.GraphicsConfiguration; diff --git a/test/jdk/java/awt/Multiscreen/DeviceIdentificationTest/DeviceIdentificationTest.java b/test/jdk/java/awt/Multiscreen/DeviceIdentificationTest/DeviceIdentificationTest.java index 684ac9e25386..cdaaad8688e6 100644 --- a/test/jdk/java/awt/Multiscreen/DeviceIdentificationTest/DeviceIdentificationTest.java +++ b/test/jdk/java/awt/Multiscreen/DeviceIdentificationTest/DeviceIdentificationTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2026, 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 @@ -39,7 +39,7 @@ * fs mode on the right device. * * @run main/manual/othervm DeviceIdentificationTest - * @run main/manual/othervm -Dsun.java2d.noddraw=true DeviceIdentificationTest + * @run main/manual/othervm -Dsun.java2d.d3d=false DeviceIdentificationTest */ import java.awt.Button; diff --git a/test/jdk/java/awt/Window/TranslucentShapedFrameTest/TranslucentShapedFrameTest.java b/test/jdk/java/awt/Window/TranslucentShapedFrameTest/TranslucentShapedFrameTest.java index b87c44d90785..33d63eb8b943 100644 --- a/test/jdk/java/awt/Window/TranslucentShapedFrameTest/TranslucentShapedFrameTest.java +++ b/test/jdk/java/awt/Window/TranslucentShapedFrameTest/TranslucentShapedFrameTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2026, 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,7 +29,7 @@ * @compile -XDignore.symbol.file=true TranslucentShapedFrameTest.java * @compile -XDignore.symbol.file=true TSFrame.java * @run main/manual/othervm TranslucentShapedFrameTest - * @run main/manual/othervm -Dsun.java2d.noddraw=true TranslucentShapedFrameTest + * @run main/manual/othervm -Dsun.java2d.d3d=false TranslucentShapedFrameTest */ import java.awt.Color; diff --git a/test/jdk/java/io/File/GetXSpace.java b/test/jdk/java/io/File/GetXSpace.java index f1529c18fb27..835e197eff00 100644 --- a/test/jdk/java/io/File/GetXSpace.java +++ b/test/jdk/java/io/File/GetXSpace.java @@ -53,8 +53,6 @@ public class GetXSpace { System.loadLibrary("GetXSpace"); } - private static final Pattern DF_PATTERN = Pattern.compile("([^\\s]+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+\\d+%\\s+([^\\s].*)\n"); - private static int fail = 0; private static int pass = 0; private static Throwable first; @@ -105,12 +103,8 @@ private static class Space { Space(String name) throws IOException { this.name = name; long[] sizes = new long[4]; - if (Platform.isWindows() && isCDDrive(name)) { - getCDDriveSpace(name, sizes); - } else { - if (getSpace(name, sizes)) - System.err.println("WARNING: total space is estimated"); - } + if (getSpace(name, sizes)) + System.err.println("WARNING: total space is estimated"); this.size = sizes[0]; this.total = sizes[1]; this.free = sizes[2]; @@ -178,8 +172,7 @@ private static void compare(Space s) throws IOException { out.format("%s (%d):%n", s.name(), s.size()); String fmt = " %-4s total = %12d free = %12d usable = %12d%n"; - String method = Platform.isWindows() && isCDDrive(s.name()) ? "getCDDriveSpace" : "getSpace"; - out.format(fmt, method, s.total(), s.free(), s.available()); + out.format(fmt, "getSpace", s.total(), s.free(), s.available()); out.format(fmt, "getXSpace", ts, fs, us); // If the file system can dynamically change size, this check will fail. @@ -331,7 +324,6 @@ private static int testVolumes() throws IOException { out.println("--- Testing volumes"); // Find all of the partitions on the machine and verify that the sizes // returned by File::getXSpace are equivalent to those from getSpace - // or getCDDriveSpace ArrayList l; try { l = paths(); @@ -417,8 +409,6 @@ public static void main(String[] args) throws Exception { private static native boolean getSpace0(String root, long[] space) throws IOException; - private static native boolean isCDDrive(String root); - private static boolean getSpace(String root, long[] space) throws IOException { try { @@ -430,38 +420,4 @@ private static boolean getSpace(String root, long[] space) throw e; } } - - private static void getCDDriveSpace(String root, long[] sizes) - throws IOException { - String[] cmd = new String[] {"df", "-k", "-P", root}; - Process p = Runtime.getRuntime().exec(cmd); - StringBuilder sb = new StringBuilder(); - - try (BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()))) { - String s; - int i = 0; - while ((s = in.readLine()) != null) { - // skip header - if (i++ == 0) continue; - sb.append(s).append("\n"); - } - } - out.println(sb); - - Matcher m = DF_PATTERN.matcher(sb); - int j = 0; - while (j < sb.length()) { - if (m.find(j)) { - sizes[0] = Long.parseLong(m.group(2)) * 1024; - sizes[1] = Long.parseLong(m.group(3)) * 1024; - sizes[2] = sizes[0] - sizes[1]; - sizes[3] = Long.parseLong(m.group(4)) * 1024; - j = m.end(); - } else { - throw new RuntimeException("unrecognized df output format: " - + "charAt(" + j + ") = '" - + sb.charAt(j) + "'"); - } - } - } } diff --git a/test/jdk/java/io/File/libGetXSpace.c b/test/jdk/java/io/File/libGetXSpace.c index 9297721b8f44..b7fab2513cf9 100644 --- a/test/jdk/java/io/File/libGetXSpace.c +++ b/test/jdk/java/io/File/libGetXSpace.c @@ -44,7 +44,7 @@ extern "C" { #ifdef WINDOWS jboolean initialized = JNI_FALSE; -BOOL(WINAPI * pfnGetDiskSpaceInformation)(LPCWSTR, LPVOID) = NULL; +HRESULT(WINAPI * pfnGetDiskSpaceInformation)(LPCWSTR, LPVOID) = NULL; #endif // @@ -82,29 +82,28 @@ Java_GetXSpace_getSpace0 if (pfnGetDiskSpaceInformation != NULL) { // use GetDiskSpaceInformationW DISK_SPACE_INFORMATION diskSpaceInfo; - BOOL hres = pfnGetDiskSpaceInformation(path, &diskSpaceInfo); - (*env)->ReleaseStringChars(env, root, strchars); + HRESULT hres = pfnGetDiskSpaceInformation(path, &diskSpaceInfo); if (FAILED(hres)) { - JNU_ThrowByNameWithLastError(env, "java/io/IOException", - "GetDiskSpaceInformationW"); - return totalSpaceIsEstimated; + totalSpaceIsEstimated = JNI_TRUE; + } else { + (*env)->ReleaseStringChars(env, root, strchars); + ULONGLONG bytesPerAllocationUnit = + diskSpaceInfo.SectorsPerAllocationUnit*diskSpaceInfo.BytesPerSector; + array[0] = (jlong)(diskSpaceInfo.ActualTotalAllocationUnits* + bytesPerAllocationUnit); + array[1] = (jlong)(diskSpaceInfo.CallerTotalAllocationUnits* + bytesPerAllocationUnit); + array[2] = (jlong)(diskSpaceInfo.ActualAvailableAllocationUnits* + bytesPerAllocationUnit); + array[3] = (jlong)(diskSpaceInfo.CallerAvailableAllocationUnits* + bytesPerAllocationUnit); } - - ULONGLONG bytesPerAllocationUnit = - diskSpaceInfo.SectorsPerAllocationUnit*diskSpaceInfo.BytesPerSector; - array[0] = (jlong)(diskSpaceInfo.ActualTotalAllocationUnits* - bytesPerAllocationUnit); - array[1] = (jlong)(diskSpaceInfo.CallerTotalAllocationUnits* - bytesPerAllocationUnit); - array[2] = (jlong)(diskSpaceInfo.ActualAvailableAllocationUnits* - bytesPerAllocationUnit); - array[3] = (jlong)(diskSpaceInfo.CallerAvailableAllocationUnits* - bytesPerAllocationUnit); } else { totalSpaceIsEstimated = JNI_TRUE; + } - // if GetDiskSpaceInformationW is unavailable ("The specified - // procedure could not be found"), fall back to GetDiskFreeSpaceExW + if (totalSpaceIsEstimated == JNI_TRUE) { + // fall back to GetDiskFreeSpaceExW ULARGE_INTEGER freeBytesAvailable; ULARGE_INTEGER totalNumberOfBytes; ULARGE_INTEGER totalNumberOfFreeBytes; @@ -112,7 +111,7 @@ Java_GetXSpace_getSpace0 BOOL hres = GetDiskFreeSpaceExW(path, &freeBytesAvailable, &totalNumberOfBytes, &totalNumberOfFreeBytes); (*env)->ReleaseStringChars(env, root, strchars); - if (FAILED(hres)) { + if (!hres) { JNU_ThrowByNameWithLastError(env, "java/io/IOException", "GetDiskFreeSpaceExW"); return totalSpaceIsEstimated; @@ -159,32 +158,6 @@ Java_GetXSpace_getSpace0 return totalSpaceIsEstimated; } -JNIEXPORT jboolean JNICALL -Java_GetXSpace_isCDDrive - (JNIEnv *env, jclass cls, jstring root) -{ -#ifdef WINDOWS - const jchar* strchars = (*env)->GetStringChars(env, root, NULL); - if (strchars == NULL) { - JNU_ThrowByNameWithLastError(env, "java/lang/RuntimeException", - "GetStringChars"); - return JNI_FALSE; - } - - LPCWSTR path = (LPCWSTR)strchars; - UINT driveType = GetDriveTypeW(path); - - (*env)->ReleaseStringChars(env, root, strchars); - - if (driveType != DRIVE_CDROM) { - return JNI_FALSE; - } - - return JNI_TRUE; -#else - return JNI_FALSE; -#endif -} #ifdef __cplusplus } #endif diff --git a/test/jdk/java/text/Format/NumberFormat/LenientParseTest.java b/test/jdk/java/text/Format/NumberFormat/LenientParseTest.java index c85fe0f6cbb5..69fb2a152211 100644 --- a/test/jdk/java/text/Format/NumberFormat/LenientParseTest.java +++ b/test/jdk/java/text/Format/NumberFormat/LenientParseTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 8327640 8331485 8333456 8335668 + * @bug 8327640 8331485 8333456 8335668 8388507 * @summary Test suite for NumberFormat parsing when lenient. * @run junit/othervm -Duser.language=en -Duser.country=US LenientParseTest * @run junit/othervm -Duser.language=ja -Duser.country=JP LenientParseTest @@ -162,6 +162,12 @@ public void badExponentParseNumberFormatTest() { assertEquals(1.23E45, successParse(fmt, "1.23E45FOO3222", 7)); } + @Test // Non-localized, only run once + @EnabledIfSystemProperty(named = "user.language", matches = "en") + public void nanNumberFormatTest() { + assertEquals(Double.NaN, successParse(new DecimalFormat(), "NaNFoo", 3)); + } + // ---- CurrencyFormat tests ---- // All input Strings should pass and return expected value. @ParameterizedTest diff --git a/test/jdk/java/text/Format/NumberFormat/StrictParseTest.java b/test/jdk/java/text/Format/NumberFormat/StrictParseTest.java index 3e90ccb39cea..1b69c53407b8 100644 --- a/test/jdk/java/text/Format/NumberFormat/StrictParseTest.java +++ b/test/jdk/java/text/Format/NumberFormat/StrictParseTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 8327640 8331485 8333755 8335668 + * @bug 8327640 8331485 8333755 8335668 8388507 * @summary Test suite for NumberFormat parsing with strict leniency * @run junit/othervm -Duser.language=en -Duser.country=US StrictParseTest * @run junit/othervm -Duser.language=ja -Duser.country=JP StrictParseTest @@ -114,8 +114,20 @@ public void uniqueCaseNumberFormatTest() { successParse(nonLocalizedDFmt, "a12345,67890b"); successParse(nonLocalizedDFmt, "a1234,67890b"); failParse(nonLocalizedDFmt, "a123456,7890b", 6); - } + // Special case: NaN + failParse(nonLocalizedDFmt, "NaNFoo", 3); + successParse(nonLocalizedDFmt, "NaN"); + // Grouping size == 0 cases + var fmt = new DecimalFormat(); + fmt.setStrict(true); + fmt.setGroupingSize(0); + fmt.setGroupingUsed(true); + var pp = new ParsePosition(0); + assertNull(fmt.parse("555,000.0", pp)); + assertEquals(3, pp.getErrorIndex()); + assertDoesNotThrow(() -> fmt.parse("555.0")); + } // 8333755: Check that parsing with integer only against a suffix value works @Test // Non-localized, run once diff --git a/test/jdk/javax/sql/test/rowset/cachedrowset/CachedRowSetWarningsTest.java b/test/jdk/javax/sql/test/rowset/cachedrowset/CachedRowSetWarningsTest.java new file mode 100644 index 000000000000..cabfd4882aee --- /dev/null +++ b/test/jdk/javax/sql/test/rowset/cachedrowset/CachedRowSetWarningsTest.java @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2026, 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. + */ +package test.rowset.cachedrowset; + +import com.sun.rowset.CachedRowSetImpl; +import org.junit.jupiter.api.Test; + +import javax.sql.rowset.CachedRowSet; +import javax.sql.rowset.RowSetFactory; +import javax.sql.rowset.RowSetMetaDataImpl; +import javax.sql.rowset.RowSetProvider; +import javax.sql.rowset.spi.SyncFactory; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Types; +import java.util.Hashtable; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +/* + * This test addresses a number of warning related issues in CachedRowSetImpl. + * See JDK-8388810 for further details. + */ +public class CachedRowSetWarningsTest { + + private static final RowSetFactory FACTORY; + private static final String WARNING_MSG = + "Populating rows setting has exceeded max row setting"; + + static { + try { + FACTORY = RowSetProvider.newFactory(); + } catch (SQLException e) { + throw new RuntimeException("Cannot create row set factory used for test", e); + } + } + + /* + * The max rows warning should only be added a single time, not for each subsequent + * row above the max row that is encountered. In the old code, only the 1-arg `populate` + * suffered from this issue, but this test covers both the 1-arg and 2-arg for coverage. + */ + @Test + public void maxRowsShouldWarnOnceTest() throws SQLException { + // RowSetWarning cannot be cleared, so use fresh instances to test the + // 1-arg and 2-arg populate + try (var oneArgCrs = FACTORY.createCachedRowSet(); + var twoArgCrs = FACTORY.createCachedRowSet(); + var pagedCrs = FACTORY.createCachedRowSet()) { + oneArgCrs.setMaxRows(1); + oneArgCrs.populate(resultSetWithRows(5)); + // There should be no subsequent chained warnings + assertNull(oneArgCrs.getRowSetWarnings().getNextWarning()); + + // The 2-arg path here also implicitly covers a bug in the old code where + // an Error would always be thrown when `getNextWarning` was invoked on the + // returned `RowSetWarning`. + twoArgCrs.setMaxRows(1); + twoArgCrs.populate(resultSetWithRows(5), 1); + // There should be no subsequent chained warnings + assertNull(twoArgCrs.getRowSetWarnings().getNextWarning()); + + // Also check the paged path for 2-arg path + pagedCrs.setPageSize(1); + pagedCrs.populate(resultSetWithRows(5), 1); + assertNull(pagedCrs.getRowSetWarnings().getNextWarning()); + } + } + + /* + * The old code in the hashtable ctor never initialized the warnings. + * An NPE would be thrown when max rows exceeded during a populate operation. + */ + @Test + public void hashtableMaxRowsTest() throws SQLException { + var env = new Hashtable(); + // Supply the standard provider + env.put(SyncFactory.ROWSET_SYNC_PROVIDER, + "com.sun.rowset.providers.RIOptimisticProvider"); + try (var crs = new CachedRowSetImpl(env); + var crs2 = new CachedRowSetImpl(env)) { + crs.setMaxRows(1); + crs2.setMaxRows(2); + // Exercise both 1-arg and 2-arg + assertDoesNotThrow(() -> crs.populate(resultSetWithRows(5))); + assertDoesNotThrow(() -> crs2.populate(resultSetWithRows(5), 1)); + } + } + + /* + * When created via the default ctor, warnings used to be eagerly created. + * Thus, the old code would return a non-null warning when there were no warnings. + * To adhere to the specification, null needs to be returned. + */ + @Test + public void noWarningsShouldBeNullTest() throws SQLException { + try (var crs = FACTORY.createCachedRowSet()) { + // Check both the SQLWarning and the RowSetWarning + assertNull(crs.getRowSetWarnings()); + assertNull(crs.getWarnings()); + } + } + + /* + * The old code always created a root warning with no message. + * If a root warning exists, it should always contain a valid warning message. + */ + @Test + public void rootWarningShouldNotBeEmptyTest() throws SQLException { + try (var crs = FACTORY.createCachedRowSet()) { + crs.setMaxRows(1); + crs.populate(resultSetWithRows(5)); + assertEquals(WARNING_MSG, crs.getRowSetWarnings().getMessage()); + } + } + + // Utility to create a crs with dummy rows (which is used to violate a crs with max rows defined) + private static ResultSet resultSetWithRows(int rows) throws SQLException { + CachedRowSet rs = FACTORY.createCachedRowSet(); + RowSetMetaDataImpl metadata = new RowSetMetaDataImpl(); + metadata.setColumnCount(1); + metadata.setColumnType(1, Types.INTEGER); + metadata.setColumnName(1, "foo"); + rs.setMetaData(metadata); + // Data does not matter, just create rows + for (int i = 1; i <= rows; i++) { + rs.moveToInsertRow(); + rs.updateInt(1, i); + rs.insertRow(); + } + rs.moveToCurrentRow(); + rs.beforeFirst(); + return rs; + } +} diff --git a/test/jdk/javax/swing/JInternalFrame/8069348/bug8069348.java b/test/jdk/javax/swing/JInternalFrame/8069348/bug8069348.java index ac253b6ccf56..c23301d2c808 100644 --- a/test/jdk/javax/swing/JInternalFrame/8069348/bug8069348.java +++ b/test/jdk/javax/swing/JInternalFrame/8069348/bug8069348.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, 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 @@ -30,6 +30,7 @@ import java.awt.Toolkit; import java.awt.image.BufferedImage; import java.awt.event.InputEvent; +import javax.swing.DesktopManager; import javax.swing.JDesktopPane; import javax.swing.JFrame; import javax.swing.JInternalFrame; @@ -45,7 +46,6 @@ * @author Alexandr Scherbatiy * @modules java.desktop/sun.awt * @run main/othervm -Dsun.java2d.uiScale=2 bug8069348 - * @run main/othervm -Dsun.java2d.d3d=true -Dsun.java2d.uiScale=2 bug8069348 */ public class bug8069348 { @@ -64,10 +64,6 @@ public class bug8069348 { public static void main(String[] args) throws Exception { - if (!isSupported()) { - return; - } - try { SwingUtilities.invokeAndWait(bug8069348::createAndShowGUI); @@ -83,14 +79,10 @@ public static void main(String[] args) throws Exception { int dx = screenBounds.width / 2; int dy = screenBounds.height / 2; - robot.mouseMove(x, y); - robot.waitForIdle(); - - robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); - robot.mouseMove(x + dx, y + dy); - robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + dragInternalFrame(dx, dy); robot.waitForIdle(); + waitForFrameBounds(robot, screenBounds.x + dx, screenBounds.y + dy); int cx = screenBounds.x + screenBounds.width + dx / 2; int cy = screenBounds.y + screenBounds.height + dy / 2; @@ -120,12 +112,37 @@ public static void main(String[] args) throws Exception { System.out.println("Test Passed"); } - private static boolean isSupported() { - String d3d = System.getProperty("sun.java2d.d3d"); - System.out.println("d3d " + d3d); - return !Boolean.getBoolean(d3d) || getOSType() == OSType.WINDOWS; + private static void dragInternalFrame(int dx, int dy) throws Exception { + SwingUtilities.invokeAndWait(() -> { + DesktopManager dm = internalFrame.getDesktopPane().getDesktopManager(); + Rectangle bounds = internalFrame.getBounds(); + + dm.beginDraggingFrame(internalFrame); + try { + dm.dragFrame(internalFrame, bounds.x + dx, bounds.y + dy); + } finally { + dm.endDraggingFrame(internalFrame); + } + }); } + private static void waitForFrameBounds(Robot robot, int x, int y) + throws Exception { + for (int i = 0; i < 10; i++) { + Rectangle bounds = getInternalFrameScreenBounds(); + if (bounds.x == x && bounds.y == y) { + return; + } + robot.delay(100); + robot.waitForIdle(); + } + + Rectangle bounds = getInternalFrameScreenBounds(); + throw new RuntimeException("Internal frame was not dragged to expected" + + " location. Expected: " + x + ", " + y + + "; actual: " + bounds.x + ", " + bounds.y); + } + private static Rectangle getInternalFrameScreenBounds() throws Exception { Rectangle[] points = new Rectangle[1]; SwingUtilities.invokeAndWait(() -> { diff --git a/test/jdk/javax/swing/JInternalFrame/Test6505027.java b/test/jdk/javax/swing/JInternalFrame/Test6505027.java index 23971408184e..5729ba782456 100644 --- a/test/jdk/javax/swing/JInternalFrame/Test6505027.java +++ b/test/jdk/javax/swing/JInternalFrame/Test6505027.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2026, 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 @@ -30,7 +30,6 @@ * @library .. */ -import java.awt.AWTException; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Container; @@ -38,6 +37,7 @@ import java.awt.Point; import java.awt.Robot; import java.awt.event.InputEvent; +import java.beans.PropertyVetoException; import javax.swing.DefaultCellEditor; import javax.swing.JComboBox; import javax.swing.JDesktopPane; @@ -67,46 +67,60 @@ public static void main(String[] args) throws Throwable { SwingTest.start(Test6505027.class); } - private final JTable table = new JTable(new DefaultTableModel(COLUMNS, 2)); + private static JTable table; public Test6505027(JFrame main) { + table = new JTable(new DefaultTableModel(COLUMNS, 2)); Container container = main; if (INTERNAL) { JInternalFrame frame = new JInternalFrame(); frame.setBounds(OFFSET, OFFSET, WIDTH, HEIGHT); - frame.setVisible(true); JDesktopPane desktop = new JDesktopPane(); desktop.add(frame, new Integer(1)); + frame.setVisible(true); container.add(desktop); + try { + frame.setSelected(true); + } catch (PropertyVetoException ex) { + throw new RuntimeException("could not select internal frame", ex); + } container = frame; } if (TERMINATE) { - this.table.putClientProperty(KEY, Boolean.TRUE); + table.putClientProperty(KEY, Boolean.TRUE); } - TableColumn column = this.table.getColumn(COLUMNS[1]); + TableColumn column = table.getColumn(COLUMNS[1]); column.setCellEditor(new DefaultCellEditor(new JComboBox(ITEMS))); container.add(BorderLayout.NORTH, new JTextField()); - container.add(BorderLayout.CENTER, new JScrollPane(this.table)); + container.add(BorderLayout.CENTER, new JScrollPane(table)); } - public void press() throws AWTException { - Point point = this.table.getCellRect(1, 1, false).getLocation(); - SwingUtilities.convertPointToScreen(point, this.table); + public static void press() throws Exception { + Point point = new Point(); + + SwingUtilities.invokeAndWait(() -> { + point.setLocation(table.getCellRect(1, 1, false).getLocation()); + SwingUtilities.convertPointToScreen(point, table); + }); Robot robot = new Robot(); robot.setAutoDelay(50); robot.mouseMove(point.x + 1, point.y + 1); - robot.mousePress(InputEvent.BUTTON1_MASK); - robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.waitForIdle(); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.waitForIdle(); + robot.delay(500); } public static void validate() { Component component = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); - if (!component.getClass().equals(JComboBox.class)) { - throw new Error("unexpected focus owner: " + component); + System.out.println("Component " + component); + if (!(component instanceof JComboBox)) { + throw new RuntimeException("unexpected focus owner: " + component); } } } diff --git a/test/jdk/sun/java2d/DirectX/OpaqueImageToSurfaceBlitTest/OpaqueImageToSurfaceBlitTest.java b/test/jdk/sun/java2d/DirectX/OpaqueImageToSurfaceBlitTest/OpaqueImageToSurfaceBlitTest.java index 7c28691aab0a..8298e9b8a1f4 100644 --- a/test/jdk/sun/java2d/DirectX/OpaqueImageToSurfaceBlitTest/OpaqueImageToSurfaceBlitTest.java +++ b/test/jdk/sun/java2d/DirectX/OpaqueImageToSurfaceBlitTest/OpaqueImageToSurfaceBlitTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2026, 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,7 +29,7 @@ * compositing * @author Dmitri.Trembovetski@sun.com: area=Graphics * @run main/othervm OpaqueImageToSurfaceBlitTest - * @run main/othervm -Dsun.java2d.noddraw=true OpaqueImageToSurfaceBlitTest + * @run main/othervm -Dsun.java2d.d3d=false OpaqueImageToSurfaceBlitTest */ import java.awt.AlphaComposite; diff --git a/test/jdk/sun/java2d/DirectX/StrikeDisposalCrashTest/StrikeDisposalCrashTest.java b/test/jdk/sun/java2d/DirectX/StrikeDisposalCrashTest/StrikeDisposalCrashTest.java index 3237d090ea89..2cba32a5b9a9 100644 --- a/test/jdk/sun/java2d/DirectX/StrikeDisposalCrashTest/StrikeDisposalCrashTest.java +++ b/test/jdk/sun/java2d/DirectX/StrikeDisposalCrashTest/StrikeDisposalCrashTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2026, 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,7 +29,7 @@ * during the lifetime of the application * * @run main/othervm -Dsun.java2d.font.reftype=weak StrikeDisposalCrashTest - * @run main/othervm -Dsun.java2d.font.reftype=weak -Dsun.java2d.noddraw=true StrikeDisposalCrashTest + * @run main/othervm -Dsun.java2d.font.reftype=weak -Dsun.java2d.d3d=false StrikeDisposalCrashTest */ import java.awt.Font; diff --git a/test/jdk/sun/java2d/SunGraphics2D/EmptyClipRenderingTest.java b/test/jdk/sun/java2d/SunGraphics2D/EmptyClipRenderingTest.java index 12770405bdd9..a59399bc5dfc 100644 --- a/test/jdk/sun/java2d/SunGraphics2D/EmptyClipRenderingTest.java +++ b/test/jdk/sun/java2d/SunGraphics2D/EmptyClipRenderingTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,7 +53,7 @@ * @author Dmitri.Trembovetski@Sun.COM: area=Graphics * @modules java.desktop/sun.awt * @run main EmptyClipRenderingTest - * @run main/othervm -Dsun.java2d.noddraw=true EmptyClipRenderingTest + * @run main/othervm -Dsun.java2d.d3d=false EmptyClipRenderingTest * @run main/othervm -Dsun.java2d.pmoffscreen=true EmptyClipRenderingTest */ public class EmptyClipRenderingTest { diff --git a/test/jdk/sun/java2d/pipe/MutableColorTest/MutableColorTest.java b/test/jdk/sun/java2d/pipe/MutableColorTest/MutableColorTest.java index 894153c399ec..1c2650ae14a4 100644 --- a/test/jdk/sun/java2d/pipe/MutableColorTest/MutableColorTest.java +++ b/test/jdk/sun/java2d/pipe/MutableColorTest/MutableColorTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2026, 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,7 +29,7 @@ * manner) mutable Colors * * @run main/othervm MutableColorTest - * @run main/othervm -Dsun.java2d.noddraw=true MutableColorTest + * @run main/othervm -Dsun.java2d.d3d=false MutableColorTest */ import java.awt.Color; diff --git a/test/jdk/sun/java2d/pipe/hw/RSLAPITest/RSLAPITest.java b/test/jdk/sun/java2d/pipe/hw/RSLAPITest/RSLAPITest.java index 9c5cf3de2e37..c949a40633ac 100644 --- a/test/jdk/sun/java2d/pipe/hw/RSLAPITest/RSLAPITest.java +++ b/test/jdk/sun/java2d/pipe/hw/RSLAPITest/RSLAPITest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2026, 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,7 +31,7 @@ * java.desktop/sun.java2d.pipe.hw * @compile -XDignore.symbol.file=true RSLAPITest.java * @run main/othervm RSLAPITest - * @run main/othervm -Dsun.java2d.noddraw=true RSLAPITest + * @run main/othervm -Dsun.java2d.d3d=false RSLAPITest */ import java.awt.Graphics; diff --git a/test/jdk/sun/util/resources/cldr/TimeZoneNamesTest.java b/test/jdk/sun/util/resources/cldr/TimeZoneNamesTest.java index 60359b8fbd4e..f9610436bc9e 100644 --- a/test/jdk/sun/util/resources/cldr/TimeZoneNamesTest.java +++ b/test/jdk/sun/util/resources/cldr/TimeZoneNamesTest.java @@ -57,8 +57,8 @@ private static Object[][] sampleTZs() { return new Object[][] { // tzid, locale, style, expected - // This list is as of CLDR version 48, and should be examined - // on the CLDR data upgrade. + // This list is current as of CLDR 48.2 and should be reviewed + // whenever the CLDR data is upgraded. // no "metazone" zones (some of them were assigned metazones // over time, thus they are not "generated" per se @@ -300,12 +300,14 @@ private static Object[][] sampleTZs() { private static Stream explicitDstOffsets() { return Stream.of( - Arguments.of(ZonedDateTime.of(2026, 4, 5, 0, 0, 0, 0, ZoneId.of("Europe/Dublin")), "Irish Standard Time"), - Arguments.of(ZonedDateTime.of(2026, 12, 5, 0, 0, 0, 0, ZoneId.of("Europe/Dublin")), "Greenwich Mean Time"), - Arguments.of(ZonedDateTime.of(2026, 4, 5, 0, 0, 0, 0, ZoneId.of("Eire")), "Irish Standard Time"), - Arguments.of(ZonedDateTime.of(2026, 12, 5, 0, 0, 0, 0, ZoneId.of("Eire")), "Greenwich Mean Time"), - Arguments.of(ZonedDateTime.of(2026, 4, 5, 0, 0, 0, 0, ZoneId.of("America/Vancouver")), "Pacific Daylight Time"), - Arguments.of(ZonedDateTime.of(2026, 12, 5, 0, 0, 0, 0, ZoneId.of("America/Vancouver")), "Pacific Daylight Time") + // CLDR v48 + Arguments.of(ZonedDateTime.of(2026, 4, 5, 0, 0, 0, 0, ZoneId.of("Europe/Dublin")), "Irish Standard Time", "IST"), + Arguments.of(ZonedDateTime.of(2026, 12, 5, 0, 0, 0, 0, ZoneId.of("Europe/Dublin")), "Greenwich Mean Time", "GMT"), + Arguments.of(ZonedDateTime.of(2026, 4, 5, 0, 0, 0, 0, ZoneId.of("Eire")), "Irish Standard Time", "IST"), + Arguments.of(ZonedDateTime.of(2026, 12, 5, 0, 0, 0, 0, ZoneId.of("Eire")), "Greenwich Mean Time", "GMT"), + // CLDR v48.2 & tz2026b. America/Vancouver switched to permanent DST + Arguments.of(ZonedDateTime.of(2026, 4, 5, 0, 0, 0, 0, ZoneId.of("America/Vancouver")), "Pacific Daylight Time", "PDT"), + Arguments.of(ZonedDateTime.of(2026, 12, 5, 0, 0, 0, 0, ZoneId.of("America/Vancouver")), "Pacific Daylight Time", "PDT") ); } @@ -340,18 +342,25 @@ public void test_getZoneStrings() { "getZoneStrings() returned array containing non-empty string element(s)"); } - // Explicit metazone dst offset test. As of CLDR v48, only Europe/Dublin utilizes - // this attribute, but will be used for America/Vancouver once CLDR adopts the - // explicit offset for that zone, which warrants the test data modification. + // Explicit metazone DST offset test. This attribute is used for Europe/Dublin + // to support the negative DST. Also, it is used to support permanent DST names, + // such as with America/Vancouver. For the latter case, both CLDR data and corresponding + // updated TZDB data are required (e.g., tz2026b for America/Vancouver). @ParameterizedTest @MethodSource("explicitDstOffsets") - public void test_ExplicitMetazoneOffsets(ZonedDateTime zdt, String expected) { + public void test_ExplicitMetazoneOffsets(ZonedDateTime zdt, String expectedLong, String expectedShort) { // java.time - assertEquals(expected, DateTimeFormatter.ofPattern("zzzz").format(zdt)); + assertEquals(expectedLong, DateTimeFormatter.ofPattern("zzzz").format(zdt)); + assertEquals(expectedShort, DateTimeFormatter.ofPattern("z").format(zdt)); // java.text/util + var date = Date.from(zdt.toInstant()); + var tz = TimeZone.getTimeZone(zdt.getZone()); var sdf = new SimpleDateFormat("zzzz"); - sdf.setTimeZone(TimeZone.getTimeZone(zdt.getZone())); - assertEquals(expected, sdf.format(Date.from(zdt.toInstant()))); + sdf.setTimeZone(tz); + assertEquals(expectedLong, sdf.format(date)); + sdf = new SimpleDateFormat("z"); + sdf.setTimeZone(tz); + assertEquals(expectedShort, sdf.format(date)); } } diff --git a/test/jdk/tools/jlink/JLinkReproducible2Test.java b/test/jdk/tools/jlink/JLinkReproducible2Test.java index 4723bd0eb8f0..56593147bfc3 100644 --- a/test/jdk/tools/jlink/JLinkReproducible2Test.java +++ b/test/jdk/tools/jlink/JLinkReproducible2Test.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2026, 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 @@ -26,6 +26,8 @@ import java.nio.file.Paths; import java.util.spi.ToolProvider; +import jdk.test.lib.util.FileUtils; + /* * @test * @summary Make sure that jimages are consistent when created by jlink. @@ -35,6 +37,8 @@ * jdk.management * jdk.unsupported * jdk.charsets + * @library /test/lib + * @build jdk.test.lib.util.FileUtils * @run main JLinkReproducible2Test */ public class JLinkReproducible2Test { @@ -54,6 +58,10 @@ public static void main(String[] args) throws Exception { throw new RuntimeException("jlink producing inconsistent result"); } + // Free disk space before creating the next pair of images. + FileUtils.deleteFileTreeWithRetry(image1); + FileUtils.deleteFileTreeWithRetry(image2); + Path image3 = Paths.get("./image3"); Path image4 = Paths.get("./image4"); diff --git a/test/jdk/tools/jlink/JLinkReproducible3Test.java b/test/jdk/tools/jlink/JLinkReproducible3Test.java index 6d37cff4ee4d..841fe1fcbb40 100644 --- a/test/jdk/tools/jlink/JLinkReproducible3Test.java +++ b/test/jdk/tools/jlink/JLinkReproducible3Test.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2026, 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,6 +22,7 @@ */ import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.util.FileUtils; import java.io.File; import java.io.IOException; @@ -40,6 +41,7 @@ * jdk.unsupported * jdk.charsets * @library /test/lib + * @build jdk.test.lib.util.FileUtils * @run main JLinkReproducible3Test */ public class JLinkReproducible3Test { @@ -48,33 +50,17 @@ public static void main(String[] args) throws Exception { Path image1 = Paths.get("./image1"); Path image2 = Paths.get("./image2"); - Path copyJdk1Dir = Path.of("./copy-jdk1-tmpdir"); - Files.createDirectory(copyJdk1Dir); - - Path copyJdk2Dir = Path.of("./copy-jdk2-tmpdir"); - Files.createDirectory(copyJdk2Dir); - Path jdkTestDir = Path.of( Optional.of( System.getProperty("test.jdk")) .orElseThrow(() -> new RuntimeException("Couldn't load JDK Test Dir")) ); - copyJDK(jdkTestDir, copyJdk1Dir); - copyJDK(jdkTestDir, copyJdk2Dir); - - Path copiedJlink1 = Optional.of( - Paths.get(copyJdk1Dir.toString(), "bin", "jlink")) - .orElseThrow(() -> new RuntimeException("Unable to load copied jlink") - ); - - Path copiedJlink2 = Optional.of( - Paths.get(copyJdk2Dir.toString(), "bin", "jlink")) - .orElseThrow(() -> new RuntimeException("Unable to load copied jlink") - ); - - runCopiedJlink(copiedJlink1.toString(), "--add-modules", "java.base,jdk.management,jdk.unsupported,jdk.charsets", "--output", image1.toString()); - runCopiedJlink(copiedJlink2.toString(), "--add-modules", "java.base,jdk.management,jdk.unsupported,jdk.charsets", "--output", image2.toString()); + // Link each image from its own copy of the JDK placed at a distinct + // location. Copy, link, then delete the copy before creating the next + // one so that at most one JDK copy exists on disk at a time. + linkFromCopy(jdkTestDir, Path.of("./copy-jdk1-tmpdir"), image1); + linkFromCopy(jdkTestDir, Path.of("./copy-jdk2-tmpdir"), image2); long mismatch = Files.mismatch(image1.resolve("lib").resolve("modules"), image2.resolve("lib").resolve("modules")); if (mismatch != -1L) { @@ -82,6 +68,20 @@ public static void main(String[] args) throws Exception { } } + private static void linkFromCopy(Path jdkTestDir, Path copyJdkDir, Path image) throws Exception { + Files.createDirectory(copyJdkDir); + copyJDK(jdkTestDir, copyJdkDir); + + Path copiedJlink = Paths.get(copyJdkDir.toString(), "bin", "jlink"); + runCopiedJlink(copiedJlink.toString(), "--add-modules", + "java.base,jdk.management,jdk.unsupported,jdk.charsets", + "--output", image.toString()); + + // The copied JDK was only needed to run jlink; free the disk space + // before creating the next copy. + FileUtils.deleteFileTreeWithRetry(copyJdkDir); + } + private static void runCopiedJlink(String... args) throws Exception { var process = new ProcessBuilder(args); var res = ProcessTools.executeProcess(process); diff --git a/test/jdk/tools/jlink/JLinkTest.java b/test/jdk/tools/jlink/JLinkTest.java index 1d84caaa147e..721870b3b9b5 100644 --- a/test/jdk/tools/jlink/JLinkTest.java +++ b/test/jdk/tools/jlink/JLinkTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,6 +36,7 @@ import jdk.tools.jlink.internal.PluginRepository; import jdk.tools.jlink.plugin.Plugin; +import jdk.test.lib.util.FileUtils; import tests.Helper; import tests.JImageGenerator; @@ -45,13 +46,14 @@ * @bug 8189777 8194922 8206962 8240349 8163382 8165735 8166810 8173717 8321139 * @author Jean-Francois Denise * @requires (vm.compMode != "Xcomp" & os.maxMemory >= 2g) - * @library ../lib + * @library ../lib /test/lib * @modules java.base/jdk.internal.jimage * jdk.jlink/jdk.tools.jlink.internal * jdk.jlink/jdk.tools.jlink.plugin * jdk.jlink/jdk.tools.jimage * jdk.compiler * @build tests.* + * @build jdk.test.lib.util.FileUtils * @run main/othervm/timeout=480 -Xmx1g JLinkTest */ public class JLinkTest { @@ -110,10 +112,12 @@ public static void main(String[] args) throws Exception { // No --module-path specified. $JAVA_HOME/jmods should be assumed. // The following should succeed as it uses only system modules. String imageDir = "bug818977-no-modulepath"; + Path image = helper.createNewImageDir(imageDir); JImageGenerator.getJLinkTask() - .output(helper.createNewImageDir(imageDir)) + .output(image) .addMods("jdk.jshell") .call().assertSuccess(); + FileUtils.deleteFileTreeWithRetry(image); } { @@ -121,11 +125,13 @@ public static void main(String[] args) throws Exception { // $JAVA_HOME/jmods should be added automatically. // The following should succeed as it uses only system modules. String imageDir = "bug8189777-invalid-modulepath"; + Path image = helper.createNewImageDir(imageDir); JImageGenerator.getJLinkTask() .modulePath("does_not_exist_path") - .output(helper.createNewImageDir(imageDir)) + .output(image) .addMods("jdk.jshell") .call().assertSuccess(); + FileUtils.deleteFileTreeWithRetry(image); } { @@ -139,11 +145,13 @@ public static void main(String[] args) throws Exception { { String moduleName = "bug8134651"; + Path image1 = helper.createNewImageDir(moduleName); JImageGenerator.getJLinkTask() .modulePath(helper.defaultModulePath()) - .output(helper.createNewImageDir(moduleName)) + .output(image1) .addMods("leaf1") .call().assertSuccess(); + FileUtils.deleteFileTreeWithRetry(image1); JImageGenerator.getJLinkTask() .modulePath(helper.defaultModulePath()) .addMods("leaf1") @@ -155,11 +163,13 @@ public static void main(String[] args) throws Exception { .addMods("leaf1") .call().assertFailure("Error: no value given for --module-path"); // do not include standard module path - should be added automatically + Path image2 = helper.createNewImageDir(moduleName); JImageGenerator.getJLinkTask() .modulePath(helper.defaultModulePath(false)) - .output(helper.createNewImageDir(moduleName)) + .output(image2) .addMods("leaf1") .call().assertSuccess(); + FileUtils.deleteFileTreeWithRetry(image2); // no --module-path. default sys mod path is assumed - but that won't contain 'leaf1' module JImageGenerator.getJLinkTask() .output(helper.createNewImageDir(moduleName)) @@ -170,18 +180,22 @@ public static void main(String[] args) throws Exception { { String moduleName = "m"; // 8163382 Path jmod = helper.generateDefaultJModule(moduleName).assertSuccess(); + Path imageM = helper.createNewImageDir(moduleName); JImageGenerator.getJLinkTask() .modulePath(helper.defaultModulePath()) - .output(helper.createNewImageDir(moduleName)) + .output(imageM) .addMods("m") .call().assertSuccess(); + FileUtils.deleteFileTreeWithRetry(imageM); moduleName = "mod"; jmod = helper.generateDefaultJModule(moduleName).assertSuccess(); + Path imageMod = helper.createNewImageDir(moduleName); JImageGenerator.getJLinkTask() .modulePath(helper.defaultModulePath()) - .output(helper.createNewImageDir(moduleName)) + .output(imageMod) .addMods("m") .call().assertSuccess(); + FileUtils.deleteFileTreeWithRetry(imageMod); } { @@ -196,13 +210,15 @@ public static void main(String[] args) throws Exception { // second --module-path does not have that module .call().assertFailure("Error: Module m_8165735 not found"); + Path imageRepeatedPath = helper.createNewImageDir(moduleName); JImageGenerator.getJLinkTask() .modulePath(".") // first --module-path overridden later .repeatedModulePath(helper.defaultModulePath()) - .output(helper.createNewImageDir(moduleName)) + .output(imageRepeatedPath) .addMods(moduleName) // second --module-path has that module .call().assertSuccess(); + FileUtils.deleteFileTreeWithRetry(imageRepeatedPath); JImageGenerator.getJLinkTask() .modulePath(helper.defaultModulePath()) @@ -212,13 +228,15 @@ public static void main(String[] args) throws Exception { .addMods(moduleName) .call().assertFailure("Error: Module m_8165735dependency not found, required by m_8165735"); + Path imageRepeatedLimit = helper.createNewImageDir(moduleName); JImageGenerator.getJLinkTask() .modulePath(helper.defaultModulePath()) - .output(helper.createNewImageDir(moduleName)) + .output(imageRepeatedLimit) .limitMods("java.base") .repeatedLimitMods(moduleName) // second --limit-modules overrides first .addMods(moduleName) .call().assertSuccess(); + FileUtils.deleteFileTreeWithRetry(imageRepeatedLimit); } { @@ -269,6 +287,7 @@ public static void main(String[] args) throws Exception { String[] files = {Helper.getDebugSymbolsExtension()}; Path imageDir = helper.generateDefaultImage(userOptions, moduleName).assertSuccess(); helper.checkImage(imageDir, moduleName, res, files); + FileUtils.deleteFileTreeWithRetry(imageDir); } // filter out + Skip debug + compress with filter + sort resources @@ -282,6 +301,7 @@ public static void main(String[] args) throws Exception { String[] res = {".jcov", "/META-INF/"}; Path imageDir = helper.generateDefaultImage(userOptions2, moduleName).assertSuccess(); helper.checkImage(imageDir, moduleName, res, null); + FileUtils.deleteFileTreeWithRetry(imageDir); } // module-info.class should not be excluded @@ -439,5 +459,6 @@ private static void testCompress(Helper helper, String moduleName, String... use helper.generateDefaultJModule(moduleName, "composite2"); Path imageDir = helper.generateDefaultImage(userOptions, moduleName).assertSuccess(); helper.checkImage(imageDir, moduleName, null, null); + FileUtils.deleteFileTreeWithRetry(imageDir); } } diff --git a/test/jdk/tools/jlink/plugins/DefaultStripDebugPluginTest.java b/test/jdk/tools/jlink/plugins/DefaultStripDebugPluginTest.java index 379b89adc9ff..c0a08093a4a7 100644 --- a/test/jdk/tools/jlink/plugins/DefaultStripDebugPluginTest.java +++ b/test/jdk/tools/jlink/plugins/DefaultStripDebugPluginTest.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2019, 2026, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2019, Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -23,6 +24,7 @@ import java.util.Map; +import jdk.tools.jlink.internal.Platform; import jdk.tools.jlink.internal.ResourcePoolManager; import jdk.tools.jlink.internal.plugins.DefaultStripDebugPlugin; import jdk.tools.jlink.internal.plugins.DefaultStripDebugPlugin.NativePluginFactory; @@ -51,12 +53,23 @@ public void testWithNativeStripPresent() { DefaultStripDebugPlugin plugin = new DefaultStripDebugPlugin(javaPlugin, nativeFactory); ResourcePoolManager inManager = new ResourcePoolManager(); + inManager.add(ResourcePoolEntry.create(MockStripPlugin.DEBUGINFO_PATH, + ResourcePoolEntry.Type.NATIVE_LIB, new byte[]{0, 1, 2, 3})); + inManager.add(ResourcePoolEntry.create(MockStripPlugin.DIZ_PATH, + ResourcePoolEntry.Type.NATIVE_LIB, new byte[]{0, 1, 2, 3})); + ResourcePoolManager outManager = new ResourcePoolManager(); ResourcePool pool = plugin.transform(inManager.resourcePool(), - inManager.resourcePoolBuilder()); + outManager.resourcePoolBuilder()); if (!pool.findEntry(MockStripPlugin.JAVA_PATH).isPresent() || !pool.findEntry(MockStripPlugin.NATIVE_PATH).isPresent()) { throw new AssertionError("Expected both native and java to get called"); } + if (pool.findEntry(MockStripPlugin.DEBUGINFO_PATH).isPresent()) { + throw new AssertionError(".debuginfo file should have been excluded"); + } + if (pool.findEntry(MockStripPlugin.DIZ_PATH).isPresent()) { + throw new AssertionError(".diz file should have been excluded"); + } } public void testNoNativeStripPluginPresent() { @@ -66,11 +79,22 @@ public void testNoNativeStripPluginPresent() { DefaultStripDebugPlugin plugin = new DefaultStripDebugPlugin(javaPlugin, nativeFactory); ResourcePoolManager inManager = new ResourcePoolManager(); + inManager.add(ResourcePoolEntry.create(MockStripPlugin.DEBUGINFO_PATH, + ResourcePoolEntry.Type.NATIVE_LIB, new byte[]{0, 1, 2, 3})); + inManager.add(ResourcePoolEntry.create(MockStripPlugin.DIZ_PATH, + ResourcePoolEntry.Type.NATIVE_LIB, new byte[]{0, 1, 2, 3})); + ResourcePoolManager outManager = new ResourcePoolManager(); ResourcePool pool = plugin.transform(inManager.resourcePool(), - inManager.resourcePoolBuilder()); + outManager.resourcePoolBuilder()); if (!pool.findEntry(MockStripPlugin.JAVA_PATH).isPresent()) { throw new AssertionError("Expected java strip plugin to get called"); } + if (pool.findEntry(MockStripPlugin.DEBUGINFO_PATH).isPresent()) { + throw new AssertionError(".debuginfo file should have been excluded"); + } + if (pool.findEntry(MockStripPlugin.DIZ_PATH).isPresent()) { + throw new AssertionError(".diz file should have been excluded"); + } } // Disable embedded strip Java plugin, with native plugin present. @@ -84,12 +108,23 @@ public void testOnlyNativePlugin() { plugin.enableJavaStripPlugin(false); ResourcePoolManager inManager = new ResourcePoolManager(); + inManager.add(ResourcePoolEntry.create(MockStripPlugin.DEBUGINFO_PATH, + ResourcePoolEntry.Type.NATIVE_LIB, new byte[]{0, 1, 2, 3})); + inManager.add(ResourcePoolEntry.create(MockStripPlugin.DIZ_PATH, + ResourcePoolEntry.Type.NATIVE_LIB, new byte[]{0, 1, 2, 3})); + ResourcePoolManager outManager = new ResourcePoolManager(); ResourcePool pool = plugin.transform(inManager.resourcePool(), - inManager.resourcePoolBuilder()); + outManager.resourcePoolBuilder()); if (pool.findEntry(MockStripPlugin.JAVA_PATH).isPresent() || !pool.findEntry(MockStripPlugin.NATIVE_PATH).isPresent()) { throw new AssertionError("Expected only native to get called"); } + if (pool.findEntry(MockStripPlugin.DEBUGINFO_PATH).isPresent()) { + throw new AssertionError(".debuginfo file should have been excluded"); + } + if (pool.findEntry(MockStripPlugin.DIZ_PATH).isPresent()) { + throw new AssertionError(".diz file should have been excluded"); + } } // Disable embedded strip Java plugin, and without native plugin present. @@ -101,12 +136,23 @@ public void testNoOperation() { nativeFactory); plugin.enableJavaStripPlugin(false); ResourcePoolManager inManager = new ResourcePoolManager(); + inManager.add(ResourcePoolEntry.create(MockStripPlugin.DEBUGINFO_PATH, + ResourcePoolEntry.Type.NATIVE_LIB, new byte[]{0, 1, 2, 3})); + inManager.add(ResourcePoolEntry.create(MockStripPlugin.DIZ_PATH, + ResourcePoolEntry.Type.NATIVE_LIB, new byte[]{0, 1, 2, 3})); + ResourcePoolManager outManager = new ResourcePoolManager(); ResourcePool pool = plugin.transform(inManager.resourcePool(), - inManager.resourcePoolBuilder()); + outManager.resourcePoolBuilder()); if (pool.findEntry(MockStripPlugin.JAVA_PATH).isPresent() || pool.findEntry(MockStripPlugin.NATIVE_PATH).isPresent()) { throw new AssertionError("Expected both native and java not called"); } + if (pool.findEntry(MockStripPlugin.DEBUGINFO_PATH).isPresent()) { + throw new AssertionError(".debuginfo file should have been excluded"); + } + if (pool.findEntry(MockStripPlugin.DIZ_PATH).isPresent()) { + throw new AssertionError(".diz file should have been excluded"); + } } public static void main(String[] args) { @@ -121,10 +167,25 @@ public static class MockStripPlugin implements Plugin { private static final String NATIVE_PATH = "/foo/lib/test.so.debug"; private static final String JAVA_PATH = "/foo/TestClass.class"; + // Platform-appropriate debug file paths, matching the patterns chosen by + // DefaultStripDebugPlugin.debugFilePattern() for the runtime platform. + static final String DEBUGINFO_PATH = platformDebugPath(); + static final String DIZ_PATH = "/foo/lib/libfoo.diz"; private static final String STRIP_NATIVE_NAME = "strip-native-debug-symbols"; private static final String OMIT_ARG = "exclude-debuginfo-files"; private final boolean isNative; + private static String platformDebugPath() { + String platform = Platform.runtime().toString(); + if (platform.startsWith("windows")) { + return "/foo/bin/libfoo.pdb"; + } else if (platform.startsWith("macos")) { + return "/foo/lib/libfoo.dylib.dSYM/Contents/Resources/DWARF/libfoo.dylib"; + } else { + return "/foo/lib/libfoo.so.debuginfo"; + } + } + MockStripPlugin(boolean isNative) { this.isNative = isNative; } @@ -153,8 +214,7 @@ public ResourcePool transform(ResourcePool in, resPath = NATIVE_PATH; type = Type.NATIVE_LIB; } - ResourcePoolEntry entry = createMockEntry(resPath, type); - out.add(entry); + out.add(createMockEntry(resPath, type)); return out.build(); } diff --git a/test/jdk/tools/jlink/plugins/ExcludeJmodSectionPluginTest.java b/test/jdk/tools/jlink/plugins/ExcludeJmodSectionPluginTest.java index ac40cda036c7..1ee00d122185 100644 --- a/test/jdk/tools/jlink/plugins/ExcludeJmodSectionPluginTest.java +++ b/test/jdk/tools/jlink/plugins/ExcludeJmodSectionPluginTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2026, 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,6 +28,7 @@ * @modules jdk.compiler * jdk.jlink * @build jdk.test.lib.compiler.CompilerUtils + * @build jdk.test.lib.util.FileUtils * @run testng ExcludeJmodSectionPluginTest */ @@ -35,12 +36,9 @@ import java.io.File; import java.io.IOException; import java.io.PrintWriter; -import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; import java.util.HashSet; import java.util.List; @@ -49,7 +47,10 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import jdk.test.lib.compiler.CompilerUtils; +import jdk.test.lib.util.FileUtils; +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeTest; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -75,6 +76,8 @@ public class ExcludeJmodSectionPluginTest { static final Path INCLUDE_DIR = Paths.get("include"); static final Path IMAGES_DIR = Paths.get("images"); + private Path lastImageDir; + @BeforeTest private void setup() throws Exception { // build jmod files @@ -209,12 +212,13 @@ public void testJavaBase() { private Path createImage(String outputDir, List options, List expectedFiles) { + lastImageDir = IMAGES_DIR.resolve(outputDir); System.out.println("jlink " + options.toString()); int rc = JLINK_TOOL.run(System.out, System.out, options.toArray(new String[0])); assertTrue(rc == 0); - Path d = IMAGES_DIR.resolve(outputDir); + Path d = lastImageDir; for (String fn : expectedFiles) { Path path = d.resolve(fn); if (Files.notExists(path)) { @@ -224,24 +228,12 @@ private Path createImage(String outputDir, List options, return d; } - private void deleteDirectory(Path dir) throws IOException { - Files.walkFileTree(dir, new SimpleFileVisitor() { - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) - throws IOException - { - Files.delete(file); - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult postVisitDirectory(Path dir, IOException exc) - throws IOException - { - Files.delete(dir); - return FileVisitResult.CONTINUE; - } - }); + @AfterMethod + public void cleanup(ITestResult result) throws IOException { + if (result.isSuccess() && lastImageDir != null && Files.exists(lastImageDir)) { + FileUtils.deleteFileTreeWithRetry(lastImageDir); + } + lastImageDir = null; } /** @@ -258,7 +250,7 @@ class JmodFileBuilder { Path msrc = SRC_DIR.resolve(name); if (Files.exists(msrc)) { - deleteDirectory(msrc); + FileUtils.deleteFileTreeWithRetry(msrc); } } diff --git a/test/jdk/tools/jlink/plugins/GenerateJLIClassesPluginTest.java b/test/jdk/tools/jlink/plugins/GenerateJLIClassesPluginTest.java index 998444b9a771..06e2c7b52f0c 100644 --- a/test/jdk/tools/jlink/plugins/GenerateJLIClassesPluginTest.java +++ b/test/jdk/tools/jlink/plugins/GenerateJLIClassesPluginTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,10 +34,13 @@ import java.util.List; import java.util.stream.Collectors; +import org.testng.ITestResult; import org.testng.Assert; +import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; +import jdk.test.lib.util.FileUtils; import jdk.tools.jlink.internal.LinkableRuntimeImage; import tests.Helper; import tests.JImageGenerator; @@ -48,7 +51,7 @@ /* * @test * @bug 8252919 8327499 - * @library ../../lib + * @library ../../lib /test/lib * @summary Test --generate-jli-classes plugin * @modules java.base/jdk.internal.jimage * jdk.jlink/jdk.tools.jlink.internal @@ -56,11 +59,13 @@ * jdk.jlink/jdk.tools.jmod * jdk.jlink/jdk.tools.jimage * @build tests.* + * @build jdk.test.lib.util.FileUtils * @run testng/othervm GenerateJLIClassesPluginTest */ public class GenerateJLIClassesPluginTest { private static Helper helper; + private static Path lastImageDir; @BeforeTest public static void setup() throws Exception { @@ -80,6 +85,14 @@ public static void setup() throws Exception { } } + @AfterMethod + public static void cleanup(ITestResult result) throws IOException { + if (result.isSuccess() && lastImageDir != null && Files.exists(lastImageDir)) { + FileUtils.deleteFileTreeWithRetry(lastImageDir); + } + lastImageDir = null; + } + @Test public static void testSpecies() throws IOException { // Check that --generate-jli-classes=@file works as intended @@ -88,7 +101,7 @@ public static void testSpecies() throws IOException { String fileString = "[SPECIES_RESOLVE] java.lang.invoke.BoundMethodHandle$Species_" + species + " (salvaged)\n"; Files.write(baseFile, fileString.getBytes(Charset.defaultCharset())); Result result = JImageGenerator.getJLinkTask() - .output(helper.createNewImageDir("generate-jli-file")) + .output(lastImageDir = helper.createNewImageDir("generate-jli-file")) .option("--generate-jli-classes=@" + baseFile.toString()) .addMods("java.base") .call(); @@ -113,7 +126,7 @@ public static void testInvalidSignatures() throws IOException { fileString = "[LF_RESOLVE] java.lang.invoke.DirectMethodHandle$Holder invokeVirtual L_L (success)\n"; Files.write(failFile, fileString.getBytes(Charset.defaultCharset())); Result result = JImageGenerator.getJLinkTask() - .output(helper.createNewImageDir("invalid-signature")) + .output(lastImageDir = helper.createNewImageDir("invalid-signature")) .option("--generate-jli-classes=@" + failFile.toString()) .addMods("java.base") .call(); @@ -125,7 +138,7 @@ public static void testInvalidSignatures() throws IOException { @Test public static void nonExistentTraceFile() throws IOException { Result result = JImageGenerator.getJLinkTask() - .output(helper.createNewImageDir("non-existent-tracefile")) + .output(lastImageDir = helper.createNewImageDir("non-existent-tracefile")) .option("--generate-jli-classes=@NON_EXISTENT_FILE") .addMods("java.base") .call(); @@ -140,7 +153,7 @@ public static void testInvokers() throws IOException { Path invokersTrace = Files.createTempFile("invokers", "trace"); Files.writeString(invokersTrace, fileString, Charset.defaultCharset()); Result result = JImageGenerator.getJLinkTask() - .output(helper.createNewImageDir("jli-invokers")) + .output(lastImageDir = helper.createNewImageDir("jli-invokers")) .option("--generate-jli-classes=@" + invokersTrace.toString()) .addMods("java.base") .call(); diff --git a/test/jdk/tools/jlink/plugins/IncludeLocalesPluginTest.java b/test/jdk/tools/jlink/plugins/IncludeLocalesPluginTest.java index 5551d54a1ea1..da0df46e73bd 100644 --- a/test/jdk/tools/jlink/plugins/IncludeLocalesPluginTest.java +++ b/test/jdk/tools/jlink/plugins/IncludeLocalesPluginTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2026, 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,6 +22,7 @@ */ import java.io.IOException; +import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; @@ -35,11 +36,13 @@ import jdk.tools.jlink.internal.plugins.PluginsResourceBundle; import jdk.tools.jlink.plugin.PluginException; import jdk.test.lib.Platform; +import jdk.test.lib.util.FileUtils; import tests.Helper; import tests.JImageGenerator; import tests.JImageValidator; import tests.Result; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -67,6 +70,7 @@ * jdk.compiler * @build tests.* * @build jdk.test.lib.Platform + * @build jdk.test.lib.util.FileUtils * @build tools.jlink.plugins.GetAvailableLocales * @run junit/othervm/timeout=720 -Xmx1g IncludeLocalesPluginTest */ @@ -75,6 +79,8 @@ public class IncludeLocalesPluginTest { private static final String MODULE_NAME = "IncludeLocalesTest"; private static Helper helper; + private Path lastImageDir; + private boolean testPassed; // Test data should include: // - --include-locales command line option @@ -422,18 +428,22 @@ public static void setup() throws IOException { @MethodSource("testData") public void launch(String optIncludeLocales, String optAddModules, List requiredRes, List shouldNotExistRes, List availableLocs, String errorMsg) throws Exception { + testPassed = false; // create image for each test data Result result; + lastImageDir = helper.createNewImageDir(MODULE_NAME); if (optIncludeLocales.isEmpty()) { System.out.println("Invoking jlink with no --include-locales option"); result = JImageGenerator.getJLinkTask() - .output(helper.createNewImageDir(MODULE_NAME)) + .output(lastImageDir) + .option("--strip-debug") .addMods(optAddModules) .call(); } else { System.out.println("Invoking jlink with \"" + optIncludeLocales + "\""); result = JImageGenerator.getJLinkTask() - .output(helper.createNewImageDir(MODULE_NAME)) + .output(lastImageDir) + .option("--strip-debug") .addMods(optAddModules) .option(optIncludeLocales) .call(); @@ -452,6 +462,14 @@ public void launch(String optIncludeLocales, String optAddModules, List .getMessage("error.prefix") + " " +errorMsg); System.out.println("\tExpected failure: " + result.getMessage()); } + testPassed = true; + } + + @AfterEach + public void cleanup() throws IOException { + if (testPassed && lastImageDir != null && Files.exists(lastImageDir)) { + FileUtils.deleteFileTreeWithRetry(lastImageDir); + } } private static void testLocaleDataEntries(Path image, List expectedLocations, diff --git a/test/jdk/tools/jlink/plugins/LegalFilePluginTest.java b/test/jdk/tools/jlink/plugins/LegalFilePluginTest.java index 3647e0fb27bf..07dd1d514be8 100644 --- a/test/jdk/tools/jlink/plugins/LegalFilePluginTest.java +++ b/test/jdk/tools/jlink/plugins/LegalFilePluginTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2026, 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,6 +29,7 @@ * @modules jdk.compiler * jdk.jlink * @build jdk.test.lib.compiler.CompilerUtils + * @build jdk.test.lib.util.FileUtils * @run testng LegalFilePluginTest */ @@ -38,12 +39,9 @@ import java.io.PrintWriter; import java.io.StringWriter; import java.io.UncheckedIOException; -import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; @@ -54,7 +52,10 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import jdk.test.lib.compiler.CompilerUtils; +import jdk.test.lib.util.FileUtils; +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeTest; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -79,6 +80,8 @@ public class LegalFilePluginTest { static final Path LEGAL_DIR = Paths.get("legal"); static final Path IMAGES_DIR = Paths.get("images"); + private Path lastImageDir; + static final Map, Map> LICENSES = Map.of( // Key is module name and requires // Value is a map of filename to the file content @@ -259,32 +262,21 @@ private void compareFileContent(Path file, String content) { } private Path createImage(String outputDir, List options) { + lastImageDir = IMAGES_DIR.resolve(outputDir); System.out.println("jlink " + options.stream().collect(Collectors.joining(" "))); int rc = JLINK_TOOL.run(System.out, System.out, options.toArray(new String[0])); assertTrue(rc == 0); - return IMAGES_DIR.resolve(outputDir); + return lastImageDir; } - private void deleteDirectory(Path dir) throws IOException { - Files.walkFileTree(dir, new SimpleFileVisitor() { - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) - throws IOException - { - Files.delete(file); - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult postVisitDirectory(Path dir, IOException exc) - throws IOException - { - Files.delete(dir); - return FileVisitResult.CONTINUE; - } - }); + @AfterMethod + public void cleanup(ITestResult result) throws IOException { + if (result.isSuccess() && lastImageDir != null && Files.exists(lastImageDir)) { + FileUtils.deleteFileTreeWithRetry(lastImageDir); + } + lastImageDir = null; } /** @@ -301,7 +293,7 @@ class JmodFileBuilder { Path msrc = SRC_DIR.resolve(name); if (Files.exists(msrc)) { - deleteDirectory(msrc); + FileUtils.deleteFileTreeWithRetry(msrc); } } diff --git a/test/jdk/tools/jlink/plugins/SystemModuleDescriptors/UserModuleTest.java b/test/jdk/tools/jlink/plugins/SystemModuleDescriptors/UserModuleTest.java index b7c9a59bd655..6d7e4df7fabc 100644 --- a/test/jdk/tools/jlink/plugins/SystemModuleDescriptors/UserModuleTest.java +++ b/test/jdk/tools/jlink/plugins/SystemModuleDescriptors/UserModuleTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,6 +37,9 @@ import static jdk.test.lib.process.ProcessTools.*; +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; import static org.testng.Assert.*; @@ -68,6 +71,8 @@ public class UserModuleTest { // the names of the modules in this test private static String[] modules = new String[] {"m1", "m2", "m3", "m4", "m5"}; + private Path lastPerTestImageDir; + private static boolean hasJmods() { if (!Files.exists(Paths.get(JAVA_HOME, "jmods"))) { @@ -100,6 +105,22 @@ public void compileAll() throws Throwable { createJmods("m1", "m4"); } + @AfterMethod + public void cleanupPerTestImage(ITestResult result) throws IOException { + if (result.isSuccess() && lastPerTestImageDir != null + && Files.exists(lastPerTestImageDir)) { + FileUtils.deleteFileTreeWithRetry(lastPerTestImageDir); + } + lastPerTestImageDir = null; + } + + @AfterTest(alwaysRun = true) + public void cleanupSharedImage() throws IOException { + if (Files.exists(IMAGE)) { + FileUtils.deleteFileTreeWithRetry(IMAGE); + } + } + /* * Test the image created when linking with a module with * no Packages attribute @@ -157,7 +178,7 @@ public void disableSystemModules() throws Throwable { public void testDedupSet() throws Throwable { if (!hasJmods()) return; - Path dir = Paths.get("dedupSetTest"); + Path dir = lastPerTestImageDir = Paths.get("dedupSetTest"); createImage(dir, "m1", "m2", "m3", "m4"); Path java = dir.resolve("bin").resolve("java"); assertTrue(executeProcess(java.toString(), @@ -172,7 +193,7 @@ public void testDedupSet() throws Throwable { public void testRequiresStatic() throws Throwable { if (!hasJmods()) return; - Path dir = Paths.get("requiresStatic"); + Path dir = lastPerTestImageDir = Paths.get("requiresStatic"); createImage(dir, "m5"); Path java = dir.resolve("bin").resolve("java"); assertTrue(executeProcess(java.toString(), "-m", "m5/p5.Main") @@ -194,7 +215,7 @@ public void testRequiresStatic() throws Throwable { public void testRequiresStatic2() throws Throwable { if (!hasJmods()) return; - Path dir = Paths.get("requiresStatic2"); + Path dir = lastPerTestImageDir = Paths.get("requiresStatic2"); createImage(dir, "m3", "m5"); Path java = dir.resolve("bin").resolve("java"); @@ -242,7 +263,7 @@ public void testModulePackagesAttribute() throws Throwable { if (!hasJmods()) return; // create an image using JMOD files - Path dir = Paths.get("packagesTest"); + Path dir = lastPerTestImageDir = Paths.get("packagesTest"); String mp = Paths.get(JAVA_HOME, "jmods").toString() + File.pathSeparator + JMODS_DIR.toString(); @@ -271,7 +292,7 @@ public void testRetainModuleTarget() throws Throwable { if (!hasJmods()) return; // create an image using JMOD files - Path dir = Paths.get("retainModuleTargetTest"); + Path dir = lastPerTestImageDir = Paths.get("retainModuleTargetTest"); String mp = Paths.get(JAVA_HOME, "jmods").toString() + File.pathSeparator + JMODS_DIR.toString(); diff --git a/test/jdk/tools/jlink/runtimeImage/AbstractLinkableRuntimeTest.java b/test/jdk/tools/jlink/runtimeImage/AbstractLinkableRuntimeTest.java index 1df4455bc7dc..9414508769bb 100644 --- a/test/jdk/tools/jlink/runtimeImage/AbstractLinkableRuntimeTest.java +++ b/test/jdk/tools/jlink/runtimeImage/AbstractLinkableRuntimeTest.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2024, 2026, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2024, Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -41,6 +42,7 @@ import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.util.FileUtils; import jdk.tools.jlink.internal.LinkableRuntimeImage; import tests.Helper; import tests.JImageGenerator; @@ -141,7 +143,11 @@ protected Path createJavaImageRuntimeLink(BaseJlinkSpec baseSpec, Set ex for (String extra: baseSpec.getExtraOptions()) { builder.extraJlinkOpt(extra); } - return jlinkUsingImage(builder.build()); + Path finalImage = jlinkUsingImage(builder.build()); + // The intermediate run-time link image was only needed as the jlink + // source for producing the final image; free the disk space now. + FileUtils.deleteFileTreeWithRetry(runtimeJlinkImage); + return finalImage; } protected Path jlinkUsingImage(JlinkSpec spec) throws Exception { @@ -280,6 +286,12 @@ protected Path createRuntimeLinkImage(BaseJlinkSpec baseSpec, // Remove JMODs as needed for the test copyJDKTreeWithoutSpecificJmods(from, runtimeJlinkImage, excludedJmodFiles); + // In the non-linkable-runtime case 'from' is a temporary + // --generate-linkable-runtime image that has now been copied into + // 'runtimeJlinkImage'; delete it to free the disk space. + if (!baseSpec.isLinkableRuntime()) { + FileUtils.deleteFileTreeWithRetry(from); + } // Verify the base image is actually without desired packaged modules if (excludedJmodFiles.isEmpty()) { if (Files.exists(runtimeJlinkImage.resolve("jmods"))) { diff --git a/test/langtools/jdk/javadoc/doclet/testFonts/TestFonts.java b/test/langtools/jdk/javadoc/doclet/testFonts/TestFonts.java index 538eea6b1ff3..d2afe0a02ccd 100644 --- a/test/langtools/jdk/javadoc/doclet/testFonts/TestFonts.java +++ b/test/langtools/jdk/javadoc/doclet/testFonts/TestFonts.java @@ -72,35 +72,22 @@ public void testFonts(Path base) throws Exception { """ @font-face { font-family: 'DejaVu Sans Mono'; - src: url('DejaVuLGCSansMono.woff2') format('woff2'), - url('DejaVuLGCSansMono.woff') format('woff'); + src: url('DejaVuLGCSansMono.woff2') format('woff2'); font-weight: normal; font-style: normal; }"""); checkFiles(true, - "resource-files/fonts/DejaVuLGCSans-Bold.woff", "resource-files/fonts/DejaVuLGCSans-Bold.woff2", - "resource-files/fonts/DejaVuLGCSans-BoldOblique.woff", "resource-files/fonts/DejaVuLGCSans-BoldOblique.woff2", - "resource-files/fonts/DejaVuLGCSans-Oblique.woff", "resource-files/fonts/DejaVuLGCSans-Oblique.woff2", - "resource-files/fonts/DejaVuLGCSans.woff", "resource-files/fonts/DejaVuLGCSans.woff2", - "resource-files/fonts/DejaVuLGCSansMono-Bold.woff", "resource-files/fonts/DejaVuLGCSansMono-Bold.woff2", - "resource-files/fonts/DejaVuLGCSansMono-BoldOblique.woff", "resource-files/fonts/DejaVuLGCSansMono-BoldOblique.woff2", - "resource-files/fonts/DejaVuLGCSansMono-Oblique.woff", "resource-files/fonts/DejaVuLGCSansMono-Oblique.woff2", - "resource-files/fonts/DejaVuLGCSansMono.woff", "resource-files/fonts/DejaVuLGCSansMono.woff2", - "resource-files/fonts/DejaVuLGCSerif-Bold.woff", "resource-files/fonts/DejaVuLGCSerif-Bold.woff2", - "resource-files/fonts/DejaVuLGCSerif-BoldItalic.woff", "resource-files/fonts/DejaVuLGCSerif-BoldItalic.woff2", - "resource-files/fonts/DejaVuLGCSerif-Italic.woff", "resource-files/fonts/DejaVuLGCSerif-Italic.woff2", - "resource-files/fonts/DejaVuLGCSerif.woff", "resource-files/fonts/DejaVuLGCSerif.woff2"); } diff --git a/test/langtools/jdk/javadoc/tool/api/basic/APITest.java b/test/langtools/jdk/javadoc/tool/api/basic/APITest.java index bd8d0cf79531..e77a50a2088f 100644 --- a/test/langtools/jdk/javadoc/tool/api/basic/APITest.java +++ b/test/langtools/jdk/javadoc/tool/api/basic/APITest.java @@ -216,29 +216,17 @@ protected void error(String msg) { "resource-files/x.svg", "resource-files/sort-a-z.svg", "resource-files/fonts/dejavu.css", - "resource-files/fonts/DejaVuLGCSans-Bold.woff", "resource-files/fonts/DejaVuLGCSans-Bold.woff2", - "resource-files/fonts/DejaVuLGCSans-BoldOblique.woff", "resource-files/fonts/DejaVuLGCSans-BoldOblique.woff2", - "resource-files/fonts/DejaVuLGCSans-Oblique.woff", "resource-files/fonts/DejaVuLGCSans-Oblique.woff2", - "resource-files/fonts/DejaVuLGCSans.woff", "resource-files/fonts/DejaVuLGCSans.woff2", - "resource-files/fonts/DejaVuLGCSansMono-Bold.woff", "resource-files/fonts/DejaVuLGCSansMono-Bold.woff2", - "resource-files/fonts/DejaVuLGCSansMono-BoldOblique.woff", "resource-files/fonts/DejaVuLGCSansMono-BoldOblique.woff2", - "resource-files/fonts/DejaVuLGCSansMono-Oblique.woff", "resource-files/fonts/DejaVuLGCSansMono-Oblique.woff2", - "resource-files/fonts/DejaVuLGCSansMono.woff", "resource-files/fonts/DejaVuLGCSansMono.woff2", - "resource-files/fonts/DejaVuLGCSerif-Bold.woff", "resource-files/fonts/DejaVuLGCSerif-Bold.woff2", - "resource-files/fonts/DejaVuLGCSerif-BoldItalic.woff", "resource-files/fonts/DejaVuLGCSerif-BoldItalic.woff2", - "resource-files/fonts/DejaVuLGCSerif-Italic.woff", "resource-files/fonts/DejaVuLGCSerif-Italic.woff2", - "resource-files/fonts/DejaVuLGCSerif.woff", "resource-files/fonts/DejaVuLGCSerif.woff2", "script-files/script.js", "script-files/search.js", diff --git a/test/langtools/tools/javac/api/8007344/Test.java b/test/langtools/tools/javac/api/8007344/Test.java index b8d4a8bb49f6..fc4941c7a43a 100644 --- a/test/langtools/tools/javac/api/8007344/Test.java +++ b/test/langtools/tools/javac/api/8007344/Test.java @@ -225,8 +225,8 @@ void checkComment() { } void checkEndPos(CompilationUnitTree unit, Tree tree) { - long sp = srcPosns.getStartPosition(unit, tree); - long ep = srcPosns.getEndPosition(unit, tree); + long sp = srcPosns.getStartPosition(tree); + long ep = srcPosns.getEndPosition(tree); if (sp >= 0 && ep == Position.NOPOS) { error("endpos not set for " + tree.getKind() + " " + Pretty.toSimpleString(((JCTree) tree)) diff --git a/test/langtools/tools/javac/api/T6412669.java b/test/langtools/tools/javac/api/T6412669.java index 03df8df461f7..9c3d6497d91c 100644 --- a/test/langtools/tools/javac/api/T6412669.java +++ b/test/langtools/tools/javac/api/T6412669.java @@ -81,8 +81,8 @@ public boolean process(Set annotations, RoundEnvironment for (Element e: roundEnv.getElementsAnnotatedWith(anno)) { m.printNote(" processing element " + e); TreePath p = trees.getPath(e); - long start = sp.getStartPosition(p.getCompilationUnit(), p.getLeaf()); - long end = sp.getEndPosition(p.getCompilationUnit(), p.getLeaf()); + long start = sp.getStartPosition(p.getLeaf()); + long end = sp.getEndPosition(p.getLeaf()); Diagnostic.Kind k = (start > 0 && end > 0 && start < end ? Diagnostic.Kind.NOTE : Diagnostic.Kind.ERROR); m.printMessage(k, "test [" + start + "," + end + "]", e); diff --git a/test/langtools/tools/javac/doctree/positions/TestPosition.java b/test/langtools/tools/javac/doctree/positions/TestPosition.java index 6d66a84d83ba..f10a0f3803f5 100644 --- a/test/langtools/tools/javac/doctree/positions/TestPosition.java +++ b/test/langtools/tools/javac/doctree/positions/TestPosition.java @@ -78,8 +78,8 @@ public boolean process(Set annotations, RoundEnvironment @Override public Void scan(DocTree node, Void p) { if (node != null) { DocSourcePositions sp = trees.getSourcePositions(); - int start = (int) sp.getStartPosition(testElement.getCompilationUnit(), docCommentTree, node); - int end = (int) sp.getEndPosition(testElement.getCompilationUnit(), docCommentTree, node); + int start = (int) sp.getStartPosition(docCommentTree, node); + int end = (int) sp.getEndPosition(docCommentTree, node); String snippet = code.substring(start, end).replace(" \n", "!trailing-whitespace!\n"); if (snippet.endsWith(" ")) { diff --git a/test/langtools/tools/javac/patterns/PatternMatchPosTest.java b/test/langtools/tools/javac/patterns/PatternMatchPosTest.java index a9ab0e6fadfb..79fcc2161290 100644 --- a/test/langtools/tools/javac/patterns/PatternMatchPosTest.java +++ b/test/langtools/tools/javac/patterns/PatternMatchPosTest.java @@ -83,8 +83,8 @@ public Void scan(Tree tree, Void p) { if (tree == null) return null; if (print) { - int start = (int) sp.getStartPosition(dataPath.getCompilationUnit(), tree); - int end = (int) sp.getEndPosition(dataPath.getCompilationUnit(), tree); + int start = (int) sp.getStartPosition(tree); + int end = (int) sp.getEndPosition(tree); if (start != (-1) || end != (-1)) { processingEnv.getMessager().printNote(text.substring(start, end)); } diff --git a/test/langtools/tools/javac/tree/TreePosRoundsTest.java b/test/langtools/tools/javac/tree/TreePosRoundsTest.java index 7ba12aa88e25..2595692f8b35 100644 --- a/test/langtools/tools/javac/tree/TreePosRoundsTest.java +++ b/test/langtools/tools/javac/tree/TreePosRoundsTest.java @@ -159,13 +159,13 @@ void check(TreePath tp) { } //System.err.println("expect: " + expect); - int start = (int)sourcePositions.getStartPosition(unit, tree); + int start = (int)sourcePositions.getStartPosition(tree); if (start == Diagnostic.NOPOS) { messager.printError("start pos not set for " + trim(tree)); return; } - int end = (int)sourcePositions.getEndPosition(unit, tree); + int end = (int)sourcePositions.getEndPosition(tree); if (end == Diagnostic.NOPOS) { messager.printError("end pos not set for " + trim(tree)); return; diff --git a/test/lib/jdk/test/lib/cds/CDSAppTester.java b/test/lib/jdk/test/lib/cds/CDSAppTester.java index 80ff54021f5e..0be21b9ec274 100644 --- a/test/lib/jdk/test/lib/cds/CDSAppTester.java +++ b/test/lib/jdk/test/lib/cds/CDSAppTester.java @@ -228,9 +228,18 @@ private OutputAnalyzer executeAndCheck(String[] cmdLine, RunMode runMode, String return output; } - private String[] addCommonVMArgs(RunMode runMode, String[] cmdLine) { + // This method should be called before `vmArgs()`, so that subclasses of CDSAppTester + // can have a chance to override the flags set here. + private String[] addCommonVMArgs(RunMode runMode) { + String[] cmdLine = new String[0]; cmdLine = addClassOrModulePath(runMode, cmdLine); cmdLine = addWhiteBox(cmdLine); + // In one-step workflow ASSEMBLY phase is not executed separately. + // Therefore AOTCompatibleOopCompression needs to be passed to the TRAINING phase, + // so that it can be propagated to the ASSEMBLY phase. + if (runMode == RunMode.TRAINING || runMode == RunMode.ASSEMBLY) { + cmdLine = StringArrayUtils.concat(cmdLine, "-XX:+UnlockDiagnosticVMOptions", "-XX:+AOTCompatibleOopCompression"); + } return cmdLine; } @@ -261,30 +270,32 @@ private String[] addWhiteBox(String[] cmdLine) { private OutputAnalyzer recordAOTConfiguration() throws Exception { RunMode runMode = RunMode.TRAINING; - String[] cmdLine = StringArrayUtils.concat(vmArgs(runMode), - "-XX:AOTMode=record", - "-XX:AOTConfiguration=" + aotConfigurationFile, - logToFile(aotConfigurationFileLog, - "class+load=debug", - "aot=debug", - "cds=debug", - "aot+class=debug")); - cmdLine = addCommonVMArgs(runMode, cmdLine); + String[] cmdLine = addCommonVMArgs(runMode); + cmdLine = StringArrayUtils.concat(cmdLine, vmArgs(runMode)); + cmdLine = StringArrayUtils.concat(cmdLine, + "-XX:AOTMode=record", + "-XX:AOTConfiguration=" + aotConfigurationFile, + logToFile(aotConfigurationFileLog, + "class+load=debug", + "aot=debug", + "cds=debug", + "aot+class=debug")); cmdLine = StringArrayUtils.concat(cmdLine, appCommandLine(runMode)); return executeAndCheck(cmdLine, runMode, aotConfigurationFile, aotConfigurationFileLog); } private OutputAnalyzer createAOTCacheOneStep() throws Exception { RunMode runMode = RunMode.TRAINING; - String[] cmdLine = StringArrayUtils.concat(vmArgs(runMode), - "-XX:AOTMode=record", - "-XX:AOTCacheOutput=" + aotCacheFile, - logToFile(aotCacheFileLog, - "class+load=debug", - "aot=debug", - "aot+class=debug", - "cds=debug")); - cmdLine = addCommonVMArgs(runMode, cmdLine); + String[] cmdLine = addCommonVMArgs(runMode); + cmdLine = StringArrayUtils.concat(cmdLine, vmArgs(runMode)); + cmdLine = StringArrayUtils.concat(cmdLine, + "-XX:AOTMode=record", + "-XX:AOTCacheOutput=" + aotCacheFile, + logToFile(aotCacheFileLog, + "class+load=debug", + "aot=debug", + "aot+class=debug", + "cds=debug")); cmdLine = StringArrayUtils.concat(cmdLine, appCommandLine(runMode)); OutputAnalyzer out = executeAndCheck(cmdLine, runMode, aotCacheFile, aotCacheFileLog); listOutputFile(aotCacheFileLog + ".0"); // the log file for the training run @@ -293,52 +304,55 @@ private OutputAnalyzer createAOTCacheOneStep() throws Exception { private OutputAnalyzer createClassList() throws Exception { RunMode runMode = RunMode.TRAINING; - String[] cmdLine = StringArrayUtils.concat(vmArgs(runMode), - "-Xshare:off", - "-XX:DumpLoadedClassList=" + classListFile, - logToFile(classListFileLog, - "class+load=debug")); - cmdLine = addCommonVMArgs(runMode, cmdLine); + String[] cmdLine = addCommonVMArgs(runMode); + cmdLine = StringArrayUtils.concat(cmdLine, vmArgs(runMode)); + cmdLine = StringArrayUtils.concat(cmdLine, + "-Xshare:off", + "-XX:DumpLoadedClassList=" + classListFile, + logToFile(classListFileLog, + "class+load=debug")); cmdLine = StringArrayUtils.concat(cmdLine, appCommandLine(runMode)); return executeAndCheck(cmdLine, runMode, classListFile, classListFileLog); } private OutputAnalyzer dumpStaticArchive() throws Exception { RunMode runMode = RunMode.DUMP_STATIC; - String[] cmdLine = StringArrayUtils.concat(vmArgs(runMode), - "-Xlog:aot", - "-Xlog:aot+heap=error", - "-Xlog:cds", - "-Xshare:dump", - "-XX:SharedArchiveFile=" + staticArchiveFile, - "-XX:SharedClassListFile=" + classListFile, - logToFile(staticArchiveFileLog, - "aot=debug", - "cds=debug", - "cds+class=debug", - "aot+heap=warning", - "aot+resolve=debug")); - cmdLine = addCommonVMArgs(runMode, cmdLine); + String[] cmdLine = addCommonVMArgs(runMode); + cmdLine = StringArrayUtils.concat(cmdLine, vmArgs(runMode)); + cmdLine = StringArrayUtils.concat(cmdLine, + "-Xlog:aot", + "-Xlog:aot+heap=error", + "-Xlog:cds", + "-Xshare:dump", + "-XX:SharedArchiveFile=" + staticArchiveFile, + "-XX:SharedClassListFile=" + classListFile, + logToFile(staticArchiveFileLog, + "aot=debug", + "cds=debug", + "cds+class=debug", + "aot+heap=warning", + "aot+resolve=debug")); cmdLine = StringArrayUtils.concat(cmdLine, appCommandLine(runMode)); return executeAndCheck(cmdLine, runMode, staticArchiveFile, staticArchiveFileLog); } private OutputAnalyzer createAOTCache() throws Exception { RunMode runMode = RunMode.ASSEMBLY; - String[] cmdLine = StringArrayUtils.concat(vmArgs(runMode), - "-Xlog:aot", - "-Xlog:aot+heap=error", - "-Xlog:cds", - "-XX:AOTMode=create", - "-XX:AOTConfiguration=" + aotConfigurationFile, - "-XX:AOTCache=" + aotCacheFile, - logToFile(aotCacheFileLog, - "cds=debug", - "aot=debug", - "aot+class=debug", - "aot+heap=warning", - "aot+resolve=debug")); - cmdLine = addCommonVMArgs(runMode, cmdLine); + String[] cmdLine = addCommonVMArgs(runMode); + cmdLine = StringArrayUtils.concat(cmdLine, vmArgs(runMode)); + cmdLine = StringArrayUtils.concat(cmdLine, + "-Xlog:aot", + "-Xlog:aot+heap=error", + "-Xlog:cds", + "-XX:AOTMode=create", + "-XX:AOTConfiguration=" + aotConfigurationFile, + "-XX:AOTCache=" + aotCacheFile, + logToFile(aotCacheFileLog, + "cds=debug", + "aot=debug", + "aot+class=debug", + "aot+heap=warning", + "aot+resolve=debug")); cmdLine = StringArrayUtils.concat(cmdLine, appCommandLine(runMode)); return executeAndCheck(cmdLine, runMode, aotCacheFile, aotCacheFileLog); } @@ -387,7 +401,9 @@ private OutputAnalyzer dumpDynamicArchive() throws Exception { String baseArchive = getBaseArchiveForDynamicArchive(); if (isDynamicWorkflow()) { // "classic" dynamic archive - cmdLine = StringArrayUtils.concat(vmArgs(runMode), + cmdLine = addCommonVMArgs(runMode); + cmdLine = StringArrayUtils.concat(cmdLine, vmArgs(runMode)); + cmdLine = StringArrayUtils.concat(cmdLine, "-Xlog:aot", "-Xlog:cds", "-XX:ArchiveClassesAtExit=" + dynamicArchiveFile, @@ -397,7 +413,6 @@ private OutputAnalyzer dumpDynamicArchive() throws Exception { "cds+class=debug", "aot+resolve=debug", "class+load=debug")); - cmdLine = addCommonVMArgs(runMode, cmdLine); } if (baseArchive != null) { cmdLine = StringArrayUtils.concat(cmdLine, "-XX:SharedArchiveFile=" + baseArchive); @@ -418,9 +433,10 @@ public OutputAnalyzer productionRun(String[] extraVmArgs) throws Exception { // using different args to the VM and application. public OutputAnalyzer productionRun(String[] extraVmArgs, String[] extraAppArgs) throws Exception { RunMode runMode = RunMode.PRODUCTION; - String[] cmdLine = StringArrayUtils.concat(vmArgs(runMode), - logToFile(productionRunLog(), "aot", "cds")); - cmdLine = addCommonVMArgs(runMode, cmdLine); + String[] cmdLine = addCommonVMArgs(runMode); + cmdLine = StringArrayUtils.concat(cmdLine, vmArgs(runMode)); + cmdLine = StringArrayUtils.concat(cmdLine, + logToFile(productionRunLog(), "aot", "cds")); if (isStaticWorkflow()) { cmdLine = StringArrayUtils.concat(cmdLine, "-Xshare:on", "-XX:SharedArchiveFile=" + staticArchiveFile); diff --git a/test/lib/jdk/test/lib/process/OutputAnalyzer.java b/test/lib/jdk/test/lib/process/OutputAnalyzer.java index 553e13b28ff4..0a9c31ed4034 100644 --- a/test/lib/jdk/test/lib/process/OutputAnalyzer.java +++ b/test/lib/jdk/test/lib/process/OutputAnalyzer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2026, 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 @@ -563,6 +563,32 @@ public String firstMatch(String pattern) { return firstMatch(pattern, 0); } + private List matchersForAllMatchingLinesInternal(Pattern needleRegex, List haystack) { + List matchingMatchers = haystack.stream(). + map(needleRegex::matcher).filter(Matcher::matches).collect(Collectors.toList()); + return matchingMatchers; + } + + /** + * Given a regular expression, matches the expression against every *line* of stderr output + * and returns a list of all matching matchers. + * @param needleRegex + * @return List of matchers + */ + public List matchersForAllMatchingLinesStderr(Pattern needleRegex) { + return matchersForAllMatchingLinesInternal(needleRegex, stderrAsLines()); + } + + /** + * Given a regular expression, matches the expression against every *line* of stdout output + * and returns a list of all matching matchers. + * @param needleRegex + * @return List of matchers + */ + public List matchersForAllMatchingLinesStdout(Pattern needleRegex) { + return matchersForAllMatchingLinesInternal(needleRegex, stdoutAsLines()); + } + /** * Verify the exit value of the process * diff --git a/test/micro/org/openjdk/bench/java/lang/MinMaxVector.java b/test/micro/org/openjdk/bench/java/lang/MinMaxVector.java index 3e4dc07c3944..3aa896042730 100644 --- a/test/micro/org/openjdk/bench/java/lang/MinMaxVector.java +++ b/test/micro/org/openjdk/bench/java/lang/MinMaxVector.java @@ -185,11 +185,11 @@ public void setup() { } final IntSummaryStatistics intStats = Arrays.stream(ints).summaryStatistics(); - highestInt = (intStats.getMax() * range) / 100; + highestInt = (int) (intStats.getMax() * (range / 100f)); lowestInt = intStats.getMin() + (intStats.getMax() - highestInt); final LongSummaryStatistics longStats = Arrays.stream(longs).summaryStatistics(); - highestLong = (longStats.getMax() * range) / 100; + highestLong = (long) (longStats.getMax() * (range / 100f)); lowestLong = longStats.getMin() + (longStats.getMax() - highestLong); } }