Merge branch 'master' into JDK-8387628-localhost

This commit is contained in:
Ashay Rane 2026-07-01 17:44:31 -05:00
commit 06ae46c445
No known key found for this signature in database
GPG Key ID: 52864602A7AB7825
113 changed files with 1032 additions and 856 deletions

View File

@ -43,8 +43,7 @@ instruct compareAndExchangeB(iRegINoSp res, indirect mem, iRegI oldval, iRegI ne
%}
ins_encode %{
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
Assembler::byte, /*acquire*/ false, /*release*/ true,
/*weak*/ false, $res$$Register);
Assembler::byte, memory_order_release, $res$$Register);
__ sxtbw($res$$Register, $res$$Register);
%}
ins_pipe(pipe_slow);
@ -59,8 +58,7 @@ instruct compareAndExchangeS(iRegINoSp res, indirect mem, iRegI oldval, iRegI ne
%}
ins_encode %{
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
Assembler::halfword, /*acquire*/ false, /*release*/ true,
/*weak*/ false, $res$$Register);
Assembler::halfword, memory_order_release, $res$$Register);
__ sxthw($res$$Register, $res$$Register);
%}
ins_pipe(pipe_slow);
@ -75,8 +73,7 @@ instruct compareAndExchangeI(iRegINoSp res, indirect mem, iRegI oldval, iRegI ne
%}
ins_encode %{
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
Assembler::word, /*acquire*/ false, /*release*/ true,
/*weak*/ false, $res$$Register);
Assembler::word, memory_order_release, $res$$Register);
%}
ins_pipe(pipe_slow);
%}
@ -90,8 +87,7 @@ instruct compareAndExchangeL(iRegLNoSp res, indirect mem, iRegL oldval, iRegL ne
%}
ins_encode %{
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
Assembler::xword, /*acquire*/ false, /*release*/ true,
/*weak*/ false, $res$$Register);
Assembler::xword, memory_order_release, $res$$Register);
%}
ins_pipe(pipe_slow);
%}
@ -106,8 +102,7 @@ instruct compareAndExchangeN(iRegNNoSp res, indirect mem, iRegN oldval, iRegN ne
%}
ins_encode %{
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
Assembler::word, /*acquire*/ false, /*release*/ true,
/*weak*/ false, $res$$Register);
Assembler::word, memory_order_release, $res$$Register);
%}
ins_pipe(pipe_slow);
%}
@ -122,8 +117,7 @@ instruct compareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP ne
%}
ins_encode %{
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
Assembler::xword, /*acquire*/ false, /*release*/ true,
/*weak*/ false, $res$$Register);
Assembler::xword, memory_order_release, $res$$Register);
%}
ins_pipe(pipe_slow);
%}
@ -138,8 +132,7 @@ instruct compareAndExchangeBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI
%}
ins_encode %{
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
Assembler::byte, /*acquire*/ true, /*release*/ true,
/*weak*/ false, $res$$Register);
Assembler::byte, memory_order_seq_cst, $res$$Register);
__ sxtbw($res$$Register, $res$$Register);
%}
ins_pipe(pipe_slow);
@ -155,8 +148,7 @@ instruct compareAndExchangeSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI
%}
ins_encode %{
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
Assembler::halfword, /*acquire*/ true, /*release*/ true,
/*weak*/ false, $res$$Register);
Assembler::halfword, memory_order_seq_cst, $res$$Register);
__ sxthw($res$$Register, $res$$Register);
%}
ins_pipe(pipe_slow);
@ -172,8 +164,7 @@ instruct compareAndExchangeIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI
%}
ins_encode %{
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
Assembler::word, /*acquire*/ true, /*release*/ true,
/*weak*/ false, $res$$Register);
Assembler::word, memory_order_seq_cst, $res$$Register);
%}
ins_pipe(pipe_slow);
%}
@ -188,8 +179,7 @@ instruct compareAndExchangeLAcq(iRegLNoSp res, indirect mem, iRegL oldval, iRegL
%}
ins_encode %{
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
Assembler::xword, /*acquire*/ true, /*release*/ true,
/*weak*/ false, $res$$Register);
Assembler::xword, memory_order_seq_cst, $res$$Register);
%}
ins_pipe(pipe_slow);
%}
@ -204,8 +194,7 @@ instruct compareAndExchangeNAcq(iRegNNoSp res, indirect mem, iRegN oldval, iRegN
%}
ins_encode %{
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
Assembler::word, /*acquire*/ true, /*release*/ true,
/*weak*/ false, $res$$Register);
Assembler::word, memory_order_seq_cst, $res$$Register);
%}
ins_pipe(pipe_slow);
%}
@ -220,8 +209,7 @@ instruct compareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP
%}
ins_encode %{
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
Assembler::xword, /*acquire*/ true, /*release*/ true,
/*weak*/ false, $res$$Register);
Assembler::xword, memory_order_seq_cst, $res$$Register);
%}
ins_pipe(pipe_slow);
%}
@ -235,9 +223,7 @@ instruct compareAndSwapB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
%}
ins_encode %{
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
Assembler::byte, /*acquire*/ false, /*release*/ true,
/*weak*/ false, noreg);
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::byte, memory_order_release);
__ csetw($res$$Register, Assembler::EQ);
%}
ins_pipe(pipe_slow);
@ -252,9 +238,7 @@ instruct compareAndSwapS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
%}
ins_encode %{
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
Assembler::halfword, /*acquire*/ false, /*release*/ true,
/*weak*/ false, noreg);
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::halfword, memory_order_release);
__ csetw($res$$Register, Assembler::EQ);
%}
ins_pipe(pipe_slow);
@ -269,9 +253,7 @@ instruct compareAndSwapI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
%}
ins_encode %{
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
Assembler::word, /*acquire*/ false, /*release*/ true,
/*weak*/ false, noreg);
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::word, memory_order_release);
__ csetw($res$$Register, Assembler::EQ);
%}
ins_pipe(pipe_slow);
@ -286,9 +268,7 @@ instruct compareAndSwapL(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
%}
ins_encode %{
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
Assembler::xword, /*acquire*/ false, /*release*/ true,
/*weak*/ false, noreg);
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword, memory_order_release);
__ csetw($res$$Register, Assembler::EQ);
%}
ins_pipe(pipe_slow);
@ -304,9 +284,7 @@ instruct compareAndSwapN(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
%}
ins_encode %{
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
Assembler::word, /*acquire*/ false, /*release*/ true,
/*weak*/ false, noreg);
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::word, memory_order_release);
__ csetw($res$$Register, Assembler::EQ);
%}
ins_pipe(pipe_slow);
@ -322,9 +300,7 @@ instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
%}
ins_encode %{
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
Assembler::xword, /*acquire*/ false, /*release*/ true,
/*weak*/ false, noreg);
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword, memory_order_release);
__ csetw($res$$Register, Assembler::EQ);
%}
ins_pipe(pipe_slow);
@ -340,9 +316,7 @@ instruct compareAndSwapBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI new
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
%}
ins_encode %{
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
Assembler::byte, /*acquire*/ true, /*release*/ true,
/*weak*/ false, noreg);
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::byte, memory_order_seq_cst);
__ csetw($res$$Register, Assembler::EQ);
%}
ins_pipe(pipe_slow);
@ -358,9 +332,7 @@ instruct compareAndSwapSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI new
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
%}
ins_encode %{
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
Assembler::halfword, /*acquire*/ true, /*release*/ true,
/*weak*/ false, noreg);
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::halfword, memory_order_seq_cst);
__ csetw($res$$Register, Assembler::EQ);
%}
ins_pipe(pipe_slow);
@ -376,9 +348,7 @@ instruct compareAndSwapIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI new
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
%}
ins_encode %{
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
Assembler::word, /*acquire*/ true, /*release*/ true,
/*weak*/ false, noreg);
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::word, memory_order_seq_cst);
__ csetw($res$$Register, Assembler::EQ);
%}
ins_pipe(pipe_slow);
@ -394,9 +364,7 @@ instruct compareAndSwapLAcq(iRegINoSp res, indirect mem, iRegL oldval, iRegL new
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
%}
ins_encode %{
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
Assembler::xword, /*acquire*/ true, /*release*/ true,
/*weak*/ false, noreg);
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword, memory_order_seq_cst);
__ csetw($res$$Register, Assembler::EQ);
%}
ins_pipe(pipe_slow);
@ -412,9 +380,7 @@ instruct compareAndSwapNAcq(iRegINoSp res, indirect mem, iRegN oldval, iRegN new
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
%}
ins_encode %{
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
Assembler::word, /*acquire*/ true, /*release*/ true,
/*weak*/ false, noreg);
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::word, memory_order_seq_cst);
__ csetw($res$$Register, Assembler::EQ);
%}
ins_pipe(pipe_slow);
@ -430,9 +396,7 @@ instruct compareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP new
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
%}
ins_encode %{
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
Assembler::xword, /*acquire*/ true, /*release*/ true,
/*weak*/ false, noreg);
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword, memory_order_seq_cst);
__ csetw($res$$Register, Assembler::EQ);
%}
ins_pipe(pipe_slow);
@ -447,9 +411,7 @@ instruct weakCompareAndSwapB(iRegINoSp res, indirect mem, iRegI oldval, iRegI ne
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
%}
ins_encode %{
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
Assembler::byte, /*acquire*/ false, /*release*/ true,
/*weak*/ true, noreg);
__ cmpxchg_weak($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::byte, memory_order_release);
__ csetw($res$$Register, Assembler::EQ);
%}
ins_pipe(pipe_slow);
@ -464,9 +426,7 @@ instruct weakCompareAndSwapS(iRegINoSp res, indirect mem, iRegI oldval, iRegI ne
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
%}
ins_encode %{
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
Assembler::halfword, /*acquire*/ false, /*release*/ true,
/*weak*/ true, noreg);
__ cmpxchg_weak($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::halfword, memory_order_release);
__ csetw($res$$Register, Assembler::EQ);
%}
ins_pipe(pipe_slow);
@ -481,9 +441,7 @@ instruct weakCompareAndSwapI(iRegINoSp res, indirect mem, iRegI oldval, iRegI ne
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
%}
ins_encode %{
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
Assembler::word, /*acquire*/ false, /*release*/ true,
/*weak*/ true, noreg);
__ cmpxchg_weak($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::word, memory_order_release);
__ csetw($res$$Register, Assembler::EQ);
%}
ins_pipe(pipe_slow);
@ -498,9 +456,7 @@ instruct weakCompareAndSwapL(iRegINoSp res, indirect mem, iRegL oldval, iRegL ne
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
%}
ins_encode %{
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
Assembler::xword, /*acquire*/ false, /*release*/ true,
/*weak*/ true, noreg);
__ cmpxchg_weak($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword, memory_order_release);
__ csetw($res$$Register, Assembler::EQ);
%}
ins_pipe(pipe_slow);
@ -516,9 +472,7 @@ instruct weakCompareAndSwapN(iRegINoSp res, indirect mem, iRegN oldval, iRegN ne
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
%}
ins_encode %{
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
Assembler::word, /*acquire*/ false, /*release*/ true,
/*weak*/ true, noreg);
__ cmpxchg_weak($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::word, memory_order_release);
__ csetw($res$$Register, Assembler::EQ);
%}
ins_pipe(pipe_slow);
@ -534,9 +488,7 @@ instruct weakCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP ne
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
%}
ins_encode %{
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
Assembler::xword, /*acquire*/ false, /*release*/ true,
/*weak*/ true, noreg);
__ cmpxchg_weak($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword, memory_order_release);
__ csetw($res$$Register, Assembler::EQ);
%}
ins_pipe(pipe_slow);
@ -552,9 +504,7 @@ instruct weakCompareAndSwapBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
%}
ins_encode %{
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
Assembler::byte, /*acquire*/ true, /*release*/ true,
/*weak*/ true, noreg);
__ cmpxchg_weak($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::byte, memory_order_seq_cst);
__ csetw($res$$Register, Assembler::EQ);
%}
ins_pipe(pipe_slow);
@ -570,9 +520,7 @@ instruct weakCompareAndSwapSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
%}
ins_encode %{
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
Assembler::halfword, /*acquire*/ true, /*release*/ true,
/*weak*/ true, noreg);
__ cmpxchg_weak($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::halfword, memory_order_seq_cst);
__ csetw($res$$Register, Assembler::EQ);
%}
ins_pipe(pipe_slow);
@ -588,9 +536,7 @@ instruct weakCompareAndSwapIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
%}
ins_encode %{
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
Assembler::word, /*acquire*/ true, /*release*/ true,
/*weak*/ true, noreg);
__ cmpxchg_weak($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::word, memory_order_seq_cst);
__ csetw($res$$Register, Assembler::EQ);
%}
ins_pipe(pipe_slow);
@ -606,9 +552,7 @@ instruct weakCompareAndSwapLAcq(iRegINoSp res, indirect mem, iRegL oldval, iRegL
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
%}
ins_encode %{
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
Assembler::xword, /*acquire*/ true, /*release*/ true,
/*weak*/ true, noreg);
__ cmpxchg_weak($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword, memory_order_seq_cst);
__ csetw($res$$Register, Assembler::EQ);
%}
ins_pipe(pipe_slow);
@ -624,9 +568,7 @@ instruct weakCompareAndSwapNAcq(iRegINoSp res, indirect mem, iRegN oldval, iRegN
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
%}
ins_encode %{
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
Assembler::word, /*acquire*/ true, /*release*/ true,
/*weak*/ true, noreg);
__ cmpxchg_weak($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::word, memory_order_seq_cst);
__ csetw($res$$Register, Assembler::EQ);
%}
ins_pipe(pipe_slow);
@ -642,9 +584,7 @@ instruct weakCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
%}
ins_encode %{
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
Assembler::xword, /*acquire*/ true, /*release*/ true,
/*weak*/ true, noreg);
__ cmpxchg_weak($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword, memory_order_seq_cst);
__ csetw($res$$Register, Assembler::EQ);
%}
ins_pipe(pipe_slow);

View File

