# HG changeset patch # User coleenp # Date 1397688025 14400 # Node ID 7e6c20c85ccf4402842e3cd4f728cd204436d4a3 # Parent bd58c9e40d0ab2f1cfe2e9cc269f97f30c5c00ae# Parent 0af0caeb6a3acff905db86d226efce08042ec318 Merge diff -r bd58c9e40d0a -r 7e6c20c85ccf src/cpu/sparc/vm/assembler_sparc.hpp --- a/src/cpu/sparc/vm/assembler_sparc.hpp Mon Mar 03 13:58:52 2014 -0500 +++ b/src/cpu/sparc/vm/assembler_sparc.hpp Wed Apr 16 18:40:25 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) { diff -r bd58c9e40d0a -r 7e6c20c85ccf src/cpu/sparc/vm/assembler_sparc.inline.hpp --- a/src/cpu/sparc/vm/assembler_sparc.inline.hpp Mon Mar 03 13:58:52 2014 -0500 +++ b/src/cpu/sparc/vm/assembler_sparc.inline.hpp Wed Apr 16 18:40:25 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); } diff -r bd58c9e40d0a -r 7e6c20c85ccf src/cpu/sparc/vm/macroAssembler_sparc.inline.hpp --- a/src/cpu/sparc/vm/macroAssembler_sparc.inline.hpp Mon Mar 03 13:58:52 2014 -0500 +++ b/src/cpu/sparc/vm/macroAssembler_sparc.inline.hpp Wed Apr 16 18:40:25 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); } diff -r bd58c9e40d0a -r 7e6c20c85ccf src/cpu/sparc/vm/sparc.ad --- a/src/cpu/sparc/vm/sparc.ad Mon Mar 03 13:58:52 2014 -0500 +++ b/src/cpu/sparc/vm/sparc.ad Wed Apr 16 18:40:25 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); %} diff -r bd58c9e40d0a -r 7e6c20c85ccf src/share/vm/adlc/output_h.cpp --- a/src/share/vm/adlc/output_h.cpp Mon Mar 03 13:58:52 2014 -0500 +++ b/src/share/vm/adlc/output_h.cpp Wed Apr 16 18:40:25 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; } } diff -r bd58c9e40d0a -r 7e6c20c85ccf src/share/vm/classfile/classFileParser.cpp --- a/src/share/vm/classfile/classFileParser.cpp Mon Mar 03 13:58:52 2014 -0500 +++ b/src/share/vm/classfile/classFileParser.cpp Wed Apr 16 18:40:25 2014 -0400 @@ -3746,18 +3746,24 @@ Exceptions::fthrow( THREAD_AND_LOCATION, vmSymbols::java_lang_UnsupportedClassVersionError(), - "Unsupported major.minor version %u.%u", + "Unsupported class file version %u.%u, " + "this version of the Java Runtime only recognizes class file versions up to %u.%u", major_version, - minor_version); + minor_version, + JAVA_MAX_SUPPORTED_VERSION, + JAVA_MAX_SUPPORTED_MINOR_VERSION); } else { ResourceMark rm(THREAD); Exceptions::fthrow( THREAD_AND_LOCATION, vmSymbols::java_lang_UnsupportedClassVersionError(), - "%s : Unsupported major.minor version %u.%u", + "%s has been compiled by a more recent version of the Java Runtime (class file version %u.%u), " + "this version of the Java Runtime only recognizes class file versions up to %u.%u", name->as_C_string(), major_version, - minor_version); + minor_version, + JAVA_MAX_SUPPORTED_VERSION, + JAVA_MAX_SUPPORTED_MINOR_VERSION); } return nullHandle; } diff -r bd58c9e40d0a -r 7e6c20c85ccf src/share/vm/opto/machnode.hpp --- a/src/share/vm/opto/machnode.hpp Mon Mar 03 13:58:52 2014 -0500 +++ b/src/share/vm/opto/machnode.hpp Wed Apr 16 18:40:25 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; } diff -r bd58c9e40d0a -r 7e6c20c85ccf src/share/vm/opto/node.hpp --- a/src/share/vm/opto/node.hpp Mon Mar 03 13:58:52 2014 -0500 +++ b/src/share/vm/opto/node.hpp Wed Apr 16 18:40:25 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 }; diff -r bd58c9e40d0a -r 7e6c20c85ccf src/share/vm/opto/output.cpp --- a/src/share/vm/opto/output.cpp Mon Mar 03 13:58:52 2014 -0500 +++ b/src/share/vm/opto/output.cpp Wed Apr 16 18:40:25 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; } diff -r bd58c9e40d0a -r 7e6c20c85ccf test/compiler/rtm/cli/TestRTMRetryCountOption.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/rtm/cli/TestRTMRetryCountOption.java Wed Apr 16 18:40:25 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 RTMRetryCount option. + * @library /testlibrary + * @build TestRTMRetryCountOption + * @run main/othervm TestRTMRetryCountOption + */ + +public class TestRTMRetryCountOption extends RTMGenericCommandLineOptionTest { + private static final String DEFAULT_VALUE = "5"; + + private TestRTMRetryCountOption() { + super(Boolean.TRUE::booleanValue, "RTMRetryCount", false, true, + TestRTMRetryCountOption.DEFAULT_VALUE, + "0", "10", "100", "1000"); + } + + public static void main(String args[]) throws Throwable { + new TestRTMRetryCountOption().test(); + } +} diff -r bd58c9e40d0a -r 7e6c20c85ccf test/compiler/types/correctness/CorrectnessTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/types/correctness/CorrectnessTest.java Wed Apr 16 18:40:25 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 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 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>> 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> 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(); + } + } +} diff -r bd58c9e40d0a -r 7e6c20c85ccf test/compiler/types/correctness/OffTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/types/correctness/OffTest.java Wed Apr 16 18:40:25 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(); + } +} diff -r bd58c9e40d0a -r 7e6c20c85ccf test/compiler/types/correctness/execution/Execution.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/types/correctness/execution/Execution.java Wed Apr 16 18:40:25 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 parameter type + * @param result Type + */ +public interface Execution { + /** + * Executes the test code of the given scenario + * See {@link scenarios.Scenario#run(T)} + * + * @param scenario test scenario + */ + void execute(Scenario scenario); + + default String getName() { + return this.getClass().getName(); + } +} diff -r bd58c9e40d0a -r 7e6c20c85ccf test/compiler/types/correctness/execution/MethodHandleDelegate.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/types/correctness/execution/MethodHandleDelegate.java Wed Apr 16 18:40:25 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 implements Execution { + private final Execution delegate; + + public MethodHandleDelegate(Execution delegate) { + this.delegate = delegate; + } + + @Override + public void execute(Scenario scenario) { + delegate.execute(new MHScenario(scenario)); + } + + @Override + public String getName() { + return "MethodHandleDelegate # " + delegate.getName(); + } + + private static class MHScenario extends Scenario { + private final Scenario 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 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); + } + } +} diff -r bd58c9e40d0a -r 7e6c20c85ccf test/compiler/types/correctness/execution/TypeConflict.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/types/correctness/execution/TypeConflict.java Wed Apr 16 18:40:25 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 implements Execution { + /** 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 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 scenario, T t) { + return scenario.run(t); + } +} + diff -r bd58c9e40d0a -r 7e6c20c85ccf test/compiler/types/correctness/execution/TypeProfile.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/types/correctness/execution/TypeProfile.java Wed Apr 16 18:40:25 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 implements Execution { + /** 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 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 scenario, T t) { + return scenario.run(t); + } +} diff -r bd58c9e40d0a -r 7e6c20c85ccf test/compiler/types/correctness/hierarchies/DefaultMethodInterface.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/types/correctness/hierarchies/DefaultMethodInterface.java Wed Apr 16 18:40:25 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 { + 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; + } + } +} diff -r bd58c9e40d0a -r 7e6c20c85ccf test/compiler/types/correctness/hierarchies/DefaultMethodInterface2.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/types/correctness/hierarchies/DefaultMethodInterface2.java Wed Apr 16 18:40:25 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 { + 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() + } +} diff -r bd58c9e40d0a -r 7e6c20c85ccf test/compiler/types/correctness/hierarchies/Linear.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/types/correctness/hierarchies/Linear.java Wed Apr 16 18:40:25 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 { + 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; + } + } +} diff -r bd58c9e40d0a -r 7e6c20c85ccf test/compiler/types/correctness/hierarchies/Linear2.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/types/correctness/hierarchies/Linear2.java Wed Apr 16 18:40:25 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 { + 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; + } + } +} diff -r bd58c9e40d0a -r 7e6c20c85ccf test/compiler/types/correctness/hierarchies/NullableType.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/types/correctness/hierarchies/NullableType.java Wed Apr 16 18:40:25 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 + extends TypeHierarchy { + + public NullableType(TypeHierarchy delegate) { + super(delegate.getM(), null, + delegate.getClassM(), delegate.getClassN()); + } +} diff -r bd58c9e40d0a -r 7e6c20c85ccf test/compiler/types/correctness/hierarchies/OneRank.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/types/correctness/hierarchies/OneRank.java Wed Apr 16 18:40:25 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 { + 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; + } + } + +} diff -r bd58c9e40d0a -r 7e6c20c85ccf test/compiler/types/correctness/hierarchies/TypeHierarchy.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/types/correctness/hierarchies/TypeHierarchy.java Wed Apr 16 18:40:25 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 { + // 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 classM; + private final Class classN; + + protected TypeHierarchy(M m, N n, Class classM, Class 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 getClassM() { + return classM; + } + + public final Class getClassN() { + return classN; + } + + public interface I { + int m(); + } + + public static class A implements I { + @Override + public int m() { + return TypeHierarchy.ANSWER; + } + } +} diff -r bd58c9e40d0a -r 7e6c20c85ccf test/compiler/types/correctness/scenarios/ArrayCopy.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/types/correctness/scenarios/ArrayCopy.java Wed Apr 16 18:40:25 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 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"); + } +} diff -r bd58c9e40d0a -r 7e6c20c85ccf test/compiler/types/correctness/scenarios/ArrayReferenceStore.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/types/correctness/scenarios/ArrayReferenceStore.java Wed Apr 16 18:40:25 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 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"); + } +} diff -r bd58c9e40d0a -r 7e6c20c85ccf test/compiler/types/correctness/scenarios/ArrayScenario.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/types/correctness/scenarios/ArrayScenario.java Wed Apr 16 18:40:25 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 { + protected final TypeHierarchy.I[] array; + protected final TypeHierarchy.I[][] matrix; + + protected ArrayScenario(String name, ProfilingType profilingType, + TypeHierarchy 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"); + } +} diff -r bd58c9e40d0a -r 7e6c20c85ccf test/compiler/types/correctness/scenarios/CheckCast.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/types/correctness/scenarios/CheckCast.java Wed Apr 16 18:40:25 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 profiling parameter + */ +public class CheckCast extends Scenario { + public CheckCast(ProfilingType profilingType, TypeHierarchy 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"); + } + } +} diff -r bd58c9e40d0a -r 7e6c20c85ccf test/compiler/types/correctness/scenarios/ClassIdentity.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/types/correctness/scenarios/ClassIdentity.java Wed Apr 16 18:40:25 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 extends Scenario { + public ClassIdentity(ProfilingType profilingType, + TypeHierarchy 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"); + } + } +} diff -r bd58c9e40d0a -r 7e6c20c85ccf test/compiler/types/correctness/scenarios/ClassInstanceOf.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/types/correctness/scenarios/ClassInstanceOf.java Wed Apr 16 18:40:25 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 extends Scenario { + public ClassInstanceOf(ProfilingType profilingType, + TypeHierarchy 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"); + } + } +} diff -r bd58c9e40d0a -r 7e6c20c85ccf test/compiler/types/correctness/scenarios/ClassIsInstance.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/types/correctness/scenarios/ClassIsInstance.java Wed Apr 16 18:40:25 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 extends Scenario { + private final Class baseClass; + + public ClassIsInstance(ProfilingType profilingType, + TypeHierarchy 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"); + } + } +} diff -r bd58c9e40d0a -r 7e6c20c85ccf test/compiler/types/correctness/scenarios/ProfilingType.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/types/correctness/scenarios/ProfilingType.java Wed Apr 16 18:40:25 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, +} diff -r bd58c9e40d0a -r 7e6c20c85ccf test/compiler/types/correctness/scenarios/ReceiverAtInvokes.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/types/correctness/scenarios/ReceiverAtInvokes.java Wed Apr 16 18:40:25 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 parameter to be returned + */ +public class ReceiverAtInvokes extends Scenario { + public ReceiverAtInvokes(ProfilingType profilingType, + TypeHierarchy 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"); + } +} diff -r bd58c9e40d0a -r 7e6c20c85ccf test/compiler/types/correctness/scenarios/Scenario.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/types/correctness/scenarios/Scenario.java Wed Apr 16 18:40:25 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 parameter type + * @param result type + */ +public abstract class Scenario { + + private final String name; + public final ProfilingType profilingType; + public final TypeHierarchy 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 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); +} diff -r bd58c9e40d0a -r 7e6c20c85ccf test/runtime/ClassFile/UnsupportedClassFileVersion.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/ClassFile/UnsupportedClassFileVersion.java Wed Apr 16 18:40:25 2014 -0400 @@ -0,0 +1,69 @@ +/* + * 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 + * @library /testlibrary + * @compile -XDignore.symbol.file UnsupportedClassFileVersion.java + * @run main UnsupportedClassFileVersion + */ + +import java.io.File; +import java.io.FileOutputStream; +import jdk.internal.org.objectweb.asm.ClassWriter; +import jdk.internal.org.objectweb.asm.MethodVisitor; +import jdk.internal.org.objectweb.asm.Opcodes; +import com.oracle.java.testlibrary.*; + +public class UnsupportedClassFileVersion implements Opcodes { + public static void main(String... args) throws Exception { + writeClassFile(); + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, "-cp", ".", "ClassFile"); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldContain("ClassFile has been compiled by a more recent version of the " + + "Java Runtime (class file version 99.0), this version of " + + "the Java Runtime only recognizes class file versions up to " + + System.getProperty("java.class.version")); + + output.shouldHaveExitValue(1); + } + + public static void writeClassFile() throws Exception { + ClassWriter cw = new ClassWriter(0); + MethodVisitor mv; + + cw.visit(99, ACC_PUBLIC + ACC_SUPER, "ClassFile", null, "java/lang/Object", null); + mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); + mv.visitCode(); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V", false); + mv.visitInsn(RETURN); + mv.visitMaxs(1, 1); + mv.visitEnd(); + cw.visitEnd(); + + try (FileOutputStream fos = new FileOutputStream(new File("ClassFile.class"))) { + fos.write(cw.toByteArray()); + } + } +} diff -r bd58c9e40d0a -r 7e6c20c85ccf test/testlibrary/com/oracle/java/testlibrary/ProcessTools.java --- a/test/testlibrary/com/oracle/java/testlibrary/ProcessTools.java Mon Mar 03 13:58:52 2014 -0500 +++ b/test/testlibrary/com/oracle/java/testlibrary/ProcessTools.java Wed Apr 16 18:40:25 2014 -0400 @@ -142,11 +142,23 @@ * with any platform specific arguments prepended */ public static ProcessBuilder createJavaProcessBuilder(String... command) throws Exception { + return createJavaProcessBuilder(false, command); + } + + public static ProcessBuilder createJavaProcessBuilder(boolean addTestVmOptions, String... command) throws Exception { String javapath = JDKToolFinder.getJDKTool("java"); ArrayList args = new ArrayList<>(); args.add(javapath); Collections.addAll(args, getPlatformSpecificVMArgs()); + + if (addTestVmOptions) { + String vmopts = System.getProperty("test.vm.opts"); + if (vmopts != null && vmopts.length() > 0) { + Collections.addAll(args, vmopts.split("\\s")); + } + } + Collections.addAll(args, command); // Reporting @@ -234,5 +246,4 @@ } return cmd.toString().trim(); } - }