Merge
This commit is contained in:
commit
96627b1708
@ -12179,21 +12179,21 @@ instruct rolL_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlag
|
||||
%}
|
||||
%}
|
||||
|
||||
instruct rolI_rReg_Var_C_32(iRegLNoSp dst, iRegL src, iRegI shift, immI_32 c_32, rFlagsReg cr)
|
||||
instruct rolI_rReg_Var_C_32(iRegINoSp dst, iRegI src, iRegI shift, immI_32 c_32, rFlagsReg cr)
|
||||
%{
|
||||
match(Set dst (OrI (LShiftI src shift) (URShiftI src (SubI c_32 shift))));
|
||||
|
||||
expand %{
|
||||
rolL_rReg(dst, src, shift, cr);
|
||||
rolI_rReg(dst, src, shift, cr);
|
||||
%}
|
||||
%}
|
||||
|
||||
instruct rolI_rReg_Var_C0(iRegLNoSp dst, iRegL src, iRegI shift, immI0 c0, rFlagsReg cr)
|
||||
instruct rolI_rReg_Var_C0(iRegINoSp dst, iRegI src, iRegI shift, immI0 c0, rFlagsReg cr)
|
||||
%{
|
||||
match(Set dst (OrI (LShiftI src shift) (URShiftI src (SubI c0 shift))));
|
||||
|
||||
expand %{
|
||||
rolL_rReg(dst, src, shift, cr);
|
||||
rolI_rReg(dst, src, shift, cr);
|
||||
%}
|
||||
%}
|
||||
|
||||
|
@ -944,8 +944,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
|
||||
Register t = r5;
|
||||
__ load_klass(t, r0);
|
||||
__ ldrw(t, Address(t, Klass::access_flags_offset()));
|
||||
__ tst(t, JVM_ACC_HAS_FINALIZER);
|
||||
__ br(Assembler::NE, register_finalizer);
|
||||
__ tbnz(t, exact_log2(JVM_ACC_HAS_FINALIZER), register_finalizer);
|
||||
__ ret(lr);
|
||||
|
||||
__ bind(register_finalizer);
|
||||
|
@ -93,10 +93,8 @@ void InterpreterMacroAssembler::check_and_handle_popframe(Register java_thread)
|
||||
// This method is only called just after the call into the vm in
|
||||
// call_VM_base, so the arg registers are available.
|
||||
ldrw(rscratch1, Address(rthread, JavaThread::popframe_condition_offset()));
|
||||
tstw(rscratch1, JavaThread::popframe_pending_bit);
|
||||
br(Assembler::EQ, L);
|
||||
tstw(rscratch1, JavaThread::popframe_processing_bit);
|
||||
br(Assembler::NE, L);
|
||||
tbz(rscratch1, exact_log2(JavaThread::popframe_pending_bit), L);
|
||||
tbnz(rscratch1, exact_log2(JavaThread::popframe_processing_bit), L);
|
||||
// Call Interpreter::remove_activation_preserving_args_entry() to get the
|
||||
// address of the same-named entrypoint in the generated interpreter code.
|
||||
call_VM_leaf(CAST_FROM_FN_PTR(address, Interpreter::remove_activation_preserving_args_entry));
|
||||
@ -505,8 +503,7 @@ void InterpreterMacroAssembler::remove_activation(
|
||||
// get method access flags
|
||||
ldr(r1, Address(rfp, frame::interpreter_frame_method_offset * wordSize));
|
||||
ldr(r2, Address(r1, Method::access_flags_offset()));
|
||||
tst(r2, JVM_ACC_SYNCHRONIZED);
|
||||
br(Assembler::EQ, unlocked);
|
||||
tbz(r2, exact_log2(JVM_ACC_SYNCHRONIZED), unlocked);
|
||||
|
||||
// Don't unlock anything if the _do_not_unlock_if_synchronized flag
|
||||
// is set.
|
||||
@ -1582,8 +1579,8 @@ void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& md
|
||||
// do. The unknown bit may have been
|
||||
// set already but no need to check.
|
||||
|
||||
tst(obj, TypeEntries::type_unknown);
|
||||
br(Assembler::NE, next); // already unknown. Nothing to do anymore.
|
||||
tbnz(obj, exact_log2(TypeEntries::type_unknown), next);
|
||||
// already unknown. Nothing to do anymore.
|
||||
|
||||
ldr(rscratch1, mdo_addr);
|
||||
cbz(rscratch1, none);
|
||||
|
@ -710,7 +710,7 @@ class StubGenerator: public StubCodeGenerator {
|
||||
__ BIND(L_loop);
|
||||
__ strb(zr, Address(start, count));
|
||||
__ subs(count, count, 1);
|
||||
__ br(Assembler::HS, L_loop);
|
||||
__ br(Assembler::GE, L_loop);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -1299,7 +1299,7 @@ class StubGenerator: public StubCodeGenerator {
|
||||
if (VerifyOops)
|
||||
verify_oop_array(size, d, count, r16);
|
||||
__ sub(count, count, 1); // make an inclusive end pointer
|
||||
__ lea(count, Address(d, count, Address::uxtw(exact_log2(size))));
|
||||
__ lea(count, Address(d, count, Address::lsl(exact_log2(size))));
|
||||
gen_write_ref_array_post_barrier(d, count, rscratch1);
|
||||
}
|
||||
__ leave();
|
||||
@ -2002,9 +2002,9 @@ class StubGenerator: public StubCodeGenerator {
|
||||
arraycopy_range_checks(src, src_pos, dst, dst_pos, scratch_length,
|
||||
rscratch2, L_failed);
|
||||
|
||||
__ lea(from, Address(src, src_pos, Address::lsl(3)));
|
||||
__ lea(from, Address(src, src_pos, Address::lsl(LogBytesPerHeapOop)));
|
||||
__ add(from, from, arrayOopDesc::base_offset_in_bytes(T_OBJECT));
|
||||
__ lea(to, Address(dst, dst_pos, Address::lsl(3)));
|
||||
__ lea(to, Address(dst, dst_pos, Address::lsl(LogBytesPerHeapOop)));
|
||||
__ add(to, to, arrayOopDesc::base_offset_in_bytes(T_OBJECT));
|
||||
__ movw(count, scratch_length); // length
|
||||
__ BIND(L_plain_copy);
|
||||
@ -2027,9 +2027,9 @@ class StubGenerator: public StubCodeGenerator {
|
||||
__ load_klass(rscratch2_dst_klass, dst); // reload
|
||||
|
||||
// Marshal the base address arguments now, freeing registers.
|
||||
__ lea(from, Address(src, src_pos, Address::lsl(3)));
|
||||
__ lea(from, Address(src, src_pos, Address::lsl(LogBytesPerHeapOop)));
|
||||
__ add(from, from, arrayOopDesc::base_offset_in_bytes(T_OBJECT));
|
||||
__ lea(to, Address(dst, dst_pos, Address::lsl(3)));
|
||||
__ lea(to, Address(dst, dst_pos, Address::lsl(LogBytesPerHeapOop)));
|
||||
__ add(to, to, arrayOopDesc::base_offset_in_bytes(T_OBJECT));
|
||||
__ movw(count, length); // length (reloaded)
|
||||
Register sco_temp = c_rarg3; // this register is free now
|
||||
|
@ -1242,8 +1242,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
|
||||
{
|
||||
Label L;
|
||||
__ ldrw(t, Address(rmethod, Method::access_flags_offset()));
|
||||
__ tst(t, JVM_ACC_STATIC);
|
||||
__ br(Assembler::EQ, L);
|
||||
__ tbz(t, exact_log2(JVM_ACC_STATIC), L);
|
||||
// get mirror
|
||||
__ load_mirror(t, rmethod);
|
||||
// copy mirror into activation frame
|
||||
@ -1435,8 +1434,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
|
||||
{
|
||||
Label L;
|
||||
__ ldrw(t, Address(rmethod, Method::access_flags_offset()));
|
||||
__ tst(t, JVM_ACC_SYNCHRONIZED);
|
||||
__ br(Assembler::EQ, L);
|
||||
__ tbz(t, exact_log2(JVM_ACC_SYNCHRONIZED), L);
|
||||
// the code below should be shared with interpreter macro
|
||||
// assembler implementation
|
||||
{
|
||||
|
@ -2190,9 +2190,8 @@ void TemplateTable::_return(TosState state)
|
||||
__ ldr(c_rarg1, aaddress(0));
|
||||
__ load_klass(r3, c_rarg1);
|
||||
__ ldrw(r3, Address(r3, Klass::access_flags_offset()));
|
||||
__ tst(r3, JVM_ACC_HAS_FINALIZER);
|
||||
Label skip_register_finalizer;
|
||||
__ br(Assembler::EQ, skip_register_finalizer);
|
||||
__ tbz(r3, exact_log2(JVM_ACC_HAS_FINALIZER), skip_register_finalizer);
|
||||
|
||||
__ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::register_finalizer), c_rarg1);
|
||||
|
||||
|
@ -503,6 +503,10 @@ class Assembler : public AbstractAssembler {
|
||||
LVSL_OPCODE = (31u << OPCODE_SHIFT | 6u << 1),
|
||||
LVSR_OPCODE = (31u << OPCODE_SHIFT | 38u << 1),
|
||||
|
||||
// Vector-Scalar (VSX) instruction support.
|
||||
LXVD2X_OPCODE = (31u << OPCODE_SHIFT | 844u << 1),
|
||||
STXVD2X_OPCODE = (31u << OPCODE_SHIFT | 972u << 1),
|
||||
|
||||
// Vector Permute and Formatting
|
||||
VPKPX_OPCODE = (4u << OPCODE_SHIFT | 782u ),
|
||||
VPKSHSS_OPCODE = (4u << OPCODE_SHIFT | 398u ),
|
||||
@ -1085,6 +1089,19 @@ class Assembler : public AbstractAssembler {
|
||||
static int vrs( VectorRegister r) { return vrs(r->encoding());}
|
||||
static int vrt( VectorRegister r) { return vrt(r->encoding());}
|
||||
|
||||
// Support Vector-Scalar (VSX) instructions.
|
||||
static int vsra( int x) { return opp_u_field(x, 15, 11); }
|
||||
static int vsrb( int x) { return opp_u_field(x, 20, 16); }
|
||||
static int vsrc( int x) { return opp_u_field(x, 25, 21); }
|
||||
static int vsrs( int x) { return opp_u_field(x, 10, 6); }
|
||||
static int vsrt( int x) { return opp_u_field(x, 10, 6); }
|
||||
|
||||
static int vsra( VectorSRegister r) { return vsra(r->encoding());}
|
||||
static int vsrb( VectorSRegister r) { return vsrb(r->encoding());}
|
||||
static int vsrc( VectorSRegister r) { return vsrc(r->encoding());}
|
||||
static int vsrs( VectorSRegister r) { return vsrs(r->encoding());}
|
||||
static int vsrt( VectorSRegister r) { return vsrt(r->encoding());}
|
||||
|
||||
static int vsplt_uim( int x) { return opp_u_field(x, 15, 12); } // for vsplt* instructions
|
||||
static int vsplti_sim(int x) { return opp_u_field(x, 15, 11); } // for vsplti* instructions
|
||||
static int vsldoi_shb(int x) { return opp_u_field(x, 25, 22); } // for vsldoi instruction
|
||||
@ -2069,6 +2086,10 @@ class Assembler : public AbstractAssembler {
|
||||
inline void mtvscr( VectorRegister b);
|
||||
inline void mfvscr( VectorRegister d);
|
||||
|
||||
// Vector-Scalar (VSX) instructions.
|
||||
inline void lxvd2x( VectorSRegister d, Register a, Register b);
|
||||
inline void stxvd2x( VectorSRegister d, Register a, Register b);
|
||||
|
||||
// AES (introduced with Power 8)
|
||||
inline void vcipher( VectorRegister d, VectorRegister a, VectorRegister b);
|
||||
inline void vcipherlast( VectorRegister d, VectorRegister a, VectorRegister b);
|
||||
|
@ -724,6 +724,10 @@ inline void Assembler::stvxl( VectorRegister d, Register s1, Register s2) { emit
|
||||
inline void Assembler::lvsl( VectorRegister d, Register s1, Register s2) { emit_int32( LVSL_OPCODE | vrt(d) | ra0mem(s1) | rb(s2)); }
|
||||
inline void Assembler::lvsr( VectorRegister d, Register s1, Register s2) { emit_int32( LVSR_OPCODE | vrt(d) | ra0mem(s1) | rb(s2)); }
|
||||
|
||||
// Vector-Scalar (VSX) instructions.
|
||||
inline void Assembler::lxvd2x (VectorSRegister d, Register s1, Register s2) { emit_int32( LXVD2X_OPCODE | vsrt(d) | ra(s1) | rb(s2)); }
|
||||
inline void Assembler::stxvd2x(VectorSRegister d, Register s1, Register s2) { emit_int32( STXVD2X_OPCODE | vsrt(d) | ra(s1) | rb(s2)); }
|
||||
|
||||
inline void Assembler::vpkpx( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VPKPX_OPCODE | vrt(d) | vra(a) | vrb(b)); }
|
||||
inline void Assembler::vpkshss( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VPKSHSS_OPCODE | vrt(d) | vra(a) | vrb(b)); }
|
||||
inline void Assembler::vpkswss( VectorRegister d, VectorRegister a, VectorRegister b) { emit_int32( VPKSWSS_OPCODE | vrt(d) | vra(a) | vrb(b)); }
|
||||
|
@ -75,3 +75,14 @@ const char* VectorRegisterImpl::name() const {
|
||||
};
|
||||
return is_valid() ? names[encoding()] : "vnoreg";
|
||||
}
|
||||
|
||||
const char* VectorSRegisterImpl::name() const {
|
||||
const char* names[number_of_registers] = {
|
||||
"VSR0", "VSR1", "VSR2", "VSR3", "VSR4", "VSR5", "VSR6", "VSR7",
|
||||
"VSR8", "VSR9", "VSR10", "VSR11", "VSR12", "VSR13", "VSR14", "VSR15",
|
||||
"VSR16", "VSR17", "VSR18", "VSR19", "VSR20", "VSR21", "VSR22", "VSR23",
|
||||
"VSR24", "VSR25", "VSR26", "VSR27", "VSR28", "VSR29", "VSR30", "VSR31"
|
||||
};
|
||||
return is_valid() ? names[encoding()] : "vsnoreg";
|
||||
}
|
||||
|
||||
|
@ -491,6 +491,106 @@ CONSTANT_REGISTER_DECLARATION(VectorRegister, VR31, (31));
|
||||
#endif // DONT_USE_REGISTER_DEFINES
|
||||
|
||||
|
||||
// Use VectorSRegister as a shortcut.
|
||||
class VectorSRegisterImpl;
|
||||
typedef VectorSRegisterImpl* VectorSRegister;
|
||||
|
||||
inline VectorSRegister as_VectorSRegister(int encoding) {
|
||||
return (VectorSRegister)(intptr_t)encoding;
|
||||
}
|
||||
|
||||
// The implementation of Vector-Scalar (VSX) registers on POWER architecture.
|
||||
class VectorSRegisterImpl: public AbstractRegisterImpl {
|
||||
public:
|
||||
enum {
|
||||
number_of_registers = 32
|
||||
};
|
||||
|
||||
// construction
|
||||
inline friend VectorSRegister as_VectorSRegister(int encoding);
|
||||
|
||||
// accessors
|
||||
int encoding() const { assert(is_valid(), "invalid register"); return value(); }
|
||||
|
||||
// testers
|
||||
bool is_valid() const { return 0 <= value() && value() < number_of_registers; }
|
||||
|
||||
const char* name() const;
|
||||
};
|
||||
|
||||
// The Vector-Scalar (VSX) registers of the POWER architecture.
|
||||
|
||||
CONSTANT_REGISTER_DECLARATION(VectorSRegister, vsnoreg, (-1));
|
||||
|
||||
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR0, ( 0));
|
||||
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR1, ( 1));
|
||||
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR2, ( 2));
|
||||
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR3, ( 3));
|
||||
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR4, ( 4));
|
||||
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR5, ( 5));
|
||||
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR6, ( 6));
|
||||
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR7, ( 7));
|
||||
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR8, ( 8));
|
||||
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR9, ( 9));
|
||||
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR10, (10));
|
||||
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR11, (11));
|
||||
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR12, (12));
|
||||
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR13, (13));
|
||||
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR14, (14));
|
||||
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR15, (15));
|
||||
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR16, (16));
|
||||
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR17, (17));
|
||||
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR18, (18));
|
||||
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR19, (19));
|
||||
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR20, (20));
|
||||
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR21, (21));
|
||||
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR22, (22));
|
||||
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR23, (23));
|
||||
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR24, (24));
|
||||
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR25, (25));
|
||||
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR26, (26));
|
||||
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR27, (27));
|
||||
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR28, (28));
|
||||
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR29, (29));
|
||||
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR30, (30));
|
||||
CONSTANT_REGISTER_DECLARATION(VectorSRegister, VSR31, (31));
|
||||
|
||||
#ifndef DONT_USE_REGISTER_DEFINES
|
||||
#define vsnoregi ((VectorSRegister)(vsnoreg_VectorSRegisterEnumValue))
|
||||
#define VSR0 ((VectorSRegister)( VSR0_VectorSRegisterEnumValue))
|
||||
#define VSR1 ((VectorSRegister)( VSR1_VectorSRegisterEnumValue))
|
||||
#define VSR2 ((VectorSRegister)( VSR2_VectorSRegisterEnumValue))
|
||||
#define VSR3 ((VectorSRegister)( VSR3_VectorSRegisterEnumValue))
|
||||
#define VSR4 ((VectorSRegister)( VSR4_VectorSRegisterEnumValue))
|
||||
#define VSR5 ((VectorSRegister)( VSR5_VectorSRegisterEnumValue))
|
||||
#define VSR6 ((VectorSRegister)( VSR6_VectorSRegisterEnumValue))
|
||||
#define VSR7 ((VectorSRegister)( VSR7_VectorSRegisterEnumValue))
|
||||
#define VSR8 ((VectorSRegister)( VSR8_VectorSRegisterEnumValue))
|
||||
#define VSR9 ((VectorSRegister)( VSR9_VectorSRegisterEnumValue))
|
||||
#define VSR10 ((VectorSRegister)( VSR10_VectorSRegisterEnumValue))
|
||||
#define VSR11 ((VectorSRegister)( VSR11_VectorSRegisterEnumValue))
|
||||
#define VSR12 ((VectorSRegister)( VSR12_VectorSRegisterEnumValue))
|
||||
#define VSR13 ((VectorSRegister)( VSR13_VectorSRegisterEnumValue))
|
||||
#define VSR14 ((VectorSRegister)( VSR14_VectorSRegisterEnumValue))
|
||||
#define VSR15 ((VectorSRegister)( VSR15_VectorSRegisterEnumValue))
|
||||
#define VSR16 ((VectorSRegister)( VSR16_VectorSRegisterEnumValue))
|
||||
#define VSR17 ((VectorSRegister)( VSR17_VectorSRegisterEnumValue))
|
||||
#define VSR18 ((VectorSRegister)( VSR18_VectorSRegisterEnumValue))
|
||||
#define VSR19 ((VectorSRegister)( VSR19_VectorSRegisterEnumValue))
|
||||
#define VSR20 ((VectorSRegister)( VSR20_VectorSRegisterEnumValue))
|
||||
#define VSR21 ((VectorSRegister)( VSR21_VectorSRegisterEnumValue))
|
||||
#define VSR22 ((VectorSRegister)( VSR22_VectorSRegisterEnumValue))
|
||||
#define VSR23 ((VectorSRegister)( VSR23_VectorSRegisterEnumValue))
|
||||
#define VSR24 ((VectorSRegister)( VSR24_VectorSRegisterEnumValue))
|
||||
#define VSR25 ((VectorSRegister)( VSR25_VectorSRegisterEnumValue))
|
||||
#define VSR26 ((VectorSRegister)( VSR26_VectorSRegisterEnumValue))
|
||||
#define VSR27 ((VectorSRegister)( VSR27_VectorSRegisterEnumValue))
|
||||
#define VSR28 ((VectorSRegister)( VSR28_VectorSRegisterEnumValue))
|
||||
#define VSR29 ((VectorSRegister)( VSR29_VectorSRegisterEnumValue))
|
||||
#define VSR30 ((VectorSRegister)( VSR30_VectorSRegisterEnumValue))
|
||||
#define VSR31 ((VectorSRegister)( VSR31_VectorSRegisterEnumValue))
|
||||
#endif // DONT_USE_REGISTER_DEFINES
|
||||
|
||||
// Maximum number of incoming arguments that can be passed in i registers.
|
||||
const int PPC_ARGS_IN_REGS_NUM = 8;
|
||||
|
||||
|
@ -1341,10 +1341,13 @@ class StubGenerator: public StubCodeGenerator {
|
||||
Register tmp3 = R8_ARG6;
|
||||
Register tmp4 = R9_ARG7;
|
||||
|
||||
VectorSRegister tmp_vsr1 = VSR1;
|
||||
VectorSRegister tmp_vsr2 = VSR2;
|
||||
|
||||
address start = __ function_entry();
|
||||
assert_positive_int(R5_ARG3);
|
||||
|
||||
Label l_1, l_2, l_3, l_4, l_5, l_6, l_7, l_8;
|
||||
Label l_1, l_2, l_3, l_4, l_5, l_6, l_7, l_8, l_9;
|
||||
|
||||
// don't try anything fancy if arrays don't have many elements
|
||||
__ li(tmp3, 0);
|
||||
@ -1403,22 +1406,60 @@ class StubGenerator: public StubCodeGenerator {
|
||||
__ andi_(R5_ARG3, R5_ARG3, 15);
|
||||
__ mtctr(tmp1);
|
||||
|
||||
__ bind(l_8);
|
||||
// Use unrolled version for mass copying (copy 16 elements a time).
|
||||
// Load feeding store gets zero latency on Power6, however not on Power5.
|
||||
// Therefore, the following sequence is made for the good of both.
|
||||
__ ld(tmp1, 0, R3_ARG1);
|
||||
__ ld(tmp2, 8, R3_ARG1);
|
||||
__ ld(tmp3, 16, R3_ARG1);
|
||||
__ ld(tmp4, 24, R3_ARG1);
|
||||
__ std(tmp1, 0, R4_ARG2);
|
||||
__ std(tmp2, 8, R4_ARG2);
|
||||
__ std(tmp3, 16, R4_ARG2);
|
||||
__ std(tmp4, 24, R4_ARG2);
|
||||
__ addi(R3_ARG1, R3_ARG1, 32);
|
||||
__ addi(R4_ARG2, R4_ARG2, 32);
|
||||
__ bdnz(l_8);
|
||||
}
|
||||
if (!VM_Version::has_vsx()) {
|
||||
|
||||
__ bind(l_8);
|
||||
// Use unrolled version for mass copying (copy 16 elements a time).
|
||||
// Load feeding store gets zero latency on Power6, however not on Power5.
|
||||
// Therefore, the following sequence is made for the good of both.
|
||||
__ ld(tmp1, 0, R3_ARG1);
|
||||
__ ld(tmp2, 8, R3_ARG1);
|
||||
__ ld(tmp3, 16, R3_ARG1);
|
||||
__ ld(tmp4, 24, R3_ARG1);
|
||||
__ std(tmp1, 0, R4_ARG2);
|
||||
__ std(tmp2, 8, R4_ARG2);
|
||||
__ std(tmp3, 16, R4_ARG2);
|
||||
__ std(tmp4, 24, R4_ARG2);
|
||||
__ addi(R3_ARG1, R3_ARG1, 32);
|
||||
__ addi(R4_ARG2, R4_ARG2, 32);
|
||||
__ bdnz(l_8);
|
||||
|
||||
} else { // Processor supports VSX, so use it to mass copy.
|
||||
|
||||
// Prefetch src data into L2 cache.
|
||||
__ dcbt(R3_ARG1, 0);
|
||||
|
||||
// If supported set DSCR pre-fetch to deepest.
|
||||
if (VM_Version::has_mfdscr()) {
|
||||
__ load_const_optimized(tmp2, VM_Version::_dscr_val | 7);
|
||||
__ mtdscr(tmp2);
|
||||
}
|
||||
__ li(tmp1, 16);
|
||||
|
||||
// Backbranch target aligned to 32-byte. It's not aligned 16-byte
|
||||
// as loop contains < 8 instructions that fit inside a single
|
||||
// i-cache sector.
|
||||
__ align(32);
|
||||
|
||||
__ bind(l_9);
|
||||
// Use loop with VSX load/store instructions to
|
||||
// copy 16 elements a time.
|
||||
__ lxvd2x(tmp_vsr1, 0, R3_ARG1); // Load from src.
|
||||
__ stxvd2x(tmp_vsr1, 0, R4_ARG2); // Store to dst.
|
||||
__ lxvd2x(tmp_vsr2, R3_ARG1, tmp1); // Load from src + 16.
|
||||
__ stxvd2x(tmp_vsr2, R4_ARG2, tmp1); // Store to dst + 16.
|
||||
__ addi(R3_ARG1, R3_ARG1, 32); // Update src+=32.
|
||||
__ addi(R4_ARG2, R4_ARG2, 32); // Update dsc+=32.
|
||||
__ bdnz(l_9); // Dec CTR and loop if not zero.
|
||||
|
||||
// Restore DSCR pre-fetch value.
|
||||
if (VM_Version::has_mfdscr()) {
|
||||
__ load_const_optimized(tmp2, VM_Version::_dscr_val);
|
||||
__ mtdscr(tmp2);
|
||||
}
|
||||
|
||||
}
|
||||
} // FasterArrayCopy
|
||||
__ bind(l_6);
|
||||
|
||||
// copy 2 elements at a time
|
||||
|
@ -38,7 +38,7 @@
|
||||
# include <sys/sysinfo.h>
|
||||
|
||||
bool VM_Version::_is_determine_features_test_running = false;
|
||||
|
||||
uint64_t VM_Version::_dscr_val = 0;
|
||||
|
||||
#define MSG(flag) \
|
||||
if (flag && !FLAG_IS_DEFAULT(flag)) \
|
||||
@ -111,7 +111,7 @@ void VM_Version::initialize() {
|
||||
// Create and print feature-string.
|
||||
char buf[(num_features+1) * 16]; // Max 16 chars per feature.
|
||||
jio_snprintf(buf, sizeof(buf),
|
||||
"ppc64%s%s%s%s%s%s%s%s%s%s%s%s%s",
|
||||
"ppc64%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
|
||||
(has_fsqrt() ? " fsqrt" : ""),
|
||||
(has_isel() ? " isel" : ""),
|
||||
(has_lxarxeh() ? " lxarxeh" : ""),
|
||||
@ -125,7 +125,8 @@ void VM_Version::initialize() {
|
||||
(has_vcipher() ? " aes" : ""),
|
||||
(has_vpmsumb() ? " vpmsumb" : ""),
|
||||
(has_tcheck() ? " tcheck" : ""),
|
||||
(has_mfdscr() ? " mfdscr" : "")
|
||||
(has_mfdscr() ? " mfdscr" : ""),
|
||||
(has_vsx() ? " vsx" : "")
|
||||
// Make sure number of %s matches num_features!
|
||||
);
|
||||
_features_string = os::strdup(buf);
|
||||
@ -643,6 +644,7 @@ void VM_Version::determine_features() {
|
||||
a->vpmsumb(VR0, VR1, VR2); // code[11] -> vpmsumb
|
||||
a->tcheck(0); // code[12] -> tcheck
|
||||
a->mfdscr(R0); // code[13] -> mfdscr
|
||||
a->lxvd2x(VSR0, 0, R3_ARG1); // code[14] -> vsx
|
||||
a->blr();
|
||||
|
||||
// Emit function to set one cache line to zero. Emit function descriptor and get pointer to it.
|
||||
@ -691,6 +693,7 @@ void VM_Version::determine_features() {
|
||||
if (code[feature_cntr++]) features |= vpmsumb_m;
|
||||
if (code[feature_cntr++]) features |= tcheck_m;
|
||||
if (code[feature_cntr++]) features |= mfdscr_m;
|
||||
if (code[feature_cntr++]) features |= vsx_m;
|
||||
|
||||
// Print the detection code.
|
||||
if (PrintAssembly) {
|
||||
@ -733,31 +736,31 @@ void VM_Version::config_dscr() {
|
||||
}
|
||||
|
||||
// Apply the configuration if needed.
|
||||
uint64_t dscr_val = (*get_dscr)();
|
||||
_dscr_val = (*get_dscr)();
|
||||
if (Verbose) {
|
||||
tty->print_cr("dscr value was 0x%lx" , dscr_val);
|
||||
tty->print_cr("dscr value was 0x%lx" , _dscr_val);
|
||||
}
|
||||
bool change_requested = false;
|
||||
if (DSCR_PPC64 != (uintx)-1) {
|
||||
dscr_val = DSCR_PPC64;
|
||||
_dscr_val = DSCR_PPC64;
|
||||
change_requested = true;
|
||||
}
|
||||
if (DSCR_DPFD_PPC64 <= 7) {
|
||||
uint64_t mask = 0x7;
|
||||
if ((dscr_val & mask) != DSCR_DPFD_PPC64) {
|
||||
dscr_val = (dscr_val & ~mask) | (DSCR_DPFD_PPC64);
|
||||
if ((_dscr_val & mask) != DSCR_DPFD_PPC64) {
|
||||
_dscr_val = (_dscr_val & ~mask) | (DSCR_DPFD_PPC64);
|
||||
change_requested = true;
|
||||
}
|
||||
}
|
||||
if (DSCR_URG_PPC64 <= 7) {
|
||||
uint64_t mask = 0x7 << 6;
|
||||
if ((dscr_val & mask) != DSCR_DPFD_PPC64 << 6) {
|
||||
dscr_val = (dscr_val & ~mask) | (DSCR_URG_PPC64 << 6);
|
||||
if ((_dscr_val & mask) != DSCR_DPFD_PPC64 << 6) {
|
||||
_dscr_val = (_dscr_val & ~mask) | (DSCR_URG_PPC64 << 6);
|
||||
change_requested = true;
|
||||
}
|
||||
}
|
||||
if (change_requested) {
|
||||
(*set_dscr)(dscr_val);
|
||||
(*set_dscr)(_dscr_val);
|
||||
if (Verbose) {
|
||||
tty->print_cr("dscr was set to 0x%lx" , (*get_dscr)());
|
||||
}
|
||||
|
@ -46,6 +46,7 @@ protected:
|
||||
vpmsumb,
|
||||
tcheck,
|
||||
mfdscr,
|
||||
vsx,
|
||||
num_features // last entry to count features
|
||||
};
|
||||
enum Feature_Flag_Set {
|
||||
@ -64,6 +65,7 @@ protected:
|
||||
vpmsumb_m = (1 << vpmsumb),
|
||||
tcheck_m = (1 << tcheck ),
|
||||
mfdscr_m = (1 << mfdscr ),
|
||||
vsx_m = (1 << vsx ),
|
||||
all_features_m = (unsigned long)-1
|
||||
};
|
||||
|
||||
@ -97,10 +99,14 @@ public:
|
||||
static bool has_vpmsumb() { return (_features & vpmsumb_m) != 0; }
|
||||
static bool has_tcheck() { return (_features & tcheck_m) != 0; }
|
||||
static bool has_mfdscr() { return (_features & mfdscr_m) != 0; }
|
||||
static bool has_vsx() { return (_features & vsx_m) != 0; }
|
||||
|
||||
// Assembler testing
|
||||
static void allow_all();
|
||||
static void revert();
|
||||
|
||||
// POWER 8: DSCR current value.
|
||||
static uint64_t _dscr_val;
|
||||
};
|
||||
|
||||
#endif // CPU_PPC_VM_VM_VERSION_PPC_HPP
|
||||
|
@ -7046,7 +7046,6 @@ void MacroAssembler::string_indexofC8(Register str1, Register str2,
|
||||
int ae) {
|
||||
ShortBranchVerifier sbv(this);
|
||||
assert(UseSSE42Intrinsics, "SSE4.2 intrinsics are required");
|
||||
assert(UseSSE >= 4, "SSE4 must be enabled for SSE4.2 intrinsics to be available");
|
||||
assert(ae != StrIntrinsicNode::LU, "Invalid encoding");
|
||||
|
||||
// This method uses the pcmpestri instruction with bound registers
|
||||
@ -7225,7 +7224,6 @@ void MacroAssembler::string_indexof(Register str1, Register str2,
|
||||
int ae) {
|
||||
ShortBranchVerifier sbv(this);
|
||||
assert(UseSSE42Intrinsics, "SSE4.2 intrinsics are required");
|
||||
assert(UseSSE >= 4, "SSE4 must be enabled for SSE4.2 intrinsics to be available");
|
||||
assert(ae != StrIntrinsicNode::LU, "Invalid encoding");
|
||||
|
||||
//
|
||||
@ -7543,7 +7541,6 @@ void MacroAssembler::string_indexof_char(Register str1, Register cnt1, Register
|
||||
XMMRegister vec1, XMMRegister vec2, XMMRegister vec3, Register tmp) {
|
||||
ShortBranchVerifier sbv(this);
|
||||
assert(UseSSE42Intrinsics, "SSE4.2 intrinsics are required");
|
||||
assert(UseSSE >= 4, "SSE4 must be enabled for SSE4.2 intrinsics to be available");
|
||||
|
||||
int stride = 8;
|
||||
|
||||
@ -7723,7 +7720,6 @@ void MacroAssembler::string_compare(Register str1, Register str2,
|
||||
}
|
||||
|
||||
if (UseAVX >= 2 && UseSSE42Intrinsics) {
|
||||
assert(UseSSE >= 4, "SSE4 must be enabled for SSE4.2 intrinsics to be available");
|
||||
Label COMPARE_WIDE_VECTORS, VECTOR_NOT_EQUAL, COMPARE_WIDE_TAIL, COMPARE_SMALL_STR;
|
||||
Label COMPARE_WIDE_VECTORS_LOOP, COMPARE_16_CHARS, COMPARE_INDEX_CHAR;
|
||||
Label COMPARE_WIDE_VECTORS_LOOP_AVX2;
|
||||
@ -7891,7 +7887,6 @@ void MacroAssembler::string_compare(Register str1, Register str2,
|
||||
|
||||
bind(COMPARE_SMALL_STR);
|
||||
} else if (UseSSE42Intrinsics) {
|
||||
assert(UseSSE >= 4, "SSE4 must be enabled for SSE4.2 intrinsics to be available");
|
||||
Label COMPARE_WIDE_VECTORS, VECTOR_NOT_EQUAL, COMPARE_TAIL;
|
||||
int pcmpmask = 0x19;
|
||||
// Setup to compare 8-char (16-byte) vectors,
|
||||
@ -8179,7 +8174,6 @@ void MacroAssembler::has_negatives(Register ary1, Register len,
|
||||
// Fallthru to tail compare
|
||||
}
|
||||
else if (UseSSE42Intrinsics) {
|
||||
assert(UseSSE >= 4, "SSE4 must be for SSE4.2 intrinsics to be available");
|
||||
// With SSE4.2, use double quad vector compare
|
||||
Label COMPARE_WIDE_VECTORS, COMPARE_TAIL;
|
||||
|
||||
@ -8383,7 +8377,6 @@ void MacroAssembler::arrays_equals(bool is_array_equ, Register ary1, Register ar
|
||||
movl(limit, result);
|
||||
// Fallthru to tail compare
|
||||
} else if (UseSSE42Intrinsics) {
|
||||
assert(UseSSE >= 4, "SSE4 must be enabled for SSE4.2 intrinsics to be available");
|
||||
// With SSE4.2, use double quad vector compare
|
||||
Label COMPARE_WIDE_VECTORS, COMPARE_TAIL;
|
||||
|
||||
@ -8747,7 +8740,6 @@ void MacroAssembler::encode_iso_array(Register src, Register dst, Register len,
|
||||
negptr(len);
|
||||
|
||||
if (UseSSE42Intrinsics || UseAVX >= 2) {
|
||||
assert(UseSSE42Intrinsics ? UseSSE >= 4 : true, "SSE4 must be enabled for SSE4.2 intrinsics to be available");
|
||||
Label L_chars_8_check, L_copy_8_chars, L_copy_8_chars_exit;
|
||||
Label L_chars_16_check, L_copy_16_chars, L_copy_16_chars_exit;
|
||||
|
||||
@ -10159,7 +10151,13 @@ void MacroAssembler::kernel_crc32(Register crc, Register buf, Register len, Regi
|
||||
movdqa(xmm1, Address(buf, 0));
|
||||
movdl(rax, xmm1);
|
||||
xorl(crc, rax);
|
||||
pinsrd(xmm1, crc, 0);
|
||||
if (VM_Version::supports_sse4_1()) {
|
||||
pinsrd(xmm1, crc, 0);
|
||||
} else {
|
||||
pinsrw(xmm1, crc, 0);
|
||||
shrl(crc, 16);
|
||||
pinsrw(xmm1, crc, 1);
|
||||
}
|
||||
addptr(buf, 16);
|
||||
subl(len, 4); // len > 0
|
||||
jcc(Assembler::less, L_fold_tail);
|
||||
@ -10881,7 +10879,6 @@ void MacroAssembler::char_array_compress(Register src, Register dst, Register le
|
||||
clear_vector_masking(); // closing of the stub context for programming mask registers
|
||||
}
|
||||
if (UseSSE42Intrinsics) {
|
||||
assert(UseSSE >= 4, "SSE4 must be enabled for SSE4.2 intrinsics to be available");
|
||||
Label copy_32_loop, copy_16, copy_tail;
|
||||
|
||||
bind(below_threshold);
|
||||
@ -11045,7 +11042,6 @@ void MacroAssembler::byte_array_inflate(Register src, Register dst, Register len
|
||||
clear_vector_masking(); // closing of the stub context for programming mask registers
|
||||
}
|
||||
if (UseSSE42Intrinsics) {
|
||||
assert(UseSSE >= 4, "SSE4 must be enabled for SSE4.2 intrinsics to be available");
|
||||
Label copy_16_loop, copy_8_loop, copy_bytes, copy_new_tail, copy_tail;
|
||||
|
||||
movl(tmp2, len);
|
||||
|
@ -658,7 +658,7 @@ void VM_Version::get_processor_features() {
|
||||
FLAG_SET_DEFAULT(UseAESCTRIntrinsics, false);
|
||||
}
|
||||
} else {
|
||||
if(supports_sse4_1() && UseSSE >= 4) {
|
||||
if(supports_sse4_1()) {
|
||||
if (FLAG_IS_DEFAULT(UseAESCTRIntrinsics)) {
|
||||
FLAG_SET_DEFAULT(UseAESCTRIntrinsics, true);
|
||||
}
|
||||
@ -970,7 +970,7 @@ void VM_Version::get_processor_features() {
|
||||
UseXmmI2D = false;
|
||||
}
|
||||
}
|
||||
if (supports_sse4_2() && UseSSE >= 4) {
|
||||
if (supports_sse4_2()) {
|
||||
if (FLAG_IS_DEFAULT(UseSSE42Intrinsics)) {
|
||||
FLAG_SET_DEFAULT(UseSSE42Intrinsics, true);
|
||||
}
|
||||
@ -1050,7 +1050,7 @@ void VM_Version::get_processor_features() {
|
||||
UseUnalignedLoadStores = true; // use movdqu on newest Intel cpus
|
||||
}
|
||||
}
|
||||
if (supports_sse4_2() && UseSSE >= 4) {
|
||||
if (supports_sse4_2()) {
|
||||
if (FLAG_IS_DEFAULT(UseSSE42Intrinsics)) {
|
||||
FLAG_SET_DEFAULT(UseSSE42Intrinsics, true);
|
||||
}
|
||||
|
@ -1718,7 +1718,7 @@ const bool Matcher::match_rule_supported(int opcode) {
|
||||
ret_value = false;
|
||||
break;
|
||||
case Op_StrIndexOfChar:
|
||||
if (!(UseSSE > 4))
|
||||
if (!UseSSE42Intrinsics)
|
||||
ret_value = false;
|
||||
break;
|
||||
case Op_OnSpinWait:
|
||||
|
@ -31,10 +31,13 @@ import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import jdk.internal.misc.VM;
|
||||
@ -213,7 +216,22 @@ public final class HotSpotJVMCIRuntime implements HotSpotJVMCIRuntimeProvider {
|
||||
|
||||
private final Map<Class<? extends Architecture>, JVMCIBackend> backends = new HashMap<>();
|
||||
|
||||
private final Iterable<HotSpotVMEventListener> vmEventListeners;
|
||||
private volatile List<HotSpotVMEventListener> vmEventListeners;
|
||||
|
||||
private Iterable<HotSpotVMEventListener> getVmEventListeners() {
|
||||
if (vmEventListeners == null) {
|
||||
synchronized (this) {
|
||||
if (vmEventListeners == null) {
|
||||
List<HotSpotVMEventListener> listeners = new ArrayList<>();
|
||||
for (HotSpotVMEventListener vmEventListener : ServiceLoader.load(HotSpotVMEventListener.class)) {
|
||||
listeners.add(vmEventListener);
|
||||
}
|
||||
vmEventListeners = listeners;
|
||||
}
|
||||
}
|
||||
}
|
||||
return vmEventListeners;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the result of {@link HotSpotJVMCICompilerFactory#getTrivialPrefixes()} so that it can
|
||||
@ -240,8 +258,6 @@ public final class HotSpotJVMCIRuntime implements HotSpotJVMCIRuntimeProvider {
|
||||
hostBackend = registerBackend(factory.createJVMCIBackend(this, null));
|
||||
}
|
||||
|
||||
vmEventListeners = Services.load(HotSpotVMEventListener.class);
|
||||
|
||||
metaAccessContext = new HotSpotJVMCIMetaAccessContext();
|
||||
|
||||
boolean printFlags = Option.PrintFlags.getBoolean();
|
||||
@ -370,7 +386,7 @@ public final class HotSpotJVMCIRuntime implements HotSpotJVMCIRuntimeProvider {
|
||||
*/
|
||||
@SuppressWarnings({"unused"})
|
||||
private void shutdown() throws Exception {
|
||||
for (HotSpotVMEventListener vmEventListener : vmEventListeners) {
|
||||
for (HotSpotVMEventListener vmEventListener : getVmEventListeners()) {
|
||||
vmEventListener.notifyShutdown();
|
||||
}
|
||||
}
|
||||
@ -382,7 +398,7 @@ public final class HotSpotJVMCIRuntime implements HotSpotJVMCIRuntimeProvider {
|
||||
*/
|
||||
@SuppressWarnings({"unused"})
|
||||
private void bootstrapFinished() throws Exception {
|
||||
for (HotSpotVMEventListener vmEventListener : vmEventListeners) {
|
||||
for (HotSpotVMEventListener vmEventListener : getVmEventListeners()) {
|
||||
vmEventListener.notifyBootstrapFinished();
|
||||
}
|
||||
}
|
||||
@ -395,7 +411,7 @@ public final class HotSpotJVMCIRuntime implements HotSpotJVMCIRuntimeProvider {
|
||||
* @param compiledCode
|
||||
*/
|
||||
void notifyInstall(HotSpotCodeCacheProvider hotSpotCodeCacheProvider, InstalledCode installedCode, CompiledCode compiledCode) {
|
||||
for (HotSpotVMEventListener vmEventListener : vmEventListeners) {
|
||||
for (HotSpotVMEventListener vmEventListener : getVmEventListeners()) {
|
||||
vmEventListener.notifyInstall(hotSpotCodeCacheProvider, installedCode, compiledCode);
|
||||
}
|
||||
}
|
||||
|
@ -144,8 +144,18 @@ class HotSpotMemoryAccessProviderImpl implements HotSpotMemoryAccessProvider {
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaConstant readUnsafeConstant(JavaKind kind, JavaConstant baseConstant, long displacement) {
|
||||
/**
|
||||
* Reads a value of this kind using a base address and a displacement. No bounds checking or
|
||||
* type checking is performed. Returns {@code null} if the value is not available at this point.
|
||||
*
|
||||
* @param baseConstant the base address from which the value is read.
|
||||
* @param displacement the displacement within the object in bytes
|
||||
* @return the read value encapsulated in a {@link JavaConstant} object, or {@code null} if the
|
||||
* value cannot be read.
|
||||
* @throws IllegalArgumentException if {@code kind} is {@code null}, {@link JavaKind#Void}, not
|
||||
* {@link JavaKind#Object} or not {@linkplain JavaKind#isPrimitive() primitive} kind
|
||||
*/
|
||||
JavaConstant readUnsafeConstant(JavaKind kind, JavaConstant baseConstant, long displacement) {
|
||||
if (kind == null) {
|
||||
throw new IllegalArgumentException("null JavaKind");
|
||||
}
|
||||
|
@ -27,19 +27,6 @@ package jdk.vm.ci.meta;
|
||||
*/
|
||||
public interface MemoryAccessProvider {
|
||||
|
||||
/**
|
||||
* Reads a value of this kind using a base address and a displacement. No bounds checking or
|
||||
* type checking is performed. Returns {@code null} if the value is not available at this point.
|
||||
*
|
||||
* @param base the base address from which the value is read.
|
||||
* @param displacement the displacement within the object in bytes
|
||||
* @return the read value encapsulated in a {@link JavaConstant} object, or {@code null} if the
|
||||
* value cannot be read.
|
||||
* @throws IllegalArgumentException if {@code kind} is {@code null}, {@link JavaKind#Void}, not
|
||||
* {@link JavaKind#Object} or not {@linkplain JavaKind#isPrimitive() primitive} kind
|
||||
*/
|
||||
JavaConstant readUnsafeConstant(JavaKind kind, JavaConstant base, long displacement) throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Reads a primitive value using a base address and a displacement.
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2016, 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
|
||||
@ -264,7 +264,7 @@ void Canonicalizer::do_LoadIndexed (LoadIndexed* x) {
|
||||
assert(array == NULL || FoldStableValues, "not enabled");
|
||||
|
||||
// Constant fold loads from stable arrays.
|
||||
if (array != NULL && index != NULL) {
|
||||
if (!x->mismatched() && array != NULL && index != NULL) {
|
||||
jint idx = index->value();
|
||||
if (idx < 0 || idx >= array->value()->length()) {
|
||||
// Leave the load as is. The range check will handle it.
|
||||
@ -310,8 +310,6 @@ void Canonicalizer::do_StoreIndexed (StoreIndexed* x) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -4227,11 +4227,11 @@ void GraphBuilder::append_char_access(ciMethod* callee, bool is_store) {
|
||||
Value index = args->at(1);
|
||||
if (is_store) {
|
||||
Value value = args->at(2);
|
||||
Instruction* store = append(new StoreIndexed(array, index, NULL, T_CHAR, value, state_before, false));
|
||||
Instruction* store = append(new StoreIndexed(array, index, NULL, T_CHAR, value, state_before, false, true));
|
||||
store->set_flag(Instruction::NeedsRangeCheckFlag, false);
|
||||
_memory->store_value(value);
|
||||
} else {
|
||||
Instruction* load = append(new LoadIndexed(array, index, NULL, T_CHAR, state_before));
|
||||
Instruction* load = append(new LoadIndexed(array, index, NULL, T_CHAR, state_before, true));
|
||||
load->set_flag(Instruction::NeedsRangeCheckFlag, false);
|
||||
push(load->type(), load);
|
||||
}
|
||||
|
@ -912,14 +912,16 @@ BASE(AccessIndexed, AccessArray)
|
||||
Value _index;
|
||||
Value _length;
|
||||
BasicType _elt_type;
|
||||
bool _mismatched;
|
||||
|
||||
public:
|
||||
// creation
|
||||
AccessIndexed(Value array, Value index, Value length, BasicType elt_type, ValueStack* state_before)
|
||||
AccessIndexed(Value array, Value index, Value length, BasicType elt_type, ValueStack* state_before, bool mismatched)
|
||||
: AccessArray(as_ValueType(elt_type), array, state_before)
|
||||
, _index(index)
|
||||
, _length(length)
|
||||
, _elt_type(elt_type)
|
||||
, _mismatched(mismatched)
|
||||
{
|
||||
set_flag(Instruction::NeedsRangeCheckFlag, true);
|
||||
ASSERT_VALUES
|
||||
@ -929,6 +931,7 @@ BASE(AccessIndexed, AccessArray)
|
||||
Value index() const { return _index; }
|
||||
Value length() const { return _length; }
|
||||
BasicType elt_type() const { return _elt_type; }
|
||||
bool mismatched() const { return _mismatched; }
|
||||
|
||||
void clear_length() { _length = NULL; }
|
||||
// perform elimination of range checks involving constants
|
||||
@ -945,8 +948,8 @@ LEAF(LoadIndexed, AccessIndexed)
|
||||
|
||||
public:
|
||||
// creation
|
||||
LoadIndexed(Value array, Value index, Value length, BasicType elt_type, ValueStack* state_before)
|
||||
: AccessIndexed(array, index, length, elt_type, state_before)
|
||||
LoadIndexed(Value array, Value index, Value length, BasicType elt_type, ValueStack* state_before, bool mismatched = false)
|
||||
: AccessIndexed(array, index, length, elt_type, state_before, mismatched)
|
||||
, _explicit_null_check(NULL) {}
|
||||
|
||||
// accessors
|
||||
@ -974,8 +977,9 @@ LEAF(StoreIndexed, AccessIndexed)
|
||||
|
||||
public:
|
||||
// creation
|
||||
StoreIndexed(Value array, Value index, Value length, BasicType elt_type, Value value, ValueStack* state_before, bool check_boolean)
|
||||
: AccessIndexed(array, index, length, elt_type, state_before)
|
||||
StoreIndexed(Value array, Value index, Value length, BasicType elt_type, Value value, ValueStack* state_before,
|
||||
bool check_boolean, bool mismatched = false)
|
||||
: AccessIndexed(array, index, length, elt_type, state_before, mismatched)
|
||||
, _value(value), _profiled_method(NULL), _profiled_bci(0), _check_boolean(check_boolean)
|
||||
{
|
||||
set_flag(NeedsWriteBarrierFlag, (as_ValueType(elt_type)->is_object()));
|
||||
|
@ -109,7 +109,7 @@ inline void G1CollectedHeap::old_set_remove(HeapRegion* hr) {
|
||||
_old_set.remove(hr);
|
||||
}
|
||||
|
||||
// It dirties the cards that cover the block so that so that the post
|
||||
// It dirties the cards that cover the block so that the post
|
||||
// write barrier never queues anything when updating objects on this
|
||||
// block. It is assumed (and in fact we assert) that the block
|
||||
// belongs to a young region.
|
||||
|
@ -386,7 +386,7 @@ size_t CollectedHeap::max_tlab_size() const {
|
||||
// initialized by this point, a fact that we assert when doing the
|
||||
// card-mark.)
|
||||
// (c) G1CollectedHeap(G1) uses two kinds of write barriers. When a
|
||||
// G1 concurrent marking is in progress an SATB (pre-write-)barrier is
|
||||
// G1 concurrent marking is in progress an SATB (pre-write-)barrier
|
||||
// is used to remember the pre-value of any store. Initializing
|
||||
// stores will not need this barrier, so we need not worry about
|
||||
// compensating for the missing pre-barrier here. Turning now
|
||||
|
@ -40,31 +40,6 @@
|
||||
#define JVMCI_ERROR_OK(...) JVMCI_ERROR_(JVMCIEnv::ok, __VA_ARGS__)
|
||||
#define CHECK_OK CHECK_(JVMCIEnv::ok)
|
||||
|
||||
class ParseClosure : public StackObj {
|
||||
int _lineNo;
|
||||
char* _filename;
|
||||
bool _abort;
|
||||
protected:
|
||||
void abort() { _abort = true; }
|
||||
void warn_and_abort(const char* message) {
|
||||
warn(message);
|
||||
abort();
|
||||
}
|
||||
void warn(const char* message) {
|
||||
warning("Error at line %d while parsing %s: %s", _lineNo, _filename == NULL ? "?" : _filename, message);
|
||||
}
|
||||
public:
|
||||
ParseClosure() : _lineNo(0), _filename(NULL), _abort(false) {}
|
||||
void parse_line(char* line) {
|
||||
_lineNo++;
|
||||
do_line(line);
|
||||
}
|
||||
virtual void do_line(char* line) = 0;
|
||||
int lineNo() { return _lineNo; }
|
||||
bool is_aborted() { return _abort; }
|
||||
void set_filename(char* path) {_filename = path; _lineNo = 0;}
|
||||
};
|
||||
|
||||
class JVMCIRuntime: public AllStatic {
|
||||
public:
|
||||
// Constants describing whether JVMCI wants to be able to adjust the compilation
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 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
|
||||
@ -204,7 +204,8 @@ Node* ArrayCopyNode::try_clone_instance(PhaseGVN *phase, bool can_reshape, int c
|
||||
}
|
||||
|
||||
if (!finish_transform(phase, can_reshape, ctl, mem)) {
|
||||
return NULL;
|
||||
// Return NodeSentinel to indicate that the transform failed
|
||||
return NodeSentinel;
|
||||
}
|
||||
|
||||
return mem;
|
||||
@ -222,6 +223,7 @@ bool ArrayCopyNode::prepare_array_copy(PhaseGVN *phase, bool can_reshape,
|
||||
Node* dest = in(ArrayCopyNode::Dest);
|
||||
const Type* src_type = phase->type(src);
|
||||
const TypeAryPtr* ary_src = src_type->isa_aryptr();
|
||||
assert(ary_src != NULL, "should be an array copy/clone");
|
||||
|
||||
if (is_arraycopy() || is_copyofrange() || is_copyof()) {
|
||||
const Type* dest_type = phase->type(dest);
|
||||
@ -520,7 +522,7 @@ Node *ArrayCopyNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||
|
||||
Node* mem = try_clone_instance(phase, can_reshape, count);
|
||||
if (mem != NULL) {
|
||||
return mem;
|
||||
return (mem == NodeSentinel) ? NULL : mem;
|
||||
}
|
||||
|
||||
Node* adr_src = NULL;
|
||||
@ -627,31 +629,37 @@ bool ArrayCopyNode::may_modify(const TypeOopPtr *t_oop, PhaseTransform *phase) {
|
||||
return CallNode::may_modify_arraycopy_helper(dest_t, t_oop, phase);
|
||||
}
|
||||
|
||||
bool ArrayCopyNode::may_modify_helper(const TypeOopPtr *t_oop, Node* n, PhaseTransform *phase) {
|
||||
bool ArrayCopyNode::may_modify_helper(const TypeOopPtr *t_oop, Node* n, PhaseTransform *phase, ArrayCopyNode*& ac) {
|
||||
if (n->is_Proj()) {
|
||||
n = n->in(0);
|
||||
if (n->is_Call() && n->as_Call()->may_modify(t_oop, phase)) {
|
||||
if (n->isa_ArrayCopy() != NULL) {
|
||||
ac = n->as_ArrayCopy();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ArrayCopyNode::may_modify(const TypeOopPtr *t_oop, MemBarNode* mb, PhaseTransform *phase) {
|
||||
bool ArrayCopyNode::may_modify(const TypeOopPtr *t_oop, MemBarNode* mb, PhaseTransform *phase, ArrayCopyNode*& ac) {
|
||||
Node* mem = mb->in(TypeFunc::Memory);
|
||||
|
||||
if (mem->is_MergeMem()) {
|
||||
Node* n = mem->as_MergeMem()->memory_at(Compile::AliasIdxRaw);
|
||||
if (may_modify_helper(t_oop, n, phase)) {
|
||||
if (may_modify_helper(t_oop, n, phase, ac)) {
|
||||
return true;
|
||||
} else if (n->is_Phi()) {
|
||||
for (uint i = 1; i < n->req(); i++) {
|
||||
if (n->in(i) != NULL) {
|
||||
if (may_modify_helper(t_oop, n->in(i), phase)) {
|
||||
if (may_modify_helper(t_oop, n->in(i), phase, ac)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (n->Opcode() == Op_StoreCM) {
|
||||
// Ignore card mark stores
|
||||
return may_modify_helper(t_oop, n->in(MemNode::Memory), phase, ac);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 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
|
||||
@ -107,7 +107,7 @@ private:
|
||||
BasicType copy_type, const Type* value_type, int count);
|
||||
bool finish_transform(PhaseGVN *phase, bool can_reshape,
|
||||
Node* ctl, Node *mem);
|
||||
static bool may_modify_helper(const TypeOopPtr *t_oop, Node* n, PhaseTransform *phase);
|
||||
static bool may_modify_helper(const TypeOopPtr *t_oop, Node* n, PhaseTransform *phase, ArrayCopyNode*& ac);
|
||||
|
||||
public:
|
||||
|
||||
@ -162,7 +162,7 @@ public:
|
||||
|
||||
bool is_alloc_tightly_coupled() const { return _alloc_tightly_coupled; }
|
||||
|
||||
static bool may_modify(const TypeOopPtr *t_oop, MemBarNode* mb, PhaseTransform *phase);
|
||||
static bool may_modify(const TypeOopPtr *t_oop, MemBarNode* mb, PhaseTransform *phase, ArrayCopyNode*& ac);
|
||||
bool modifies(intptr_t offset_lo, intptr_t offset_hi, PhaseTransform* phase, bool must_modify);
|
||||
|
||||
#ifndef PRODUCT
|
||||
|
@ -4306,8 +4306,15 @@ void GraphKit::g1_write_barrier_post(Node* oop_store,
|
||||
} __ end_if();
|
||||
} __ end_if();
|
||||
} else {
|
||||
// Object.clone() instrinsic uses this path.
|
||||
g1_mark_card(ideal, card_adr, oop_store, alias_idx, index, index_adr, buffer, tf);
|
||||
// The Object.clone() intrinsic uses this path if !ReduceInitialCardMarks.
|
||||
// We don't need a barrier here if the destination is a newly allocated object
|
||||
// in Eden. Otherwise, GC verification breaks because we assume that cards in Eden
|
||||
// are set to 'g1_young_gen' (see G1SATBCardTableModRefBS::verify_g1_young_region()).
|
||||
assert(!use_ReduceInitialCardMarks(), "can only happen with card marking");
|
||||
Node* card_val = __ load(__ ctrl(), card_adr, TypeInt::INT, T_BYTE, Compile::AliasIdxRaw);
|
||||
__ if_then(card_val, BoolTest::ne, young_card); {
|
||||
g1_mark_card(ideal, card_adr, oop_store, alias_idx, index, index_adr, buffer, tf);
|
||||
} __ end_if();
|
||||
}
|
||||
|
||||
// Final sync IdealKit and GraphKit.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -32,6 +32,7 @@
|
||||
#include "opto/cfgnode.hpp"
|
||||
#include "opto/compile.hpp"
|
||||
#include "opto/convertnode.hpp"
|
||||
#include "opto/graphKit.hpp"
|
||||
#include "opto/locknode.hpp"
|
||||
#include "opto/loopnode.hpp"
|
||||
#include "opto/macro.hpp"
|
||||
@ -263,41 +264,58 @@ void PhaseMacroExpand::eliminate_card_mark(Node* p2x) {
|
||||
// checks if the store done to a different from the value's region.
|
||||
// And replace Cmp with #0 (false) to collapse G1 post barrier.
|
||||
Node* xorx = p2x->find_out_with(Op_XorX);
|
||||
assert(xorx != NULL, "missing G1 post barrier");
|
||||
Node* shift = xorx->unique_out();
|
||||
Node* cmpx = shift->unique_out();
|
||||
assert(cmpx->is_Cmp() && cmpx->unique_out()->is_Bool() &&
|
||||
cmpx->unique_out()->as_Bool()->_test._test == BoolTest::ne,
|
||||
"missing region check in G1 post barrier");
|
||||
_igvn.replace_node(cmpx, makecon(TypeInt::CC_EQ));
|
||||
if (xorx != NULL) {
|
||||
Node* shift = xorx->unique_out();
|
||||
Node* cmpx = shift->unique_out();
|
||||
assert(cmpx->is_Cmp() && cmpx->unique_out()->is_Bool() &&
|
||||
cmpx->unique_out()->as_Bool()->_test._test == BoolTest::ne,
|
||||
"missing region check in G1 post barrier");
|
||||
_igvn.replace_node(cmpx, makecon(TypeInt::CC_EQ));
|
||||
|
||||
// Remove G1 pre barrier.
|
||||
// Remove G1 pre barrier.
|
||||
|
||||
// Search "if (marking != 0)" check and set it to "false".
|
||||
// There is no G1 pre barrier if previous stored value is NULL
|
||||
// (for example, after initialization).
|
||||
if (this_region->is_Region() && this_region->req() == 3) {
|
||||
int ind = 1;
|
||||
if (!this_region->in(ind)->is_IfFalse()) {
|
||||
ind = 2;
|
||||
}
|
||||
if (this_region->in(ind)->is_IfFalse()) {
|
||||
Node* bol = this_region->in(ind)->in(0)->in(1);
|
||||
assert(bol->is_Bool(), "");
|
||||
cmpx = bol->in(1);
|
||||
if (bol->as_Bool()->_test._test == BoolTest::ne &&
|
||||
cmpx->is_Cmp() && cmpx->in(2) == intcon(0) &&
|
||||
cmpx->in(1)->is_Load()) {
|
||||
Node* adr = cmpx->in(1)->as_Load()->in(MemNode::Address);
|
||||
const int marking_offset = in_bytes(JavaThread::satb_mark_queue_offset() +
|
||||
SATBMarkQueue::byte_offset_of_active());
|
||||
if (adr->is_AddP() && adr->in(AddPNode::Base) == top() &&
|
||||
adr->in(AddPNode::Address)->Opcode() == Op_ThreadLocal &&
|
||||
adr->in(AddPNode::Offset) == MakeConX(marking_offset)) {
|
||||
_igvn.replace_node(cmpx, makecon(TypeInt::CC_EQ));
|
||||
// Search "if (marking != 0)" check and set it to "false".
|
||||
// There is no G1 pre barrier if previous stored value is NULL
|
||||
// (for example, after initialization).
|
||||
if (this_region->is_Region() && this_region->req() == 3) {
|
||||
int ind = 1;
|
||||
if (!this_region->in(ind)->is_IfFalse()) {
|
||||
ind = 2;
|
||||
}
|
||||
if (this_region->in(ind)->is_IfFalse()) {
|
||||
Node* bol = this_region->in(ind)->in(0)->in(1);
|
||||
assert(bol->is_Bool(), "");
|
||||
cmpx = bol->in(1);
|
||||
if (bol->as_Bool()->_test._test == BoolTest::ne &&
|
||||
cmpx->is_Cmp() && cmpx->in(2) == intcon(0) &&
|
||||
cmpx->in(1)->is_Load()) {
|
||||
Node* adr = cmpx->in(1)->as_Load()->in(MemNode::Address);
|
||||
const int marking_offset = in_bytes(JavaThread::satb_mark_queue_offset() +
|
||||
SATBMarkQueue::byte_offset_of_active());
|
||||
if (adr->is_AddP() && adr->in(AddPNode::Base) == top() &&
|
||||
adr->in(AddPNode::Address)->Opcode() == Op_ThreadLocal &&
|
||||
adr->in(AddPNode::Offset) == MakeConX(marking_offset)) {
|
||||
_igvn.replace_node(cmpx, makecon(TypeInt::CC_EQ));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
assert(!GraphKit::use_ReduceInitialCardMarks(), "can only happen with card marking");
|
||||
// This is a G1 post barrier emitted by the Object.clone() intrinsic.
|
||||
// Search for the CastP2X->URShiftX->AddP->LoadB->Cmp path which checks if the card
|
||||
// is marked as young_gen and replace the Cmp with 0 (false) to collapse the barrier.
|
||||
Node* shift = p2x->find_out_with(Op_URShiftX);
|
||||
assert(shift != NULL, "missing G1 post barrier");
|
||||
Node* addp = shift->unique_out();
|
||||
Node* load = addp->find_out_with(Op_LoadB);
|
||||
assert(load != NULL, "missing G1 post barrier");
|
||||
Node* cmpx = load->unique_out();
|
||||
assert(cmpx->is_Cmp() && cmpx->unique_out()->is_Bool() &&
|
||||
cmpx->unique_out()->as_Bool()->_test._test == BoolTest::ne,
|
||||
"missing card value check in G1 post barrier");
|
||||
_igvn.replace_node(cmpx, makecon(TypeInt::CC_EQ));
|
||||
// There is no G1 pre barrier in this case
|
||||
}
|
||||
// Now CastP2X can be removed since it is used only on dead path
|
||||
// which currently still alive until igvn optimize it.
|
||||
@ -326,17 +344,15 @@ static Node *scan_mem_chain(Node *mem, int alias_idx, int offset, Node *start_me
|
||||
CallNode *call = in->as_Call();
|
||||
if (call->may_modify(tinst, phase)) {
|
||||
assert(call->is_ArrayCopy(), "ArrayCopy is the only call node that doesn't make allocation escape");
|
||||
|
||||
if (call->as_ArrayCopy()->modifies(offset, offset, phase, false)) {
|
||||
return in;
|
||||
}
|
||||
}
|
||||
mem = in->in(TypeFunc::Memory);
|
||||
} else if (in->is_MemBar()) {
|
||||
if (ArrayCopyNode::may_modify(tinst, in->as_MemBar(), phase)) {
|
||||
assert(in->in(0)->is_Proj() && in->in(0)->in(0)->is_ArrayCopy(), "should be arraycopy");
|
||||
ArrayCopyNode* ac = in->in(0)->in(0)->as_ArrayCopy();
|
||||
assert(ac->is_clonebasic(), "Only basic clone is a non escaping clone");
|
||||
ArrayCopyNode* ac = NULL;
|
||||
if (ArrayCopyNode::may_modify(tinst, in->as_MemBar(), phase, ac)) {
|
||||
assert(ac != NULL && ac->is_clonebasic(), "Only basic clone is a non escaping clone");
|
||||
return ac;
|
||||
}
|
||||
mem = in->in(TypeFunc::Memory);
|
||||
|
@ -160,7 +160,8 @@ Node *MemNode::optimize_simple_memory_chain(Node *mchain, const TypeOopPtr *t_oo
|
||||
}
|
||||
}
|
||||
} else if (proj_in->is_MemBar()) {
|
||||
if (ArrayCopyNode::may_modify(t_oop, proj_in->as_MemBar(), phase)) {
|
||||
ArrayCopyNode* ac = NULL;
|
||||
if (ArrayCopyNode::may_modify(t_oop, proj_in->as_MemBar(), phase, ac)) {
|
||||
break;
|
||||
}
|
||||
result = proj_in->in(TypeFunc::Memory);
|
||||
@ -657,7 +658,8 @@ Node* MemNode::find_previous_store(PhaseTransform* phase) {
|
||||
continue; // (a) advance through independent call memory
|
||||
}
|
||||
} else if (mem->is_Proj() && mem->in(0)->is_MemBar()) {
|
||||
if (ArrayCopyNode::may_modify(addr_t, mem->in(0)->as_MemBar(), phase)) {
|
||||
ArrayCopyNode* ac = NULL;
|
||||
if (ArrayCopyNode::may_modify(addr_t, mem->in(0)->as_MemBar(), phase, ac)) {
|
||||
break;
|
||||
}
|
||||
mem = mem->in(0)->in(TypeFunc::Memory);
|
||||
|
@ -166,14 +166,11 @@ class Parse : public GraphKit {
|
||||
int _all_successors; // Include exception paths also.
|
||||
Block** _successors;
|
||||
|
||||
// Use init_node/init_graph to initialize Blocks.
|
||||
// Block() : _live_locals((uintptr_t*)NULL,0) { ShouldNotReachHere(); }
|
||||
Block() : _live_locals() { ShouldNotReachHere(); }
|
||||
|
||||
public:
|
||||
|
||||
// Set up the block data structure itself.
|
||||
void init_node(Parse* outer, int po);
|
||||
Block(Parse* outer, int rpo);
|
||||
|
||||
// Set up the block's relations to other blocks.
|
||||
void init_graph(Parse* outer);
|
||||
|
||||
|
@ -1235,29 +1235,33 @@ void Parse::init_blocks() {
|
||||
// Create the blocks.
|
||||
_block_count = flow()->block_count();
|
||||
_blocks = NEW_RESOURCE_ARRAY(Block, _block_count);
|
||||
Copy::zero_to_bytes(_blocks, sizeof(Block)*_block_count);
|
||||
|
||||
int rpo;
|
||||
|
||||
// Initialize the structs.
|
||||
for (rpo = 0; rpo < block_count(); rpo++) {
|
||||
for (int rpo = 0; rpo < block_count(); rpo++) {
|
||||
Block* block = rpo_at(rpo);
|
||||
block->init_node(this, rpo);
|
||||
new(block) Block(this, rpo);
|
||||
}
|
||||
|
||||
// Collect predecessor and successor information.
|
||||
for (rpo = 0; rpo < block_count(); rpo++) {
|
||||
for (int rpo = 0; rpo < block_count(); rpo++) {
|
||||
Block* block = rpo_at(rpo);
|
||||
block->init_graph(this);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------init_node-------------------------------------
|
||||
void Parse::Block::init_node(Parse* outer, int rpo) {
|
||||
Parse::Block::Block(Parse* outer, int rpo) : _live_locals() {
|
||||
_flow = outer->flow()->rpo_at(rpo);
|
||||
_pred_count = 0;
|
||||
_preds_parsed = 0;
|
||||
_count = 0;
|
||||
_is_parsed = false;
|
||||
_is_handler = false;
|
||||
_has_merged_backedge = false;
|
||||
_start_map = NULL;
|
||||
_num_successors = 0;
|
||||
_all_successors = 0;
|
||||
_successors = NULL;
|
||||
assert(pred_count() == 0 && preds_parsed() == 0, "sanity");
|
||||
assert(!(is_merged() || is_parsed() || is_handler() || has_merged_backedge()), "sanity");
|
||||
assert(_live_locals.size() == 0, "sanity");
|
||||
|
@ -356,19 +356,6 @@ UNSAFE_ENTRY(jobject, Unsafe_GetUncompressedObject(JNIEnv *env, jobject unsafe,
|
||||
return JNIHandles::make_local(env, v);
|
||||
} UNSAFE_END
|
||||
|
||||
UNSAFE_ENTRY(jclass, Unsafe_GetJavaMirror(JNIEnv *env, jobject unsafe, jlong metaspace_klass)) {
|
||||
Klass* klass = (Klass*) (address) metaspace_klass;
|
||||
|
||||
return (jclass) JNIHandles::make_local(klass->java_mirror());
|
||||
} UNSAFE_END
|
||||
|
||||
UNSAFE_ENTRY(jlong, Unsafe_GetKlassPointer(JNIEnv *env, jobject unsafe, jobject obj)) {
|
||||
oop o = JNIHandles::resolve(obj);
|
||||
jlong klass = (jlong) (address) o->klass();
|
||||
|
||||
return klass;
|
||||
} UNSAFE_END
|
||||
|
||||
#ifndef SUPPORTS_NATIVE_CX8
|
||||
|
||||
// VM_Version::supports_cx8() is a surrogate for 'supports atomic long memory ops'.
|
||||
@ -1152,8 +1139,6 @@ static JNINativeMethod jdk_internal_misc_Unsafe_methods[] = {
|
||||
{CC "putObjectVolatile",CC "(" OBJ "J" OBJ ")V", FN_PTR(Unsafe_PutObjectVolatile)},
|
||||
|
||||
{CC "getUncompressedObject", CC "(" ADR ")" OBJ, FN_PTR(Unsafe_GetUncompressedObject)},
|
||||
{CC "getJavaMirror", CC "(" ADR ")" CLS, FN_PTR(Unsafe_GetJavaMirror)},
|
||||
{CC "getKlassPointer", CC "(" OBJ ")" ADR, FN_PTR(Unsafe_GetKlassPointer)},
|
||||
|
||||
DECLARE_GETPUTOOP(Boolean, Z),
|
||||
DECLARE_GETPUTOOP(Byte, B),
|
||||
|
@ -498,6 +498,19 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread
|
||||
}
|
||||
#endif
|
||||
|
||||
if (thread->frames_to_pop_failed_realloc() > 0 && exec_mode != Unpack_uncommon_trap) {
|
||||
assert(thread->has_pending_exception(), "should have thrown OOME");
|
||||
thread->set_exception_oop(thread->pending_exception());
|
||||
thread->clear_pending_exception();
|
||||
exec_mode = Unpack_exception;
|
||||
}
|
||||
|
||||
#if INCLUDE_JVMCI
|
||||
if (thread->frames_to_pop_failed_realloc() > 0) {
|
||||
thread->set_pending_monitorenter(false);
|
||||
}
|
||||
#endif
|
||||
|
||||
UnrollBlock* info = new UnrollBlock(array->frame_size() * BytesPerWord,
|
||||
caller_adjustment * BytesPerWord,
|
||||
caller_was_method_handle ? 0 : callee_parameters,
|
||||
|
@ -171,6 +171,8 @@ void vframeArrayElement::unpack_on_stack(int caller_actual_parameters,
|
||||
int exec_mode) {
|
||||
JavaThread* thread = (JavaThread*) Thread::current();
|
||||
|
||||
bool realloc_failure_exception = thread->frames_to_pop_failed_realloc() > 0;
|
||||
|
||||
// Look at bci and decide on bcp and continuation pc
|
||||
address bcp;
|
||||
// C++ interpreter doesn't need a pc since it will figure out what to do when it
|
||||
@ -204,10 +206,12 @@ void vframeArrayElement::unpack_on_stack(int caller_actual_parameters,
|
||||
//
|
||||
// For Compiler1, deoptimization can occur while throwing a NullPointerException at monitorenter,
|
||||
// in which case bcp should point to the monitorenter since it is within the exception's range.
|
||||
//
|
||||
// For realloc failure exception we just pop frames, skip the guarantee.
|
||||
|
||||
assert(*bcp != Bytecodes::_monitorenter || is_top_frame, "a _monitorenter must be a top frame");
|
||||
assert(thread->deopt_compiled_method() != NULL, "compiled method should be known");
|
||||
guarantee(!(thread->deopt_compiled_method()->is_compiled_by_c2() &&
|
||||
guarantee(realloc_failure_exception || !(thread->deopt_compiled_method()->is_compiled_by_c2() &&
|
||||
*bcp == Bytecodes::_monitorenter &&
|
||||
exec_mode == Deoptimization::Unpack_exception),
|
||||
"shouldn't get exception during monitorenter");
|
||||
@ -237,12 +241,17 @@ void vframeArrayElement::unpack_on_stack(int caller_actual_parameters,
|
||||
// Deoptimization::fetch_unroll_info_helper
|
||||
popframe_preserved_args_size_in_words = in_words(thread->popframe_preserved_args_size_in_words());
|
||||
}
|
||||
} else if (JvmtiExport::can_force_early_return() && state != NULL && state->is_earlyret_pending()) {
|
||||
} else if (!realloc_failure_exception && JvmtiExport::can_force_early_return() && state != NULL && state->is_earlyret_pending()) {
|
||||
// Force early return from top frame after deoptimization
|
||||
#ifndef CC_INTERP
|
||||
pc = Interpreter::remove_activation_early_entry(state->earlyret_tos());
|
||||
#endif
|
||||
} else {
|
||||
if (realloc_failure_exception && JvmtiExport::can_force_early_return() && state != NULL && state->is_earlyret_pending()) {
|
||||
state->clr_earlyret_pending();
|
||||
state->set_earlyret_oop(NULL);
|
||||
state->clr_earlyret_value();
|
||||
}
|
||||
// Possibly override the previous pc computation of the top (youngest) frame
|
||||
switch (exec_mode) {
|
||||
case Deoptimization::Unpack_deopt:
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,10 +23,10 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8130847
|
||||
* @bug 8130847 8156760
|
||||
* @summary Eliminated instance/array written to by an array copy variant must be correctly initialized when reallocated at a deopt
|
||||
* @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement TestEliminatedArrayCopyDeopt
|
||||
*
|
||||
* @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:+IgnoreUnrecognizedVMOptions -XX:-ReduceInitialCardMarks TestEliminatedArrayCopyDeopt
|
||||
*/
|
||||
|
||||
// Test that if an ArrayCopy node is eliminated because it doesn't
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,12 +23,12 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6700100
|
||||
* @bug 6700100 8156760
|
||||
* @summary small instance clone as loads/stores
|
||||
* @compile TestInstanceCloneAsLoadsStores.java TestInstanceCloneUtils.java
|
||||
* @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:CompileCommand=dontinline,TestInstanceCloneAsLoadsStores::m* TestInstanceCloneAsLoadsStores
|
||||
* @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:CompileCommand=dontinline,TestInstanceCloneAsLoadsStores::m* -XX:+IgnoreUnrecognizedVMOptions -XX:+StressArrayCopyMacroNode TestInstanceCloneAsLoadsStores
|
||||
*
|
||||
* @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:CompileCommand=dontinline,TestInstanceCloneAsLoadsStores::m* -XX:+IgnoreUnrecognizedVMOptions -XX:-ReduceInitialCardMarks TestInstanceCloneAsLoadsStores
|
||||
*/
|
||||
|
||||
public class TestInstanceCloneAsLoadsStores extends TestInstanceCloneUtils {
|
||||
|
@ -34,12 +34,12 @@
|
||||
import jdk.test.lib.*;
|
||||
|
||||
public class Test6857159 {
|
||||
public static void main(String[] args) throws Exception {
|
||||
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xbatch", "-XX:+PrintCompilation",
|
||||
"-XX:CompileOnly=Test$ct.run", "Test");
|
||||
OutputAnalyzer analyzer = new OutputAnalyzer(pb.start());
|
||||
public static void main(String[] args) throws Throwable {
|
||||
OutputAnalyzer analyzer = ProcessTools.executeTestJvm("-Xbatch",
|
||||
"-XX:+PrintCompilation", "-XX:CompileOnly=Test$ct.run", "Test");
|
||||
analyzer.shouldNotContain("COMPILE SKIPPED");
|
||||
analyzer.shouldContain("Test$ct0::run (16 bytes)");
|
||||
analyzer.shouldHaveExitValue(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,54 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2009, 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.
|
||||
#
|
||||
#
|
||||
## some tests require path to find test source dir
|
||||
if [ "${TESTSRC}" = "" ]
|
||||
then
|
||||
TESTSRC=${PWD}
|
||||
echo "TESTSRC not set. Using "${TESTSRC}" as default"
|
||||
fi
|
||||
echo "TESTSRC=${TESTSRC}"
|
||||
## Adding common setup Variables for running shell tests.
|
||||
. ${TESTSRC}/../../../test_env.sh
|
||||
|
||||
set -x
|
||||
|
||||
cp ${TESTSRC}/Test6857159.java .
|
||||
cp ${TESTSRC}/Test6857159.sh .
|
||||
|
||||
${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} -d . Test6857159.java
|
||||
|
||||
${TESTJAVA}/bin/java ${TESTOPTS} -Xbatch -XX:+PrintCompilation -XX:CompileOnly=Test6857159\$ct.run Test6857159 > test.out 2>&1
|
||||
|
||||
grep "COMPILE SKIPPED" test.out
|
||||
|
||||
result=$?
|
||||
if [ $result -eq 1 ]
|
||||
then
|
||||
echo "Passed"
|
||||
exit 0
|
||||
else
|
||||
echo "Failed"
|
||||
exit 1
|
||||
fi
|
@ -25,8 +25,7 @@
|
||||
* @test
|
||||
* @bug 6894807
|
||||
* @summary No ClassCastException for HashAttributeSet constructors if run with -Xcomp
|
||||
* @compile IsInstanceTest.java
|
||||
* @run shell Test6894807.sh
|
||||
* @run main IsInstanceTest
|
||||
*/
|
||||
|
||||
public class IsInstanceTest {
|
||||
@ -35,13 +34,7 @@ public class IsInstanceTest {
|
||||
BaseInterface baseInterfaceImpl = new BaseInterfaceImpl();
|
||||
for (int i = 0; i < 100000; i++) {
|
||||
if (isInstanceOf(baseInterfaceImpl, ExtendedInterface.class)) {
|
||||
System.out.println("Failed at index:" + i);
|
||||
System.out.println("Arch: "+System.getProperty("os.arch", "")+
|
||||
" OS: "+System.getProperty("os.name", "")+
|
||||
" OSV: "+System.getProperty("os.version", "")+
|
||||
" Cores: "+Runtime.getRuntime().availableProcessors()+
|
||||
" JVM: "+System.getProperty("java.version", "")+" "+System.getProperty("sun.arch.data.model", ""));
|
||||
break;
|
||||
throw new AssertionError("Failed at index:" + i);
|
||||
}
|
||||
}
|
||||
System.out.println("Done!");
|
||||
|
@ -1,48 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2012, 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.
|
||||
#
|
||||
|
||||
if [ "${TESTSRC}" = "" ]
|
||||
then
|
||||
TESTSRC=${PWD}
|
||||
echo "TESTSRC not set. Using "${TESTSRC}" as default"
|
||||
fi
|
||||
echo "TESTSRC=${TESTSRC}"
|
||||
|
||||
## Adding common setup Variables for running shell tests.
|
||||
. ${TESTSRC}/../../../test_env.sh
|
||||
|
||||
${TESTJAVA}${FS}bin${FS}java ${TESTOPTS} IsInstanceTest > test.out 2>&1
|
||||
|
||||
cat test.out
|
||||
|
||||
grep "Failed at index" test.out
|
||||
|
||||
if [ $? = 0 ]
|
||||
then
|
||||
echo "Test Failed"
|
||||
exit 1
|
||||
else
|
||||
echo "Test Passed"
|
||||
exit 0
|
||||
fi
|
@ -2,8 +2,10 @@
|
||||
* @test
|
||||
* @bug 7070134
|
||||
* @summary Hotspot crashes with sigsegv from PorterStemmer
|
||||
*
|
||||
* @run shell Test7070134.sh
|
||||
* @modules java.base/jdk.internal.misc
|
||||
* @library /testlibrary
|
||||
* @run driver jdk.test.lib.FileInstaller words words
|
||||
* @run main/othervm -Xbatch Stemmer words
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -61,7 +63,7 @@ import java.io.*;
|
||||
* by calling one of the various stem(something) methods.
|
||||
*/
|
||||
|
||||
class Stemmer
|
||||
public class Stemmer
|
||||
{ private char[] b;
|
||||
private int i, /* offset into b */
|
||||
i_end, /* offset to end of stemmed word */
|
||||
|
@ -1,45 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2011, 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.
|
||||
#
|
||||
#
|
||||
## some tests require path to find test source dir
|
||||
if [ "${TESTSRC}" = "" ]
|
||||
then
|
||||
TESTSRC=${PWD}
|
||||
echo "TESTSRC not set. Using "${TESTSRC}" as default"
|
||||
fi
|
||||
echo "TESTSRC=${TESTSRC}"
|
||||
## Adding common setup Variables for running shell tests.
|
||||
. ${TESTSRC}/../../../test_env.sh
|
||||
|
||||
set -x
|
||||
|
||||
cp ${TESTSRC}/Stemmer.java .
|
||||
cp ${TESTSRC}/words .
|
||||
|
||||
${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} -d . Stemmer.java
|
||||
|
||||
${TESTJAVA}/bin/java ${TESTOPTS} -Xbatch Stemmer words > test.out 2>&1
|
||||
|
||||
exit $?
|
||||
|
@ -38,6 +38,7 @@ import sun.hotspot.code.BlobType;
|
||||
/*
|
||||
* @test PoolsIndependenceTest
|
||||
* @modules java.base/jdk.internal.misc
|
||||
* java.management
|
||||
* @library /testlibrary /test/lib
|
||||
* @build PoolsIndependenceTest
|
||||
* @run main ClassFileInstaller sun.hotspot.WhiteBox
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 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
|
||||
@ -19,29 +19,19 @@
|
||||
* 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 8022853
|
||||
* @library /testlibrary
|
||||
* @modules java.base/jdk.internal.misc
|
||||
* @build jdk.test.lib.*
|
||||
* @run main GetKlassPointerGetJavaMirror
|
||||
/*
|
||||
* @test TestSSE4Disabled
|
||||
* @bug 8158214
|
||||
* @requires (os.simpleArch == "x64")
|
||||
* @summary Test correct execution without SSE 4.
|
||||
* @run main/othervm -Xcomp -XX:UseSSE=3 TestSSE4Disabled
|
||||
*/
|
||||
|
||||
import static jdk.test.lib.Asserts.*;
|
||||
|
||||
import jdk.test.lib.*;
|
||||
import jdk.internal.misc.Unsafe;
|
||||
|
||||
public class GetKlassPointerGetJavaMirror {
|
||||
|
||||
public static void main(String args[]) throws Exception {
|
||||
Unsafe unsafe = Utils.getUnsafe();
|
||||
Object o = new GetKlassPointerGetJavaMirror();
|
||||
final long metaspaceKlass = unsafe.getKlassPointer(o);
|
||||
Class<?> c = unsafe.getJavaMirror(metaspaceKlass);
|
||||
assertEquals(o.getClass(), c);
|
||||
public class TestSSE4Disabled {
|
||||
public static void main(String args[]) {
|
||||
System.out.println("Passed");
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -25,9 +25,9 @@
|
||||
* @bug 8139258
|
||||
* @summary Regression test for 8139258 which failed to properly pass float args
|
||||
* to a jni function on ppc64le.
|
||||
* @run main/othervm -Xint Test15FloatJNIArgs
|
||||
* @run main/othervm -XX:+TieredCompilation -Xcomp Test15FloatJNIArgs
|
||||
* @run main/othervm -XX:-TieredCompilation -Xcomp Test15FloatJNIArgs
|
||||
* @run main/othervm/native -Xint Test15FloatJNIArgs
|
||||
* @run main/othervm/native -XX:+TieredCompilation -Xcomp Test15FloatJNIArgs
|
||||
* @run main/othervm/native -XX:-TieredCompilation -Xcomp Test15FloatJNIArgs
|
||||
*/
|
||||
|
||||
public class Test15FloatJNIArgs {
|
||||
|
@ -0,0 +1 @@
|
||||
compiler.jvmci.common.JVMCIHelpers$EmptyVMEventListener
|
@ -0,0 +1 @@
|
||||
compiler.jvmci.common.JVMCIHelpers$EmptyCompilerFactory
|
@ -138,17 +138,6 @@ public class GetConstantPoolTest {
|
||||
return CompilerToVMHelper.getConstantPool(cpInst, ptr);
|
||||
}
|
||||
},
|
||||
OBJECT_TYPE_BASE {
|
||||
@Override
|
||||
ConstantPool getConstantPool() {
|
||||
HotSpotResolvedObjectType type
|
||||
= HotSpotResolvedObjectType.fromObjectClass(
|
||||
OBJECT_TYPE_BASE.getClass());
|
||||
long ptrToClass = UNSAFE.getKlassPointer(OBJECT_TYPE_BASE);
|
||||
return CompilerToVMHelper.getConstantPool(type,
|
||||
getPtrToCpAddress() - ptrToClass);
|
||||
}
|
||||
},
|
||||
;
|
||||
abstract ConstantPool getConstantPool();
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
/*
|
||||
* @test
|
||||
* @bug 8136421
|
||||
* @ignore 8158860
|
||||
* @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9" | os.simpleArch == "aarch64")
|
||||
* @library / /testlibrary /test/lib
|
||||
* @library ../common/patches
|
||||
@ -149,25 +150,12 @@ public class GetResolvedJavaTypeTest {
|
||||
ptr, COMPRESSED);
|
||||
}
|
||||
},
|
||||
OBJECT_TYPE_BASE {
|
||||
@Override
|
||||
HotSpotResolvedObjectType getResolvedJavaType() {
|
||||
HotSpotResolvedObjectType type
|
||||
= HotSpotResolvedObjectType.fromObjectClass(
|
||||
OBJECT_TYPE_BASE.getClass());
|
||||
long ptrToClass = UNSAFE.getKlassPointer(OBJECT_TYPE_BASE);
|
||||
return CompilerToVMHelper.getResolvedJavaType(type,
|
||||
getPtrToKlass() - ptrToClass, COMPRESSED);
|
||||
}
|
||||
},
|
||||
;
|
||||
abstract HotSpotResolvedObjectType getResolvedJavaType();
|
||||
}
|
||||
|
||||
private static final Unsafe UNSAFE = Utils.getUnsafe();
|
||||
private static final WhiteBox WB = WhiteBox.getWhiteBox();
|
||||
private static final long PTR = UNSAFE.getKlassPointer(
|
||||
new GetResolvedJavaTypeTest());
|
||||
private static final Class TEST_CLASS = GetResolvedJavaTypeTest.class;
|
||||
/* a compressed parameter for tested method is set to false because
|
||||
unsafe.getKlassPointer always returns uncompressed pointer */
|
||||
|
@ -0,0 +1 @@
|
||||
compiler.jvmci.events.JvmciNotifyBootstrapFinishedEventTest
|
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 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 8156034
|
||||
* @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9" | os.simpleArch == "aarch64")
|
||||
* @library / /testlibrary
|
||||
* @library ../common/patches
|
||||
* @modules java.base/jdk.internal.misc
|
||||
java.base/jdk.internal.org.objectweb.asm
|
||||
* java.base/jdk.internal.org.objectweb.asm.tree
|
||||
* jdk.vm.ci/jdk.vm.ci.hotspot
|
||||
* jdk.vm.ci/jdk.vm.ci.code
|
||||
* jdk.vm.ci/jdk.vm.ci.meta
|
||||
* jdk.vm.ci/jdk.vm.ci.runtime
|
||||
* @build jdk.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper
|
||||
* @build compiler.jvmci.common.JVMCIHelpers
|
||||
* compiler.jvmci.events.JvmciNotifyBootstrapFinishedEventTest
|
||||
* @run main jdk.test.lib.FileInstaller ../common/services/ ./META-INF/services/
|
||||
* @run main jdk.test.lib.FileInstaller ./JvmciNotifyBootstrapFinishedEventTest.config
|
||||
* ./META-INF/services/jdk.vm.ci.hotspot.services.HotSpotVMEventListener
|
||||
* @run main ClassFileInstaller
|
||||
* compiler.jvmci.common.JVMCIHelpers$EmptyHotspotCompiler
|
||||
* compiler.jvmci.common.JVMCIHelpers$EmptyCompilerFactory
|
||||
* compiler.jvmci.events.JvmciNotifyBootstrapFinishedEventTest
|
||||
* jdk.test.lib.Asserts
|
||||
* jdk.test.lib.Utils
|
||||
* @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
|
||||
* -Djvmci.Compiler=EmptyCompiler -Xbootclasspath/a:.
|
||||
* -XX:+UseJVMCICompiler -XX:-BootstrapJVMCI
|
||||
* -Dcompiler.jvmci.events.JvmciNotifyBootstrapFinishedEventTest.bootstrap=false
|
||||
* compiler.jvmci.events.JvmciNotifyBootstrapFinishedEventTest
|
||||
* @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
|
||||
* -Djvmci.Compiler=EmptyCompiler -Xbootclasspath/a:.
|
||||
* -XX:+UseJVMCICompiler -XX:+BootstrapJVMCI
|
||||
* -Dcompiler.jvmci.events.JvmciNotifyBootstrapFinishedEventTest.bootstrap=true
|
||||
* compiler.jvmci.events.JvmciNotifyBootstrapFinishedEventTest
|
||||
*/
|
||||
|
||||
package compiler.jvmci.events;
|
||||
|
||||
import jdk.test.lib.Asserts;
|
||||
import jdk.vm.ci.hotspot.services.HotSpotVMEventListener;
|
||||
|
||||
public class JvmciNotifyBootstrapFinishedEventTest extends HotSpotVMEventListener {
|
||||
private static final boolean BOOTSTRAP = Boolean
|
||||
.getBoolean("compiler.jvmci.events.JvmciNotifyBootstrapFinishedEventTest.bootstrap");
|
||||
private static volatile int gotBoostrapNotification = 0;
|
||||
|
||||
public static void main(String args[]) {
|
||||
if (BOOTSTRAP) {
|
||||
Asserts.assertEQ(gotBoostrapNotification, 1, "Did not receive expected number of bootstrap events");
|
||||
} else {
|
||||
Asserts.assertEQ(gotBoostrapNotification, 0, "Got unexpected bootstrap event");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyBootstrapFinished() {
|
||||
gotBoostrapNotification++;
|
||||
}
|
||||
}
|
@ -48,26 +48,6 @@ import jdk.vm.ci.runtime.JVMCI;
|
||||
public class MemoryAccessProviderTest {
|
||||
private static final MemoryAccessProvider PROVIDER = JVMCI.getRuntime().getHostJVMCIBackend().getConstantReflection().getMemoryAccessProvider();
|
||||
|
||||
@Test(dataProvider = "positivePrimitive", dataProviderClass = MemoryAccessProviderData.class)
|
||||
public void testPositiveReadUnsafeConstant(JavaKind kind, JavaConstant base, Long offset, Object expected, int bitsCount) {
|
||||
Assert.assertEquals(PROVIDER.readUnsafeConstant(kind, base, offset), expected, "Failed to read constant");
|
||||
}
|
||||
|
||||
@Test(dataProvider = "positivePrimitive", dataProviderClass = MemoryAccessProviderData.class, expectedExceptions = {IllegalArgumentException.class})
|
||||
public void testReadUnsafeConstantNullBase(JavaKind kind, JavaConstant base, Long offset, Object expected, int bitsCount) {
|
||||
PROVIDER.readUnsafeConstant(kind, null, offset);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "positivePrimitive", dataProviderClass = MemoryAccessProviderData.class, expectedExceptions = {IllegalArgumentException.class})
|
||||
public void testNegativeReadUnsafeConstantNullKind(JavaKind kind, JavaConstant base, Long offset, Object expected, int bitsCount) {
|
||||
Assert.assertNull(PROVIDER.readUnsafeConstant(null, base, offset), "Expected null return");
|
||||
}
|
||||
|
||||
@Test(dataProvider = "negative", dataProviderClass = MemoryAccessProviderData.class, expectedExceptions = {IllegalArgumentException.class})
|
||||
public void testNegativeReadUnsafeConstant(JavaKind kind, JavaConstant base) {
|
||||
PROVIDER.readUnsafeConstant(kind, base, 0L);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "positivePrimitive", dataProviderClass = MemoryAccessProviderData.class)
|
||||
public void testPositiveReadPrimitiveConstant(JavaKind kind, Constant base, Long offset, Object expected, int bitsCount) {
|
||||
Assert.assertEquals(PROVIDER.readPrimitiveConstant(kind, base, offset, bitsCount), expected, "Failed to read constant");
|
||||
|
@ -31,7 +31,6 @@
|
||||
* @build jdk.vm.ci.runtime.test.ConstantTest
|
||||
* @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI jdk.vm.ci.runtime.test.ConstantTest
|
||||
*/
|
||||
// * @compile ConstantTest.java FieldUniverse.java TypeUniverse.java TestMetaAccessProvider.java
|
||||
package jdk.vm.ci.runtime.test;
|
||||
|
||||
import org.junit.Assert;
|
||||
|
50
hotspot/test/compiler/stable/TestStableMismatched.java
Normal file
50
hotspot/test/compiler/stable/TestStableMismatched.java
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 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 TestStableMismatched
|
||||
* @bug 8158228
|
||||
* @summary Tests if mismatched char load from stable byte[] returns correct result
|
||||
* @run main/othervm -XX:-CompactStrings -XX:TieredStopAtLevel=1 -Xcomp
|
||||
* -XX:CompileOnly=TestStableMismatched::test,::charAt
|
||||
* TestStableMismatched
|
||||
* @run main/othervm -XX:-CompactStrings -XX:-TieredCompilation -Xcomp
|
||||
* -XX:CompileOnly=TestStableMismatched::test,::charAt
|
||||
* TestStableMismatched
|
||||
*/
|
||||
public class TestStableMismatched {
|
||||
public static void main(String args[]) {
|
||||
test();
|
||||
}
|
||||
|
||||
public static void test() {
|
||||
String text = "abcdefg";
|
||||
// Mismatched char load from @Stable byte[] String.value field
|
||||
char returned = text.charAt(6);
|
||||
if (returned != 'g') {
|
||||
throw new RuntimeException("failed: charAt(6) returned '" + returned + "' instead of 'g'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
91
hotspot/test/compiler/uncommontrap/DeoptReallocFailure.java
Normal file
91
hotspot/test/compiler/uncommontrap/DeoptReallocFailure.java
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 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 8146416
|
||||
* @library /test/lib /testlibrary /
|
||||
* @build sun.hotspot.WhiteBox
|
||||
* @run main ClassFileInstaller sun.hotspot.WhiteBox
|
||||
* sun.hotspot.WhiteBox$WhiteBoxPermission
|
||||
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbatch -XX:CompileCommand=exclude,DeoptReallocFailure::main -Xmx100m DeoptReallocFailure
|
||||
*
|
||||
*/
|
||||
import java.lang.reflect.Method;
|
||||
import sun.hotspot.WhiteBox;
|
||||
|
||||
class MemoryChunk {
|
||||
MemoryChunk other;
|
||||
Object[][] array;
|
||||
|
||||
MemoryChunk(MemoryChunk other) {
|
||||
this.other = other;
|
||||
array = new Object[1024 * 256][];
|
||||
}
|
||||
}
|
||||
|
||||
class NoEscape {
|
||||
long f1;
|
||||
}
|
||||
|
||||
public class DeoptReallocFailure {
|
||||
|
||||
static MemoryChunk root;
|
||||
private static final WhiteBox WB = WhiteBox.getWhiteBox();
|
||||
|
||||
public static synchronized long test() {
|
||||
NoEscape[] noEscape = new NoEscape[45];
|
||||
noEscape[0] = new NoEscape();
|
||||
for (int i=0;i<1024*256;i++) {
|
||||
root.array[i]= new Object[45];
|
||||
}
|
||||
return noEscape[0].f1;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Throwable {
|
||||
|
||||
//Exhaust Memory
|
||||
root = null;
|
||||
try {
|
||||
while (true) {
|
||||
root = new MemoryChunk(root);
|
||||
}
|
||||
} catch (OutOfMemoryError oom) {
|
||||
}
|
||||
|
||||
if (root == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
NoEscape dummy = new NoEscape();
|
||||
Method m = DeoptReallocFailure.class.getMethod("test");
|
||||
WB.enqueueMethodForCompilation(m, 4);
|
||||
test();
|
||||
} catch (OutOfMemoryError oom) {
|
||||
root = null;
|
||||
oom.printStackTrace();
|
||||
}
|
||||
System.out.println("TEST PASSED");
|
||||
}
|
||||
}
|
@ -45,8 +45,8 @@ public class FileInstaller {
|
||||
if (args.length != 2) {
|
||||
throw new IllegalArgumentException("Unexpected number of arguments for file copy");
|
||||
}
|
||||
Path src = Paths.get(Utils.TEST_SRC, args[0]);
|
||||
Path dst = Paths.get(args[1]);
|
||||
Path src = Paths.get(Utils.TEST_SRC, args[0]).toAbsolutePath();
|
||||
Path dst = Paths.get(args[1]).toAbsolutePath();
|
||||
if (src.toFile().exists()) {
|
||||
if (src.toFile().isDirectory()) {
|
||||
Files.walkFileTree(src, new CopyFileVisitor(src, dst));
|
||||
|
@ -44,6 +44,10 @@ ifneq "x$(SEED)" "x"
|
||||
APPLICATION_ARGS += --seed $(SEED)
|
||||
endif
|
||||
|
||||
ifneq "x$(EXTRA_SRC_DIR)" "x"
|
||||
EXTRA_SRC_FILES := $(shell find $(EXTRA_SRC_DIR) -name '*.java')
|
||||
endif
|
||||
|
||||
JAVA = $(JDK_HOME)/bin/java
|
||||
JAVAC = $(JDK_HOME)/bin/javac
|
||||
JAR = $(JDK_HOME)/bin/jar
|
||||
@ -99,6 +103,7 @@ COMPILE: INIT filelist compile_testlib
|
||||
filelist: $(SRC_FILES)
|
||||
@rm -f $@
|
||||
@echo $(SRC_FILES) > $@
|
||||
@echo $(EXTRA_SRC_FILES) >> $@
|
||||
|
||||
INIT: $(DIST_DIR)
|
||||
$(shell if [ ! -d $(CLASSES_DIR) ]; then mkdir -p $(CLASSES_DIR); fi)
|
||||
|
@ -9,3 +9,5 @@ exclude-methods-file=conf/exclude.methods.lst
|
||||
print-complexity=true
|
||||
print-hierarchy=true
|
||||
disable-static=true
|
||||
generatorsFactories=jdk.test.lib.jittester.TestGeneratorsFactory
|
||||
generators=JavaCode,ByteCode
|
||||
|
@ -25,50 +25,19 @@ package jdk.test.lib.jittester;
|
||||
|
||||
import jdk.test.lib.Pair;
|
||||
import jdk.test.lib.jittester.factories.IRNodeBuilder;
|
||||
import jdk.test.lib.jittester.jtreg.Printer;
|
||||
import jdk.test.lib.jittester.types.TypeKlass;
|
||||
import jdk.test.lib.jittester.utils.FixedTrees;
|
||||
import jdk.test.lib.jittester.utils.OptionResolver;
|
||||
import jdk.test.lib.jittester.utils.OptionResolver.Option;
|
||||
import jdk.test.lib.jittester.utils.PseudoRandom;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.time.LocalTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class Automatic {
|
||||
private static final int MINUTES_TO_WAIT = Integer.getInteger("jdk.test.lib.jittester", 3);
|
||||
|
||||
static String getJtregHeader(String mainClass, boolean addCompile) {
|
||||
String synopsis = "seed = '" + ProductionParams.seed.value() + "'"
|
||||
+ ", specificSeed = '" + PseudoRandom.getCurrentSeed() + "'";
|
||||
StringBuilder header = new StringBuilder();
|
||||
header.append("/*\n * @test\n * @summary ")
|
||||
.append(synopsis)
|
||||
.append(" \n* @library / ../\n");
|
||||
if (addCompile) {
|
||||
header.append("\n * @compile ")
|
||||
.append(mainClass)
|
||||
.append(".java\n");
|
||||
}
|
||||
header.append(" * @run build jdk.test.lib.jittester.jtreg.JitTesterDriver "
|
||||
+ "jdk.test.lib.jittester.jtreg.Printer\n")
|
||||
.append(" * @run driver jdk.test.lib.jittester.jtreg.JitTesterDriver ")
|
||||
.append(mainClass)
|
||||
.append("\n */\n\n");
|
||||
if (ProductionParams.printHierarchy.value()) {
|
||||
header.append("/*\n")
|
||||
.append(Automatic.printHierarchy())
|
||||
.append("*/\n");
|
||||
}
|
||||
return header.toString();
|
||||
}
|
||||
public static final int MINUTES_TO_WAIT = Integer.getInteger("jdk.test.lib.jittester", 3);
|
||||
|
||||
private static Pair<IRNode, IRNode> generateIRTree(String name) {
|
||||
SymbolTable.removeAll();
|
||||
@ -120,123 +89,48 @@ public class Automatic {
|
||||
}
|
||||
}
|
||||
|
||||
private static List<TestsGenerator> getTestGenerators() {
|
||||
List<TestsGenerator> result = new ArrayList<>();
|
||||
Class<?> factoryClass;
|
||||
Function<String[], List<TestsGenerator>> factory;
|
||||
String[] factoryClassNames = ProductionParams.generatorsFactories.value().split(",");
|
||||
String[] generatorNames = ProductionParams.generators.value().split(",");
|
||||
for (String factoryClassName : factoryClassNames) {
|
||||
try {
|
||||
factoryClass = Class.forName(factoryClassName);
|
||||
factory = (Function<String[], List<TestsGenerator>>) factoryClass.newInstance();
|
||||
} catch (ReflectiveOperationException roe) {
|
||||
throw new Error("Can't instantiate generators factory", roe);
|
||||
}
|
||||
result.addAll(factory.apply(generatorNames));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
initializeTestGenerator(args);
|
||||
int counter = 0;
|
||||
try {
|
||||
Path testbaseDir = Paths.get(ProductionParams.testbaseDir.value());
|
||||
System.out.printf(" %13s | %8s | %8s | %8s |%n", "start time", "count", "generat",
|
||||
"running");
|
||||
System.out.printf(" %13s | %8s | %8s | %8s |%n", "---", "---", "---","---");
|
||||
String path = getJavaPath();
|
||||
String javacPath = Paths.get(path, "javac").toString();
|
||||
String javaPath = Paths.get(path, "java").toString();
|
||||
|
||||
// compile Printer class first. A common one for all tests
|
||||
ensureExisting(testbaseDir);
|
||||
ProcessBuilder pbPrinter = new ProcessBuilder(javacPath,
|
||||
Paths.get(testbaseDir.toString(), "jdk", "test", "lib", "jittester",
|
||||
"jtreg", "Printer.java").toString());
|
||||
runProcess(pbPrinter, testbaseDir.resolve("Printer").toString());
|
||||
do {
|
||||
double start = System.currentTimeMillis();
|
||||
System.out.print("[" + LocalTime.now() + "] |");
|
||||
String name = "Test_" + counter;
|
||||
Pair<IRNode, IRNode> irTree = generateIRTree(name);
|
||||
System.out.printf(" %8d |", counter);
|
||||
double generationTime = System.currentTimeMillis() - start;
|
||||
System.out.printf(" %8.0f |", generationTime);
|
||||
if (!ProductionParams.disableJavacodeGeneration.value()) {
|
||||
JavaCodeGenerator generator = new JavaCodeGenerator();
|
||||
String javaFile = generator.apply(irTree.first, irTree.second);
|
||||
ProcessBuilder pb = new ProcessBuilder(javacPath, "-cp", testbaseDir.toString()
|
||||
+ ":" + generator.getTestbase().toString(), javaFile);
|
||||
runProcess(pb, generator.getTestbase().resolve(name).toString());
|
||||
start = System.currentTimeMillis();
|
||||
|
||||
// Run compiled class files
|
||||
pb = new ProcessBuilder(javaPath, "-Xint", "-cp", testbaseDir.toString()
|
||||
+ ":" + generator.getTestbase().toString(), name);
|
||||
String goldFile = name + ".gold";
|
||||
runProcess(pb, generator.getTestbase().resolve(goldFile).toString());
|
||||
}
|
||||
|
||||
if (!ProductionParams.disableBytecodeGeneration.value()) {
|
||||
ByteCodeGenerator generator = new ByteCodeGenerator();
|
||||
generator.apply(irTree.first, irTree.second);
|
||||
generator.writeJtregBytecodeRunner(name);
|
||||
// Run generated bytecode
|
||||
ProcessBuilder pb = new ProcessBuilder(javaPath, "-Xint", "-Xverify", "-cp",
|
||||
testbaseDir.toString() + ":" + generator.getTestbase().toString(),
|
||||
name);
|
||||
String goldFile = name + ".gold";
|
||||
start = System.currentTimeMillis();
|
||||
runProcess(pb, generator.getTestbase().resolve(goldFile).toString());
|
||||
}
|
||||
|
||||
double runningTime = System.currentTimeMillis() - start;
|
||||
System.out.printf(" %8.0f |%n", runningTime);
|
||||
if (runningTime < TimeUnit.MINUTES.toMillis(MINUTES_TO_WAIT)) {
|
||||
++counter;
|
||||
}
|
||||
} while (counter < ProductionParams.numberOfTests.value());
|
||||
} catch (IOException | InterruptedException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static String getJavaPath() {
|
||||
String[] env = { "JDK_HOME", "JAVA_HOME", "BOOTDIR" };
|
||||
for (String name : env) {
|
||||
String path = System.getenv(name);
|
||||
if (path != null) {
|
||||
return path + "/bin/";
|
||||
System.out.printf(" %13s | %8s | %8s | %8s |%n", "start time", "count", "generat",
|
||||
"running");
|
||||
System.out.printf(" %13s | %8s | %8s | %8s |%n", "---", "---", "---", "---");
|
||||
List<TestsGenerator> generators = getTestGenerators();
|
||||
do {
|
||||
double start = System.currentTimeMillis();
|
||||
System.out.print("[" + LocalTime.now() + "] |");
|
||||
String name = "Test_" + counter;
|
||||
Pair<IRNode, IRNode> irTree = generateIRTree(name);
|
||||
System.out.printf(" %8d |", counter);
|
||||
double generationTime = System.currentTimeMillis() - start;
|
||||
System.out.printf(" %8.0f |", generationTime);
|
||||
start = System.currentTimeMillis();
|
||||
for (TestsGenerator generator : generators) {
|
||||
generator.accept(irTree.first, irTree.second);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private static int runProcess(ProcessBuilder pb, String name)
|
||||
throws IOException, InterruptedException {
|
||||
pb.redirectError(new File(name + ".err"));
|
||||
pb.redirectOutput(new File(name + ".out"));
|
||||
Process process = pb.start();
|
||||
if (process.waitFor(MINUTES_TO_WAIT, TimeUnit.MINUTES)) {
|
||||
try (FileWriter file = new FileWriter(name + ".exit")) {
|
||||
file.write(Integer.toString(process.exitValue()));
|
||||
double runningTime = System.currentTimeMillis() - start;
|
||||
System.out.printf(" %8.0f |%n", runningTime);
|
||||
if (runningTime < TimeUnit.MINUTES.toMillis(MINUTES_TO_WAIT)) {
|
||||
++counter;
|
||||
}
|
||||
return process.exitValue();
|
||||
} else {
|
||||
process.destroyForcibly();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
private static String printHierarchy() {
|
||||
return TypeList.getAll().stream()
|
||||
.filter(t -> t instanceof TypeKlass)
|
||||
.map(t -> typeDescription((TypeKlass) t))
|
||||
.collect(Collectors.joining("\n","CLASS HIERARCHY:\n", "\n"));
|
||||
}
|
||||
|
||||
private static String typeDescription(TypeKlass type) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
String parents = type.getParentsNames().stream().collect(Collectors.joining(","));
|
||||
result.append(type.isAbstract() ? "abstract " : "")
|
||||
.append(type.isFinal() ? "final " : "")
|
||||
.append(type.isInterface() ? "interface " : "class ")
|
||||
.append(type.getName())
|
||||
.append(parents.isEmpty() ? "" : ": " + parents);
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
static void ensureExisting(Path path) {
|
||||
if (Files.notExists(path)) {
|
||||
try {
|
||||
Files.createDirectories(path);
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
} while (counter < ProductionParams.numberOfTests.value());
|
||||
}
|
||||
}
|
||||
|
@ -23,54 +23,60 @@
|
||||
|
||||
package jdk.test.lib.jittester;
|
||||
|
||||
import jdk.test.lib.jittester.visitors.ByteCodeVisitor;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import jdk.test.lib.jittester.visitors.ByteCodeVisitor;
|
||||
|
||||
/**
|
||||
* Generates class files from bytecode
|
||||
* Generates class files from IRTree
|
||||
*/
|
||||
class ByteCodeGenerator implements BiFunction<IRNode, IRNode, String> {
|
||||
private final Path testbase = Paths.get(ProductionParams.testbaseDir.value(),
|
||||
"bytecode_tests");
|
||||
class ByteCodeGenerator extends TestsGenerator {
|
||||
private static final String DEFAULT_SUFFIX = "bytecode_tests";
|
||||
|
||||
public void writeJtregBytecodeRunner(String name) {
|
||||
try (FileWriter file = new FileWriter(testbase.resolve(name + ".java").toFile())) {
|
||||
file.write(Automatic.getJtregHeader(name, false));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
ByteCodeGenerator() {
|
||||
super(DEFAULT_SUFFIX);
|
||||
}
|
||||
|
||||
public String apply(IRNode mainClass, IRNode privateClasses) {
|
||||
Automatic.ensureExisting(testbase);
|
||||
ByteCodeGenerator(String suffix, Function<String, String[]> preRunActions, String jtDriverOptions) {
|
||||
super(suffix, preRunActions, jtDriverOptions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(IRNode mainClass, IRNode privateClasses) {
|
||||
generateClassFiles(mainClass, privateClasses);
|
||||
generateSeparateJtregHeader(mainClass);
|
||||
compilePrinter();
|
||||
generateGoldenOut(mainClass.getName());
|
||||
}
|
||||
|
||||
private void generateSeparateJtregHeader(IRNode mainClass) {
|
||||
String mainClassName = mainClass.getName();
|
||||
writeFile(generatorDir, mainClassName + ".java", getJtregHeader(mainClassName));
|
||||
}
|
||||
|
||||
private void generateClassFiles(IRNode mainClass, IRNode privateClasses) {
|
||||
String mainClassName = mainClass.getName();
|
||||
ensureExisting(generatorDir);
|
||||
try {
|
||||
ByteCodeVisitor vis = new ByteCodeVisitor();
|
||||
if (privateClasses != null) {
|
||||
privateClasses.accept(vis);
|
||||
}
|
||||
mainClass.accept(vis);
|
||||
|
||||
Path mainClassPath = testbase.resolve(mainClass.getName() + ".class");
|
||||
writeToClassFile(mainClassPath, vis.getByteCode(mainClass.getName()));
|
||||
writeFile(mainClassName + ".class", vis.getByteCode(mainClassName));
|
||||
if (privateClasses != null) {
|
||||
privateClasses.getChildren().forEach(c -> {
|
||||
String name = c.getName();
|
||||
Path classPath = testbase.resolve(name + ".class");
|
||||
writeToClassFile(classPath, vis.getByteCode(name));
|
||||
writeFile(name + ".class", vis.getByteCode(name));
|
||||
});
|
||||
}
|
||||
return mainClassPath.toString();
|
||||
} catch (Throwable t) {
|
||||
Path errFile = testbase.resolve(mainClass.getName() + ".err");
|
||||
Path errFile = generatorDir.resolve(mainClassName + ".err");
|
||||
try (PrintWriter pw = new PrintWriter(Files.newOutputStream(errFile,
|
||||
StandardOpenOption.CREATE_NEW))) {
|
||||
t.printStackTrace(pw);
|
||||
@ -78,16 +84,11 @@ class ByteCodeGenerator implements BiFunction<IRNode, IRNode, String> {
|
||||
t.printStackTrace();
|
||||
throw new Error("can't write error to error file " + errFile, e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Path getTestbase() {
|
||||
return testbase;
|
||||
}
|
||||
|
||||
private void writeToClassFile(Path path, byte[] bytecode) {
|
||||
try (FileOutputStream file = new FileOutputStream(path.toString())) {
|
||||
private void writeFile(String fileName, byte[] bytecode) {
|
||||
try (FileOutputStream file = new FileOutputStream(generatorDir.resolve(fileName).toFile())) {
|
||||
file.write(bytecode);
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
|
@ -23,48 +23,59 @@
|
||||
|
||||
package jdk.test.lib.jittester;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.function.Function;
|
||||
import jdk.test.lib.jittester.visitors.JavaCodeVisitor;
|
||||
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
/**
|
||||
* Generates class files from java source code
|
||||
* Generates java source code from IRTree
|
||||
*/
|
||||
class JavaCodeGenerator implements BiFunction<IRNode, IRNode, String> {
|
||||
private final Path testbase = Paths.get(ProductionParams.testbaseDir.value(), "java_tests");
|
||||
public class JavaCodeGenerator extends TestsGenerator {
|
||||
private static final String DEFAULT_SUFFIX = "java_tests";
|
||||
|
||||
private String generateJavaCode(IRNode mainClass, IRNode privateClasses) {
|
||||
JavaCodeGenerator() {
|
||||
this(DEFAULT_SUFFIX, JavaCodeGenerator::generatePrerunAction, "");
|
||||
}
|
||||
|
||||
JavaCodeGenerator(String prefix, Function<String, String[]> preRunActions, String jtDriverOptions) {
|
||||
super(prefix, preRunActions, jtDriverOptions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(IRNode mainClass, IRNode privateClasses) {
|
||||
String mainClassName = mainClass.getName();
|
||||
generateSources(mainClass, privateClasses);
|
||||
compilePrinter();
|
||||
compileJavaFile(mainClassName);
|
||||
generateGoldenOut(mainClassName);
|
||||
}
|
||||
|
||||
private void generateSources(IRNode mainClass, IRNode privateClasses) {
|
||||
String mainClassName = mainClass.getName();
|
||||
StringBuilder code = new StringBuilder();
|
||||
JavaCodeVisitor vis = new JavaCodeVisitor();
|
||||
|
||||
code.append(Automatic.getJtregHeader(mainClass.getName(), true));
|
||||
code.append(getJtregHeader(mainClassName));
|
||||
if (privateClasses != null) {
|
||||
code.append(privateClasses.accept(vis));
|
||||
}
|
||||
code.append(mainClass.accept(vis));
|
||||
|
||||
return code.toString();
|
||||
ensureExisting(generatorDir);
|
||||
writeFile(generatorDir, mainClassName + ".java", code.toString());
|
||||
}
|
||||
|
||||
public Path getTestbase() {
|
||||
return testbase;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String apply(IRNode mainClass, IRNode privateClasses) {
|
||||
String code = generateJavaCode(mainClass, privateClasses);
|
||||
Automatic.ensureExisting(testbase);
|
||||
Path fileName = testbase.resolve(mainClass.getName() + ".java");
|
||||
try (FileWriter file = new FileWriter(fileName.toFile())) {
|
||||
file.write(code);
|
||||
return fileName.toString();
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
private void compileJavaFile(String mainClassName) {
|
||||
String classPath = getRoot() + File.pathSeparator + generatorDir;
|
||||
ProcessBuilder pb = new ProcessBuilder(JAVAC, "-cp", classPath,
|
||||
generatorDir.resolve(mainClassName + ".java").toString());
|
||||
try {
|
||||
runProcess(pb, generatorDir.resolve(mainClassName).toString());
|
||||
} catch (IOException | InterruptedException e) {
|
||||
throw new Error("Can't compile sources ", e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private static String[] generatePrerunAction(String mainClassName) {
|
||||
return new String[] {"@compile " + mainClassName + ".java"};
|
||||
}
|
||||
}
|
||||
|
@ -68,8 +68,6 @@ public class ProductionParams {
|
||||
public static Option<Boolean> disableNestedBlocks = null;
|
||||
public static Option<Boolean> disableArrays = null;
|
||||
public static Option<Boolean> enableFinalizers = null;
|
||||
public static Option<Boolean> disableBytecodeGeneration = null;
|
||||
public static Option<Boolean> disableJavacodeGeneration = null;
|
||||
// workaraound: to reduce chance throwing ArrayIndexOutOfBoundsException
|
||||
public static Option<Integer> chanceExpressionIndex = null;
|
||||
public static Option<String> testbaseDir = null;
|
||||
@ -78,6 +76,8 @@ public class ProductionParams {
|
||||
public static Option<Long> specificSeed = null;
|
||||
public static Option<String> classesFile = null;
|
||||
public static Option<String> excludeMethodsFile = null;
|
||||
public static Option<String> generators = null;
|
||||
public static Option<String> generatorsFactories = null;
|
||||
|
||||
public static void register(OptionResolver optionResolver) {
|
||||
productionLimit = optionResolver.addIntegerOption('l', "production-limit", 100, "Limit on steps in the production of an expression");
|
||||
@ -120,8 +120,6 @@ public class ProductionParams {
|
||||
disableNestedBlocks = optionResolver.addBooleanOption("disable-nested-blocks", "Disable generation of nested blocks");
|
||||
disableArrays = optionResolver.addBooleanOption("disable-arrays", "Disable generation of arrays");
|
||||
enableFinalizers = optionResolver.addBooleanOption("enable-finalizers", "Enable finalizers (for stress testing)");
|
||||
disableBytecodeGeneration = optionResolver.addBooleanOption("disable-bytecode-generation", "Disable generation of bytecode output");
|
||||
disableJavacodeGeneration = optionResolver.addBooleanOption("disable-javacode-generation", "Disable generation of java source code output");
|
||||
chanceExpressionIndex = optionResolver.addIntegerOption("chance-expression-index", 0, "A non negative decimal integer used to restrict chane of generating expression in array index while creating or accessing by index");
|
||||
testbaseDir = optionResolver.addStringOption("testbase-dir", ".", "Testbase dir");
|
||||
numberOfTests = optionResolver.addIntegerOption('n', "number-of-tests", 0, "Number of test classes to generate");
|
||||
@ -129,5 +127,7 @@ public class ProductionParams {
|
||||
specificSeed = optionResolver.addLongOption('z', "specificSeed", 0L, "A seed to be set for specific test generation(regular seed still needed for initialization)");
|
||||
classesFile = optionResolver.addStringOption('f', "classes-file", "conf/classes.lst", "File to read classes from");
|
||||
excludeMethodsFile = optionResolver.addStringOption('r', "exclude-methods-file", "conf/exclude.methods.lst", "File to read excluded methods from");
|
||||
generators = optionResolver.addStringOption("generators", "", "Comma-separated list of generator names");
|
||||
generatorsFactories = optionResolver.addStringOption("generatorsFactories", "", "Comma-separated list of generators factories class names");
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 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 jdk.test.lib.jittester;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class TestGeneratorsFactory implements Function<String[], List<TestsGenerator>> {
|
||||
|
||||
@Override
|
||||
public List<TestsGenerator> apply(String[] input) {
|
||||
List<TestsGenerator> result = new ArrayList<>();
|
||||
for (String generatorName : input) {
|
||||
switch (generatorName) {
|
||||
case "JavaCode":
|
||||
result.add(new JavaCodeGenerator());
|
||||
break;
|
||||
case "ByteCode":
|
||||
result.add(new ByteCodeGenerator());
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown generator: " + generatorName);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,184 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 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 jdk.test.lib.jittester;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import jdk.test.lib.jittester.types.TypeKlass;
|
||||
import jdk.test.lib.jittester.utils.PseudoRandom;
|
||||
|
||||
public abstract class TestsGenerator implements BiConsumer<IRNode, IRNode> {
|
||||
protected static final String JAVA_BIN = getJavaPath();
|
||||
protected static final String JAVAC = Paths.get(JAVA_BIN, "javac").toString();
|
||||
protected static final String JAVA = Paths.get(JAVA_BIN, "java").toString();
|
||||
protected final Path generatorDir;
|
||||
protected final Function<String, String[]> preRunActions;
|
||||
protected final String jtDriverOptions;
|
||||
|
||||
protected TestsGenerator(String suffix) {
|
||||
this(suffix, s -> new String[0], "");
|
||||
}
|
||||
|
||||
protected TestsGenerator(String suffix, Function<String, String[]> preRunActions,
|
||||
String jtDriverOptions) {
|
||||
generatorDir = getRoot().resolve(suffix);
|
||||
this.preRunActions = preRunActions;
|
||||
this.jtDriverOptions = jtDriverOptions;
|
||||
}
|
||||
|
||||
protected void generateGoldenOut(String mainClassName) {
|
||||
String classPath = getRoot() + File.pathSeparator + generatorDir;
|
||||
ProcessBuilder pb = new ProcessBuilder(JAVA, "-Xint", "-Xverify", "-cp", classPath,
|
||||
mainClassName);
|
||||
String goldFile = mainClassName + ".gold";
|
||||
try {
|
||||
runProcess(pb, generatorDir.resolve(goldFile).toString());
|
||||
} catch (IOException | InterruptedException e) {
|
||||
throw new Error("Can't run generated test ", e);
|
||||
}
|
||||
}
|
||||
|
||||
protected static int runProcess(ProcessBuilder pb, String name)
|
||||
throws IOException, InterruptedException {
|
||||
pb.redirectError(new File(name + ".err"));
|
||||
pb.redirectOutput(new File(name + ".out"));
|
||||
Process process = pb.start();
|
||||
if (process.waitFor(Automatic.MINUTES_TO_WAIT, TimeUnit.MINUTES)) {
|
||||
try (FileWriter file = new FileWriter(name + ".exit")) {
|
||||
file.write(Integer.toString(process.exitValue()));
|
||||
}
|
||||
return process.exitValue();
|
||||
} else {
|
||||
process.destroyForcibly();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
protected static void compilePrinter() {
|
||||
Path root = getRoot();
|
||||
ProcessBuilder pbPrinter = new ProcessBuilder(JAVAC,
|
||||
root.resolve("jdk")
|
||||
.resolve("test")
|
||||
.resolve("lib")
|
||||
.resolve("jittester")
|
||||
.resolve("jtreg")
|
||||
.resolve("Printer.java")
|
||||
.toString());
|
||||
try {
|
||||
int exitCode = runProcess(pbPrinter, root.resolve("Printer").toString());
|
||||
if (exitCode != 0) {
|
||||
throw new Error("Printer compilation returned exit code " + exitCode);
|
||||
}
|
||||
} catch (IOException | InterruptedException e) {
|
||||
throw new Error("Can't compile printer", e);
|
||||
}
|
||||
}
|
||||
|
||||
protected static void ensureExisting(Path path) {
|
||||
if (Files.notExists(path)) {
|
||||
try {
|
||||
Files.createDirectories(path);
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected String getJtregHeader(String mainClassName) {
|
||||
String synopsis = "seed = '" + ProductionParams.seed.value() + "'"
|
||||
+ ", specificSeed = '" + PseudoRandom.getCurrentSeed() + "'";
|
||||
StringBuilder header = new StringBuilder();
|
||||
header.append("/*\n * @test\n * @summary ")
|
||||
.append(synopsis)
|
||||
.append(" \n * @library / ../\n");
|
||||
header.append(" * @run build jdk.test.lib.jittester.jtreg.JitTesterDriver "
|
||||
+ "jdk.test.lib.jittester.jtreg.Printer\n");
|
||||
for (String action : preRunActions.apply(mainClassName)) {
|
||||
header.append(" * ")
|
||||
.append(action)
|
||||
.append("\n");
|
||||
}
|
||||
header.append(" * @run driver jdk.test.lib.jittester.jtreg.JitTesterDriver ")
|
||||
.append(jtDriverOptions)
|
||||
.append(" ")
|
||||
.append(mainClassName)
|
||||
.append("\n */\n\n");
|
||||
if (ProductionParams.printHierarchy.value()) {
|
||||
header.append("/*\n")
|
||||
.append(printHierarchy())
|
||||
.append("*/\n");
|
||||
}
|
||||
return header.toString();
|
||||
}
|
||||
|
||||
protected static Path getRoot() {
|
||||
return Paths.get(ProductionParams.testbaseDir.value());
|
||||
}
|
||||
|
||||
protected static void writeFile(Path targetDir, String fileName, String content) {
|
||||
try (FileWriter file = new FileWriter(targetDir.resolve(fileName).toFile())) {
|
||||
file.write(content);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static String printHierarchy() {
|
||||
return TypeList.getAll()
|
||||
.stream()
|
||||
.filter(t -> t instanceof TypeKlass)
|
||||
.map(t -> typeDescription((TypeKlass) t))
|
||||
.collect(Collectors.joining("\n","CLASS HIERARCHY:\n", "\n"));
|
||||
}
|
||||
|
||||
private static String typeDescription(TypeKlass type) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
String parents = type.getParentsNames().stream().collect(Collectors.joining(","));
|
||||
result.append(type.isAbstract() ? "abstract " : "")
|
||||
.append(type.isFinal() ? "final " : "")
|
||||
.append(type.isInterface() ? "interface " : "class ")
|
||||
.append(type.getName())
|
||||
.append(parents.isEmpty() ? "" : ": " + parents);
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
private static String getJavaPath() {
|
||||
String[] env = { "JDK_HOME", "JAVA_HOME", "BOOTDIR" };
|
||||
for (String name : env) {
|
||||
String path = System.getenv(name);
|
||||
if (path != null) {
|
||||
return path + "/bin/";
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
@ -51,13 +51,13 @@ class LiteralFactory extends Factory<Literal> {
|
||||
} else if (resultType.equals(TypeList.LONG)) {
|
||||
literal = new Literal((long) (PseudoRandom.random() * Long.MAX_VALUE), TypeList.LONG);
|
||||
} else if (resultType.equals(TypeList.FLOAT)) {
|
||||
literal = new Literal(new Float(String.format(
|
||||
literal = new Literal(Float.valueOf(String.format(
|
||||
(Locale) null,
|
||||
"%." + ProductionParams.floatingPointPrecision.value() + "EF",
|
||||
(float) PseudoRandom.random() * Float.MAX_VALUE)),
|
||||
TypeList.FLOAT);
|
||||
} else if (resultType.equals(TypeList.DOUBLE)) {
|
||||
literal = new Literal(new Double(String.format(
|
||||
literal = new Literal(Double.valueOf(String.format(
|
||||
(Locale) null,
|
||||
"%." + 2 * ProductionParams.floatingPointPrecision.value() + "E",
|
||||
PseudoRandom.random() * Double.MAX_VALUE)),
|
||||
|
@ -40,40 +40,36 @@ import java.util.stream.Stream;
|
||||
public class JitTesterDriver {
|
||||
|
||||
public static void main(String[] args) {
|
||||
if (args.length != 1) {
|
||||
if (args.length < 1) {
|
||||
throw new IllegalArgumentException(
|
||||
"[TESTBUG]: wrong number of argument : " + args.length
|
||||
+ ". Expected 1 argument -- jit-tester test name.");
|
||||
+ ". Expected at least 1 argument -- jit-tester test name.");
|
||||
}
|
||||
OutputAnalyzer oa;
|
||||
try {
|
||||
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, args[0]);
|
||||
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, args);
|
||||
oa = new OutputAnalyzer(pb.start());
|
||||
} catch (Exception e) {
|
||||
throw new Error("Unexpected exception on test jvm start :" + e, e);
|
||||
}
|
||||
|
||||
String name = args[args.length - 1];
|
||||
Pattern splitOut = Pattern.compile("\\n"); // tests use \n only in stdout
|
||||
Pattern splitErr = Pattern.compile("\\r?\\n"); // can handle both \r\n and \n
|
||||
Path testDir = Paths.get(Utils.TEST_SRC);
|
||||
String goldOut = formatOutput(streamGoldFile(testDir, args[0], "out"), s -> true);
|
||||
String anlzOut = formatOutput(Arrays.stream(splitOut.split(oa.getStdout())), s -> true);
|
||||
String goldOut = formatOutput(streamGoldFile(testDir, name, "out"));
|
||||
String anlzOut = formatOutput(Arrays.stream(splitOut.split(oa.getStdout())));
|
||||
Asserts.assertEQ(anlzOut, goldOut, "Actual stdout isn't equal to golden one");
|
||||
// TODO: add a comment why we skip such lines
|
||||
Predicate<String> notStartWhitespaces = s -> !(s.startsWith("\t") || s.startsWith(" "));
|
||||
String goldErr = formatOutput(streamGoldFile(testDir, args[0], "err"), notStartWhitespaces);
|
||||
String anlzErr = formatOutput(Arrays.stream(splitErr.split(oa.getStderr())),
|
||||
notStartWhitespaces);
|
||||
String goldErr = formatOutput(streamGoldFile(testDir, name, "err"));
|
||||
String anlzErr = formatOutput(Arrays.stream(splitErr.split(oa.getStderr())));
|
||||
Asserts.assertEQ(anlzErr, goldErr, "Actual stderr isn't equal to golden one");
|
||||
|
||||
int exitValue = Integer.parseInt(streamGoldFile(testDir, args[0], "exit").findFirst().get());
|
||||
int exitValue = Integer.parseInt(streamGoldFile(testDir, name, "exit").findFirst().get());
|
||||
oa.shouldHaveExitValue(exitValue);
|
||||
}
|
||||
|
||||
private static String formatOutput(Stream<String> stream, Predicate<String> predicate) {
|
||||
String result = stream
|
||||
.filter(predicate)
|
||||
.collect(Collectors.joining(Utils.NEW_LINE));
|
||||
private static String formatOutput(Stream<String> stream) {
|
||||
String result = stream.collect(Collectors.joining(Utils.NEW_LINE));
|
||||
if (result.length() > 0) {
|
||||
result += Utils.NEW_LINE;
|
||||
}
|
||||
|
@ -23,9 +23,11 @@
|
||||
|
||||
package jdk.test.lib.jittester.utils;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import jdk.test.lib.jittester.BinaryOperator;
|
||||
import jdk.test.lib.jittester.Block;
|
||||
import jdk.test.lib.jittester.CatchBlock;
|
||||
@ -60,6 +62,8 @@ import jdk.test.lib.jittester.types.TypeArray;
|
||||
import jdk.test.lib.jittester.types.TypeKlass;
|
||||
|
||||
public class FixedTrees {
|
||||
private static final Literal EOL = new Literal("\n", TypeList.STRING);
|
||||
|
||||
public static FunctionDefinition printVariablesAsFunction(PrintVariables node) {
|
||||
TypeKlass owner = node.getOwner();
|
||||
|
||||
@ -72,7 +76,6 @@ public class FixedTrees {
|
||||
List<Symbol> vars = node.getVars();
|
||||
|
||||
TypeKlass printerKlass = new TypeKlass(Printer.class.getName());
|
||||
Literal EOL = new Literal("\n", TypeList.STRING);
|
||||
VariableInfo thisInfo = new VariableInfo("this", node.getOwner(),
|
||||
node.getOwner(), VariableInfo.LOCAL | VariableInfo.INITIALIZED);
|
||||
|
||||
@ -109,6 +112,7 @@ public class FixedTrees {
|
||||
FunctionInfo toStringInfo = new FunctionInfo("toString", owner, TypeList.STRING, 0L, FunctionInfo.PUBLIC, thisInfo);
|
||||
return new FunctionDefinition(toStringInfo, new ArrayList<>(), block, new Return(resultVar));
|
||||
}
|
||||
|
||||
public static FunctionDefinition generateMainOrExecuteMethod(TypeKlass owner, boolean isMain) {
|
||||
Nothing nothing = new Nothing();
|
||||
ArrayList<IRNode> testCallNodeContent = new ArrayList<>();
|
||||
@ -149,39 +153,50 @@ public class FixedTrees {
|
||||
List<Type> throwables = new ArrayList<>();
|
||||
throwables.add(throwableKlass);
|
||||
|
||||
VariableInfo exInfo = new VariableInfo("ex", owner, throwableKlass,
|
||||
VariableInfo.LOCAL | VariableInfo.INITIALIZED);
|
||||
FunctionInfo printStackTraceInfo = new FunctionInfo("printStackTrace", throwableKlass,
|
||||
TypeList.VOID, 0, FunctionInfo.PUBLIC, exInfo);
|
||||
Function printStackTraceCall = new Function(throwableKlass, printStackTraceInfo, null);
|
||||
printStackTraceCall.addChild(new LocalVariable(exInfo));
|
||||
ArrayList<IRNode> printStackTraceCallBlockContent = new ArrayList<>();
|
||||
// { ex.printStackTrace(); }
|
||||
printStackTraceCallBlockContent.add(new Statement(printStackTraceCall, true));
|
||||
|
||||
Block printStackTraceCallBlock = new Block(owner, TypeList.VOID, printStackTraceCallBlockContent, 3);
|
||||
List<CatchBlock> catchBlocks1 = new ArrayList<>();
|
||||
catchBlocks1.add(new CatchBlock(printStackTraceCallBlock, throwables, 3));
|
||||
List<CatchBlock> catchBlocks2 = new ArrayList<>();
|
||||
catchBlocks2.add(new CatchBlock(printStackTraceCallBlock, throwables, 3));
|
||||
List<CatchBlock> catchBlocks3 = new ArrayList<>();
|
||||
catchBlocks3.add(new CatchBlock(printStackTraceCallBlock, throwables, 2));
|
||||
|
||||
TryCatchBlock tryCatch1 = new TryCatchBlock(tryNode, nothing, catchBlocks1, 3);
|
||||
TypeKlass printStreamKlass = new TypeKlass("java.io.PrintStream");
|
||||
TypeKlass systemKlass = new TypeKlass("java.lang.System");
|
||||
FunctionInfo systemOutPrintInfo = new FunctionInfo("print", printStreamKlass,
|
||||
FunctionInfo printInfo = new FunctionInfo("print", printStreamKlass,
|
||||
TypeList.VOID, 0, FunctionInfo.PUBLIC,
|
||||
new VariableInfo("this", owner, printStreamKlass, VariableInfo.LOCAL | VariableInfo.INITIALIZED),
|
||||
new VariableInfo("t", owner, TypeList.OBJECT,
|
||||
VariableInfo.LOCAL | VariableInfo.INITIALIZED));
|
||||
TypeKlass systemKlass = new TypeKlass("java.lang.System");
|
||||
StaticMemberVariable systemErrVar = new StaticMemberVariable(owner,
|
||||
new VariableInfo("err", systemKlass, printStreamKlass, VariableInfo.STATIC | VariableInfo.PUBLIC));
|
||||
|
||||
LocalVariable exVar = new LocalVariable(
|
||||
new VariableInfo("ex", owner, throwableKlass, VariableInfo.LOCAL | VariableInfo.INITIALIZED));
|
||||
TypeKlass classKlass = new TypeKlass("java.lang.Class");
|
||||
FunctionInfo getClassInfo = new FunctionInfo("getClass", TypeList.OBJECT,
|
||||
classKlass, 0, FunctionInfo.PUBLIC,
|
||||
new VariableInfo("this", owner, TypeList.OBJECT, VariableInfo.LOCAL | VariableInfo.INITIALIZED));
|
||||
Function getClass = new Function(TypeList.OBJECT, getClassInfo, Arrays.asList(exVar));
|
||||
FunctionInfo getNameInfo = new FunctionInfo("getName", classKlass,
|
||||
TypeList.STRING, 0, FunctionInfo.PUBLIC,
|
||||
new VariableInfo("this", owner, TypeList.OBJECT, VariableInfo.LOCAL | VariableInfo.INITIALIZED));
|
||||
Function getName = new Function(classKlass, getNameInfo, Arrays.asList(getClass));
|
||||
ArrayList<IRNode> printExceptionBlockContent = new ArrayList<>();
|
||||
// { System.err.print(ex.getClass().getName()); System.err.print("\n"); }
|
||||
printExceptionBlockContent.add(new Statement(
|
||||
new Function(printStreamKlass, printInfo, Arrays.asList(systemErrVar, getName)), true));
|
||||
printExceptionBlockContent.add(new Statement(
|
||||
new Function(printStreamKlass, printInfo, Arrays.asList(systemErrVar, EOL)), true));
|
||||
|
||||
Block printExceptionBlock = new Block(owner, TypeList.VOID, printExceptionBlockContent, 3);
|
||||
List<CatchBlock> catchBlocks1 = new ArrayList<>();
|
||||
catchBlocks1.add(new CatchBlock(printExceptionBlock, throwables, 3));
|
||||
List<CatchBlock> catchBlocks2 = new ArrayList<>();
|
||||
catchBlocks2.add(new CatchBlock(printExceptionBlock, throwables, 3));
|
||||
List<CatchBlock> catchBlocks3 = new ArrayList<>();
|
||||
catchBlocks3.add(new CatchBlock(printExceptionBlock, throwables, 2));
|
||||
|
||||
TryCatchBlock tryCatch1 = new TryCatchBlock(tryNode, nothing, catchBlocks1, 3);
|
||||
List<IRNode> printArgs = new ArrayList<>();
|
||||
VariableInfo systemOutInfo = new VariableInfo("out", systemKlass, printStreamKlass,
|
||||
VariableInfo.STATIC | VariableInfo.PUBLIC);
|
||||
StaticMemberVariable systemOutVar = new StaticMemberVariable(owner, systemOutInfo);
|
||||
printArgs.add(systemOutVar);
|
||||
printArgs.add(tVar);
|
||||
Function print = new Function(printStreamKlass, systemOutPrintInfo, printArgs);
|
||||
Function print = new Function(printStreamKlass, printInfo, printArgs);
|
||||
ArrayList<IRNode> printBlockContent = new ArrayList<>();
|
||||
printBlockContent.add(new Statement(print, true));
|
||||
Block printBlock = new Block(owner, TypeList.VOID, printBlockContent, 3);
|
||||
|
@ -230,7 +230,7 @@ public class OptionResolver {
|
||||
|
||||
@Override
|
||||
public Long parseFromString(String arg) {
|
||||
return new Long(arg);
|
||||
return Long.valueOf(arg);
|
||||
}
|
||||
}
|
||||
|
||||
@ -242,7 +242,7 @@ public class OptionResolver {
|
||||
|
||||
@Override
|
||||
public Integer parseFromString(String arg) {
|
||||
return new Integer(arg);
|
||||
return Integer.valueOf(arg);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user