@ -53,8 +53,7 @@ ifelse($7,Acq,INDENT(predicate(needs_acquiring_load_exclusive(n));),`dnl')
%}
ins_encode %{
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
Assembler::$4, /*acquire*/ ifelse($7,Acq,true,false), /*release*/ true,
/*weak*/ false, $res$$Register);
Assembler::$4, ifelse($7,Acq,memory_order_seq_cst,memory_order_release), $res$$Register);
__ $6($res$$Register, $res$$Register);
%}
ins_pipe(pipe_slow);
@ -76,8 +75,7 @@ ifelse($1$6,PAcq,INDENT(predicate(needs_acquiring_load_exclusive(n) && (n->as_Lo
%}
ins_encode %{
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
Assembler::$4, /*acquire*/ ifelse($6,Acq,true,false), /*release*/ true,
/*weak*/ false, $res$$Register);
Assembler::$4, ifelse($6,Acq,memory_order_seq_cst,memory_order_release), $res$$Register);
%}
ins_pipe(pipe_slow);
%}')dnl
@ -112,9 +110,7 @@ ifelse($6,Acq,INDENT(predicate(needs_acquiring_load_exclusive(n));),`dnl')
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
%}
ins_encode %{
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
Assembler::$4, /*acquire*/ ifelse($6,Acq,true,false), /*release*/ true,
/*weak*/ ifelse($7,Weak,true,false), noreg);
__ ifelse($7,Weak,cmpxchg_weak,cmpxchg)($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::$4, ifelse($6,Acq,memory_order_seq_cst,memory_order_release));
__ csetw($res$$Register, Assembler::EQ);
%}
ins_pipe(pipe_slow);
@ -137,9 +133,7 @@ ifelse($1$6,PAcq,INDENT(predicate(needs_acquiring_load_exclusive(n) && (n->as_Lo
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
%}
ins_encode %{
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
Assembler::$4, /*acquire*/ ifelse($6,Acq,true,false), /*release*/ true,
/*weak*/ ifelse($7,Weak,true,false), noreg);
__ ifelse($7,Weak,cmpxchg_weak,cmpxchg)($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::$4, ifelse($6,Acq,memory_order_seq_cst,memory_order_release));
__ csetw($res$$Register, Assembler::EQ);
%}
ins_pipe(pipe_slow);

View File

@ -1492,12 +1492,12 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) {
}
void LIR_Assembler::casw(Register addr, Register newval, Register cmpval) {
__ cmpxchg(addr, cmpval, newval, Assembler::word, /* acquire*/ true, /* release*/ true, /* weak*/ false, rscratch1);
__ cmpxchg(addr, cmpval, newval, Assembler::word, memory_order_seq_cst, rscratch1);
__ cset(rscratch1, Assembler::NE);
}
void LIR_Assembler::casl(Register addr, Register newval, Register cmpval) {
__ cmpxchg(addr, cmpval, newval, Assembler::xword, /* acquire*/ true, /* release*/ true, /* weak*/ false, rscratch1);
__ cmpxchg(addr, cmpval, newval, Assembler::xword, memory_order_seq_cst, rscratch1);
__ cset(rscratch1, Assembler::NE);
}

View File

@ -204,8 +204,7 @@ void C2_MacroAssembler::fast_lock(Register obj, Register box, Register t1,
// Try to lock. Transition lock-bits 0b01 => 0b00
orr(t1_mark, t1_mark, markWord::unlocked_value);
eor(t3_t, t1_mark, markWord::unlocked_value);
cmpxchg(/*addr*/ obj, /*expected*/ t1_mark, /*new*/ t3_t, Assembler::xword,
/*acquire*/ true, /*release*/ false, /*weak*/ false, noreg);
cmpxchg(/*addr*/ obj, /*expected*/ t1_mark, /*new*/ t3_t, Assembler::xword, memory_order_acquire);
br(Assembler::NE, slow_path);
bind(push);
@ -285,8 +284,7 @@ void C2_MacroAssembler::fast_lock(Register obj, Register box, Register t1,
// Try to CAS owner (no owner => current thread's _monitor_owner_id).
ldr(rscratch2, Address(rthread, JavaThread::monitor_owner_id_offset()));
cmpxchg(t2_owner_addr, zr, rscratch2, Assembler::xword, /*acquire*/ true,
/*release*/ false, /*weak*/ false, t3_owner);
cmpxchg(t2_owner_addr, zr, rscratch2, Assembler::xword, memory_order_acquire, t3_owner);
br(Assembler::EQ, monitor_locked);
// Check if recursive.
@ -371,8 +369,7 @@ void C2_MacroAssembler::fast_unlock(Register obj, Register box, Register t1,
// Try to unlock. Transition lock bits 0b00 => 0b01
assert(oopDesc::mark_offset_in_bytes() == 0, "required to avoid lea");
orr(t3_t, t1_mark, markWord::unlocked_value);
cmpxchg(/*addr*/ obj, /*expected*/ t1_mark, /*new*/ t3_t, Assembler::xword,
/*acquire*/ false, /*release*/ true, /*weak*/ false, noreg);
cmpxchg(/*addr*/ obj, /*expected*/ t1_mark, /*new*/ t3_t, Assembler::xword, memory_order_release);
br(Assembler::EQ, unlocked);
bind(push_and_slow_path);

View File

@ -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.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -66,7 +66,6 @@
public:
enum {
pc_return_offset = 0,
// All frames
link_offset = 0,
return_addr_offset = 1,

View File

@ -283,7 +283,7 @@ instruct g1CompareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP
RegSet::of($mem$$Register, $oldval$$Register, $newval$$Register) /* preserve */,
RegSet::of($res$$Register) /* no_preserve */);
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword,
false /* acquire */, true /* release */, false /* weak */, $res$$Register);
memory_order_release, $res$$Register);
write_barrier_post(masm, this,
$mem$$Register /* store_addr */,
$newval$$Register /* new_val */,
@ -316,7 +316,7 @@ instruct g1CompareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRe
RegSet::of($mem$$Register, $oldval$$Register, $newval$$Register) /* preserve */,
RegSet::of($res$$Register) /* no_preserve */);
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword,
true /* acquire */, true /* release */, false /* weak */, $res$$Register);
memory_order_seq_cst, $res$$Register);
write_barrier_post(masm, this,
$mem$$Register /* store_addr */,
$newval$$Register /* new_val */,
@ -346,7 +346,7 @@ instruct g1CompareAndExchangeN(iRegNNoSp res, indirect mem, iRegN oldval, iRegN
RegSet::of($mem$$Register, $oldval$$Register, $newval$$Register) /* preserve */,
RegSet::of($res$$Register) /* no_preserve */);
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::word,
false /* acquire */, true /* release */, false /* weak */, $res$$Register);
memory_order_release, $res$$Register);
__ decode_heap_oop($tmp1$$Register, $newval$$Register);
write_barrier_post(masm, this,
$mem$$Register /* store_addr */,
@ -377,7 +377,7 @@ instruct g1CompareAndExchangeNAcq(iRegNNoSp res, indirect mem, iRegN oldval, iRe
RegSet::of($mem$$Register, $oldval$$Register, $newval$$Register) /* preserve */,
RegSet::of($res$$Register) /* no_preserve */);
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::word,
true /* acquire */, true /* release */, false /* weak */, $res$$Register);
memory_order_seq_cst, $res$$Register);
__ decode_heap_oop($tmp1$$Register, $newval$$Register);
write_barrier_post(masm, this,
$mem$$Register /* store_addr */,
@ -409,8 +409,7 @@ instruct g1CompareAndSwapP(iRegINoSp res, indirect mem, iRegP newval, iRegPNoSp
$tmp2$$Register /* tmp2 */,
RegSet::of($mem$$Register, $oldval$$Register, $newval$$Register) /* preserve */,
RegSet::of($res$$Register) /* no_preserve */);
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword,
false /* acquire */, true /* release */, false /* weak */, noreg);
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword, memory_order_release);
__ cset($res$$Register, Assembler::EQ);
write_barrier_post(masm, this,
$mem$$Register /* store_addr */,
@ -442,8 +441,7 @@ instruct g1CompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP newval, iRegPNo
$tmp2$$Register /* tmp2 */,
RegSet::of($mem$$Register, $oldval$$Register, $newval$$Register) /* preserve */,
RegSet::of($res$$Register) /* no_preserve */);
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword,
true /* acquire */, true /* release */, false /* weak */, noreg);
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword, memory_order_seq_cst);
__ cset($res$$Register, Assembler::EQ);
write_barrier_post(masm, this,
$mem$$Register /* store_addr */,
@ -475,8 +473,7 @@ instruct g1CompareAndSwapN(iRegINoSp res, indirect mem, iRegN newval, iRegPNoSp
$tmp3$$Register /* tmp2 */,
RegSet::of($mem$$Register, $oldval$$Register, $newval$$Register) /* preserve */,
RegSet::of($res$$Register) /* no_preserve */);
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::word,
false /* acquire */, true /* release */, false /* weak */, noreg);
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::word, memory_order_release);
__ cset($res$$Register, Assembler::EQ);
__ decode_heap_oop($tmp1$$Register, $newval$$Register);
write_barrier_post(masm, this,
@ -509,8 +506,7 @@ instruct g1CompareAndSwapNAcq(iRegINoSp res, indirect mem, iRegN newval, iRegPNo
$tmp3$$Register /* tmp2 */,
RegSet::of($mem$$Register, $oldval$$Register, $newval$$Register) /* preserve */,
RegSet::of($res$$Register) /* no_preserve */);
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::word,
true /* acquire */, true /* release */, false /* weak */, noreg);
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::word, memory_order_seq_cst);
__ cset($res$$Register, Assembler::EQ);
__ decode_heap_oop($tmp1$$Register, $newval$$Register);
write_barrier_post(masm, this,

View File

@ -151,7 +151,7 @@ instruct g1CompareAndExchangeP$1(iRegPNoSp res, indirect mem, iRegP oldval, iReg
RegSet::of($mem$$Register, $oldval$$Register, $newval$$Register) /* preserve */,
RegSet::of($res$$Register) /* no_preserve */);
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword,
$3 /* acquire */, true /* release */, false /* weak */, $res$$Register);
ifelse($1,Acq,memory_order_seq_cst,memory_order_release), $res$$Register);
write_barrier_post(masm, this,
$mem$$Register /* store_addr */,
$newval$$Register /* new_val */,
@ -160,8 +160,8 @@ instruct g1CompareAndExchangeP$1(iRegPNoSp res, indirect mem, iRegP oldval, iReg
%}
ins_pipe(pipe_slow);
%}')dnl
CAEP_INSN(,,false)
CAEP_INSN(Acq,_acq,true)
CAEP_INSN(,)
CAEP_INSN(Acq,_acq)
dnl
define(`CAEN_INSN',
`
@ -185,7 +185,7 @@ instruct g1CompareAndExchangeN$1(iRegNNoSp res, indirect mem, iRegN oldval, iReg
RegSet::of($mem$$Register, $oldval$$Register, $newval$$Register) /* preserve */,
RegSet::of($res$$Register) /* no_preserve */);
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::word,
$3 /* acquire */, true /* release */, false /* weak */, $res$$Register);
ifelse($1,Acq,memory_order_seq_cst,memory_order_release), $res$$Register);
__ decode_heap_oop($tmp1$$Register, $newval$$Register);
write_barrier_post(masm, this,
$mem$$Register /* store_addr */,
@ -195,8 +195,8 @@ instruct g1CompareAndExchangeN$1(iRegNNoSp res, indirect mem, iRegN oldval, iReg
%}
ins_pipe(pipe_slow);
%}')dnl
CAEN_INSN(,,false)
CAEN_INSN(Acq,_acq,true)
CAEN_INSN(,)
CAEN_INSN(Acq,_acq)
dnl
define(`CASP_INSN',
`
@ -221,8 +221,7 @@ instruct g1CompareAndSwapP$1(iRegINoSp res, indirect mem, iRegP newval, iRegPNoS
$tmp2$$Register /* tmp2 */,
RegSet::of($mem$$Register, $oldval$$Register, $newval$$Register) /* preserve */,
RegSet::of($res$$Register) /* no_preserve */);
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword,
$3 /* acquire */, true /* release */, false /* weak */, noreg);
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword, ifelse($1,Acq,memory_order_seq_cst,memory_order_release));
__ cset($res$$Register, Assembler::EQ);
write_barrier_post(masm, this,
$mem$$Register /* store_addr */,
@ -232,8 +231,8 @@ instruct g1CompareAndSwapP$1(iRegINoSp res, indirect mem, iRegP newval, iRegPNoS
%}
ins_pipe(pipe_slow);
%}')dnl
CASP_INSN(,,false)
CASP_INSN(Acq,_acq,true)
CASP_INSN(,)
CASP_INSN(Acq,_acq)
dnl
define(`CASN_INSN',
`
@ -258,8 +257,7 @@ instruct g1CompareAndSwapN$1(iRegINoSp res, indirect mem, iRegN newval, iRegPNoS
$tmp3$$Register /* tmp2 */,
RegSet::of($mem$$Register, $oldval$$Register, $newval$$Register) /* preserve */,
RegSet::of($res$$Register) /* no_preserve */);
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::word,
$3 /* acquire */, true /* release */, false /* weak */, noreg);
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::word, ifelse($1,Acq,memory_order_seq_cst,memory_order_release));
__ cset($res$$Register, Assembler::EQ);
__ decode_heap_oop($tmp1$$Register, $newval$$Register);
write_barrier_post(masm, this,
@ -270,8 +268,8 @@ instruct g1CompareAndSwapN$1(iRegINoSp res, indirect mem, iRegN newval, iRegPNoS
%}
ins_pipe(pipe_slow);
%}')dnl
CASN_INSN(,,false)
CASN_INSN(Acq,_acq,true)
CASN_INSN(,)
CASN_INSN(Acq,_acq)
dnl
define(`XCHGP_INSN',
`

View File

@ -597,8 +597,14 @@ void ShenandoahBarrierSetAssembler::compare_and_set_c2(const MachNode* node, Mac
ShenandoahBarrierStubC2::load_store_pre(masm, node, addr, tmp1, tmp2, tmp3, narrow);
atomic_memory_order order = acquire ? memory_order_seq_cst : memory_order_release;
// CAS!
__ cmpxchg(addr, oldval, newval, op_size, acquire, /* release */ true, weak, exchange ? res : noreg);
if (weak) {
__ cmpxchg_weak(addr, oldval, newval, op_size, order, exchange ? res : noreg);
} else {
__ cmpxchg(addr, oldval, newval, op_size, order, exchange ? res : noreg);
}
// If we need a boolean result out of CAS, set the flag appropriately and promote the result.
if (!exchange) {

View File

@ -283,10 +283,7 @@ void ZBarrierSetAssembler::store_barrier_medium(MacroAssembler* masm,
// If we get this far, we know there is a young raw null value in the field.
__ relocate(barrier_Relocation::spec(), ZBarrierRelocationFormatStoreGoodBeforeMov);
__ movzw(rtmp1, barrier_Relocation::unpatched);
__ cmpxchg(rtmp2, zr, rtmp1,
Assembler::xword,
false /* acquire */, false /* release */, true /* weak */,
rtmp3);
__ cmpxchg_weak(rtmp2, zr, rtmp1, Assembler::xword, memory_order_relaxed, rtmp3);
__ br(Assembler::NE, slow_path);
__ bind(slow_path_continuation);

View File

@ -207,8 +207,7 @@ instruct zCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newva
Address ref_addr($mem$$Register);
z_store_barrier(masm, this, ref_addr, $newval$$Register, $newval_tmp$$Register, rscratch2, true /* is_atomic */);
z_color(masm, this, $oldval_tmp$$Register, $oldval$$Register);
__ cmpxchg($mem$$Register, $oldval_tmp$$Register, $newval_tmp$$Register, Assembler::xword,
false /* acquire */, true /* release */, false /* weak */, noreg);
__ cmpxchg($mem$$Register, $oldval_tmp$$Register, $newval_tmp$$Register, Assembler::xword, memory_order_release);
__ cset($res$$Register, Assembler::EQ);
%}
@ -231,8 +230,7 @@ instruct zCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP ne
Address ref_addr($mem$$Register);
z_store_barrier(masm, this, ref_addr, $newval$$Register, $newval_tmp$$Register, rscratch2, true /* is_atomic */);
z_color(masm, this, $oldval_tmp$$Register, $oldval$$Register);
__ cmpxchg($mem$$Register, $oldval_tmp$$Register, $newval_tmp$$Register, Assembler::xword,
true /* acquire */, true /* release */, false /* weak */, noreg);
__ cmpxchg($mem$$Register, $oldval_tmp$$Register, $newval_tmp$$Register, Assembler::xword, memory_order_seq_cst);
__ cset($res$$Register, Assembler::EQ);
%}
@ -255,7 +253,7 @@ instruct zCompareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP n
z_store_barrier(masm, this, ref_addr, $newval$$Register, $newval_tmp$$Register, rscratch2, true /* is_atomic */);
z_color(masm, this, $oldval_tmp$$Register, $oldval$$Register);
__ cmpxchg($mem$$Register, $oldval_tmp$$Register, $newval_tmp$$Register, Assembler::xword,
false /* acquire */, true /* release */, false /* weak */, $res$$Register);
memory_order_release, $res$$Register);
z_uncolor(masm, this, $res$$Register);
%}
@ -278,7 +276,7 @@ instruct zCompareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iReg
z_store_barrier(masm, this, ref_addr, $newval$$Register, $newval_tmp$$Register, rscratch2, true /* is_atomic */);
z_color(masm, this, $oldval_tmp$$Register, $oldval$$Register);
__ cmpxchg($mem$$Register, $oldval_tmp$$Register, $newval_tmp$$Register, Assembler::xword,
true /* acquire */, true /* release */, false /* weak */, $res$$Register);
memory_order_seq_cst, $res$$Register);
z_uncolor(masm, this, $res$$Register);
%}

