--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp Fri Apr 11 13:04:59 2014 +0200
+++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp Fri Apr 11 15:08:40 2014 -0400
@@ -630,11 +630,20 @@
}
protected:
+ // Insert a nop if the previous is cbcond
+ void insert_nop_after_cbcond() {
+ if (UseCBCond && cbcond_before()) {
+ nop();
+ }
+ }
// Delay slot helpers
// cti is called when emitting control-transfer instruction,
// BEFORE doing the emitting.
// Only effective when assertion-checking is enabled.
void cti() {
+ // A cbcond instruction immediately followed by a CTI
+ // instruction introduces pipeline stalls, we need to avoid that.
+ no_cbcond_before();
#ifdef CHECK_DELAY
assert_not_delayed("cti should not be in delay slot");
#endif
@@ -658,7 +667,6 @@
void no_cbcond_before() {
assert(offset() == 0 || !cbcond_before(), "cbcond should not follow an other cbcond");
}
-
public:
bool use_cbcond(Label& L) {
--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.inline.hpp Fri Apr 11 13:04:59 2014 +0200
+++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.inline.hpp Fri Apr 11 15:08:40 2014 -0400
@@ -54,33 +54,33 @@
inline void Assembler::add(Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(add_op3) | rs1(s1) | rs2(s2) ); }
inline void Assembler::add(Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(add_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
-inline void Assembler::bpr( RCondition c, bool a, Predict p, Register s1, address d, relocInfo::relocType rt ) { v9_only(); cti(); emit_data( op(branch_op) | annul(a) | cond(c) | op2(bpr_op2) | wdisp16(intptr_t(d), intptr_t(pc())) | predict(p) | rs1(s1), rt); has_delay_slot(); }
-inline void Assembler::bpr( RCondition c, bool a, Predict p, Register s1, Label& L) { bpr( c, a, p, s1, target(L)); }
+inline void Assembler::bpr( RCondition c, bool a, Predict p, Register s1, address d, relocInfo::relocType rt ) { v9_only(); insert_nop_after_cbcond(); cti(); emit_data( op(branch_op) | annul(a) | cond(c) | op2(bpr_op2) | wdisp16(intptr_t(d), intptr_t(pc())) | predict(p) | rs1(s1), rt); has_delay_slot(); }
+inline void Assembler::bpr( RCondition c, bool a, Predict p, Register s1, Label& L) { insert_nop_after_cbcond(); bpr( c, a, p, s1, target(L)); }
-inline void Assembler::fb( Condition c, bool a, address d, relocInfo::relocType rt ) { v9_dep(); cti(); emit_data( op(branch_op) | annul(a) | cond(c) | op2(fb_op2) | wdisp(intptr_t(d), intptr_t(pc()), 22), rt); has_delay_slot(); }
-inline void Assembler::fb( Condition c, bool a, Label& L ) { fb(c, a, target(L)); }
+inline void Assembler::fb( Condition c, bool a, address d, relocInfo::relocType rt ) { v9_dep(); insert_nop_after_cbcond(); cti(); emit_data( op(branch_op) | annul(a) | cond(c) | op2(fb_op2) | wdisp(intptr_t(d), intptr_t(pc()), 22), rt); has_delay_slot(); }
+inline void Assembler::fb( Condition c, bool a, Label& L ) { insert_nop_after_cbcond(); fb(c, a, target(L)); }
-inline void Assembler::fbp( Condition c, bool a, CC cc, Predict p, address d, relocInfo::relocType rt ) { v9_only(); cti(); emit_data( op(branch_op) | annul(a) | cond(c) | op2(fbp_op2) | branchcc(cc) | predict(p) | wdisp(intptr_t(d), intptr_t(pc()), 19), rt); has_delay_slot(); }
-inline void Assembler::fbp( Condition c, bool a, CC cc, Predict p, Label& L ) { fbp(c, a, cc, p, target(L)); }
+inline void Assembler::fbp( Condition c, bool a, CC cc, Predict p, address d, relocInfo::relocType rt ) { v9_only(); insert_nop_after_cbcond(); cti(); emit_data( op(branch_op) | annul(a) | cond(c) | op2(fbp_op2) | branchcc(cc) | predict(p) | wdisp(intptr_t(d), intptr_t(pc()), 19), rt); has_delay_slot(); }
+inline void Assembler::fbp( Condition c, bool a, CC cc, Predict p, Label& L ) { insert_nop_after_cbcond(); fbp(c, a, cc, p, target(L)); }
-inline void Assembler::br( Condition c, bool a, address d, relocInfo::relocType rt ) { v9_dep(); cti(); emit_data( op(branch_op) | annul(a) | cond(c) | op2(br_op2) | wdisp(intptr_t(d), intptr_t(pc()), 22), rt); has_delay_slot(); }
-inline void Assembler::br( Condition c, bool a, Label& L ) { br(c, a, target(L)); }
+inline void Assembler::br( Condition c, bool a, address d, relocInfo::relocType rt ) { v9_dep(); insert_nop_after_cbcond(); cti(); emit_data( op(branch_op) | annul(a) | cond(c) | op2(br_op2) | wdisp(intptr_t(d), intptr_t(pc()), 22), rt); has_delay_slot(); }
+inline void Assembler::br( Condition c, bool a, Label& L ) { insert_nop_after_cbcond(); br(c, a, target(L)); }
-inline void Assembler::bp( Condition c, bool a, CC cc, Predict p, address d, relocInfo::relocType rt ) { v9_only(); cti(); emit_data( op(branch_op) | annul(a) | cond(c) | op2(bp_op2) | branchcc(cc) | predict(p) | wdisp(intptr_t(d), intptr_t(pc()), 19), rt); has_delay_slot(); }
-inline void Assembler::bp( Condition c, bool a, CC cc, Predict p, Label& L ) { bp(c, a, cc, p, target(L)); }
+inline void Assembler::bp( Condition c, bool a, CC cc, Predict p, address d, relocInfo::relocType rt ) { v9_only(); insert_nop_after_cbcond(); cti(); emit_data( op(branch_op) | annul(a) | cond(c) | op2(bp_op2) | branchcc(cc) | predict(p) | wdisp(intptr_t(d), intptr_t(pc()), 19), rt); has_delay_slot(); }
+inline void Assembler::bp( Condition c, bool a, CC cc, Predict p, Label& L ) { insert_nop_after_cbcond(); bp(c, a, cc, p, target(L)); }
// compare and branch
inline void Assembler::cbcond(Condition c, CC cc, Register s1, Register s2, Label& L) { cti(); no_cbcond_before(); emit_data(op(branch_op) | cond_cbcond(c) | op2(bpr_op2) | branchcc(cc) | wdisp10(intptr_t(target(L)), intptr_t(pc())) | rs1(s1) | rs2(s2)); }
inline void Assembler::cbcond(Condition c, CC cc, Register s1, int simm5, Label& L) { cti(); no_cbcond_before(); emit_data(op(branch_op) | cond_cbcond(c) | op2(bpr_op2) | branchcc(cc) | wdisp10(intptr_t(target(L)), intptr_t(pc())) | rs1(s1) | immed(true) | simm(simm5, 5)); }
-inline void Assembler::call( address d, relocInfo::relocType rt ) { cti(); emit_data( op(call_op) | wdisp(intptr_t(d), intptr_t(pc()), 30), rt); has_delay_slot(); assert(rt != relocInfo::virtual_call_type, "must use virtual_call_Relocation::spec"); }
-inline void Assembler::call( Label& L, relocInfo::relocType rt ) { call( target(L), rt); }
+inline void Assembler::call( address d, relocInfo::relocType rt ) { insert_nop_after_cbcond(); cti(); emit_data( op(call_op) | wdisp(intptr_t(d), intptr_t(pc()), 30), rt); has_delay_slot(); assert(rt != relocInfo::virtual_call_type, "must use virtual_call_Relocation::spec"); }
+inline void Assembler::call( Label& L, relocInfo::relocType rt ) { insert_nop_after_cbcond(); call( target(L), rt); }
inline void Assembler::flush( Register s1, Register s2) { emit_int32( op(arith_op) | op3(flush_op3) | rs1(s1) | rs2(s2)); }
inline void Assembler::flush( Register s1, int simm13a) { emit_data( op(arith_op) | op3(flush_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); }
-inline void Assembler::jmpl( Register s1, Register s2, Register d ) { cti(); emit_int32( op(arith_op) | rd(d) | op3(jmpl_op3) | rs1(s1) | rs2(s2)); has_delay_slot(); }
-inline void Assembler::jmpl( Register s1, int simm13a, Register d, RelocationHolder const& rspec ) { cti(); emit_data( op(arith_op) | rd(d) | op3(jmpl_op3) | rs1(s1) | immed(true) | simm(simm13a, 13), rspec); has_delay_slot(); }
+inline void Assembler::jmpl( Register s1, Register s2, Register d ) { insert_nop_after_cbcond(); cti(); emit_int32( op(arith_op) | rd(d) | op3(jmpl_op3) | rs1(s1) | rs2(s2)); has_delay_slot(); }
+inline void Assembler::jmpl( Register s1, int simm13a, Register d, RelocationHolder const& rspec ) { insert_nop_after_cbcond(); cti(); emit_data( op(arith_op) | rd(d) | op3(jmpl_op3) | rs1(s1) | immed(true) | simm(simm13a, 13), rspec); has_delay_slot(); }
inline void Assembler::ldf(FloatRegisterImpl::Width w, Register s1, Register s2, FloatRegister d) { emit_int32( op(ldst_op) | fd(d, w) | alt_op3(ldf_op3, w) | rs1(s1) | rs2(s2) ); }
inline void Assembler::ldf(FloatRegisterImpl::Width w, Register s1, int simm13a, FloatRegister d, RelocationHolder const& rspec) { emit_data( op(ldst_op) | fd(d, w) | alt_op3(ldf_op3, w) | rs1(s1) | immed(true) | simm(simm13a, 13), rspec); }
--- a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.inline.hpp Fri Apr 11 13:04:59 2014 +0200
+++ b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.inline.hpp Fri Apr 11 15:08:40 2014 -0400
@@ -233,6 +233,7 @@
}
inline void MacroAssembler::br( Condition c, bool a, Predict p, Label& L ) {
+ insert_nop_after_cbcond();
br(c, a, p, target(L));
}
@@ -248,6 +249,7 @@
}
inline void MacroAssembler::brx( Condition c, bool a, Predict p, Label& L ) {
+ insert_nop_after_cbcond();
brx(c, a, p, target(L));
}
@@ -269,6 +271,7 @@
}
inline void MacroAssembler::fb( Condition c, bool a, Predict p, Label& L ) {
+ insert_nop_after_cbcond();
fb(c, a, p, target(L));
}
@@ -318,6 +321,7 @@
}
inline void MacroAssembler::call( Label& L, relocInfo::relocType rt ) {
+ insert_nop_after_cbcond();
MacroAssembler::call( target(L), rt);
}
--- a/hotspot/src/cpu/sparc/vm/sparc.ad Fri Apr 11 13:04:59 2014 +0200
+++ b/hotspot/src/cpu/sparc/vm/sparc.ad Fri Apr 11 15:08:40 2014 -0400
@@ -1268,7 +1268,7 @@
void MachEpilogNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
Compile* C = ra_->C;
- if( do_polling() && ra_->C->is_method_compilation() ) {
+ if(do_polling() && ra_->C->is_method_compilation()) {
st->print("SETHI #PollAddr,L0\t! Load Polling address\n\t");
#ifdef _LP64
st->print("LDX [L0],G0\t!Poll for Safepointing\n\t");
@@ -1277,8 +1277,12 @@
#endif
}
- if( do_polling() )
+ if(do_polling()) {
+ if (UseCBCond && !ra_->C->is_method_compilation()) {
+ st->print("NOP\n\t");
+ }
st->print("RET\n\t");
+ }
st->print("RESTORE");
}
@@ -1291,15 +1295,20 @@
__ verify_thread();
// If this does safepoint polling, then do it here
- if( do_polling() && ra_->C->is_method_compilation() ) {
+ if(do_polling() && ra_->C->is_method_compilation()) {
AddressLiteral polling_page(os::get_polling_page());
__ sethi(polling_page, L0);
__ relocate(relocInfo::poll_return_type);
- __ ld_ptr( L0, 0, G0 );
+ __ ld_ptr(L0, 0, G0);
}
// If this is a return, then stuff the restore in the delay slot
- if( do_polling() ) {
+ if(do_polling()) {
+ if (UseCBCond && !ra_->C->is_method_compilation()) {
+ // Insert extra padding for the case when the epilogue is preceded by
+ // a cbcond jump, which can't be followed by a CTI instruction
+ __ nop();
+ }
__ ret();
__ delayed()->restore();
} else {
@@ -3330,7 +3339,18 @@
//----------Instruction Attributes---------------------------------------------
ins_attrib ins_cost(DEFAULT_COST); // Required cost attribute
ins_attrib ins_size(32); // Required size attribute (in bits)
-ins_attrib ins_avoid_back_to_back(0); // instruction should not be generated back to back
+
+// avoid_back_to_back attribute is an expression that must return
+// one of the following values defined in MachNode:
+// AVOID_NONE - instruction can be placed anywhere
+// AVOID_BEFORE - instruction cannot be placed after an
+// instruction with MachNode::AVOID_AFTER
+// AVOID_AFTER - the next instruction cannot be the one
+// with MachNode::AVOID_BEFORE
+// AVOID_BEFORE_AND_AFTER - BEFORE and AFTER attributes at
+// the same time
+ins_attrib ins_avoid_back_to_back(MachNode::AVOID_NONE);
+
ins_attrib ins_short_branch(0); // Required flag: is this instruction a
// non-matching short branch variant of some
// long branch?
@@ -6630,6 +6650,7 @@
ins_encode %{
__ encode_heap_oop($src$$Register, $dst$$Register);
%}
+ ins_avoid_back_to_back(Universe::narrow_oop_base() == NULL ? AVOID_NONE : AVOID_BEFORE);
ins_pipe(ialu_reg);
%}
@@ -9199,6 +9220,7 @@
__ ba(*L);
__ delayed()->nop();
%}
+ ins_avoid_back_to_back(AVOID_BEFORE);
ins_pipe(br);
%}
@@ -9217,7 +9239,7 @@
__ ba_short(*L);
%}
ins_short_branch(1);
- ins_avoid_back_to_back(1);
+ ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER);
ins_pipe(cbcond_reg_imm);
%}
@@ -9231,6 +9253,7 @@
format %{ "BP$cmp $icc,$labl" %}
// Prim = bits 24-22, Secnd = bits 31-30
ins_encode( enc_bp( labl, cmp, icc ) );
+ ins_avoid_back_to_back(AVOID_BEFORE);
ins_pipe(br_cc);
%}
@@ -9242,6 +9265,7 @@
format %{ "BP$cmp $icc,$labl" %}
// Prim = bits 24-22, Secnd = bits 31-30
ins_encode( enc_bp( labl, cmp, icc ) );
+ ins_avoid_back_to_back(AVOID_BEFORE);
ins_pipe(br_cc);
%}
@@ -9260,6 +9284,7 @@
__ bp( (Assembler::Condition)($cmp$$cmpcode), false, Assembler::ptr_cc, predict_taken, *L);
__ delayed()->nop();
%}
+ ins_avoid_back_to_back(AVOID_BEFORE);
ins_pipe(br_cc);
%}
@@ -9278,6 +9303,7 @@
__ fbp( (Assembler::Condition)($cmp$$cmpcode), false, (Assembler::CC)($fcc$$reg), predict_taken, *L);
__ delayed()->nop();
%}
+ ins_avoid_back_to_back(AVOID_BEFORE);
ins_pipe(br_fcc);
%}
@@ -9290,6 +9316,7 @@
format %{ "BP$cmp $icc,$labl\t! Loop end" %}
// Prim = bits 24-22, Secnd = bits 31-30
ins_encode( enc_bp( labl, cmp, icc ) );
+ ins_avoid_back_to_back(AVOID_BEFORE);
ins_pipe(br_cc);
%}
@@ -9302,6 +9329,7 @@
format %{ "BP$cmp $icc,$labl\t! Loop end" %}
// Prim = bits 24-22, Secnd = bits 31-30
ins_encode( enc_bp( labl, cmp, icc ) );
+ ins_avoid_back_to_back(AVOID_BEFORE);
ins_pipe(br_cc);
%}
@@ -9552,7 +9580,7 @@
__ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, $op2$$Register, *L);
%}
ins_short_branch(1);
- ins_avoid_back_to_back(1);
+ ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER);
ins_pipe(cbcond_reg_reg);
%}
@@ -9570,7 +9598,7 @@
__ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, $op2$$constant, *L);
%}
ins_short_branch(1);
- ins_avoid_back_to_back(1);
+ ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER);
ins_pipe(cbcond_reg_imm);
%}
@@ -9588,7 +9616,7 @@
__ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, $op2$$Register, *L);
%}
ins_short_branch(1);
- ins_avoid_back_to_back(1);
+ ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER);
ins_pipe(cbcond_reg_reg);
%}
@@ -9606,7 +9634,7 @@
__ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, $op2$$constant, *L);
%}
ins_short_branch(1);
- ins_avoid_back_to_back(1);
+ ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER);
ins_pipe(cbcond_reg_imm);
%}
@@ -9624,7 +9652,7 @@
__ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::xcc, $op1$$Register, $op2$$Register, *L);
%}
ins_short_branch(1);
- ins_avoid_back_to_back(1);
+ ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER);
ins_pipe(cbcond_reg_reg);
%}
@@ -9642,7 +9670,7 @@
__ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::xcc, $op1$$Register, $op2$$constant, *L);
%}
ins_short_branch(1);
- ins_avoid_back_to_back(1);
+ ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER);
ins_pipe(cbcond_reg_imm);
%}
@@ -9665,7 +9693,7 @@
__ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::ptr_cc, $op1$$Register, $op2$$Register, *L);
%}
ins_short_branch(1);
- ins_avoid_back_to_back(1);
+ ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER);
ins_pipe(cbcond_reg_reg);
%}
@@ -9687,7 +9715,7 @@
__ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::ptr_cc, $op1$$Register, G0, *L);
%}
ins_short_branch(1);
- ins_avoid_back_to_back(1);
+ ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER);
ins_pipe(cbcond_reg_reg);
%}
@@ -9705,7 +9733,7 @@
__ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, $op2$$Register, *L);
%}
ins_short_branch(1);
- ins_avoid_back_to_back(1);
+ ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER);
ins_pipe(cbcond_reg_reg);
%}
@@ -9723,7 +9751,7 @@
__ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, G0, *L);
%}
ins_short_branch(1);
- ins_avoid_back_to_back(1);
+ ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER);
ins_pipe(cbcond_reg_reg);
%}
@@ -9742,7 +9770,7 @@
__ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, $op2$$Register, *L);
%}
ins_short_branch(1);
- ins_avoid_back_to_back(1);
+ ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER);
ins_pipe(cbcond_reg_reg);
%}
@@ -9760,7 +9788,7 @@
__ cbcond((Assembler::Condition)($cmp$$cmpcode), Assembler::icc, $op1$$Register, $op2$$constant, *L);
%}
ins_short_branch(1);
- ins_avoid_back_to_back(1);
+ ins_avoid_back_to_back(AVOID_BEFORE_AND_AFTER);
ins_pipe(cbcond_reg_imm);
%}
@@ -9777,6 +9805,7 @@
ins_cost(BRANCH_COST);
format %{ "BR$cmp $op1,$labl" %}
ins_encode( enc_bpr( labl, cmp, op1 ) );
+ ins_avoid_back_to_back(AVOID_BEFORE);
ins_pipe(br_reg);
%}
@@ -9789,6 +9818,7 @@
ins_cost(BRANCH_COST);
format %{ "BR$cmp $op1,$labl" %}
ins_encode( enc_bpr( labl, cmp, op1 ) );
+ ins_avoid_back_to_back(AVOID_BEFORE);
ins_pipe(br_reg);
%}
@@ -9801,6 +9831,7 @@
ins_cost(BRANCH_COST);
format %{ "BR$cmp $op1,$labl" %}
ins_encode( enc_bpr( labl, cmp, op1 ) );
+ ins_avoid_back_to_back(AVOID_BEFORE);
ins_pipe(br_reg);
%}
@@ -9841,6 +9872,7 @@
__ bp( (Assembler::Condition)($cmp$$cmpcode), false, Assembler::xcc, predict_taken, *L);
__ delayed()->nop();
%}
+ ins_avoid_back_to_back(AVOID_BEFORE);
ins_pipe(br_cc);
%}
@@ -9968,6 +10000,7 @@
ins_cost(CALL_COST);
format %{ "CALL,static ; NOP ==> " %}
ins_encode( Java_Static_Call( meth ), call_epilog );
+ ins_avoid_back_to_back(AVOID_BEFORE);
ins_pipe(simple_call);
%}
@@ -10004,6 +10037,7 @@
format %{ "CALL,runtime" %}
ins_encode( Java_To_Runtime( meth ),
call_epilog, adjust_long_from_native_call );
+ ins_avoid_back_to_back(AVOID_BEFORE);
ins_pipe(simple_call);
%}
@@ -10016,6 +10050,7 @@
ins_encode( Java_To_Runtime( meth ),
call_epilog,
adjust_long_from_native_call );
+ ins_avoid_back_to_back(AVOID_BEFORE);
ins_pipe(simple_call);
%}
@@ -10028,6 +10063,7 @@
ins_encode( Java_To_Runtime( meth ),
call_epilog,
adjust_long_from_native_call );
+ ins_avoid_back_to_back(AVOID_BEFORE);
ins_pipe(simple_call);
%}
@@ -10041,6 +10077,7 @@
ins_cost(CALL_COST);
format %{ "Jmp $jump_target ; NOP \t! $method_oop holds method oop" %}
ins_encode(form_jmpl(jump_target));
+ ins_avoid_back_to_back(AVOID_BEFORE);
ins_pipe(tail_call);
%}
@@ -10072,6 +10109,7 @@
// opcode(Assembler::jmpl_op3, Assembler::arith_op);
// The hack duplicates the exception oop into G3, so that CreateEx can use it there.
// ins_encode( form3_rs1_simm13_rd( jump_target, 0x00, R_G0 ), move_return_pc_to_o1() );
+ ins_avoid_back_to_back(AVOID_BEFORE);
ins_pipe(tail_call);
%}
@@ -10102,6 +10140,7 @@
// use the following format syntax
format %{ "Jmp rethrow_stub" %}
ins_encode(enc_rethrow);
+ ins_avoid_back_to_back(AVOID_BEFORE);
ins_pipe(tail_call);
%}
@@ -10130,6 +10169,7 @@
ins_cost(DEFAULT_COST*10);
format %{ "CALL PartialSubtypeCheck\n\tNOP" %}
ins_encode( enc_PartialSubtypeCheck() );
+ ins_avoid_back_to_back(AVOID_BEFORE);
ins_pipe(partial_subtype_check_pipe);
%}
@@ -10139,6 +10179,7 @@
ins_cost(DEFAULT_COST*10);
format %{ "CALL PartialSubtypeCheck\n\tNOP\t# (sets condition codes)" %}
ins_encode( enc_PartialSubtypeCheck() );
+ ins_avoid_back_to_back(AVOID_BEFORE);
ins_pipe(partial_subtype_check_pipe);
%}
--- a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/CallSite.java Fri Apr 11 13:04:59 2014 +0200
+++ b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/CallSite.java Fri Apr 11 15:08:40 2014 -0400
@@ -25,6 +25,7 @@
package com.sun.hotspot.tools.compiler;
import java.io.PrintStream;
+import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
@@ -40,6 +41,7 @@
private int endNodes;
private int endLiveNodes;
private double timeStamp;
+ private long inlineId;
CallSite() {
}
@@ -94,7 +96,7 @@
public void print(PrintStream stream, int indent) {
emit(stream, indent);
- String m = getMethod().getHolder().replace('/', '.') + "::" + getMethod().getName();
+ String m = getMethod().getHolder() + "::" + getMethod().getName();
if (getReason() == null) {
stream.print(" @ " + getBci() + " " + m + " (" + getMethod().getBytes() + " bytes)");
@@ -214,4 +216,45 @@
return timeStamp;
}
+ private boolean matches(CallSite other) {
+ // Every late inline call site has a unique inline id. If the
+ // call site we're looking for has one then use it other rely
+ // on method name and bci.
+ if (other.inlineId != 0) {
+ return inlineId == other.inlineId;
+ }
+ return method.equals(other.method) && bci == other.bci;
+ }
+
+ public CallSite findCallSite(ArrayDeque<CallSite> sites) {
+ // Locate a late inline call site. Multiple chains of
+ // identical call sites with the same method name/bci are
+ // possible so we have to try them all until we find the late
+ // inline call site that has a matching inline id.
+ CallSite site = sites.pop();
+ for (CallSite c : calls) {
+ if (c.matches(site)) {
+ if (!sites.isEmpty()) {
+ CallSite res = c.findCallSite(sites);
+ if (res != null) {
+ sites.push(site);
+ return res;
+ }
+ } else {
+ sites.push(site);
+ return c;
+ }
+ }
+ }
+ sites.push(site);
+ return null;
+ }
+
+ public long getInlineId() {
+ return inlineId;
+ }
+
+ public void setInlineId(long inlineId) {
+ this.inlineId = inlineId;
+ }
}
--- a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java Fri Apr 11 13:04:59 2014 +0200
+++ b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java Fri Apr 11 15:08:40 2014 -0400
@@ -31,6 +31,7 @@
import java.io.FileReader;
import java.io.Reader;
+import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -144,9 +145,12 @@
private Stack<CallSite> scopes = new Stack<CallSite>();
private Compilation compile;
private CallSite site;
+ private CallSite methodHandleSite;
private Stack<Phase> phaseStack = new Stack<Phase>();
private UncommonTrapEvent currentTrap;
- private Stack<CallSite> late_inline_scope;
+ private Stack<CallSite> lateInlineScope;
+ private boolean lateInlining;
+
long parseLong(String l) {
try {
@@ -330,18 +334,61 @@
}
methods.put(id, m);
} else if (qname.equals("call")) {
- site = new CallSite(bci, method(search(atts, "method")));
+ if (methodHandleSite != null) {
+ methodHandleSite = null;
+ }
+ Method m = method(search(atts, "method"));
+ if (lateInlining && scopes.size() == 0) {
+ // re-attempting already seen call site (late inlining for MH invokes)
+ if (m != site.getMethod()) {
+ if (bci != site.getBci()) {
+ System.out.println(m + " bci: " + bci);
+ System.out.println(site.getMethod() + " bci: " + site.getBci());
+ throw new InternalError("bci mismatch after late inlining");
+ }
+ site.setMethod(m);
+ }
+ } else {
+ site = new CallSite(bci, m);
+ }
site.setCount(Integer.parseInt(search(atts, "count", "0")));
String receiver = atts.getValue("receiver");
if (receiver != null) {
site.setReceiver(type(receiver));
site.setReceiver_count(Integer.parseInt(search(atts, "receiver_count")));
}
- scopes.peek().add(site);
+ int methodHandle = Integer.parseInt(search(atts, "method_handle_intrinsic", "0"));
+ if (lateInlining && scopes.size() == 0) {
+ // The call was added before this round of late inlining
+ } else if (methodHandle == 0) {
+ scopes.peek().add(site);
+ } else {
+ // method handle call site can be followed by another
+ // call (in case it is inlined). If that happens we
+ // discard the method handle call site. So we keep
+ // track of it but don't add it to the list yet.
+ methodHandleSite = site;
+ }
} else if (qname.equals("regalloc")) {
compile.setAttempts(Integer.parseInt(search(atts, "attempts")));
} else if (qname.equals("inline_fail")) {
- scopes.peek().last().setReason(search(atts, "reason"));
+ if (methodHandleSite != null) {
+ scopes.peek().add(methodHandleSite);
+ methodHandleSite = null;
+ }
+ if (lateInlining && scopes.size() == 0) {
+ site.setReason(search(atts, "reason"));
+ lateInlining = false;
+ } else {
+ scopes.peek().last().setReason(search(atts, "reason"));
+ }
+ } else if (qname.equals("inline_success")) {
+ if (methodHandleSite != null) {
+ throw new InternalError("method handle site should have been replaced");
+ }
+ if (lateInlining && scopes.size() == 0) {
+ site.setReason(null);
+ }
} else if (qname.equals("failure")) {
failureReason = search(atts, "reason");
} else if (qname.equals("task_done")) {
@@ -371,22 +418,30 @@
// ignore for now
}
} else if (qname.equals("late_inline")) {
- late_inline_scope = new Stack<CallSite>();
+ long inlineId = Long.parseLong(search(atts, "inline_id"));
+ lateInlineScope = new Stack<CallSite>();
site = new CallSite(-999, method(search(atts, "method")));
- late_inline_scope.push(site);
+ site.setInlineId(inlineId);
+ lateInlineScope.push(site);
} else if (qname.equals("jvms")) {
// <jvms bci='4' method='java/io/DataInputStream readChar ()C' bytes='40' count='5815' iicount='20815'/>
if (currentTrap != null) {
currentTrap.addJVMS(atts.getValue("method"), Integer.parseInt(atts.getValue("bci")));
- } else if (late_inline_scope != null) {
+ } else if (lateInlineScope != null) {
bci = Integer.parseInt(search(atts, "bci"));
site = new CallSite(bci, method(search(atts, "method")));
- late_inline_scope.push(site);
+ lateInlineScope.push(site);
} else {
// Ignore <eliminate_allocation type='667'>,
// <eliminate_lock lock='1'>,
// <replace_string_concat arguments='2' string_alloc='0' multiple='0'>
}
+ } else if (qname.equals("inline_id")) {
+ if (methodHandleSite != null) {
+ throw new InternalError("method handle site should have been replaced");
+ }
+ long id = Long.parseLong(search(atts, "id"));
+ site.setInlineId(id);
} else if (qname.equals("nmethod")) {
String id = makeId(atts);
NMethod nm = new NMethod(Double.parseDouble(search(atts, "stamp")),
@@ -396,8 +451,18 @@
nmethods.put(id, nm);
events.add(nm);
} else if (qname.equals("parse")) {
+ if (methodHandleSite != null) {
+ throw new InternalError("method handle site should have been replaced");
+ }
Method m = method(search(atts, "method"));
- if (scopes.size() == 0) {
+ if (lateInlining && scopes.size() == 0) {
+ if (site.getMethod() != m) {
+ System.out.println(site.getMethod());
+ System.out.println(m);
+ throw new InternalError("Unexpected method mismatch during late inlining");
+ }
+ }
+ if (scopes.size() == 0 && !lateInlining) {
compile.setMethod(m);
scopes.push(site);
} else {
@@ -427,14 +492,19 @@
if (qname.equals("parse")) {
indent -= 2;
scopes.pop();
+ if (scopes.size() == 0) {
+ lateInlining = false;
+ }
} else if (qname.equals("uncommon_trap")) {
currentTrap = null;
} else if (qname.equals("late_inline")) {
// Populate late inlining info.
-
- // late_inline scopes are specified in reverse order:
+ if (scopes.size() != 0) {
+ throw new InternalError("scopes should be empty for late inline");
+ }
+ // late inline scopes are specified in reverse order:
// compiled method should be on top of stack.
- CallSite caller = late_inline_scope.pop();
+ CallSite caller = lateInlineScope.pop();
Method m = compile.getMethod();
if (m != caller.getMethod()) {
System.out.println(m);
@@ -444,28 +514,42 @@
// late_inline contains caller+bci info, convert it
// to bci+callee info used by LogCompilation.
- site = compile.getLateInlineCall();
+ CallSite lateInlineSite = compile.getLateInlineCall();
+ ArrayDeque<CallSite> thisCallScopes = new ArrayDeque<CallSite>();
do {
bci = caller.getBci();
// Next inlined call.
- caller = late_inline_scope.pop();
+ caller = lateInlineScope.pop();
CallSite callee = new CallSite(bci, caller.getMethod());
- site.add(callee);
- site = callee;
- } while (!late_inline_scope.empty());
+ callee.setInlineId(caller.getInlineId());
+ thisCallScopes.addLast(callee);
+ lateInlineSite.add(callee);
+ lateInlineSite = callee;
+ } while (!lateInlineScope.empty());
+
+ site = compile.getCall().findCallSite(thisCallScopes);
+ if (site == null) {
+ System.out.println(caller.getMethod() + " bci: " + bci);
+ throw new InternalError("couldn't find call site");
+ }
+ lateInlining = true;
if (caller.getBci() != -999) {
System.out.println(caller.getMethod());
throw new InternalError("broken late_inline info");
}
if (site.getMethod() != caller.getMethod()) {
- System.out.println(site.getMethod());
- System.out.println(caller.getMethod());
- throw new InternalError("call site and late_inline info don't match");
+ if (site.getInlineId() == caller.getInlineId()) {
+ site.setMethod(caller.getMethod());
+ } else {
+ System.out.println(site.getMethod());
+ System.out.println(caller.getMethod());
+ throw new InternalError("call site and late_inline info don't match");
+ }
}
// late_inline is followed by parse with scopes.size() == 0,
// 'site' will be pushed to scopes.
- late_inline_scope = null;
+ lateInlineScope = null;
} else if (qname.equals("task")) {
types.clear();
methods.clear();
--- a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/Method.java Fri Apr 11 13:04:59 2014 +0200
+++ b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/Method.java Fri Apr 11 15:08:40 2014 -0400
@@ -51,15 +51,15 @@
String format(int osr_bci) {
if (osr_bci >= 0) {
- return getHolder().replace('/', '.') + "::" + getName() + " @ " + osr_bci + " (" + getBytes() + " bytes)";
+ return getHolder() + "::" + getName() + " @ " + osr_bci + " (" + getBytes() + " bytes)";
} else {
- return getHolder().replace('/', '.') + "::" + getName() + " (" + getBytes() + " bytes)";
+ return getHolder() + "::" + getName() + " (" + getBytes() + " bytes)";
}
}
@Override
public String toString() {
- return getHolder().replace('/', '.') + "::" + getName() + " (" + getBytes() + " bytes)";
+ return getHolder() + "::" + getName() + " (" + getBytes() + " bytes)";
}
public String getHolder() {
@@ -117,4 +117,14 @@
public void setFlags(String flags) {
this.flags = flags;
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof Method) {
+ Method other = (Method)o;
+ return holder.equals(other.holder) && name.equals(other.name) &&
+ arguments.equals(other.arguments) && returnType.equals(other.returnType);
+ }
+ return false;
+ }
}
--- a/hotspot/src/share/vm/adlc/output_h.cpp Fri Apr 11 13:04:59 2014 +0200
+++ b/hotspot/src/share/vm/adlc/output_h.cpp Fri Apr 11 15:08:40 2014 -0400
@@ -1613,21 +1613,20 @@
// Each instruction attribute results in a virtual call of same name.
// The ins_cost is not handled here.
Attribute *attr = instr->_attribs;
- bool avoid_back_to_back = false;
+ Attribute *avoid_back_to_back_attr = NULL;
while (attr != NULL) {
- if (strcmp (attr->_ident, "ins_cost") != 0 &&
+ if (strcmp (attr->_ident, "ins_is_TrapBasedCheckNode") == 0) {
+ fprintf(fp, " virtual bool is_TrapBasedCheckNode() const { return %s; }\n", attr->_val);
+ } else if (strcmp (attr->_ident, "ins_cost") != 0 &&
strncmp(attr->_ident, "ins_field_", 10) != 0 &&
// Must match function in node.hpp: return type bool, no prefix "ins_".
strcmp (attr->_ident, "ins_is_TrapBasedCheckNode") != 0 &&
strcmp (attr->_ident, "ins_short_branch") != 0) {
fprintf(fp, " virtual int %s() const { return %s; }\n", attr->_ident, attr->_val);
}
- // Check value for ins_avoid_back_to_back, and if it is true (1), set the flag
- if (!strcmp(attr->_ident, "ins_avoid_back_to_back") != 0 && attr->int_val(*this) != 0)
- avoid_back_to_back = true;
- if (strcmp (attr->_ident, "ins_is_TrapBasedCheckNode") == 0)
- fprintf(fp, " virtual bool is_TrapBasedCheckNode() const { return %s; }\n", attr->_val);
-
+ if (strcmp(attr->_ident, "ins_avoid_back_to_back") == 0) {
+ avoid_back_to_back_attr = attr;
+ }
attr = (Attribute *)attr->_next;
}
@@ -1799,11 +1798,11 @@
}
// flag: if this instruction should not be generated back to back.
- if ( avoid_back_to_back ) {
- if ( node_flags_set ) {
- fprintf(fp," | Flag_avoid_back_to_back");
+ if (avoid_back_to_back_attr != NULL) {
+ if (node_flags_set) {
+ fprintf(fp," | (%s)", avoid_back_to_back_attr->_val);
} else {
- fprintf(fp,"init_flags(Flag_avoid_back_to_back");
+ fprintf(fp,"init_flags((%s)", avoid_back_to_back_attr->_val);
node_flags_set = true;
}
}
--- a/hotspot/src/share/vm/asm/codeBuffer.cpp Fri Apr 11 13:04:59 2014 +0200
+++ b/hotspot/src/share/vm/asm/codeBuffer.cpp Fri Apr 11 15:08:40 2014 -0400
@@ -968,6 +968,7 @@
void CodeBuffer::log_section_sizes(const char* name) {
if (xtty != NULL) {
+ ttyLocker ttyl;
// log info about buffer usage
xtty->print_cr("<blob name='%s' size='%d'>", name, _total_size);
for (int n = (int) CodeBuffer::SECT_FIRST; n < (int) CodeBuffer::SECT_LIMIT; n++) {
--- a/hotspot/src/share/vm/ci/ciKlass.cpp Fri Apr 11 13:04:59 2014 +0200
+++ b/hotspot/src/share/vm/ci/ciKlass.cpp Fri Apr 11 15:08:40 2014 -0400
@@ -237,3 +237,9 @@
void ciKlass::print_name_on(outputStream* st) {
name()->print_symbol_on(st);
}
+
+const char* ciKlass::external_name() const {
+ GUARDED_VM_ENTRY(
+ return get_Klass()->external_name();
+ )
+}
--- a/hotspot/src/share/vm/ci/ciKlass.hpp Fri Apr 11 13:04:59 2014 +0200
+++ b/hotspot/src/share/vm/ci/ciKlass.hpp Fri Apr 11 15:08:40 2014 -0400
@@ -125,6 +125,8 @@
virtual ciKlass* exact_klass() = 0;
void print_name_on(outputStream* st);
+
+ const char* external_name() const;
};
#endif // SHARE_VM_CI_CIKLASS_HPP
--- a/hotspot/src/share/vm/ci/ciSymbol.cpp Fri Apr 11 13:04:59 2014 +0200
+++ b/hotspot/src/share/vm/ci/ciSymbol.cpp Fri Apr 11 15:08:40 2014 -0400
@@ -123,6 +123,10 @@
GUARDED_VM_ENTRY(get_symbol()->print_symbol_on(st);)
}
+const char* ciSymbol::as_klass_external_name() const {
+ GUARDED_VM_ENTRY(return get_symbol()->as_klass_external_name(););
+}
+
// ------------------------------------------------------------------
// ciSymbol::make_impl
//
--- a/hotspot/src/share/vm/ci/ciSymbol.hpp Fri Apr 11 13:04:59 2014 +0200
+++ b/hotspot/src/share/vm/ci/ciSymbol.hpp Fri Apr 11 15:08:40 2014 -0400
@@ -90,6 +90,7 @@
void print_symbol() {
print_symbol_on(tty);
}
+ const char* as_klass_external_name() const;
// Make a ciSymbol from a C string.
// Consider adding to vmSymbols.hpp instead of using this constructor.
--- a/hotspot/src/share/vm/compiler/compileLog.cpp Fri Apr 11 13:04:59 2014 +0200
+++ b/hotspot/src/share/vm/compiler/compileLog.cpp Fri Apr 11 15:08:40 2014 -0400
@@ -106,7 +106,7 @@
if (mobj->is_klass()) {
ciKlass* klass = mobj->as_klass();
begin_elem("klass id='%d'", id);
- name(klass->name());
+ name(klass);
if (!klass->is_loaded()) {
print(" unloaded='1'");
} else {
@@ -171,6 +171,15 @@
print("'");
}
+void CompileLog::name(ciKlass* k) {
+ print(" name='");
+ if (!k->is_loaded()) {
+ text()->print(k->name()->as_klass_external_name());
+ } else {
+ text()->print(k->external_name());
+ }
+ print("'");
+}
// ------------------------------------------------------------------
// CompileLog::clear_identities
--- a/hotspot/src/share/vm/compiler/compileLog.hpp Fri Apr 11 13:04:59 2014 +0200
+++ b/hotspot/src/share/vm/compiler/compileLog.hpp Fri Apr 11 15:08:40 2014 -0400
@@ -28,6 +28,7 @@
#include "utilities/xmlstream.hpp"
class ciBaseObject;
+class ciKlass;
class ciObject;
class ciMetadata;
class ciSymbol;
@@ -72,6 +73,7 @@
void name(ciSymbol* s); // name='s'
void name(Symbol* s) { xmlStream::name(s); }
+ void name(ciKlass* k);
// Output an object description, return obj->ident().
int identify(ciBaseObject* obj);
--- a/hotspot/src/share/vm/opto/callGenerator.cpp Fri Apr 11 13:04:59 2014 +0200
+++ b/hotspot/src/share/vm/opto/callGenerator.cpp Fri Apr 11 15:08:40 2014 -0400
@@ -266,14 +266,17 @@
// Allow inlining decisions to be delayed
class LateInlineCallGenerator : public DirectCallGenerator {
+ private:
+ // unique id for log compilation
+ jlong _unique_id;
+
protected:
CallGenerator* _inline_cg;
-
virtual bool do_late_inline_check(JVMState* jvms) { return true; }
public:
LateInlineCallGenerator(ciMethod* method, CallGenerator* inline_cg) :
- DirectCallGenerator(method, true), _inline_cg(inline_cg) {}
+ DirectCallGenerator(method, true), _inline_cg(inline_cg), _unique_id(0) {}
virtual bool is_late_inline() const { return true; }
@@ -283,6 +286,8 @@
virtual JVMState* generate(JVMState* jvms, Parse* parent_parser) {
Compile *C = Compile::current();
+ C->log_inline_id(this);
+
// Record that this call site should be revisited once the main
// parse is finished.
if (!is_mh_late_inline()) {
@@ -304,6 +309,14 @@
C->print_inlining_move_to(this);
C->print_inlining_update_delayed(this);
}
+
+ virtual void set_unique_id(jlong id) {
+ _unique_id = id;
+ }
+
+ virtual jlong unique_id() const {
+ return _unique_id;
+ }
};
void LateInlineCallGenerator::do_late_inline() {
@@ -368,6 +381,8 @@
C->print_inlining_move_to(this);
+ C->log_late_inline(this);
+
// This check is done here because for_method_handle_inline() method
// needs jvms for inlined state.
if (!do_late_inline_check(jvms)) {
@@ -375,17 +390,6 @@
return;
}
- CompileLog* log = C->log();
- if (log != NULL) {
- log->head("late_inline method='%d'", log->identify(method()));
- JVMState* p = jvms;
- while (p != NULL) {
- log->elem("jvms bci='%d' method='%d'", p->bci(), log->identify(p->method()));
- p = p->caller();
- }
- log->tail("late_inline");
- }
-
// Setup default node notes to be picked up by the inlining
Node_Notes* old_nn = C->default_node_notes();
if (old_nn != NULL) {
@@ -438,11 +442,12 @@
virtual JVMState* generate(JVMState* jvms, Parse* parent_parser) {
JVMState* new_jvms = LateInlineCallGenerator::generate(jvms, parent_parser);
+ Compile* C = Compile::current();
if (_input_not_const) {
// inlining won't be possible so no need to enqueue right now.
call_node()->set_generator(this);
} else {
- Compile::current()->add_late_inline(this);
+ C->add_late_inline(this);
}
return new_jvms;
}
@@ -483,6 +488,9 @@
virtual JVMState* generate(JVMState* jvms, Parse* parent_parser) {
Compile *C = Compile::current();
+
+ C->log_inline_id(this);
+
C->add_string_late_inline(this);
JVMState* new_jvms = DirectCallGenerator::generate(jvms, parent_parser);
@@ -505,6 +513,8 @@
virtual JVMState* generate(JVMState* jvms, Parse* parent_parser) {
Compile *C = Compile::current();
+ C->log_inline_id(this);
+
C->add_boxing_late_inline(this);
JVMState* new_jvms = DirectCallGenerator::generate(jvms, parent_parser);
@@ -786,6 +796,7 @@
} else {
const char* msg = "receiver not constant";
if (PrintInlining) C->print_inlining(callee, jvms->depth() - 1, jvms->bci(), msg);
+ C->log_inline_failure(msg);
}
}
break;
@@ -858,6 +869,7 @@
} else {
const char* msg = "member_name not constant";
if (PrintInlining) C->print_inlining(callee, jvms->depth() - 1, jvms->bci(), msg);
+ C->log_inline_failure(msg);
}
}
break;
--- a/hotspot/src/share/vm/opto/callGenerator.hpp Fri Apr 11 13:04:59 2014 +0200
+++ b/hotspot/src/share/vm/opto/callGenerator.hpp Fri Apr 11 15:08:40 2014 -0400
@@ -84,6 +84,9 @@
virtual CallStaticJavaNode* call_node() const { ShouldNotReachHere(); return NULL; }
+ virtual void set_unique_id(jlong id) { fatal("unique id only for late inlines"); };
+ virtual jlong unique_id() const { fatal("unique id only for late inlines"); return 0; };
+
// Note: It is possible for a CG to be both inline and virtual.
// (The hashCode intrinsic does a vtable check and an inlined fast path.)
--- a/hotspot/src/share/vm/opto/compile.cpp Fri Apr 11 13:04:59 2014 +0200
+++ b/hotspot/src/share/vm/opto/compile.cpp Fri Apr 11 15:08:40 2014 -0400
@@ -3851,7 +3851,7 @@
void Compile::dump_inlining() {
bool do_print_inlining = print_inlining() || print_intrinsics();
- if (do_print_inlining) {
+ if (do_print_inlining || log() != NULL) {
// Print inlining message for candidates that we couldn't inline
// for lack of space
for (int i = 0; i < _late_inlines.length(); i++) {
@@ -3861,6 +3861,7 @@
if (do_print_inlining) {
cg->print_inlining_late(msg);
}
+ log_late_inline_failure(cg, msg);
}
}
}
@@ -3871,6 +3872,48 @@
}
}
+void Compile::log_late_inline(CallGenerator* cg) {
+ if (log() != NULL) {
+ log()->head("late_inline method='%d' inline_id='" JLONG_FORMAT "'", log()->identify(cg->method()),
+ cg->unique_id());
+ JVMState* p = cg->call_node()->jvms();
+ while (p != NULL) {
+ log()->elem("jvms bci='%d' method='%d'", p->bci(), log()->identify(p->method()));
+ p = p->caller();
+ }
+ log()->tail("late_inline");
+ }
+}
+
+void Compile::log_late_inline_failure(CallGenerator* cg, const char* msg) {
+ log_late_inline(cg);
+ if (log() != NULL) {
+ log()->inline_fail(msg);
+ }
+}
+
+void Compile::log_inline_id(CallGenerator* cg) {
+ if (log() != NULL) {
+ // The LogCompilation tool needs a unique way to identify late
+ // inline call sites. This id must be unique for this call site in
+ // this compilation. Try to have it unique across compilations as
+ // well because it can be convenient when grepping through the log
+ // file.
+ // Distinguish OSR compilations from others in case CICountOSR is
+ // on.
+ jlong id = ((jlong)unique()) + (((jlong)compile_id()) << 33) + (CICountOSR && is_osr_compilation() ? ((jlong)1) << 32 : 0);
+ cg->set_unique_id(id);
+ log()->elem("inline_id id='" JLONG_FORMAT "'", id);
+ }
+}
+
+void Compile::log_inline_failure(const char* msg) {
+ if (C->log() != NULL) {
+ C->log()->inline_fail(msg);
+ }
+}
+
+
// Dump inlining replay data to the stream.
// Don't change thread state and acquire any locks.
void Compile::dump_inline_data(outputStream* out) {
@@ -4048,8 +4091,8 @@
worklist.push(root());
for (uint next = 0; next < worklist.size(); ++next) {
Node *n = worklist.at(next);
- const Type* t = igvn.type(n);
- assert(t == t->remove_speculative(), "no more speculative types");
+ const Type* t = igvn.type_or_null(n);
+ assert((t == NULL) || (t == t->remove_speculative()), "no more speculative types");
if (n->is_Type()) {
t = n->as_Type()->type();
assert(t == t->remove_speculative(), "no more speculative types");
--- a/hotspot/src/share/vm/opto/compile.hpp Fri Apr 11 13:04:59 2014 +0200
+++ b/hotspot/src/share/vm/opto/compile.hpp Fri Apr 11 15:08:40 2014 -0400
@@ -440,6 +440,8 @@
void print_inlining_push();
PrintInliningBuffer& print_inlining_current();
+ void log_late_inline_failure(CallGenerator* cg, const char* msg);
+
public:
outputStream* print_inlining_stream() const {
@@ -459,6 +461,10 @@
print_inlining_stream()->print(ss.as_string());
}
+ void log_late_inline(CallGenerator* cg);
+ void log_inline_id(CallGenerator* cg);
+ void log_inline_failure(const char* msg);
+
void* replay_inline_data() const { return _replay_inline_data; }
// Dump inlining replay data to the stream.
--- a/hotspot/src/share/vm/opto/doCall.cpp Fri Apr 11 13:04:59 2014 +0200
+++ b/hotspot/src/share/vm/opto/doCall.cpp Fri Apr 11 15:08:40 2014 -0400
@@ -104,6 +104,9 @@
log->print(" receiver2='%d' receiver2_count='%d'", r2id, profile.receiver_count(1));
}
}
+ if (callee->is_method_handle_intrinsic()) {
+ log->print(" method_handle_intrinsic='1'");
+ }
log->end_elem();
}
@@ -296,6 +299,7 @@
if (call_does_dispatch) {
const char* msg = "virtual call";
if (PrintInlining) print_inlining(callee, jvms->depth() - 1, jvms->bci(), msg);
+ C->log_inline_failure(msg);
return CallGenerator::for_virtual_call(callee, vtable_index);
} else {
// Class Hierarchy Analysis or Type Profile reveals a unique target,
--- a/hotspot/src/share/vm/opto/machnode.hpp Fri Apr 11 13:04:59 2014 +0200
+++ b/hotspot/src/share/vm/opto/machnode.hpp Fri Apr 11 15:08:40 2014 -0400
@@ -210,7 +210,14 @@
bool may_be_short_branch() const { return (flags() & Flag_may_be_short_branch) != 0; }
// Avoid back to back some instructions on some CPUs.
- bool avoid_back_to_back() const { return (flags() & Flag_avoid_back_to_back) != 0; }
+ enum AvoidBackToBackFlag { AVOID_NONE = 0,
+ AVOID_BEFORE = Flag_avoid_back_to_back_before,
+ AVOID_AFTER = Flag_avoid_back_to_back_after,
+ AVOID_BEFORE_AND_AFTER = AVOID_BEFORE | AVOID_AFTER };
+
+ bool avoid_back_to_back(AvoidBackToBackFlag flag_value) const {
+ return (flags() & flag_value) == flag_value;
+ }
// instruction implemented with a call
bool has_call() const { return (flags() & Flag_has_call) != 0; }
--- a/hotspot/src/share/vm/opto/node.hpp Fri Apr 11 13:04:59 2014 +0200
+++ b/hotspot/src/share/vm/opto/node.hpp Fri Apr 11 15:08:40 2014 -0400
@@ -645,17 +645,18 @@
// Flags are sorted by usage frequency.
enum NodeFlags {
- Flag_is_Copy = 0x01, // should be first bit to avoid shift
- Flag_rematerialize = Flag_is_Copy << 1,
+ Flag_is_Copy = 0x01, // should be first bit to avoid shift
+ Flag_rematerialize = Flag_is_Copy << 1,
Flag_needs_anti_dependence_check = Flag_rematerialize << 1,
- Flag_is_macro = Flag_needs_anti_dependence_check << 1,
- Flag_is_Con = Flag_is_macro << 1,
- Flag_is_cisc_alternate = Flag_is_Con << 1,
- Flag_is_dead_loop_safe = Flag_is_cisc_alternate << 1,
- Flag_may_be_short_branch = Flag_is_dead_loop_safe << 1,
- Flag_avoid_back_to_back = Flag_may_be_short_branch << 1,
- Flag_has_call = Flag_avoid_back_to_back << 1,
- Flag_is_expensive = Flag_has_call << 1,
+ Flag_is_macro = Flag_needs_anti_dependence_check << 1,
+ Flag_is_Con = Flag_is_macro << 1,
+ Flag_is_cisc_alternate = Flag_is_Con << 1,
+ Flag_is_dead_loop_safe = Flag_is_cisc_alternate << 1,
+ Flag_may_be_short_branch = Flag_is_dead_loop_safe << 1,
+ Flag_avoid_back_to_back_before = Flag_may_be_short_branch << 1,
+ Flag_avoid_back_to_back_after = Flag_avoid_back_to_back_before << 1,
+ Flag_has_call = Flag_avoid_back_to_back_after << 1,
+ Flag_is_expensive = Flag_has_call << 1,
_max_flags = (Flag_is_expensive << 1) - 1 // allow flags combination
};
--- a/hotspot/src/share/vm/opto/output.cpp Fri Apr 11 13:04:59 2014 +0200
+++ b/hotspot/src/share/vm/opto/output.cpp Fri Apr 11 15:08:40 2014 -0400
@@ -411,7 +411,7 @@
blk_size += nop_size;
}
}
- if (mach->avoid_back_to_back()) {
+ if (mach->avoid_back_to_back(MachNode::AVOID_BEFORE)) {
// Nop is inserted between "avoid back to back" instructions.
// ScheduleAndBundle() can rearrange nodes in a block,
// check for all offsets inside this block.
@@ -439,7 +439,7 @@
last_call_adr = blk_starts[i]+blk_size;
}
// Remember end of avoid_back_to_back offset
- if (nj->is_Mach() && nj->as_Mach()->avoid_back_to_back()) {
+ if (nj->is_Mach() && nj->as_Mach()->avoid_back_to_back(MachNode::AVOID_AFTER)) {
last_avoid_back_to_back_adr = blk_starts[i]+blk_size;
}
}
@@ -525,11 +525,11 @@
int new_size = replacement->size(_regalloc);
int diff = br_size - new_size;
assert(diff >= (int)nop_size, "short_branch size should be smaller");
- // Conservatively take into accound padding between
+ // Conservatively take into account padding between
// avoid_back_to_back branches. Previous branch could be
// converted into avoid_back_to_back branch during next
// rounds.
- if (needs_padding && replacement->avoid_back_to_back()) {
+ if (needs_padding && replacement->avoid_back_to_back(MachNode::AVOID_BEFORE)) {
jmp_offset[i] += nop_size;
diff -= nop_size;
}
@@ -548,7 +548,7 @@
}
} // (mach->may_be_short_branch())
if (mach != NULL && (mach->may_be_short_branch() ||
- mach->avoid_back_to_back())) {
+ mach->avoid_back_to_back(MachNode::AVOID_AFTER))) {
last_may_be_short_branch_adr = blk_starts[i] + jmp_offset[i] + jmp_size[i];
}
blk_starts[i+1] -= adjust_block_start;
@@ -1313,7 +1313,7 @@
if (is_sfn && !is_mcall && padding == 0 && current_offset == last_call_offset) {
padding = nop_size;
}
- if (padding == 0 && mach->avoid_back_to_back() &&
+ if (padding == 0 && mach->avoid_back_to_back(MachNode::AVOID_BEFORE) &&
current_offset == last_avoid_back_to_back_offset) {
// Avoid back to back some instructions.
padding = nop_size;
@@ -1407,7 +1407,7 @@
int new_size = replacement->size(_regalloc);
assert((br_size - new_size) >= (int)nop_size, "short_branch size should be smaller");
// Insert padding between avoid_back_to_back branches.
- if (needs_padding && replacement->avoid_back_to_back()) {
+ if (needs_padding && replacement->avoid_back_to_back(MachNode::AVOID_BEFORE)) {
MachNode *nop = new (this) MachNopNode();
block->insert_node(nop, j++);
_cfg->map_node_to_block(nop, block);
@@ -1515,7 +1515,7 @@
last_call_offset = current_offset;
}
- if (n->is_Mach() && n->as_Mach()->avoid_back_to_back()) {
+ if (n->is_Mach() && n->as_Mach()->avoid_back_to_back(MachNode::AVOID_AFTER)) {
// Avoid back to back some instructions.
last_avoid_back_to_back_offset = current_offset;
}
--- a/hotspot/src/share/vm/opto/phaseX.cpp Fri Apr 11 13:04:59 2014 +0200
+++ b/hotspot/src/share/vm/opto/phaseX.cpp Fri Apr 11 15:08:40 2014 -0400
@@ -1514,6 +1514,21 @@
C->set_root( transform(C->root())->as_Root() );
assert( C->top(), "missing TOP node" );
assert( C->root(), "missing root" );
+
+ // Eagerly remove castPP nodes here. CastPP nodes might not be
+ // removed in the subsequent IGVN phase if a node that changes
+ // in(1) of a castPP is processed prior to the castPP node.
+ for (uint i = 0; i < _worklist.size(); i++) {
+ Node* n = _worklist.at(i);
+
+ if (n->is_ConstraintCast()) {
+ Node* nn = n->Identity(this);
+ if (nn != n) {
+ replace_node(n, nn);
+ --i;
+ }
+ }
+ }
}
//------------------------------transform--------------------------------------
--- a/hotspot/src/share/vm/utilities/growableArray.hpp Fri Apr 11 13:04:59 2014 +0200
+++ b/hotspot/src/share/vm/utilities/growableArray.hpp Fri Apr 11 15:08:40 2014 -0400
@@ -147,6 +147,9 @@
}
};
+template<class E> class GrowableArrayIterator;
+template<class E, class UnaryPredicate> class GrowableArrayFilterIterator;
+
template<class E> class GrowableArray : public GenericGrowableArray {
friend class VMStructs;
@@ -243,6 +246,14 @@
return _data[_len-1];
}
+ GrowableArrayIterator<E> begin() const {
+ return GrowableArrayIterator<E>(this, 0);
+ }
+
+ GrowableArrayIterator<E> end() const {
+ return GrowableArrayIterator<E>(this, length());
+ }
+
void push(const E& elem) { append(elem); }
E pop() {
@@ -412,4 +423,83 @@
tty->print("}\n");
}
+// Custom STL-style iterator to iterate over GrowableArrays
+// It is constructed by invoking GrowableArray::begin() and GrowableArray::end()
+template<class E> class GrowableArrayIterator : public StackObj {
+ friend class GrowableArray<E>;
+ template<class F, class UnaryPredicate> friend class GrowableArrayFilterIterator;
+
+ private:
+ const GrowableArray<E>* _array; // GrowableArray we iterate over
+ int _position; // The current position in the GrowableArray
+
+ // Private constructor used in GrowableArray::begin() and GrowableArray::end()
+ GrowableArrayIterator(const GrowableArray<E>* array, int position) : _array(array), _position(position) {
+ assert(0 <= position && position <= _array->length(), "illegal position");
+ }
+
+ public:
+ GrowableArrayIterator<E>& operator++() { ++_position; return *this; }
+ E operator*() { return _array->at(_position); }
+
+ bool operator==(const GrowableArrayIterator<E>& rhs) {
+ assert(_array == rhs._array, "iterator belongs to different array");
+ return _position == rhs._position;
+ }
+
+ bool operator!=(const GrowableArrayIterator<E>& rhs) {
+ assert(_array == rhs._array, "iterator belongs to different array");
+ return _position != rhs._position;
+ }
+};
+
+// Custom STL-style iterator to iterate over elements of a GrowableArray that satisfy a given predicate
+template<class E, class UnaryPredicate> class GrowableArrayFilterIterator : public StackObj {
+ friend class GrowableArray<E>;
+
+ private:
+ const GrowableArray<E>* _array; // GrowableArray we iterate over
+ int _position; // Current position in the GrowableArray
+ UnaryPredicate _predicate; // Unary predicate the elements of the GrowableArray should satisfy
+
+ public:
+ GrowableArrayFilterIterator(const GrowableArrayIterator<E>& begin, UnaryPredicate filter_predicate)
+ : _array(begin._array), _position(begin._position), _predicate(filter_predicate) {
+ // Advance to first element satisfying the predicate
+ while(_position != _array->length() && !_predicate(_array->at(_position))) {
+ ++_position;
+ }
+ }
+
+ GrowableArrayFilterIterator<E, UnaryPredicate>& operator++() {
+ do {
+ // Advance to next element satisfying the predicate
+ ++_position;
+ } while(_position != _array->length() && !_predicate(_array->at(_position)));
+ return *this;
+ }
+
+ E operator*() { return _array->at(_position); }
+
+ bool operator==(const GrowableArrayIterator<E>& rhs) {
+ assert(_array == rhs._array, "iterator belongs to different array");
+ return _position == rhs._position;
+ }
+
+ bool operator!=(const GrowableArrayIterator<E>& rhs) {
+ assert(_array == rhs._array, "iterator belongs to different array");
+ return _position != rhs._position;
+ }
+
+ bool operator==(const GrowableArrayFilterIterator<E, UnaryPredicate>& rhs) {
+ assert(_array == rhs._array, "iterator belongs to different array");
+ return _position == rhs._position;
+ }
+
+ bool operator!=(const GrowableArrayFilterIterator<E, UnaryPredicate>& rhs) {
+ assert(_array == rhs._array, "iterator belongs to different array");
+ return _position != rhs._position;
+ }
+};
+
#endif // SHARE_VM_UTILITIES_GROWABLEARRAY_HPP
--- a/hotspot/src/share/vm/utilities/xmlstream.cpp Fri Apr 11 13:04:59 2014 +0200
+++ b/hotspot/src/share/vm/utilities/xmlstream.cpp Fri Apr 11 15:08:40 2014 -0400
@@ -396,10 +396,10 @@
}
void xmlStream::method_text(methodHandle method) {
+ ResourceMark rm;
assert_if_no_error(inside_attrs(), "printing attributes");
if (method.is_null()) return;
- //method->print_short_name(text());
- method->method_holder()->name()->print_symbol_on(text());
+ text()->print(method->method_holder()->external_name());
print_raw(" "); // " " is easier for tools to parse than "::"
method->name()->print_symbol_on(text());
print_raw(" "); // separator
--- a/hotspot/test/TEST.groups Fri Apr 11 13:04:59 2014 +0200
+++ b/hotspot/test/TEST.groups Fri Apr 11 15:08:40 2014 -0400
@@ -134,7 +134,8 @@
runtime/InternalApi/ThreadCpuTimesDeadlock.java \
serviceability/threads/TestFalseDeadLock.java \
compiler/tiered/NonTieredLevelsTest.java \
- compiler/tiered/TieredLevelsTest.java
+ compiler/tiered/TieredLevelsTest.java \
+ compiler/intrinsics/bmi/verifycode
# Compact 2 adds full VM tests
compact2 = \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/AddnTestI.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8031321
+ * @library /testlibrary /testlibrary/whitebox /compiler/whitebox ..
+ * @build AddnTestI
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ * -XX:+IgnoreUnrecognizedVMOptions -XX:+UseBMI1Instructions AddnTestI
+ */
+
+import java.lang.reflect.Method;
+
+public class AddnTestI extends BmiIntrinsicBase.BmiTestCase {
+
+ protected AddnTestI(Method method) {
+ super(method);
+ // from intel manual VEX.NDS.LZ.0F38.W0 F2 /r, example c4e260f2c2
+ instrMask = new byte[]{
+ (byte) 0xFF,
+ (byte) 0x1F,
+ (byte) 0x00,
+ (byte) 0xFF};
+ instrPattern = new byte[]{
+ (byte) 0xC4, // prefix for 3-byte VEX instruction
+ (byte) 0x02, // 00010 implied 0F 38 leading opcode bytes
+ (byte) 0x00,
+ (byte) 0xF2};
+ }
+
+ public static void main(String[] args) throws Exception {
+ BmiIntrinsicBase.verifyTestCase(AddnTestI::new, TestAndnI.AndnIExpr.class.getDeclaredMethods());
+ BmiIntrinsicBase.verifyTestCase(AddnTestI::new, TestAndnI.AndnICommutativeExpr.class.getDeclaredMethods());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/AddnTestL.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8031321
+ * @library /testlibrary /testlibrary/whitebox /compiler/whitebox ..
+ * @build AddnTestL
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ * -XX:+IgnoreUnrecognizedVMOptions -XX:+UseBMI1Instructions AddnTestL
+ */
+
+import java.lang.reflect.Method;
+
+public class AddnTestL extends AddnTestI {
+
+ protected AddnTestL(Method method) {
+ super(method);
+ isLongOperation = true;
+ }
+
+ public static void main(String[] args) throws Exception {
+ BmiIntrinsicBase.verifyTestCase(AddnTestL::new, TestAndnL.AndnLExpr.class.getDeclaredMethods());
+ BmiIntrinsicBase.verifyTestCase(AddnTestL::new, TestAndnL.AndnLCommutativeExpr.class.getDeclaredMethods());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsiTestI.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8031321
+ * @library /testlibrary /testlibrary/whitebox /compiler/whitebox ..
+ * @build BlsiTestI
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ * -XX:+IgnoreUnrecognizedVMOptions -XX:+UseBMI1Instructions BlsiTestI
+ */
+
+import java.lang.reflect.Method;
+
+public class BlsiTestI extends BmiIntrinsicBase.BmiTestCase {
+
+ protected BlsiTestI(Method method) {
+ super(method);
+ //from intel manual VEX.NDD.LZ.0F38.W0 F3 /3
+ instrMask = new byte[]{
+ (byte) 0xFF,
+ (byte) 0x1F,
+ (byte) 0x00,
+ (byte) 0xFF,
+ (byte) 0b0011_1000};
+ instrPattern = new byte[]{
+ (byte) 0xC4, // prefix for 3-byte VEX instruction
+ (byte) 0x02, // 00010 implied 0F 38 leading opcode bytes
+ (byte) 0x00,
+ (byte) 0xF3,
+ (byte) 0b0001_1000}; // bits 543 == 011 (3)
+ }
+
+ public static void main(String[] args) throws Exception {
+ BmiIntrinsicBase.verifyTestCase(BlsiTestI::new, TestBlsiI.BlsiIExpr.class.getDeclaredMethods());
+ BmiIntrinsicBase.verifyTestCase(BlsiTestI::new, TestBlsiI.BlsiICommutativeExpr.class.getDeclaredMethods());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsiTestL.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8031321
+ * @library /testlibrary /testlibrary/whitebox /compiler/whitebox ..
+ * @build BlsiTestL
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ * -XX:+IgnoreUnrecognizedVMOptions -XX:+UseBMI1Instructions BlsiTestL
+ */
+
+import java.lang.reflect.Method;
+
+public class BlsiTestL extends BlsiTestI {
+
+ protected BlsiTestL(Method method) {
+ super(method);
+ isLongOperation = true;
+ }
+
+ public static void main(String[] args) throws Exception {
+ BmiIntrinsicBase.verifyTestCase(BlsiTestL::new, TestBlsiL.BlsiLExpr.class.getDeclaredMethods());
+ BmiIntrinsicBase.verifyTestCase(BlsiTestL::new, TestBlsiL.BlsiLCommutativeExpr.class.getDeclaredMethods());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsmskTestI.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8031321
+ * @library /testlibrary /testlibrary/whitebox /compiler/whitebox ..
+ * @build BlsmskTestI
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ * -XX:+IgnoreUnrecognizedVMOptions -XX:+UseBMI1Instructions BlsmskTestI
+ */
+
+import java.lang.reflect.Method;
+
+public class BlsmskTestI extends BmiIntrinsicBase.BmiTestCase {
+
+ protected BlsmskTestI(Method method) {
+ super(method);
+ //from intel manual VEX.NDD.LZ.0F38.W0 F3 /2
+ instrMask = new byte[]{
+ (byte) 0xFF,
+ (byte) 0x1F,
+ (byte) 0x00,
+ (byte) 0xFF,
+ (byte) 0b0011_1000};
+ instrPattern = new byte[]{
+ (byte) 0xC4, // prefix for 3-byte VEX instruction
+ (byte) 0x02, // 00010 implied 0F 38 leading opcode bytes
+ (byte) 0x00,
+ (byte) 0xF3,
+ (byte) 0b0001_0000}; // bits 543 == 011 (3)
+ }
+
+ public static void main(String[] args) throws Exception {
+ BmiIntrinsicBase.verifyTestCase(BlsmskTestI::new, TestBlsmskI.BlsmskIExpr.class.getDeclaredMethods());
+ BmiIntrinsicBase.verifyTestCase(BlsmskTestI::new, TestBlsmskI.BlsmskICommutativeExpr.class.getDeclaredMethods());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsmskTestL.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8031321
+ * @library /testlibrary /testlibrary/whitebox /compiler/whitebox ..
+ * @build BlsmskTestL
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ * -XX:+IgnoreUnrecognizedVMOptions -XX:+UseBMI1Instructions BlsmskTestL
+ */
+
+import java.lang.reflect.Method;
+
+public class BlsmskTestL extends BlsmskTestI {
+
+ protected BlsmskTestL(Method method) {
+ super(method);
+ isLongOperation = true;
+ }
+
+ public static void main(String[] args) throws Exception {
+ BmiIntrinsicBase.verifyTestCase(BlsmskTestL::new, TestBlsmskL.BlsmskLExpr.class.getDeclaredMethods());
+ BmiIntrinsicBase.verifyTestCase(BlsmskTestL::new, TestBlsmskL.BlsmskLCommutativeExpr.class.getDeclaredMethods());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsrTestI.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8031321
+ * @library /testlibrary /testlibrary/whitebox /compiler/whitebox ..
+ * @build BlsrTestI
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ * -XX:+IgnoreUnrecognizedVMOptions -XX:+UseBMI1Instructions BlsrTestI
+ */
+
+import java.lang.reflect.Method;
+
+public class BlsrTestI extends BmiIntrinsicBase.BmiTestCase {
+
+ protected BlsrTestI(Method method) {
+ super(method);
+ //from intel manual VEX.NDD.LZ.0F38.W0 F3 /1
+ instrMask = new byte[]{
+ (byte) 0xFF,
+ (byte) 0x1F,
+ (byte) 0x00,
+ (byte) 0xFF,
+ (byte) 0b0011_1000};
+ instrPattern = new byte[]{
+ (byte) 0xC4, // prefix for 3-byte VEX instruction
+ (byte) 0x02, // 00010 implied 0F 38 leading opcode bytes
+ (byte) 0x00,
+ (byte) 0xF3,
+ (byte) 0b0000_1000}; // bits 543 == 011 (3)
+ }
+
+ public static void main(String[] args) throws Exception {
+ BmiIntrinsicBase.verifyTestCase(BlsrTestI::new, TestBlsrI.BlsrIExpr.class.getDeclaredMethods());
+ BmiIntrinsicBase.verifyTestCase(BlsrTestI::new, TestBlsrI.BlsrICommutativeExpr.class.getDeclaredMethods());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsrTestL.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8031321
+ * @library /testlibrary /testlibrary/whitebox /compiler/whitebox ..
+ * @build BlsrTestL
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ * -XX:+IgnoreUnrecognizedVMOptions -XX:+UseBMI1Instructions BlsrTestL
+ */
+
+import java.lang.reflect.Method;
+
+public class BlsrTestL extends BlsrTestI {
+
+ protected BlsrTestL(Method method) {
+ super(method);
+ isLongOperation = true;
+ }
+
+ public static void main(String[] args) throws Exception {
+ BmiIntrinsicBase.verifyTestCase(BlsrTestL::new, TestBlsrL.BlsrLExpr.class.getDeclaredMethods());
+ BmiIntrinsicBase.verifyTestCase(BlsrTestL::new, TestBlsrL.BlsrLCommutativeExpr.class.getDeclaredMethods());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BmiIntrinsicBase.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+import com.oracle.java.testlibrary.Asserts;
+import com.oracle.java.testlibrary.Platform;
+import com.oracle.java.testlibrary.Utils;
+import sun.hotspot.code.NMethod;
+import sun.hotspot.cpuinfo.CPUInfo;
+
+import java.lang.reflect.Executable;
+import java.lang.reflect.Method;
+import java.util.concurrent.Callable;
+import java.util.function.Function;
+
+public class BmiIntrinsicBase extends CompilerWhiteBoxTest {
+
+ protected BmiIntrinsicBase(BmiTestCase testCase) {
+ super(testCase);
+ }
+
+ public static void verifyTestCase(Function<Method, BmiTestCase> constructor, Method... methods) throws Exception {
+ for (Method method : methods) {
+ new BmiIntrinsicBase(constructor.apply(method)).test();
+ }
+ }
+
+ @Override
+ protected void test() throws Exception {
+ BmiTestCase bmiTestCase = (BmiTestCase) testCase;
+
+ if (!(Platform.isX86() || Platform.isX64())) {
+ System.out.println("Unsupported platform, test SKIPPED");
+ return;
+ }
+
+ if (!Platform.isServer()) {
+ System.out.println("Not server VM, test SKIPPED");
+ return;
+ }
+
+ if (!CPUInfo.hasFeature(bmiTestCase.getCpuFlag())) {
+ System.out.println("Unsupported hardware, no required CPU flag " + bmiTestCase.getCpuFlag() + " , test SKIPPED");
+ return;
+ }
+
+ if (!Boolean.valueOf(getVMOption(bmiTestCase.getVMFlag()))) {
+ System.out.println("VM flag " + bmiTestCase.getVMFlag() + " disabled, test SKIPPED");
+ return;
+ }
+
+ System.out.println(testCase.name());
+
+ switch (MODE) {
+ case "compiled mode":
+ case "mixed mode":
+ if (TIERED_COMPILATION && TIERED_STOP_AT_LEVEL != CompilerWhiteBoxTest.COMP_LEVEL_MAX) {
+ System.out.println("TieredStopAtLevel value (" + TIERED_STOP_AT_LEVEL + ") is too low, test SKIPPED");
+ return;
+ }
+ deoptimize();
+ compileAtLevelAndCheck(CompilerWhiteBoxTest.COMP_LEVEL_MAX);
+ break;
+ case "interpreted mode": // test is not applicable in this mode;
+ System.err.println("Warning: This test is not applicable in mode: " + MODE);
+ break;
+ default:
+ throw new AssertionError("Test bug, unknown VM mode: " + MODE);
+ }
+ }
+
+ protected void compileAtLevelAndCheck(int level) {
+ WHITE_BOX.enqueueMethodForCompilation(method, level);
+ waitBackgroundCompilation();
+ checkCompilation(method, level);
+ checkEmittedCode(method);
+ }
+
+ protected void checkCompilation(Executable executable, int level) {
+ if (!WHITE_BOX.isMethodCompiled(executable)) {
+ throw new AssertionError("Test bug, expected compilation (level): " + level + ", but not compiled" + WHITE_BOX.isMethodCompilable(executable, level));
+ }
+ final int compilationLevel = WHITE_BOX.getMethodCompilationLevel(executable);
+ if (compilationLevel != level) {
+ throw new AssertionError("Test bug, expected compilation (level): " + level + ", but level: " + compilationLevel);
+ }
+ }
+
+ protected void checkEmittedCode(Executable executable) {
+ final byte[] nativeCode = NMethod.get(executable, false).insts;
+ if (!((BmiTestCase) testCase).verifyPositive(nativeCode)) {
+ throw new AssertionError(testCase.name() + "CPU instructions expected not found: " + Utils.toHexString(nativeCode));
+ } else {
+ System.out.println("CPU instructions found, PASSED");
+ }
+ }
+
+ abstract static class BmiTestCase implements CompilerWhiteBoxTest.TestCase {
+ private final Method method;
+ protected byte[] instrMask;
+ protected byte[] instrPattern;
+ protected boolean isLongOperation;
+
+ public BmiTestCase(Method method) {
+ this.method = method;
+ }
+
+ @Override
+ public String name() {
+ return method.toGenericString();
+ }
+
+ @Override
+ public Executable getExecutable() {
+ return method;
+ }
+
+ @Override
+ public Callable<Integer> getCallable() {
+ return null;
+ }
+
+ @Override
+ public boolean isOsr() {
+ return false;
+ }
+
+ protected int countCpuInstructions(byte[] nativeCode) {
+ int count = 0;
+ int patternSize = Math.min(instrMask.length, instrPattern.length);
+ boolean found;
+ Asserts.assertGreaterThan(patternSize, 0);
+ for (int i = 0, n = nativeCode.length - patternSize; i < n; i++) {
+ found = true;
+ for (int j = 0; j < patternSize; j++) {
+ if ((nativeCode[i + j] & instrMask[j]) != instrPattern[j]) {
+ found = false;
+ break;
+ }
+ }
+ if (found) {
+ ++count;
+ i += patternSize - 1;
+ }
+ }
+ return count;
+ }
+
+ public boolean verifyPositive(byte[] nativeCode) {
+ final int cnt = countCpuInstructions(nativeCode);
+ if (Platform.isX86()) {
+ return cnt >= (isLongOperation ? 2 : 1);
+ } else {
+ return Platform.isX64() && cnt >= 1;
+ }
+ }
+
+ protected String getCpuFlag() {
+ return "bmi1";
+ }
+
+ protected String getVMFlag() {
+ return "UseBMI1Instructions";
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/LZcntTestI.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8031321
+ * @library /testlibrary /testlibrary/whitebox /compiler/whitebox ..
+ * @build LZcntTestI
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ * -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCountLeadingZerosInstruction LZcntTestI
+ */
+
+import java.lang.reflect.Method;
+
+public class LZcntTestI extends BmiIntrinsicBase.BmiTestCase {
+
+ protected LZcntTestI(Method method) {
+ super(method);
+ instrMask = new byte[]{(byte) 0xFF, (byte) 0xFF, (byte) 0xFF};
+ instrPattern = new byte[]{(byte) 0xF3, (byte) 0x0F, (byte) 0xBD};
+ }
+
+ public static void main(String[] args) throws Exception {
+ // j.l.Integer and Long should be loaded to allow a compilation of the methods that use their methods
+ System.out.println("class java.lang.Integer should be loaded. Proof: " + Integer.class);
+ BmiIntrinsicBase.verifyTestCase(LZcntTestI::new, TestLzcntI.LzcntIExpr.class.getDeclaredMethods());
+ }
+
+ @Override
+ protected String getVMFlag() {
+ return "UseCountLeadingZerosInstruction";
+ }
+
+ @Override
+ protected String getCpuFlag() {
+ return "lzcnt";
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/LZcntTestL.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8031321
+ * @library /testlibrary /testlibrary/whitebox /compiler/whitebox ..
+ * @build LZcntTestL
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ * -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCountLeadingZerosInstruction LZcntTestL
+ */
+
+import com.oracle.java.testlibrary.Platform;
+
+import java.lang.reflect.Method;
+
+public class LZcntTestL extends LZcntTestI {
+
+ protected LZcntTestL(Method method) {
+ super(method);
+ isLongOperation = true;
+ if (Platform.isX64()) {
+ instrMask = new byte[]{(byte) 0xFF, (byte) 0x00, (byte) 0xFF, (byte) 0xFF};
+ instrPattern = new byte[]{(byte) 0xF3, (byte) 0x00, (byte) 0x0F, (byte) 0xBD};
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ // j.l.Integer and Long should be loaded to allow a compilation of the methods that use their methods
+ System.out.println("classes java.lang.Long should be loaded. Proof: " + Long.class);
+ BmiIntrinsicBase.verifyTestCase(LZcntTestL::new, TestLzcntL.LzcntLExpr.class.getDeclaredMethods());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/TZcntTestI.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8031321
+ * @library /testlibrary /testlibrary/whitebox /compiler/whitebox ..
+ * @build TZcntTestI
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ * -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCountTrailingZerosInstruction TZcntTestI
+ */
+
+import java.lang.reflect.Method;
+
+public class TZcntTestI extends BmiIntrinsicBase.BmiTestCase {
+
+ protected TZcntTestI(Method method) {
+ super(method);
+ instrMask = new byte[]{(byte) 0xFF, (byte) 0xFF, (byte) 0xFF};
+ instrPattern = new byte[]{(byte) 0xF3, (byte) 0x0F, (byte) 0xBC};
+ }
+
+ public static void main(String[] args) throws Exception {
+ // j.l.Integer and Long should be loaded to allow a compilation of the methods that use their methods
+ System.out.println("class java.lang.Integer should be loaded. Proof: " + Integer.class);
+ BmiIntrinsicBase.verifyTestCase(TZcntTestI::new, TestTzcntI.TzcntIExpr.class.getDeclaredMethods());
+ }
+
+ @Override
+ protected String getVMFlag() {
+ return "UseCountTrailingZerosInstruction";
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/TZcntTestL.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8031321
+ * @library /testlibrary /testlibrary/whitebox /compiler/whitebox ..
+ * @build TZcntTestL
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ * -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCountTrailingZerosInstruction TZcntTestL
+ */
+
+import com.oracle.java.testlibrary.Platform;
+
+import java.lang.reflect.Method;
+
+public class TZcntTestL extends TZcntTestI {
+
+ protected TZcntTestL(Method method) {
+ super(method);
+ isLongOperation = true;
+ if (Platform.isX64()) {
+ instrMask = new byte[]{(byte) 0xFF, (byte) 0x00, (byte) 0xFF, (byte) 0xFF};
+ instrPattern = new byte[]{(byte) 0xF3, (byte) 0x00, (byte) 0x0F, (byte) 0xBC};
+ }
+ isLongOperation = true;
+ }
+
+ public static void main(String[] args) throws Exception {
+ // j.l.Integer and Long should be loaded to allow a compilation of the methods that use their methods
+ System.out.println("classes java.lang.Long should be loaded. Proof: " + Long.class);
+ BmiIntrinsicBase.verifyTestCase(TZcntTestL::new, TestTzcntL.TzcntLExpr.class.getDeclaredMethods());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/cli/RTMGenericCommandLineOptionTest.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.*;
+
+import java.util.function.BooleanSupplier;
+
+/**
+ * Base for all RTM-related CLI tests.
+ */
+public abstract class RTMGenericCommandLineOptionTest
+ extends CommandLineOptionTest {
+ protected static final String RTM_INSTR_ERROR
+ = "RTM instructions are not available on this CPU";
+ protected static final String RTM_UNSUPPORTED_VM_ERROR
+ = "RTM locking optimization is not supported in this VM";
+ protected static final String RTM_ABORT_RATIO_WARNING
+ = "RTMAbortRatio must be in the range 0 to 100, resetting it to 50";
+ protected static final String RTM_FOR_STACK_LOCKS_WARNING
+ = "UseRTMForStackLocks flag should be off when UseRTMLocking "
+ + "flag is off";
+ protected static final String RTM_COUNT_INCR_WARNING
+ = "RTMTotalCountIncrRate must be a power of 2, resetting it to 64";
+ protected static final String RTM_BIASED_LOCKING_WARNING
+ = "Biased locking is not supported with RTM locking; "
+ + "ignoring UseBiasedLocking flag";
+
+ protected final String optionName;
+ protected final String errorMessage;
+ protected final String experimentalOptionError;
+ protected final boolean isExperimental;
+ protected final boolean isBoolean;
+ protected final String defaultValue;
+ protected final String[] optionValues;
+
+ /**
+ * Constructs new genetic RTM CLI test, for option {@code optionName} which
+ * has default value {@code defaultValue}. Test cases will use option's
+ * values passed via {@code optionValues} for verification of correct
+ * option processing.
+ *
+ * Test constructed using this ctor will be started on any cpu regardless
+ * it's architecture and supported/unsupported features.
+ *
+ * @param predicate predicate responsible for test's preconditions check
+ * @param optionName name of option to be tested
+ * @param isBoolean {@code true} if option is binary
+ * @param isExperimental {@code true} if option is experimental
+ * @param defaultValue default value of tested option
+ * @param optionValues different option values
+ */
+ public RTMGenericCommandLineOptionTest(BooleanSupplier predicate,
+ String optionName, boolean isBoolean, boolean isExperimental,
+ String defaultValue, String... optionValues) {
+ super(predicate);
+ this.optionName = optionName;
+ this.isExperimental = isExperimental;
+ this.isBoolean = isBoolean;
+ this.defaultValue = defaultValue;
+ this.optionValues = optionValues;
+ this.errorMessage = CommandLineOptionTest.
+ getUnrecognizedOptionErrorMessage(optionName);
+ this.experimentalOptionError = CommandLineOptionTest.
+ getExperimentalOptionErrorMessage(optionName);
+ }
+
+ @Override
+ public void runTestCases() throws Throwable {
+ if (Platform.isX86() || Platform.isX64()) {
+ if (Platform.isServer() && !Platform.isEmbedded()) {
+ runX86SupportedVMTestCases();
+ } else {
+ runX86UnsupportedVMTestCases();
+ }
+ } else {
+ runNonX86TestCases();
+ }
+ }
+
+ /**
+ * Runs test cases on X86 CPU if VM supports RTM locking.
+ * @throws Throwable
+ */
+ protected void runX86SupportedVMTestCases() throws Throwable {
+ runGenericX86TestCases();
+ }
+
+ /**
+ * Runs test cases on non-X86 CPU if VM does not support RTM locking.
+ * @throws Throwable
+ */
+ protected void runX86UnsupportedVMTestCases() throws Throwable {
+ runGenericX86TestCases();
+ }
+
+ /**
+ * Runs test cases on non-X86 CPU.
+ * @throws Throwable
+ */
+ protected void runNonX86TestCases() throws Throwable {
+ CommandLineOptionTest.verifySameJVMStartup(
+ new String[] { errorMessage }, null, ExitCode.FAIL,
+ prepareOptionValue(defaultValue));
+ }
+
+ /**
+ * Runs generic X86 test cases.
+ * @throws Throwable
+ */
+ protected void runGenericX86TestCases() throws Throwable {
+ verifyJVMStartup();
+ verifyOptionValues();
+ }
+
+ protected void verifyJVMStartup() throws Throwable {
+ String optionValue = prepareOptionValue(defaultValue);
+ if (isExperimental) {
+ // verify that option is experimental
+ CommandLineOptionTest.verifySameJVMStartup(
+ new String[] { experimentalOptionError },
+ new String[] { errorMessage }, ExitCode.FAIL,
+ optionValue);
+ // verify that it could be passed if experimental options
+ // are unlocked
+ CommandLineOptionTest.verifySameJVMStartup(null,
+ new String[] {
+ experimentalOptionError,
+ errorMessage
+ },
+ ExitCode.OK,
+ CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
+ optionValue);
+ } else {
+ // verify that option could be passed
+ CommandLineOptionTest.verifySameJVMStartup(null,
+ new String[]{errorMessage}, ExitCode.OK, optionValue);
+ }
+ }
+
+ protected void verifyOptionValues() throws Throwable {
+ // verify default value
+ if (isExperimental) {
+ CommandLineOptionTest.verifyOptionValueForSameVM(optionName,
+ defaultValue,
+ CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS);
+ } else {
+ CommandLineOptionTest.verifyOptionValueForSameVM(optionName,
+ defaultValue);
+ }
+ // verify other specified option values
+ if (optionValues == null) {
+ return;
+ }
+
+ for (String value : optionValues) {
+ if (isExperimental) {
+ CommandLineOptionTest.verifyOptionValueForSameVM(optionName,
+ value,
+ CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
+ prepareOptionValue(value));
+ } else {
+ CommandLineOptionTest.verifyOptionValueForSameVM(optionName,
+ value, prepareOptionValue(value));
+ }
+ }
+ }
+
+ protected String prepareOptionValue(String value) {
+ if (isBoolean) {
+ return CommandLineOptionTest.prepareBooleanFlag(optionName,
+ Boolean.valueOf(value));
+ } else {
+ return String.format("-XX:%s=%s", optionName, value);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/cli/RTMLockingAwareTest.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+import java.util.List;
+import java.util.LinkedList;
+
+import com.oracle.java.testlibrary.ExitCode;
+import com.oracle.java.testlibrary.cli.*;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+/**
+ * Base for all RTM-related CLI tests on options whose processing depends
+ * on UseRTMLocking value.
+ *
+ * Since UseRTMLocking option could be used when both CPU and VM supports RTM
+ * locking, this test will be skipped on all unsupported configurations.
+ */
+public abstract class RTMLockingAwareTest
+ extends RTMGenericCommandLineOptionTest {
+ protected final String warningMessage;
+ protected final String[] correctValues;
+ protected final String[] incorrectValues;
+ /**
+ * Constructs new test for option {@code optionName} that should be executed
+ * only on CPU with RTM support.
+ * Test will be executed using set of correct values from
+ * {@code correctValues} and set of incorrect values from
+ * {@code incorrectValues}.
+ *
+ * @param optionName name of option to be tested
+ * @param isBoolean {@code true} if tested option is binary
+ * @param isExperimental {@code true} if tested option is experimental
+ * @param defaultValue default value of tested option
+ * @param correctValues array with correct values, that should not emit
+ * {@code warningMessage} to VM output
+ * @param incorrectValues array with incorrect values, that should emit
+ * {@code waningMessage} to VM output
+ * @param warningMessage warning message associated with tested option
+ */
+ protected RTMLockingAwareTest(String optionName, boolean isBoolean,
+ boolean isExperimental, String defaultValue,
+ String[] correctValues, String[] incorrectValues,
+ String warningMessage) {
+ super(new AndPredicate(new SupportedCPU(), new SupportedVM()),
+ optionName, isBoolean, isExperimental, defaultValue);
+ this.correctValues = correctValues;
+ this.incorrectValues = incorrectValues;
+ this.warningMessage = warningMessage;
+ }
+
+ @Override
+ protected void verifyJVMStartup() throws Throwable {
+ // Run generic sanity checks
+ super.verifyJVMStartup();
+ // Verify how option values will be processed depending on
+ // UseRTMLocking value.
+ if (correctValues != null) {
+ for (String correctValue : correctValues) {
+ // For correct values it is expected to see no warnings
+ // regardless to UseRTMLocking
+ verifyStartupWarning(correctValue, true, false);
+ verifyStartupWarning(correctValue, false, false);
+ }
+ }
+
+ if (incorrectValues != null) {
+ for (String incorrectValue : incorrectValues) {
+ // For incorrect values it is expected to see warning
+ // only with -XX:+UseRTMLocking
+ verifyStartupWarning(incorrectValue, true, true);
+ verifyStartupWarning(incorrectValue, false, false);
+ }
+ }
+ }
+
+ @Override
+ protected void verifyOptionValues() throws Throwable {
+ super.verifyOptionValues();
+ // Verify how option values will be setup after processing
+ // depending on UseRTMLocking value
+ if (correctValues != null) {
+ for (String correctValue : correctValues) {
+ // Correct value could be set up regardless to UseRTMLocking
+ verifyOptionValues(correctValue, false, correctValue);
+ verifyOptionValues(correctValue, true, correctValue);
+ }
+ }
+
+ if (incorrectValues != null) {
+ for (String incorrectValue : incorrectValues) {
+ // With -XX:+UseRTMLocking, incorrect value will be changed to
+ // default value.
+ verifyOptionValues(incorrectValue, false, incorrectValue);
+ verifyOptionValues(incorrectValue, true, defaultValue);
+ }
+ }
+ }
+
+ private void verifyStartupWarning(String value, boolean useRTMLocking,
+ boolean isWarningExpected) throws Throwable {
+ String warnings[] = new String[] { warningMessage };
+ List<String> options = new LinkedList<>();
+ options.add(CommandLineOptionTest.prepareBooleanFlag("UseRTMLocking",
+ useRTMLocking));
+
+ if (isExperimental) {
+ options.add(CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS);
+ }
+ options.add(prepareOptionValue(value));
+
+ CommandLineOptionTest.verifySameJVMStartup(
+ (isWarningExpected ? warnings : null),
+ (isWarningExpected ? null : warnings),
+ ExitCode.OK, options.toArray(new String[options.size()]));
+ }
+
+ private void verifyOptionValues(String value, boolean useRTMLocking,
+ String expectedValue) throws Throwable {
+ List<String> options = new LinkedList<>();
+ options.add(CommandLineOptionTest.prepareBooleanFlag("UseRTMLocking",
+ useRTMLocking));
+
+ if (isExperimental) {
+ options.add(CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS);
+ }
+ options.add(prepareOptionValue(value));
+
+ CommandLineOptionTest.verifyOptionValueForSameVM(optionName,
+ expectedValue, options.toArray(new String[options.size()]));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsBase.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.*;
+
+import java.util.function.BooleanSupplier;
+
+public abstract class TestPrintPreciseRTMLockingStatisticsBase
+ extends RTMGenericCommandLineOptionTest {
+ protected static final String DEFAULT_VALUE = "false";
+
+ protected TestPrintPreciseRTMLockingStatisticsBase(
+ BooleanSupplier predicate) {
+ super(predicate, "PrintPreciseRTMLockingStatistics", true, false,
+ TestPrintPreciseRTMLockingStatisticsBase.DEFAULT_VALUE);
+ }
+
+ @Override
+ protected void runNonX86TestCases() throws Throwable {
+ verifyJVMStartup();
+ verifyOptionValues();
+ }
+
+ @Override
+ protected void verifyJVMStartup() throws Throwable {
+ if (Platform.isServer()) {
+ if (!Platform.isDebugBuild()) {
+ String errorMessage = CommandLineOptionTest.
+ getDiagnosticOptionErrorMessage(optionName);
+ // verify that option is actually diagnostic
+ CommandLineOptionTest.verifySameJVMStartup(
+ new String[] { errorMessage }, null, ExitCode.FAIL,
+ prepareOptionValue("true"));
+
+ CommandLineOptionTest.verifySameJVMStartup(null,
+ new String[] { errorMessage }, ExitCode.OK,
+ CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
+ prepareOptionValue("true"));
+ } else {
+ CommandLineOptionTest.verifySameJVMStartup(
+ null, null, ExitCode.OK, prepareOptionValue("true"));
+ }
+ } else {
+ String errorMessage = CommandLineOptionTest.
+ getUnrecognizedOptionErrorMessage(optionName);
+
+ CommandLineOptionTest.verifySameJVMStartup(
+ new String[]{errorMessage}, null, ExitCode.FAIL,
+ CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
+ prepareOptionValue("true"));
+ }
+ }
+
+ @Override
+ protected void verifyOptionValues() throws Throwable {
+ if (Platform.isServer()) {
+ // Verify default value
+ CommandLineOptionTest.verifyOptionValueForSameVM(optionName,
+ TestPrintPreciseRTMLockingStatisticsBase.DEFAULT_VALUE,
+ CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsOptionOnSupportedConfig.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify PrintPreciseRTMLockingStatistics on CPUs with
+ * rtm support and on VM with rtm locking support,
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestPrintPreciseRTMLockingStatisticsOptionOnSupportedConfig
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI
+ * TestPrintPreciseRTMLockingStatisticsOptionOnSupportedConfig
+ */
+
+import com.oracle.java.testlibrary.cli.*;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+public class TestPrintPreciseRTMLockingStatisticsOptionOnSupportedConfig
+ extends TestPrintPreciseRTMLockingStatisticsBase {
+ private TestPrintPreciseRTMLockingStatisticsOptionOnSupportedConfig() {
+ super(new AndPredicate(new SupportedVM(), new SupportedCPU()));
+ }
+
+ @Override
+ protected void verifyOptionValues() throws Throwable {
+ super.verifyOptionValues();
+ // verify default value
+ CommandLineOptionTest.verifyOptionValueForSameVM(optionName,
+ TestPrintPreciseRTMLockingStatisticsBase.DEFAULT_VALUE,
+ CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
+ "-XX:+UseRTMLocking");
+
+ CommandLineOptionTest.verifyOptionValueForSameVM(optionName,
+ TestPrintPreciseRTMLockingStatisticsBase.DEFAULT_VALUE,
+ CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
+ "-XX:-UseRTMLocking", prepareOptionValue("true"));
+
+ // verify that option could be turned on
+ CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "true",
+ CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
+ "-XX:+UseRTMLocking", prepareOptionValue("true"));
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestPrintPreciseRTMLockingStatisticsOptionOnSupportedConfig()
+ .test();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsOptionOnUnsupportedConfig.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify PrintPreciseRTMLockingStatistics on CPUs without
+ * rtm support and/or unsupported VM.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestPrintPreciseRTMLockingStatisticsOptionOnUnsupportedConfig
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI
+ * TestPrintPreciseRTMLockingStatisticsOptionOnUnsupportedConfig
+ */
+
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import com.oracle.java.testlibrary.cli.predicate.NotPredicate;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+public class TestPrintPreciseRTMLockingStatisticsOptionOnUnsupportedConfig
+ extends TestPrintPreciseRTMLockingStatisticsBase {
+ private TestPrintPreciseRTMLockingStatisticsOptionOnUnsupportedConfig() {
+ super(new NotPredicate(new AndPredicate(new SupportedCPU(),
+ new SupportedVM())));
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestPrintPreciseRTMLockingStatisticsOptionOnUnsupportedConfig()
+ .test();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/cli/TestRTMAbortRatioOptionOnSupportedConfig.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify RTMAbortRatio option processing on CPU with rtm
+ * support and on VM with rtm locking support.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestRTMAbortRatioOptionOnSupportedConfig
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI TestRTMAbortRatioOptionOnSupportedConfig
+ */
+
+public class TestRTMAbortRatioOptionOnSupportedConfig
+ extends RTMLockingAwareTest {
+ private static final String DEFAULT_VALUE = "50";
+
+ private TestRTMAbortRatioOptionOnSupportedConfig() {
+ super("RTMAbortRatio", false, true,
+ TestRTMAbortRatioOptionOnSupportedConfig.DEFAULT_VALUE,
+ /* correct values */
+ new String[] { "0", "20", "100" },
+ /* incorrect values */
+ new String[] { "-1", "101" },
+ RTMGenericCommandLineOptionTest.RTM_ABORT_RATIO_WARNING);
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestRTMAbortRatioOptionOnSupportedConfig().test();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/cli/TestRTMAbortRatioOptionOnUnsupportedConfig.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify RTMAbortRatio option processing on CPU without rtm
+ * support or on VM that does not support rtm locking.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestRTMAbortRatioOptionOnUnsupportedConfig
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI TestRTMAbortRatioOptionOnUnsupportedConfig
+ */
+
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import com.oracle.java.testlibrary.cli.predicate.NotPredicate;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+public class TestRTMAbortRatioOptionOnUnsupportedConfig
+ extends RTMGenericCommandLineOptionTest {
+ private static final String DEFAULT_VALUE = "50";
+
+ private TestRTMAbortRatioOptionOnUnsupportedConfig() {
+ super(new NotPredicate(new AndPredicate(new SupportedVM(),
+ new SupportedCPU())),
+ "RTMAbortRatio", false, true,
+ TestRTMAbortRatioOptionOnUnsupportedConfig.DEFAULT_VALUE,
+ "0", "10", "100", "200");
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestRTMAbortRatioOptionOnUnsupportedConfig().test();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/cli/TestRTMAbortThresholdOption.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify processing of RTMAbortThreshold option.
+ * @library /testlibrary
+ * @build TestRTMAbortThresholdOption
+ * @run main/othervm TestRTMAbortThresholdOption
+ */
+
+public class TestRTMAbortThresholdOption
+ extends RTMGenericCommandLineOptionTest {
+ private static final String DEFAULT_VALUE = "1000";
+
+ private TestRTMAbortThresholdOption() {
+ super(Boolean.TRUE::booleanValue, "RTMAbortThreshold", false, true,
+ TestRTMAbortThresholdOption.DEFAULT_VALUE,
+ "0", "42", "100", "10000");
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestRTMAbortThresholdOption().test();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/cli/TestRTMLockingCalculationDelayOption.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify processing of RTMLockingCalculationDelay option.
+ * @library /testlibrary
+ * @build TestRTMLockingCalculationDelayOption
+ * @run main/othervm TestRTMLockingCalculationDelayOption
+ */
+
+public class TestRTMLockingCalculationDelayOption
+ extends RTMGenericCommandLineOptionTest {
+ private static final String DEFAULT_VALUE = "0";
+
+ private TestRTMLockingCalculationDelayOption() {
+ super(Boolean.TRUE::booleanValue, "RTMLockingCalculationDelay", false,
+ true, TestRTMLockingCalculationDelayOption.DEFAULT_VALUE);
+ }
+
+ public static void main(String agrs[]) throws Throwable {
+ new TestRTMLockingCalculationDelayOption().test();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/cli/TestRTMLockingThresholdOption.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify processing of RTMLockingThreshold option.
+ * @library /testlibrary
+ * @build TestRTMLockingThresholdOption
+ * @run main/othervm TestRTMLockingThresholdOption
+ */
+
+public class TestRTMLockingThresholdOption
+ extends RTMGenericCommandLineOptionTest {
+ private static final String DEFAULT_VALUE = "10000";
+
+ private TestRTMLockingThresholdOption() {
+ super(Boolean.TRUE::booleanValue, "RTMLockingThreshold", false, true,
+ TestRTMLockingThresholdOption.DEFAULT_VALUE);
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestRTMLockingThresholdOption().test();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/cli/TestRTMSpinLoopCountOption.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify processing of RTMSpinLoopCount option.
+ * @library /testlibrary
+ * @build TestRTMSpinLoopCountOption
+ * @run main/othervm TestRTMSpinLoopCountOption
+ */
+
+public class TestRTMSpinLoopCountOption
+ extends RTMGenericCommandLineOptionTest {
+ private static final String DEFAULT_VALUE = "100";
+
+ private TestRTMSpinLoopCountOption() {
+ super(Boolean.TRUE::booleanValue, "RTMSpinLoopCount", false, true,
+ TestRTMSpinLoopCountOption.DEFAULT_VALUE,
+ "0", "10", "42", "1000");
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestRTMSpinLoopCountOption().test();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/cli/TestRTMTotalCountIncrRateOptionOnSupportedConfig.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify RTMTotalCountIncrRate option processing on CPU with
+ * rtm support and on VM with rtm locking support.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestRTMTotalCountIncrRateOptionOnSupportedConfig
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI
+ * TestRTMTotalCountIncrRateOptionOnSupportedConfig
+ */
+
+public class TestRTMTotalCountIncrRateOptionOnSupportedConfig
+ extends RTMLockingAwareTest {
+ private static final String DEFAULT_VALUE = "64";
+
+ private TestRTMTotalCountIncrRateOptionOnSupportedConfig() {
+ super("RTMTotalCountIncrRate", false, true,
+ TestRTMTotalCountIncrRateOptionOnSupportedConfig.DEFAULT_VALUE,
+ /* correct values */
+ new String[] { "1", "2", "128", "1024" },
+ /* incorrect values */
+ new String[] { "-1", "0", "3", "42" },
+ RTMGenericCommandLineOptionTest.RTM_COUNT_INCR_WARNING);
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestRTMTotalCountIncrRateOptionOnSupportedConfig().test();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/cli/TestRTMTotalCountIncrRateOptionOnUnsupportedConfig.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import com.oracle.java.testlibrary.cli.predicate.NotPredicate;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify RTMTotalCountIncrRate option processing on CPU without
+ * rtm support and/or on VM without rtm locking support.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestRTMTotalCountIncrRateOptionOnUnsupportedConfig
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI
+ * TestRTMTotalCountIncrRateOptionOnUnsupportedConfig
+ */
+
+public class TestRTMTotalCountIncrRateOptionOnUnsupportedConfig
+ extends RTMGenericCommandLineOptionTest {
+ private static final String DEFAULT_VALUE = "64";
+
+ private TestRTMTotalCountIncrRateOptionOnUnsupportedConfig() {
+ super(new NotPredicate(new AndPredicate(new SupportedCPU(),
+ new SupportedVM())),
+ "RTMTotalCountIncrRate", false, true,
+ TestRTMTotalCountIncrRateOptionOnUnsupportedConfig
+ .DEFAULT_VALUE,
+ "-1", "0", "42", "128");
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestRTMTotalCountIncrRateOptionOnUnsupportedConfig().test();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/cli/TestUseRTMDeoptOptionOnSupportedConfig.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify UseRTMDeopt option processing on CPUs with rtm support
+ * when rtm locking is supported by VM.
+ * @library /testlibrary /testlibrary/whitebox
+ * @build TestUseRTMDeoptOptionOnSupportedConfig
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI TestUseRTMDeoptOptionOnSupportedConfig
+ */
+
+import com.oracle.java.testlibrary.ExitCode;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+public class TestUseRTMDeoptOptionOnSupportedConfig
+ extends CommandLineOptionTest {
+ private static final String DEFAULT_VALUE = "false";
+
+ private TestUseRTMDeoptOptionOnSupportedConfig() {
+ super(new AndPredicate(new SupportedVM(), new SupportedCPU()));
+ }
+
+ @Override
+ public void runTestCases() throws Throwable {
+ // verify that option could be turned on
+ CommandLineOptionTest.verifySameJVMStartup(
+ null, null, ExitCode.OK, "-XX:+UseRTMDeopt");
+ // verify that option could be turned off
+ CommandLineOptionTest.verifySameJVMStartup(
+ null, null, ExitCode.OK, "-XX:-UseRTMDeopt");
+ // verify default value
+ CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMDeopt",
+ TestUseRTMDeoptOptionOnSupportedConfig.DEFAULT_VALUE);
+ // verify default value
+ CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMDeopt",
+ TestUseRTMDeoptOptionOnSupportedConfig.DEFAULT_VALUE,
+ "-XX:+UseRTMLocking");
+ // verify that option is off when UseRTMLocking is off
+ CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMDeopt",
+ "false", "-XX:-UseRTMLocking", "-XX:+UseRTMDeopt");
+ // verify that option could be turned on
+ CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMDeopt",
+ "true", "-XX:+UseRTMLocking", "-XX:+UseRTMDeopt");
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestUseRTMDeoptOptionOnSupportedConfig().test();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/cli/TestUseRTMDeoptOptionOnUnsupportedConfig.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify UseRTMDeopt option processing on CPUs without rtm support
+ * or on VMs without rtm locking support.
+ * @library /testlibrary /testlibrary/whitebox
+ * @build TestUseRTMDeoptOptionOnUnsupportedConfig
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI TestUseRTMDeoptOptionOnUnsupportedConfig
+ */
+
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import com.oracle.java.testlibrary.cli.predicate.NotPredicate;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+public class TestUseRTMDeoptOptionOnUnsupportedConfig
+ extends RTMGenericCommandLineOptionTest {
+ private static final String DEFAULT_VALUE = "false";
+
+ private TestUseRTMDeoptOptionOnUnsupportedConfig() {
+ super(new NotPredicate(new AndPredicate(new SupportedCPU(),
+ new SupportedVM())),
+ "UseRTMDeopt", true, false,
+ TestUseRTMDeoptOptionOnUnsupportedConfig.DEFAULT_VALUE, "true");
+ }
+
+ @Override
+ protected void runX86SupportedVMTestCases() throws Throwable {
+ super.verifyJVMStartup();
+ // verify default value
+ CommandLineOptionTest.verifyOptionValueForSameVM(optionName,
+ defaultValue);
+ // verify that until RTMLocking is not used, value
+ // will be set to default false.
+ CommandLineOptionTest.verifyOptionValueForSameVM(optionName,
+ defaultValue, "-XX:+UseRTMDeopt");
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestUseRTMDeoptOptionOnUnsupportedConfig().test();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/cli/TestUseRTMForStackLocksOptionOnSupportedConfig.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify UseRTMForStackLocks option processing on CPU with
+ * rtm support when VM supports rtm locking.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestUseRTMForStackLocksOptionOnSupportedConfig
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI
+ * TestUseRTMForStackLocksOptionOnSupportedConfig
+ */
+
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.*;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+public class TestUseRTMForStackLocksOptionOnSupportedConfig
+ extends CommandLineOptionTest {
+ private static final String DEFAULT_VALUE = "false";
+
+ private TestUseRTMForStackLocksOptionOnSupportedConfig() {
+ super(new AndPredicate(new SupportedVM(), new SupportedCPU()));
+ }
+
+ @Override
+ public void runTestCases() throws Throwable {
+ String errorMessage
+ = CommandLineOptionTest.getExperimentalOptionErrorMessage(
+ "UseRTMForStackLocks");
+ String warningMessage
+ = RTMGenericCommandLineOptionTest.RTM_FOR_STACK_LOCKS_WARNING;
+
+ CommandLineOptionTest.verifySameJVMStartup(
+ new String[] { errorMessage }, null, ExitCode.FAIL,
+ "-XX:+UseRTMForStackLocks");
+ // verify that we get a warning when trying to use rtm for stack
+ // lock, but not using rtm locking.
+ CommandLineOptionTest.verifySameJVMStartup(
+ new String[] { warningMessage }, null, ExitCode.OK,
+ CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
+ "-XX:+UseRTMForStackLocks",
+ "-XX:-UseRTMLocking");
+ // verify that we don't get a warning when no using rtm for stack
+ // lock and not using rtm locking.
+ CommandLineOptionTest.verifySameJVMStartup(null,
+ new String[] { warningMessage }, ExitCode.OK,
+ CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
+ "-XX:-UseRTMForStackLocks",
+ "-XX:-UseRTMLocking");
+ // verify that we don't get a warning when using rtm for stack
+ // lock and using rtm locking.
+ CommandLineOptionTest.verifySameJVMStartup(null,
+ new String[] { warningMessage }, ExitCode.OK,
+ CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
+ "-XX:+UseRTMForStackLocks",
+ "-XX:+UseRTMLocking");
+ // verify that default value if false
+ CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMForStackLocks",
+ TestUseRTMForStackLocksOptionOnSupportedConfig.DEFAULT_VALUE,
+ CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS);
+ // verify that default value is false even with +UseRTMLocking
+ CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMForStackLocks",
+ TestUseRTMForStackLocksOptionOnSupportedConfig.DEFAULT_VALUE,
+ CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
+ "-XX:+UseRTMLocking");
+ // verify that we can turn the option on
+ CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMForStackLocks",
+ "true", CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
+ "-XX:+UseRTMLocking", "-XX:+UseRTMForStackLocks");
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestUseRTMForStackLocksOptionOnSupportedConfig().test();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/cli/TestUseRTMForStackLocksOptionOnUnsupportedConfig.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify UseRTMForStackLocks option processing on CPUs without
+ * rtm support and/or on VMs without rtm locking support.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestUseRTMForStackLocksOptionOnUnsupportedConfig
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI
+ * TestUseRTMForStackLocksOptionOnUnsupportedConfig
+ */
+
+import com.oracle.java.testlibrary.ExitCode;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import com.oracle.java.testlibrary.cli.predicate.NotPredicate;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+public class TestUseRTMForStackLocksOptionOnUnsupportedConfig
+ extends RTMGenericCommandLineOptionTest {
+ private static final String DEFAULT_VALUE = "false";
+
+ private TestUseRTMForStackLocksOptionOnUnsupportedConfig() {
+ super(new NotPredicate(new AndPredicate(new SupportedCPU(),
+ new SupportedVM())),
+ "UseRTMForStackLocks", true, true,
+ TestUseRTMForStackLocksOptionOnUnsupportedConfig.DEFAULT_VALUE,
+ "true");
+ }
+
+ @Override
+ protected void runX86SupportedVMTestCases() throws Throwable {
+ // verify that option is experimental
+ CommandLineOptionTest.verifySameJVMStartup(
+ new String[]{ experimentalOptionError },
+ null, ExitCode.FAIL, prepareOptionValue("true"));
+
+ CommandLineOptionTest.verifySameJVMStartup(
+ new String[]{ experimentalOptionError },
+ null, ExitCode.FAIL, prepareOptionValue("false"));
+
+ // verify that if we turn it on, then VM output will contain
+ // warning saying that this option could be turned on only
+ // when we use rtm locking
+ CommandLineOptionTest.verifySameJVMStartup(
+ new String[]{
+ RTMGenericCommandLineOptionTest.RTM_FOR_STACK_LOCKS_WARNING
+ },
+ null, ExitCode.OK,
+ CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
+ prepareOptionValue("true")
+ );
+ // verify that options is turned off by default
+ CommandLineOptionTest.verifyOptionValueForSameVM(optionName,
+ TestUseRTMForStackLocksOptionOnUnsupportedConfig.DEFAULT_VALUE,
+ CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS);
+ // verify that it could not be turned on without rtm locking
+ CommandLineOptionTest.verifyOptionValueForSameVM(optionName,
+ TestUseRTMForStackLocksOptionOnUnsupportedConfig.DEFAULT_VALUE,
+ CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
+ prepareOptionValue("true"));
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestUseRTMForStackLocksOptionOnUnsupportedConfig().test();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnSupportedConfig.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify UseRTMLocking option processing on CPU with rtm support and
+ * on VM with rtm-locking support.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestUseRTMLockingOptionOnSupportedConfig
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI TestUseRTMLockingOptionOnSupportedConfig
+ */
+
+import com.oracle.java.testlibrary.ExitCode;
+import com.oracle.java.testlibrary.cli.*;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+public class TestUseRTMLockingOptionOnSupportedConfig
+ extends CommandLineOptionTest {
+ private static final String DEFAULT_VALUE = "false";
+
+ private TestUseRTMLockingOptionOnSupportedConfig() {
+ super(new AndPredicate(new SupportedVM(), new SupportedCPU()));
+ }
+
+ @Override
+ public void runTestCases() throws Throwable {
+ String unrecongnizedOption
+ = CommandLineOptionTest.getUnrecognizedOptionErrorMessage(
+ "UseRTMLocking");
+ // verify that there are no warning or error in VM output
+ CommandLineOptionTest.verifySameJVMStartup(null,
+ new String[]{
+ RTMGenericCommandLineOptionTest.RTM_INSTR_ERROR,
+ unrecongnizedOption
+ }, ExitCode.OK, "-XX:+UseRTMLocking"
+ );
+
+ CommandLineOptionTest.verifySameJVMStartup(null,
+ new String[]{
+ RTMGenericCommandLineOptionTest.RTM_INSTR_ERROR,
+ unrecongnizedOption
+ }, ExitCode.OK, "-XX:-UseRTMLocking"
+ );
+ // verify that UseRTMLocking is of by default
+ CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMLocking",
+ TestUseRTMLockingOptionOnSupportedConfig.DEFAULT_VALUE);
+ // verify that we can change UseRTMLocking value
+ CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMLocking",
+ TestUseRTMLockingOptionOnSupportedConfig.DEFAULT_VALUE,
+ "-XX:-UseRTMLocking");
+ CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMLocking",
+ "true", "-XX:+UseRTMLocking");
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestUseRTMLockingOptionOnSupportedConfig().test();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnUnsupportedCPU.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify UseRTMLocking option processing on CPU without
+ * rtm support.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestUseRTMLockingOptionOnUnsupportedCPU
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI TestUseRTMLockingOptionOnUnsupportedCPU
+ */
+
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.*;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import com.oracle.java.testlibrary.cli.predicate.NotPredicate;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+public class TestUseRTMLockingOptionOnUnsupportedCPU
+ extends CommandLineOptionTest {
+ private static final String DEFAULT_VALUE = "false";
+
+ private TestUseRTMLockingOptionOnUnsupportedCPU() {
+ super(new AndPredicate(new NotPredicate(new SupportedCPU()),
+ new SupportedVM()));
+ }
+
+ @Override
+ public void runTestCases() throws Throwable {
+ String unrecongnizedOption
+ = CommandLineOptionTest.getUnrecognizedOptionErrorMessage(
+ "UseRTMLocking");
+ String errorMessage = RTMGenericCommandLineOptionTest.RTM_INSTR_ERROR;
+
+ if (Platform.isX86() || Platform.isX64()) {
+ // verify that we get an error when use +UseRTMLocking
+ // on unsupported CPU
+ CommandLineOptionTest.verifySameJVMStartup(
+ new String[] { errorMessage },
+ new String[] { unrecongnizedOption },
+ ExitCode.FAIL, "-XX:+UseRTMLocking");
+ // verify that we can pass -UseRTMLocking without
+ // getting any error messages
+ CommandLineOptionTest.verifySameJVMStartup(
+ null,
+ new String[]{
+ errorMessage,
+ unrecongnizedOption
+ }, ExitCode.OK, "-XX:-UseRTMLocking");
+
+ // verify that UseRTMLocking is false by default
+ CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMLocking",
+ TestUseRTMLockingOptionOnUnsupportedCPU.DEFAULT_VALUE);
+ } else {
+ // verify that on non-x86 CPUs RTMLocking could not be used
+ CommandLineOptionTest.verifySameJVMStartup(
+ new String[] { unrecongnizedOption },
+ null, ExitCode.FAIL, "-XX:+UseRTMLocking");
+
+ CommandLineOptionTest.verifySameJVMStartup(
+ new String[] { unrecongnizedOption },
+ null, ExitCode.FAIL, "-XX:-UseRTMLocking");
+ }
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestUseRTMLockingOptionOnUnsupportedCPU().test();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnUnsupportedVM.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify UseRTMLocking option processing on CPU with rtm support
+ * in case when VM should not support this option.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestUseRTMLockingOptionOnUnsupportedVM
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI TestUseRTMLockingOptionOnUnsupportedVM
+ */
+
+import com.oracle.java.testlibrary.ExitCode;
+import com.oracle.java.testlibrary.cli.*;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import com.oracle.java.testlibrary.cli.predicate.NotPredicate;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+public class TestUseRTMLockingOptionOnUnsupportedVM
+ extends CommandLineOptionTest {
+ private static final String DEFAULT_VALUE = "false";
+
+ private TestUseRTMLockingOptionOnUnsupportedVM() {
+ super(new AndPredicate(new SupportedCPU(),
+ new NotPredicate(new SupportedVM())));
+ }
+ @Override
+ public void runTestCases() throws Throwable {
+ String errorMessage
+ = RTMGenericCommandLineOptionTest.RTM_UNSUPPORTED_VM_ERROR;
+ // verify that we can't use +UseRTMLocking
+ CommandLineOptionTest.verifySameJVMStartup(
+ new String[] { errorMessage }, null, ExitCode.FAIL,
+ "-XX:+UseRTMLocking");
+ // verify that we can turn it off
+ CommandLineOptionTest.verifySameJVMStartup(null,
+ new String[] { errorMessage }, ExitCode.OK,
+ "-XX:-UseRTMLocking");
+ // verify that it is off by default
+ CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMLocking",
+ TestUseRTMLockingOptionOnUnsupportedVM.DEFAULT_VALUE);
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestUseRTMLockingOptionOnUnsupportedVM().test();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionWithBiasedLocking.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify processing of UseRTMLocking and UseBiasedLocking
+ * options combination on CPU and VM with rtm support.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestUseRTMLockingOptionWithBiasedLocking
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI TestUseRTMLockingOptionWithBiasedLocking
+ */
+
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.*;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+public class TestUseRTMLockingOptionWithBiasedLocking
+ extends CommandLineOptionTest {
+ private TestUseRTMLockingOptionWithBiasedLocking() {
+ super(new AndPredicate(new SupportedCPU(), new SupportedVM()));
+ }
+
+ @Override
+ public void runTestCases() throws Throwable {
+ String warningMessage
+ = RTMGenericCommandLineOptionTest.RTM_BIASED_LOCKING_WARNING;
+ // verify that we will not get a warning
+ CommandLineOptionTest.verifySameJVMStartup(null,
+ new String[] { warningMessage }, ExitCode.OK,
+ "-XX:+UseRTMLocking", "-XX:-UseBiasedLocking");
+ // verify that we will get a warning
+ CommandLineOptionTest.verifySameJVMStartup(
+ new String[] { warningMessage }, null, ExitCode.OK,
+ "-XX:+UseRTMLocking", "-XX:+UseBiasedLocking");
+ // verify that UseBiasedLocking is false when we use rtm locking
+ CommandLineOptionTest.verifyOptionValueForSameVM("UseBiasedLocking",
+ "false", "-XX:+UseRTMLocking");
+ // verify that we can't turn on biased locking when
+ // using rtm locking
+ CommandLineOptionTest.verifyOptionValueForSameVM("UseBiasedLocking",
+ "false", "-XX:+UseRTMLocking", "-XX:+UseBiasedLocking");
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestUseRTMLockingOptionWithBiasedLocking().test();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/cli/TestUseRTMXendForLockBusyOption.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify processing of UseRTMXendForLockBusy option.
+ * @library /testlibrary
+ * @build TestUseRTMXendForLockBusyOption
+ * @run main/othervm TestUseRTMXendForLockBusyOption
+ */
+
+public class TestUseRTMXendForLockBusyOption
+ extends RTMGenericCommandLineOptionTest {
+ private static final String DEFAULT_VALUE = "true";
+
+ public TestUseRTMXendForLockBusyOption() {
+ super(Boolean.TRUE::booleanValue, "UseRTMXendForLockBusy", true, true,
+ TestUseRTMXendForLockBusyOption.DEFAULT_VALUE, "true");
+ }
+
+ public static void main(String agrs[]) throws Throwable {
+ new TestUseRTMXendForLockBusyOption().test();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/locking/TestRTMAbortRatio.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify that RTMAbortRatio affects amount of aborts before
+ * deoptimization.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestRTMAbortRatio
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI TestRTMAbortRatio
+ */
+
+import java.util.List;
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+import sun.misc.Unsafe;
+
+/**
+ * Test verifies that method will be deoptimized on high abort ratio
+ * as soon as abort ratio reaches RTMAbortRatio's value.
+ */
+public class TestRTMAbortRatio extends CommandLineOptionTest {
+ private TestRTMAbortRatio() {
+ super(new AndPredicate(new SupportedCPU(), new SupportedVM()));
+ }
+
+ @Override
+ protected void runTestCases() throws Throwable {
+ verifyAbortRatio(0, false);
+ verifyAbortRatio(10, false);
+ verifyAbortRatio(50, false);
+ verifyAbortRatio(100, false);
+
+ verifyAbortRatio(0, true);
+ verifyAbortRatio(10, true);
+ verifyAbortRatio(50, true);
+ verifyAbortRatio(100, true);
+ }
+
+ private void verifyAbortRatio(int abortRatio, boolean useStackLock)
+ throws Throwable {
+ CompilableTest test = new Test();
+
+ OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+ test,
+ CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks",
+ useStackLock),
+ "-XX:+UseRTMDeopt",
+ "-XX:RTMTotalCountIncrRate=1",
+ "-XX:RTMAbortThreshold=0",
+ CommandLineOptionTest.prepareNumericFlag("RTMLockingThreshold",
+ 10 * Test.TOTAL_ITERATIONS),
+ CommandLineOptionTest.prepareNumericFlag("RTMAbortRatio",
+ abortRatio),
+ "-XX:+PrintPreciseRTMLockingStatistics",
+ test.getClass().getName(),
+ Boolean.toString(!useStackLock));
+
+ outputAnalyzer.shouldHaveExitValue(0);
+
+ List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+ test.getMethodWithLockName(), outputAnalyzer.getOutput());
+
+ Asserts.assertEQ(statistics.size(), 1, "VM output should contain "
+ + "exactly one RTM locking statistics entry.");
+
+ RTMLockingStatistics lock = statistics.get(0);
+ int actualRatio;
+
+ if (lock.getTotalAborts() == 1L) {
+ actualRatio = 0;
+ } else {
+ actualRatio = (int) (lock.getTotalLocks()
+ / (lock.getTotalAborts() - 1L));
+ }
+
+ Asserts.assertLTE(actualRatio, abortRatio, String.format(
+ "Actual abort ratio (%d) should lower or equal to "
+ + "specified (%d).", actualRatio, abortRatio));
+ }
+
+ /**
+ * Force abort after {@code Test.WARMUP_ITERATIONS} is done.
+ */
+ public static class Test implements CompilableTest {
+ private static final int TOTAL_ITERATIONS = 10000;
+ private static final int WARMUP_ITERATIONS = 1000;
+ private static final Unsafe UNSAFE = Utils.getUnsafe();
+ private final Object monitor = new Object();
+ // Following field have to be static in order to avoid escape analysis.
+ @SuppressWarnings("UnsuedDeclaration")
+ private static int field = 0;
+
+ @Override
+ public String getMethodWithLockName() {
+ return this.getClass().getName() + "::lock";
+ }
+
+ @Override
+ public String[] getMethodsToCompileNames() {
+ return new String[] {
+ getMethodWithLockName(),
+ Unsafe.class.getName() + "::addressSize"
+ };
+ }
+
+ public void lock(boolean abort) {
+ synchronized(monitor) {
+ if (abort) {
+ Test.UNSAFE.addressSize();
+ }
+ }
+ }
+
+ /**
+ * Usage:
+ * Test <inflate monitor>
+ */
+ public static void main(String args[]) throws Throwable {
+ Asserts.assertGTE(args.length, 1, "One argument required.");
+ Test t = new Test();
+ if (Boolean.valueOf(args[0])) {
+ AbortProvoker.inflateMonitor(t.monitor);
+ }
+ for (int i = 0; i < Test.TOTAL_ITERATIONS; i++) {
+ t.lock(i >= Test.WARMUP_ITERATIONS);
+ }
+ }
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestRTMAbortRatio().test();
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/locking/TestRTMAbortThreshold.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify that RTMAbortThreshold option affects
+ * amount of aborts after which abort ratio is calculated.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestRTMAbortThreshold
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI TestRTMAbortThreshold
+ */
+
+import java.util.List;
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+/**
+ * Test verifies that on RTMAbortThreshold option actually affects how soon
+ * method will be deoptimized on high abort ratio.
+ */
+public class TestRTMAbortThreshold extends CommandLineOptionTest {
+ private TestRTMAbortThreshold() {
+ super(new AndPredicate(new SupportedCPU(), new SupportedVM()));
+ }
+
+ @Override
+ protected void runTestCases() throws Throwable {
+ verifyAbortThreshold(false, 1);
+ verifyAbortThreshold(false, 10);
+ verifyAbortThreshold(false, 1000);
+
+ verifyAbortThreshold(true, 1);
+ verifyAbortThreshold(true, 10);
+ verifyAbortThreshold(true, 1000);
+ }
+
+ private void verifyAbortThreshold(boolean useStackLock,
+ long abortThreshold) throws Throwable {
+ AbortProvoker provoker = AbortType.XABORT.provoker();
+
+ OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+ provoker,
+ "-XX:+UseRTMDeopt",
+ "-XX:RTMAbortRatio=0",
+ CommandLineOptionTest.prepareNumericFlag("RTMAbortThreshold",
+ abortThreshold),
+ CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks",
+ useStackLock),
+ "-XX:RTMTotalCountIncrRate=1",
+ "-XX:+PrintPreciseRTMLockingStatistics",
+ AbortProvoker.class.getName(),
+ AbortType.XABORT.toString(),
+ Boolean.toString(!useStackLock));
+
+ outputAnalyzer.shouldHaveExitValue(0);
+
+ List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+ provoker.getMethodWithLockName(), outputAnalyzer.getOutput());
+
+ Asserts.assertEQ(statistics.size(), 1, "VM output should contain "
+ + "exactly one RTM locking statistics entry for method "
+ + provoker.getMethodWithLockName());
+
+ Asserts.assertEQ(statistics.get(0).getTotalLocks(), abortThreshold,
+ String.format("Expected that method with rtm lock elision was"
+ + " deoptimized after %d lock attempts",
+ abortThreshold));
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestRTMAbortThreshold().test();
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify that if we use RTMDeopt, then deoptimization
+ * caused by reason other then rtm_state_change will reset
+ * method's RTM state. And if we don't use RTMDeopt, then
+ * RTM state remain the same after such deoptimization.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestRTMAfterNonRTMDeopt
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI TestRTMAfterNonRTMDeopt
+ */
+
+import java.util.List;
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+import sun.misc.Unsafe;
+
+/**
+ * To verify that with +UseRTMDeopt method's RTM state will be
+ * changed to ProfileRTM on deoptimization unrelated to
+ * rtm_state_change following sequence of events is used:
+ * <pre>
+ *
+ * rtm state ^
+ * |
+ * UseRTM | ******| ******
+ * | |
+ * ProfileRTM |******| |*****|
+ * | | | |
+ * 0-------|-----|-----|---------------------> time
+ * | | \ force abort
+ * | |
+ * | \ force deoptimization
+ * |
+ * \ force xabort
+ * </pre>
+ * When xabort is forced by native method call method should
+ * change it's state to UseRTM, because we use RTMAbortRatio=100
+ * and low RTMLockingThreshold, so at this point actual abort
+ * ratio will be below 100% and there should be enough lock
+ * attempts to recompile method without RTM profiling.
+ */
+public class TestRTMAfterNonRTMDeopt extends CommandLineOptionTest {
+ private static final int ABORT_THRESHOLD = 1000;
+ private static final String RANGE_CHECK = "range_check";
+
+ private TestRTMAfterNonRTMDeopt() {
+ super(new AndPredicate(new SupportedCPU(), new SupportedVM()));
+ }
+
+ @Override
+ protected void runTestCases() throws Throwable {
+ verifyRTMAfterDeopt(false, false);
+ verifyRTMAfterDeopt(true, false);
+
+ verifyRTMAfterDeopt(false, true);
+ verifyRTMAfterDeopt(true, true);
+ }
+
+ private void verifyRTMAfterDeopt(boolean useStackLock,
+ boolean useRTMDeopt) throws Throwable {
+ CompilableTest test = new Test();
+ String logFile = String.format("rtm_%s_stack_lock_%s_deopt.xml",
+ (useStackLock ? "use" : "no"), (useRTMDeopt ? "use" : "no"));
+
+ OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+ logFile,
+ test,
+ "-XX:CompileThreshold=1",
+ CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks",
+ useStackLock),
+ CommandLineOptionTest.prepareBooleanFlag("UseRTMDeopt",
+ useRTMDeopt),
+ "-XX:RTMAbortRatio=100",
+ CommandLineOptionTest.prepareNumericFlag("RTMAbortThreshold",
+ TestRTMAfterNonRTMDeopt.ABORT_THRESHOLD),
+ CommandLineOptionTest.prepareNumericFlag("RTMLockingThreshold",
+ TestRTMAfterNonRTMDeopt.ABORT_THRESHOLD / 2L),
+ "-XX:RTMTotalCountIncrRate=1",
+ "-XX:+PrintPreciseRTMLockingStatistics",
+ Test.class.getName(),
+ Boolean.toString(!useStackLock)
+ );
+
+ outputAnalyzer.shouldHaveExitValue(0);
+
+ int traps = RTMTestBase.firedRTMStateChangeTraps(logFile);
+
+ if (useRTMDeopt) {
+ Asserts.assertEQ(traps, 2, "Two uncommon traps with "
+ + "reason rtm_state_change should be fired.");
+ } else {
+ Asserts.assertEQ(traps, 0, "No uncommon traps with "
+ + "reason rtm_state_change should be fired.");
+ }
+
+ int rangeCheckTraps = RTMTestBase.firedUncommonTraps(logFile,
+ TestRTMAfterNonRTMDeopt.RANGE_CHECK);
+
+ Asserts.assertEQ(rangeCheckTraps, 1,
+ "One range_check uncommon trap should be fired.");
+
+ List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+ test.getMethodWithLockName(), outputAnalyzer.getOutput());
+
+ int expectedStatEntries = (useRTMDeopt ? 4 : 2);
+
+ Asserts.assertEQ(statistics.size(), expectedStatEntries,
+ String.format("VM output should contain %d RTM locking "
+ + "statistics entries.", expectedStatEntries));
+ }
+
+ public static class Test implements CompilableTest {
+ // Following field have to be static in order to avoid escape analysis.
+ @SuppressWarnings("UnsuedDeclaration")
+ private static int field = 0;
+ private static final int ITERATIONS = 10000;
+ private static final int RANGE_CHECK_AT = ITERATIONS / 2;
+ private static final Unsafe UNSAFE = Utils.getUnsafe();
+ private final Object monitor = new Object();
+
+ @Override
+ public String getMethodWithLockName() {
+ return this.getClass().getName() + "::forceAbort";
+ }
+
+ @Override
+ public String[] getMethodsToCompileNames() {
+ return new String[] {
+ getMethodWithLockName(),
+ sun.misc.Unsafe.class.getName() + "::forceAbort"
+ };
+ }
+
+ public void forceAbort(int a[], boolean abort) {
+ try {
+ synchronized(monitor) {
+ a[0]++;
+ if (abort) {
+ Test.field = Test.UNSAFE.addressSize();
+ }
+ }
+ } catch (Throwable t) {
+ // suppress any throwables
+ }
+ }
+
+ /**
+ * Usage:
+ * Test <inflate monitor>
+ */
+ public static void main(String args[]) throws Throwable {
+ Test t = new Test();
+
+ if (Boolean.valueOf(args[0])) {
+ AbortProvoker.inflateMonitor(t.monitor);
+ }
+
+ int tmp[] = new int[1];
+
+ for (int i = 0; i < Test.ITERATIONS; i++ ) {
+ if (i == Test.RANGE_CHECK_AT) {
+ t.forceAbort(new int[0], false);
+ } else {
+ boolean isThreshold
+ = (i == TestRTMAfterNonRTMDeopt.ABORT_THRESHOLD);
+ boolean isThresholdPlusRange
+ = (i == TestRTMAfterNonRTMDeopt.ABORT_THRESHOLD
+ + Test.RANGE_CHECK_AT);
+ t.forceAbort(tmp, isThreshold || isThresholdPlusRange);
+ }
+ }
+ }
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestRTMAfterNonRTMDeopt().test();
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnHighAbortRatio.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify that on high abort ratio method will be recompiled
+ * without rtm locking.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestRTMDeoptOnHighAbortRatio
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI TestRTMDeoptOnHighAbortRatio
+ */
+
+import java.util.List;
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+/**
+ * Test verifies that on high abort ratio method wil be deoptimized with
+ * <i>rtm_state_change</i> reason and after that RTM-based lock elision will not
+ * be used for that method.
+ * This test make asserts on total locks count done by compiled method,
+ * so in order to avoid issue with retriable locks -XX:RTMRetryCount=0 is used.
+ * For more details on that issue see {@link TestUseRTMAfterLockInflation}.
+ */
+public class TestRTMDeoptOnHighAbortRatio extends CommandLineOptionTest {
+ private static final long ABORT_THRESHOLD
+ = AbortProvoker.DEFAULT_ITERATIONS / 2L;
+
+ private TestRTMDeoptOnHighAbortRatio() {
+ super(new AndPredicate(new SupportedCPU(), new SupportedVM()));
+ }
+
+ @Override
+ protected void runTestCases() throws Throwable {
+ verifyDeopt(false);
+ verifyDeopt(true);
+ }
+
+ private void verifyDeopt(boolean useStackLock) throws Throwable {
+ AbortProvoker provoker = AbortType.XABORT.provoker();
+ String logFileName = String.format("rtm_deopt_%s_stack_lock.xml",
+ (useStackLock ? "use" : "no"));
+
+ OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+ logFileName,
+ provoker,
+ "-XX:+UseRTMDeopt",
+ CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks",
+ useStackLock),
+ "-XX:RTMRetryCount=0",
+ CommandLineOptionTest.prepareNumericFlag("RTMAbortThreshold",
+ TestRTMDeoptOnHighAbortRatio.ABORT_THRESHOLD),
+ "-XX:RTMAbortRatio=100",
+ "-XX:CompileThreshold=1",
+ "-XX:RTMTotalCountIncrRate=1",
+ "-XX:+PrintPreciseRTMLockingStatistics",
+ AbortProvoker.class.getName(),
+ AbortType.XABORT.toString(),
+ Boolean.toString(!useStackLock)
+ );
+
+ outputAnalyzer.shouldHaveExitValue(0);
+
+ int firedTraps = RTMTestBase.firedRTMStateChangeTraps(logFileName);
+
+ Asserts.assertEQ(firedTraps, 1, "Expected to get only one "
+ + "deoptimization due to rtm state change");
+
+ List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+ provoker.getMethodWithLockName(), outputAnalyzer.getOutput());
+
+ Asserts.assertEQ(statistics.size(), 1, "VM output should contain "
+ + "exactly one RTM locking statistics entry for method "
+ + provoker.getMethodWithLockName());
+
+ Asserts.assertEQ(statistics.get(0).getTotalLocks(),
+ TestRTMDeoptOnHighAbortRatio.ABORT_THRESHOLD,
+ "After AbortThreshold was reached, method should be"
+ + " recompiled without rtm lock eliding.");
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestRTMDeoptOnHighAbortRatio().test();
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify that on low abort ratio method will be recompiled.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestRTMDeoptOnLowAbortRatio
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI TestRTMDeoptOnLowAbortRatio
+ */
+
+import java.util.List;
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+import sun.misc.Unsafe;
+
+/**
+ * Test verifies that low abort ratio method will be deoptimized with
+ * <i>rtm_state_change</i> reason and will continue to use RTM-based lock
+ * elision after that.
+ * This test make asserts on total locks count done by compiled method,
+ * so in order to avoid issue with retriable locks -XX:RTMRetryCount=0 is used.
+ * For more details on that issue see {@link TestUseRTMAfterLockInflation}.
+ */
+public class TestRTMDeoptOnLowAbortRatio extends CommandLineOptionTest {
+ private static final long LOCKING_THRESHOLD = 100L;
+
+ private TestRTMDeoptOnLowAbortRatio() {
+ super(new AndPredicate(new SupportedCPU(), new SupportedVM()));
+ }
+
+ @Override
+ protected void runTestCases() throws Throwable {
+ verifyRTMDeopt(false);
+ verifyRTMDeopt(true);
+ }
+
+ private void verifyRTMDeopt(boolean useStackLock) throws Throwable {
+ CompilableTest test = new Test();
+ String logFileName = String.format("rtm_deopt_%s_stack_lock.xml",
+ useStackLock ? "use" : "no");
+
+ OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+ logFileName,
+ test,
+ "-XX:+UseRTMDeopt",
+ CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks",
+ useStackLock),
+ CommandLineOptionTest.prepareNumericFlag("RTMLockingThreshold",
+ TestRTMDeoptOnLowAbortRatio.LOCKING_THRESHOLD),
+ "-XX:RTMAbortThreshold=1",
+ "-XX:RTMAbortRatio=100",
+ "-XX:CompileThreshold=1",
+ "-XX:RTMRetryCount=0",
+ "-XX:RTMTotalCountIncrRate=1",
+ "-XX:+PrintPreciseRTMLockingStatistics",
+ Test.class.getName(),
+ Boolean.toString(!useStackLock)
+ );
+
+ outputAnalyzer.shouldHaveExitValue(0);
+
+ int firedTraps = RTMTestBase.firedRTMStateChangeTraps(logFileName);
+
+ Asserts.assertEQ(firedTraps, 1,
+ "Expected to get only one deoptimization due to rtm"
+ + " state change");
+
+ List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+ test.getMethodWithLockName(), outputAnalyzer.getOutput());
+
+ Asserts.assertEQ(statistics.size(), 2,
+ "VM output should contain two RTM locking "
+ + "statistics entries for method "
+ + test.getMethodWithLockName());
+
+ RTMLockingStatistics statisticsBeforeDeopt = null;
+
+ for (RTMLockingStatistics s : statistics) {
+ if (s.getTotalLocks()
+ == TestRTMDeoptOnLowAbortRatio.LOCKING_THRESHOLD + 1L) {
+ Asserts.assertNull(statisticsBeforeDeopt,
+ "Only one abort was expected during test run");
+ statisticsBeforeDeopt = s;
+ }
+ }
+
+ Asserts.assertNotNull(statisticsBeforeDeopt,
+ "After LockThreshold was reached, method should be recompiled "
+ + "with rtm lock eliding.");
+ }
+
+ public static class Test implements CompilableTest {
+ private static final Unsafe UNSAFE = Utils.getUnsafe();
+ private final Object monitor = new Object();
+
+ @Override
+ public String getMethodWithLockName() {
+ return this.getClass().getName() + "::forceAbort";
+ }
+
+ @Override
+ public String[] getMethodsToCompileNames() {
+ return new String[] {
+ getMethodWithLockName(),
+ sun.misc.Unsafe.class.getName() + "::addressSize"
+ };
+ }
+
+ public void forceAbort(boolean abort) {
+ synchronized(monitor) {
+ if (abort) {
+ Test.UNSAFE.addressSize();
+ }
+ }
+ }
+
+ /**
+ * Usage:
+ * Test <inflate monitor>
+ */
+ public static void main(String args[]) throws Throwable {
+ Asserts.assertGTE(args.length, 1, "One argument required.");
+ Test t = new Test();
+
+ if (Boolean.valueOf(args[0])) {
+ AbortProvoker.inflateMonitor(t.monitor);
+ }
+ for (int i = 0; i < AbortProvoker.DEFAULT_ITERATIONS; i++) {
+ t.forceAbort(
+ i == TestRTMDeoptOnLowAbortRatio.LOCKING_THRESHOLD);
+ }
+ }
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestRTMDeoptOnLowAbortRatio().test();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/locking/TestRTMLockingCalculationDelay.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify that RTMLockingCalculationDelay affect when
+ * abort ratio calculation is started.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestRTMLockingCalculationDelay
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI TestRTMLockingCalculationDelay
+ */
+
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+/**
+ * Test verifies that abort ratio calculation could be delayed using
+ * RTMLockingCalculationDelay option.
+ */
+public class TestRTMLockingCalculationDelay extends CommandLineOptionTest {
+ private static final boolean INFLATE_MONITOR = true;
+
+ private TestRTMLockingCalculationDelay() {
+ super(new AndPredicate(new SupportedCPU(), new SupportedVM()));
+ }
+
+ @Override
+ protected void runTestCases() throws Throwable {
+ // verify that calculation will be started immediately
+ verifyLockingCalculationDelay(0, 0, true);
+
+ // verify that calculation will not be started during
+ // first 10 minutes, while test will be started immediately
+ verifyLockingCalculationDelay(600000, 0, false);
+
+ // verify that calculation will be started after a second
+ verifyLockingCalculationDelay(1000, 1000, true);
+ }
+
+ private void verifyLockingCalculationDelay(long delay, long testDelay,
+ boolean deoptExpected) throws Throwable {
+ AbortProvoker provoker = AbortType.XABORT.provoker();
+ String logFileName = String.format("rtm_delay_%d_%d.xml", delay,
+ testDelay);
+
+ OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+ logFileName,
+ provoker,
+ "-XX:+UseRTMDeopt",
+ CommandLineOptionTest.prepareNumericFlag(
+ "RTMLockingCalculationDelay", delay),
+ "-XX:RTMAbortRatio=0",
+ "-XX:RTMAbortThreshold=0",
+ AbortProvoker.class.getName(),
+ AbortType.XABORT.toString(),
+ Boolean.toString(
+ TestRTMLockingCalculationDelay.INFLATE_MONITOR),
+ Long.toString(AbortProvoker.DEFAULT_ITERATIONS),
+ Long.toString(testDelay)
+ );
+
+ outputAnalyzer.shouldHaveExitValue(0);
+
+ int deopts = RTMTestBase.firedRTMStateChangeTraps(logFileName);
+
+ if (deoptExpected) {
+ Asserts.assertGT(deopts, 0, "At least one deoptimization due to "
+ + "rtm_state_chage is expected");
+ } else {
+ Asserts.assertEQ(deopts, 0, "No deoptimizations due to "
+ + "rtm_state_chage are expected");
+ }
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestRTMLockingCalculationDelay().test();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/locking/TestRTMLockingThreshold.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify that RTMLockingThreshold affects rtm state transition
+ * ProfileRTM => UseRTM.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestRTMLockingThreshold
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI TestRTMLockingThreshold
+ */
+
+import java.util.List;
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+import sun.misc.Unsafe;
+
+/**
+ * Test verifies that RTMLockingThreshold option actually affects how soon
+ * method will be deoptimized on low abort ratio.
+ */
+public class TestRTMLockingThreshold extends CommandLineOptionTest {
+ private TestRTMLockingThreshold() {
+ super(new AndPredicate(new SupportedVM(), new SupportedCPU()));
+ }
+
+ /**
+ * We use non-zero abort threshold to avoid abort related to
+ * interrupts, VMM calls, etc. during first lock attempt.
+ *
+ */
+ private static final int ABORT_THRESHOLD = 10;
+
+ @Override
+ protected void runTestCases() throws Throwable {
+ verifyLockingThreshold(0, false);
+ verifyLockingThreshold(100, false);
+ verifyLockingThreshold(1000, false);
+
+ verifyLockingThreshold(0, true);
+ verifyLockingThreshold(100, true);
+ verifyLockingThreshold(1000, true);
+ }
+
+ private void verifyLockingThreshold(int lockingThreshold,
+ boolean useStackLock) throws Throwable {
+ CompilableTest test = new Test();
+
+ OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+ test,
+ "-XX:CompileThreshold=1",
+ CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks",
+ useStackLock),
+ "-XX:+UseRTMDeopt",
+ "-XX:RTMTotalCountIncrRate=1",
+ "-XX:RTMRetryCount=0",
+ CommandLineOptionTest.prepareNumericFlag("RTMAbortThreshold",
+ TestRTMLockingThreshold.ABORT_THRESHOLD),
+ CommandLineOptionTest.prepareNumericFlag("RTMLockingThreshold",
+ lockingThreshold),
+ "-XX:RTMAbortRatio=100",
+ "-XX:+PrintPreciseRTMLockingStatistics",
+ Test.class.getName(),
+ Boolean.toString(!useStackLock),
+ Integer.toString(lockingThreshold)
+ );
+
+ outputAnalyzer.shouldHaveExitValue(0);
+
+ List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+ test.getMethodWithLockName(), outputAnalyzer.getOutput());
+
+ Asserts.assertEQ(statistics.size(), 2, "VM output should contain two "
+ + "RTM locking statistics entries.");
+
+ /**
+ * We force abort on each odd iteration, so if RTMLockingThreshold==0,
+ * then we have to make 1 call without abort to avoid rtm state
+ * transition to NoRTM (otherwise actual abort ratio will be 100%),
+ * and after that make 1 call with abort to force deoptimization.
+ * This leads us to two locks for threshold 0.
+ * For other threshold values we have to make RTMLockingThreshold + 1
+ * locks if locking threshold is even, or + 0 if odd.
+ */
+ long expectedValue = lockingThreshold +
+ (lockingThreshold == 0L ? 2L : lockingThreshold % 2L);
+
+ RTMLockingStatistics statBeforeDeopt = null;
+ for (RTMLockingStatistics s : statistics) {
+ if (s.getTotalLocks() == expectedValue) {
+ Asserts.assertNull(statBeforeDeopt,
+ "Only one statistics entry should contain aborts");
+ statBeforeDeopt = s;
+ }
+ }
+
+ Asserts.assertNotNull(statBeforeDeopt, "There should be exactly one "
+ + "statistics entry corresponding to ProfileRTM state.");
+ }
+
+ public static class Test implements CompilableTest {
+ // Following field have to be static in order to avoid escape analysis.
+ @SuppressWarnings("UnsuedDeclaration")
+ private static int field = 0;
+ private static final int TOTAL_ITERATIONS = 10000;
+ private static final Unsafe UNSAFE = Utils.getUnsafe();
+ private final Object monitor = new Object();
+
+
+ @Override
+ public String getMethodWithLockName() {
+ return this.getClass().getName() + "::lock";
+ }
+
+ @Override
+ public String[] getMethodsToCompileNames() {
+ return new String[] {
+ getMethodWithLockName(),
+ sun.misc.Unsafe.class.getName() + "::addressSize"
+ };
+ }
+
+ public void lock(boolean abort) {
+ synchronized(monitor) {
+ if (abort) {
+ Test.field += Test.UNSAFE.addressSize();
+ }
+ }
+ }
+
+ /**
+ * Usage:
+ * Test <inflate monitor>
+ */
+ public static void main(String args[]) throws Throwable {
+ Asserts.assertGTE(args.length, 1, "One argument required.");
+ Test t = new Test();
+
+ if (Boolean.valueOf(args[0])) {
+ AbortProvoker.inflateMonitor(t.monitor);
+ }
+ for (int i = 0; i < Test.TOTAL_ITERATIONS; i++) {
+ t.lock(i % 2 == 1);
+ }
+ }
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestRTMLockingThreshold().test();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/locking/TestRTMRetryCount.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify that RTMRetryCount affects actual amount of retries.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestRTMRetryCount
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI TestRTMRetryCount
+ */
+
+import java.util.List;
+
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+/**
+ * Test verifies that RTMRetryCount option actually affects amount of
+ * retries on lock busy.
+ */
+public class TestRTMRetryCount extends CommandLineOptionTest {
+ /**
+ * Time in ms, during which busy lock will be locked.
+ */
+ private static final int LOCKING_TIME = 5000;
+ private static final boolean INFLATE_MONITOR = true;
+
+ private TestRTMRetryCount() {
+ super(new AndPredicate(new SupportedCPU(), new SupportedVM()));
+ }
+
+ @Override
+ protected void runTestCases() throws Throwable {
+ verifyRTMRetryCount(0);
+ verifyRTMRetryCount(1);
+ verifyRTMRetryCount(5);
+ verifyRTMRetryCount(10);
+ }
+
+ private void verifyRTMRetryCount(int retryCount) throws Throwable {
+ CompilableTest busyLock = new BusyLock();
+ long expectedAborts = retryCount + 1L;
+
+ OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+ busyLock,
+ "-XX:-UseRTMXendForLockBusy",
+ "-XX:RTMTotalCountIncrRate=1",
+ CommandLineOptionTest.prepareNumericFlag("RTMRetryCount",
+ retryCount),
+ "-XX:RTMTotalCountIncrRate=1",
+ "-XX:+PrintPreciseRTMLockingStatistics",
+ BusyLock.class.getName(),
+ Boolean.toString(TestRTMRetryCount.INFLATE_MONITOR),
+ Integer.toString(TestRTMRetryCount.LOCKING_TIME)
+ );
+
+ outputAnalyzer.shouldHaveExitValue(0);
+
+ List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+ busyLock.getMethodWithLockName(), outputAnalyzer.getStdout());
+
+ Asserts.assertEQ(statistics.size(), 1, "VM output should contain "
+ + "exactly one rtm locking statistics entry for method "
+ + busyLock.getMethodWithLockName());
+
+ Asserts.assertEQ(statistics.get(0).getTotalAborts(), expectedAborts,
+ String.format("It is expected to get %d aborts",
+ expectedAborts));
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestRTMRetryCount().test();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/locking/TestRTMSpinLoopCount.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify that RTMSpinLoopCount affects time spent
+ * between locking attempts.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestRTMSpinLoopCount
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI TestRTMSpinLoopCount
+ */
+
+import java.util.List;
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+/**
+ * Test verifies that RTMSpinLoopCount increase time spent between retries
+ * by comparing amount of retries done with different RTMSpinLoopCount's values.
+ */
+public class TestRTMSpinLoopCount extends CommandLineOptionTest {
+ private static final int LOCKING_TIME = 1000;
+ private static final int RTM_RETRY_COUNT = 1000;
+ private static final boolean INFLATE_MONITOR = true;
+ private static final long MAX_ABORTS = RTM_RETRY_COUNT + 1L;
+ private static final int[] SPIN_LOOP_COUNTS
+ = new int[] { 0, 100, 1_000, 1_000_000, 10_000_000 };
+
+ private TestRTMSpinLoopCount() {
+ super(new AndPredicate(new SupportedVM(), new SupportedCPU()));
+ }
+
+ @Override
+ protected void runTestCases() throws Throwable {
+ long[] aborts = new long[TestRTMSpinLoopCount.SPIN_LOOP_COUNTS.length];
+ for (int i = 0; i < TestRTMSpinLoopCount.SPIN_LOOP_COUNTS.length; i++) {
+ aborts[i] = getAbortsCountOnLockBusy(
+ TestRTMSpinLoopCount.SPIN_LOOP_COUNTS[i]);
+ }
+
+ for (int i = 1; i < aborts.length; i++) {
+ Asserts.assertLTE(aborts[i], aborts[i - 1], "Increased spin loop "
+ + "count should not increase retries count.");
+ }
+ }
+
+ private long getAbortsCountOnLockBusy(int spinLoopCount) throws Throwable {
+ CompilableTest test = new BusyLock();
+
+ OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+ test,
+ CommandLineOptionTest.prepareNumericFlag("RTMRetryCount",
+ TestRTMSpinLoopCount.RTM_RETRY_COUNT),
+ CommandLineOptionTest.prepareNumericFlag("RTMSpinLoopCount",
+ spinLoopCount),
+ "-XX:-UseRTMXendForLockBusy",
+ "-XX:RTMTotalCountIncrRate=1",
+ "-XX:+PrintPreciseRTMLockingStatistics",
+ BusyLock.class.getName(),
+ Boolean.toString(TestRTMSpinLoopCount.INFLATE_MONITOR),
+ Integer.toString(TestRTMSpinLoopCount.LOCKING_TIME)
+ );
+
+ outputAnalyzer.shouldHaveExitValue(0);
+
+ List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+ test.getMethodWithLockName(), outputAnalyzer.getOutput());
+
+ Asserts.assertEQ(statistics.size(), 1,
+ "VM output should contain exactly one entry for method "
+ + test.getMethodWithLockName());
+
+ RTMLockingStatistics lock = statistics.get(0);
+
+ Asserts.assertLTE(lock.getTotalAborts(),
+ TestRTMSpinLoopCount.MAX_ABORTS, String.format("Total aborts "
+ + "count (%d) should be less or equal to %d",
+ lock.getTotalAborts(),
+ TestRTMSpinLoopCount.MAX_ABORTS));
+
+ return lock.getTotalAborts();
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestRTMSpinLoopCount().test();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify that RTMTotalCountIncrRate option affects
+ * RTM locking statistics.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestRTMTotalCountIncrRate
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI TestRTMTotalCountIncrRate
+ */
+
+import java.util.List;
+
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+/**
+ * Test verifies that with RTMTotalCountIncrRate=1 RTM locking statistics
+ * contains precise information abort attempted locks and that with other values
+ * statistics contains information abort non-zero locking attempts.
+ * Since assert done for RTMTotalCountIncrRate=1 is pretty strict, test uses
+ * -XX:RTMRetryCount=0 to avoid issue with retriable aborts. For more details on
+ * that issue see {@link TestUseRTMAfterLockInflation}.
+ */
+public class TestRTMTotalCountIncrRate extends CommandLineOptionTest {
+ private TestRTMTotalCountIncrRate() {
+ super(new AndPredicate(new SupportedCPU(), new SupportedVM()));
+ }
+
+ @Override
+ protected void runTestCases() throws Throwable {
+ verifyLocksCount(1, false);
+ verifyLocksCount(64, false);
+ verifyLocksCount(128, false);
+ verifyLocksCount(1, true);
+ verifyLocksCount(64, true);
+ verifyLocksCount(128, true);
+ }
+
+ private void verifyLocksCount(int incrRate, boolean useStackLock)
+ throws Throwable{
+ CompilableTest test = new Test();
+
+ OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+ test,
+ CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks",
+ useStackLock),
+ CommandLineOptionTest.prepareNumericFlag(
+ "RTMTotalCountIncrRate", incrRate),
+ "-XX:RTMRetryCount=0",
+ "-XX:+PrintPreciseRTMLockingStatistics",
+ Test.class.getName(),
+ Boolean.toString(!useStackLock)
+ );
+
+ outputAnalyzer.shouldHaveExitValue(0);
+
+ List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+ test.getMethodWithLockName(), outputAnalyzer.getOutput());
+
+ Asserts.assertEQ(statistics.size(), 1, "VM output should contain "
+ + "exactly one RTM locking statistics entry for method "
+ + test.getMethodWithLockName());
+
+ RTMLockingStatistics lock = statistics.get(0);
+ if (incrRate == 1) {
+ Asserts.assertEQ(lock.getTotalLocks(), Test.TOTAL_ITERATIONS,
+ "Total locks should be exactly the same as amount of "
+ + "iterations.");
+ } else {
+ Asserts.assertGT(lock.getTotalLocks(), 0L, "RTM statistics "
+ + "should contain information for at least on lock.");
+ }
+ }
+
+ public static class Test implements CompilableTest {
+ private static final long TOTAL_ITERATIONS = 10000L;
+ private final Object monitor = new Object();
+ // Following field have to be static in order to avoid escape analysis.
+ @SuppressWarnings("UnsuedDeclaration")
+ private static int field = 0;
+
+ @Override
+ public String getMethodWithLockName() {
+ return this.getClass().getName() + "::lock";
+ }
+
+ @Override
+ public String[] getMethodsToCompileNames() {
+ return new String[] {
+ getMethodWithLockName()
+ };
+ }
+
+ public void lock() {
+ synchronized(monitor) {
+ Test.field++;
+ }
+ }
+
+ /**
+ * Usage:
+ * Test <inflate monitor>
+ */
+ public static void main(String args[]) throws Throwable {
+ Asserts.assertGTE(args.length, 1, "One argument required.");
+ Test test = new Test();
+
+ if (Boolean.valueOf(args[0])) {
+ AbortProvoker.inflateMonitor(test.monitor);
+ }
+ for (long i = 0L; i < Test.TOTAL_ITERATIONS; i++) {
+ test.lock();
+ }
+ }
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestRTMTotalCountIncrRate().test();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/locking/TestUseRTMAfterLockInflation.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify that rtm locking is used for stack locks before
+ * inflation and after it used for inflated locks.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestUseRTMAfterLockInflation
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI TestUseRTMAfterLockInflation
+ */
+
+import java.util.List;
+
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+/**
+ * Test verifies that RTM is used after lock inflation by executing compiled
+ * method with RTM-based lock elision using stack lock first, then that lock
+ * is inflated and the same compiled method invoked again.
+ *
+ * Compiled method invoked {@code AbortProvoker.DEFAULT_ITERATIONS} times before
+ * lock inflation and the same amount of times after inflation.
+ * As a result total locks count should be equal to
+ * {@code 2*AbortProvoker.DEFAULT_ITERATIONS}.
+ * It is a pretty strict assertion which could fail if some retriable abort
+ * happened: it could be {@code AbortType.RETRIABLE} or
+ * {@code AbortType.MEM_CONFLICT}, but unfortunately abort can has both these
+ * reasons simultaneously. In order to avoid false negative failures related
+ * to incorrect aborts counting, -XX:RTMRetryCount=0 is used.
+ */
+public class TestUseRTMAfterLockInflation extends CommandLineOptionTest {
+ private static final long EXPECTED_LOCKS
+ = 2L * AbortProvoker.DEFAULT_ITERATIONS;
+
+ private TestUseRTMAfterLockInflation() {
+ super(new AndPredicate(new SupportedVM(), new SupportedCPU()));
+ }
+
+ @Override
+ protected void runTestCases() throws Throwable {
+ AbortProvoker provoker = AbortType.XABORT.provoker();
+ long totalLocksCount = 0;
+
+ OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+ provoker,
+ "-XX:+UseRTMForStackLocks",
+ "-XX:RTMTotalCountIncrRate=1",
+ "-XX:RTMRetryCount=0",
+ "-XX:+PrintPreciseRTMLockingStatistics",
+ Test.class.getName(),
+ AbortType.XABORT.toString());
+
+ outputAnalyzer.shouldHaveExitValue(0);
+
+ List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+ provoker.getMethodWithLockName(), outputAnalyzer.getOutput());
+
+ Asserts.assertEQ(statistics.size(), 2,
+ "VM output should contain two rtm locking statistics entries "
+ + "for method " + provoker.getMethodWithLockName());
+
+ for (RTMLockingStatistics s : statistics) {
+ totalLocksCount += s.getTotalLocks();
+ }
+
+ Asserts.assertEQ(totalLocksCount,
+ TestUseRTMAfterLockInflation.EXPECTED_LOCKS,
+ "Total lock count should be greater or equal to "
+ + TestUseRTMAfterLockInflation.EXPECTED_LOCKS);
+ }
+
+ public static class Test {
+
+ /**
+ * Usage:
+ * Test <provoker type>
+ */
+ public static void main(String args[]) throws Throwable {
+ Asserts.assertGT(args.length, 0,
+ "AbortType name is expected as first argument.");
+
+ AbortProvoker provoker
+ = AbortType.lookup(Integer.valueOf(args[0])).provoker();
+ for (int i = 0; i < AbortProvoker.DEFAULT_ITERATIONS; i++) {
+ provoker.forceAbort();
+ }
+ provoker.inflateMonitor();
+ for (int i = 0; i < AbortProvoker.DEFAULT_ITERATIONS; i++) {
+ provoker.forceAbort();
+ }
+ }
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestUseRTMAfterLockInflation().test();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/locking/TestUseRTMDeopt.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify that UseRTMDeopt affects uncommon trap installation in
+ * copmpiled methods with synchronized block.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestUseRTMDeopt
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI TestUseRTMDeopt
+ */
+
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+/**
+ * Test verifies that usage of UseRTMDeopt option affects uncommon traps usage
+ * for methods that use locking.
+ */
+public class TestUseRTMDeopt extends CommandLineOptionTest {
+ private TestUseRTMDeopt() {
+ super(new AndPredicate(new SupportedVM(), new SupportedCPU()));
+ }
+
+ @Override
+ protected void runTestCases() throws Throwable {
+ verifyUseRTMDeopt(false);
+ verifyUseRTMDeopt(true);
+ }
+
+ private void verifyUseRTMDeopt(boolean useRTMDeopt) throws Throwable {
+ AbortProvoker provoker = AbortType.XABORT.provoker();
+ String logFileName = String.format("rtm_%s_deopt.xml",
+ useRTMDeopt ? "use" : "no");
+
+ OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+ logFileName,
+ provoker,
+ CommandLineOptionTest.prepareBooleanFlag("UseRTMDeopt",
+ useRTMDeopt),
+ AbortProvoker.class.getName(),
+ AbortType.XABORT.toString()
+ );
+
+ outputAnalyzer.shouldHaveExitValue(0);
+
+ int expectedUncommonTraps = useRTMDeopt ? 1 : 0;
+ int installedUncommonTraps
+ = RTMTestBase.installedRTMStateChangeTraps(logFileName);
+
+ Asserts.assertEQ(expectedUncommonTraps, installedUncommonTraps,
+ String.format("Expected to find %d uncommon traps "
+ + "installed with reason rtm_state_change.",
+ expectedUncommonTraps));
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestUseRTMDeopt().test();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/locking/TestUseRTMForInflatedLocks.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify that rtm locking is used for inflated locks.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestUseRTMForInflatedLocks
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI TestUseRTMForInflatedLocks
+ */
+
+import java.util.List;
+
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+/**
+ * Test verifies that RTM-based lock elision could be used for inflated locks
+ * by calling compiled method that use RTM-based lock elision and using
+ * manually inflated lock.
+ * Compiled method invoked {@code AbortProvoker.DEFAULT_ITERATIONS} times,
+ * so total locks count should be the same.
+ * This test could also be affected by retriable aborts, so -XX:RTMRetryCount=0
+ * is used. For more information abort that issue see
+ * {@link TestUseRTMAfterLockInflation}.
+ */
+public class TestUseRTMForInflatedLocks extends CommandLineOptionTest {
+ private TestUseRTMForInflatedLocks() {
+ super(new AndPredicate(new SupportedCPU(), new SupportedVM()));
+ }
+
+ @Override
+ protected void runTestCases() throws Throwable {
+ AbortProvoker provoker = AbortType.XABORT.provoker();
+ RTMLockingStatistics lock;
+
+ OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+ provoker,
+ "-XX:-UseRTMForStackLocks",
+ "-XX:RTMTotalCountIncrRate=1",
+ "-XX:RTMRetryCount=0",
+ "-XX:+PrintPreciseRTMLockingStatistics",
+ AbortProvoker.class.getName(),
+ AbortType.XABORT.toString());
+
+ outputAnalyzer.shouldHaveExitValue(0);
+
+ List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+ provoker.getMethodWithLockName(), outputAnalyzer.getOutput());
+
+ Asserts.assertEQ(statistics.size(), 1,
+ "VM output should contain exactly one rtm locking statistics "
+ + "entry for method " + provoker.getMethodWithLockName());
+
+ lock = statistics.get(0);
+ Asserts.assertEQ(lock.getTotalLocks(), AbortProvoker.DEFAULT_ITERATIONS,
+ "Total lock count should be greater or equal to "
+ + AbortProvoker.DEFAULT_ITERATIONS);
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestUseRTMForInflatedLocks().test();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/locking/TestUseRTMForStackLocks.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify that rtm locking is used for stack locks.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestUseRTMForStackLocks
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI TestUseRTMForStackLocks
+ */
+
+import java.util.List;
+
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+/**
+ * Test verifies that RTM-based lock elision could be used for stack locks
+ * by calling compiled method that use RTM-based lock elision and using
+ * stack lock.
+ * Compiled method invoked {@code AbortProvoker.DEFAULT_ITERATIONS} times,
+ * so total locks count should be the same.
+ * This test could also be affected by retriable aborts, so -XX:RTMRetryCount=0
+ * is used. For more information abort that issue see
+ * {@link TestUseRTMAfterLockInflation}.
+ */
+public class TestUseRTMForStackLocks extends CommandLineOptionTest {
+ private static final boolean INFLATE_MONITOR = false;
+
+ private TestUseRTMForStackLocks() {
+ super(new AndPredicate(new SupportedCPU(), new SupportedVM()));
+ }
+
+ @Override
+ protected void runTestCases() throws Throwable {
+ AbortProvoker provoker = AbortType.XABORT.provoker();
+ RTMLockingStatistics lock;
+
+ OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+ provoker,
+ "-XX:+UseRTMForStackLocks",
+ "-XX:RTMTotalCountIncrRate=1",
+ "-XX:RTMRetryCount=0",
+ "-XX:+PrintPreciseRTMLockingStatistics",
+ AbortProvoker.class.getName(),
+ AbortType.XABORT.toString(),
+ Boolean.toString(TestUseRTMForStackLocks.INFLATE_MONITOR));
+
+ outputAnalyzer.shouldHaveExitValue(0);
+
+ List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+ provoker.getMethodWithLockName(), outputAnalyzer.getOutput());
+
+ Asserts.assertEQ(statistics.size(), 1,
+ "VM output should contain exactly one rtm locking statistics "
+ + "entry for method " + provoker.getMethodWithLockName());
+
+ lock = statistics.get(0);
+ Asserts.assertEQ(lock.getTotalLocks(), AbortProvoker.DEFAULT_ITERATIONS,
+ "Total locks count should be greater or equal to "
+ + AbortProvoker.DEFAULT_ITERATIONS);
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestUseRTMForStackLocks().test();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/locking/TestUseRTMXendForLockBusy.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify that UseRTMXendForLockBusy option affects
+ * method behaviour if lock is busy.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestUseRTMXendForLockBusy
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI TestUseRTMXendForLockBusy
+ */
+
+import java.util.List;
+
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+/**
+ * Test verifies that with +UseRTMXendForLockBusy there will be no aborts
+ * forced by the test.
+ */
+public class TestUseRTMXendForLockBusy extends CommandLineOptionTest {
+ private final static int LOCKING_TIME = 5000;
+
+ private TestUseRTMXendForLockBusy() {
+ super(new AndPredicate(new SupportedVM(), new SupportedCPU()));
+ }
+
+ @Override
+ protected void runTestCases() throws Throwable {
+ // inflated lock, xabort on lock busy
+ verifyXendForLockBusy(true, false);
+ // inflated lock, xend on lock busy
+ verifyXendForLockBusy(true, true);
+ // stack lock, xabort on lock busy
+ verifyXendForLockBusy(false, false);
+ // stack lock, xend on lock busy
+ verifyXendForLockBusy(false, true);
+ }
+
+ private void verifyXendForLockBusy(boolean inflateMonitor,
+ boolean useXend) throws Throwable {
+ CompilableTest test = new BusyLock();
+
+ OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+ test,
+ CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks",
+ inflateMonitor),
+ CommandLineOptionTest.prepareBooleanFlag(
+ "UseRTMXendForLockBusy",
+ useXend),
+ "-XX:RTMRetryCount=0",
+ "-XX:RTMTotalCountIncrRate=1",
+ "-XX:+PrintPreciseRTMLockingStatistics",
+ BusyLock.class.getName(),
+ Boolean.toString(inflateMonitor),
+ Integer.toString(TestUseRTMXendForLockBusy.LOCKING_TIME)
+ );
+
+ outputAnalyzer.shouldHaveExitValue(0);
+
+ List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+ test.getMethodWithLockName(), outputAnalyzer.getOutput());
+
+ Asserts.assertEQ(statistics.size(), 1, "VM output should contain "
+ + "exactly one rtm locking statistics entry for method "
+ + test.getMethodWithLockName());
+
+ long aborts = statistics.get(0).getAborts(AbortType.XABORT);
+
+ if (useXend) {
+ Asserts.assertEQ(aborts, 0L,
+ "Expected to get no aborts on busy lock");
+ } else {
+ Asserts.assertGT(aborts, 0L,
+ "Expected to get at least one abort on busy lock");
+ }
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestUseRTMXendForLockBusy().test();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/method_options/TestNoRTMLockElidingOption.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify that NoRTMLockEliding option could be applied to
+ * specified method and that such method will not use rtm.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestNoRTMLockElidingOption
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI TestNoRTMLockElidingOption
+ */
+
+import java.util.List;
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+/**
+ * Test verifies that method tagged with option <i>NoRTMLockElidingOption</i>
+ * will not use RTM-based lock elision.
+ * Test invokes compiled method and checks that no deoptimization with
+ * <i>rtm_state_change</i> reason had happened and that that VM output
+ * does not contain RTM locking statistics for compiled method.
+ */
+public class TestNoRTMLockElidingOption extends CommandLineOptionTest {
+ private TestNoRTMLockElidingOption() {
+ super(new AndPredicate(new SupportedCPU(), new SupportedVM()));
+ }
+
+ @Override
+ public void runTestCases() throws Throwable {
+ verifyOption(false);
+ verifyOption(true);
+ }
+
+ public void verifyOption(boolean useStackLock) throws Throwable {
+ AbortProvoker provoker = AbortType.XABORT.provoker();
+ String logFileName = String.format("rtm_deopt_%s_stack_lock.xml",
+ (useStackLock ? "use" : "no"));
+ String methodOption = String.format("-XX:CompileCommand=option," +
+ "%s,NoRTMLockEliding", provoker.getMethodWithLockName());
+
+ OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+ logFileName,
+ provoker,
+ CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks",
+ useStackLock),
+ methodOption,
+ "-XX:RTMTotalCountIncrRate=1",
+ "-XX:+UseRTMDeopt",
+ "-XX:+PrintPreciseRTMLockingStatistics",
+ AbortProvoker.class.getName(),
+ AbortType.XABORT.toString(),
+ Boolean.toString(!useStackLock)
+ );
+
+ outputAnalyzer.shouldHaveExitValue(0);
+
+ int firedTraps = RTMTestBase.firedRTMStateChangeTraps(logFileName);
+
+ Asserts.assertEQ(firedTraps, 0,
+ "No deoptimizations with rtm_state_change reason are expected");
+
+ List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+ provoker.getMethodWithLockName(), outputAnalyzer.getOutput());
+
+ Asserts.assertEQ(statistics.size(), 0,
+ "VM output should not contain RTM locking statistics entries "
+ + "for method " + provoker.getMethodWithLockName());
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestNoRTMLockElidingOption().test();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/method_options/TestUseRTMLockElidingOption.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify that UseRTMLockEliding option could be applied to
+ * specified method and that such method will not be deoptimized
+ * on high abort ratio.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestUseRTMLockElidingOption
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI TestUseRTMLockElidingOption
+ */
+
+import java.util.List;
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+/**
+ * Test verifies that method tagged with option <i>UseRTMLockElidingOption</i>
+ * will use RTM-based lock elision, but will be never deoptimized with
+ * <i>rtm_state_change reason</i>.
+ * Test invokes compiled method and checks that no deoptimization with
+ * <i>rtm_state_change</i> reason had happened and that that VM output
+ * contains RTM locking statistics for compiled method and that total locks
+ * count equals to method's invocations.
+ * Since last assert is pretty strict, test uses -XX:RTMRetryCount=0 in order
+ * to avoid issue with retriable aborts described in
+ * {@link TestUseRTMAfterLockInflation}.
+ */
+public class TestUseRTMLockElidingOption extends CommandLineOptionTest {
+ private TestUseRTMLockElidingOption() {
+ super(new AndPredicate(new SupportedCPU(), new SupportedVM()));
+ }
+
+ @Override
+ public void runTestCases() throws Throwable {
+ verifyOption(false);
+ verifyOption(true);
+ }
+
+ public void verifyOption(boolean useStackLock) throws Throwable {
+ AbortProvoker provoker = AbortType.XABORT.provoker();
+ String logFileName = String.format("rtm_deopt_%s_stack_lock.xml",
+ (useStackLock ? "use" : "no"));
+ String methodOption = String.format("-XX:CompileCommand=option," +
+ "%s,UseRTMLockEliding", provoker.getMethodWithLockName());
+
+ OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+ logFileName,
+ provoker,
+ CommandLineOptionTest.prepareBooleanFlag("UseRTMForStackLocks",
+ useStackLock),
+ methodOption,
+ "-XX:RTMTotalCountIncrRate=1",
+ "-XX:RTMRetryCount=0",
+ "-XX:+UseRTMDeopt",
+ "-XX:+PrintPreciseRTMLockingStatistics",
+ provoker.getClass().getName(),
+ AbortType.XABORT.toString(),
+ Boolean.toString(!useStackLock)
+ );
+
+ outputAnalyzer.shouldHaveExitValue(0);
+
+ int firedTraps = RTMTestBase.firedRTMStateChangeTraps(logFileName);
+
+ Asserts.assertEQ(firedTraps, 0,
+ "Method deoptimization with rtm_state_change is unexpected");
+
+ List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+ provoker.getMethodWithLockName(), outputAnalyzer.getOutput());
+
+ Asserts.assertEQ(statistics.size(), 1,
+ "VM output should contain exactly one RTM locking "
+ + "statistics entry for method "
+ + provoker.getMethodWithLockName());
+
+ RTMLockingStatistics lock = statistics.get(0);
+
+ Asserts.assertEQ(lock.getTotalLocks(), AbortProvoker.DEFAULT_ITERATIONS,
+ "Expected to get total locks count equal to total amount of "
+ + "lock attempts.");
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestUseRTMLockElidingOption().test();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/rtm/print/TestPrintPreciseRTMLockingStatistics.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 8031320
+ * @summary Verify that rtm locking statistics contain proper information
+ * on overall aborts and locks count and count of aborts of
+ * different types. Test also verify that VM output does not
+ * contain rtm locking statistics when it should not.
+ * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary
+ * @build TestPrintPreciseRTMLockingStatistics
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+WhiteBoxAPI TestPrintPreciseRTMLockingStatistics
+ */
+
+import java.util.*;
+
+import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+import com.oracle.java.testlibrary.cli.predicate.AndPredicate;
+import rtm.*;
+import rtm.predicate.SupportedCPU;
+import rtm.predicate.SupportedVM;
+
+/**
+ * Test verifies that VM output does not contain RTM locking statistics when it
+ * should not (when PrintPreciseRTMLockingStatistics is off) and that with
+ * -XX:+PrintPreciseRTMLockingStatistics locking statistics contains sane
+ * total locks and aborts count as well as for specific abort types.
+ */
+public class TestPrintPreciseRTMLockingStatistics
+ extends CommandLineOptionTest {
+ private TestPrintPreciseRTMLockingStatistics() {
+ super(new AndPredicate(new SupportedCPU(), new SupportedVM()));
+ }
+
+ @Override
+ public void runTestCases() throws Throwable {
+ verifyNoStatistics();
+ verifyStatistics();
+ }
+
+ // verify that VM output does not contain
+ // rtm locking statistics
+ private void verifyNoStatistics() throws Throwable {
+ verifyNoStatistics(AbortType.XABORT);
+
+ verifyNoStatistics(AbortType.XABORT,
+ "-XX:-PrintPreciseRTMLockingStatistics");
+
+ verifyNoStatistics(AbortType.XABORT, "-XX:-UseRTMLocking",
+ "-XX:+PrintPreciseRTMLockingStatistics");
+ }
+
+ // verify that rtm locking statistics contain information
+ // about each type of aborts
+ private void verifyStatistics() throws Throwable {
+ verifyAbortsCount(AbortType.XABORT);
+ verifyAbortsCount(AbortType.MEM_CONFLICT);
+ verifyAbortsCount(AbortType.BUF_OVERFLOW);
+ verifyAbortsCount(AbortType.NESTED_ABORT);
+ }
+
+ private void verifyNoStatistics(AbortType abortProvokerType,
+ String... vmOpts) throws Throwable {
+ AbortProvoker provoker = abortProvokerType.provoker();
+ List<String> finalVMOpts = new LinkedList<>();
+ Collections.addAll(finalVMOpts, vmOpts);
+ Collections.addAll(finalVMOpts, AbortProvoker.class.getName(),
+ abortProvokerType.toString());
+
+ OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(provoker,
+ finalVMOpts.toArray(new String[finalVMOpts.size()]));
+
+ outputAnalyzer.shouldHaveExitValue(0);
+
+ List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+ outputAnalyzer.getOutput());
+
+ Asserts.assertEQ(statistics.size(), 0, "VM output should not contain "
+ + "any RTM locking statistics");
+ }
+
+ private void verifyAbortsCount(AbortType abortType) throws Throwable {
+ AbortProvoker provoker = abortType.provoker();
+
+ OutputAnalyzer outputAnalyzer = RTMTestBase.executeRTMTest(
+ provoker,
+ "-XX:+PrintPreciseRTMLockingStatistics",
+ AbortProvoker.class.getName(),
+ abortType.toString());
+
+ outputAnalyzer.shouldHaveExitValue(0);
+
+ List<RTMLockingStatistics> statistics = RTMLockingStatistics.fromString(
+ provoker.getMethodWithLockName(),outputAnalyzer.getOutput());
+
+ Asserts.assertGT(statistics.size(), 0, "VM output should contain one "
+ + "rtm locking statistics entry for method "
+ + provoker.getMethodWithLockName());
+
+ RTMLockingStatistics lock = statistics.get(0);
+
+ Asserts.assertGT(lock.getTotalLocks(), 0L, "RTM locking statistics "
+ + "should contain non zero total locks count");
+
+ Asserts.assertGT(lock.getTotalAborts(), 0L,
+ "RTM locking statistics should contain non zero total aborts "
+ + "count");
+
+ Asserts.assertGT(lock.getAborts(abortType), 0L, String.format(
+ "RTM locking statistics should contain non zero aborts count "
+ + "for abort reason %s", abortType));
+ }
+
+ public static void main(String args[]) throws Throwable {
+ new TestPrintPreciseRTMLockingStatistics().test();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/testlibrary/rtm/AbortProvoker.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2014, 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 rtm;
+
+import java.util.Objects;
+import java.util.concurrent.BrokenBarrierException;
+import java.util.concurrent.CyclicBarrier;
+
+import com.oracle.java.testlibrary.Asserts;
+import com.oracle.java.testlibrary.Utils;
+import sun.misc.Unsafe;
+
+/**
+ * Base class for different transactional execution abortion
+ * provokers aimed to force abort due to specified reason.
+ */
+public abstract class AbortProvoker implements CompilableTest {
+ public static final long DEFAULT_ITERATIONS = 10000L;
+ /**
+ * Inflates monitor associated with object {@code monitor}.
+ * Inflation is forced by entering the same monitor from
+ * two different threads.
+ *
+ * @param monitor monitor to be inflated.
+ * @return inflated monitor.
+ * @throws Exception if something went wrong.
+ */
+ public static Object inflateMonitor(Object monitor) throws Exception {
+ Unsafe unsafe = Utils.getUnsafe();
+ CyclicBarrier barrier = new CyclicBarrier(2);
+
+ Runnable inflatingRunnable = () -> {
+ unsafe.monitorEnter(monitor);
+ try {
+ barrier.await();
+ barrier.await();
+ } catch (InterruptedException | BrokenBarrierException e) {
+ throw new RuntimeException(
+ "Synchronization issue occurred.", e);
+ } finally {
+ unsafe.monitorExit(monitor);
+ }
+ };
+
+ Thread t = new Thread(inflatingRunnable);
+ t.start();
+ // Wait until thread t enters the monitor.
+ barrier.await();
+ // At this point monitor will be owned by thread t,
+ // so our attempt to enter the same monitor will force
+ // monitor inflation.
+ Asserts.assertFalse(unsafe.tryMonitorEnter(monitor),
+ "Not supposed to enter the monitor first");
+ barrier.await();
+ t.join();
+ return monitor;
+ }
+
+
+ /**
+ * Get instance of specified AbortProvoker, inflate associated monitor
+ * if needed and then invoke forceAbort method in a loop.
+ *
+ * Usage:
+ * AbortProvoker <AbortType name> [<inflate monitor>
+ * [<iterations> [ <delay>]]]
+ *
+ * Default parameters are:
+ * <ul>
+ * <li>inflate monitor = <b>true</b></li>
+ * <li>iterations = {@code AbortProvoker.DEFAULT_ITERATIONS}</li>
+ * <li>delay = <b>0</b></li>
+ * </ul>
+ */
+ public static void main(String args[]) throws Throwable {
+ Asserts.assertGT(args.length, 0, "At least one argument is required.");
+
+ AbortType abortType = AbortType.lookup(Integer.valueOf(args[0]));
+ boolean monitorShouldBeInflated = true;
+ long iterations = AbortProvoker.DEFAULT_ITERATIONS;
+
+ if (args.length > 1) {
+ monitorShouldBeInflated = Boolean.valueOf(args[1]);
+
+ if (args.length > 2) {
+ iterations = Long.valueOf(args[2]);
+
+ if (args.length > 3) {
+ Thread.sleep(Integer.valueOf(args[3]));
+ }
+ }
+ }
+
+ AbortProvoker provoker = abortType.provoker();
+
+ if (monitorShouldBeInflated) {
+ provoker.inflateMonitor();
+ }
+
+ for (long i = 0; i < iterations; i++) {
+ provoker.forceAbort();
+ }
+ }
+
+ protected final Object monitor;
+
+ protected AbortProvoker() {
+ this(new Object());
+ }
+
+ protected AbortProvoker(Object monitor) {
+ this.monitor = Objects.requireNonNull(monitor);
+ }
+
+ /**
+ * Inflates monitor used by this AbortProvoker instance.
+ * @throws Exception
+ */
+ public void inflateMonitor() throws Exception {
+ AbortProvoker.inflateMonitor(monitor);
+ }
+
+ /**
+ * Forces transactional execution abortion.
+ */
+ public abstract void forceAbort();
+
+ /**
+ * Returns names of all methods that have to be compiled
+ * in order to successfully force transactional execution
+ * abortion.
+ *
+ * @return array with methods' names that have to be compiled.
+ */
+ @Override
+ public String[] getMethodsToCompileNames() {
+ return new String[] { getMethodWithLockName() };
+ }
+
+ /**
+ * Returns name of the method that will contain monitor whose locking
+ * will be elided using transactional execution.
+ *
+ * @return name of the method that will contain elided lock.
+ */
+ @Override
+ public String getMethodWithLockName() {
+ return this.getClass().getName() + "::forceAbort";
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/testlibrary/rtm/AbortType.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2014, 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 rtm;
+
+import com.oracle.java.testlibrary.Asserts;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Type of transactional execution abort.
+ * For more details on different abort types please see
+ * shared/vm/runtime/rtmLocking.hpp
+ */
+public enum AbortType {
+ XABORT(0),
+ RETRIABLE(1),
+ MEM_CONFLICT(2),
+ BUF_OVERFLOW(3),
+ DEBUG_BREAKPOINT(4),
+ NESTED_ABORT(5);
+
+ private final int type;
+ private static final Map<Integer, AbortType> LOOKUP_MAP = new HashMap<>();
+
+ static {
+ for (AbortType abortType : AbortType.values()) {
+ Asserts.assertFalse(LOOKUP_MAP.containsKey(abortType.type),
+ "Abort type values should be unique.");
+ LOOKUP_MAP.put(abortType.type, abortType);
+ }
+ }
+
+ private AbortType(int type) {
+ this.type = type;
+ }
+
+ /**
+ * Returns AbortProvoker for aborts represented by this abort type.
+ *
+ * @return an AbortProvoker instance
+ */
+ public AbortProvoker provoker() {
+ return AbortType.createNewProvoker(this);
+ }
+
+ public static AbortType lookup(int type) {
+ Asserts.assertLT(type, AbortType.values().length,
+ "Unknown abort type.");
+ return LOOKUP_MAP.get(type);
+ }
+
+ /**
+ * Returns transaction execution abort provoker for specified abortion type.
+ *
+ * @param type a type of abort which will be forced by returned
+ * AbortProvoker instance.
+ * @return AbortProvoker instance that will force abort of specified type
+ * @throws RuntimeException if there is no provoker for specified type
+ */
+ private static AbortProvoker createNewProvoker(AbortType type) {
+ switch (type) {
+ case XABORT:
+ return new XAbortProvoker();
+ case MEM_CONFLICT:
+ return new MemoryConflictProvoker();
+ case BUF_OVERFLOW:
+ return new BufferOverflowProvoker();
+ case NESTED_ABORT:
+ return new NestedAbortProvoker();
+ default:
+ throw new RuntimeException("No provoker exists for type "
+ + type.name());
+ }
+ }
+
+ @Override
+ public String toString() {
+ return Integer.toString(type);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/testlibrary/rtm/BufferOverflowProvoker.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2014, 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 rtm;
+
+/**
+ * In order to provoke transactional execution abort due to
+ * internal's buffer overflow BufferOverflowProvoker modifies
+ * 1MB of BYTES during single transaction.
+ */
+class BufferOverflowProvoker extends AbortProvoker {
+ /**
+ * To force buffer overflow abort we modify memory region with
+ * size more then L1d cache size.
+ */
+ private static final int MORE_THAN_L1D_SIZE = 1024 * 1024;
+ private static final byte[] DATA = new byte[MORE_THAN_L1D_SIZE];
+
+ @Override
+ public void forceAbort() {
+ synchronized(monitor) {
+ for (int i = 0; i < BufferOverflowProvoker.DATA.length; i++) {
+ BufferOverflowProvoker.DATA[i]++;
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/testlibrary/rtm/BusyLock.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2014, 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 rtm;
+
+import com.oracle.java.testlibrary.Utils;
+import sun.misc.Unsafe;
+
+import java.util.concurrent.BrokenBarrierException;
+import java.util.concurrent.CyclicBarrier;
+
+/**
+ * Test case for busy lock scenario.
+ * One thread enters the monitor and sleep for a while.
+ * Another thread is blocked on the same monitor.
+ */
+public class BusyLock implements CompilableTest, Runnable {
+ private static final int DEFAULT_TIMEOUT = 1000;
+ private final CyclicBarrier barrier;
+
+ // Following field have to be static in order to avoid escape analysis.
+ @SuppressWarnings("UnsuedDeclaration")
+ private static int field = 0;
+ private static final Unsafe UNSAFE = Utils.getUnsafe();
+ protected final Object monitor;
+ protected final int timeout;
+
+ public BusyLock() {
+ this(BusyLock.DEFAULT_TIMEOUT);
+ }
+
+ public BusyLock(int timeout) {
+ this.timeout = timeout;
+ this.monitor = new Object();
+ this.barrier = new CyclicBarrier(2);
+ }
+
+ @Override
+ public void run() {
+ try {
+ // wait until forceAbort leave monitor
+ barrier.await();
+ if (UNSAFE.tryMonitorEnter(monitor)) {
+ try {
+ barrier.await();
+ Thread.sleep(timeout);
+ } finally {
+ UNSAFE.monitorExit(monitor);
+ }
+ } else {
+ throw new RuntimeException("Monitor should be entered by " +
+ "::run() first.");
+ }
+ } catch (InterruptedException | BrokenBarrierException e) {
+ throw new RuntimeException("Synchronization error happened.", e);
+ }
+ }
+
+ public void test() {
+ try {
+ barrier.await();
+ // wait until monitor is locked by a ::run method
+ barrier.await();
+ } catch (InterruptedException | BrokenBarrierException e) {
+ throw new RuntimeException("Synchronization error happened.", e);
+ }
+ synchronized(monitor) {
+ BusyLock.field++;
+ }
+ }
+
+ @Override
+ public String getMethodWithLockName() {
+ return this.getClass().getName() + "::test";
+ }
+
+ @Override
+ public String[] getMethodsToCompileNames() {
+ return new String[] { getMethodWithLockName() };
+ }
+
+ /**
+ * Usage:
+ * BusyLock [ <inflate monitor> [ <timeout> ] ]
+ *
+ * Default values are:
+ * <ul>
+ * <li>inflate monitor = {@code true}</li>
+ * <li>timeout = {@code BusyLock.DEFAULT_TIMEOUT}</li>
+ * </ul>
+ */
+ public static void main(String args[]) throws Exception {
+ int timeoutValue = BusyLock.DEFAULT_TIMEOUT;
+ boolean inflateMonitor = true;
+
+ if (args.length > 0 ) {
+ inflateMonitor = Boolean.valueOf(args[0]);
+
+ if (args.length > 1) {
+ timeoutValue = Integer.valueOf(args[1]);
+ }
+ }
+
+ BusyLock busyLock = new BusyLock(timeoutValue);
+
+ if (inflateMonitor) {
+ AbortProvoker.inflateMonitor(busyLock.monitor);
+ }
+
+ Thread t = new Thread(busyLock);
+ t.start();
+ busyLock.test();
+ t.join();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/testlibrary/rtm/CompilableTest.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2014, 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 rtm;
+
+/**
+ * Interface for test scenarios that contain methods
+ * that should be compiled.
+ */
+public interface CompilableTest {
+ /**
+ * @return array with methods' names that should be compiled.
+ */
+ String[] getMethodsToCompileNames();
+
+ /**
+ * @return name of method with RTM-elided lock.
+ */
+ String getMethodWithLockName();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/testlibrary/rtm/MemoryConflictProvoker.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2014, 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 rtm;
+
+import java.util.concurrent.BrokenBarrierException;
+import java.util.concurrent.CyclicBarrier;
+
+/**
+ * To force transactional execution abort due to memory conflict
+ * one thread should access memory region from transactional region
+ * while another thread should modify the same memory region.
+ * Since this scenario is based on the race condition between threads
+ * you should not expect some particular amount of aborts.
+ */
+class MemoryConflictProvoker extends AbortProvoker {
+ // Following field have to be static in order to avoid escape analysis.
+ @SuppressWarnings("UnsuedDeclaration")
+ private static int field = 0;
+ private static final int INNER_ITERATIONS = 10000;
+ private final CyclicBarrier barrier;
+ /**
+ * This thread will access and modify memory region
+ * from outside of the transaction.
+ */
+ private final Runnable conflictingThread;
+
+ public MemoryConflictProvoker() {
+ this(new Object());
+ }
+
+ public MemoryConflictProvoker(Object monitor) {
+ super(monitor);
+ barrier = new CyclicBarrier(2);
+ conflictingThread = () -> {
+ try {
+ barrier.await();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ for (int i = 0; i < MemoryConflictProvoker.INNER_ITERATIONS; i++) {
+ MemoryConflictProvoker.field++;
+ }
+ };
+ }
+
+ /**
+ * Accesses and modifies memory region from within the transaction.
+ */
+ public void transactionalRegion() {
+ try {
+ barrier.await();
+ } catch (InterruptedException | BrokenBarrierException e) {
+ throw new RuntimeException(e);
+ }
+ for (int i = 0; i < MemoryConflictProvoker.INNER_ITERATIONS; i++) {
+ synchronized(monitor) {
+ MemoryConflictProvoker.field--;
+ }
+ }
+ }
+
+ @Override
+ public void forceAbort() {
+ try {
+ Thread t = new Thread(conflictingThread);
+ t.start();
+ transactionalRegion();
+ t.join();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public String getMethodWithLockName() {
+ return this.getClass().getName() + "::transactionalRegion";
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/testlibrary/rtm/NestedAbortProvoker.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2014, 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 rtm;
+
+import java.util.Arrays;
+
+/**
+ * In order to force nested transaction abort NestedAbortProvoker
+ * invoke BufferOverflowProvoker from transactional region.
+ */
+class NestedAbortProvoker extends AbortProvoker {
+ // Following field have to be static in order to avoid escape analysis.
+ @SuppressWarnings("UnsuedDeclaration")
+ private static int field = 0;
+ private final AbortProvoker nestedAbortProvoker;
+
+ public NestedAbortProvoker() {
+ this.nestedAbortProvoker = new XAbortProvoker(monitor);
+ }
+
+ @Override
+ public void forceAbort() {
+ synchronized(monitor) {
+ NestedAbortProvoker.field++;
+ nestedAbortProvoker.forceAbort();
+ NestedAbortProvoker.field--;
+ }
+ }
+
+ @Override
+ public String[] getMethodsToCompileNames() {
+ String nestedProvokerMethods[]
+ = nestedAbortProvoker.getMethodsToCompileNames();
+ String methods[] = Arrays.copyOf(nestedProvokerMethods,
+ nestedProvokerMethods.length + 1);
+ methods[methods.length - 1] = getMethodWithLockName();
+ return methods;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/testlibrary/rtm/RTMLockingStatistics.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 2014, 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 rtm;
+
+import java.util.EnumMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+
+/**
+ * Wrapper for +UsePreciseRTMLockingStatistics output.
+ *
+ * Example of locking statistics:
+ *
+ * java/lang/ClassLoader.loadClass@7
+ * # rtm locks total (estimated): 0
+ * # rtm lock aborts : 13
+ * # rtm lock aborts 0: 12
+ * # rtm lock aborts 1: 0
+ * # rtm lock aborts 2: 0
+ * # rtm lock aborts 3: 0
+ * # rtm lock aborts 4: 0
+ * # rtm lock aborts 5: 0
+ */
+public class RTMLockingStatistics {
+ /**
+ * Pattern for aborts per abort type entries.
+ */
+ private static final Pattern ABORT_PATTERN;
+
+ /**
+ * Pattern for whole statistics.
+ */
+ private static final Pattern RTM_LOCKING_STATISTICS_PATTERN;
+
+ static {
+ String abortRe
+ = "# rtm lock aborts\\s+(?<type>[0-9]+):\\s(?<count>[0-9]+)";
+
+ ABORT_PATTERN = Pattern.compile(abortRe);
+ RTM_LOCKING_STATISTICS_PATTERN = Pattern.compile(
+ "(?<className>[^.\n]+)\\." +
+ "(?<methodName>[^@\n]+)@(?<bci>[0-9]+)\n" +
+ "# rtm locks total \\(estimated\\):\\s*" +
+ "(?<totalLocks>[0-9]+)\n" +
+ "# rtm lock aborts\\s+:\\s*(?<totalAborts>[0-9]+)\n" +
+ "(?<abortStats>(" + abortRe + "\n)+)");
+ }
+
+ private final long totalLocks;
+ private final long totalAborts;
+ private final String className;
+ private final String methodName;
+ private final int bci;
+ private final Map<AbortType, Long> aborts = new EnumMap<>(AbortType.class);
+
+ /**
+ * Constructs RTMLockingStatistics from matcher captured statistics entry.
+ * @param matcher Matcher captured statistics entry.
+ */
+ private RTMLockingStatistics(Matcher matcher) {
+ className = matcher.group("className");
+ methodName = matcher.group("methodName");
+ bci = Integer.valueOf(matcher.group("bci"));
+ totalLocks = Long.valueOf(matcher.group("totalLocks"));
+ totalAborts = Long.valueOf(matcher.group("totalAborts"));
+
+ Matcher abortMatcher = ABORT_PATTERN.matcher(matcher.
+ group("abortStats"));
+
+ while (abortMatcher.find()) {
+ int type = Integer.valueOf(abortMatcher.group("type"));
+ long count = Long.valueOf(abortMatcher.group("count"));
+ setAborts(AbortType.lookup(type), count);
+ }
+ }
+
+
+ /**
+ * Parses string and return all founded RTM locking statistics entries.
+ *
+ * @param str the string to be parsed.
+ * @return list with all founded RTM locking statistics entries or
+ * empty list if nothing was found.
+ */
+ public static List<RTMLockingStatistics> fromString(String str) {
+ List<RTMLockingStatistics> statistics = new LinkedList<>();
+ Matcher matcher = RTM_LOCKING_STATISTICS_PATTERN.matcher(str);
+
+ while (matcher.find()) {
+ RTMLockingStatistics lock = new RTMLockingStatistics(matcher);
+ statistics.add(lock);
+ }
+
+ return statistics;
+ }
+
+ /**
+ * Parses string and return all founded RTM locking statistics entries
+ * for locks in method {@code methodName}.
+ *
+ * @param methodName a name of the method for locks from which statistics
+ * should be gathered.
+ * @param str the string to be parsed.
+ * @return list with all founded RTM locking statistics entries or
+ * empty list if nothing was found.
+ */
+ public static List<RTMLockingStatistics> fromString(String methodName,
+ String str) {
+ String formattedMethodName = formatMethodName(methodName);
+
+ List<RTMLockingStatistics> statisticsForMethod = new LinkedList<>();
+ for (RTMLockingStatistics statistics : fromString(str)) {
+ if (statistics.getLockName().startsWith(formattedMethodName)) {
+ statisticsForMethod.add(statistics);
+ }
+ }
+ return statisticsForMethod;
+ }
+
+ /**
+ * Formats method's name so it will have the same format as
+ * in rtm locking statistics.
+ *
+ * <pre>
+ * Example:
+ * com/example/Klass::method => com/example/Klass.method
+ * com/example/Klass.method => com/example/Klass.method
+ * com.example.Klass::method => com/example/Klass.method
+ * com.example.Klass.method => com/example/Klass.method
+ * </pre>
+ *
+ * @param methodName method's name that should be formatted.
+ * @return formatted method's name.
+ */
+ private static String formatMethodName(String methodName) {
+ String m[];
+ if (methodName.contains("::")) {
+ m = methodName.split("::");
+ } else {
+ int splitAt = methodName.lastIndexOf('.');
+ m = new String[2];
+ m[0] = methodName.substring(0, splitAt);
+ m[1] = methodName.substring(splitAt + 1);
+ }
+ return String.format("%s.%s", m[0].replaceAll("\\.", "/"), m[1]);
+ }
+
+ /**
+ * Returns name of lock for which this statistics was collected.
+ * Lock name has following format:
+ * <class name>.<method name>@<bci>
+ *
+ * @return name of lock.
+ */
+ public String getLockName() {
+ return String.format("%s.%s@%d", className, methodName, bci);
+ }
+
+ /**
+ * Returns aborts count for specified abort type.
+ *
+ * @param type an abort type.
+ * @return count of aborts.
+ */
+ public long getAborts(AbortType type) {
+ return aborts.getOrDefault(type, 0L);
+ }
+
+ /**
+ * Sets aborts count for specified abort type.
+ *
+ * @param type an abort type.
+ * @param count count of aborts.
+ */
+ public void setAborts(AbortType type, long count) {
+ aborts.put(type, count);
+ }
+
+ public long getTotalLocks() {
+ return totalLocks;
+ }
+
+ public long getTotalAborts() {
+ return totalAborts;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append(getLockName()).append('\n');
+ builder.append(String.format("# rtm locks total (estimated): %d\n",
+ getTotalLocks()));
+ builder.append(String.format("# rtm lock aborts: %d\n",
+ getTotalLocks()));
+
+ for (AbortType type : AbortType.values()) {
+ builder.append(String.format("# rtm lock aborts %s %d\n",
+ type.toString(), getAborts(type)));
+ }
+ return builder.toString();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/testlibrary/rtm/RTMTestBase.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,279 @@
+/*
+ * Copyright (c) 2014, 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 rtm;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.List;
+import java.util.LinkedList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.ProcessTools;
+import com.oracle.java.testlibrary.Utils;
+import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
+
+/**
+ * Auxiliary methods used for RTM testing.
+ */
+public class RTMTestBase {
+ private static final String RTM_STATE_CHANGE_REASON = "rtm_state_change";
+ /**
+ * We don't parse compilation log as XML-document and use regular
+ * expressions instead, because in some cases it could be
+ * malformed.
+ */
+ private static final String FIRED_UNCOMMON_TRAP_PATTERN_TEMPLATE
+ = "<uncommon_trap thread='[0-9]+' reason='%s'";
+ private static final String INSTALLED_UNCOMMON_TRAP_PATTERN_TEMPLATE
+ = "<uncommon_trap bci='[0-9]+' reason='%s'";
+
+ /**
+ * Executes RTM test in a new JVM started with {@code options} cli options.
+ *
+ * @param test test case to execute.
+ * @param options additional options for VM
+ * @throws Exception when something went wrong.
+ */
+ public static OutputAnalyzer executeRTMTest(CompilableTest test,
+ String... options) throws Exception {
+ ProcessBuilder processBuilder
+ = ProcessTools.createJavaProcessBuilder(
+ RTMTestBase.prepareTestOptions(test, options));
+ OutputAnalyzer outputAnalyzer
+ = new OutputAnalyzer(processBuilder.start());
+ System.out.println(outputAnalyzer.getOutput());
+ return outputAnalyzer;
+ }
+
+ /**
+ * Executes test case and save compilation log to {@code logFileName}.
+ *
+ * @param logFileName a name of compilation log file
+ * @param test a test case to execute case to execute
+ * @param options additional options to VM
+ * @return OutputAnalyzer for started test case
+ * @throws Exception when something went wrong
+ */
+ public static OutputAnalyzer executeRTMTest(String logFileName,
+ CompilableTest test, String... options) throws Exception {
+ ProcessBuilder processBuilder
+ = ProcessTools.createJavaProcessBuilder(
+ RTMTestBase.prepareTestOptions(logFileName, test, options));
+ OutputAnalyzer outputAnalyzer
+ = new OutputAnalyzer(processBuilder.start());
+
+ System.out.println(outputAnalyzer.getOutput());
+
+ return outputAnalyzer;
+ }
+
+ /**
+ * Finds count of uncommon traps with reason {@code reason} installed
+ * during compilation.
+ *
+ * @param compilationLogFile a path to file with LogCompilation output.
+ * @param reason reason of installed uncommon traps.
+ * @return count of installed uncommon traps with reason {@code reason}.
+ * @throws IOException
+ */
+ public static int installedUncommonTraps(String compilationLogFile,
+ String reason)throws IOException {
+ String pattern = String.format(
+ RTMTestBase.INSTALLED_UNCOMMON_TRAP_PATTERN_TEMPLATE,
+ reason);
+ return RTMTestBase.findTraps(compilationLogFile, pattern);
+ }
+
+ /**
+ * Finds count of uncommon traps with reason <i>rtm_state_change</i>
+ * installed during compilation.
+ *
+ * @param compilationLogFile a path to file with LogCompilation output.
+ * @return count of installed uncommon traps with reason
+ * <i>rtm_state_change</i>.
+ * @throws IOException
+ */
+ public static int installedRTMStateChangeTraps(String compilationLogFile)
+ throws IOException {
+ return RTMTestBase.installedUncommonTraps(compilationLogFile,
+ RTMTestBase.RTM_STATE_CHANGE_REASON);
+ }
+
+ /**
+ * Finds count of fired uncommon traps with reason {@code reason}.
+ *
+ * @param compilationLogFile a path to file with LogCompilation output.
+ * @param reason a reason of fired uncommon traps.
+ * @return count of fired uncommon traps with reason {@code reason}.
+ * @throws IOException
+ */
+ public static int firedUncommonTraps(String compilationLogFile,
+ String reason) throws IOException {
+ String pattern = String.format(
+ RTMTestBase.FIRED_UNCOMMON_TRAP_PATTERN_TEMPLATE,
+ reason);
+ return RTMTestBase.findTraps(compilationLogFile, pattern);
+ }
+
+ /**
+ * Finds count of fired uncommon traps with reason <i>rtm_state_change</i>.
+ *
+ * @param compilationLogFile a path to file with LogCompilation output.
+ * @return count of fired uncommon traps with reason
+ * <i>rtm_state_change</i>.
+ * @throws IOException
+ */
+ public static int firedRTMStateChangeTraps(String compilationLogFile)
+ throws IOException {
+ return RTMTestBase.firedUncommonTraps(compilationLogFile,
+ RTMTestBase.RTM_STATE_CHANGE_REASON);
+ }
+
+ /**
+ * Finds count of uncommon traps that matches regular
+ * expression in {@code re}.
+ *
+ * @param compilationLogFile a path to file with LogCompilation output.
+ * @param re regular expression to match uncommon traps.
+ * @throws IOException
+ */
+ private static int findTraps(String compilationLogFile, String re)
+ throws IOException {
+ String compilationLog = RTMTestBase.fileAsString(compilationLogFile);
+ Pattern pattern = Pattern.compile(re);
+ Matcher matcher = pattern.matcher(compilationLog);
+ int traps = 0;
+ while (matcher.find()) {
+ traps++;
+ }
+ return traps;
+ }
+
+ /**
+ * Returns file's content as a string.
+ *
+ * @param path a path to file to operate on.
+ * @return string with content of file.
+ * @throws IOException
+ */
+ private static String fileAsString(String path) throws IOException {
+ byte[] fileAsBytes = Files.readAllBytes(Paths.get(path));
+ return new String(fileAsBytes);
+ }
+
+ /**
+ * Prepares VM options for test execution.
+ * This method get test java options, filter out all RTM-related options,
+ * adds CompileCommand=compileonly,method_name options for each method
+ * from {@code methodToCompile} and finally appends all {@code vmOpts}.
+ *
+ * @param test test case whose methods that should be compiled.
+ * If {@code null} then no additional <i>compileonly</i>
+ * commands will be added to VM options.
+ * @param vmOpts additional options to pass to VM.
+ * @return Array with VM options.
+ */
+ private static String[] prepareTestOptions(CompilableTest test,
+ String... vmOpts) {
+ return RTMTestBase.prepareFilteredTestOptions(test, null, vmOpts);
+ }
+
+ /**
+ * Prepares VM options for test execution.
+ * This method get test java options, filter out all RTM-related options
+ * and all options that matches regexps in {@code additionalFilters},
+ * adds CompileCommand=compileonly,method_name options for each method
+ * from {@code methodToCompile} and finally appends all {@code vmOpts}.
+ *
+ * @param test test case whose methods that should be compiled.
+ * If {@code null} then no additional <i>compileonly</i>
+ * commands will be added to VM options.
+ * @param additionalFilters array with regular expression that will be
+ * used to filter out test java options.
+ * If {@code null} then no additional filters
+ * will be used.
+ * @param vmOpts additional options to pass to VM.
+ * @return array with VM options.
+ */
+ private static String[] prepareFilteredTestOptions(CompilableTest test,
+ String[] additionalFilters, String... vmOpts) {
+ List<String> finalVMOpts = new LinkedList<>();
+ String[] filters;
+
+ if (additionalFilters != null) {
+ filters = Arrays.copyOf(additionalFilters,
+ additionalFilters.length + 1);
+ } else {
+ filters = new String[1];
+ }
+
+ filters[filters.length - 1] = "RTM";
+ String[] filteredVMOpts = Utils.getFilteredTestJavaOpts(filters);
+ Collections.addAll(finalVMOpts, filteredVMOpts);
+ Collections.addAll(finalVMOpts, "-Xcomp", "-server",
+ "-XX:-TieredCompilation", "-XX:+UseRTMLocking",
+ CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
+ CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS);
+
+ if (test != null) {
+ for (String method : test.getMethodsToCompileNames()) {
+ finalVMOpts.add("-XX:CompileCommand=compileonly," + method);
+ }
+ }
+ Collections.addAll(finalVMOpts, vmOpts);
+ return finalVMOpts.toArray(new String[finalVMOpts.size()]);
+ }
+
+ /**
+ * Adds additional options for VM required for successful execution of test.
+ *
+ * @param logFileName a name of compilation log file
+ * @param test a test case to execute
+ * @param options additional options to VM
+ * @return an array with VM options
+ */
+ private static String[] prepareTestOptions(String logFileName,
+ CompilableTest test, String... options) {
+ String[] preparedOptions = RTMTestBase.prepareFilteredTestOptions(
+ test,
+ new String[] {
+ "LogCompilation",
+ "LogFile"
+ });
+ List<String> updatedOptions = new LinkedList<>();
+ Collections.addAll(updatedOptions, preparedOptions);
+ Collections.addAll(updatedOptions,
+ "-XX:+LogCompilation",
+ "-XX:LogFile=" + logFileName);
+ Collections.addAll(updatedOptions, options);
+
+ return updatedOptions.toArray(new String[updatedOptions.size()]);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/testlibrary/rtm/XAbortProvoker.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2014, 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 rtm;
+
+import com.oracle.java.testlibrary.Utils;
+import sun.misc.Unsafe;
+
+/**
+ * Current RTM locking implementation force transaction abort
+ * before native method call by explicit xabort(0) call.
+ */
+class XAbortProvoker extends AbortProvoker {
+ // Following field have to be static in order to avoid escape analysis.
+ @SuppressWarnings("UnsuedDeclaration")
+ private static int field = 0;
+ private static final Unsafe UNSAFE = Utils.getUnsafe();
+
+ public XAbortProvoker() {
+ this(new Object());
+ }
+
+ public XAbortProvoker(Object monitor) {
+ super(monitor);
+ }
+
+ @Override
+ public void forceAbort() {
+ synchronized(monitor) {
+ XAbortProvoker.field = UNSAFE.addressSize();
+ }
+ }
+
+ @Override
+ public String[] getMethodsToCompileNames() {
+ return new String[] {
+ getMethodWithLockName(),
+ Unsafe.class.getName() + "::addressSize"
+ };
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/testlibrary/rtm/predicate/SupportedCPU.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2014, 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 rtm.predicate;
+
+import sun.hotspot.cpuinfo.CPUInfo;
+
+import java.util.function.BooleanSupplier;
+
+public class SupportedCPU implements BooleanSupplier {
+ @Override
+ public boolean getAsBoolean() {
+ return CPUInfo.hasFeature("rtm");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/testlibrary/rtm/predicate/SupportedVM.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2014, 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 rtm.predicate;
+
+import com.oracle.java.testlibrary.Platform;
+
+import java.util.function.BooleanSupplier;
+
+public class SupportedVM implements BooleanSupplier {
+ @Override
+ public boolean getAsBoolean() {
+ return Platform.isServer() && !Platform.isEmbedded();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/correctness/CorrectnessTest.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test CorrectnessTest
+ * @bug 8038418
+ * @library /testlibrary /testlibrary/whitebox
+ * @compile execution/TypeConflict.java execution/TypeProfile.java
+ * execution/MethodHandleDelegate.java
+ * @build CorrectnessTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ * -XX:TypeProfileLevel=222 -XX:+UseTypeSpeculation
+ * -XX:CompileCommand=exclude,execution/*::methodNotToCompile
+ * -XX:CompileCommand=dontinline,scenarios/Scenario::collectReturnType
+ * CorrectnessTest RETURN
+ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ * -XX:TypeProfileLevel=222 -XX:+UseTypeSpeculation
+ * -XX:CompileCommand=exclude,execution/*::methodNotToCompile
+ * -XX:CompileCommand=dontinline,scenarios/Scenario::collectReturnType
+ * CorrectnessTest PARAMETERS
+ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions
+ * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ * -XX:TypeProfileLevel=222 -XX:+UseTypeSpeculation
+ * -XX:CompileCommand=exclude,execution/*::methodNotToCompile
+ * -XX:CompileCommand=dontinline,scenarios/Scenario::collectReturnType
+ * CorrectnessTest ARGUMENTS
+ * @summary Tests correctness of type usage with type profiling and speculations
+ */
+
+import com.oracle.java.testlibrary.Asserts;
+import com.oracle.java.testlibrary.Platform;
+import execution.Execution;
+import execution.MethodHandleDelegate;
+import execution.TypeConflict;
+import execution.TypeProfile;
+import hierarchies.*;
+import scenarios.*;
+import sun.hotspot.WhiteBox;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.BiFunction;
+
+public class CorrectnessTest {
+ private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
+
+ public static void main(String[] args) {
+ if (!Platform.isServer()) {
+ System.out.println("ALL TESTS SKIPPED");
+ }
+ Asserts.assertGTE(args.length, 1);
+ ProfilingType profilingType = ProfilingType.valueOf(args[0]);
+ if (runTests(profilingType)) {
+ System.out.println("ALL TESTS PASSED");
+ } else {
+ throw new RuntimeException("SOME TESTS FAILED");
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public static boolean runTests(ProfilingType profilingType) {
+ boolean result = true;
+
+ List<Execution> executionList = new ArrayList<>();
+ executionList.add(new TypeConflict());
+ executionList.add(new TypeProfile());
+ for (int i = 0, n = executionList.size(); i < n; i++) {
+ executionList.add(new MethodHandleDelegate(executionList.get(i)));
+ }
+
+ List<TypeHierarchy> hierarchyList = new ArrayList<>();
+ hierarchyList.add(new DefaultMethodInterface.Hierarchy());
+ hierarchyList.add(new DefaultMethodInterface2.Hierarchy());
+ hierarchyList.add(new Linear.Hierarchy());
+ hierarchyList.add(new Linear2.Hierarchy());
+ hierarchyList.add(new OneRank.Hierarchy());
+ for (int i = 0, n = hierarchyList.size(); i < n; i++) {
+ hierarchyList.add(new NullableType(hierarchyList.get(i)));
+ }
+
+ List<BiFunction<ProfilingType, TypeHierarchy, Scenario<?, ?>>> testCasesConstructors
+ = new ArrayList<>();
+ testCasesConstructors.add(ArrayCopy::new);
+ testCasesConstructors.add(ArrayReferenceStore::new);
+ testCasesConstructors.add(ClassIdentity::new);
+ testCasesConstructors.add(ClassInstanceOf::new);
+ testCasesConstructors.add(ClassIsInstance::new);
+ testCasesConstructors.add(ReceiverAtInvokes::new);
+ testCasesConstructors.add(CheckCast::new);
+
+ for (TypeHierarchy hierarchy : hierarchyList) {
+ for (BiFunction<ProfilingType, TypeHierarchy, Scenario<?, ?>> constructor : testCasesConstructors) {
+ for (Execution execution : executionList) {
+ Scenario<?, ?> scenario = constructor.apply(profilingType, hierarchy);
+ if (scenario.isApplicable()) {
+ result &= executeTest(hierarchy, execution, scenario);
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Executes test case
+ *
+ * @param hierarchy type hierarchy for the test
+ * @param execution execution scenario
+ * @param scenario test scenario executed with given Execution
+ */
+ private static boolean executeTest(TypeHierarchy hierarchy, Execution execution, Scenario<?, ?> scenario) {
+ boolean testCaseResult = false;
+ String testName = hierarchy.getClass().getName() + " :: " + scenario.getName() + " @ " + execution.getName();
+ clearAllMethodsState(scenario.getClass());
+ try {
+ execution.execute(scenario);
+ testCaseResult = true;
+ } catch (Exception e) {
+ System.err.println(testName + " failed with exception " + e);
+ e.printStackTrace();
+ }
+ System.out.println((testCaseResult ? "PASSED: " : "FAILED: ") + testName);
+ return testCaseResult;
+ }
+
+ private static void clearAllMethodsState(Class aClass) {
+ while (aClass != null) {
+ for (Method m : aClass.getDeclaredMethods()) {
+ WHITE_BOX.clearMethodState(m);
+ }
+ aClass = aClass.getSuperclass();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/correctness/OffTest.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test CorrectnessTest
+ * @bug 8038418
+ * @library /testlibrary /testlibrary/whitebox
+ * @compile execution/TypeConflict.java execution/TypeProfile.java
+ * execution/MethodHandleDelegate.java
+ * @build CorrectnessTest
+ * @build OffTest
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/timeout=1200 OffTest
+ */
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.ProcessTools;
+import scenarios.ProfilingType;
+
+import java.util.Random;
+
+public class OffTest {
+ private static final String[] OPTIONS = {
+ "-Xbootclasspath/a:.",
+ "-XX:+IgnoreUnrecognizedVMOptions",
+ "-XX:+UnlockExperimentalVMOptions",
+ "-XX:+UnlockDiagnosticVMOptions",
+ "-XX:+WhiteBoxAPI",
+ "-XX:CompileCommand=exclude,execution/*::methodNotToCompile",
+ "-XX:CompileCommand=dontinline,scenarios/Scenario::collectReturnType",
+ "", // -XX:TypeProfileLevel=?
+ "", // -XX:?UseTypeSpeculation
+ CorrectnessTest.class.getName(),
+ "", // ProfilingType.name()
+ };
+
+ private static final String TYPE_PROFILE_LEVEL = "TypeProfileLevel";
+ private static final String USE_TYPE_SPECULATION = "UseTypeSpeculation";
+ private static final int TYPE_PROFILE_LEVEL_LENGTH = 3;
+ private static final int TYPE_PROFILE_LEVEL_BOUND = 3;
+ private static final int DEFAULT_COUNT = 10;
+ private static final int PROFILING_TYPE_INDEX = OPTIONS.length - 1;
+ private static final int TYPE_PROFILE_INDEX = OPTIONS.length - 4;
+ private static final int USE_TYPE_SPECULATION_INDEX = OPTIONS.length - 3;
+ private static final Random RNG;
+
+ static {
+ String str = System.getProperty("seed");
+ long seed = str != null ? Long.parseLong(str) : new Random().nextLong();
+ RNG = new Random(seed);
+ System.out.printf("-Dseed=%d%n", seed);
+ }
+
+ public static void main(String[] args) throws Exception {
+ int count = DEFAULT_COUNT;
+ if (args.length > 0) {
+ count = Integer.parseInt(args[0]) ;
+ }
+ for (int i = 0; i < count; ++i) {
+ runTest();
+ }
+ }
+
+ private static void runTest() throws Exception {
+ String useTypeSpeculation = "-XX:" + (RNG.nextBoolean() ? "+" : "-") + USE_TYPE_SPECULATION;
+ String typeProfileLevel = "-XX:" + TYPE_PROFILE_LEVEL + "=" + randomTypeProfileLevel();
+ ProfilingType type = randomProfileType();
+ OPTIONS[TYPE_PROFILE_INDEX] = typeProfileLevel;
+ OPTIONS[USE_TYPE_SPECULATION_INDEX] = useTypeSpeculation;
+ OPTIONS[PROFILING_TYPE_INDEX] = type.name();
+ ProcessBuilder processBuilder = ProcessTools.createJavaProcessBuilder(/* addTestVmOptions= */ true, OPTIONS);
+ OutputAnalyzer outputAnalyzer = new OutputAnalyzer(processBuilder.start());
+ outputAnalyzer.shouldHaveExitValue(0);
+ }
+
+ private static ProfilingType randomProfileType() {
+ ProfilingType[] value = ProfilingType.values();
+ return value[RNG.nextInt(value.length)];
+ }
+
+ private static String randomTypeProfileLevel() {
+ StringBuilder stringBuilder = new StringBuilder();
+ for (int i = 0; i < TYPE_PROFILE_LEVEL_LENGTH; ++i) {
+ stringBuilder.append(RNG.nextInt(TYPE_PROFILE_LEVEL_BOUND));
+ }
+ return stringBuilder.toString();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/correctness/execution/Execution.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2014, 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 execution;
+
+import hierarchies.TypeHierarchy;
+import scenarios.Scenario;
+
+/**
+ * Execution scenario represents test methods execution type.
+ * @param <T> parameter type
+ * @param <R> result Type
+ */
+public interface Execution<T extends TypeHierarchy.I, R> {
+ /**
+ * Executes the test code of the given scenario
+ * See {@link scenarios.Scenario#run(T)}
+ *
+ * @param scenario test scenario
+ */
+ void execute(Scenario<T, R> scenario);
+
+ default String getName() {
+ return this.getClass().getName();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/correctness/execution/MethodHandleDelegate.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2014, 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 execution;
+
+import hierarchies.TypeHierarchy;
+import scenarios.Scenario;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+
+/**
+ * Executes test scenario using {@link MethodHandle#invoke(Object...)}.
+ * Delegates execution to the given {@link Execution} by creating
+ * new test scenario, see {@link Scenario}
+ */
+public class MethodHandleDelegate<T extends TypeHierarchy.I, R> implements Execution<T, R> {
+ private final Execution<T, R> delegate;
+
+ public MethodHandleDelegate(Execution<T, R> delegate) {
+ this.delegate = delegate;
+ }
+
+ @Override
+ public void execute(Scenario<T, R> scenario) {
+ delegate.execute(new MHScenario<T, R>(scenario));
+ }
+
+ @Override
+ public String getName() {
+ return "MethodHandleDelegate # " + delegate.getName();
+ }
+
+ private static class MHScenario<T extends TypeHierarchy.I, R> extends Scenario<T, R> {
+ private final Scenario<T, R> scenario;
+ private static final MethodHandle METHOD_HANDLE_RUN;
+
+ static {
+ MethodHandles.Lookup lookup = MethodHandles.lookup();
+ MethodType methodType = MethodType.methodType(Object.class, TypeHierarchy.I.class);
+
+ try {
+ METHOD_HANDLE_RUN = lookup.findVirtual(Scenario.class, "run", methodType);
+ } catch (NoSuchMethodException | IllegalAccessException e) {
+ System.err.println("Failed to get target method run() with " + e);
+ e.printStackTrace();
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Constructor
+ *
+ * @param scenario test scenario to be executed
+ */
+ private MHScenario(Scenario<T, R> scenario) {
+ super("MethodHandle::" + scenario.getName(), scenario.profilingType, scenario.hierarchy);
+ this.scenario = scenario;
+ }
+
+ /**
+ * Runs {@link Scenario#run(T)} with {@link MethodHandle#invoke(Object...)}
+ *
+ * @param t subject of the test
+ * @return result of the underlying {@link Scenario#run(T)} invocation
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public R run(T t) {
+ try {
+ return (R) METHOD_HANDLE_RUN.invoke(scenario, t);
+ } catch (Throwable thr) {
+ System.err.println(scenario.getName()
+ + " failed to invoke target method run() with " + thr);
+ throw new RuntimeException("Invocation failed", thr);
+ }
+ }
+
+ @Override
+ public void check(R r, T t) {
+ scenario.check(r, t);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/correctness/execution/TypeConflict.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2014, 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 execution;
+
+import hierarchies.TypeHierarchy;
+import scenarios.Scenario;
+
+/**
+ * Type profiling conflict execution scenario. The main goal is
+ * to make compiler profile and compile methods with different types.
+ * Scenario tests guards by passing conflicting types (incompatible
+ * for the profiled data).
+ */
+public class TypeConflict<T extends TypeHierarchy.I, R> implements Execution<T, R> {
+ /** Test methods execution number to make profile */
+ private final static int POLLUTION_THRESHOLD = 5000;
+ /** Test methods execution number to make it profiled and compiled*/
+ private final static int PROFILE_THRESHOLD = 20000;
+
+ @Override
+ public void execute(Scenario<T, R> scenario) {
+ T base = scenario.getProfiled();
+ T incompatible = scenario.getConflict();
+
+ // pollute profile by passing different types
+ R baseResult = null;
+ R incResult = null;
+ for (int i = 0; i < POLLUTION_THRESHOLD; i++) {
+ baseResult = methodNotToCompile(scenario, base);
+ incResult = methodNotToCompile(scenario, incompatible);
+ }
+ scenario.check(baseResult, base);
+ scenario.check(incResult, incompatible);
+
+ // profile and compile
+ R result = null;
+ for (int i = 0; i < PROFILE_THRESHOLD; i++) {
+ result = methodNotToCompile(scenario, base);
+ }
+ scenario.check(result, base);
+
+ // pass another type to make guard work and recompile
+ for (int i = 0; i < PROFILE_THRESHOLD; i++) {
+ result = methodNotToCompile(scenario, incompatible);
+ }
+ scenario.check(result, incompatible);
+ }
+
+ private R methodNotToCompile(Scenario<T, R> scenario, T t) {
+ return scenario.run(t);
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/correctness/execution/TypeProfile.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2014, 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 execution;
+
+import hierarchies.TypeHierarchy;
+import scenarios.Scenario;
+
+/**
+ * Profile type execution scenario. Executes tester method
+ * in a loop without any manipulation with types or instances.
+ */
+public class TypeProfile<T extends TypeHierarchy.I, R> implements Execution<T, R> {
+ /** Number of test method execution to make it profiled and compiled */
+ private final static int PROFILE_THRESHOLD = 100000;
+
+ /**
+ * Makes scenario code be profiled and compiled
+ * @param scenario Test scenario
+ */
+ @Override
+ public void execute(Scenario<T, R> scenario) {
+ R result = null;
+ T prof = scenario.getProfiled();
+ T confl = scenario.getConflict();
+
+ for (int i = 0; i < PROFILE_THRESHOLD; i++) {
+ result = methodNotToCompile(scenario, prof);
+ }
+ scenario.check(result, prof);
+
+ result = methodNotToCompile(scenario, confl);
+ scenario.check(result, confl);
+ }
+
+ protected R methodNotToCompile(Scenario<T, R> scenario, T t) {
+ return scenario.run(t);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/correctness/hierarchies/DefaultMethodInterface.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2014, 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 hierarchies;
+
+public class DefaultMethodInterface {
+ private DefaultMethodInterface() {
+ }
+
+ public static class Hierarchy
+ extends TypeHierarchy<DefaultMethodInterface.A, DefaultMethodInterface.B> {
+ public Hierarchy() {
+ super(new DefaultMethodInterface.A(), new DefaultMethodInterface.B(),
+ DefaultMethodInterface.A.class, DefaultMethodInterface.B.class);
+ }
+ }
+
+ public static interface I2 extends TypeHierarchy.I {
+ default int m() {
+ return TypeHierarchy.ANSWER;
+ }
+ }
+
+ public static class A implements I2 {
+ // use default method from I2
+ }
+
+ public static class B extends A {
+ @Override
+ public int m() {
+ return TypeHierarchy.YEAR;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/correctness/hierarchies/DefaultMethodInterface2.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2014, 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 hierarchies;
+
+public class DefaultMethodInterface2 {
+ private DefaultMethodInterface2() {
+ }
+
+ public static class Hierarchy
+ extends TypeHierarchy<TypeHierarchy.A, DefaultMethodInterface2.B> {
+ public Hierarchy() {
+ super(new TypeHierarchy.A(), new DefaultMethodInterface2.B(),
+ TypeHierarchy.A.class, DefaultMethodInterface2.B.class);
+ }
+ }
+
+ public static interface I2 extends TypeHierarchy.I {
+ default int m() {
+ return TypeHierarchy.ANSWER;
+ }
+ }
+
+ public static class B implements I2 {
+ // default method I2.m()
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/correctness/hierarchies/Linear.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2014, 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 hierarchies;
+
+public class Linear {
+ private Linear() {
+ }
+
+ public static class Hierarchy extends TypeHierarchy<TypeHierarchy.A, Linear.B> {
+ public Hierarchy() {
+ super(new TypeHierarchy.A(), new Linear.B(),
+ TypeHierarchy.A.class, Linear.B.class);
+ }
+ }
+
+ public static class B extends TypeHierarchy.A {
+ @Override
+ public int m() {
+ return TypeHierarchy.YEAR;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/correctness/hierarchies/Linear2.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2014, 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 hierarchies;
+
+public class Linear2 {
+ private Linear2() {
+ }
+
+ public static class Hierarchy extends TypeHierarchy<TypeHierarchy.A, Linear2.B> {
+ public Hierarchy() {
+ super(new A(), new Linear2.B(),
+ A.class, Linear2.B.class);
+ }
+ }
+
+ public static interface I2 {
+ int m();
+ }
+
+ public static class B extends TypeHierarchy.A implements Linear2.I2 {
+ @Override
+ public int m() {
+ return TypeHierarchy.YEAR;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/correctness/hierarchies/NullableType.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2014, 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 hierarchies;
+
+public class NullableType<M extends TypeHierarchy.I, N extends TypeHierarchy.I>
+ extends TypeHierarchy<M, N> {
+
+ public NullableType(TypeHierarchy<M, N> delegate) {
+ super(delegate.getM(), null,
+ delegate.getClassM(), delegate.getClassN());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/correctness/hierarchies/OneRank.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2014, 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 hierarchies;
+
+public class OneRank {
+ private OneRank() {
+ }
+
+ public static class Hierarchy extends TypeHierarchy<TypeHierarchy.A, OneRank.B> {
+ public Hierarchy() {
+ super(new TypeHierarchy.A(), new OneRank.B(),
+ TypeHierarchy.A.class, OneRank.B.class);
+ }
+ }
+
+ public static class B implements TypeHierarchy.I {
+ @Override
+ public int m() {
+ return TypeHierarchy.YEAR;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/correctness/hierarchies/TypeHierarchy.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2014, 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 hierarchies;
+
+/**
+ * Type hierarchy contains classes the type profiling and speculation are tested with
+ */
+public abstract class TypeHierarchy<M extends TypeHierarchy.I, N extends TypeHierarchy.I> {
+ // Magic numbers
+ public static final int ANSWER = 42;
+ public static final int TEMP = 451;
+ public static final int YEAR = 1984;
+
+ private final M m;
+ private final N n;
+ private final Class<M> classM;
+ private final Class<N> classN;
+
+ protected TypeHierarchy(M m, N n, Class<M> classM, Class<N> classN) {
+ this.m = m;
+ this.n = n;
+ this.classM = classM;
+ this.classN = classN;
+ }
+
+ public final M getM() {
+ return m;
+ }
+
+ public final N getN() {
+ return n;
+ }
+
+ public final Class<M> getClassM() {
+ return classM;
+ }
+
+ public final Class<N> getClassN() {
+ return classN;
+ }
+
+ public interface I {
+ int m();
+ }
+
+ public static class A implements I {
+ @Override
+ public int m() {
+ return TypeHierarchy.ANSWER;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/correctness/scenarios/ArrayCopy.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2014, 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 scenarios;
+
+import hierarchies.TypeHierarchy;
+
+import java.util.Arrays;
+
+/**
+ * Tests System.arraycopy()
+ */
+public class ArrayCopy extends ArrayScenario {
+ public ArrayCopy(ProfilingType profilingType,
+ TypeHierarchy<? extends TypeHierarchy.I, ? extends TypeHierarchy.I> hierarchy) {
+ super("ArrayCopy", profilingType, hierarchy);
+ }
+
+ /**
+ * @param obj is used to fill arrays
+ * @return the same obj
+ */
+ @Override
+ public TypeHierarchy.I run(TypeHierarchy.I obj) {
+ switch (profilingType) {
+ case RETURN:
+ TypeHierarchy.I t = collectReturnType(obj);
+ Arrays.fill(array, t);
+ System.arraycopy(array, 0, matrix[0], 0, array.length);
+ return array[0];
+ case ARGUMENTS:
+ field = obj;
+ Arrays.fill(array, field);
+ System.arraycopy(array, 0, matrix[0], 0, array.length);
+ return array[0];
+ case PARAMETERS:
+ Arrays.fill(array, obj);
+ System.arraycopy(array, 0, matrix[0], 0, array.length);
+ return array[0];
+ }
+ throw new RuntimeException("Should not reach here");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/correctness/scenarios/ArrayReferenceStore.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2014, 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 scenarios;
+
+import hierarchies.TypeHierarchy;
+
+import java.util.Arrays;
+
+/**
+ * Tests aastore bytecode
+ */
+public class ArrayReferenceStore extends ArrayScenario {
+ public ArrayReferenceStore(ProfilingType profilingType,
+ TypeHierarchy<? extends TypeHierarchy.I, ? extends TypeHierarchy.I> hierarchy) {
+ super("ArrayReferenceStore", profilingType, hierarchy);
+ }
+
+ /**
+ * @param obj is used to fill arrays
+ * @return obj
+ */
+ @Override
+ public TypeHierarchy.I run(TypeHierarchy.I obj) {
+ switch (profilingType) {
+ case RETURN:
+ TypeHierarchy.I t = collectReturnType(obj);
+ Arrays.fill(array, t);
+ matrix[0] = array;
+ return matrix[0][0];
+ case ARGUMENTS:
+ field = obj;
+ Arrays.fill(array, field);
+ matrix[0] = array;
+ return matrix[0][0];
+ case PARAMETERS:
+ Arrays.fill(array, obj);
+ matrix[0] = array;
+ return matrix[0][0];
+ }
+ throw new RuntimeException("Should not reach here");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/correctness/scenarios/ArrayScenario.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2014, 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 scenarios;
+
+import com.oracle.java.testlibrary.Asserts;
+import hierarchies.TypeHierarchy;
+
+import java.lang.reflect.Array;
+import java.util.Arrays;
+
+/**
+ * Base class for array scenarios
+ */
+public abstract class ArrayScenario extends Scenario<TypeHierarchy.I, TypeHierarchy.I> {
+ protected final TypeHierarchy.I[] array;
+ protected final TypeHierarchy.I[][] matrix;
+
+ protected ArrayScenario(String name, ProfilingType profilingType,
+ TypeHierarchy<? extends TypeHierarchy.I, ? extends TypeHierarchy.I> hierarchy) {
+ super(name, profilingType, hierarchy);
+ final int x = 20;
+ final int y = 10;
+
+ TypeHierarchy.I prof = hierarchy.getM();
+ TypeHierarchy.I confl = hierarchy.getN();
+
+ this.array = (TypeHierarchy.I[]) Array.newInstance(hierarchy.getClassM(), y);
+ Arrays.fill(array, prof);
+
+ this.matrix = (TypeHierarchy.I[][]) Array.newInstance(hierarchy.getClassM(), x, y);
+ for (int i = 0; i < x; i++) {
+ this.matrix[i] = this.array;
+ }
+
+ Asserts.assertEquals(array.length, matrix[0].length, "Invariant");
+ }
+
+ @Override
+ public boolean isApplicable() {
+ return hierarchy.getClassM().isAssignableFrom(hierarchy.getClassN());
+ }
+
+ @Override
+ public void check(TypeHierarchy.I res, TypeHierarchy.I orig) {
+ Asserts.assertEquals(res, orig, "Check failed");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/correctness/scenarios/CheckCast.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2014, 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 scenarios;
+
+import com.oracle.java.testlibrary.Asserts;
+import hierarchies.TypeHierarchy;
+
+import java.util.Objects;
+
+/**
+ * Checkcast scenario
+ * @param <T> profiling parameter
+ */
+public class CheckCast<T extends TypeHierarchy.I> extends Scenario<T, Integer> {
+ public CheckCast(ProfilingType profilingType, TypeHierarchy<? extends T, ? extends T> hierarchy) {
+ super("CheckCast", profilingType, hierarchy);
+ }
+
+ /**
+ * Returns type profiling.
+ * @param obj is a profiled parameter for the test
+ * @return parameter casted to the type R
+ */
+ @Override
+ public Integer run(T obj) {
+ switch (profilingType) {
+ case RETURN:
+ T t = collectReturnType(obj);
+ if (t != null) {
+ return t.m();
+ }
+ return null;
+ case ARGUMENTS:
+ field = obj;
+ if (field != null) {
+ return field.m();
+ }
+ return null;
+ case PARAMETERS:
+ if (obj != null) {
+ return obj.m();
+ }
+ return null;
+ }
+ throw new RuntimeException("Should not reach here");
+ }
+
+ @Override
+ public void check(Integer result, T orig) {
+ if (result != null || orig != null) {
+ Objects.requireNonNull(result);
+ Objects.requireNonNull(orig);
+ Asserts.assertEquals(result, orig.m(), "Results mismatch");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/correctness/scenarios/ClassIdentity.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2014, 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 scenarios;
+
+import com.oracle.java.testlibrary.Asserts;
+import hierarchies.TypeHierarchy;
+
+/**
+ * Tests pattern: if (a.getClass() == D.class)
+ */
+public class ClassIdentity<T extends TypeHierarchy.I> extends Scenario<T, Integer> {
+ public ClassIdentity(ProfilingType profilingType,
+ TypeHierarchy<? extends T, ? extends T> hierarchy) {
+ super("ClassIdentity", profilingType, hierarchy);
+ }
+
+ @Override
+ public boolean isApplicable() {
+ return hierarchy.getM() != null && hierarchy.getN() != null;
+ }
+
+ @Override
+ public Integer run(T obj) {
+ switch (profilingType) {
+ case RETURN:
+ T t = collectReturnType(obj);
+ if (t.getClass() == TypeHierarchy.A.class) {
+ return inlinee(t);
+ }
+ return TypeHierarchy.TEMP;
+ case ARGUMENTS:
+ field = obj;
+ if (field.getClass() == TypeHierarchy.A.class) {
+ return inlinee(field);
+ }
+ return TypeHierarchy.TEMP;
+ case PARAMETERS:
+ if (obj.getClass() == TypeHierarchy.A.class) {
+ return inlinee(obj);
+ }
+ return TypeHierarchy.TEMP;
+ }
+ throw new RuntimeException("Should not reach here");
+ }
+
+ public int inlinee(T obj) {
+ return obj.m();
+ }
+
+ @Override
+ public void check(Integer result, T orig) {
+ if (orig.getClass() == TypeHierarchy.A.class) {
+ Asserts.assertEquals(result, orig.m(),
+ "Results are not equal for TypeHierarchy.A.class");
+ } else {
+ Asserts.assertEquals(result, TypeHierarchy.TEMP, "Result differs from expected");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/correctness/scenarios/ClassInstanceOf.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2014, 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 scenarios;
+
+import com.oracle.java.testlibrary.Asserts;
+import hierarchies.TypeHierarchy;
+
+/**
+ * Tests instanceof
+ */
+public class ClassInstanceOf<T extends TypeHierarchy.I> extends Scenario<T, Integer> {
+ public ClassInstanceOf(ProfilingType profilingType,
+ TypeHierarchy<? extends T, ? extends T> hierarchy) {
+ super("ClassInstanceOf", profilingType, hierarchy);
+ }
+
+ @Override
+ public Integer run(T obj) {
+ switch (profilingType) {
+ case RETURN:
+ T t = collectReturnType(obj);
+ if (t instanceof TypeHierarchy.A) {
+ return inlinee(t);
+ }
+ return TypeHierarchy.TEMP;
+ case ARGUMENTS:
+ field = obj;
+ if (field instanceof TypeHierarchy.A) {
+ return inlinee(field);
+ }
+ return TypeHierarchy.TEMP;
+ case PARAMETERS:
+ if (obj instanceof TypeHierarchy.A) {
+ return inlinee(obj);
+ }
+ return TypeHierarchy.TEMP;
+ }
+ throw new RuntimeException("Should not reach here");
+ }
+
+ public int inlinee(T obj) {
+ return obj.m();
+ }
+
+ @Override
+ public void check(Integer result, T orig) {
+ if (orig instanceof TypeHierarchy.A) {
+ Asserts.assertEquals(result, orig.m(), "Results are not equal for TypeHierarchy.A");
+ } else {
+ Asserts.assertEquals(result, TypeHierarchy.TEMP, "Result differs from expected");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/correctness/scenarios/ClassIsInstance.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2014, 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 scenarios;
+
+import com.oracle.java.testlibrary.Asserts;
+import hierarchies.TypeHierarchy;
+
+/**
+ * Tests {@link Class#isInstance(Object)}
+ */
+public class ClassIsInstance<T extends TypeHierarchy.I> extends Scenario<T, Integer> {
+ private final Class<?> baseClass;
+
+ public ClassIsInstance(ProfilingType profilingType,
+ TypeHierarchy<? extends T, ? extends T> hierarchy) {
+ super("ClassIsInstance", profilingType, hierarchy);
+ this.baseClass = hierarchy.getClassM();
+ }
+
+ @Override
+ public Integer run(T obj) {
+ switch (profilingType) {
+ case RETURN:
+ T t = collectReturnType(obj);
+ if (baseClass.isInstance(t)) {
+ return inlinee(t);
+ }
+ return TypeHierarchy.TEMP;
+ case ARGUMENTS:
+ field = obj;
+ if (baseClass.isInstance(field)) {
+ return inlinee(field);
+ }
+ return TypeHierarchy.TEMP;
+ case PARAMETERS:
+ if (baseClass.isInstance(obj)) {
+ return inlinee(obj);
+ }
+ return TypeHierarchy.TEMP;
+ }
+ throw new RuntimeException("Should not reach here");
+ }
+
+ public int inlinee(T obj) {
+ return obj.m();
+ }
+
+ @Override
+ public void check(Integer result, T orig) {
+ if (baseClass.isInstance(orig)) {
+ Asserts.assertEquals(result, orig.m(), "Results are not equal for base class");
+ } else {
+ Asserts.assertEquals(result, TypeHierarchy.TEMP, "Result differs from expected");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/correctness/scenarios/ProfilingType.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2014, 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 scenarios;
+
+public enum ProfilingType {
+ /** type profiling of return values of reference types from an invoke */
+ RETURN,
+ /** type profiling for reference parameters on method entries */
+ PARAMETERS,
+ /** type profiling for reference arguments at an invoke */
+ ARGUMENTS,
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/correctness/scenarios/ReceiverAtInvokes.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2014, 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 scenarios;
+
+import com.oracle.java.testlibrary.Asserts;
+import hierarchies.TypeHierarchy;
+
+/**
+ * Receiver at invokes profiling and speculation
+ *
+ * @param <T> parameter to be returned
+ */
+public class ReceiverAtInvokes<T extends TypeHierarchy.I> extends Scenario<T, Integer> {
+ public ReceiverAtInvokes(ProfilingType profilingType,
+ TypeHierarchy<? extends T, ? extends T> hierarchy) {
+ super("ReceiverAtInvokes", profilingType, hierarchy);
+ }
+
+ @Override
+ public boolean isApplicable() {
+ return hierarchy.getM() != null && hierarchy.getN() != null;
+ }
+
+ /**
+ * Receiver profiling
+ *
+ * @param obj is a profiled parameter for the test
+ * @return parameter casted to the type R
+ */
+ @Override
+ public Integer run(T obj) {
+ switch (profilingType) {
+ case RETURN:
+ T t = collectReturnType(obj);
+ return inlinee(t);
+ case ARGUMENTS:
+ field = obj;
+ return inlinee(field);
+ case PARAMETERS:
+ return inlinee(obj);
+ }
+ throw new RuntimeException("Should not reach here");
+ }
+
+ private Integer inlinee(T obj) {
+ return obj.m(); // should be inlined
+ }
+
+ @Override
+ public void check(Integer result, T orig) {
+ Asserts.assertEquals(result, orig.m(), "Results mismatch");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/types/correctness/scenarios/Scenario.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2014, 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 scenarios;
+
+import hierarchies.TypeHierarchy;
+
+/**
+ * Test scenario
+ *
+ * @param <T> parameter type
+ * @param <R> result type
+ */
+public abstract class Scenario<T extends TypeHierarchy.I, R> {
+
+ private final String name;
+ public final ProfilingType profilingType;
+ public final TypeHierarchy <? extends T, ? extends T> hierarchy;
+ protected volatile T field;
+
+ /**
+ * Constructor
+ *
+ * @param name scenario name
+ * @param profilingType tested profiling type
+ * @param hierarchy type hierarchy
+ */
+ protected Scenario(String name, ProfilingType profilingType,
+ TypeHierarchy<? extends T, ? extends T> hierarchy) {
+ this.profilingType = profilingType;
+ this.name = name + " # " + profilingType.name();
+ this.hierarchy = hierarchy;
+ }
+
+ /**
+ * Returns the object which should be used as a parameter
+ * for the methods used for profile data
+ *
+ * @return profiled type object
+ */
+ public T getProfiled() {
+ return hierarchy.getM();
+ }
+
+ /**
+ * Returns the object which makes a conflict for a profiled data
+ * when passed instead of {@linkplain Scenario#getProfiled}
+ *
+ * @return incompatible to profiled object
+ */
+ public T getConflict() {
+ return hierarchy.getN();
+ }
+
+ /**
+ * @return scenario name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /** Is this scenario applicable for a hierarchy it was constructed with */
+ public boolean isApplicable() {
+ return true;
+ }
+
+ /**
+ * Runs test scenario
+ *
+ * @param t subject of the test
+ * @return result of the test invocation
+ */
+ public abstract R run(T t);
+
+ /** Used for a return type profiling */
+ protected final T collectReturnType(T t) {
+ return t;
+ }
+
+ /**
+ * Checks the result for R and T
+ *
+ * @param r result
+ * @param t original
+ * @throws java.lang.RuntimeException on result mismatch
+ */
+ public abstract void check(R r, T t);
+}
--- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/Platform.java Fri Apr 11 13:04:59 2014 +0200
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/Platform.java Fri Apr 11 15:08:40 2014 -0400
@@ -30,13 +30,25 @@
private static final String osArch = System.getProperty("os.arch");
private static final String vmName = System.getProperty("java.vm.name");
- public static boolean isClient() {
- return vmName.endsWith(" Client VM");
- }
+ public static boolean isClient() {
+ return vmName.endsWith(" Client VM");
+ }
+
+ public static boolean isServer() {
+ return vmName.endsWith(" Server VM");
+ }
- public static boolean isServer() {
- return vmName.endsWith(" Server VM");
- }
+ public static boolean isGraal() {
+ return vmName.endsWith(" Graal VM");
+ }
+
+ public static boolean isMinimal() {
+ return vmName.endsWith(" Minimal VM");
+ }
+
+ public static boolean isEmbedded() {
+ return vmName.contains("Embedded");
+ }
public static boolean is32bit() {
return dataModel.equals("32");
--- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/Utils.java Fri Apr 11 13:04:59 2014 +0200
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/Utils.java Fri Apr 11 15:08:40 2014 -0400
@@ -38,6 +38,8 @@
import java.util.Collections;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
+import java.lang.reflect.Field;
+import sun.misc.Unsafe;
/**
* Common library for various test helper functions.
@@ -59,6 +61,8 @@
*/
public static final String JAVA_OPTIONS = System.getProperty("test.java.opts", "").trim();
+ private static Unsafe unsafe = null;
+
/**
* Returns the value of 'test.timeout.factor' system property
* converted to {@code double}.
@@ -109,10 +113,10 @@
/**
* Returns the default JTReg arguments for a jvm running a test without
- * options that matches regular expresions in {@code filters}.
+ * options that matches regular expressions in {@code filters}.
* This is the combination of JTReg arguments test.vm.opts and test.java.opts.
* @param filters Regular expressions used to filter out options.
- * @return An array of options, or an empty array if no opptions.
+ * @return An array of options, or an empty array if no options.
*/
public static String[] getFilteredTestJavaOpts(String... filters) {
String options[] = getTestJavaOpts();
@@ -294,4 +298,38 @@
return output;
}
+ /**
+ * @return Unsafe instance.
+ */
+ public static synchronized Unsafe getUnsafe() {
+ if (unsafe == null) {
+ try {
+ Field f = Unsafe.class.getDeclaredField("theUnsafe");
+ f.setAccessible(true);
+ unsafe = (Unsafe) f.get(null);
+ } catch (NoSuchFieldException | IllegalAccessException e) {
+ throw new RuntimeException("Unable to get Unsafe instance.", e);
+ }
+ }
+ return unsafe;
+ }
+ private static final char[] hexArray = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
+
+ /**
+ * Returns hex view of byte array
+ *
+ * @param bytes byte array to process
+ * @return Space separated hexadecimal string representation of bytes
+ */
+
+ public static String toHexString(byte[] bytes) {
+ char[] hexView = new char[bytes.length * 3];
+ int i = 0;
+ for (byte b : bytes) {
+ hexView[i++] = hexArray[(b >> 4) & 0x0F];
+ hexView[i++] = hexArray[b & 0x0F];
+ hexView[i++] = ' ';
+ }
+ return new String(hexView);
+ }
}
--- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/CPUSpecificCommandLineOptionTest.java Fri Apr 11 13:04:59 2014 +0200
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/CPUSpecificCommandLineOptionTest.java Fri Apr 11 15:08:40 2014 -0400
@@ -23,22 +23,16 @@
package com.oracle.java.testlibrary.cli;
-import sun.hotspot.cpuinfo.CPUInfo;
-import com.oracle.java.testlibrary.*;
+import com.oracle.java.testlibrary.cli.predicate.CPUSpecificPredicate;
/**
* Base class for command line options tests that
* requires specific CPU arch or specific CPU features.
*/
public abstract class CPUSpecificCommandLineOptionTest
- extends CommandLineOptionTest {
-
- private String cpuArchPattern;
- private String supportedCPUFeatures[];
- private String unsupportedCPUFeatures[];
-
+ extends CommandLineOptionTest {
/**
- * Create new CPU specific test instance that does not
+ * Creates new CPU specific test instance that does not
* require any CPU features.
*
* @param cpuArchPattern Regular expression that should
@@ -49,62 +43,23 @@
}
/**
- * Create new CPU specific test instance that does not
+ * Creates new CPU specific test instance that does not
* require from CPU support of {@code supportedCPUFeatures} features
* and no support of {@code unsupportedCPUFeatures}.
*
* @param cpuArchPattern Regular expression that should
* match os.arch.
* @param supportedCPUFeatures Array with names of features that
- * should be supported by CPU. If <b>null</b>,
+ * should be supported by CPU. If {@code null},
* then no features have to be supported.
* @param unsupportedCPUFeatures Array with names of features that
* should not be supported by CPU.
- * If <b>null</b>, then CPU may support any
+ * If {@code null}, then CPU may support any
* features.
*/
public CPUSpecificCommandLineOptionTest(String cpuArchPattern,
- String supportedCPUFeatures[],
- String unsupportedCPUFeatures[]) {
- this.cpuArchPattern = cpuArchPattern;
- this.supportedCPUFeatures = supportedCPUFeatures;
- this.unsupportedCPUFeatures = unsupportedCPUFeatures;
- }
-
- /**
- * Check that CPU on test box has appropriate architecture, support all
- * required features and does not support all features that should not be
- * supported.
- *
- * @return <b>true</b> if CPU on test box fulfill all requirements.
- */
- @Override
- public boolean checkPreconditions() {
- if (!Platform.getOsArch().matches(cpuArchPattern)) {
- System.out.println("CPU arch does not match " + cpuArchPattern);
- return false;
- }
-
- if (supportedCPUFeatures != null) {
- for (String feature : supportedCPUFeatures) {
- if (!CPUInfo.hasFeature(feature)) {
- System.out.println("CPU does not support " + feature +
- " feature");
- return false;
- }
- }
- }
-
- if (unsupportedCPUFeatures != null) {
- for (String feature : unsupportedCPUFeatures) {
- if (CPUInfo.hasFeature(feature)) {
- System.out.println("CPU support " + feature + " feature");
- return false;
- }
- }
- }
-
- return true;
+ String supportedCPUFeatures[], String unsupportedCPUFeatures[]) {
+ super(new CPUSpecificPredicate(cpuArchPattern, supportedCPUFeatures,
+ unsupportedCPUFeatures));
}
}
-
--- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/CommandLineOptionTest.java Fri Apr 11 13:04:59 2014 +0200
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/CommandLineOptionTest.java Fri Apr 11 15:08:40 2014 -0400
@@ -26,6 +26,7 @@
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.function.BooleanSupplier;
import com.oracle.java.testlibrary.*;
@@ -33,34 +34,71 @@
* Base class for command line option tests.
*/
public abstract class CommandLineOptionTest {
-
- public static final String UNRECOGNIZED_OPTION_ERROR_FORMAT =
- "Unrecognized VM option '[+-]?%s'";
-
- public static final String printFlagsFinalFormat = "%s\\s*:?=\\s*%s";
+ public static final String UNLOCK_DIAGNOSTIC_VM_OPTIONS
+ = "-XX:+UnlockDiagnosticVMOptions";
+ public static final String UNLOCK_EXPERIMENTAL_VM_OPTIONS
+ = "-XX:+UnlockExperimentalVMOptions";
+ protected static final String UNRECOGNIZED_OPTION_ERROR_FORMAT
+ = "Unrecognized VM option '[+-]?%s(=.*)?'";
+ protected static final String EXPERIMENTAL_OPTION_ERROR_FORMAT
+ = "VM option '%s' is experimental and must be enabled via "
+ + "-XX:\\+UnlockExperimentalVMOptions.";
+ protected static final String DIAGNOSTIC_OPTION_ERROR_FORMAT
+ = " VM option '%s' is diagnostic and must be enabled via "
+ + "-XX:\\+UnlockDiagnosticVMOptions.";
+ private static final String PRINT_FLAGS_FINAL_FORMAT = "%s\\s*:?=\\s*%s";
/**
- * Verify that JVM startup behaviour matches our expectations.
+ * Verifies that JVM startup behaviour matches our expectations.
*
- * @param option The option that should be passed to JVM
- * @param excpectedMessages Array of patterns that should occur
- * in JVM output. If <b>null</b> then
+ * @param option an option that should be passed to JVM
+ * @param expectedMessages an array of patterns that should occur
+ * in JVM output. If {@code null} then
* JVM output could be empty.
- * @param unexpectedMessages Array of patterns that should not
- * occur in JVM output. If <b>null</b> then
- * JVM output could be empty.
+ * @param unexpectedMessages an array of patterns that should not
+ * occur in JVM output. If {@code null} then
+ * JVM output could be empty.
* @param exitCode expected exit code.
* @throws Throwable if verification fails or some other issues occur.
*/
public static void verifyJVMStartup(String option,
- String expectedMessages[],
- String unexpectedMessages[],
- ExitCode exitCode)
- throws Throwable {
+ String expectedMessages[], String unexpectedMessages[],
+ ExitCode exitCode) throws Throwable {
+ CommandLineOptionTest.verifyJVMStartup(expectedMessages,
+ unexpectedMessages, exitCode, false, option);
+ }
- OutputAnalyzer outputAnalyzer =
- ProcessTools.executeTestJvm(option, "-version");
+ /**
+ * Verifies that JVM startup behaviour matches our expectations.
+ *
+ * @param expectedMessages an array of patterns that should occur
+ * in JVM output. If {@code null} then
+ * JVM output could be empty.
+ * @param unexpectedMessages an array of patterns that should not
+ * occur in JVM output. If {@code null} then
+ * JVM output could be empty.
+ * @param exitCode expected exit code.
+ * @param addTestVMOptions if {@code true} then test VM options will be
+ * passed to VM.
+ * @param options options that should be passed to VM in addition to mode
+ * flag.
+ * @throws Throwable if verification fails or some other issues occur.
+ */
+ public static void verifyJVMStartup(String expectedMessages[],
+ String unexpectedMessages[], ExitCode exitCode,
+ boolean addTestVMOptions, String... options) throws Throwable {
+ List<String> finalOptions = new ArrayList<>();
+ if (addTestVMOptions) {
+ Collections.addAll(finalOptions, Utils.getTestJavaOpts());
+ }
+ Collections.addAll(finalOptions, options);
+ finalOptions.add("-version");
+ ProcessBuilder processBuilder
+ = ProcessTools.createJavaProcessBuilder(finalOptions.toArray(
+ new String[finalOptions.size()]));
+ OutputAnalyzer outputAnalyzer
+ = new OutputAnalyzer(processBuilder.start());
outputAnalyzer.shouldHaveExitValue(exitCode.value);
if (expectedMessages != null) {
@@ -77,97 +115,216 @@
}
/**
- * Verify that value of specified JVM option is the same as
+ * Verifies that JVM startup behaviour matches our expectations when type
+ * of newly started VM is the same as the type of current.
+ *
+ * @param expectedMessages an array of patterns that should occur
+ * in JVM output. If {@code null} then
+ * JVM output could be empty.
+ * @param unexpectedMessages an array of patterns that should not
+ * occur in JVM output. If {@code null} then
+ * JVM output could be empty.
+ * @param exitCode expected exit code.
+ * @param options options that should be passed to VM in addition to mode
+ * flag.
+ * @throws Throwable if verification fails or some other issues occur.
+ */
+ public static void verifySameJVMStartup(String expectedMessages[],
+ String unexpectedMessages[], ExitCode exitCode, String... options)
+ throws Throwable {
+ List<String> finalOptions = new ArrayList<>();
+ finalOptions.add(CommandLineOptionTest.getVMTypeOption());
+ Collections.addAll(finalOptions, options);
+
+ CommandLineOptionTest.verifyJVMStartup(expectedMessages,
+ unexpectedMessages, exitCode, false,
+ finalOptions.toArray(new String[finalOptions.size()]));
+ }
+
+ /**
+ * Verifies that value of specified JVM option is the same as
* expected value.
* This method filter out option with {@code optionName}
* name from test java options.
*
- * @param optionName Name of tested option.
- * @param expectedValue Expected value of tested option.
- * @param additionalVMOpts Additonal options that should be
+ * @param optionName a name of tested option.
+ * @param expectedValue expected value of tested option.
+ * @param additionalVMOpts additional options that should be
* passed to JVM.
* @throws Throwable if verification fails or some other issues occur.
*/
public static void verifyOptionValue(String optionName,
- String expectedValue,
- String... additionalVMOpts)
- throws Throwable {
+ String expectedValue, String... additionalVMOpts) throws Throwable {
verifyOptionValue(optionName, expectedValue, true, additionalVMOpts);
}
/**
- * Verify that value of specified JVM option is the same as
+ * Verifies that value of specified JVM option is the same as
* expected value.
* This method filter out option with {@code optionName}
* name from test java options.
*
- * @param optionName Name of tested option.
- * @param expectedValue Expected value of tested option.
- * @param addTestVmOptions If <b>true</b>, then test VM options
+ * @param optionName a name of tested option.
+ * @param expectedValue expected value of tested option.
+ * @param addTestVmOptions if {@code true}, then test VM options
* will be used.
- * @param additionalVMOpts Additonal options that should be
+ * @param additionalVMOpts additional options that should be
* passed to JVM.
- * @throws Throwable if verification fails or some other issues occur.
+ * @throws Throwable if verification fails or some other issues
+ * occur.
*/
public static void verifyOptionValue(String optionName,
- String expectedValue,
- boolean addTestVmOptions,
- String... additionalVMOpts)
- throws Throwable {
-
- List<String> vmOpts = new ArrayList<String>();
+ String expectedValue, boolean addTestVmOptions,
+ String... additionalVMOpts) throws Throwable {
+ List<String> vmOpts = new ArrayList<>();
if (addTestVmOptions) {
Collections.addAll(vmOpts,
Utils.getFilteredTestJavaOpts(optionName));
}
Collections.addAll(vmOpts, additionalVMOpts);
- Collections.addAll(vmOpts, new String[] {
- "-XX:+PrintFlagsFinal",
- "-version"
- });
+ Collections.addAll(vmOpts, "-XX:+PrintFlagsFinal", "-version");
- ProcessBuilder processBuilder =
- ProcessTools.
- createJavaProcessBuilder(vmOpts.
- toArray(new String[vmOpts.size()]));
+ ProcessBuilder processBuilder = ProcessTools.createJavaProcessBuilder(
+ vmOpts.toArray(new String[vmOpts.size()]));
- OutputAnalyzer outputAnalyzer =
- new OutputAnalyzer(processBuilder.start());
+ OutputAnalyzer outputAnalyzer
+ = new OutputAnalyzer(processBuilder.start());
outputAnalyzer.shouldHaveExitValue(0);
- outputAnalyzer.shouldMatch(String.
- format(printFlagsFinalFormat,
- optionName,
- expectedValue));
+ outputAnalyzer.shouldMatch(String.format(
+ CommandLineOptionTest.PRINT_FLAGS_FINAL_FORMAT,
+ optionName, expectedValue));
+ }
+
+ /**
+ * Verifies that value of specified JVM when type of newly started VM
+ * is the same as the type of current.
+ * This method filter out option with {@code optionName}
+ * name from test java options.
+ * Only mode flag will be passed to VM in addition to
+ * {@code additionalVMOpts}
+ *
+ * @param optionName name of tested option.
+ * @param expectedValue expected value of tested option.
+ * @param additionalVMOpts additional options that should be
+ * passed to JVM.
+ * @throws Throwable if verification fails or some other issues occur.
+ */
+ public static void verifyOptionValueForSameVM(String optionName,
+ String expectedValue, String... additionalVMOpts) throws Throwable {
+ List<String> finalOptions = new ArrayList<>();
+ finalOptions.add(CommandLineOptionTest.getVMTypeOption());
+ Collections.addAll(finalOptions, additionalVMOpts);
+
+ CommandLineOptionTest.verifyOptionValue(optionName, expectedValue,
+ false, finalOptions.toArray(new String[finalOptions.size()]));
+ }
+
+ /**
+ * Prepares boolean command line flag with name {@code name} according
+ * to it's {@code value}.
+ *
+ * @param name the name of option to be prepared
+ * @param value the value of option
+ * @return prepared command line flag
+ */
+ public static String prepareBooleanFlag(String name, boolean value) {
+ return String.format("-XX:%c%s", (value ? '+' : '-'), name);
+ }
+
+ /**
+ * Prepares numeric command line flag with name {@code name} by setting
+ * it's value to {@code value}.
+ *
+ * @param name the name of option to be prepared
+ * @param value the value of option
+ * @return prepared command line flag
+ */
+ public static String prepareNumericFlag(String name, Number value) {
+ return String.format("-XX:%s=%s", name, value.toString());
}
+ /**
+ * Returns message that should occur in VM output if option
+ * {@code optionName} if unrecognized.
+ *
+ * @param optionName the name of option for which message should be returned
+ * @return message saying that option {@code optionName} is unrecognized
+ */
+ public static String getUnrecognizedOptionErrorMessage(String optionName) {
+ return String.format(
+ CommandLineOptionTest.UNRECOGNIZED_OPTION_ERROR_FORMAT,
+ optionName);
+ }
+
+ /**
+ * Returns message that should occur in VM output if option
+ * {@code optionName} is experimental and
+ * -XX:+UnlockExperimentalVMOptions was not passed to VM.
+ *
+ * @param optionName the name of option for which message should be returned
+ * @return message saying that option {@code optionName} is experimental
+ */
+ public static String getExperimentalOptionErrorMessage(String optionName) {
+ return String.format(
+ CommandLineOptionTest.EXPERIMENTAL_OPTION_ERROR_FORMAT,
+ optionName);
+ }
/**
- * Run command line option test.
+ * Returns message that should occur in VM output if option
+ * {@code optionName} is diagnostic and -XX:+UnlockDiagnosticVMOptions
+ * was not passed to VM.
*
- * @throws Throwable if test failed.
+ * @param optionName the name of option for which message should be returned
+ * @return message saying that option {@code optionName} is diganostic
+ */
+ public static String getDiagnosticOptionErrorMessage(String optionName) {
+ return String.format(
+ CommandLineOptionTest.DIAGNOSTIC_OPTION_ERROR_FORMAT,
+ optionName);
+ }
+
+ /**
+ * @return option required to start a new VM with the same type as current.
+ * @throws RuntimeException when VM type is unknown.
+ */
+ private static String getVMTypeOption() {
+ if (Platform.isServer()) {
+ return "-server";
+ } else if (Platform.isClient()) {
+ return "-client";
+ } else if (Platform.isMinimal()) {
+ return "-minimal";
+ } else if (Platform.isGraal()) {
+ return "-graal";
+ }
+ throw new RuntimeException("Unknown VM mode.");
+ }
+
+ private final BooleanSupplier predicate;
+
+ /**
+ * Constructs new CommandLineOptionTest that will be executed only if
+ * predicate {@code predicate} return {@code true}.
+ * @param predicate a predicate responsible for test's preconditions check.
+ */
+ public CommandLineOptionTest(BooleanSupplier predicate) {
+ this.predicate = predicate;
+ }
+
+ /**
+ * Runs command line option test.
*/
public final void test() throws Throwable {
- if (checkPreconditions()) {
+ if (predicate.getAsBoolean()) {
runTestCases();
}
}
/**
- * Check that all preconditions for test execution are met.
- *
- * @return <b>true</b> if test could be executed.
+ * @throws Throwable if some issue happened during test cases execution.
*/
- public boolean checkPreconditions() {
- return true;
- }
-
- /**
- * Run test cases.
- *
- * @throws Throwable if test failed.
- */
- public abstract void runTestCases() throws Throwable;
+ protected abstract void runTestCases() throws Throwable;
}
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/predicate/AndPredicate.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2014, 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 com.oracle.java.testlibrary.cli.predicate;
+
+import java.util.function.BooleanSupplier;
+
+public class AndPredicate implements BooleanSupplier {
+ private final BooleanSupplier a;
+ private final BooleanSupplier b;
+
+ public AndPredicate(BooleanSupplier a, BooleanSupplier b) {
+ this.a = a;
+ this.b = b;
+ }
+
+ @Override
+ public boolean getAsBoolean() {
+ return a.getAsBoolean() && b.getAsBoolean();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/predicate/CPUSpecificPredicate.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2014, 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 com.oracle.java.testlibrary.cli.predicate;
+
+import com.oracle.java.testlibrary.Platform;
+import sun.hotspot.cpuinfo.CPUInfo;
+
+import java.util.function.BooleanSupplier;
+
+public class CPUSpecificPredicate implements BooleanSupplier {
+ private final String cpuArchPattern;
+ private final String supportedCPUFeatures[];
+ private final String unsupportedCPUFeatures[];
+
+ public CPUSpecificPredicate(String cpuArchPattern,
+ String supportedCPUFeatures[],
+ String unsupportedCPUFeatures[]) {
+ this.cpuArchPattern = cpuArchPattern;
+ this.supportedCPUFeatures = supportedCPUFeatures;
+ this.unsupportedCPUFeatures = unsupportedCPUFeatures;
+ }
+
+ @Override
+ public boolean getAsBoolean() {
+ if (!Platform.getOsArch().matches(cpuArchPattern)) {
+ System.out.println("CPU arch does not match " + cpuArchPattern);
+ return false;
+ }
+
+ if (supportedCPUFeatures != null) {
+ for (String feature : supportedCPUFeatures) {
+ if (!CPUInfo.hasFeature(feature)) {
+ System.out.println("CPU does not support " + feature
+ + " feature");
+ return false;
+ }
+ }
+ }
+
+ if (unsupportedCPUFeatures != null) {
+ for (String feature : unsupportedCPUFeatures) {
+ if (CPUInfo.hasFeature(feature)) {
+ System.out.println("CPU support " + feature + " feature");
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/predicate/NotPredicate.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2014, 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 com.oracle.java.testlibrary.cli.predicate;
+
+import java.util.function.BooleanSupplier;
+
+public class NotPredicate implements BooleanSupplier {
+ private final BooleanSupplier s;
+
+ public NotPredicate(BooleanSupplier s) {
+ this.s = s;
+ }
+
+ @Override
+ public boolean getAsBoolean() {
+ return !s.getAsBoolean();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/predicate/OrPredicate.java Fri Apr 11 15:08:40 2014 -0400
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2014, 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 com.oracle.java.testlibrary.cli.predicate;
+
+import java.util.function.BooleanSupplier;
+
+public class OrPredicate implements BooleanSupplier {
+ private final BooleanSupplier a;
+ private final BooleanSupplier b;
+
+ public OrPredicate(BooleanSupplier a, BooleanSupplier b) {
+ this.a = a;
+ this.b = b;
+ }
+
+ @Override
+ public boolean getAsBoolean() {
+ return a.getAsBoolean() || b.getAsBoolean();
+ }
+}