提交 455c27bc 编写于 作者: C coleenp

Merge

......@@ -630,11 +630,20 @@ class Assembler : public AbstractAssembler {
}
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 @@ class Assembler : public AbstractAssembler {
void no_cbcond_before() {
assert(offset() == 0 || !cbcond_before(), "cbcond should not follow an other cbcond");
}
public:
bool use_cbcond(Label& L) {
......
......@@ -54,33 +54,33 @@ inline void Assembler::emit_data(int x, RelocationHolder const& rspec) {
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); }
......
......@@ -233,6 +233,7 @@ inline void MacroAssembler::br( Condition c, bool a, Predict p, address d, reloc
}
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, address d, relo
}
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, address d, reloc
}
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( address d, relocInfo::relocType rt ) {
}
inline void MacroAssembler::call( Label& L, relocInfo::relocType rt ) {
insert_nop_after_cbcond();
MacroAssembler::call( target(L), rt);
}
......
......@@ -1268,7 +1268,7 @@ int MachPrologNode::reloc() const {
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 @@ void MachEpilogNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
#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 @@ void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
__ 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 @@ op_attrib op_cost(1); // Required cost attribute
//----------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 @@ instruct encodeHeapOop(iRegN dst, iRegP src) %{
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 @@ instruct branch(label labl) %{
__ ba(*L);
__ delayed()->nop();
%}
ins_avoid_back_to_back(AVOID_BEFORE);
ins_pipe(br);
%}
......@@ -9217,7 +9239,7 @@ instruct branch_short(label labl) %{
__ 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 @@ instruct branchCon(cmpOp cmp, flagsReg icc, label labl) %{
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 @@ instruct branchConU(cmpOpU cmp, flagsRegU icc, label labl) %{
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 @@ instruct branchConP(cmpOpP cmp, flagsRegP pcc, label labl) %{
__ 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 @@ instruct branchConF(cmpOpF cmp, flagsRegF fcc, label labl) %{
__ 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 @@ instruct branchLoopEnd(cmpOp cmp, flagsReg icc, label labl) %{
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 @@ instruct branchLoopEndU(cmpOpU cmp, flagsRegU icc, label labl) %{
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 @@ instruct cmpI_reg_branch_short(cmpOp cmp, iRegI op1, iRegI op2, label labl, flag
__ 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 @@ instruct cmpI_imm_branch_short(cmpOp cmp, iRegI op1, immI5 op2, label labl, flag
__ 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 @@ instruct cmpU_reg_branch_short(cmpOpU cmp, iRegI op1, iRegI op2, label labl, fla
__ 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 @@ instruct cmpU_imm_branch_short(cmpOpU cmp, iRegI op1, immI5 op2, label labl, fla
__ 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 @@ instruct cmpL_reg_branch_short(cmpOp cmp, iRegL op1, iRegL op2, label labl, flag
__ 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 @@ instruct cmpL_imm_branch_short(cmpOp cmp, iRegL op1, immL5 op2, label labl, flag
__ 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 @@ instruct cmpP_reg_branch_short(cmpOpP cmp, iRegP op1, iRegP op2, label labl, fla
__ 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 @@ instruct cmpP_null_branch_short(cmpOpP cmp, iRegP op1, immP0 null, label labl, f
__ 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 @@ instruct cmpN_reg_branch_short(cmpOp cmp, iRegN op1, iRegN op2, label labl, flag
__ 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 @@ instruct cmpN_null_branch_short(cmpOp cmp, iRegN op1, immN0 null, label labl, fl
__ 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 @@ instruct cmpI_reg_branchLoopEnd_short(cmpOp cmp, iRegI op1, iRegI op2, label lab
__ 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 @@ instruct cmpI_imm_branchLoopEnd_short(cmpOp cmp, iRegI op1, immI5 op2, label lab
__ 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 @@ instruct branchCon_regI(cmpOp_reg cmp, iRegI op1, immI0 zero, label labl) %{
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 @@ instruct branchCon_regP(cmpOp_reg cmp, iRegP op1, immP0 null, label labl) %{
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 @@ instruct branchCon_regL(cmpOp_reg cmp, iRegL op1, immL0 zero, label labl) %{
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 @@ instruct branchCon_long(cmpOp cmp, flagsRegL xcc, label labl) %{
__ 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 @@ instruct CallStaticJavaDirect( method meth ) %{
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 @@ instruct CallRuntimeDirect(method meth, l7RegP l7) %{
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 @@ instruct CallLeafDirect(method meth, l7RegP l7) %{
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 @@ instruct CallLeafNoFPDirect(method meth, l7RegP l7) %{
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 @@ instruct TailCalljmpInd(g3RegP jump_target, inline_cache_regP method_oop) %{
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 @@ instruct tailjmpInd(g1RegP jump_target, i0RegP ex_oop) %{
// 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 @@ instruct RethrowException()
// 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 @@ instruct partialSubtypeCheck( o0RegP index, o1RegP sub, o2RegP super, flagsRegP
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 @@ instruct partialSubtypeCheck_vs_zero( flagsRegP pcc, o1RegP sub, o2RegP super, i
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);
%}
......
......@@ -1613,21 +1613,20 @@ void ArchDesc::declareClasses(FILE *fp) {
// 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 @@ void ArchDesc::declareClasses(FILE *fp) {
}
// 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;
}
}
......
......@@ -3746,18 +3746,24 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
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;
}
......
......@@ -210,7 +210,14 @@ public:
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; }
......
......@@ -645,17 +645,18 @@ public:
// 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
};
......
......@@ -411,7 +411,7 @@ void Compile::shorten_branches(uint* blk_starts, int& code_size, int& reloc_size
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 @@ void Compile::shorten_branches(uint* blk_starts, int& code_size, int& reloc_size
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 @@ void Compile::shorten_branches(uint* blk_starts, int& code_size, int& reloc_size
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 @@ void Compile::shorten_branches(uint* blk_starts, int& code_size, int& reloc_size
}
} // (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 @@ void Compile::fill_buffer(CodeBuffer* cb, uint* blk_starts) {
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 @@ void Compile::fill_buffer(CodeBuffer* cb, uint* blk_starts) {
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 @@ void Compile::fill_buffer(CodeBuffer* cb, uint* blk_starts) {
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;
}
......
/*
* 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();
}
}
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test CorrectnessTest
* @bug 8038418
* @library /testlibrary /testlibrary/whitebox
* @compile execution/TypeConflict.java execution/TypeProfile.java
* execution/MethodHandleDelegate.java
* @build CorrectnessTest
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions
* -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
* -XX:TypeProfileLevel=222 -XX:+UseTypeSpeculation
* -XX:CompileCommand=exclude,execution/*::methodNotToCompile
* -XX:CompileCommand=dontinline,scenarios/Scenario::collectReturnType
* CorrectnessTest RETURN
* @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions
* -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
* -XX:TypeProfileLevel=222 -XX:+UseTypeSpeculation
* -XX:CompileCommand=exclude,execution/*::methodNotToCompile
* -XX:CompileCommand=dontinline,scenarios/Scenario::collectReturnType
* CorrectnessTest PARAMETERS
* @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions
* -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
* -XX:TypeProfileLevel=222 -XX:+UseTypeSpeculation
* -XX:CompileCommand=exclude,execution/*::methodNotToCompile
* -XX:CompileCommand=dontinline,scenarios/Scenario::collectReturnType
* CorrectnessTest ARGUMENTS
* @summary Tests correctness of type usage with type profiling and speculations
*/
import com.oracle.java.testlibrary.Asserts;
import com.oracle.java.testlibrary.Platform;
import execution.Execution;
import execution.MethodHandleDelegate;
import execution.TypeConflict;
import execution.TypeProfile;
import hierarchies.*;
import scenarios.*;
import sun.hotspot.WhiteBox;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.function.BiFunction;
public class CorrectnessTest {
private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
public static void main(String[] args) {
if (!Platform.isServer()) {
System.out.println("ALL TESTS SKIPPED");
}
Asserts.assertGTE(args.length, 1);
ProfilingType profilingType = ProfilingType.valueOf(args[0]);
if (runTests(profilingType)) {
System.out.println("ALL TESTS PASSED");
} else {
throw new RuntimeException("SOME TESTS FAILED");
}
}
@SuppressWarnings("unchecked")
public static boolean runTests(ProfilingType profilingType) {
boolean result = true;
List<Execution> executionList = new ArrayList<>();
executionList.add(new TypeConflict());
executionList.add(new TypeProfile());
for (int i = 0, n = executionList.size(); i < n; i++) {
executionList.add(new MethodHandleDelegate(executionList.get(i)));
}
List<TypeHierarchy> hierarchyList = new ArrayList<>();
hierarchyList.add(new DefaultMethodInterface.Hierarchy());
hierarchyList.add(new DefaultMethodInterface2.Hierarchy());
hierarchyList.add(new Linear.Hierarchy());
hierarchyList.add(new Linear2.Hierarchy());
hierarchyList.add(new OneRank.Hierarchy());
for (int i = 0, n = hierarchyList.size(); i < n; i++) {
hierarchyList.add(new NullableType(hierarchyList.get(i)));
}
List<BiFunction<ProfilingType, TypeHierarchy, Scenario<?, ?>>> testCasesConstructors
= new ArrayList<>();
testCasesConstructors.add(ArrayCopy::new);
testCasesConstructors.add(ArrayReferenceStore::new);
testCasesConstructors.add(ClassIdentity::new);
testCasesConstructors.add(ClassInstanceOf::new);
testCasesConstructors.add(ClassIsInstance::new);
testCasesConstructors.add(ReceiverAtInvokes::new);
testCasesConstructors.add(CheckCast::new);
for (TypeHierarchy hierarchy : hierarchyList) {
for (BiFunction<ProfilingType, TypeHierarchy, Scenario<?, ?>> constructor : testCasesConstructors) {
for (Execution execution : executionList) {
Scenario<?, ?> scenario = constructor.apply(profilingType, hierarchy);
if (scenario.isApplicable()) {
result &= executeTest(hierarchy, execution, scenario);
}
}
}
}
return result;
}
/**
* Executes test case
*
* @param hierarchy type hierarchy for the test
* @param execution execution scenario
* @param scenario test scenario executed with given Execution
*/
private static boolean executeTest(TypeHierarchy hierarchy, Execution execution, Scenario<?, ?> scenario) {
boolean testCaseResult = false;
String testName = hierarchy.getClass().getName() + " :: " + scenario.getName() + " @ " + execution.getName();
clearAllMethodsState(scenario.getClass());
try {
execution.execute(scenario);
testCaseResult = true;
} catch (Exception e) {
System.err.println(testName + " failed with exception " + e);
e.printStackTrace();
}
System.out.println((testCaseResult ? "PASSED: " : "FAILED: ") + testName);
return testCaseResult;
}
private static void clearAllMethodsState(Class aClass) {
while (aClass != null) {
for (Method m : aClass.getDeclaredMethods()) {
WHITE_BOX.clearMethodState(m);
}
aClass = aClass.getSuperclass();
}
}
}
/*
* 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();
}
}
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package execution;
import hierarchies.TypeHierarchy;
import scenarios.Scenario;
/**
* Execution scenario represents test methods execution type.
* @param <T> parameter type
* @param <R> result Type
*/
public interface Execution<T extends TypeHierarchy.I, R> {
/**
* Executes the test code of the given scenario
* See {@link scenarios.Scenario#run(T)}
*
* @param scenario test scenario
*/
void execute(Scenario<T, R> scenario);
default String getName() {
return this.getClass().getName();
}
}
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package execution;
import hierarchies.TypeHierarchy;
import scenarios.Scenario;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
/**
* Executes test scenario using {@link MethodHandle#invoke(Object...)}.
* Delegates execution to the given {@link Execution} by creating
* new test scenario, see {@link Scenario}
*/
public class MethodHandleDelegate<T extends TypeHierarchy.I, R> implements Execution<T, R> {
private final Execution<T, R> delegate;
public MethodHandleDelegate(Execution<T, R> delegate) {
this.delegate = delegate;
}
@Override
public void execute(Scenario<T, R> scenario) {
delegate.execute(new MHScenario<T, R>(scenario));
}
@Override
public String getName() {
return "MethodHandleDelegate # " + delegate.getName();
}
private static class MHScenario<T extends TypeHierarchy.I, R> extends Scenario<T, R> {
private final Scenario<T, R> scenario;
private static final MethodHandle METHOD_HANDLE_RUN;
static {
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodType methodType = MethodType.methodType(Object.class, TypeHierarchy.I.class);
try {
METHOD_HANDLE_RUN = lookup.findVirtual(Scenario.class, "run", methodType);
} catch (NoSuchMethodException | IllegalAccessException e) {
System.err.println("Failed to get target method run() with " + e);
e.printStackTrace();
throw new RuntimeException(e);
}
}
/**
* Constructor
*
* @param scenario test scenario to be executed
*/
private MHScenario(Scenario<T, R> scenario) {
super("MethodHandle::" + scenario.getName(), scenario.profilingType, scenario.hierarchy);
this.scenario = scenario;
}
/**
* Runs {@link Scenario#run(T)} with {@link MethodHandle#invoke(Object...)}
*
* @param t subject of the test
* @return result of the underlying {@link Scenario#run(T)} invocation
*/
@SuppressWarnings("unchecked")
@Override
public R run(T t) {
try {
return (R) METHOD_HANDLE_RUN.invoke(scenario, t);
} catch (Throwable thr) {
System.err.println(scenario.getName()
+ " failed to invoke target method run() with " + thr);
throw new RuntimeException("Invocation failed", thr);
}
}
@Override
public void check(R r, T t) {
scenario.check(r, t);
}
}
}
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package execution;
import hierarchies.TypeHierarchy;
import scenarios.Scenario;
/**
* Type profiling conflict execution scenario. The main goal is
* to make compiler profile and compile methods with different types.
* Scenario tests guards by passing conflicting types (incompatible
* for the profiled data).
*/
public class TypeConflict<T extends TypeHierarchy.I, R> implements Execution<T, R> {
/** Test methods execution number to make profile */
private final static int POLLUTION_THRESHOLD = 5000;
/** Test methods execution number to make it profiled and compiled*/
private final static int PROFILE_THRESHOLD = 20000;
@Override
public void execute(Scenario<T, R> scenario) {
T base = scenario.getProfiled();
T incompatible = scenario.getConflict();
// pollute profile by passing different types
R baseResult = null;
R incResult = null;
for (int i = 0; i < POLLUTION_THRESHOLD; i++) {
baseResult = methodNotToCompile(scenario, base);
incResult = methodNotToCompile(scenario, incompatible);
}
scenario.check(baseResult, base);
scenario.check(incResult, incompatible);
// profile and compile
R result = null;
for (int i = 0; i < PROFILE_THRESHOLD; i++) {
result = methodNotToCompile(scenario, base);
}
scenario.check(result, base);
// pass another type to make guard work and recompile
for (int i = 0; i < PROFILE_THRESHOLD; i++) {
result = methodNotToCompile(scenario, incompatible);
}
scenario.check(result, incompatible);
}
private R methodNotToCompile(Scenario<T, R> scenario, T t) {
return scenario.run(t);
}
}
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package execution;
import hierarchies.TypeHierarchy;
import scenarios.Scenario;
/**
* Profile type execution scenario. Executes tester method
* in a loop without any manipulation with types or instances.
*/
public class TypeProfile<T extends TypeHierarchy.I, R> implements Execution<T, R> {
/** Number of test method execution to make it profiled and compiled */
private final static int PROFILE_THRESHOLD = 100000;
/**
* Makes scenario code be profiled and compiled
* @param scenario Test scenario
*/
@Override
public void execute(Scenario<T, R> scenario) {
R result = null;
T prof = scenario.getProfiled();
T confl = scenario.getConflict();
for (int i = 0; i < PROFILE_THRESHOLD; i++) {
result = methodNotToCompile(scenario, prof);
}
scenario.check(result, prof);
result = methodNotToCompile(scenario, confl);
scenario.check(result, confl);
}
protected R methodNotToCompile(Scenario<T, R> scenario, T t) {
return scenario.run(t);
}
}
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package hierarchies;
public class DefaultMethodInterface {
private DefaultMethodInterface() {
}
public static class Hierarchy
extends TypeHierarchy<DefaultMethodInterface.A, DefaultMethodInterface.B> {
public Hierarchy() {
super(new DefaultMethodInterface.A(), new DefaultMethodInterface.B(),
DefaultMethodInterface.A.class, DefaultMethodInterface.B.class);
}
}
public static interface I2 extends TypeHierarchy.I {
default int m() {
return TypeHierarchy.ANSWER;
}
}
public static class A implements I2 {
// use default method from I2
}
public static class B extends A {
@Override
public int m() {
return TypeHierarchy.YEAR;
}
}
}
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package hierarchies;
public class DefaultMethodInterface2 {
private DefaultMethodInterface2() {
}
public static class Hierarchy
extends TypeHierarchy<TypeHierarchy.A, DefaultMethodInterface2.B> {
public Hierarchy() {
super(new TypeHierarchy.A(), new DefaultMethodInterface2.B(),
TypeHierarchy.A.class, DefaultMethodInterface2.B.class);
}
}
public static interface I2 extends TypeHierarchy.I {
default int m() {
return TypeHierarchy.ANSWER;
}
}
public static class B implements I2 {
// default method I2.m()
}
}
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package hierarchies;
public class Linear {
private Linear() {
}
public static class Hierarchy extends TypeHierarchy<TypeHierarchy.A, Linear.B> {
public Hierarchy() {
super(new TypeHierarchy.A(), new Linear.B(),
TypeHierarchy.A.class, Linear.B.class);
}
}
public static class B extends TypeHierarchy.A {
@Override
public int m() {
return TypeHierarchy.YEAR;
}
}
}
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package hierarchies;
public class Linear2 {
private Linear2() {
}
public static class Hierarchy extends TypeHierarchy<TypeHierarchy.A, Linear2.B> {
public Hierarchy() {
super(new A(), new Linear2.B(),
A.class, Linear2.B.class);
}
}
public static interface I2 {
int m();
}
public static class B extends TypeHierarchy.A implements Linear2.I2 {
@Override
public int m() {
return TypeHierarchy.YEAR;
}
}
}
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package hierarchies;
public class NullableType<M extends TypeHierarchy.I, N extends TypeHierarchy.I>
extends TypeHierarchy<M, N> {
public NullableType(TypeHierarchy<M, N> delegate) {
super(delegate.getM(), null,
delegate.getClassM(), delegate.getClassN());
}
}
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package hierarchies;
public class OneRank {
private OneRank() {
}
public static class Hierarchy extends TypeHierarchy<TypeHierarchy.A, OneRank.B> {
public Hierarchy() {
super(new TypeHierarchy.A(), new OneRank.B(),
TypeHierarchy.A.class, OneRank.B.class);
}
}
public static class B implements TypeHierarchy.I {
@Override
public int m() {
return TypeHierarchy.YEAR;
}
}
}
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package hierarchies;
/**
* Type hierarchy contains classes the type profiling and speculation are tested with
*/
public abstract class TypeHierarchy<M extends TypeHierarchy.I, N extends TypeHierarchy.I> {
// Magic numbers
public static final int ANSWER = 42;
public static final int TEMP = 451;
public static final int YEAR = 1984;
private final M m;
private final N n;
private final Class<M> classM;
private final Class<N> classN;
protected TypeHierarchy(M m, N n, Class<M> classM, Class<N> classN) {
this.m = m;
this.n = n;
this.classM = classM;
this.classN = classN;
}
public final M getM() {
return m;
}
public final N getN() {
return n;
}
public final Class<M> getClassM() {
return classM;
}
public final Class<N> getClassN() {
return classN;
}
public interface I {
int m();
}
public static class A implements I {
@Override
public int m() {
return TypeHierarchy.ANSWER;
}
}
}
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package scenarios;
import hierarchies.TypeHierarchy;
import java.util.Arrays;
/**
* Tests System.arraycopy()
*/
public class ArrayCopy extends ArrayScenario {
public ArrayCopy(ProfilingType profilingType,
TypeHierarchy<? extends TypeHierarchy.I, ? extends TypeHierarchy.I> hierarchy) {
super("ArrayCopy", profilingType, hierarchy);
}
/**
* @param obj is used to fill arrays
* @return the same obj
*/
@Override
public TypeHierarchy.I run(TypeHierarchy.I obj) {
switch (profilingType) {
case RETURN:
TypeHierarchy.I t = collectReturnType(obj);
Arrays.fill(array, t);
System.arraycopy(array, 0, matrix[0], 0, array.length);
return array[0];
case ARGUMENTS:
field = obj;
Arrays.fill(array, field);
System.arraycopy(array, 0, matrix[0], 0, array.length);
return array[0];
case PARAMETERS:
Arrays.fill(array, obj);
System.arraycopy(array, 0, matrix[0], 0, array.length);
return array[0];
}
throw new RuntimeException("Should not reach here");
}
}
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package scenarios;
import hierarchies.TypeHierarchy;
import java.util.Arrays;
/**
* Tests aastore bytecode
*/
public class ArrayReferenceStore extends ArrayScenario {
public ArrayReferenceStore(ProfilingType profilingType,
TypeHierarchy<? extends TypeHierarchy.I, ? extends TypeHierarchy.I> hierarchy) {
super("ArrayReferenceStore", profilingType, hierarchy);
}
/**
* @param obj is used to fill arrays
* @return obj
*/
@Override
public TypeHierarchy.I run(TypeHierarchy.I obj) {
switch (profilingType) {
case RETURN:
TypeHierarchy.I t = collectReturnType(obj);
Arrays.fill(array, t);
matrix[0] = array;
return matrix[0][0];
case ARGUMENTS:
field = obj;
Arrays.fill(array, field);
matrix[0] = array;
return matrix[0][0];
case PARAMETERS:
Arrays.fill(array, obj);
matrix[0] = array;
return matrix[0][0];
}
throw new RuntimeException("Should not reach here");
}
}
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package scenarios;
import com.oracle.java.testlibrary.Asserts;
import hierarchies.TypeHierarchy;
import java.lang.reflect.Array;
import java.util.Arrays;
/**
* Base class for array scenarios
*/
public abstract class ArrayScenario extends Scenario<TypeHierarchy.I, TypeHierarchy.I> {
protected final TypeHierarchy.I[] array;
protected final TypeHierarchy.I[][] matrix;
protected ArrayScenario(String name, ProfilingType profilingType,
TypeHierarchy<? extends TypeHierarchy.I, ? extends TypeHierarchy.I> hierarchy) {
super(name, profilingType, hierarchy);
final int x = 20;
final int y = 10;
TypeHierarchy.I prof = hierarchy.getM();
TypeHierarchy.I confl = hierarchy.getN();
this.array = (TypeHierarchy.I[]) Array.newInstance(hierarchy.getClassM(), y);
Arrays.fill(array, prof);
this.matrix = (TypeHierarchy.I[][]) Array.newInstance(hierarchy.getClassM(), x, y);
for (int i = 0; i < x; i++) {
this.matrix[i] = this.array;
}
Asserts.assertEquals(array.length, matrix[0].length, "Invariant");
}
@Override
public boolean isApplicable() {
return hierarchy.getClassM().isAssignableFrom(hierarchy.getClassN());
}
@Override
public void check(TypeHierarchy.I res, TypeHierarchy.I orig) {
Asserts.assertEquals(res, orig, "Check failed");
}
}
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package scenarios;
import com.oracle.java.testlibrary.Asserts;
import hierarchies.TypeHierarchy;
import java.util.Objects;
/**
* Checkcast scenario
* @param <T> profiling parameter
*/
public class CheckCast<T extends TypeHierarchy.I> extends Scenario<T, Integer> {
public CheckCast(ProfilingType profilingType, TypeHierarchy<? extends T, ? extends T> hierarchy) {
super("CheckCast", profilingType, hierarchy);
}
/**
* Returns type profiling.
* @param obj is a profiled parameter for the test
* @return parameter casted to the type R
*/
@Override
public Integer run(T obj) {
switch (profilingType) {
case RETURN:
T t = collectReturnType(obj);
if (t != null) {
return t.m();
}
return null;
case ARGUMENTS:
field = obj;
if (field != null) {
return field.m();
}
return null;
case PARAMETERS:
if (obj != null) {
return obj.m();
}
return null;
}
throw new RuntimeException("Should not reach here");
}
@Override
public void check(Integer result, T orig) {
if (result != null || orig != null) {
Objects.requireNonNull(result);
Objects.requireNonNull(orig);
Asserts.assertEquals(result, orig.m(), "Results mismatch");
}
}
}
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package scenarios;
import com.oracle.java.testlibrary.Asserts;
import hierarchies.TypeHierarchy;
/**
* Tests pattern: if (a.getClass() == D.class)
*/
public class ClassIdentity<T extends TypeHierarchy.I> extends Scenario<T, Integer> {
public ClassIdentity(ProfilingType profilingType,
TypeHierarchy<? extends T, ? extends T> hierarchy) {
super("ClassIdentity", profilingType, hierarchy);
}
@Override
public boolean isApplicable() {
return hierarchy.getM() != null && hierarchy.getN() != null;
}
@Override
public Integer run(T obj) {
switch (profilingType) {
case RETURN:
T t = collectReturnType(obj);
if (t.getClass() == TypeHierarchy.A.class) {
return inlinee(t);
}
return TypeHierarchy.TEMP;
case ARGUMENTS:
field = obj;
if (field.getClass() == TypeHierarchy.A.class) {
return inlinee(field);
}
return TypeHierarchy.TEMP;
case PARAMETERS:
if (obj.getClass() == TypeHierarchy.A.class) {
return inlinee(obj);
}
return TypeHierarchy.TEMP;
}
throw new RuntimeException("Should not reach here");
}
public int inlinee(T obj) {
return obj.m();
}
@Override
public void check(Integer result, T orig) {
if (orig.getClass() == TypeHierarchy.A.class) {
Asserts.assertEquals(result, orig.m(),
"Results are not equal for TypeHierarchy.A.class");
} else {
Asserts.assertEquals(result, TypeHierarchy.TEMP, "Result differs from expected");
}
}
}
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package scenarios;
import com.oracle.java.testlibrary.Asserts;
import hierarchies.TypeHierarchy;
/**
* Tests instanceof
*/
public class ClassInstanceOf<T extends TypeHierarchy.I> extends Scenario<T, Integer> {
public ClassInstanceOf(ProfilingType profilingType,
TypeHierarchy<? extends T, ? extends T> hierarchy) {
super("ClassInstanceOf", profilingType, hierarchy);
}
@Override
public Integer run(T obj) {
switch (profilingType) {
case RETURN:
T t = collectReturnType(obj);
if (t instanceof TypeHierarchy.A) {
return inlinee(t);
}
return TypeHierarchy.TEMP;
case ARGUMENTS:
field = obj;
if (field instanceof TypeHierarchy.A) {
return inlinee(field);
}
return TypeHierarchy.TEMP;
case PARAMETERS:
if (obj instanceof TypeHierarchy.A) {
return inlinee(obj);
}
return TypeHierarchy.TEMP;
}
throw new RuntimeException("Should not reach here");
}
public int inlinee(T obj) {
return obj.m();
}
@Override
public void check(Integer result, T orig) {
if (orig instanceof TypeHierarchy.A) {
Asserts.assertEquals(result, orig.m(), "Results are not equal for TypeHierarchy.A");
} else {
Asserts.assertEquals(result, TypeHierarchy.TEMP, "Result differs from expected");
}
}
}
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package scenarios;
import com.oracle.java.testlibrary.Asserts;
import hierarchies.TypeHierarchy;
/**
* Tests {@link Class#isInstance(Object)}
*/
public class ClassIsInstance<T extends TypeHierarchy.I> extends Scenario<T, Integer> {
private final Class<?> baseClass;
public ClassIsInstance(ProfilingType profilingType,
TypeHierarchy<? extends T, ? extends T> hierarchy) {
super("ClassIsInstance", profilingType, hierarchy);
this.baseClass = hierarchy.getClassM();
}
@Override
public Integer run(T obj) {
switch (profilingType) {
case RETURN:
T t = collectReturnType(obj);
if (baseClass.isInstance(t)) {
return inlinee(t);
}
return TypeHierarchy.TEMP;
case ARGUMENTS:
field = obj;
if (baseClass.isInstance(field)) {
return inlinee(field);
}
return TypeHierarchy.TEMP;
case PARAMETERS:
if (baseClass.isInstance(obj)) {
return inlinee(obj);
}
return TypeHierarchy.TEMP;
}
throw new RuntimeException("Should not reach here");
}
public int inlinee(T obj) {
return obj.m();
}
@Override
public void check(Integer result, T orig) {
if (baseClass.isInstance(orig)) {
Asserts.assertEquals(result, orig.m(), "Results are not equal for base class");
} else {
Asserts.assertEquals(result, TypeHierarchy.TEMP, "Result differs from expected");
}
}
}
/*
* 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,
}
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package scenarios;
import com.oracle.java.testlibrary.Asserts;
import hierarchies.TypeHierarchy;
/**
* Receiver at invokes profiling and speculation
*
* @param <T> parameter to be returned
*/
public class ReceiverAtInvokes<T extends TypeHierarchy.I> extends Scenario<T, Integer> {
public ReceiverAtInvokes(ProfilingType profilingType,
TypeHierarchy<? extends T, ? extends T> hierarchy) {
super("ReceiverAtInvokes", profilingType, hierarchy);
}
@Override
public boolean isApplicable() {
return hierarchy.getM() != null && hierarchy.getN() != null;
}
/**
* Receiver profiling
*
* @param obj is a profiled parameter for the test
* @return parameter casted to the type R
*/
@Override
public Integer run(T obj) {
switch (profilingType) {
case RETURN:
T t = collectReturnType(obj);
return inlinee(t);
case ARGUMENTS:
field = obj;
return inlinee(field);
case PARAMETERS:
return inlinee(obj);
}
throw new RuntimeException("Should not reach here");
}
private Integer inlinee(T obj) {
return obj.m(); // should be inlined
}
@Override
public void check(Integer result, T orig) {
Asserts.assertEquals(result, orig.m(), "Results mismatch");
}
}
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package scenarios;
import hierarchies.TypeHierarchy;
/**
* Test scenario
*
* @param <T> parameter type
* @param <R> result type
*/
public abstract class Scenario<T extends TypeHierarchy.I, R> {
private final String name;
public final ProfilingType profilingType;
public final TypeHierarchy <? extends T, ? extends T> hierarchy;
protected volatile T field;
/**
* Constructor
*
* @param name scenario name
* @param profilingType tested profiling type
* @param hierarchy type hierarchy
*/
protected Scenario(String name, ProfilingType profilingType,
TypeHierarchy<? extends T, ? extends T> hierarchy) {
this.profilingType = profilingType;
this.name = name + " # " + profilingType.name();
this.hierarchy = hierarchy;
}
/**
* Returns the object which should be used as a parameter
* for the methods used for profile data
*
* @return profiled type object
*/
public T getProfiled() {
return hierarchy.getM();
}
/**
* Returns the object which makes a conflict for a profiled data
* when passed instead of {@linkplain Scenario#getProfiled}
*
* @return incompatible to profiled object
*/
public T getConflict() {
return hierarchy.getN();
}
/**
* @return scenario name
*/
public String getName() {
return name;
}
/** Is this scenario applicable for a hierarchy it was constructed with */
public boolean isApplicable() {
return true;
}
/**
* Runs test scenario
*
* @param t subject of the test
* @return result of the test invocation
*/
public abstract R run(T t);
/** Used for a return type profiling */
protected final T collectReturnType(T t) {
return t;
}
/**
* Checks the result for R and T
*
* @param r result
* @param t original
* @throws java.lang.RuntimeException on result mismatch
*/
public abstract void check(R r, T t);
}
/*
* 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, "<init>", "()V", null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()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());
}
}
}
......@@ -142,11 +142,23 @@ public final class ProcessTools {
* 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<String> 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 @@ public final class ProcessTools {
}
return cmd.toString().trim();
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册