View File

@ -2231,8 +2231,7 @@ void MacroAssembler::profile_receiver_type(Register recv, Register mdp, int mdp_
// offset is no longer needed after the address is computed.
lea(rscratch2, Address(mdp, offset));
cmpxchg(/*addr*/ rscratch2, /*expected*/ zr, /*new*/ recv, Assembler::xword,
/*acquire*/ false, /*release*/ false, /*weak*/ true, noreg);
cmpxchg_weak(/*addr*/ rscratch2, /*expected*/ zr, /*new*/ recv, Assembler::xword, memory_order_relaxed);
// CAS success means the slot now has the receiver we want. CAS failure means
// something had claimed the slot concurrently: it can be the same receiver we want,
@ -3494,9 +3493,33 @@ void MacroAssembler::reinit_heapbase()
void MacroAssembler::cmpxchg(Register addr, Register expected,
Register new_val,
enum operand_size size,
bool acquire, bool release,
enum atomic_memory_order order,
bool weak,
Register result) {
bool acquire, release;
switch (order) {
case memory_order_relaxed:
acquire = false;
release = false;
break;
case memory_order_acquire:
acquire = true;
release = false;
break;
case memory_order_release:
acquire = false;
release = true;
break;
case memory_order_acq_rel:
case memory_order_seq_cst:
acquire = true;
release = true;
break;
default:
ShouldNotReachHere();
}
if (result == noreg) result = rscratch1;
BLOCK_COMMENT("cmpxchg {");
if (UseLSE) {
@ -7180,8 +7203,7 @@ void MacroAssembler::fast_lock(Register basic_lock, Register obj, Register t1, R
assert(oopDesc::mark_offset_in_bytes() == 0, "required to avoid lea");
orr(mark, mark, markWord::unlocked_value);
eor(t, mark, markWord::unlocked_value);
cmpxchg(/*addr*/ obj, /*expected*/ mark, /*new*/ t, Assembler::xword,
/*acquire*/ true, /*release*/ false, /*weak*/ false, noreg);
cmpxchg(/*addr*/ obj, /*expected*/ mark, /*new*/ t, Assembler::xword, memory_order_acquire);
br(Assembler::NE, slow);
bind(push);
@ -7249,8 +7271,7 @@ void MacroAssembler::fast_unlock(Register obj, Register t1, Register t2, Registe
// Try to unlock. Transition lock bits 0b00 => 0b01
assert(oopDesc::mark_offset_in_bytes() == 0, "required to avoid lea");
orr(t, mark, markWord::unlocked_value);
cmpxchg(obj, mark, t, Assembler::xword,
/*acquire*/ false, /*release*/ true, /*weak*/ false, noreg);
cmpxchg(obj, mark, t, Assembler::xword, memory_order_release);
br(Assembler::EQ, unlocked);
bind(push_and_slow);

View File

@ -32,6 +32,7 @@
#include "metaprogramming/enableIf.hpp"
#include "oops/compressedOops.hpp"
#include "oops/compressedKlass.hpp"
#include "runtime/atomicAccess.hpp"
#include "runtime/vm_version.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/powerOfTwo.hpp"
@ -1239,12 +1240,25 @@ public:
str(rscratch1, adr);
}
private:
// A generic CAS; success or failure is in the EQ flag.
// Clobbers rscratch1
void cmpxchg(Register addr, Register expected, Register new_val,
enum operand_size size,
bool acquire, bool release, bool weak,
Register result);
enum operand_size size, enum atomic_memory_order order,
bool weak, Register result);
public:
void cmpxchg(Register addr, Register expected, Register new_val,
enum operand_size size, enum atomic_memory_order order,
Register result = noreg) {
cmpxchg(addr, expected, new_val, size, order, /* weak */ false, result);
}
void cmpxchg_weak(Register addr, Register expected, Register new_val,
enum operand_size size, enum atomic_memory_order order,
Register result = noreg) {
cmpxchg(addr, expected, new_val, size, order, /* weak */ true, result);
}
#ifdef ASSERT
// Template short-hand support to clean-up after a failed call to trampoline

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2025, 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
@ -27,7 +27,6 @@
public:
enum {
pc_return_offset = 0,
// All frames
link_offset = 0,
return_addr_offset = 1,

View File

@ -75,23 +75,46 @@ int Assembler::branch_destination(int inst, int pos) {
return r;
}
// Low-level andi-one-instruction-macro.
void Assembler::andi(Register a, Register s, const long ui16) {
if (is_power_of_2(((unsigned long) ui16)+1)) {
// Low-level andi-one-instruction-macro. May clobber CR0.
void Assembler::andi(Register a, Register s, julong int_or_long_const) {
// Instructions which don't set CR0 are preferred.
if (int_or_long_const == 0) {
// should not be handled as pow2minus1
li(a, 0);
} else if (is_power_of_2(int_or_long_const + 1)) {
// pow2minus1
clrldi(a, s, 64 - log2i_exact((((unsigned long) ui16)+1)));
} else if (is_power_of_2((jlong) ui16)) {
// pow2
rlwinm(a, s, 0, 31 - log2i_exact((jlong) ui16), 31 - log2i_exact((jlong) ui16));
} else if (is_power_of_2((jlong)-ui16)) {
// negpow2
clrrdi(a, s, log2i_exact((jlong)-ui16));
clrldi(a, s, 64 - log2i_exact(int_or_long_const + 1));
} else if (is_power_of_2(-int_or_long_const)) {
// negpow2 (includes (julong)min_jlong)
clrrdi(a, s, log2i_exact(-int_or_long_const));
} else if (is_uimm((jlong)int_or_long_const, 32) && has_consecutive_ones(int_or_long_const)) {
// consecutive ones
rlwinm(a, s, 0, count_leading_zeros((uint32_t)int_or_long_const),
31 - count_trailing_zeros((uint32_t)int_or_long_const));
} else if (is_uimm((jlong)int_or_long_const, 16)) {
// side effect: clobbers CR0
andi_(a, s, int_or_long_const);
} else {
assert(is_uimm(ui16, 16), "must be 16-bit unsigned immediate");
andi_(a, s, ui16);
assert(is_uimm((jlong)int_or_long_const, 32) && (int_or_long_const & 0xFFFF) == 0,
"not encodable: " UINT64_FORMAT_X, int_or_long_const);
// side effect: clobbers CR0
andis_(a, s, int_or_long_const >> 16);
}
}
// Check if int_or_long_const is supported by Assembler::andi.
bool Assembler::andi_supports(julong int_or_long_const) {
// 16 bit always possible by andi_ (but other instructions are preferred)
if (is_uimm((jlong)int_or_long_const, 16)) return true;
// special cases 32 bit: higher 16 bit and consecutive ones are supported
if (is_uimm((jlong)int_or_long_const, 32) &&
((int_or_long_const & 0xFFFF) == 0 || has_consecutive_ones(int_or_long_const))) return true;
// special cases 64 bit: clrldi, clrrdi
return is_power_of_2(int_or_long_const + 1) || is_power_of_2(-int_or_long_const);
}
// RegisterOrConstant version.
void Assembler::ld(Register d, RegisterOrConstant roc, Register s1) {
if (roc.is_constant()) {

View File

@ -1048,6 +1048,13 @@ class Assembler : public AbstractAssembler {
return (julong)x < maxplus1;
}
// Test if x has exactly one consecutive range of one bits (e.g. 00111000)
static bool has_consecutive_ones(julong x) {
if (x == max_julong) return true;
if (x == 0) return false;
return is_power_of_2((x >> count_trailing_zeros(x)) + 1);
}
protected:
// helpers
@ -1606,7 +1613,8 @@ class Assembler : public AbstractAssembler {
inline void isel_0( Register d, ConditionRegister cr, Condition cc, Register b = noreg);
// PPC 1, section 3.3.11, Fixed-Point Logical Instructions
void andi( Register a, Register s, long ui16); // optimized version
void andi( Register a, Register s, julong int_or_long_const); // optimized version, may clobber CR0
static bool andi_supports(julong int_or_long_const);
inline void andi_( Register a, Register s, int ui16);
inline void andis_( Register a, Register s, int ui16);
inline void ori( Register a, Register s, int ui16);

View File

@ -1669,26 +1669,40 @@ void LIR_Assembler::logic_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr
d = dest->as_register_lo();
l = left->as_register_lo();
}
long uimms = (unsigned long)uimm >> 16,
uimmss = (unsigned long)uimm >> 32;
long uimms = (unsigned long)uimm >> 16;
switch (code) {
case lir_logic_and:
if (uimmss != 0 || (uimms != 0 && (uimm & 0xFFFF) != 0) || is_power_of_2(uimm)) {
__ andi(d, l, uimm); // special cases
} else if (uimms != 0) { __ andis_(d, l, uimms); }
else { __ andi_(d, l, uimm); }
if (Assembler::andi_supports(uimm)) {
__ andi(d, l, uimm); // includes andis_ and special cases
} else { // for operands which are not generated by LIRGenerator::do_LogicOp
__ load_const_optimized(R0, uimm);
__ andr(d, l, R0);
}
break;
case lir_logic_or:
if (uimms != 0) { assert((uimm & 0xFFFF) == 0, "sanity"); __ oris(d, l, uimms); }
else { __ ori(d, l, uimm); }
if (Assembler::is_uimm(uimm, 16)) {
__ ori(d, l, uimm);
} else if ((uimm & 0xFFFF) == 0 && Assembler::is_uimm(uimms, 16)) {
__ oris(d, l, uimms);
} else { // for operands which are not generated by LIRGenerator::do_LogicOp
__ load_const_optimized(R0, uimm);
__ orr(d, l, R0);
}
break;
case lir_logic_xor:
if (uimm == -1) { __ nand(d, l, l); } // special case
else if (uimms != 0) { assert((uimm & 0xFFFF) == 0, "sanity"); __ xoris(d, l, uimms); }
else { __ xori(d, l, uimm); }
if (Assembler::is_uimm(uimm, 16)) {
__ xori(d, l, uimm);
} else if ((uimm & 0xFFFF) == 0 && Assembler::is_uimm(uimms, 16)) {
__ xoris(d, l, uimms);
} else if (uimm == -1) {
__ nand(d, l, l); // special case
} else { // for operands which are not generated by LIRGenerator::do_LogicOp
__ load_const_optimized(R0, uimm);
__ xorr(d, l, R0);
}
break;
default: ShouldNotReachHere();

View File

@ -578,18 +578,13 @@ inline bool can_handle_logic_op_as_uimm(ValueType *type, Bytecodes::Code bc) {
Assembler::is_uimm((jlong)((julong)int_or_long_const >> 16), 16)) return true;
// see Assembler::andi
if (bc == Bytecodes::_iand &&
(is_power_of_2(int_or_long_const+1) ||
is_power_of_2(int_or_long_const) ||
is_power_of_2(-int_or_long_const))) return true;
if (bc == Bytecodes::_land &&
(is_power_of_2((unsigned long)int_or_long_const+1) ||
(Assembler::is_uimm(int_or_long_const, 32) && is_power_of_2(int_or_long_const)) ||
(int_or_long_const != min_jlong && is_power_of_2(-int_or_long_const)))) return true;
if ((bc == Bytecodes::_iand || bc == Bytecodes::_land))
return Assembler::andi_supports(int_or_long_const);
// special case: xor -1
if ((bc == Bytecodes::_ixor || bc == Bytecodes::_lxor) &&
int_or_long_const == -1) return true;
if ((bc == Bytecodes::_ixor || bc == Bytecodes::_lxor))
return (int_or_long_const == -1);
return false;
}

View File

@ -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.
* Copyright (c) 2012, 2025 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -391,8 +391,6 @@
}
enum {
// normal return address is 1 bundle past PC
pc_return_offset = 0,
// size, in words, of frame metadata (e.g. pc and link)
metadata_words = sizeof(java_abi) >> LogBytesPerWord,
// size, in words, of metadata at frame bottom, i.e. it is not part of the

View File

@ -9155,61 +9155,14 @@ instruct andI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
ins_pipe(pipe_class_default);
%}
// Left shifted Immediate And
instruct andI_reg_immIhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2, flagsRegCR0 cr0) %{
instruct andI_reg_immI(iRegIdst dst, iRegIsrc src1, immI src2, flagsRegCR0 cr0) %{
match(Set dst (AndI src1 src2));
predicate(Assembler::andi_supports((juint)(n->in(2)->get_int())));
effect(KILL cr0);
format %{ "ANDIS $dst, $src1, $src2.hi" %}
size(4);
ins_encode %{
__ andis_($dst$$Register, $src1$$Register, (int)((unsigned short)(($src2$$constant & 0xFFFF0000) >> 16)));
%}
ins_pipe(pipe_class_default);
%}
// Immediate And
instruct andI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2, flagsRegCR0 cr0) %{
match(Set dst (AndI src1 src2));
effect(KILL cr0);
format %{ "ANDI $dst, $src1, $src2" %}
size(4);
ins_encode %{
// FIXME: avoid andi_ ?
__ andi_($dst$$Register, $src1$$Register, $src2$$constant);
%}
ins_pipe(pipe_class_default);
%}
// Immediate And where the immediate is a negative power of 2.
instruct andI_reg_immInegpow2(iRegIdst dst, iRegIsrc src1, immInegpow2 src2) %{
match(Set dst (AndI src1 src2));
format %{ "ANDWI $dst, $src1, $src2" %}
size(4);
ins_encode %{
__ clrrdi($dst$$Register, $src1$$Register, log2i_exact(-(juint)$src2$$constant));
%}
ins_pipe(pipe_class_default);
%}
instruct andI_reg_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immIpow2minus1 src2) %{
match(Set dst (AndI src1 src2));
format %{ "ANDWI $dst, $src1, $src2" %}
size(4);
ins_encode %{
__ clrldi($dst$$Register, $src1$$Register, 64 - log2i_exact((juint)$src2$$constant + 1u));
%}
ins_pipe(pipe_class_default);
%}
instruct andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src1, immIpowerOf2 src2) %{
match(Set dst (AndI src1 src2));
predicate(UseRotateAndMaskInstructionsPPC64);
format %{ "ANDWI $dst, $src1, $src2" %}
size(4);
ins_encode %{
int bitpos = 31 - log2i_exact((juint)$src2$$constant);
__ rlwinm($dst$$Register, $src1$$Register, 0, bitpos, bitpos);
__ andi($dst$$Register, $src1$$Register, (juint)$src2$$constant); // optimized version
%}
ins_pipe(pipe_class_default);
%}
@ -9227,50 +9180,27 @@ instruct andL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
ins_pipe(pipe_class_default);
%}
// Immediate And long
instruct andL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2, flagsRegCR0 cr0) %{
instruct andL_reg_immL(iRegLdst dst, iRegLsrc src1, immL src2, flagsRegCR0 cr0) %{
match(Set dst (AndL src1 src2));
predicate(Assembler::andi_supports(n->in(2)->get_long()));
effect(KILL cr0);
format %{ "ANDI $dst, $src1, $src2 \t// long" %}
size(4);
ins_encode %{
// FIXME: avoid andi_ ?
__ andi_($dst$$Register, $src1$$Register, $src2$$constant);
%}
ins_pipe(pipe_class_default);
%}
// Immediate And Long where the immediate is a negative power of 2.
instruct andL_reg_immLnegpow2(iRegLdst dst, iRegLsrc src1, immLnegpow2 src2) %{
match(Set dst (AndL src1 src2));
format %{ "ANDDI $dst, $src1, $src2" %}
size(4);
ins_encode %{
__ clrrdi($dst$$Register, $src1$$Register, log2i_exact(-(julong)$src2$$constant));
%}
ins_pipe(pipe_class_default);
%}
instruct andL_reg_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immLpow2minus1 src2) %{
match(Set dst (AndL src1 src2));
format %{ "ANDDI $dst, $src1, $src2" %}
size(4);
ins_encode %{
__ clrldi($dst$$Register, $src1$$Register, 64 - log2i_exact((julong)$src2$$constant + 1ull));
__ andi($dst$$Register, $src1$$Register, $src2$$constant); // optimized version
%}
ins_pipe(pipe_class_default);
%}
// AndL + ConvL2I.
instruct convL2I_andL_reg_immLpow2minus1(iRegIdst dst, iRegLsrc src1, immLpow2minus1 src2) %{
instruct convL2I_andL_reg_immL(iRegIdst dst, iRegLsrc src1, immL src2, flagsRegCR0 cr0) %{
match(Set dst (ConvL2I (AndL src1 src2)));
ins_cost(DEFAULT_COST);
format %{ "ANDDI $dst, $src1, $src2 \t// long + l2i" %}
predicate(Assembler::andi_supports(n->in(1)->in(2)->get_long()));
effect(KILL cr0);
format %{ "ANDI $dst, $src1, $src2 \t// long + l2i" %}
size(4);
ins_encode %{
__ clrldi($dst$$Register, $src1$$Register, 64 - log2i_exact((julong)$src2$$constant + 1ull));
__ andi($dst$$Register, $src1$$Register, $src2$$constant); // optimized version
%}
ins_pipe(pipe_class_default);
%}

View File

@ -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.
* Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -103,8 +103,6 @@
public:
enum {
pc_return_offset = 0,
// All frames
link_offset = -2,
return_addr_offset = -1,

View File

@ -542,14 +542,6 @@
unsigned long flags, int max_frames = 0);
enum {
// This enum value specifies the offset from the pc remembered by
// call instructions to the location where control returns to
// after a normal return. Most architectures remember the return
// location directly, i.e. the offset is zero. This is the case
// for z/Architecture, too.
//
// Normal return address is the instruction following the branch.
pc_return_offset = 0,
metadata_words = 0,
metadata_words_at_bottom = 0,
metadata_words_at_top = 0,

View File

@ -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
@ -54,7 +54,6 @@
public:
enum {
pc_return_offset = 0,
// All frames
link_offset = 0,
return_addr_offset = 1,

View File

@ -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 2007, 2008, 2009, 2010 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -30,7 +30,6 @@
public:
enum {
pc_return_offset = 0,
metadata_words = 0,
// size, in words, of metadata at frame bottom, i.e. it is not part of the
// caller/callee overlap

View File

@ -6387,7 +6387,7 @@ void os::jfr_report_memory_info() {
// Send the RSS JFR event
EventResidentSetSize event;
event.set_size(pmex.WorkingSetSize);
event.set_peak(pmex.PeakWorkingSetSize);
event.set_peak(MAX2(pmex.PeakWorkingSetSize, pmex.WorkingSetSize));
event.commit();
} else {
// Log a warning

View File

@ -261,13 +261,16 @@ void RiscvHwprobe::add_features_from_query_result() {
// ====== non-extensions ======
//
if (is_valid(RISCV_HWPROBE_KEY_MARCHID)) {
// For value-type keys, the kernel returns (uint64_t)-1 when CPUs in the
// query set disagree (different core types). Skip these as the value is
// not meaningful for the system as a whole.
if (is_valid(RISCV_HWPROBE_KEY_MARCHID) && query[RISCV_HWPROBE_KEY_MARCHID].value != (uint64_t)-1) {
VM_Version::marchid.enable_feature(query[RISCV_HWPROBE_KEY_MARCHID].value);
}
if (is_valid(RISCV_HWPROBE_KEY_MIMPID)) {
if (is_valid(RISCV_HWPROBE_KEY_MIMPID) && query[RISCV_HWPROBE_KEY_MIMPID].value != (uint64_t)-1) {
VM_Version::mimpid.enable_feature(query[RISCV_HWPROBE_KEY_MIMPID].value);
}
if (is_valid(RISCV_HWPROBE_KEY_MVENDORID)) {
if (is_valid(RISCV_HWPROBE_KEY_MVENDORID) && query[RISCV_HWPROBE_KEY_MVENDORID].value != (uint64_t)-1) {
VM_Version::mvendorid.enable_feature(query[RISCV_HWPROBE_KEY_MVENDORID].value);
}
// RISCV_HWPROBE_KEY_CPUPERF_0 is deprecated and returns similar values

View File

@ -2424,9 +2424,6 @@ int AOTCodeAddressTable::id_for_address(address addr, RelocIterator reloc, CodeB
id = search_address(addr, _stubs_addr, _stubs_max);
if (id == BAD_ADDRESS_ID) {
StubCodeDesc* desc = StubCodeDesc::desc_for(addr);
if (desc == nullptr) {
desc = StubCodeDesc::desc_for(addr + frame::pc_return_offset);
}
const char* sub_name = (desc != nullptr) ? desc->name() : "<unknown>";
assert(false, "Address " INTPTR_FORMAT " for Stub:%s is missing in AOT Code Cache addresses table", p2i(addr), sub_name);
} else {

View File

@ -3783,9 +3783,6 @@ const char* nmethod::reloc_string_for(u_char* begin, u_char* end) {
address dest = r->destination();
if (StubRoutines::contains(dest)) {
StubCodeDesc* desc = StubCodeDesc::desc_for(dest);
if (desc == nullptr) {
desc = StubCodeDesc::desc_for(dest + frame::pc_return_offset);
}
if (desc != nullptr) {
st.print(" Stub::%s", desc->name());
return st.as_string();

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 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
@ -302,9 +302,6 @@ void ExternalsRecorder::print_statistics() {
if (addr != nullptr) {
if (StubRoutines::contains(addr)) {
StubCodeDesc* desc = StubCodeDesc::desc_for(addr);
if (desc == nullptr) {
desc = StubCodeDesc::desc_for(addr + frame::pc_return_offset);
}
const char* stub_name = (desc != nullptr) ? desc->name() : "<unknown>";
tty->print(" stub: %s", stub_name);
} else {

View File

@ -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
@ -922,9 +922,6 @@ void RelocIterator::print_current_on(outputStream* st) {
st->print(" | [destination=" INTPTR_FORMAT "]", p2i(dest));
if (StubRoutines::contains(dest)) {
StubCodeDesc* desc = StubCodeDesc::desc_for(dest);
if (desc == nullptr) {
desc = StubCodeDesc::desc_for(dest + frame::pc_return_offset);
}
if (desc != nullptr) {
st->print(" Stub::%s", desc->name());
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2025, 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
@ -591,9 +591,6 @@ void decode_env::print_address(address adr) {
if (Universe::is_fully_initialized()) {
if (StubRoutines::contains(adr)) {
StubCodeDesc* desc = StubCodeDesc::desc_for(adr);
if (desc == nullptr) {
desc = StubCodeDesc::desc_for(adr + frame::pc_return_offset);
}
if (desc != nullptr) {
st->print("Stub::%s", desc->name());
if (desc->begin() != adr) {

View File

@ -1654,6 +1654,9 @@ void G1CollectedHeap::stop() {
// that are destroyed during shutdown.
_cr->stop();
_service_thread->stop();
VM_G1StopMarking op;
VMThread::execute(&op);
_cm->stop();
}

View File

@ -2036,6 +2036,26 @@ void G1ConcurrentMark::print_stats() {
}
}
bool G1ConcurrentMark::shutdown_cleanup_needed() const {
// Cleanup (aborting threads, setting abort flags) is needed throughout the whole cycle before
// stopping the CM thread.
return is_fully_initialized() && is_in_concurrent_cycle();
}
void G1ConcurrentMark::shutdown_concurrent_cycle() {
assert_at_safepoint_on_vm_thread();
abort_root_region_scan_at_safepoint();
abort_marking_threads();
SATBMarkQueueSet& satb_mq_set = G1BarrierSet::satb_mark_queue_set();
satb_mq_set.abandon_partial_marking();
// This can be called either during or outside marking, we'll read
// the expected_active value from the SATB queue set.
satb_mq_set.set_active_all_threads(false, /* new active value */
satb_mq_set.is_active() /* expected_active */);
}
bool G1ConcurrentMark::concurrent_cycle_abort() {
assert_at_safepoint_on_vm_thread();
assert(_g1h->collector_state()->is_in_full_gc(), "must be");

View File

@ -608,6 +608,8 @@ public:
bool mark_stack_empty() const { return _global_mark_stack.is_empty(); }
void concurrent_cycle_start();
bool shutdown_cleanup_needed() const;
void shutdown_concurrent_cycle();
// Abandon current marking iteration due to a Full GC.
bool concurrent_cycle_abort();
void concurrent_cycle_end(bool mark_cycle_completed);

View File

@ -50,7 +50,8 @@ class G1ConcurrentMarkThread: public ConcurrentGCThread {
Atomic<ServiceState> _state;
ServiceState state() const { return _state.load_relaxed(); }
ServiceState state() const { return _state.load_acquire(); }
void set_state(ServiceState new_state) { _state.release_store(new_state); }
// Returns whether we are in a "Full" cycle.
bool is_in_full_concurrent_cycle() const;

View File

@ -48,31 +48,31 @@ inline bool G1ConcurrentMarkThread::is_in_full_concurrent_cycle() const {
inline void G1ConcurrentMarkThread::set_idle() {
// Concurrent cycle may be aborted any time.
assert(!is_idle(), "must not be idle");
_state.store_relaxed(Idle);
set_state(Idle);
}
inline void G1ConcurrentMarkThread::start_full_cycle() {
assert(SafepointSynchronize::is_at_safepoint(), "must be");
assert(is_idle(), "cycle in progress");
_state.store_relaxed(FullCycleMarking);
set_state(FullCycleMarking);
}
inline void G1ConcurrentMarkThread::start_undo_cycle() {
assert(SafepointSynchronize::is_at_safepoint(), "must be");
assert(is_idle(), "cycle in progress");
_state.store_relaxed(UndoCycleResetForNextCycle);
set_state(UndoCycleResetForNextCycle);
}
inline void G1ConcurrentMarkThread::set_full_cycle_rebuild_and_scrub() {
assert(SafepointSynchronize::is_at_safepoint(), "must be");
assert(state() == FullCycleMarking, "must be");
_state.store_relaxed(FullCycleRebuildOrScrub);
set_state(FullCycleRebuildOrScrub);
}
inline void G1ConcurrentMarkThread::set_full_cycle_reset_for_next_cycle() {
assert(SafepointSynchronize::is_at_safepoint(), "must be");
assert(state() == FullCycleRebuildOrScrub, "must be");
_state.store_relaxed(FullCycleResetForNextCycle);
set_state(FullCycleResetForNextCycle);
}
inline bool G1ConcurrentMarkThread::is_in_marking() const {

View File

@ -114,12 +114,5 @@ public:
};
void G1SATBMarkQueueSet::filter(SATBMarkQueue& queue) {
G1CollectedHeap* g1h = G1CollectedHeap::heap();
if (g1h->collector_state()->is_in_marking()) {
apply_filter(G1SATBMarkQueueFilterFn(), queue);
} else {
// is_in_marking() covers both the concurrent marking and the Remark pause. Outside
// of that, there can be no entry that requires SATB marking.
queue.set_empty();
}
apply_filter(G1SATBMarkQueueFilterFn(), queue);
}

View File

@ -130,8 +130,13 @@ void VM_G1CollectForAllocation::doit() {
}
void VM_G1PauseConcurrent::doit() {
GCIdMark gc_id_mark(_gc_id);
G1CollectedHeap* g1h = G1CollectedHeap::heap();
if (_is_shutting_down) {
g1h->concurrent_mark()->shutdown_concurrent_cycle();
return;
}
GCIdMark gc_id_mark(_gc_id);
GCTraceCPUTime tcpu(g1h->concurrent_mark()->gc_tracer_cm());
// GCTraceTime(...) only supports sub-phases, so a more verbose version
@ -150,12 +155,9 @@ void VM_G1PauseConcurrent::doit() {
bool VM_G1PauseConcurrent::doit_prologue() {
Heap_lock->lock();
G1CollectedHeap* g1h = G1CollectedHeap::heap();
if (g1h->is_shutting_down()) {
_is_shutting_down = g1h->is_shutting_down();
if (_is_shutting_down && !g1h->concurrent_mark()->shutdown_cleanup_needed()) {
Heap_lock->unlock();
// JVM shutdown has started. Abort concurrent marking to ensure that any further
// concurrent VM operations will not try to start and interfere with the shutdown
// process.
g1h->concurrent_mark()->abort_marking_threads();
return false;
}
return true;
@ -177,3 +179,19 @@ void VM_G1PauseCleanup::work() {
G1ConcurrentMark* cm = G1CollectedHeap::heap()->concurrent_mark();
cm->cleanup();
}
bool VM_G1StopMarking::doit_prologue() {
G1CollectedHeap* g1h = G1CollectedHeap::heap();
#ifdef ASSERT
{
MutexLocker ml(Heap_lock);
assert(g1h->is_shutting_down(), "must be");
}
#endif
return g1h->concurrent_mark()->shutdown_cleanup_needed();
}
void VM_G1StopMarking::doit() {
G1ConcurrentMark* cm = G1CollectedHeap::heap()->concurrent_mark();
cm->shutdown_concurrent_cycle();
}

View File

@ -80,11 +80,12 @@ public:
// Concurrent G1 stop-the-world operations such as remark and cleanup.
class VM_G1PauseConcurrent : public VM_Operation {
uint _gc_id;
bool _is_shutting_down;
const char* _message;
protected:
VM_G1PauseConcurrent(const char* message) :
_gc_id(GCId::current()), _message(message) { }
_gc_id(GCId::current()), _is_shutting_down(false), _message(message) { }
virtual void work() = 0;
// Does this concurrent pause affect the memory pools? If so, update the collectionUsage()
@ -116,4 +117,15 @@ public:
void work() override;
};
class VM_G1StopMarking : public VM_Operation {
public:
VM_G1StopMarking() : VM_Operation() { }
VMOp_Type type() const override { return VMOp_G1StopMarking; }
bool doit_prologue() override;
void doit() override;
bool is_gc_operation() const override { return true; }
};
#endif // SHARE_GC_G1_G1VMOPERATIONS_HPP

View File

@ -315,17 +315,16 @@ HeapWord* ParallelScavengeHeap::mem_allocate_work(size_t size, bool is_tlab) {
return result;
}
// Ensure that is_init_completed() does not transition while expanding the heap.
ConditionalMutexLocker ml_init(InitCompleted_lock, !is_init_completed(), Mutex::_no_safepoint_check_flag);
if (!is_init_completed()) {
// Double checked locking, this ensure that is_init_completed() does not
// transition while expanding the heap.
MonitorLocker ml(InitCompleted_lock, Monitor::_no_safepoint_check_flag);
if (!is_init_completed()) {
result = expand_heap_and_allocate(size, is_tlab);
// Return the result if it's tlab-allocation. If the result is null, callers will retry
// non-tlab allocation.
if (result != nullptr || is_tlab) {
return result;
}
// Rechecked !is_init_completed() implies we have mutual exclusion via
// `Heap_lock` and `InitCompleted_lock`
result = expand_heap_and_allocate(size, is_tlab);
// Return the result if it's tlab-allocation. If the result is null,
// callers will retry non-tlab allocation.
if (result != nullptr || is_tlab) {
return result;
}
}
}

View File

@ -144,7 +144,7 @@ void ShenandoahEvacuateUpdateRootClosureBase<CONCURRENT, STABLE_THREAD>::do_oop(
template <bool CONCURRENT, bool STABLE_THREAD>
template <class T>
void ShenandoahEvacuateUpdateRootClosureBase<CONCURRENT, STABLE_THREAD>::do_oop_work(T* p) {
assert(_heap->is_concurrent_weak_root_in_progress() ||
assert((_heap->is_concurrent_weak_root_in_progress() && _heap->is_evacuation_in_progress()) ||
_heap->is_concurrent_strong_root_in_progress(),
"Only do this in root processing phase");

View File

@ -111,7 +111,7 @@ public:
return;
}
{
if (_heap->is_evacuation_in_progress()) {
ShenandoahNMethodLocker locker(nm_data->lock());
// Heal oops

View File

@ -183,7 +183,7 @@ bool ShenandoahConcurrentGC::collect(GCCause::Cause cause) {
assert(heap->is_concurrent_weak_root_in_progress(), "Must be doing weak roots now");
// Concurrent stack processing
// Finish all thread/stack roots if needed. This completes stack watermark processing.
if (heap->is_evacuation_in_progress()) {
entry_thread_roots();
}
@ -211,6 +211,9 @@ bool ShenandoahConcurrentGC::collect(GCCause::Cause cause) {
entry_strong_roots();
}
// Roots processing is complete, put the weak roots flag down.
entry_final_roots();
// Continue the cycle with evacuation and optional update-refs.
// This may be skipped if there is nothing to evacuate.
// If so, evac_in_progress would be unset by collection set preparation code.
@ -249,9 +252,18 @@ bool ShenandoahConcurrentGC::collect(GCCause::Cause cause) {
entry_cleanup_complete();
} else {
_abbreviated = true;
if (!entry_final_roots()) {
assert(_degen_point != _degenerated_unset, "Need to know where to start degenerated cycle");
return false;
if (heap->mode()->is_generational()) {
entry_complete_abbreviated_cycle();
// If the promote-in-place operation was cancelled, we can have the degenerated
// cycle complete the operation. It will see that no evacuations are in progress,
// and that there are regions wanting promotion. The risk with not handling the
// cancellation would be failing to restore top for these regions and leaving
// them unable to serve allocations for the old generation.
if (check_cancellation_and_abort(ShenandoahDegenPoint::_degenerated_evac)) {
return false;
}
}
// In normal cycle, final-update-refs would verify at the end of the cycle.
@ -275,34 +287,34 @@ bool ShenandoahConcurrentGC::collect(GCCause::Cause cause) {
return true;
}
bool ShenandoahConcurrentGC::complete_abbreviated_cycle() {
void ShenandoahConcurrentGC::entry_complete_abbreviated_cycle() {
shenandoah_assert_generational();
ShenandoahGenerationalHeap* const heap = ShenandoahGenerationalHeap::heap();
TraceCollectorStats tcs(heap->monitoring_support()->concurrent_collection_counters());
static const char* msg = "Concurrent complete abbreviated cycle";
ShenandoahConcurrentPhase gc_phase(msg, ShenandoahPhaseTimings::complete_abbreviated);
EventMark em("%s", msg);
ShenandoahWorkerScope scope(heap->workers(),
ShenandoahWorkerPolicy::calc_workers_for_conc_evac(),
msg);
// We chose not to evacuate because we found sufficient immediate garbage.
// However, there may still be regions to promote in place, so do that now.
if (heap->old_generation()->has_in_place_promotions()) {
entry_promote_in_place();
// If the promote-in-place operation was cancelled, we can have the degenerated
// cycle complete the operation. It will see that no evacuations are in progress,
// and that there are regions wanting promotion. The risk with not handling the
// cancellation would be failing to restore top for these regions and leaving
// them unable to serve allocations for the old generation.This will leave the weak
// roots flag set (the degenerated cycle will unset it).
if (check_cancellation_and_abort(ShenandoahDegenPoint::_degenerated_evac)) {
return false;
}
ShenandoahTimingsTracker timing(ShenandoahPhaseTimings::complete_abbreviated_promote_in_place);
ShenandoahGCWorkerPhase worker_phase(ShenandoahPhaseTimings::complete_abbreviated_promote_in_place);
heap->promote_regions_in_place(_generation, true);
}
// At this point, the cycle is effectively complete. If the cycle has been cancelled here,
// the control thread will detect it on its next iteration and run a degenerated young cycle.
if (!_generation->is_old()) {
if (!heap->cancelled_gc() && !_generation->is_old()) {
ShenandoahTimingsTracker tracker(ShenandoahPhaseTimings::complete_abbreviated_update_region_ages);
heap->update_region_ages(_generation->complete_marking_context());
}
return true;
}
void ShenandoahConcurrentGC::vmop_entry_init_mark() {
@ -582,16 +594,6 @@ void ShenandoahConcurrentGC::entry_evacuate() {
op_evacuate();
}
void ShenandoahConcurrentGC::entry_promote_in_place() const {
shenandoah_assert_generational();
ShenandoahTimingsTracker timing(ShenandoahPhaseTimings::promote_in_place);
ShenandoahGCWorkerPhase worker_phase(ShenandoahPhaseTimings::promote_in_place);
EventMark em("%s", "Promote in place");
ShenandoahGenerationalHeap::heap()->promote_regions_in_place(_generation, true);
}
void ShenandoahConcurrentGC::entry_update_thread_roots() {
ShenandoahHeap* const heap = ShenandoahHeap::heap();
TraceCollectorStats tcs(heap->monitoring_support()->concurrent_collection_counters());
@ -1227,26 +1229,14 @@ void ShenandoahConcurrentGC::op_final_update_refs() {
}
}
bool ShenandoahConcurrentGC::entry_final_roots() {
void ShenandoahConcurrentGC::entry_final_roots() {
ShenandoahHeap* const heap = ShenandoahHeap::heap();
TraceCollectorStats tcs(heap->monitoring_support()->concurrent_collection_counters());
const char* msg = conc_final_roots_event_message();
ShenandoahConcurrentPhase gc_phase(msg, ShenandoahPhaseTimings::conc_final_roots);
EventMark em("%s", msg);
ShenandoahWorkerScope scope(heap->workers(),
ShenandoahWorkerPolicy::calc_workers_for_conc_evac(),
msg);
if (heap->mode()->is_generational()) {
if (!complete_abbreviated_cycle()) {
return false;
}
}
heap->concurrent_final_roots();
return true;
}
void ShenandoahConcurrentGC::op_verify_final() {

View File

@ -91,6 +91,8 @@ protected:
void entry_class_unloading();
void entry_strong_roots();
void entry_cleanup_early();
void entry_complete_abbreviated_cycle();
void entry_final_roots();
void entry_evacuate();
void entry_update_thread_roots();
void entry_update_card_table();
@ -98,12 +100,6 @@ protected:
void entry_update_refs();
void entry_cleanup_complete();
// This is the last phase of a cycle which performs no evacuations
bool entry_final_roots();
// Called when the collection set is empty, but the generational mode has regions to promote in place
void entry_promote_in_place() const;
// Actual work for the phases
void op_reset();
void op_init_mark();
@ -135,8 +131,6 @@ protected:
private:
void start_mark();
bool complete_abbreviated_cycle();
static bool has_in_place_promotions(ShenandoahHeap* heap);
// Messages for GC trace events, they have to be immortal for

View File

@ -1236,7 +1236,6 @@ void ShenandoahHeap::concurrent_prepare_for_update_refs() {
// A cancellation at this point means the degenerated cycle must resume from update-refs.
set_gc_state_concurrent(EVACUATION, false);
set_gc_state_concurrent(WEAK_ROOTS, false);
set_gc_state_concurrent(UPDATE_REFS, true);
}
@ -1252,35 +1251,24 @@ void ShenandoahHeap::concurrent_prepare_for_update_refs() {
_update_refs_iterator.reset();
}
class ShenandoahCompositeHandshakeClosure : public HandshakeClosure {
HandshakeClosure* _handshake_1;
HandshakeClosure* _handshake_2;
public:
ShenandoahCompositeHandshakeClosure(HandshakeClosure* handshake_1, HandshakeClosure* handshake_2) :
HandshakeClosure(handshake_2->name()),
_handshake_1(handshake_1), _handshake_2(handshake_2) {}
void do_thread(Thread* thread) override {
_handshake_1->do_thread(thread);
_handshake_2->do_thread(thread);
}
};
void ShenandoahHeap::concurrent_final_roots(HandshakeClosure* handshake_closure) {
void ShenandoahHeap::concurrent_final_roots() {
{
assert(!is_evacuation_in_progress(), "Should not evacuate for abbreviated or old cycles");
MutexLocker lock(Threads_lock);
#ifdef ASSERT
for (JavaThreadIteratorWithHandle jtiwh; JavaThread* jt = jtiwh.next();) {
StackWatermark* sw = StackWatermarkSet::get(jt, StackWatermarkKind::gc);
assert(sw == nullptr || sw->processing_completed(),
"Cannot turn off weak roots before stack watermark processing is complete");
}
#endif
set_gc_state_concurrent(WEAK_ROOTS, false);
}
ShenandoahGCStatePropagatorHandshakeClosure propagator(_gc_state.raw_value());
Threads::non_java_threads_do(&propagator);
if (handshake_closure == nullptr) {
Handshake::execute(&propagator);
} else {
ShenandoahCompositeHandshakeClosure composite(&propagator, handshake_closure);
Handshake::execute(&composite);
}
Handshake::execute(&propagator);
}
oop ShenandoahHeap::evacuate_object(oop p, Thread* thread) {

View File

@ -493,8 +493,8 @@ private:
// Retires LABs used for evacuation
void concurrent_prepare_for_update_refs();
// Turn off weak roots flag, purge old satb buffers in generational mode
void concurrent_final_roots(HandshakeClosure* handshake_closure = nullptr);
// Turn off weak roots flag
void concurrent_final_roots();
virtual void update_heap_references(ShenandoahGeneration* generation, bool concurrent);
// Final update region states

View File

@ -124,7 +124,7 @@ void ShenandoahNMethod::heal_nmethod(nmethod* nm) {
assert(data->lock()->owned_by_self(), "Must hold the lock");
ShenandoahHeap* const heap = ShenandoahHeap::heap();
if (heap->is_concurrent_weak_root_in_progress() ||
if ((heap->is_concurrent_weak_root_in_progress() && heap->is_evacuation_in_progress()) ||
heap->is_concurrent_strong_root_in_progress()) {
heal_nmethod_metadata(data);
} else if (heap->is_concurrent_mark_in_progress()) {

View File

@ -134,7 +134,7 @@ bool ShenandoahOldGC::collect(GCCause::Cause cause) {
// return from here with weak roots in progress. This is not a valid gc state
// for any young collections (or allocation failures) that interrupt the old
// collection.
heap->concurrent_final_roots();
entry_final_roots();
// After concurrent old marking finishes, we reclaim immediate garbage. Further, we may also want to expand OLD in order
// to make room for anticipated promotions and/or for mixed evacuations. Mixed evacuations are especially likely to

View File

@ -106,8 +106,10 @@ class outputStream;
" CE: ") \
SHENANDOAH_SIMPLE_PHASE_DEF(f, conc_update_card_table, "Concurrent Update Cards") \
SHENANDOAH_SIMPLE_PHASE_DEF(f, conc_final_roots, "Concurrent Final Roots") \
SHENANDOAH_WORKER_PHASE_DEF(f, promote_in_place, " Promote Regions", \
SHENANDOAH_SIMPLE_PHASE_DEF(f, complete_abbreviated, "Complete Abbreviated Cycle") \
SHENANDOAH_WORKER_PHASE_DEF(f, complete_abbreviated_promote_in_place, " Promote Regions", \
" PIP: ") \
SHENANDOAH_SIMPLE_PHASE_DEF(f, complete_abbreviated_update_region_ages, " Update Region Ages") \
SHENANDOAH_SIMPLE_PHASE_DEF(f, final_verify_gross, "Pause Final Verify (G)") \
SHENANDOAH_SIMPLE_PHASE_DEF(f, final_verify, "Pause Final Verify (N)") \
SHENANDOAH_SIMPLE_PHASE_DEF(f, init_update_refs_gross, "Pause Init Update Refs (G)") \

View File

@ -67,14 +67,13 @@ ShenandoahStackWatermark::ShenandoahStackWatermark(JavaThread* jt) :
OopClosure* ShenandoahStackWatermark::closure_from_context(void* context) {
if (context != nullptr) {
assert(_heap->is_concurrent_weak_root_in_progress() ||
assert((_heap->is_concurrent_weak_root_in_progress() && _heap->is_evacuation_in_progress()) ||
_heap->is_concurrent_mark_in_progress(),
"Only these two phases");
assert(Thread::current()->is_Worker_thread(), "Unexpected thread passing in context: " PTR_FORMAT, p2i(context));
return reinterpret_cast<OopClosure*>(context);
} else {
if (_heap->is_concurrent_weak_root_in_progress()) {
assert(_heap->is_evacuation_in_progress(), "Nothing to evacuate");
if (_heap->is_concurrent_weak_root_in_progress() && _heap->is_evacuation_in_progress()) {
return &_evac_update_oop_cl;
} else if (_heap->is_concurrent_mark_in_progress()) {
return &_keep_alive_cl;
@ -87,11 +86,9 @@ OopClosure* ShenandoahStackWatermark::closure_from_context(void* context) {
void ShenandoahStackWatermark::start_processing_impl(void* context) {
NoSafepointVerifier nsv;
ShenandoahHeap* const heap = ShenandoahHeap::heap();
// Process the non-frame part of the thread
if (heap->is_concurrent_weak_root_in_progress()) {
assert(heap->is_evacuation_in_progress(), "Should not be armed");
if (_heap->is_concurrent_weak_root_in_progress() && _heap->is_evacuation_in_progress()) {
// Retire the TLABs, which will force threads to reacquire their TLABs.
// This is needed for two reasons. Strong one: new allocations would be with new freeset,
// which would be outside the collection set, so no cset writes would happen there.
@ -100,7 +97,7 @@ void ShenandoahStackWatermark::start_processing_impl(void* context) {
retire_tlab();
_jt->oops_do_no_frames(closure_from_context(context), &_nm_cl);
} else if (heap->is_concurrent_mark_in_progress()) {
} else if (_heap->is_concurrent_mark_in_progress()) {
// We need to reset all TLABs because they might be below the TAMS, and we need to mark
// the objects in them. Do not let mutators allocate any new objects in their current TLABs.
// It is also a good place to resize the TLAB sizes for future allocations.
@ -129,9 +126,8 @@ void ShenandoahStackWatermark::retire_tlab() {
void ShenandoahStackWatermark::process(const frame& fr, RegisterMap& register_map, void* context) {
OopClosure* oops = closure_from_context(context);
assert(oops != nullptr, "Should not get to here");
ShenandoahHeap* const heap = ShenandoahHeap::heap();
assert((heap->is_concurrent_weak_root_in_progress() && heap->is_evacuation_in_progress()) ||
heap->is_concurrent_mark_in_progress(),
assert((_heap->is_concurrent_weak_root_in_progress() && _heap->is_evacuation_in_progress()) ||
_heap->is_concurrent_mark_in_progress(),
"Only these two phases");
fr.oops_do(oops, &_nm_cl, &register_map, DerivedPointerIterationMode::_directly);
}

View File

@ -3497,22 +3497,38 @@ void Compile::final_graph_reshaping_main_switch(Node* n, Final_Reshape_Counts& f
ResourceMark rm;
Unique_Node_List wq;
wq.push(n);
// When we remove a CastPP, we need to pin all of its transitive users under the control of
// the removed node. The simplest approach is to pin all of the uses of the removed CastPP,
// but it is overly conservative, as an AddP does not really need pinning. As a result, we
// look through those nodes that do not need pinning and only pin memory access nodes under
// n->in(0).
for (uint next = 0; next < wq.size(); ++next) {
Node *m = wq.at(next);
for (DUIterator_Fast imax, i = m->fast_outs(imax); i < imax; i++) {
Node* use = m->fast_out(i);
if (use->is_Mem() || use->is_EncodeNarrowPtr()) {
int use_op = use->Opcode();
if (use->is_CFG() || use->pinned() || // already pinned at the exact control
use->is_Cmp() || use_op == Op_CastP2X || use_op == Op_Conv2B) { // pure computations
continue;
} else if (use->is_EncodeNarrowPtr() || // EncodeP remembers whether its input is nullable, so it must be pinned
use_op == Op_PartialSubtypeCheck || // This accesses its pointer inputs, so it must depend on them being not-null
use->is_Mem() || use->is_memory_access_intrinsic()) {
use->ensure_control_or_add_prec(n->in(0));
} else if (use_op == Op_AddP ||
use_op == Op_CastPP || use_op == Op_CheckCastPP ||
use_op == Op_CMoveP || use_op == Op_CMoveN ||
use_op == Op_DecodeN || use_op == Op_DecodeNKlass ||
use_op == Op_VerifyVectorAlignment) {
// Look through use to find memory accesses if use does not need pinning
wq.push(use);
} else {
switch(use->Opcode()) {
case Op_AddP:
case Op_DecodeN:
case Op_DecodeNKlass:
case Op_CheckCastPP:
case Op_CastPP:
wq.push(use);
break;
}
// Should have handled all kinds of nodes, verify that we do not unexpectedly arrive
// here
assert(false, "unexpected node %s", use->Name());
// Be conservative in product and pin the unexpected use
use->ensure_control_or_add_prec(n->in(0));
}
}
}

View File

@ -3018,6 +3018,27 @@ bool Node::is_data_proj_of_pure_function(const Node* maybe_pure_function) const
return Opcode() == Op_Proj && as_Proj()->_con == TypeFunc::Parms && maybe_pure_function->is_CallLeafPure();
}
// Whether this is an intrinsic node that accesses memory and has a memory input, such as array
// equal intrinsic. Some nodes do access memory but do not have a memory input, such as
// PartialSubTypeCheck, they are not included here.
bool Node::is_memory_access_intrinsic() const {
switch (Opcode()) {
case Op_StrComp:
case Op_StrEquals:
case Op_StrIndexOf:
case Op_StrIndexOfChar:
case Op_StrCompressedCopy:
case Op_StrInflatedCopy:
case Op_AryEq:
case Op_CountPositives:
case Op_VectorizedHashCode:
case Op_EncodeISOArray:
return true;
default:
return false;
}
}
//--------------------------has_non_debug_uses------------------------------
// Checks whether the node has any non-debug uses or not.
bool Node::has_non_debug_uses() const {

View File

@ -1069,6 +1069,7 @@ public:
uint is_Copy() const { return (_flags & Flag_is_Copy); }
virtual bool is_CFG() const { return false; }
bool is_memory_access_intrinsic() const;
// If this node is control-dependent on a test, can it be rerouted to a dominating equivalent
// test? This means that the node can be executed safely as long as it happens after the test

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2023 Google LLC. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -25,6 +25,7 @@
#include "runtime/atomicAccess.hpp"
#include "runtime/cpuTimeCounters.hpp"
#include "utilities/globalCounter.inline.hpp"
const char* CPUTimeGroups::to_string(CPUTimeType val) {
switch (val) {
@ -77,6 +78,10 @@ void CPUTimeCounters::inc_gc_total_cpu_time(jlong diff) {
}
void CPUTimeCounters::publish_gc_total_cpu_time() {
GlobalCounter::CriticalSection cs(Thread::current());
if (!UsePerfData || !PerfDataManager::has_PerfData()) {
return;
}
CPUTimeCounters* instance = CPUTimeCounters::get_instance();
// Atomically fetch the current _gc_total_cpu_time_diff and reset it to zero.
jlong new_value = 0;
@ -103,6 +108,10 @@ PerfCounter* CPUTimeCounters::get_counter(CPUTimeGroups::CPUTimeType name) {
}
void CPUTimeCounters::update_counter(CPUTimeGroups::CPUTimeType name, jlong total) {
GlobalCounter::CriticalSection cs(Thread::current());
if (!UsePerfData || !PerfDataManager::has_PerfData()) {
return;
}
CPUTimeCounters* instance = CPUTimeCounters::get_instance();
PerfCounter* counter = instance->get_counter(name);
jlong prev_value = counter->get_value();

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2023 Google LLC. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -79,6 +79,8 @@ private:
static void inc_gc_total_cpu_time(jlong diff);
static PerfCounter* get_counter(CPUTimeGroups::CPUTimeType name);
public:
static void initialize() {
assert(_instance == nullptr, "we can only allocate one CPUTimeCounters object");
@ -91,7 +93,6 @@ public:
}
static void create_counter(CPUTimeGroups::CPUTimeType name);
static PerfCounter* get_counter(CPUTimeGroups::CPUTimeType name);
static void update_counter(CPUTimeGroups::CPUTimeType name, jlong total);
static void publish_gc_total_cpu_time();

View File

@ -673,7 +673,7 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread
// as interpreted so the skeleton frame will be walkable
// The correct pc will be set when the skeleton frame is completely filled out
// The final pc we store in the loop is wrong and will be overwritten below
frame_pcs[number_of_frames - 1 - index ] = Interpreter::deopt_entry(vtos, 0) - frame::pc_return_offset;
frame_pcs[number_of_frames - 1 - index ] = Interpreter::deopt_entry(vtos, 0);
callee_parameters = array->element(index)->method()->size_of_parameters();
callee_locals = array->element(index)->method()->max_locals();

View File

@ -206,9 +206,9 @@ address frame::raw_pc() const {
if (is_deoptimized_frame()) {
nmethod* nm = cb()->as_nmethod_or_null();
assert(nm != nullptr, "only nmethod is expected here");
return nm->deopt_handler_entry() - pc_return_offset;
return nm->deopt_handler_entry();
} else {
return (pc() - pc_return_offset);
return pc();
}
}

View File

@ -61,15 +61,13 @@ bool ThreadSampler::sample_all_java_threads() {
continue;
}
if (CodeCache::contains(pc)) {
nmethod* nm = CodeCache::find_blob(pc)->as_nmethod_or_null();
if (nm != nullptr) {
bool created = false;
int *count = _samples.put_if_absent(nm, 0, &created);
(*count)++;
if (created) {
_samples.maybe_grow();
}
CodeBlob* cb = CodeCache::find_blob(pc);
if (cb != nullptr && cb->is_nmethod()) {
bool created = false;
int *count = _samples.put_if_absent(cb->as_nmethod(), 0, &created);
(*count)++;
if (created) {
_samples.maybe_grow();
}
}
}

View File

@ -1810,7 +1810,7 @@ JRT_LEAF(void, SharedRuntime::fixup_callers_callsite(Method* method, address cal
nmethod* caller = cb->as_nmethod();
// Get the return PC for the passed caller PC.
address return_pc = caller_pc + frame::pc_return_offset;
address return_pc = caller_pc;
if (!caller->is_in_use() || !NativeCall::is_call_before(return_pc)) {
return;

View File

@ -59,6 +59,7 @@
template(G1PauseCleanup) \
template(G1TryInitiateConcMark) \
template(G1RendezvousGCThreads) \
template(G1StopMarking) \
template(ZMarkEndOld) \
template(ZMarkEndYoung) \
template(ZMarkFlushOperation) \

View File

@ -1709,8 +1709,6 @@
/**********************/ \
NOT_ZERO(PPC64_ONLY(declare_constant(frame::entry_frame_locals_size))) \
\
declare_constant(frame::pc_return_offset) \
\
/*************/ \
/* vmSymbols */ \
/*************/ \

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2026, IBM Corporation. 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
@ -172,9 +173,18 @@ class SSLAlgorithmDecomposer extends AlgorithmDecomposer {
case B_AES_128_GCM:
components.add("AES_128_GCM");
break;
case B_AES_128_GCM_IV:
components.add("AES_128_GCM");
break;
case B_AES_256_GCM:
components.add("AES_256_GCM");
break;
case B_AES_256_GCM_IV:
components.add("AES_256_GCM");
break;
case B_CC20_P1305:
components.add("CHACHA20_POLY1305");
break;
}
return components;

View File

@ -1,28 +0,0 @@
Owner: CN=LuxTrust Global Root, O=LuxTrust s.a., C=LU
Issuer: CN=LuxTrust Global Root, O=LuxTrust s.a., C=LU
Serial number: bb8
Valid from: Thu Mar 17 09:51:37 GMT 2011 until: Wed Mar 17 09:51:37 GMT 2021
Signature algorithm name: SHA256withRSA
Subject Public Key Algorithm: 2048-bit RSA key
Version: 3
-----BEGIN CERTIFICATE-----
MIIDZDCCAkygAwIBAgICC7gwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UEBhMCTFUx
FjAUBgNVBAoTDUx1eFRydXN0IHMuYS4xHTAbBgNVBAMTFEx1eFRydXN0IEdsb2Jh
bCBSb290MB4XDTExMDMxNzA5NTEzN1oXDTIxMDMxNzA5NTEzN1owRDELMAkGA1UE
BhMCTFUxFjAUBgNVBAoTDUx1eFRydXN0IHMuYS4xHTAbBgNVBAMTFEx1eFRydXN0
IEdsb2JhbCBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsn+n
QPAiygz267Hxyw6VV0B1r6A/Ps7sqjJX5hmxZ0OYWmt8s7j6eJyqpoSyYBuAQc5j
zR8XCJmk9e8+EsdMsFeaXHhAePxFjdqRZ9w6Ubltc+a3OY52OrQfBfVpVfmTz3iI
Sr6qm9d7R1tGBEyCFqY19vx039a0r9jitScRdFmiwmYsaArhmIiIPIoFdRTjuK7z
CISbasE/MRivJ6VLm6T9eTHemD0OYcqHmMH4ijCc+j4z1aXEAwfh95Z0GAAnOCfR
K6qq4UFFi2/xJcLcopeVx0IUM115hCNq52XAV6DYXaljAeew5Ivo+MVjuOVsdJA9
x3f8K7p56aTGEnin/wIDAQABo2AwXjAMBgNVHRMEBTADAQH/MA4GA1UdDwEB/wQE
AwIBBjAfBgNVHSMEGDAWgBQXFYWJCS8kh28/HRvk8pZ5g0gTzjAdBgNVHQ4EFgQU
FxWFiQkvJIdvPx0b5PKWeYNIE84wDQYJKoZIhvcNAQELBQADggEBAFrwHNDUUM9B
fua4nX3DcNBeNv9ujnov3kgR1TQuPLdFwlQlp+HBHjeDtpSutkVIA+qVvuucarQ3
XB8u02uCgUNbCj8RVWOs+nwIAjegPDkEM/6XMshS5dklTbDG7mgfcKpzzlcD3H0K
DTPy0lrfCmw7zBFRlxqkIaKFNQLXgCLShLL4wKpov9XrqsMLq6F8K/f1O4fhVFfs
BSTveUJO84ton+Ruy4KZycwq3FPCH3CDqyEPVrRI/98HIrOM+R2mBN8tAza53W/+
MYhm/2xtRDSvCHc+JtJy9LtHVpM8mGPhM7uZI5K1g3noHZ9nrWLWidb2/CfeMifL
hNp3hSGhEiE=
-----END CERTIFICATE-----

View File

@ -75,12 +75,6 @@ public abstract class Frame implements Cloneable {
/** Size of ConstMethod for computing BCI from BCP (FIXME: hack) */
private static long ConstMethodSize;
private static int pcReturnOffset;
public static int pcReturnOffset() {
return pcReturnOffset;
}
protected void adjustForDeopt() {
if (pc != null) {
// Look for a deopt pc and if it is deopted convert to original pc
@ -104,8 +98,6 @@ public abstract class Frame implements Cloneable {
// FIXME: not sure whether alignment here is correct or how to
// force it (round up to address size?)
ConstMethodSize = ConstMethodType.getSize();
pcReturnOffset = db.lookupIntConstant("frame::pc_return_offset").intValue();
}
protected int bcpToBci(Address bcp, ConstMethod cm) {

View File

@ -29,6 +29,11 @@ serviceability/AsyncGetCallTrace/MyPackage/ASGCTBaseTest.java 8308026 generic-al
serviceability/jvmti/Heap/IterateHeapWithEscapeAnalysisEnabled.java 8264699 generic-all
vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2manyDiff_a/TestDescription.java 8308367 generic-all
vmTestbase/nsk/jvmti/unit/functions/Dispose/JvmtiTest/TestDescription.java 8387429 generic-all
vmTestbase/nsk/jvmti/scenarios/capability/CM02/cm02t001/TestDescription.java 8299217 generic-all
vmTestbase/nsk/jdi/EventRequestManager/threadStartRequests/thrstartreq002/TestDescription.java 8327967 generic-all
####
## Classes not unloaded as expected (TODO, need to check if FJ keeps a reference)

View File

@ -70,6 +70,8 @@ compiler/c2/aarch64/TestStaticCallStub.java 8359963 generic-aarch64
compiler/unsafe/AlignmentGapAccess.java 8373487 generic-all
compiler/escapeAnalysis/TestBCEscapeAnalyzerOverflow.java 8387392 windows-aarch64
#############################################################################
# :hotspot_gc
@ -160,6 +162,7 @@ vmTestbase/metaspace/gc/firstGC_default/TestDescription.java 8208250 generic-all
vmTestbase/nsk/jvmti/scenarios/capability/CM03/cm03t001/TestDescription.java 8073470 linux-all
vmTestbase/nsk/jvmti/scenarios/events/EM02/em02t006/TestDescription.java 8372206 generic-all
vmTestbase/nsk/jvmti/InterruptThread/intrpthrd003/TestDescription.java 8288911 macosx-all
vmTestbase/nsk/jvmti/unit/timers/JvmtiTest/TestDescription.java 8235348 windows-x64
vmTestbase/jit/escape/LockCoarsening/LockCoarsening001.java 8148743 generic-all
vmTestbase/jit/escape/LockCoarsening/LockCoarsening002.java 8208259 generic-all

View File

@ -314,7 +314,8 @@ tier1_gc_shenandoah = \
gc/shenandoah/compiler/ \
gc/shenandoah/mxbeans/ \
gc/shenandoah/TestSmallHeap.java \
gc/shenandoah/oom/
gc/shenandoah/oom/ \
gtest/ShenandoahGtests.java
tier2_gc_shenandoah = \
runtime/MemberName/MemberNameLeak.java \

View File

@ -38,7 +38,7 @@ import compiler.lib.ir_framework.*;
* @summary Tests to ensure that reachabilityFence() correctly keeps objects from being collected prematurely.
* @modules java.base/jdk.internal.misc
* @library /test/lib /
* @run main/othervm -Xbatch compiler.c2.ReachabilityFenceTest
* @run driver ${test.main.class}
*/
public class ReachabilityFenceTest {
private static final int SIZE = 100;

View File

@ -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
@ -38,7 +38,7 @@ import java.util.Random;
* @summary Test merging of consecutive stores
* @modules java.base/jdk.internal.misc
* @library /test/lib /
* @run main/timeout=480 compiler.c2.TestMergeStores aligned
* @run driver/timeout=480 ${test.main.class} aligned
*/
/*
@ -48,7 +48,7 @@ import java.util.Random;
* @summary Test merging of consecutive stores
* @modules java.base/jdk.internal.misc
* @library /test/lib /
* @run main/timeout=480 compiler.c2.TestMergeStores unaligned
* @run driver/timeout=480 ${test.main.class} unaligned
*/
/*
@ -58,7 +58,7 @@ import java.util.Random;
* @summary Test merging of consecutive stores
* @modules java.base/jdk.internal.misc
* @library /test/lib /
* @run main/timeout=480 compiler.c2.TestMergeStores StressIGVN
* @run driver/timeout=480 ${test.main.class} StressIGVN
*/
public class TestMergeStores {

View File

@ -31,7 +31,7 @@ import compiler.lib.ir_framework.*;
* @summary Test barriers emitted in constructors
* @library /test/lib /
* @requires os.arch=="aarch64" | os.arch=="riscv64" | os.arch=="x86_64" | os.arch=="amd64"
* @run main compiler.c2.irTests.ConstructorBarriers
* @run driver ${test.main.class}
*/
public class ConstructorBarriers {
public static void main(String[] args) {

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2023, Red Hat, Inc. All rights reserved.
* 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
@ -26,7 +26,6 @@ package compiler.c2.irTests;
import compiler.lib.ir_framework.*;
import jdk.test.lib.Utils;
import jdk.test.whitebox.WhiteBox;
import jdk.internal.misc.Unsafe;
import java.util.Random;
import java.util.Arrays;
@ -40,15 +39,12 @@ import java.util.List;
* @summary C2: vectorization fails on simple ByteBuffer loop
* @modules java.base/jdk.internal.misc
* @library /test/lib /
* @build jdk.test.whitebox.WhiteBox
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI compiler.c2.irTests.TestVectorizationMismatchedAccess
* @run driver ${test.main.class}
*/
public class TestVectorizationMismatchedAccess {
private static final Unsafe UNSAFE = Unsafe.getUnsafe();
private static final Random RANDOM = Utils.getRandomInstance();
private final static WhiteBox wb = WhiteBox.getWhiteBox();
public static void main(String[] args) {
TestFramework framework = new TestFramework();

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2025, Rivos Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -30,7 +30,7 @@
*
* @library /test/lib /
* @requires os.arch == "riscv64" & vm.cpu.features ~= ".*zbkb.*"
* @run main/othervm compiler.c2.riscv64.TestIntegerReverse
* @run driver ${test.main.class}
*/
package compiler.c2.riscv64;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2025, Rivos Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -30,7 +30,7 @@
*
* @library /test/lib /
* @requires os.arch == "riscv64" & vm.cpu.features ~= ".*zbkb.*"
* @run main/othervm compiler.c2.riscv64.TestLongReverse
* @run driver ${test.main.class}
*/
package compiler.c2.riscv64;

View File

@ -0,0 +1,53 @@
/*
* 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.controldependency;
/*
* @test
* @bug 8385420
* @summary C2 correctly handles the case when the removed CastPPNode has a CMove use.
* @run main ${test.main.class}
* @run main/othervm -Xbatch -XX:CompileOnly=${test.main.class}::test
* -XX:+UnlockDiagnosticVMOptions -XX:+StressGCM ${test.main.class}
*
*/
public class TestRemoveCastPPWithCMoveUse {
public static void main(String[] args) {
for (int i = 0; i < 10_000; i++) {
test(null, false);
test(null, true);
test("", false);
test("", true);
}
}
static int test(String a, boolean flag) {
StringBuilder sb = new StringBuilder();
if (a == null) {
sb.append("");
} else {
sb.append(flag ? a : "");
}
return sb.length();
}
}

View File

@ -43,7 +43,7 @@ import test.java.lang.invoke.lib.InstructionHelper;
* @library /test/lib /test/jdk/java/lang/invoke/common /
* @build test.java.lang.invoke.lib.InstructionHelper
*
* @run main/othervm ${test.main.class}
* @run driver ${test.main.class}
*/
public class TestDebugDuringExceptionCatching {

View File

@ -79,6 +79,8 @@ public class HotCodeCollectorMoveFunction {
private static final int C2_LEVEL = 4;
private static final int FUNC_RUN_MILLIS = 60_000;
private static volatile int blackholeCount = 0;
static {
try {
method = Runner.class.getMethod("func");
@ -111,7 +113,15 @@ public class HotCodeCollectorMoveFunction {
public static void func() {
long start = System.currentTimeMillis();
while (System.currentTimeMillis() - start < FUNC_RUN_MILLIS) {}
while (System.currentTimeMillis() - start < FUNC_RUN_MILLIS) {
// Perform multiplicative LCG to ensure the compiler does not optimize away the code.
// Integer overflow is used for the modulus so the loop terminates after (2^32)/4 iterations
int num = 1;
do {
blackholeCount++;
num *= 69069;
} while (num != 1);
}
}
}
}

View File

@ -1,5 +1,5 @@
/*
* 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
@ -27,7 +27,7 @@
* @summary Ranges can be proven to be disjoint but not orderable (thanks to unsigned range)
* Comparing such values in such range with != should always be true.
* @library /test/lib /
* @run main compiler.igvn.CmpDisjointButNonOrderedRangesLong
* @run driver ${test.main.class}
*/
package compiler.igvn;

View File

@ -32,14 +32,11 @@ import java.util.Objects;
* @bug 8342692
* @summary C2: long counted loop/long range checks: don't create loop-nest for short running loops
* @library /test/lib /
* @build jdk.test.whitebox.WhiteBox
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI compiler.longcountedloops.TestShortRunningLongCountedLoop
* @run driver ${test.main.class}
*/
public class TestShortRunningLongCountedLoop {
private static volatile int volatileField;
private final static WhiteBox wb = WhiteBox.getWhiteBox();
public static void main(String[] args) {
// IR rules expect a single loop so disable unrolling
@ -351,8 +348,9 @@ public class TestShortRunningLongCountedLoop {
throw new RuntimeException("incorrect result: " + res);
}
}
wb.enqueueMethodForCompilation(info.getTest(), CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION);
if (!wb.isMethodCompiled(info.getTest())) {
WhiteBox whitebox = WhiteBox.getWhiteBox();
whitebox.enqueueMethodForCompilation(info.getTest(), CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION);
if (!whitebox.isMethodCompiled(info.getTest())) {
throw new RuntimeException("Should be compiled now");
}
for (int i = 0; i < 10; i++) {

View File

@ -27,14 +27,14 @@
* @summary Test CountedLoopConverter::has_truncation_wrap logic that checks if
* a truncated iv (e.g. byte or char iv) is still a valid counted loop.
* @library /test/lib /
* @run main ${test.main.class}
* @run driver ${test.main.class}
*/
/*
* @test id=Xcomp
* @bug 8385855
* @library /test/lib /
* @run main ${test.main.class} -Xcomp -XX:-TieredCompilation -XX:CompileCommand=compileonly,${test.main.class}::test*
* @run driver ${test.main.class} -Xcomp -XX:-TieredCompilation -XX:CompileCommand=compileonly,${test.main.class}::test*
*/
package compiler.loopopts;

View File

@ -30,7 +30,7 @@ import compiler.lib.ir_framework.*;
* @bug 8347499
* @summary Tests that redundant safepoints can be eliminated in loops.
* @library /test/lib /
* @run main compiler.loopopts.TestRedundantSafepointElimination
* @run driver ${test.main.class}
*/
public class TestRedundantSafepointElimination {
public static void main(String[] args) {

View File

@ -1,5 +1,5 @@
/*
* 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
@ -27,14 +27,14 @@
* @summary Test logic in IfNode::fold_compares, which folds 2 signed comparisons
* into a single comparison.
* @library /test/lib /
* @run main ${test.main.class}
* @run driver ${test.main.class}
*/
/*
* @test id=Xcomp
* @bug 8346420
* @library /test/lib /
* @run main ${test.main.class} -Xcomp -XX:-TieredCompilation -XX:CompileCommand=compileonly,${test.main.class}::test*
* @run driver ${test.main.class} -Xcomp -XX:-TieredCompilation -XX:CompileCommand=compileonly,${test.main.class}::test*
*/
package compiler.rangechecks;

View File

@ -27,7 +27,7 @@
* @modules java.base/jdk.internal.lang
* @library /test/lib /
* @enablePreview
* @run main ${test.main.class}
* @run driver ${test.main.class}
*/
package compiler.stable;

View File

@ -29,7 +29,7 @@
* @key randomness
* @summary Test vectorization of rotate byte and short
* @library /test/lib /
* @run main/othervm TestRotateByteAndShortVector
* @run driver ${test.main.class}
*/
import java.util.Random;

View File

@ -31,7 +31,7 @@
* @library /test/lib /
* @modules java.base/jdk.internal.math
* @requires os.arch == "riscv64" & vm.cpu.features ~= ".*rvv.*"
* @run main compiler.vectorization.TestRoundVectorDoubleRandom
* @run driver ${test.main.class}
*/
package compiler.vectorization;

View File

@ -31,7 +31,7 @@
* @library /test/lib /
* @modules java.base/jdk.internal.math
* @requires os.arch == "riscv64" & vm.cpu.features ~= ".*rvv.*"
* @run main compiler.vectorization.TestRoundVectorFloatRandom
* @run driver ${test.main.class}
*/
package compiler.vectorization;

View File

@ -24,18 +24,10 @@
/*
* @test
* @summary Vectorization test on array copy
* @requires vm.compiler2.enabled
* @library /test/lib /
*
* @build jdk.test.whitebox.WhiteBox
* compiler.vectorization.runner.VectorizationTestRunner
*
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
* @run main/othervm -Xbootclasspath/a:.
* -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI
* compiler.vectorization.runner.ArrayCopyTest
*
* @requires vm.compiler2.enabled
* @run driver ${test.main.class}
*/
package compiler.vectorization.runner;

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2022, 2023, Arm Limited. All rights reserved.
* 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
@ -26,18 +26,10 @@
* @test
* @summary Vectorization test on array index fill
* @library /test/lib /
*
* @build jdk.test.whitebox.WhiteBox
* compiler.vectorization.runner.VectorizationTestRunner
*
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
* @run main/othervm -Xbootclasspath/a:.
* -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI
* compiler.vectorization.runner.ArrayIndexFillTest
*
* @requires (os.simpleArch == "x64") | (os.simpleArch == "aarch64") | (os.simpleArch == "riscv64")
* @requires vm.compiler2.enabled
*
* @run driver ${test.main.class}
*/
package compiler.vectorization.runner;

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2022, 2023, Arm Limited. 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
@ -25,24 +26,11 @@
* @test
* @summary Vectorization test on array invariant fill
* @library /test/lib /
*
* @build jdk.test.whitebox.WhiteBox
* compiler.vectorization.runner.VectorizationTestRunner
*
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
* @run main/othervm -Xbootclasspath/a:.
* -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI
* -XX:-OptimizeFill
* compiler.vectorization.runner.ArrayInvariantFillTest
* @run main/othervm -Xbootclasspath/a:.
* -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI
* -XX:+OptimizeFill
* compiler.vectorization.runner.ArrayInvariantFillTest
*
* @requires (os.simpleArch == "x64") | (os.simpleArch == "aarch64") | (os.simpleArch == "riscv64")
* @requires vm.compiler2.enabled
*
* @run driver ${test.main.class} NoOptimizeFill
* @run driver ${test.main.class} OptimizeFill
*/
package compiler.vectorization.runner;
@ -68,11 +56,22 @@ public class ArrayInvariantFillTest extends VectorizationTestRunner {
doubleInv = ran.nextDouble();
}
// We must pass the flags directly to the Test VM, and not the Driver VM in the @run above.
@Override
protected String[] testVMFlags(String[] args) {
return switch (args[0]) {
case "NoOptimizeFill" -> new String[]{"-XX:-OptimizeFill"};
case "OptimizeFill" -> new String[]{"-XX:+OptimizeFill"};
default -> throw new RuntimeException("Test argument not recognized: " + args[0]);
};
}
// ---------------- Simple Fill ----------------
@Test
@IR(applyIfCPUFeatureOr = {"asimd", "true", "sse2", "true", "rvv", "true"},
applyIf = {"OptimizeFill", "false"},
counts = {IRNode.REPLICATE_B, ">0"})
// TODO 8387402
//@IR(applyIfCPUFeatureOr = {"asimd", "true", "sse2", "true", "rvv", "true"},
// applyIf = {"OptimizeFill", "false"},
// counts = {IRNode.REPLICATE_B, ">0"})
@IR(applyIfCPUFeatureOr = {"asimd", "true", "sse2", "true", "rvv", "true"},
applyIf = {"OptimizeFill", "true"},
counts = {IRNode.REPLICATE_B, "0"})

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2022, 2023, Arm Limited. All rights reserved.
* Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2024, 2026, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2025, Rivos Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -28,18 +28,10 @@
* @bug 8183390 8332905
* @summary Vectorization test on bug-prone shift operation
* @library /test/lib /
*
* @build jdk.test.whitebox.WhiteBox
* compiler.vectorization.runner.VectorizationTestRunner
*
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
* @run main/othervm -Xbootclasspath/a:.
* -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI
* compiler.vectorization.runner.ArrayShiftOpTest
*
* @requires (os.simpleArch == "x64") | (os.simpleArch == "aarch64") | (os.simpleArch == "riscv64")
* @requires vm.compiler2.enabled
*
* @run driver ${test.main.class}
*/
package compiler.vectorization.runner;

View File

@ -27,33 +27,12 @@
* @bug 8183390 8340010 8342095
* @summary Vectorization test on array type conversions
* @library /test/lib /
*
* @build jdk.test.whitebox.WhiteBox
* compiler.vectorization.runner.VectorizationTestRunner
*
* @requires vm.compiler2.enabled
*
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
*
* @run main/othervm -Xbootclasspath/a:.
* -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI
* compiler.vectorization.runner.ArrayTypeConvertTest nCOH_nAV
*
* @run main/othervm -Xbootclasspath/a:.
* -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI
* compiler.vectorization.runner.ArrayTypeConvertTest nCOH_yAV
*
* @run main/othervm -Xbootclasspath/a:.
* -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI
* compiler.vectorization.runner.ArrayTypeConvertTest yCOH_nAV
*
* @run main/othervm -Xbootclasspath/a:.
* -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI
* compiler.vectorization.runner.ArrayTypeConvertTest yCOH_yAV
* @run driver ${test.main.class} nCOH_nAV
* @run driver ${test.main.class} nCOH_yAV
* @run driver ${test.main.class} yCOH_nAV
* @run driver ${test.main.class} yCOH_yAV
*/
package compiler.vectorization.runner;

View File

@ -25,17 +25,9 @@
* @test
* @summary Vectorization test on array unsafe operations
* @library /test/lib /
*
* @build jdk.test.whitebox.WhiteBox
* compiler.vectorization.runner.VectorizationTestRunner
*
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
* @run main/othervm -Xbootclasspath/a:.
* -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI
* compiler.vectorization.runner.ArrayUnsafeOpTest
*
* @requires vm.compiler2.enabled
*
* @run driver ${test.main.class}
*/
package compiler.vectorization.runner;

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2022, 2023, Arm Limited. All rights reserved.
* 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
@ -27,17 +27,9 @@
* @summary Vectorization test on basic boolean operations
* @requires vm.opt.StressUnstableIfTraps == null | !vm.opt.StressUnstableIfTraps
* @library /test/lib /
*
* @build jdk.test.whitebox.WhiteBox
* compiler.vectorization.runner.VectorizationTestRunner
*
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
* @run main/othervm -Xbootclasspath/a:.
* -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI
* compiler.vectorization.runner.BasicBooleanOpTest
*
* @requires vm.compiler2.enabled
*
* @run driver ${test.main.class}
*/
package compiler.vectorization.runner;

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2022, 2023, Arm Limited. All rights reserved.
* Copyright (c) 2023, 2025, Oracle and/or its affiliates. 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
@ -26,19 +26,9 @@
* @test
* @summary Vectorization test on basic byte operations
* @library /test/lib /
*
* @build jdk.test.whitebox.WhiteBox
* compiler.vectorization.runner.VectorizationTestRunner
*
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
* @run main/othervm -Xbootclasspath/a:.
* -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI
* -XX:CompileCommand=CompileOnly,compiler.vectorization.runner.BasicByteOpTest::*
* -XX:LoopUnrollLimit=1000
* compiler.vectorization.runner.BasicByteOpTest
*
* @requires vm.compiler2.enabled
*
* @run driver ${test.main.class}
*/
package compiler.vectorization.runner;
@ -64,6 +54,12 @@ public class BasicByteOpTest extends VectorizationTestRunner {
}
}
// We must pass the flags directly to the test-VM, and not the driver vm in the @run above.
@Override
protected String[] testVMFlags(String[] args) {
return new String[]{"-XX:CompileCommand=CompileOnly,compiler.vectorization.runner.BasicByteOpTest::*", "-XX:LoopUnrollLimit=1000"};
}
// ---------------- Arithmetic ----------------
@Test
@IR(applyIfCPUFeatureOr = {"asimd", "true", "sse2", "true", "rvv", "true"},

View File

@ -25,17 +25,9 @@
* @test
* @summary Vectorization test on basic char operations
* @library /test/lib /
*
* @build jdk.test.whitebox.WhiteBox
* compiler.vectorization.runner.VectorizationTestRunner
*
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
* @run main/othervm -Xbootclasspath/a:.
* -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI
* compiler.vectorization.runner.BasicCharOpTest
*
* @requires vm.compiler2.enabled
*
* @run driver ${test.main.class}
*/
package compiler.vectorization.runner;

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2022, 2023, Arm Limited. All rights reserved.
* Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2024, 2026, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2025, Rivos Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -27,18 +27,10 @@
* @test
* @summary Vectorization test on basic double operations
* @library /test/lib /
*
* @build jdk.test.whitebox.WhiteBox
* compiler.vectorization.runner.VectorizationTestRunner
*
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
* @run main/othervm -Xbootclasspath/a:.
* -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI
* compiler.vectorization.runner.BasicDoubleOpTest
*
* @requires (os.simpleArch == "x64") | (os.simpleArch == "aarch64") | (os.simpleArch == "riscv64")
* @requires vm.compiler2.enabled
*
* @run driver ${test.main.class}
*/
package compiler.vectorization.runner;

View File

@ -25,18 +25,10 @@
* @test
* @summary Vectorization test on basic float operations
* @library /test/lib /
*
* @build jdk.test.whitebox.WhiteBox
* compiler.vectorization.runner.VectorizationTestRunner
*
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
* @run main/othervm -Xbootclasspath/a:.
* -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI
* compiler.vectorization.runner.BasicFloatOpTest
*
* @requires (os.simpleArch == "x64") | (os.simpleArch == "aarch64") | (os.simpleArch == "riscv64")
* @requires vm.compiler2.enabled
*
* @run driver ${test.main.class}
*/
package compiler.vectorization.runner;

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2022, 2023, Arm Limited. All rights reserved.
* Copyright (c) 2023, 2025, Oracle and/or its affiliates. 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
@ -26,17 +26,9 @@
* @test
* @summary Vectorization test on basic int operations
* @library /test/lib /
*
* @build jdk.test.whitebox.WhiteBox
* compiler.vectorization.runner.VectorizationTestRunner
*
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
* @run main/othervm -Xbootclasspath/a:.
* -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI
* compiler.vectorization.runner.BasicIntOpTest
*
* @requires vm.compiler2.enabled
*
* @run driver ${test.main.class}
*/
package compiler.vectorization.runner;

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2022, 2023, Arm Limited. All rights reserved.
* Copyright (c) 2023, 2025, Oracle and/or its affiliates. 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
@ -26,18 +26,10 @@
* @test
* @summary Vectorization test on basic long operations
* @library /test/lib /
*
* @build jdk.test.whitebox.WhiteBox
* compiler.vectorization.runner.VectorizationTestRunner
*
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
* @run main/othervm -Xbootclasspath/a:.
* -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI
* compiler.vectorization.runner.BasicLongOpTest
*
* @requires (os.simpleArch == "x64") | (os.simpleArch == "aarch64") | (os.simpleArch == "riscv64")
* @requires vm.compiler2.enabled
*
* @run driver ${test.main.class}
*/
package compiler.vectorization.runner;

View File

@ -27,17 +27,9 @@
* @bug 8183390 8342095
* @summary Vectorization test on basic short operations
* @library /test/lib /
*
* @build jdk.test.whitebox.WhiteBox
* compiler.vectorization.runner.VectorizationTestRunner
*
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
* @run main/othervm -Xbootclasspath/a:.
* -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI
* compiler.vectorization.runner.BasicShortOpTest
*
* @requires vm.compiler2.enabled
*
* @run driver ${test.main.class}
*/
package compiler.vectorization.runner;

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2022, 2023, Arm Limited. All rights reserved.
* Copyright (c) 2023, 2025, Oracle and/or its affiliates. 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
@ -26,26 +26,13 @@
* @test
* @summary Vectorization test on loop array index computation
* @library /test/lib /
*
* @build jdk.test.whitebox.WhiteBox
* compiler.vectorization.runner.VectorizationTestRunner
*
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
*
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
* compiler.vectorization.runner.LoopArrayIndexComputeTest nAV_ySAC
*
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
* compiler.vectorization.runner.LoopArrayIndexComputeTest yAV_ySAC
*
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
* compiler.vectorization.runner.LoopArrayIndexComputeTest nAV_nSAC
*
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
* compiler.vectorization.runner.LoopArrayIndexComputeTest yAV_nSAC
*
* @requires (os.simpleArch == "x64") | (os.simpleArch == "aarch64")
* @requires vm.compiler2.enabled
*
* @run driver ${test.main.class} nAV_ySAC
* @run driver ${test.main.class} yAV_ySAC
* @run driver ${test.main.class} nAV_nSAC
* @run driver ${test.main.class} yAV_nSAC
*/
package compiler.vectorization.runner;
@ -60,10 +47,10 @@ public class LoopArrayIndexComputeTest extends VectorizationTestRunner {
@Override
protected String[] testVMFlags(String[] args) {
return switch (args[0]) {
case "nAV_ySAC" -> new String[]{"-XX:-AlignVector", "-XX:+UseAutoVectorizationSpeculativeAliasingChecks"};
case "yAV_ySAC" -> new String[]{"-XX:+AlignVector", "-XX:+UseAutoVectorizationSpeculativeAliasingChecks"};
case "nAV_nSAC" -> new String[]{"-XX:-AlignVector", "-XX:-UseAutoVectorizationSpeculativeAliasingChecks"};
case "yAV_nSAC" -> new String[]{"-XX:+AlignVector", "-XX:-UseAutoVectorizationSpeculativeAliasingChecks"};
case "nAV_ySAC" -> new String[]{"-XX:+UnlockDiagnosticVMOptions", "-XX:-AlignVector", "-XX:+UseAutoVectorizationSpeculativeAliasingChecks"};
case "yAV_ySAC" -> new String[]{"-XX:+UnlockDiagnosticVMOptions", "-XX:+AlignVector", "-XX:+UseAutoVectorizationSpeculativeAliasingChecks"};
case "nAV_nSAC" -> new String[]{"-XX:+UnlockDiagnosticVMOptions", "-XX:-AlignVector", "-XX:-UseAutoVectorizationSpeculativeAliasingChecks"};
case "yAV_nSAC" -> new String[]{"-XX:+UnlockDiagnosticVMOptions", "-XX:+AlignVector", "-XX:-UseAutoVectorizationSpeculativeAliasingChecks"};
default -> { throw new RuntimeException("Test argument not recognized: " + args[0]); }
};
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2022, 2023, Arm Limited. All rights reserved.
* Copyright (c) 2023, 2025, Oracle and/or its affiliates. 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
@ -26,33 +26,12 @@
* @test
* @summary Vectorization test on combined operations
* @library /test/lib /
*
* @build jdk.test.whitebox.WhiteBox
* compiler.vectorization.runner.VectorizationTestRunner
*
* @requires vm.compiler2.enabled
*
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
*
* @run main/othervm -Xbootclasspath/a:.
* -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI
* compiler.vectorization.runner.LoopCombinedOpTest nCOH_nAV
*
* @run main/othervm -Xbootclasspath/a:.
* -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI
* compiler.vectorization.runner.LoopCombinedOpTest nCOH_yAV
*
* @run main/othervm -Xbootclasspath/a:.
* -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI
* compiler.vectorization.runner.LoopCombinedOpTest yCOH_nAV
*
* @run main/othervm -Xbootclasspath/a:.
* -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI
* compiler.vectorization.runner.LoopCombinedOpTest yCOH_yAV
* @run driver ${test.main.class} nCOH_nAV
* @run driver ${test.main.class} nCOH_yAV
* @run driver ${test.main.class} yCOH_nAV
* @run driver ${test.main.class} yCOH_yAV
*/
package compiler.vectorization.runner;

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