Merge
This commit is contained in:
commit
73a6885c23
@ -335,7 +335,19 @@ jprt.test.targets = \
|
||||
|
||||
# The default test/Makefile targets that should be run
|
||||
|
||||
# Example:
|
||||
# jprt.make.rule.test.targets=*-*-*-packtest
|
||||
#jprt.make.rule.test.targets=*-product-*-packtest
|
||||
|
||||
jprt.make.rule.test.targets = \
|
||||
${jprt.my.solaris.sparc}-*-c1-clienttest, \
|
||||
${jprt.my.solaris.i586}-*-c1-clienttest, \
|
||||
${jprt.my.linux.i586}-*-c1-clienttest, \
|
||||
${jprt.my.windows.i586}-*-c1-clienttest, \
|
||||
${jprt.my.solaris.sparc}-*-c2-servertest, \
|
||||
${jprt.my.solaris.sparcv9}-*-c2-servertest, \
|
||||
${jprt.my.solaris.i586}-*-c2-servertest, \
|
||||
${jprt.my.solaris.x64}-*-c2-servertest, \
|
||||
${jprt.my.linux.i586}-*-c2-servertest, \
|
||||
${jprt.my.linux.x64}-*-c2-servertest, \
|
||||
${jprt.my.windows.i586}-*-c2-servertest, \
|
||||
${jprt.my.windows.x64}-*-c2-servertest
|
||||
|
||||
|
@ -171,3 +171,9 @@ DEBUG_CFLAGS += $(DEBUG_CFLAGS/$(BUILDARCH))
|
||||
ifeq ($(DEBUG_CFLAGS/$(BUILDARCH)),)
|
||||
DEBUG_CFLAGS += -gstabs
|
||||
endif
|
||||
|
||||
# DEBUG_BINARIES overrides everything, use full -g debug information
|
||||
ifeq ($(DEBUG_BINARIES), true)
|
||||
DEBUG_CFLAGS = -g
|
||||
CFLAGS += $(DEBUG_CFLAGS)
|
||||
endif
|
||||
|
@ -41,10 +41,15 @@ LIBJSIG_MAPFILE = $(MAKEFILES_DIR)/mapfile-vers-jsig
|
||||
|
||||
LFLAGS_JSIG += -D_GNU_SOURCE -D_REENTRANT $(LDFLAGS_HASH_STYLE)
|
||||
|
||||
# DEBUG_BINARIES overrides everything, use full -g debug information
|
||||
ifeq ($(DEBUG_BINARIES), true)
|
||||
JSIG_DEBUG_CFLAGS = -g
|
||||
endif
|
||||
|
||||
$(LIBJSIG): $(JSIGSRCDIR)/jsig.c $(LIBJSIG_MAPFILE)
|
||||
@echo Making signal interposition lib...
|
||||
$(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) $(SHARED_FLAG) $(PICFLAG) \
|
||||
$(LFLAGS_JSIG) -o $@ $< -ldl
|
||||
$(LFLAGS_JSIG) $(JSIG_DEBUG_CFLAGS) -o $@ $< -ldl
|
||||
|
||||
install_jsig: $(LIBJSIG)
|
||||
@echo "Copying $(LIBJSIG) to $(DEST_JSIG)"
|
||||
|
@ -43,6 +43,11 @@ SAMAPFILE = $(SASRCDIR)/mapfile
|
||||
|
||||
DEST_SAPROC = $(JDK_LIBDIR)/$(LIBSAPROC)
|
||||
|
||||
# DEBUG_BINARIES overrides everything, use full -g debug information
|
||||
ifeq ($(DEBUG_BINARIES), true)
|
||||
SA_DEBUG_CFLAGS = -g
|
||||
endif
|
||||
|
||||
# if $(AGENT_DIR) does not exist, we don't build SA
|
||||
# also, we don't build SA on Itanium.
|
||||
|
||||
@ -67,6 +72,7 @@ $(LIBSAPROC): $(SASRCFILES) $(SAMAPFILE)
|
||||
-I$(BOOT_JAVA_HOME)/include/$(Platform_os_family) \
|
||||
$(SASRCFILES) \
|
||||
$(SA_LFLAGS) \
|
||||
$(SA_DEBUG_CFLAGS) \
|
||||
-o $@ \
|
||||
-lthread_db
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -378,7 +378,7 @@ void LIR_Assembler::emit_exception_handler() {
|
||||
compilation()->offsets()->set_value(CodeOffsets::Exceptions, code_offset());
|
||||
|
||||
|
||||
if (compilation()->has_exception_handlers() || JvmtiExport::can_post_exceptions()) {
|
||||
if (compilation()->has_exception_handlers() || compilation()->env()->jvmti_can_post_exceptions()) {
|
||||
__ call(Runtime1::entry_for(Runtime1::handle_exception_id), relocInfo::runtime_call_type);
|
||||
__ delayed()->nop();
|
||||
}
|
||||
|
@ -286,7 +286,7 @@ void C1_MacroAssembler::initialize_object(
|
||||
initialize_body(base, index);
|
||||
}
|
||||
|
||||
if (DTraceAllocProbes) {
|
||||
if (CURRENT_ENV->dtrace_alloc_probes()) {
|
||||
assert(obj == O0, "must be");
|
||||
call(CAST_FROM_FN_PTR(address, Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)),
|
||||
relocInfo::runtime_call_type);
|
||||
@ -355,7 +355,7 @@ void C1_MacroAssembler::allocate_array(
|
||||
sub(arr_size, hdr_size * wordSize, index); // compute index = number of words to clear
|
||||
initialize_body(base, index);
|
||||
|
||||
if (DTraceAllocProbes) {
|
||||
if (CURRENT_ENV->dtrace_alloc_probes()) {
|
||||
assert(obj == O0, "must be");
|
||||
call(CAST_FROM_FN_PTR(address, Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)),
|
||||
relocInfo::runtime_call_type);
|
||||
|
@ -1712,6 +1712,23 @@ static FloatRegister reg_to_DoubleFloatRegister_object(int register_encoding) {
|
||||
return as_DoubleFloatRegister(register_encoding);
|
||||
}
|
||||
|
||||
const bool Matcher::match_rule_supported(int opcode) {
|
||||
if (!has_match_rule(opcode))
|
||||
return false;
|
||||
|
||||
switch (opcode) {
|
||||
case Op_CountLeadingZerosI:
|
||||
case Op_CountLeadingZerosL:
|
||||
case Op_CountTrailingZerosI:
|
||||
case Op_CountTrailingZerosL:
|
||||
if (!UsePopCountInstruction)
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
return true; // Per default match rules are supported.
|
||||
}
|
||||
|
||||
int Matcher::regnum_to_fpu_offset(int regnum) {
|
||||
return regnum - 32; // The FP registers are in the second chunk
|
||||
}
|
||||
@ -1874,15 +1891,17 @@ RegMask Matcher::modL_proj_mask() {
|
||||
// The intptr_t operand types, defined by textual substitution.
|
||||
// (Cf. opto/type.hpp. This lets us avoid many, many other ifdefs.)
|
||||
#ifdef _LP64
|
||||
#define immX immL
|
||||
#define immX13 immL13
|
||||
#define iRegX iRegL
|
||||
#define g1RegX g1RegL
|
||||
#define immX immL
|
||||
#define immX13 immL13
|
||||
#define immX13m7 immL13m7
|
||||
#define iRegX iRegL
|
||||
#define g1RegX g1RegL
|
||||
#else
|
||||
#define immX immI
|
||||
#define immX13 immI13
|
||||
#define iRegX iRegI
|
||||
#define g1RegX g1RegI
|
||||
#define immX immI
|
||||
#define immX13 immI13
|
||||
#define immX13m7 immI13m7
|
||||
#define iRegX iRegI
|
||||
#define g1RegX g1RegI
|
||||
#endif
|
||||
|
||||
//----------ENCODING BLOCK-----------------------------------------------------
|
||||
@ -3437,6 +3456,16 @@ operand immI13() %{
|
||||
interface(CONST_INTER);
|
||||
%}
|
||||
|
||||
// Integer Immediate: 13-bit minus 7
|
||||
operand immI13m7() %{
|
||||
predicate((-4096 < n->get_int()) && ((n->get_int() + 7) <= 4095));
|
||||
match(ConI);
|
||||
op_cost(0);
|
||||
|
||||
format %{ %}
|
||||
interface(CONST_INTER);
|
||||
%}
|
||||
|
||||
// Unsigned (positive) Integer Immediate: 13-bit
|
||||
operand immU13() %{
|
||||
predicate((0 <= n->get_int()) && Assembler::is_simm13(n->get_int()));
|
||||
@ -3515,6 +3544,28 @@ operand immI_32_63() %{
|
||||
interface(CONST_INTER);
|
||||
%}
|
||||
|
||||
// Immediates for special shifts (sign extend)
|
||||
|
||||
// Integer Immediate: the value 16
|
||||
operand immI_16() %{
|
||||
predicate(n->get_int() == 16);
|
||||
match(ConI);
|
||||
op_cost(0);
|
||||
|
||||
format %{ %}
|
||||
interface(CONST_INTER);
|
||||
%}
|
||||
|
||||
// Integer Immediate: the value 24
|
||||
operand immI_24() %{
|
||||
predicate(n->get_int() == 24);
|
||||
match(ConI);
|
||||
op_cost(0);
|
||||
|
||||
format %{ %}
|
||||
interface(CONST_INTER);
|
||||
%}
|
||||
|
||||
// Integer Immediate: the value 255
|
||||
operand immI_255() %{
|
||||
predicate( n->get_int() == 255 );
|
||||
@ -3525,6 +3576,16 @@ operand immI_255() %{
|
||||
interface(CONST_INTER);
|
||||
%}
|
||||
|
||||
// Integer Immediate: the value 65535
|
||||
operand immI_65535() %{
|
||||
predicate(n->get_int() == 65535);
|
||||
match(ConI);
|
||||
op_cost(0);
|
||||
|
||||
format %{ %}
|
||||
interface(CONST_INTER);
|
||||
%}
|
||||
|
||||
// Long Immediate: the value FF
|
||||
operand immL_FF() %{
|
||||
predicate( n->get_long() == 0xFFL );
|
||||
@ -3630,6 +3691,16 @@ operand immL13() %{
|
||||
interface(CONST_INTER);
|
||||
%}
|
||||
|
||||
// Long Immediate: 13-bit minus 7
|
||||
operand immL13m7() %{
|
||||
predicate((-4096L < n->get_long()) && ((n->get_long() + 7L) <= 4095L));
|
||||
match(ConL);
|
||||
op_cost(0);
|
||||
|
||||
format %{ %}
|
||||
interface(CONST_INTER);
|
||||
%}
|
||||
|
||||
// Long Immediate: low 32-bit mask
|
||||
operand immL_32bits() %{
|
||||
predicate(n->get_long() == 0xFFFFFFFFL);
|
||||
@ -4067,7 +4138,7 @@ operand indirect(sp_ptr_RegP reg) %{
|
||||
%}
|
||||
%}
|
||||
|
||||
// Indirect with Offset
|
||||
// Indirect with simm13 Offset
|
||||
operand indOffset13(sp_ptr_RegP reg, immX13 offset) %{
|
||||
constraint(ALLOC_IN_RC(sp_ptr_reg));
|
||||
match(AddP reg offset);
|
||||
@ -4082,6 +4153,21 @@ operand indOffset13(sp_ptr_RegP reg, immX13 offset) %{
|
||||
%}
|
||||
%}
|
||||
|
||||
// Indirect with simm13 Offset minus 7
|
||||
operand indOffset13m7(sp_ptr_RegP reg, immX13m7 offset) %{
|
||||
constraint(ALLOC_IN_RC(sp_ptr_reg));
|
||||
match(AddP reg offset);
|
||||
|
||||
op_cost(100);
|
||||
format %{ "[$reg + $offset]" %}
|
||||
interface(MEMORY_INTER) %{
|
||||
base($reg);
|
||||
index(0x0);
|
||||
scale(0x0);
|
||||
disp($offset);
|
||||
%}
|
||||
%}
|
||||
|
||||
// Note: Intel has a swapped version also, like this:
|
||||
//operand indOffsetX(iRegI reg, immP offset) %{
|
||||
// constraint(ALLOC_IN_RC(int_reg));
|
||||
@ -5487,6 +5573,20 @@ instruct loadS(iRegI dst, memory mem) %{
|
||||
ins_pipe(iload_mask_mem);
|
||||
%}
|
||||
|
||||
// Load Short (16 bit signed) to Byte (8 bit signed)
|
||||
instruct loadS2B(iRegI dst, indOffset13m7 mem, immI_24 twentyfour) %{
|
||||
match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour));
|
||||
ins_cost(MEMORY_REF_COST);
|
||||
|
||||
size(4);
|
||||
|
||||
format %{ "LDSB $mem+1,$dst\t! short -> byte" %}
|
||||
ins_encode %{
|
||||
__ ldsb($mem$$Address, $dst$$Register, 1);
|
||||
%}
|
||||
ins_pipe(iload_mask_mem);
|
||||
%}
|
||||
|
||||
// Load Short (16bit signed) into a Long Register
|
||||
instruct loadS2L(iRegL dst, memory mem) %{
|
||||
match(Set dst (ConvI2L (LoadS mem)));
|
||||
@ -5513,6 +5613,19 @@ instruct loadUS(iRegI dst, memory mem) %{
|
||||
ins_pipe(iload_mask_mem);
|
||||
%}
|
||||
|
||||
// Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed)
|
||||
instruct loadUS2B(iRegI dst, indOffset13m7 mem, immI_24 twentyfour) %{
|
||||
match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour));
|
||||
ins_cost(MEMORY_REF_COST);
|
||||
|
||||
size(4);
|
||||
format %{ "LDSB $mem+1,$dst\t! ushort -> byte" %}
|
||||
ins_encode %{
|
||||
__ ldsb($mem$$Address, $dst$$Register, 1);
|
||||
%}
|
||||
ins_pipe(iload_mask_mem);
|
||||
%}
|
||||
|
||||
// Load Unsigned Short/Char (16bit UNsigned) into a Long Register
|
||||
instruct loadUS2L(iRegL dst, memory mem) %{
|
||||
match(Set dst (ConvI2L (LoadUS mem)));
|
||||
@ -5539,6 +5652,62 @@ instruct loadI(iRegI dst, memory mem) %{
|
||||
ins_pipe(iload_mem);
|
||||
%}
|
||||
|
||||
// Load Integer to Byte (8 bit signed)
|
||||
instruct loadI2B(iRegI dst, indOffset13m7 mem, immI_24 twentyfour) %{
|
||||
match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour));
|
||||
ins_cost(MEMORY_REF_COST);
|
||||
|
||||
size(4);
|
||||
|
||||
format %{ "LDSB $mem+3,$dst\t! int -> byte" %}
|
||||
ins_encode %{
|
||||
__ ldsb($mem$$Address, $dst$$Register, 3);
|
||||
%}
|
||||
ins_pipe(iload_mask_mem);
|
||||
%}
|
||||
|
||||
// Load Integer to Unsigned Byte (8 bit UNsigned)
|
||||
instruct loadI2UB(iRegI dst, indOffset13m7 mem, immI_255 mask) %{
|
||||
match(Set dst (AndI (LoadI mem) mask));
|
||||
ins_cost(MEMORY_REF_COST);
|
||||
|
||||
size(4);
|
||||
|
||||
format %{ "LDUB $mem+3,$dst\t! int -> ubyte" %}
|
||||
ins_encode %{
|
||||
__ ldub($mem$$Address, $dst$$Register, 3);
|
||||
%}
|
||||
ins_pipe(iload_mask_mem);
|
||||
%}
|
||||
|
||||
// Load Integer to Short (16 bit signed)
|
||||
instruct loadI2S(iRegI dst, indOffset13m7 mem, immI_16 sixteen) %{
|
||||
match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen));
|
||||
ins_cost(MEMORY_REF_COST);
|
||||
|
||||
size(4);
|
||||
|
||||
format %{ "LDSH $mem+2,$dst\t! int -> short" %}
|
||||
ins_encode %{
|
||||
__ ldsh($mem$$Address, $dst$$Register, 2);
|
||||
%}
|
||||
ins_pipe(iload_mask_mem);
|
||||
%}
|
||||
|
||||
// Load Integer to Unsigned Short (16 bit UNsigned)
|
||||
instruct loadI2US(iRegI dst, indOffset13m7 mem, immI_65535 mask) %{
|
||||
match(Set dst (AndI (LoadI mem) mask));
|
||||
ins_cost(MEMORY_REF_COST);
|
||||
|
||||
size(4);
|
||||
|
||||
format %{ "LDUH $mem+2,$dst\t! int -> ushort/char" %}
|
||||
ins_encode %{
|
||||
__ lduh($mem$$Address, $dst$$Register, 2);
|
||||
%}
|
||||
ins_pipe(iload_mask_mem);
|
||||
%}
|
||||
|
||||
// Load Integer into a Long Register
|
||||
instruct loadI2L(iRegL dst, memory mem) %{
|
||||
match(Set dst (ConvI2L (LoadI mem)));
|
||||
@ -9188,6 +9357,145 @@ instruct array_equals(o0RegP ary1, o1RegP ary2, g3RegP tmp1, g4RegP tmp2, notemp
|
||||
ins_pipe(long_memory_op);
|
||||
%}
|
||||
|
||||
|
||||
//---------- Zeros Count Instructions ------------------------------------------
|
||||
|
||||
instruct countLeadingZerosI(iRegI dst, iRegI src, iRegI tmp, flagsReg cr) %{
|
||||
predicate(UsePopCountInstruction); // See Matcher::match_rule_supported
|
||||
match(Set dst (CountLeadingZerosI src));
|
||||
effect(TEMP dst, TEMP tmp, KILL cr);
|
||||
|
||||
// x |= (x >> 1);
|
||||
// x |= (x >> 2);
|
||||
// x |= (x >> 4);
|
||||
// x |= (x >> 8);
|
||||
// x |= (x >> 16);
|
||||
// return (WORDBITS - popc(x));
|
||||
format %{ "SRL $src,1,$dst\t! count leading zeros (int)\n\t"
|
||||
"OR $src,$tmp,$dst\n\t"
|
||||
"SRL $dst,2,$tmp\n\t"
|
||||
"OR $dst,$tmp,$dst\n\t"
|
||||
"SRL $dst,4,$tmp\n\t"
|
||||
"OR $dst,$tmp,$dst\n\t"
|
||||
"SRL $dst,8,$tmp\n\t"
|
||||
"OR $dst,$tmp,$dst\n\t"
|
||||
"SRL $dst,16,$tmp\n\t"
|
||||
"OR $dst,$tmp,$dst\n\t"
|
||||
"POPC $dst,$dst\n\t"
|
||||
"MOV 32,$tmp\n\t"
|
||||
"SUB $tmp,$dst,$dst" %}
|
||||
ins_encode %{
|
||||
Register Rdst = $dst$$Register;
|
||||
Register Rsrc = $src$$Register;
|
||||
Register Rtmp = $tmp$$Register;
|
||||
__ srl(Rsrc, 1, Rtmp);
|
||||
__ or3(Rsrc, Rtmp, Rdst);
|
||||
__ srl(Rdst, 2, Rtmp);
|
||||
__ or3(Rdst, Rtmp, Rdst);
|
||||
__ srl(Rdst, 4, Rtmp);
|
||||
__ or3(Rdst, Rtmp, Rdst);
|
||||
__ srl(Rdst, 8, Rtmp);
|
||||
__ or3(Rdst, Rtmp, Rdst);
|
||||
__ srl(Rdst, 16, Rtmp);
|
||||
__ or3(Rdst, Rtmp, Rdst);
|
||||
__ popc(Rdst, Rdst);
|
||||
__ mov(BitsPerInt, Rtmp);
|
||||
__ sub(Rtmp, Rdst, Rdst);
|
||||
%}
|
||||
ins_pipe(ialu_reg);
|
||||
%}
|
||||
|
||||
instruct countLeadingZerosL(iRegI dst, iRegL src, iRegL tmp, flagsReg cr) %{
|
||||
predicate(UsePopCountInstruction); // See Matcher::match_rule_supported
|
||||
match(Set dst (CountLeadingZerosL src));
|
||||
effect(TEMP dst, TEMP tmp, KILL cr);
|
||||
|
||||
// x |= (x >> 1);
|
||||
// x |= (x >> 2);
|
||||
// x |= (x >> 4);
|
||||
// x |= (x >> 8);
|
||||
// x |= (x >> 16);
|
||||
// x |= (x >> 32);
|
||||
// return (WORDBITS - popc(x));
|
||||
format %{ "SRLX $src,1,$dst\t! count leading zeros (long)\n\t"
|
||||
"OR $src,$tmp,$dst\n\t"
|
||||
"SRLX $dst,2,$tmp\n\t"
|
||||
"OR $dst,$tmp,$dst\n\t"
|
||||
"SRLX $dst,4,$tmp\n\t"
|
||||
"OR $dst,$tmp,$dst\n\t"
|
||||
"SRLX $dst,8,$tmp\n\t"
|
||||
"OR $dst,$tmp,$dst\n\t"
|
||||
"SRLX $dst,16,$tmp\n\t"
|
||||
"OR $dst,$tmp,$dst\n\t"
|
||||
"SRLX $dst,32,$tmp\n\t"
|
||||
"OR $dst,$tmp,$dst\n\t"
|
||||
"POPC $dst,$dst\n\t"
|
||||
"MOV 64,$tmp\n\t"
|
||||
"SUB $tmp,$dst,$dst" %}
|
||||
ins_encode %{
|
||||
Register Rdst = $dst$$Register;
|
||||
Register Rsrc = $src$$Register;
|
||||
Register Rtmp = $tmp$$Register;
|
||||
__ srlx(Rsrc, 1, Rtmp);
|
||||
__ or3(Rsrc, Rtmp, Rdst);
|
||||
__ srlx(Rdst, 2, Rtmp);
|
||||
__ or3(Rdst, Rtmp, Rdst);
|
||||
__ srlx(Rdst, 4, Rtmp);
|
||||
__ or3(Rdst, Rtmp, Rdst);
|
||||
__ srlx(Rdst, 8, Rtmp);
|
||||
__ or3(Rdst, Rtmp, Rdst);
|
||||
__ srlx(Rdst, 16, Rtmp);
|
||||
__ or3(Rdst, Rtmp, Rdst);
|
||||
__ srlx(Rdst, 32, Rtmp);
|
||||
__ or3(Rdst, Rtmp, Rdst);
|
||||
__ popc(Rdst, Rdst);
|
||||
__ mov(BitsPerLong, Rtmp);
|
||||
__ sub(Rtmp, Rdst, Rdst);
|
||||
%}
|
||||
ins_pipe(ialu_reg);
|
||||
%}
|
||||
|
||||
instruct countTrailingZerosI(iRegI dst, iRegI src, flagsReg cr) %{
|
||||
predicate(UsePopCountInstruction); // See Matcher::match_rule_supported
|
||||
match(Set dst (CountTrailingZerosI src));
|
||||
effect(TEMP dst, KILL cr);
|
||||
|
||||
// return popc(~x & (x - 1));
|
||||
format %{ "SUB $src,1,$dst\t! count trailing zeros (int)\n\t"
|
||||
"ANDN $dst,$src,$dst\n\t"
|
||||
"SRL $dst,R_G0,$dst\n\t"
|
||||
"POPC $dst,$dst" %}
|
||||
ins_encode %{
|
||||
Register Rdst = $dst$$Register;
|
||||
Register Rsrc = $src$$Register;
|
||||
__ sub(Rsrc, 1, Rdst);
|
||||
__ andn(Rdst, Rsrc, Rdst);
|
||||
__ srl(Rdst, G0, Rdst);
|
||||
__ popc(Rdst, Rdst);
|
||||
%}
|
||||
ins_pipe(ialu_reg);
|
||||
%}
|
||||
|
||||
instruct countTrailingZerosL(iRegI dst, iRegL src, flagsReg cr) %{
|
||||
predicate(UsePopCountInstruction); // See Matcher::match_rule_supported
|
||||
match(Set dst (CountTrailingZerosL src));
|
||||
effect(TEMP dst, KILL cr);
|
||||
|
||||
// return popc(~x & (x - 1));
|
||||
format %{ "SUB $src,1,$dst\t! count trailing zeros (long)\n\t"
|
||||
"ANDN $dst,$src,$dst\n\t"
|
||||
"POPC $dst,$dst" %}
|
||||
ins_encode %{
|
||||
Register Rdst = $dst$$Register;
|
||||
Register Rsrc = $src$$Register;
|
||||
__ sub(Rsrc, 1, Rdst);
|
||||
__ andn(Rdst, Rsrc, Rdst);
|
||||
__ popc(Rdst, Rdst);
|
||||
%}
|
||||
ins_pipe(ialu_reg);
|
||||
%}
|
||||
|
||||
|
||||
//---------- Population Count Instructions -------------------------------------
|
||||
|
||||
instruct popCountI(iRegI dst, iRegI src) %{
|
||||
|
@ -952,6 +952,21 @@ void Assembler::andpd(XMMRegister dst, Address src) {
|
||||
emit_operand(dst, src);
|
||||
}
|
||||
|
||||
void Assembler::bsfl(Register dst, Register src) {
|
||||
int encode = prefix_and_encode(dst->encoding(), src->encoding());
|
||||
emit_byte(0x0F);
|
||||
emit_byte(0xBC);
|
||||
emit_byte(0xC0 | encode);
|
||||
}
|
||||
|
||||
void Assembler::bsrl(Register dst, Register src) {
|
||||
assert(!VM_Version::supports_lzcnt(), "encoding is treated as LZCNT");
|
||||
int encode = prefix_and_encode(dst->encoding(), src->encoding());
|
||||
emit_byte(0x0F);
|
||||
emit_byte(0xBD);
|
||||
emit_byte(0xC0 | encode);
|
||||
}
|
||||
|
||||
void Assembler::bswapl(Register reg) { // bswap
|
||||
int encode = prefix_and_encode(reg->encoding());
|
||||
emit_byte(0x0F);
|
||||
@ -1438,6 +1453,15 @@ void Assembler::lock() {
|
||||
}
|
||||
}
|
||||
|
||||
void Assembler::lzcntl(Register dst, Register src) {
|
||||
assert(VM_Version::supports_lzcnt(), "encoding is treated as BSR");
|
||||
emit_byte(0xF3);
|
||||
int encode = prefix_and_encode(dst->encoding(), src->encoding());
|
||||
emit_byte(0x0F);
|
||||
emit_byte(0xBD);
|
||||
emit_byte(0xC0 | encode);
|
||||
}
|
||||
|
||||
// Emit mfence instruction
|
||||
void Assembler::mfence() {
|
||||
NOT_LP64(assert(VM_Version::supports_sse2(), "unsupported");)
|
||||
@ -3688,6 +3712,21 @@ void Assembler::andq(Register dst, Register src) {
|
||||
emit_arith(0x23, 0xC0, dst, src);
|
||||
}
|
||||
|
||||
void Assembler::bsfq(Register dst, Register src) {
|
||||
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
|
||||
emit_byte(0x0F);
|
||||
emit_byte(0xBC);
|
||||
emit_byte(0xC0 | encode);
|
||||
}
|
||||
|
||||
void Assembler::bsrq(Register dst, Register src) {
|
||||
assert(!VM_Version::supports_lzcnt(), "encoding is treated as LZCNT");
|
||||
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
|
||||
emit_byte(0x0F);
|
||||
emit_byte(0xBD);
|
||||
emit_byte(0xC0 | encode);
|
||||
}
|
||||
|
||||
void Assembler::bswapq(Register reg) {
|
||||
int encode = prefixq_and_encode(reg->encoding());
|
||||
emit_byte(0x0F);
|
||||
@ -3941,6 +3980,15 @@ void Assembler::cmp_narrow_oop(Address src1, int32_t imm32, RelocationHolder con
|
||||
emit_data((int)imm32, rspec, narrow_oop_operand);
|
||||
}
|
||||
|
||||
void Assembler::lzcntq(Register dst, Register src) {
|
||||
assert(VM_Version::supports_lzcnt(), "encoding is treated as BSR");
|
||||
emit_byte(0xF3);
|
||||
int encode = prefixq_and_encode(dst->encoding(), src->encoding());
|
||||
emit_byte(0x0F);
|
||||
emit_byte(0xBD);
|
||||
emit_byte(0xC0 | encode);
|
||||
}
|
||||
|
||||
void Assembler::movdq(XMMRegister dst, Register src) {
|
||||
// table D-1 says MMX/SSE2
|
||||
NOT_LP64(assert(VM_Version::supports_sse2() || VM_Version::supports_mmx(), ""));
|
||||
|
@ -757,6 +757,14 @@ private:
|
||||
void andpd(XMMRegister dst, Address src);
|
||||
void andpd(XMMRegister dst, XMMRegister src);
|
||||
|
||||
void bsfl(Register dst, Register src);
|
||||
void bsrl(Register dst, Register src);
|
||||
|
||||
#ifdef _LP64
|
||||
void bsfq(Register dst, Register src);
|
||||
void bsrq(Register dst, Register src);
|
||||
#endif
|
||||
|
||||
void bswapl(Register reg);
|
||||
|
||||
void bswapq(Register reg);
|
||||
@ -1061,6 +1069,12 @@ private:
|
||||
|
||||
void lock();
|
||||
|
||||
void lzcntl(Register dst, Register src);
|
||||
|
||||
#ifdef _LP64
|
||||
void lzcntq(Register dst, Register src);
|
||||
#endif
|
||||
|
||||
enum Membar_mask_bits {
|
||||
StoreStore = 1 << 3,
|
||||
LoadStore = 1 << 2,
|
||||
|
@ -439,7 +439,7 @@ void LIR_Assembler::emit_exception_handler() {
|
||||
|
||||
// if the method does not have an exception handler, then there is
|
||||
// no reason to search for one
|
||||
if (compilation()->has_exception_handlers() || JvmtiExport::can_post_exceptions()) {
|
||||
if (compilation()->has_exception_handlers() || compilation()->env()->jvmti_can_post_exceptions()) {
|
||||
// the exception oop and pc are in rax, and rdx
|
||||
// no other registers need to be preserved, so invalidate them
|
||||
__ invalidate_registers(false, true, true, false, true, true);
|
||||
|
@ -258,7 +258,7 @@ void C1_MacroAssembler::initialize_object(Register obj, Register klass, Register
|
||||
}
|
||||
}
|
||||
|
||||
if (DTraceAllocProbes) {
|
||||
if (CURRENT_ENV->dtrace_alloc_probes()) {
|
||||
assert(obj == rax, "must be");
|
||||
call(RuntimeAddress(Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)));
|
||||
}
|
||||
@ -291,7 +291,7 @@ void C1_MacroAssembler::allocate_array(Register obj, Register len, Register t1,
|
||||
const Register len_zero = len;
|
||||
initialize_body(obj, arr_size, header_size * BytesPerWord, len_zero);
|
||||
|
||||
if (DTraceAllocProbes) {
|
||||
if (CURRENT_ENV->dtrace_alloc_probes()) {
|
||||
assert(obj == rax, "must be");
|
||||
call(RuntimeAddress(Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)));
|
||||
}
|
||||
|
@ -284,7 +284,7 @@ void VM_Version::get_processor_features() {
|
||||
}
|
||||
|
||||
char buf[256];
|
||||
jio_snprintf(buf, sizeof(buf), "(%u cores per cpu, %u threads per core) family %d model %d stepping %d%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
|
||||
jio_snprintf(buf, sizeof(buf), "(%u cores per cpu, %u threads per core) family %d model %d stepping %d%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
|
||||
cores_per_cpu(), threads_per_core(),
|
||||
cpu_family(), _model, _stepping,
|
||||
(supports_cmov() ? ", cmov" : ""),
|
||||
@ -301,6 +301,7 @@ void VM_Version::get_processor_features() {
|
||||
(supports_mmx_ext() ? ", mmxext" : ""),
|
||||
(supports_3dnow() ? ", 3dnow" : ""),
|
||||
(supports_3dnow2() ? ", 3dnowext" : ""),
|
||||
(supports_lzcnt() ? ", lzcnt": ""),
|
||||
(supports_sse4a() ? ", sse4a": ""),
|
||||
(supports_ht() ? ", ht": ""));
|
||||
_features_str = strdup(buf);
|
||||
@ -364,6 +365,13 @@ void VM_Version::get_processor_features() {
|
||||
UseXmmI2D = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Use count leading zeros count instruction if available.
|
||||
if (supports_lzcnt()) {
|
||||
if (FLAG_IS_DEFAULT(UseCountLeadingZerosInstruction)) {
|
||||
UseCountLeadingZerosInstruction = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( is_intel() ) { // Intel cpus specific settings
|
||||
|
@ -120,7 +120,7 @@ public:
|
||||
uint32_t LahfSahf : 1,
|
||||
CmpLegacy : 1,
|
||||
: 4,
|
||||
abm : 1,
|
||||
lzcnt : 1,
|
||||
sse4a : 1,
|
||||
misalignsse : 1,
|
||||
prefetchw : 1,
|
||||
@ -182,7 +182,8 @@ protected:
|
||||
CPU_SSE4A = (1 << 10),
|
||||
CPU_SSE4_1 = (1 << 11),
|
||||
CPU_SSE4_2 = (1 << 12),
|
||||
CPU_POPCNT = (1 << 13)
|
||||
CPU_POPCNT = (1 << 13),
|
||||
CPU_LZCNT = (1 << 14)
|
||||
} cpuFeatureFlags;
|
||||
|
||||
// cpuid information block. All info derived from executing cpuid with
|
||||
@ -277,8 +278,6 @@ protected:
|
||||
if (_cpuid_info.std_cpuid1_edx.bits.mmx != 0 || is_amd() &&
|
||||
_cpuid_info.ext_cpuid1_edx.bits.mmx != 0)
|
||||
result |= CPU_MMX;
|
||||
if (is_amd() && _cpuid_info.ext_cpuid1_edx.bits.tdnow != 0)
|
||||
result |= CPU_3DNOW;
|
||||
if (_cpuid_info.std_cpuid1_edx.bits.sse != 0)
|
||||
result |= CPU_SSE;
|
||||
if (_cpuid_info.std_cpuid1_edx.bits.sse2 != 0)
|
||||
@ -287,14 +286,23 @@ protected:
|
||||
result |= CPU_SSE3;
|
||||
if (_cpuid_info.std_cpuid1_ecx.bits.ssse3 != 0)
|
||||
result |= CPU_SSSE3;
|
||||
if (is_amd() && _cpuid_info.ext_cpuid1_ecx.bits.sse4a != 0)
|
||||
result |= CPU_SSE4A;
|
||||
if (_cpuid_info.std_cpuid1_ecx.bits.sse4_1 != 0)
|
||||
result |= CPU_SSE4_1;
|
||||
if (_cpuid_info.std_cpuid1_ecx.bits.sse4_2 != 0)
|
||||
result |= CPU_SSE4_2;
|
||||
if (_cpuid_info.std_cpuid1_ecx.bits.popcnt != 0)
|
||||
result |= CPU_POPCNT;
|
||||
|
||||
// AMD features.
|
||||
if (is_amd()) {
|
||||
if (_cpuid_info.ext_cpuid1_edx.bits.tdnow != 0)
|
||||
result |= CPU_3DNOW;
|
||||
if (_cpuid_info.ext_cpuid1_ecx.bits.lzcnt != 0)
|
||||
result |= CPU_LZCNT;
|
||||
if (_cpuid_info.ext_cpuid1_ecx.bits.sse4a != 0)
|
||||
result |= CPU_SSE4A;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -391,6 +399,7 @@ public:
|
||||
static bool supports_3dnow() { return (_cpuFeatures & CPU_3DNOW) != 0; }
|
||||
static bool supports_mmx_ext() { return is_amd() && _cpuid_info.ext_cpuid1_edx.bits.mmx_amd != 0; }
|
||||
static bool supports_3dnow2() { return is_amd() && _cpuid_info.ext_cpuid1_edx.bits.tdnow2 != 0; }
|
||||
static bool supports_lzcnt() { return (_cpuFeatures & CPU_LZCNT) != 0; }
|
||||
static bool supports_sse4a() { return (_cpuFeatures & CPU_SSE4A) != 0; }
|
||||
|
||||
static bool supports_compare_and_exchange() { return true; }
|
||||
|
@ -1281,6 +1281,13 @@ static void emit_float_constant(CodeBuffer& cbuf, float x) {
|
||||
}
|
||||
|
||||
|
||||
const bool Matcher::match_rule_supported(int opcode) {
|
||||
if (!has_match_rule(opcode))
|
||||
return false;
|
||||
|
||||
return true; // Per default match rules are supported.
|
||||
}
|
||||
|
||||
int Matcher::regnum_to_fpu_offset(int regnum) {
|
||||
return regnum - 32; // The FP registers are in the second chunk
|
||||
}
|
||||
@ -5233,6 +5240,15 @@ operand immI_255() %{
|
||||
interface(CONST_INTER);
|
||||
%}
|
||||
|
||||
// Constant for short-wide masking
|
||||
operand immI_65535() %{
|
||||
predicate(n->get_int() == 65535);
|
||||
match(ConI);
|
||||
|
||||
format %{ %}
|
||||
interface(CONST_INTER);
|
||||
%}
|
||||
|
||||
// Register Operands
|
||||
// Integer Register
|
||||
operand eRegI() %{
|
||||
@ -6644,6 +6660,153 @@ instruct bytes_reverse_long(eRegL dst) %{
|
||||
%}
|
||||
|
||||
|
||||
//---------- Zeros Count Instructions ------------------------------------------
|
||||
|
||||
instruct countLeadingZerosI(eRegI dst, eRegI src, eFlagsReg cr) %{
|
||||
predicate(UseCountLeadingZerosInstruction);
|
||||
match(Set dst (CountLeadingZerosI src));
|
||||
effect(KILL cr);
|
||||
|
||||
format %{ "LZCNT $dst, $src\t# count leading zeros (int)" %}
|
||||
ins_encode %{
|
||||
__ lzcntl($dst$$Register, $src$$Register);
|
||||
%}
|
||||
ins_pipe(ialu_reg);
|
||||
%}
|
||||
|
||||
instruct countLeadingZerosI_bsr(eRegI dst, eRegI src, eFlagsReg cr) %{
|
||||
predicate(!UseCountLeadingZerosInstruction);
|
||||
match(Set dst (CountLeadingZerosI src));
|
||||
effect(KILL cr);
|
||||
|
||||
format %{ "BSR $dst, $src\t# count leading zeros (int)\n\t"
|
||||
"JNZ skip\n\t"
|
||||
"MOV $dst, -1\n"
|
||||
"skip:\n\t"
|
||||
"NEG $dst\n\t"
|
||||
"ADD $dst, 31" %}
|
||||
ins_encode %{
|
||||
Register Rdst = $dst$$Register;
|
||||
Register Rsrc = $src$$Register;
|
||||
Label skip;
|
||||
__ bsrl(Rdst, Rsrc);
|
||||
__ jccb(Assembler::notZero, skip);
|
||||
__ movl(Rdst, -1);
|
||||
__ bind(skip);
|
||||
__ negl(Rdst);
|
||||
__ addl(Rdst, BitsPerInt - 1);
|
||||
%}
|
||||
ins_pipe(ialu_reg);
|
||||
%}
|
||||
|
||||
instruct countLeadingZerosL(eRegI dst, eRegL src, eFlagsReg cr) %{
|
||||
predicate(UseCountLeadingZerosInstruction);
|
||||
match(Set dst (CountLeadingZerosL src));
|
||||
effect(TEMP dst, KILL cr);
|
||||
|
||||
format %{ "LZCNT $dst, $src.hi\t# count leading zeros (long)\n\t"
|
||||
"JNC done\n\t"
|
||||
"LZCNT $dst, $src.lo\n\t"
|
||||
"ADD $dst, 32\n"
|
||||
"done:" %}
|
||||
ins_encode %{
|
||||
Register Rdst = $dst$$Register;
|
||||
Register Rsrc = $src$$Register;
|
||||
Label done;
|
||||
__ lzcntl(Rdst, HIGH_FROM_LOW(Rsrc));
|
||||
__ jccb(Assembler::carryClear, done);
|
||||
__ lzcntl(Rdst, Rsrc);
|
||||
__ addl(Rdst, BitsPerInt);
|
||||
__ bind(done);
|
||||
%}
|
||||
ins_pipe(ialu_reg);
|
||||
%}
|
||||
|
||||
instruct countLeadingZerosL_bsr(eRegI dst, eRegL src, eFlagsReg cr) %{
|
||||
predicate(!UseCountLeadingZerosInstruction);
|
||||
match(Set dst (CountLeadingZerosL src));
|
||||
effect(TEMP dst, KILL cr);
|
||||
|
||||
format %{ "BSR $dst, $src.hi\t# count leading zeros (long)\n\t"
|
||||
"JZ msw_is_zero\n\t"
|
||||
"ADD $dst, 32\n\t"
|
||||
"JMP not_zero\n"
|
||||
"msw_is_zero:\n\t"
|
||||
"BSR $dst, $src.lo\n\t"
|
||||
"JNZ not_zero\n\t"
|
||||
"MOV $dst, -1\n"
|
||||
"not_zero:\n\t"
|
||||
"NEG $dst\n\t"
|
||||
"ADD $dst, 63\n" %}
|
||||
ins_encode %{
|
||||
Register Rdst = $dst$$Register;
|
||||
Register Rsrc = $src$$Register;
|
||||
Label msw_is_zero;
|
||||
Label not_zero;
|
||||
__ bsrl(Rdst, HIGH_FROM_LOW(Rsrc));
|
||||
__ jccb(Assembler::zero, msw_is_zero);
|
||||
__ addl(Rdst, BitsPerInt);
|
||||
__ jmpb(not_zero);
|
||||
__ bind(msw_is_zero);
|
||||
__ bsrl(Rdst, Rsrc);
|
||||
__ jccb(Assembler::notZero, not_zero);
|
||||
__ movl(Rdst, -1);
|
||||
__ bind(not_zero);
|
||||
__ negl(Rdst);
|
||||
__ addl(Rdst, BitsPerLong - 1);
|
||||
%}
|
||||
ins_pipe(ialu_reg);
|
||||
%}
|
||||
|
||||
instruct countTrailingZerosI(eRegI dst, eRegI src, eFlagsReg cr) %{
|
||||
match(Set dst (CountTrailingZerosI src));
|
||||
effect(KILL cr);
|
||||
|
||||
format %{ "BSF $dst, $src\t# count trailing zeros (int)\n\t"
|
||||
"JNZ done\n\t"
|
||||
"MOV $dst, 32\n"
|
||||
"done:" %}
|
||||
ins_encode %{
|
||||
Register Rdst = $dst$$Register;
|
||||
Label done;
|
||||
__ bsfl(Rdst, $src$$Register);
|
||||
__ jccb(Assembler::notZero, done);
|
||||
__ movl(Rdst, BitsPerInt);
|
||||
__ bind(done);
|
||||
%}
|
||||
ins_pipe(ialu_reg);
|
||||
%}
|
||||
|
||||
instruct countTrailingZerosL(eRegI dst, eRegL src, eFlagsReg cr) %{
|
||||
match(Set dst (CountTrailingZerosL src));
|
||||
effect(TEMP dst, KILL cr);
|
||||
|
||||
format %{ "BSF $dst, $src.lo\t# count trailing zeros (long)\n\t"
|
||||
"JNZ done\n\t"
|
||||
"BSF $dst, $src.hi\n\t"
|
||||
"JNZ msw_not_zero\n\t"
|
||||
"MOV $dst, 32\n"
|
||||
"msw_not_zero:\n\t"
|
||||
"ADD $dst, 32\n"
|
||||
"done:" %}
|
||||
ins_encode %{
|
||||
Register Rdst = $dst$$Register;
|
||||
Register Rsrc = $src$$Register;
|
||||
Label msw_not_zero;
|
||||
Label done;
|
||||
__ bsfl(Rdst, Rsrc);
|
||||
__ jccb(Assembler::notZero, done);
|
||||
__ bsfl(Rdst, HIGH_FROM_LOW(Rsrc));
|
||||
__ jccb(Assembler::notZero, msw_not_zero);
|
||||
__ movl(Rdst, BitsPerInt);
|
||||
__ bind(msw_not_zero);
|
||||
__ addl(Rdst, BitsPerInt);
|
||||
__ bind(done);
|
||||
%}
|
||||
ins_pipe(ialu_reg);
|
||||
%}
|
||||
|
||||
|
||||
//---------- Population Count Instructions -------------------------------------
|
||||
|
||||
instruct popCountI(eRegI dst, eRegI src) %{
|
||||
@ -6784,6 +6947,18 @@ instruct loadS(eRegI dst, memory mem) %{
|
||||
ins_pipe(ialu_reg_mem);
|
||||
%}
|
||||
|
||||
// Load Short (16 bit signed) to Byte (8 bit signed)
|
||||
instruct loadS2B(eRegI dst, memory mem, immI_24 twentyfour) %{
|
||||
match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour));
|
||||
|
||||
ins_cost(125);
|
||||
format %{ "MOVSX $dst, $mem\t# short -> byte" %}
|
||||
ins_encode %{
|
||||
__ movsbl($dst$$Register, $mem$$Address);
|
||||
%}
|
||||
ins_pipe(ialu_reg_mem);
|
||||
%}
|
||||
|
||||
// Load Short (16bit signed) into Long Register
|
||||
instruct loadS2L(eRegL dst, memory mem) %{
|
||||
match(Set dst (ConvI2L (LoadS mem)));
|
||||
@ -6816,9 +6991,20 @@ instruct loadUS(eRegI dst, memory mem) %{
|
||||
ins_pipe(ialu_reg_mem);
|
||||
%}
|
||||
|
||||
// Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed)
|
||||
instruct loadUS2B(eRegI dst, memory mem, immI_24 twentyfour) %{
|
||||
match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour));
|
||||
|
||||
ins_cost(125);
|
||||
format %{ "MOVSX $dst, $mem\t# ushort -> byte" %}
|
||||
ins_encode %{
|
||||
__ movsbl($dst$$Register, $mem$$Address);
|
||||
%}
|
||||
ins_pipe(ialu_reg_mem);
|
||||
%}
|
||||
|
||||
// Load Unsigned Short/Char (16 bit UNsigned) into Long Register
|
||||
instruct loadUS2L(eRegL dst, memory mem)
|
||||
%{
|
||||
instruct loadUS2L(eRegL dst, memory mem) %{
|
||||
match(Set dst (ConvI2L (LoadUS mem)));
|
||||
|
||||
ins_cost(250);
|
||||
@ -6847,6 +7033,54 @@ instruct loadI(eRegI dst, memory mem) %{
|
||||
ins_pipe(ialu_reg_mem);
|
||||
%}
|
||||
|
||||
// Load Integer (32 bit signed) to Byte (8 bit signed)
|
||||
instruct loadI2B(eRegI dst, memory mem, immI_24 twentyfour) %{
|
||||
match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour));
|
||||
|
||||
ins_cost(125);
|
||||
format %{ "MOVSX $dst, $mem\t# int -> byte" %}
|
||||
ins_encode %{
|
||||
__ movsbl($dst$$Register, $mem$$Address);
|
||||
%}
|
||||
ins_pipe(ialu_reg_mem);
|
||||
%}
|
||||
|
||||
// Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned)
|
||||
instruct loadI2UB(eRegI dst, memory mem, immI_255 mask) %{
|
||||
match(Set dst (AndI (LoadI mem) mask));
|
||||
|
||||
ins_cost(125);
|
||||
format %{ "MOVZX $dst, $mem\t# int -> ubyte" %}
|
||||
ins_encode %{
|
||||
__ movzbl($dst$$Register, $mem$$Address);
|
||||
%}
|
||||
ins_pipe(ialu_reg_mem);
|
||||
%}
|
||||
|
||||
// Load Integer (32 bit signed) to Short (16 bit signed)
|
||||
instruct loadI2S(eRegI dst, memory mem, immI_16 sixteen) %{
|
||||
match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen));
|
||||
|
||||
ins_cost(125);
|
||||
format %{ "MOVSX $dst, $mem\t# int -> short" %}
|
||||
ins_encode %{
|
||||
__ movswl($dst$$Register, $mem$$Address);
|
||||
%}
|
||||
ins_pipe(ialu_reg_mem);
|
||||
%}
|
||||
|
||||
// Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned)
|
||||
instruct loadI2US(eRegI dst, memory mem, immI_65535 mask) %{
|
||||
match(Set dst (AndI (LoadI mem) mask));
|
||||
|
||||
ins_cost(125);
|
||||
format %{ "MOVZX $dst, $mem\t# int -> ushort/char" %}
|
||||
ins_encode %{
|
||||
__ movzwl($dst$$Register, $mem$$Address);
|
||||
%}
|
||||
ins_pipe(ialu_reg_mem);
|
||||
%}
|
||||
|
||||
// Load Integer into Long Register
|
||||
instruct loadI2L(eRegL dst, memory mem) %{
|
||||
match(Set dst (ConvI2L (LoadI mem)));
|
||||
@ -8880,28 +9114,28 @@ instruct shrI_eReg_imm(eRegI dst, immI8 shift, eFlagsReg cr) %{
|
||||
|
||||
// Logical Shift Right by 24, followed by Arithmetic Shift Left by 24.
|
||||
// This idiom is used by the compiler for the i2b bytecode.
|
||||
instruct i2b(eRegI dst, xRegI src, immI_24 twentyfour, eFlagsReg cr) %{
|
||||
instruct i2b(eRegI dst, xRegI src, immI_24 twentyfour) %{
|
||||
match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour));
|
||||
effect(KILL cr);
|
||||
|
||||
size(3);
|
||||
format %{ "MOVSX $dst,$src :8" %}
|
||||
opcode(0xBE, 0x0F);
|
||||
ins_encode( OpcS, OpcP, RegReg( dst, src));
|
||||
ins_pipe( ialu_reg_reg );
|
||||
ins_encode %{
|
||||
__ movsbl($dst$$Register, $src$$Register);
|
||||
%}
|
||||
ins_pipe(ialu_reg_reg);
|
||||
%}
|
||||
|
||||
// Logical Shift Right by 16, followed by Arithmetic Shift Left by 16.
|
||||
// This idiom is used by the compiler the i2s bytecode.
|
||||
instruct i2s(eRegI dst, xRegI src, immI_16 sixteen, eFlagsReg cr) %{
|
||||
instruct i2s(eRegI dst, xRegI src, immI_16 sixteen) %{
|
||||
match(Set dst (RShiftI (LShiftI src sixteen) sixteen));
|
||||
effect(KILL cr);
|
||||
|
||||
size(3);
|
||||
format %{ "MOVSX $dst,$src :16" %}
|
||||
opcode(0xBF, 0x0F);
|
||||
ins_encode( OpcS, OpcP, RegReg( dst, src));
|
||||
ins_pipe( ialu_reg_reg );
|
||||
ins_encode %{
|
||||
__ movswl($dst$$Register, $src$$Register);
|
||||
%}
|
||||
ins_pipe(ialu_reg_reg);
|
||||
%}
|
||||
|
||||
|
||||
|
@ -1980,6 +1980,13 @@ static void emit_float_constant(CodeBuffer& cbuf, float x) {
|
||||
}
|
||||
|
||||
|
||||
const bool Matcher::match_rule_supported(int opcode) {
|
||||
if (!has_match_rule(opcode))
|
||||
return false;
|
||||
|
||||
return true; // Per default match rules are supported.
|
||||
}
|
||||
|
||||
int Matcher::regnum_to_fpu_offset(int regnum)
|
||||
{
|
||||
return regnum - 32; // The FP registers are in the second chunk
|
||||
@ -6452,6 +6459,18 @@ instruct loadS(rRegI dst, memory mem)
|
||||
ins_pipe(ialu_reg_mem);
|
||||
%}
|
||||
|
||||
// Load Short (16 bit signed) to Byte (8 bit signed)
|
||||
instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{
|
||||
match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour));
|
||||
|
||||
ins_cost(125);
|
||||
format %{ "movsbl $dst, $mem\t# short -> byte" %}
|
||||
ins_encode %{
|
||||
__ movsbl($dst$$Register, $mem$$Address);
|
||||
%}
|
||||
ins_pipe(ialu_reg_mem);
|
||||
%}
|
||||
|
||||
// Load Short (16 bit signed) into Long Register
|
||||
instruct loadS2L(rRegL dst, memory mem)
|
||||
%{
|
||||
@ -6482,6 +6501,18 @@ instruct loadUS(rRegI dst, memory mem)
|
||||
ins_pipe(ialu_reg_mem);
|
||||
%}
|
||||
|
||||
// Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed)
|
||||
instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{
|
||||
match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour));
|
||||
|
||||
ins_cost(125);
|
||||
format %{ "movsbl $dst, $mem\t# ushort -> byte" %}
|
||||
ins_encode %{
|
||||
__ movsbl($dst$$Register, $mem$$Address);
|
||||
%}
|
||||
ins_pipe(ialu_reg_mem);
|
||||
%}
|
||||
|
||||
// Load Unsigned Short/Char (16 bit UNsigned) into Long Register
|
||||
instruct loadUS2L(rRegL dst, memory mem)
|
||||
%{
|
||||
@ -6512,6 +6543,54 @@ instruct loadI(rRegI dst, memory mem)
|
||||
ins_pipe(ialu_reg_mem);
|
||||
%}
|
||||
|
||||
// Load Integer (32 bit signed) to Byte (8 bit signed)
|
||||
instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{
|
||||
match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour));
|
||||
|
||||
ins_cost(125);
|
||||
format %{ "movsbl $dst, $mem\t# int -> byte" %}
|
||||
ins_encode %{
|
||||
__ movsbl($dst$$Register, $mem$$Address);
|
||||
%}
|
||||
ins_pipe(ialu_reg_mem);
|
||||
%}
|
||||
|
||||
// Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned)
|
||||
instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{
|
||||
match(Set dst (AndI (LoadI mem) mask));
|
||||
|
||||
ins_cost(125);
|
||||
format %{ "movzbl $dst, $mem\t# int -> ubyte" %}
|
||||
ins_encode %{
|
||||
__ movzbl($dst$$Register, $mem$$Address);
|
||||
%}
|
||||
ins_pipe(ialu_reg_mem);
|
||||
%}
|
||||
|
||||
// Load Integer (32 bit signed) to Short (16 bit signed)
|
||||
instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{
|
||||
match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen));
|
||||
|
||||
ins_cost(125);
|
||||
format %{ "movswl $dst, $mem\t# int -> short" %}
|
||||
ins_encode %{
|
||||
__ movswl($dst$$Register, $mem$$Address);
|
||||
%}
|
||||
ins_pipe(ialu_reg_mem);
|
||||
%}
|
||||
|
||||
// Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned)
|
||||
instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{
|
||||
match(Set dst (AndI (LoadI mem) mask));
|
||||
|
||||
ins_cost(125);
|
||||
format %{ "movzwl $dst, $mem\t# int -> ushort/char" %}
|
||||
ins_encode %{
|
||||
__ movzwl($dst$$Register, $mem$$Address);
|
||||
%}
|
||||
ins_pipe(ialu_reg_mem);
|
||||
%}
|
||||
|
||||
// Load Integer into Long Register
|
||||
instruct loadI2L(rRegL dst, memory mem)
|
||||
%{
|
||||
@ -7656,6 +7735,121 @@ instruct storeL_reversed(memory dst, rRegL src) %{
|
||||
%}
|
||||
|
||||
|
||||
//---------- Zeros Count Instructions ------------------------------------------
|
||||
|
||||
instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{
|
||||
predicate(UseCountLeadingZerosInstruction);
|
||||
match(Set dst (CountLeadingZerosI src));
|
||||
effect(KILL cr);
|
||||
|
||||
format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %}
|
||||
ins_encode %{
|
||||
__ lzcntl($dst$$Register, $src$$Register);
|
||||
%}
|
||||
ins_pipe(ialu_reg);
|
||||
%}
|
||||
|
||||
instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{
|
||||
predicate(!UseCountLeadingZerosInstruction);
|
||||
match(Set dst (CountLeadingZerosI src));
|
||||
effect(KILL cr);
|
||||
|
||||
format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t"
|
||||
"jnz skip\n\t"
|
||||
"movl $dst, -1\n"
|
||||
"skip:\n\t"
|
||||
"negl $dst\n\t"
|
||||
"addl $dst, 31" %}
|
||||
ins_encode %{
|
||||
Register Rdst = $dst$$Register;
|
||||
Register Rsrc = $src$$Register;
|
||||
Label skip;
|
||||
__ bsrl(Rdst, Rsrc);
|
||||
__ jccb(Assembler::notZero, skip);
|
||||
__ movl(Rdst, -1);
|
||||
__ bind(skip);
|
||||
__ negl(Rdst);
|
||||
__ addl(Rdst, BitsPerInt - 1);
|
||||
%}
|
||||
ins_pipe(ialu_reg);
|
||||
%}
|
||||
|
||||
instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{
|
||||
predicate(UseCountLeadingZerosInstruction);
|
||||
match(Set dst (CountLeadingZerosL src));
|
||||
effect(KILL cr);
|
||||
|
||||
format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %}
|
||||
ins_encode %{
|
||||
__ lzcntq($dst$$Register, $src$$Register);
|
||||
%}
|
||||
ins_pipe(ialu_reg);
|
||||
%}
|
||||
|
||||
instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{
|
||||
predicate(!UseCountLeadingZerosInstruction);
|
||||
match(Set dst (CountLeadingZerosL src));
|
||||
effect(KILL cr);
|
||||
|
||||
format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t"
|
||||
"jnz skip\n\t"
|
||||
"movl $dst, -1\n"
|
||||
"skip:\n\t"
|
||||
"negl $dst\n\t"
|
||||
"addl $dst, 63" %}
|
||||
ins_encode %{
|
||||
Register Rdst = $dst$$Register;
|
||||
Register Rsrc = $src$$Register;
|
||||
Label skip;
|
||||
__ bsrq(Rdst, Rsrc);
|
||||
__ jccb(Assembler::notZero, skip);
|
||||
__ movl(Rdst, -1);
|
||||
__ bind(skip);
|
||||
__ negl(Rdst);
|
||||
__ addl(Rdst, BitsPerLong - 1);
|
||||
%}
|
||||
ins_pipe(ialu_reg);
|
||||
%}
|
||||
|
||||
instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{
|
||||
match(Set dst (CountTrailingZerosI src));
|
||||
effect(KILL cr);
|
||||
|
||||
format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t"
|
||||
"jnz done\n\t"
|
||||
"movl $dst, 32\n"
|
||||
"done:" %}
|
||||
ins_encode %{
|
||||
Register Rdst = $dst$$Register;
|
||||
Label done;
|
||||
__ bsfl(Rdst, $src$$Register);
|
||||
__ jccb(Assembler::notZero, done);
|
||||
__ movl(Rdst, BitsPerInt);
|
||||
__ bind(done);
|
||||
%}
|
||||
ins_pipe(ialu_reg);
|
||||
%}
|
||||
|
||||
instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{
|
||||
match(Set dst (CountTrailingZerosL src));
|
||||
effect(KILL cr);
|
||||
|
||||
format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t"
|
||||
"jnz done\n\t"
|
||||
"movl $dst, 64\n"
|
||||
"done:" %}
|
||||
ins_encode %{
|
||||
Register Rdst = $dst$$Register;
|
||||
Label done;
|
||||
__ bsfq(Rdst, $src$$Register);
|
||||
__ jccb(Assembler::notZero, done);
|
||||
__ movl(Rdst, BitsPerLong);
|
||||
__ bind(done);
|
||||
%}
|
||||
ins_pipe(ialu_reg);
|
||||
%}
|
||||
|
||||
|
||||
//---------- Population Count Instructions -------------------------------------
|
||||
|
||||
instruct popCountI(rRegI dst, rRegI src) %{
|
||||
|
@ -73,7 +73,7 @@ class FileBuff {
|
||||
|
||||
// This converts a pointer into the buffer to a file offset. It only works
|
||||
// when the pointer is valid (i.e. just obtained from getline()).
|
||||
long getoff(const char* s) { return _bufoff + (s - _buf); }
|
||||
long getoff(const char* s) { return _bufoff + (long)(s - _buf); }
|
||||
};
|
||||
|
||||
//------------------------------FileBuffRegion---------------------------------
|
||||
|
@ -1745,6 +1745,7 @@ void ArchDesc::defineExpand(FILE *fp, InstructForm *node) {
|
||||
fprintf(fp," del_req(i);\n");
|
||||
fprintf(fp," }\n");
|
||||
fprintf(fp," _num_opnds = %d;\n", new_num_opnds);
|
||||
assert(new_num_opnds == node->num_unique_opnds(), "what?");
|
||||
}
|
||||
}
|
||||
|
||||
@ -3761,6 +3762,12 @@ bool InstructForm::define_cisc_version(ArchDesc &AD, FILE *fp_cpp) {
|
||||
if ( this->captures_bottom_type() ) {
|
||||
fprintf(fp_cpp, " node->_bottom_type = bottom_type();\n");
|
||||
}
|
||||
|
||||
uint cur_num_opnds = num_opnds();
|
||||
if (cur_num_opnds > 1 && cur_num_opnds != num_unique_opnds()) {
|
||||
fprintf(fp_cpp," node->_num_opnds = %d;\n", num_unique_opnds());
|
||||
}
|
||||
|
||||
fprintf(fp_cpp, "\n");
|
||||
fprintf(fp_cpp, " // Copy _idx, inputs and operands to new node\n");
|
||||
fprintf(fp_cpp, " fill_new_machnode(node, C);\n");
|
||||
|
@ -319,7 +319,7 @@ void Compilation::compile_method() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (JvmtiExport::can_hotswap_or_post_breakpoint()) {
|
||||
if (_env->jvmti_can_hotswap_or_post_breakpoint()) {
|
||||
// We can assert evol_method because method->can_be_compiled is true.
|
||||
dependency_recorder()->assert_evol_method(method());
|
||||
}
|
||||
@ -435,7 +435,7 @@ Compilation::Compilation(AbstractCompiler* compiler, ciEnv* env, ciMethod* metho
|
||||
assert(_arena == NULL, "shouldn't only one instance of Compilation in existence at a time");
|
||||
_arena = Thread::current()->resource_area();
|
||||
_compilation = this;
|
||||
_needs_debug_information = JvmtiExport::can_examine_or_deopt_anywhere() ||
|
||||
_needs_debug_information = _env->jvmti_can_examine_or_deopt_anywhere() ||
|
||||
JavaMonitorsInStackTrace || AlwaysEmitDebugInfo || DeoptimizeALot;
|
||||
_exception_info_list = new ExceptionInfoList();
|
||||
_implicit_exception_table.set_size(0);
|
||||
|
@ -1662,7 +1662,7 @@ void GraphBuilder::invoke(Bytecodes::Code code) {
|
||||
// Register dependence if JVMTI has either breakpoint
|
||||
// setting or hotswapping of methods capabilities since they may
|
||||
// cause deoptimization.
|
||||
if (JvmtiExport::can_hotswap_or_post_breakpoint()) {
|
||||
if (compilation()->env()->jvmti_can_hotswap_or_post_breakpoint()) {
|
||||
dependency_recorder()->assert_evol_method(inline_target);
|
||||
}
|
||||
return;
|
||||
@ -2863,7 +2863,7 @@ GraphBuilder::GraphBuilder(Compilation* compilation, IRScope* scope)
|
||||
start_block->merge(_initial_state);
|
||||
|
||||
BlockBegin* sync_handler = NULL;
|
||||
if (method()->is_synchronized() || DTraceMethodProbes) {
|
||||
if (method()->is_synchronized() || _compilation->env()->dtrace_method_probes()) {
|
||||
// setup an exception handler to do the unlocking and/or notification
|
||||
sync_handler = new BlockBegin(-1);
|
||||
sync_handler->set(BlockBegin::exception_entry_flag);
|
||||
|
@ -1064,7 +1064,7 @@ void LIRGenerator::do_IfInstanceOf(IfInstanceOf* x) {
|
||||
|
||||
|
||||
void LIRGenerator::do_Return(Return* x) {
|
||||
if (DTraceMethodProbes) {
|
||||
if (compilation()->env()->dtrace_method_probes()) {
|
||||
BasicTypeList signature;
|
||||
signature.append(T_INT); // thread
|
||||
signature.append(T_OBJECT); // methodOop
|
||||
@ -1769,7 +1769,7 @@ void LIRGenerator::do_Throw(Throw* x) {
|
||||
__ null_check(exception_opr, new CodeEmitInfo(info, true));
|
||||
}
|
||||
|
||||
if (JvmtiExport::can_post_exceptions() &&
|
||||
if (compilation()->env()->jvmti_can_post_exceptions() &&
|
||||
!block()->is_set(BlockBegin::default_exception_handler_flag)) {
|
||||
// we need to go through the exception lookup path to get JVMTI
|
||||
// notification done
|
||||
@ -1779,7 +1779,7 @@ void LIRGenerator::do_Throw(Throw* x) {
|
||||
assert(!block()->is_set(BlockBegin::default_exception_handler_flag) || unwind,
|
||||
"should be no more handlers to dispatch to");
|
||||
|
||||
if (DTraceMethodProbes &&
|
||||
if (compilation()->env()->dtrace_method_probes() &&
|
||||
block()->is_set(BlockBegin::default_exception_handler_flag)) {
|
||||
// notify that this frame is unwinding
|
||||
BasicTypeList signature;
|
||||
@ -2204,7 +2204,7 @@ void LIRGenerator::do_Base(Base* x) {
|
||||
java_index += type2size[t];
|
||||
}
|
||||
|
||||
if (DTraceMethodProbes) {
|
||||
if (compilation()->env()->dtrace_method_probes()) {
|
||||
BasicTypeList signature;
|
||||
signature.append(T_INT); // thread
|
||||
signature.append(T_OBJECT); // methodOop
|
||||
|
@ -170,6 +170,34 @@ ciEnv::~ciEnv() {
|
||||
current_thread->set_env(NULL);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Cache Jvmti state
|
||||
void ciEnv::cache_jvmti_state() {
|
||||
VM_ENTRY_MARK;
|
||||
// Get Jvmti capabilities under lock to get consistant values.
|
||||
MutexLocker mu(JvmtiThreadState_lock);
|
||||
_jvmti_can_hotswap_or_post_breakpoint = JvmtiExport::can_hotswap_or_post_breakpoint();
|
||||
_jvmti_can_examine_or_deopt_anywhere = JvmtiExport::can_examine_or_deopt_anywhere();
|
||||
_jvmti_can_access_local_variables = JvmtiExport::can_access_local_variables();
|
||||
_jvmti_can_post_exceptions = JvmtiExport::can_post_exceptions();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Cache DTrace flags
|
||||
void ciEnv::cache_dtrace_flags() {
|
||||
// Need lock?
|
||||
_dtrace_extended_probes = ExtendedDTraceProbes;
|
||||
if (_dtrace_extended_probes) {
|
||||
_dtrace_monitor_probes = true;
|
||||
_dtrace_method_probes = true;
|
||||
_dtrace_alloc_probes = true;
|
||||
} else {
|
||||
_dtrace_monitor_probes = DTraceMonitorProbes;
|
||||
_dtrace_method_probes = DTraceMethodProbes;
|
||||
_dtrace_alloc_probes = DTraceAllocProbes;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// helper for lazy exception creation
|
||||
ciInstance* ciEnv::get_or_create_exception(jobject& handle, symbolHandle name) {
|
||||
@ -810,16 +838,39 @@ void ciEnv::register_method(ciMethod* target,
|
||||
// and invalidating our dependencies until we install this method.
|
||||
MutexLocker ml(Compile_lock);
|
||||
|
||||
if (log() != NULL) {
|
||||
// Log the dependencies which this compilation declares.
|
||||
dependencies()->log_all_dependencies();
|
||||
// Change in Jvmti state may invalidate compilation.
|
||||
if (!failing() &&
|
||||
( (!jvmti_can_hotswap_or_post_breakpoint() &&
|
||||
JvmtiExport::can_hotswap_or_post_breakpoint()) ||
|
||||
(!jvmti_can_examine_or_deopt_anywhere() &&
|
||||
JvmtiExport::can_examine_or_deopt_anywhere()) ||
|
||||
(!jvmti_can_access_local_variables() &&
|
||||
JvmtiExport::can_access_local_variables()) ||
|
||||
(!jvmti_can_post_exceptions() &&
|
||||
JvmtiExport::can_post_exceptions()) )) {
|
||||
record_failure("Jvmti state change invalidated dependencies");
|
||||
}
|
||||
|
||||
// Encode the dependencies now, so we can check them right away.
|
||||
dependencies()->encode_content_bytes();
|
||||
// Change in DTrace flags may invalidate compilation.
|
||||
if (!failing() &&
|
||||
( (!dtrace_extended_probes() && ExtendedDTraceProbes) ||
|
||||
(!dtrace_method_probes() && DTraceMethodProbes) ||
|
||||
(!dtrace_alloc_probes() && DTraceAllocProbes) )) {
|
||||
record_failure("DTrace flags change invalidated dependencies");
|
||||
}
|
||||
|
||||
// Check for {class loads, evolution, breakpoints} during compilation
|
||||
check_for_system_dictionary_modification(target);
|
||||
if (!failing()) {
|
||||
if (log() != NULL) {
|
||||
// Log the dependencies which this compilation declares.
|
||||
dependencies()->log_all_dependencies();
|
||||
}
|
||||
|
||||
// Encode the dependencies now, so we can check them right away.
|
||||
dependencies()->encode_content_bytes();
|
||||
|
||||
// Check for {class loads, evolution, breakpoints} during compilation
|
||||
check_for_system_dictionary_modification(target);
|
||||
}
|
||||
|
||||
methodHandle method(THREAD, target->get_methodOop());
|
||||
|
||||
|
@ -53,6 +53,18 @@ private:
|
||||
char* _name_buffer;
|
||||
int _name_buffer_len;
|
||||
|
||||
// Cache Jvmti state
|
||||
bool _jvmti_can_hotswap_or_post_breakpoint;
|
||||
bool _jvmti_can_examine_or_deopt_anywhere;
|
||||
bool _jvmti_can_access_local_variables;
|
||||
bool _jvmti_can_post_exceptions;
|
||||
|
||||
// Cache DTrace flags
|
||||
bool _dtrace_extended_probes;
|
||||
bool _dtrace_monitor_probes;
|
||||
bool _dtrace_method_probes;
|
||||
bool _dtrace_alloc_probes;
|
||||
|
||||
// Distinguished instances of certain ciObjects..
|
||||
static ciObject* _null_object_instance;
|
||||
static ciMethodKlass* _method_klass_instance;
|
||||
@ -236,6 +248,20 @@ public:
|
||||
bool break_at_compile() { return _break_at_compile; }
|
||||
void set_break_at_compile(bool z) { _break_at_compile = z; }
|
||||
|
||||
// Cache Jvmti state
|
||||
void cache_jvmti_state();
|
||||
bool jvmti_can_hotswap_or_post_breakpoint() const { return _jvmti_can_hotswap_or_post_breakpoint; }
|
||||
bool jvmti_can_examine_or_deopt_anywhere() const { return _jvmti_can_examine_or_deopt_anywhere; }
|
||||
bool jvmti_can_access_local_variables() const { return _jvmti_can_access_local_variables; }
|
||||
bool jvmti_can_post_exceptions() const { return _jvmti_can_post_exceptions; }
|
||||
|
||||
// Cache DTrace flags
|
||||
void cache_dtrace_flags();
|
||||
bool dtrace_extended_probes() const { return _dtrace_extended_probes; }
|
||||
bool dtrace_monitor_probes() const { return _dtrace_monitor_probes; }
|
||||
bool dtrace_method_probes() const { return _dtrace_method_probes; }
|
||||
bool dtrace_alloc_probes() const { return _dtrace_alloc_probes; }
|
||||
|
||||
// The compiler task which has created this env.
|
||||
// May be useful to find out compile_id, comp_level, etc.
|
||||
CompileTask* task() { return _task; }
|
||||
|
@ -60,7 +60,8 @@ ciMethod::ciMethod(methodHandle h_m) : ciObject(h_m) {
|
||||
_flow = NULL;
|
||||
#endif // COMPILER2
|
||||
|
||||
if (JvmtiExport::can_hotswap_or_post_breakpoint() && _is_compilable) {
|
||||
ciEnv *env = CURRENT_ENV;
|
||||
if (env->jvmti_can_hotswap_or_post_breakpoint() && _is_compilable) {
|
||||
// 6328518 check hotswap conditions under the right lock.
|
||||
MutexLocker locker(Compile_lock);
|
||||
if (Dependencies::check_evol_method(h_m()) != NULL) {
|
||||
@ -84,7 +85,6 @@ ciMethod::ciMethod(methodHandle h_m) : ciObject(h_m) {
|
||||
if (_can_be_statically_bound && h_m()->is_abstract())
|
||||
_can_be_statically_bound = false;
|
||||
|
||||
ciEnv *env = CURRENT_ENV;
|
||||
// generating _signature may allow GC and therefore move m.
|
||||
// These fields are always filled in.
|
||||
_name = env->get_object(h_m()->name())->as_symbol();
|
||||
@ -337,7 +337,7 @@ MethodLivenessResult ciMethod::liveness_at_bci(int bci) {
|
||||
_liveness->compute_liveness();
|
||||
}
|
||||
MethodLivenessResult result = _liveness->get_liveness_at(bci);
|
||||
if (JvmtiExport::can_access_local_variables() || DeoptimizeALot || CompileTheWorld) {
|
||||
if (CURRENT_ENV->jvmti_can_access_local_variables() || DeoptimizeALot || CompileTheWorld) {
|
||||
// Keep all locals live for the user's edification and amusement.
|
||||
result.at_put_range(0, result.size(), true);
|
||||
}
|
||||
|
@ -313,6 +313,8 @@
|
||||
template(value_name, "value") \
|
||||
template(frontCacheEnabled_name, "frontCacheEnabled") \
|
||||
template(stringCacheEnabled_name, "stringCacheEnabled") \
|
||||
template(numberOfLeadingZeros_name, "numberOfLeadingZeros") \
|
||||
template(numberOfTrailingZeros_name, "numberOfTrailingZeros") \
|
||||
template(bitCount_name, "bitCount") \
|
||||
template(profile_name, "profile") \
|
||||
template(equals_name, "equals") \
|
||||
@ -559,6 +561,12 @@
|
||||
do_intrinsic(_longBitsToDouble, java_lang_Double, longBitsToDouble_name, long_double_signature, F_S) \
|
||||
do_name( longBitsToDouble_name, "longBitsToDouble") \
|
||||
\
|
||||
do_intrinsic(_numberOfLeadingZeros_i, java_lang_Integer, numberOfLeadingZeros_name,int_int_signature, F_S) \
|
||||
do_intrinsic(_numberOfLeadingZeros_l, java_lang_Long, numberOfLeadingZeros_name,long_int_signature, F_S) \
|
||||
\
|
||||
do_intrinsic(_numberOfTrailingZeros_i, java_lang_Integer, numberOfTrailingZeros_name,int_int_signature, F_S) \
|
||||
do_intrinsic(_numberOfTrailingZeros_l, java_lang_Long, numberOfTrailingZeros_name,long_int_signature, F_S) \
|
||||
\
|
||||
do_intrinsic(_bitCount_i, java_lang_Integer, bitCount_name, int_int_signature, F_S) \
|
||||
do_intrinsic(_bitCount_l, java_lang_Long, bitCount_name, long_int_signature, F_S) \
|
||||
\
|
||||
|
@ -1530,6 +1530,12 @@ void CompileBroker::invoke_compiler_on_method(CompileTask* task) {
|
||||
assert(thread->env() == &ci_env, "set by ci_env");
|
||||
// The thread-env() field is cleared in ~CompileTaskWrapper.
|
||||
|
||||
// Cache Jvmti state
|
||||
ci_env.cache_jvmti_state();
|
||||
|
||||
// Cache DTrace flags
|
||||
ci_env.cache_dtrace_flags();
|
||||
|
||||
ciMethod* target = ci_env.get_method_from_handle(target_handle);
|
||||
|
||||
TraceTime t1("compilation", &time);
|
||||
|
@ -104,6 +104,10 @@ macro(ConvL2I)
|
||||
macro(CosD)
|
||||
macro(CountedLoop)
|
||||
macro(CountedLoopEnd)
|
||||
macro(CountLeadingZerosI)
|
||||
macro(CountLeadingZerosL)
|
||||
macro(CountTrailingZerosI)
|
||||
macro(CountTrailingZerosL)
|
||||
macro(CreateEx)
|
||||
macro(DecodeN)
|
||||
macro(DivD)
|
||||
|
@ -1255,3 +1255,93 @@ const Type *MoveD2LNode::Value( PhaseTransform *phase ) const {
|
||||
v.set_jdouble(td->getd());
|
||||
return TypeLong::make( v.get_jlong() );
|
||||
}
|
||||
|
||||
//------------------------------Value------------------------------------------
|
||||
const Type* CountLeadingZerosINode::Value(PhaseTransform* phase) const {
|
||||
const Type* t = phase->type(in(1));
|
||||
if (t == Type::TOP) return Type::TOP;
|
||||
const TypeInt* ti = t->isa_int();
|
||||
if (ti && ti->is_con()) {
|
||||
jint i = ti->get_con();
|
||||
// HD, Figure 5-6
|
||||
if (i == 0)
|
||||
return TypeInt::make(BitsPerInt);
|
||||
int n = 1;
|
||||
unsigned int x = i;
|
||||
if (x >> 16 == 0) { n += 16; x <<= 16; }
|
||||
if (x >> 24 == 0) { n += 8; x <<= 8; }
|
||||
if (x >> 28 == 0) { n += 4; x <<= 4; }
|
||||
if (x >> 30 == 0) { n += 2; x <<= 2; }
|
||||
n -= x >> 31;
|
||||
return TypeInt::make(n);
|
||||
}
|
||||
return TypeInt::INT;
|
||||
}
|
||||
|
||||
//------------------------------Value------------------------------------------
|
||||
const Type* CountLeadingZerosLNode::Value(PhaseTransform* phase) const {
|
||||
const Type* t = phase->type(in(1));
|
||||
if (t == Type::TOP) return Type::TOP;
|
||||
const TypeLong* tl = t->isa_long();
|
||||
if (tl && tl->is_con()) {
|
||||
jlong l = tl->get_con();
|
||||
// HD, Figure 5-6
|
||||
if (l == 0)
|
||||
return TypeInt::make(BitsPerLong);
|
||||
int n = 1;
|
||||
unsigned int x = (((julong) l) >> 32);
|
||||
if (x == 0) { n += 32; x = (int) l; }
|
||||
if (x >> 16 == 0) { n += 16; x <<= 16; }
|
||||
if (x >> 24 == 0) { n += 8; x <<= 8; }
|
||||
if (x >> 28 == 0) { n += 4; x <<= 4; }
|
||||
if (x >> 30 == 0) { n += 2; x <<= 2; }
|
||||
n -= x >> 31;
|
||||
return TypeInt::make(n);
|
||||
}
|
||||
return TypeInt::INT;
|
||||
}
|
||||
|
||||
//------------------------------Value------------------------------------------
|
||||
const Type* CountTrailingZerosINode::Value(PhaseTransform* phase) const {
|
||||
const Type* t = phase->type(in(1));
|
||||
if (t == Type::TOP) return Type::TOP;
|
||||
const TypeInt* ti = t->isa_int();
|
||||
if (ti && ti->is_con()) {
|
||||
jint i = ti->get_con();
|
||||
// HD, Figure 5-14
|
||||
int y;
|
||||
if (i == 0)
|
||||
return TypeInt::make(BitsPerInt);
|
||||
int n = 31;
|
||||
y = i << 16; if (y != 0) { n = n - 16; i = y; }
|
||||
y = i << 8; if (y != 0) { n = n - 8; i = y; }
|
||||
y = i << 4; if (y != 0) { n = n - 4; i = y; }
|
||||
y = i << 2; if (y != 0) { n = n - 2; i = y; }
|
||||
y = i << 1; if (y != 0) { n = n - 1; }
|
||||
return TypeInt::make(n);
|
||||
}
|
||||
return TypeInt::INT;
|
||||
}
|
||||
|
||||
//------------------------------Value------------------------------------------
|
||||
const Type* CountTrailingZerosLNode::Value(PhaseTransform* phase) const {
|
||||
const Type* t = phase->type(in(1));
|
||||
if (t == Type::TOP) return Type::TOP;
|
||||
const TypeLong* tl = t->isa_long();
|
||||
if (tl && tl->is_con()) {
|
||||
jlong l = tl->get_con();
|
||||
// HD, Figure 5-14
|
||||
int x, y;
|
||||
if (l == 0)
|
||||
return TypeInt::make(BitsPerLong);
|
||||
int n = 63;
|
||||
y = (int) l; if (y != 0) { n = n - 32; x = y; } else x = (((julong) l) >> 32);
|
||||
y = x << 16; if (y != 0) { n = n - 16; x = y; }
|
||||
y = x << 8; if (y != 0) { n = n - 8; x = y; }
|
||||
y = x << 4; if (y != 0) { n = n - 4; x = y; }
|
||||
y = x << 2; if (y != 0) { n = n - 2; x = y; }
|
||||
y = x << 1; if (y != 0) { n = n - 1; }
|
||||
return TypeInt::make(n);
|
||||
}
|
||||
return TypeInt::INT;
|
||||
}
|
||||
|
@ -636,22 +636,62 @@ class MoveD2LNode : public Node {
|
||||
virtual const Type* Value( PhaseTransform *phase ) const;
|
||||
};
|
||||
|
||||
//---------- PopCountINode -----------------------------------------------------
|
||||
// Population count (bit count) of an integer.
|
||||
class PopCountINode : public Node {
|
||||
//---------- CountBitsNode -----------------------------------------------------
|
||||
class CountBitsNode : public Node {
|
||||
public:
|
||||
PopCountINode(Node* in1) : Node(0, in1) {}
|
||||
virtual int Opcode() const;
|
||||
CountBitsNode(Node* in1) : Node(0, in1) {}
|
||||
const Type* bottom_type() const { return TypeInt::INT; }
|
||||
virtual uint ideal_reg() const { return Op_RegI; }
|
||||
};
|
||||
|
||||
//---------- CountLeadingZerosINode --------------------------------------------
|
||||
// Count leading zeros (0-bit count starting from MSB) of an integer.
|
||||
class CountLeadingZerosINode : public CountBitsNode {
|
||||
public:
|
||||
CountLeadingZerosINode(Node* in1) : CountBitsNode(in1) {}
|
||||
virtual int Opcode() const;
|
||||
virtual const Type* Value(PhaseTransform* phase) const;
|
||||
};
|
||||
|
||||
//---------- CountLeadingZerosLNode --------------------------------------------
|
||||
// Count leading zeros (0-bit count starting from MSB) of a long.
|
||||
class CountLeadingZerosLNode : public CountBitsNode {
|
||||
public:
|
||||
CountLeadingZerosLNode(Node* in1) : CountBitsNode(in1) {}
|
||||
virtual int Opcode() const;
|
||||
virtual const Type* Value(PhaseTransform* phase) const;
|
||||
};
|
||||
|
||||
//---------- CountTrailingZerosINode -------------------------------------------
|
||||
// Count trailing zeros (0-bit count starting from LSB) of an integer.
|
||||
class CountTrailingZerosINode : public CountBitsNode {
|
||||
public:
|
||||
CountTrailingZerosINode(Node* in1) : CountBitsNode(in1) {}
|
||||
virtual int Opcode() const;
|
||||
virtual const Type* Value(PhaseTransform* phase) const;
|
||||
};
|
||||
|
||||
//---------- CountTrailingZerosLNode -------------------------------------------
|
||||
// Count trailing zeros (0-bit count starting from LSB) of a long.
|
||||
class CountTrailingZerosLNode : public CountBitsNode {
|
||||
public:
|
||||
CountTrailingZerosLNode(Node* in1) : CountBitsNode(in1) {}
|
||||
virtual int Opcode() const;
|
||||
virtual const Type* Value(PhaseTransform* phase) const;
|
||||
};
|
||||
|
||||
//---------- PopCountINode -----------------------------------------------------
|
||||
// Population count (bit count) of an integer.
|
||||
class PopCountINode : public CountBitsNode {
|
||||
public:
|
||||
PopCountINode(Node* in1) : CountBitsNode(in1) {}
|
||||
virtual int Opcode() const;
|
||||
};
|
||||
|
||||
//---------- PopCountLNode -----------------------------------------------------
|
||||
// Population count (bit count) of a long.
|
||||
class PopCountLNode : public Node {
|
||||
class PopCountLNode : public CountBitsNode {
|
||||
public:
|
||||
PopCountLNode(Node* in1) : Node(0, in1) {}
|
||||
PopCountLNode(Node* in1) : CountBitsNode(in1) {}
|
||||
virtual int Opcode() const;
|
||||
const Type* bottom_type() const { return TypeInt::INT; }
|
||||
virtual uint ideal_reg() const { return Op_RegI; }
|
||||
};
|
||||
|
@ -47,7 +47,7 @@ CallGenerator* Compile::call_generator(ciMethod* call_method, int vtable_index,
|
||||
CallGenerator* cg;
|
||||
|
||||
// Dtrace currently doesn't work unless all calls are vanilla
|
||||
if (DTraceMethodProbes) {
|
||||
if (env()->dtrace_method_probes()) {
|
||||
allow_inline = false;
|
||||
}
|
||||
|
||||
|
@ -905,15 +905,22 @@ void ConnectionGraph::split_unique_types(GrowableArray<Node *> &alloc_worklist)
|
||||
// see if it is unescaped.
|
||||
if (es != PointsToNode::NoEscape || !ptn->_scalar_replaceable)
|
||||
continue;
|
||||
if (alloc->is_Allocate()) {
|
||||
// Set the scalar_replaceable flag before the next check.
|
||||
alloc->as_Allocate()->_is_scalar_replaceable = true;
|
||||
}
|
||||
// find CheckCastPP of call return value
|
||||
|
||||
// Find CheckCastPP for the allocate or for the return value of a call
|
||||
n = alloc->result_cast();
|
||||
if (n == NULL || // No uses accept Initialize or
|
||||
!n->is_CheckCastPP()) // not unique CheckCastPP.
|
||||
if (n == NULL) { // No uses except Initialize node
|
||||
if (alloc->is_Allocate()) {
|
||||
// Set the scalar_replaceable flag for allocation
|
||||
// so it could be eliminated if it has no uses.
|
||||
alloc->as_Allocate()->_is_scalar_replaceable = true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (!n->is_CheckCastPP()) { // not unique CheckCastPP.
|
||||
assert(!alloc->is_Allocate(), "allocation should have unique type");
|
||||
continue;
|
||||
}
|
||||
|
||||
// The inline code for Object.clone() casts the allocation result to
|
||||
// java.lang.Object and then to the actual type of the allocated
|
||||
// object. Detect this case and use the second cast.
|
||||
@ -934,9 +941,17 @@ void ConnectionGraph::split_unique_types(GrowableArray<Node *> &alloc_worklist)
|
||||
if (cast2 != NULL) {
|
||||
n = cast2;
|
||||
} else {
|
||||
// Non-scalar replaceable if the allocation type is unknown statically
|
||||
// (reflection allocation), the object can't be restored during
|
||||
// deoptimization without precise type.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (alloc->is_Allocate()) {
|
||||
// Set the scalar_replaceable flag for allocation
|
||||
// so it could be eliminated.
|
||||
alloc->as_Allocate()->_is_scalar_replaceable = true;
|
||||
}
|
||||
set_escape_state(n->_idx, es);
|
||||
// in order for an object to be scalar-replaceable, it must be:
|
||||
// - a direct allocation (not a call returning an object)
|
||||
|
@ -617,6 +617,9 @@ Block* PhaseCFG::insert_anti_dependences(Block* LCA, Node* load, bool verify) {
|
||||
assert(!LCA_orig->dominates(pred_block) ||
|
||||
early->dominates(pred_block), "early is high enough");
|
||||
must_raise_LCA = true;
|
||||
} else {
|
||||
// anti-dependent upon PHI pinned below 'early', no edge needed
|
||||
LCA = early; // but can not schedule below 'early'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -459,7 +459,7 @@ Bytecodes::Code GraphKit::java_bc() const {
|
||||
void GraphKit::builtin_throw(Deoptimization::DeoptReason reason, Node* arg) {
|
||||
bool must_throw = true;
|
||||
|
||||
if (JvmtiExport::can_post_exceptions()) {
|
||||
if (env()->jvmti_can_post_exceptions()) {
|
||||
// Do not try anything fancy if we're notifying the VM on every throw.
|
||||
// Cf. case Bytecodes::_athrow in parse2.cpp.
|
||||
uncommon_trap(reason, Deoptimization::Action_none,
|
||||
@ -769,7 +769,7 @@ void GraphKit::add_safepoint_edges(SafePointNode* call, bool must_throw) {
|
||||
}
|
||||
}
|
||||
|
||||
if (JvmtiExport::can_examine_or_deopt_anywhere()) {
|
||||
if (env()->jvmti_can_examine_or_deopt_anywhere()) {
|
||||
// At any safepoint, this method can get breakpointed, which would
|
||||
// then require an immediate deoptimization.
|
||||
full_info = true;
|
||||
|
@ -222,6 +222,8 @@ class LibraryCallKit : public GraphKit {
|
||||
bool inline_unsafe_CAS(BasicType type);
|
||||
bool inline_unsafe_ordered_store(BasicType type);
|
||||
bool inline_fp_conversions(vmIntrinsics::ID id);
|
||||
bool inline_numberOfLeadingZeros(vmIntrinsics::ID id);
|
||||
bool inline_numberOfTrailingZeros(vmIntrinsics::ID id);
|
||||
bool inline_bitCount(vmIntrinsics::ID id);
|
||||
bool inline_reverseBytes(vmIntrinsics::ID id);
|
||||
};
|
||||
@ -630,6 +632,14 @@ bool LibraryCallKit::try_to_inline() {
|
||||
case vmIntrinsics::_longBitsToDouble:
|
||||
return inline_fp_conversions(intrinsic_id());
|
||||
|
||||
case vmIntrinsics::_numberOfLeadingZeros_i:
|
||||
case vmIntrinsics::_numberOfLeadingZeros_l:
|
||||
return inline_numberOfLeadingZeros(intrinsic_id());
|
||||
|
||||
case vmIntrinsics::_numberOfTrailingZeros_i:
|
||||
case vmIntrinsics::_numberOfTrailingZeros_l:
|
||||
return inline_numberOfTrailingZeros(intrinsic_id());
|
||||
|
||||
case vmIntrinsics::_bitCount_i:
|
||||
case vmIntrinsics::_bitCount_l:
|
||||
return inline_bitCount(intrinsic_id());
|
||||
@ -1844,6 +1854,48 @@ inline Node* LibraryCallKit::make_unsafe_address(Node* base, Node* offset) {
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------inline_numberOfLeadingZeros_int/long-----------------------
|
||||
// inline int Integer.numberOfLeadingZeros(int)
|
||||
// inline int Long.numberOfLeadingZeros(long)
|
||||
bool LibraryCallKit::inline_numberOfLeadingZeros(vmIntrinsics::ID id) {
|
||||
assert(id == vmIntrinsics::_numberOfLeadingZeros_i || id == vmIntrinsics::_numberOfLeadingZeros_l, "not numberOfLeadingZeros");
|
||||
if (id == vmIntrinsics::_numberOfLeadingZeros_i && !Matcher::match_rule_supported(Op_CountLeadingZerosI)) return false;
|
||||
if (id == vmIntrinsics::_numberOfLeadingZeros_l && !Matcher::match_rule_supported(Op_CountLeadingZerosL)) return false;
|
||||
_sp += arg_size(); // restore stack pointer
|
||||
switch (id) {
|
||||
case vmIntrinsics::_numberOfLeadingZeros_i:
|
||||
push(_gvn.transform(new (C, 2) CountLeadingZerosINode(pop())));
|
||||
break;
|
||||
case vmIntrinsics::_numberOfLeadingZeros_l:
|
||||
push(_gvn.transform(new (C, 2) CountLeadingZerosLNode(pop_pair())));
|
||||
break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//-------------------inline_numberOfTrailingZeros_int/long----------------------
|
||||
// inline int Integer.numberOfTrailingZeros(int)
|
||||
// inline int Long.numberOfTrailingZeros(long)
|
||||
bool LibraryCallKit::inline_numberOfTrailingZeros(vmIntrinsics::ID id) {
|
||||
assert(id == vmIntrinsics::_numberOfTrailingZeros_i || id == vmIntrinsics::_numberOfTrailingZeros_l, "not numberOfTrailingZeros");
|
||||
if (id == vmIntrinsics::_numberOfTrailingZeros_i && !Matcher::match_rule_supported(Op_CountTrailingZerosI)) return false;
|
||||
if (id == vmIntrinsics::_numberOfTrailingZeros_l && !Matcher::match_rule_supported(Op_CountTrailingZerosL)) return false;
|
||||
_sp += arg_size(); // restore stack pointer
|
||||
switch (id) {
|
||||
case vmIntrinsics::_numberOfTrailingZeros_i:
|
||||
push(_gvn.transform(new (C, 2) CountTrailingZerosINode(pop())));
|
||||
break;
|
||||
case vmIntrinsics::_numberOfTrailingZeros_l:
|
||||
push(_gvn.transform(new (C, 2) CountTrailingZerosLNode(pop_pair())));
|
||||
break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------inline_bitCount_int/long-----------------------
|
||||
// inline int Integer.bitCount(int)
|
||||
// inline int Long.bitCount(long)
|
||||
@ -2541,7 +2593,8 @@ bool LibraryCallKit::inline_native_isInterrupted() {
|
||||
Node* p = basic_plus_adr(top()/*!oop*/, tls_ptr, in_bytes(JavaThread::osthread_offset()));
|
||||
Node* osthread = make_load(NULL, p, TypeRawPtr::NOTNULL, T_ADDRESS);
|
||||
p = basic_plus_adr(top()/*!oop*/, osthread, in_bytes(OSThread::interrupted_offset()));
|
||||
Node* int_bit = make_load(NULL, p, TypeInt::BOOL, T_INT);
|
||||
// Set the control input on the field _interrupted read to prevent it floating up.
|
||||
Node* int_bit = make_load(control(), p, TypeInt::BOOL, T_INT);
|
||||
Node* cmp_bit = _gvn.transform( new (C, 3) CmpINode(int_bit, intcon(0)) );
|
||||
Node* bol_bit = _gvn.transform( new (C, 2) BoolNode(cmp_bit, BoolTest::ne) );
|
||||
|
||||
|
@ -1630,6 +1630,10 @@ bool IdealLoopTree::iteration_split_impl( PhaseIdealLoop *phase, Node_List &old_
|
||||
// Before attempting fancy unrolling, RCE or alignment, see if we want
|
||||
// to completely unroll this loop or do loop unswitching.
|
||||
if( cl->is_normal_loop() ) {
|
||||
if (should_unswitch) {
|
||||
phase->do_unswitching(this, old_new);
|
||||
return true;
|
||||
}
|
||||
bool should_maximally_unroll = policy_maximally_unroll(phase);
|
||||
if( should_maximally_unroll ) {
|
||||
// Here we did some unrolling and peeling. Eventually we will
|
||||
@ -1637,10 +1641,6 @@ bool IdealLoopTree::iteration_split_impl( PhaseIdealLoop *phase, Node_List &old_
|
||||
phase->do_maximally_unroll(this,old_new);
|
||||
return true;
|
||||
}
|
||||
if (should_unswitch) {
|
||||
phase->do_unswitching(this, old_new);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -988,7 +988,7 @@ void PhaseMacroExpand::expand_allocate_common(
|
||||
initial_slow_test = BoolNode::make_predicate(initial_slow_test, &_igvn);
|
||||
}
|
||||
|
||||
if (DTraceAllocProbes ||
|
||||
if (C->env()->dtrace_alloc_probes() ||
|
||||
!UseTLAB && (!Universe::heap()->supports_inline_contig_alloc() ||
|
||||
(UseConcMarkSweepGC && CMSIncrementalMode))) {
|
||||
// Force slow-path allocation
|
||||
@ -1150,7 +1150,7 @@ void PhaseMacroExpand::expand_allocate_common(
|
||||
fast_oop_ctrl, fast_oop_rawmem, fast_oop,
|
||||
klass_node, length, size_in_bytes);
|
||||
|
||||
if (ExtendedDTraceProbes) {
|
||||
if (C->env()->dtrace_extended_probes()) {
|
||||
// Slow-path call
|
||||
int size = TypeFunc::Parms + 2;
|
||||
CallLeafNode *call = new (C, size) CallLeafNode(OptoRuntime::dtrace_object_alloc_Type(),
|
||||
|
@ -225,10 +225,16 @@ public:
|
||||
OptoRegPair *_parm_regs; // Array of machine registers per argument
|
||||
RegMask *_calling_convention_mask; // Array of RegMasks per argument
|
||||
|
||||
// Does matcher support this ideal node?
|
||||
// Does matcher have a match rule for this ideal node?
|
||||
static const bool has_match_rule(int opcode);
|
||||
static const bool _hasMatchRule[_last_opcode];
|
||||
|
||||
// Does matcher have a match rule for this ideal node and is the
|
||||
// predicate (if there is one) true?
|
||||
// NOTE: If this function is used more commonly in the future, ADLC
|
||||
// should generate this one.
|
||||
static const bool match_rule_supported(int opcode);
|
||||
|
||||
// Used to determine if we have fast l2f conversion
|
||||
// USII has it, USIII doesn't
|
||||
static const bool convL2FSupported(void);
|
||||
|
@ -439,7 +439,7 @@ Parse::Parse(JVMState* caller, ciMethod* parse_method, float expected_uses)
|
||||
// Always register dependence if JVMTI is enabled, because
|
||||
// either breakpoint setting or hotswapping of methods may
|
||||
// cause deoptimization.
|
||||
if (JvmtiExport::can_hotswap_or_post_breakpoint()) {
|
||||
if (C->env()->jvmti_can_hotswap_or_post_breakpoint()) {
|
||||
C->dependencies()->assert_evol_method(method());
|
||||
}
|
||||
|
||||
@ -953,7 +953,7 @@ void Parse::do_exits() {
|
||||
bool do_synch = method()->is_synchronized() && GenerateSynchronizationCode;
|
||||
|
||||
// record exit from a method if compiled while Dtrace is turned on.
|
||||
if (do_synch || DTraceMethodProbes) {
|
||||
if (do_synch || C->env()->dtrace_method_probes()) {
|
||||
// First move the exception list out of _exits:
|
||||
GraphKit kit(_exits.transfer_exceptions_into_jvms());
|
||||
SafePointNode* normal_map = kit.map(); // keep this guy safe
|
||||
@ -975,7 +975,7 @@ void Parse::do_exits() {
|
||||
// Unlock!
|
||||
kit.shared_unlock(_synch_lock->box_node(), _synch_lock->obj_node());
|
||||
}
|
||||
if (DTraceMethodProbes) {
|
||||
if (C->env()->dtrace_method_probes()) {
|
||||
kit.make_dtrace_method_exit(method());
|
||||
}
|
||||
// Done with exception-path processing.
|
||||
@ -1074,7 +1074,7 @@ void Parse::do_method_entry() {
|
||||
|
||||
NOT_PRODUCT( count_compiled_calls(true/*at_method_entry*/, false/*is_inline*/); )
|
||||
|
||||
if (DTraceMethodProbes) {
|
||||
if (C->env()->dtrace_method_probes()) {
|
||||
make_dtrace_method_entry(method());
|
||||
}
|
||||
|
||||
@ -1960,7 +1960,7 @@ void Parse::return_current(Node* value) {
|
||||
if (method()->is_synchronized() && GenerateSynchronizationCode) {
|
||||
shared_unlock(_synch_lock->box_node(), _synch_lock->obj_node());
|
||||
}
|
||||
if (DTraceMethodProbes) {
|
||||
if (C->env()->dtrace_method_probes()) {
|
||||
make_dtrace_method_exit(method());
|
||||
}
|
||||
SafePointNode* exit_return = _exits.map();
|
||||
|
@ -2052,7 +2052,7 @@ void Parse::do_one_bytecode() {
|
||||
// null exception oop throws NULL pointer exception
|
||||
do_null_check(peek(), T_OBJECT);
|
||||
if (stopped()) return;
|
||||
if (JvmtiExport::can_post_exceptions()) {
|
||||
if (env()->jvmti_can_post_exceptions()) {
|
||||
// "Full-speed throwing" is not necessary here,
|
||||
// since we're notifying the VM on every throw.
|
||||
uncommon_trap(Deoptimization::Reason_unhandled,
|
||||
|
@ -640,7 +640,11 @@ const Type *CmpPNode::sub( const Type *t1, const Type *t2 ) const {
|
||||
if (klass0 && klass1 &&
|
||||
kps != 1 && // both or neither are klass pointers
|
||||
klass0->is_loaded() && !klass0->is_interface() && // do not trust interfaces
|
||||
klass1->is_loaded() && !klass1->is_interface()) {
|
||||
klass1->is_loaded() && !klass1->is_interface() &&
|
||||
(!klass0->is_obj_array_klass() ||
|
||||
!klass0->as_obj_array_klass()->base_element_klass()->is_interface()) &&
|
||||
(!klass1->is_obj_array_klass() ||
|
||||
!klass1->as_obj_array_klass()->base_element_klass()->is_interface())) {
|
||||
bool unrelated_classes = false;
|
||||
// See if neither subclasses the other, or if the class on top
|
||||
// is precise. In either of these cases, the compare is known
|
||||
|
@ -2189,6 +2189,9 @@ class CommandLineFlags {
|
||||
diagnostic(bool, PrintIntrinsics, false, \
|
||||
"prints attempted and successful inlining of intrinsics") \
|
||||
\
|
||||
product(bool, UseCountLeadingZerosInstruction, false, \
|
||||
"Use count leading zeros instruction") \
|
||||
\
|
||||
product(bool, UsePopCountInstruction, false, \
|
||||
"Use population count instruction") \
|
||||
\
|
||||
|
@ -172,6 +172,33 @@ PHONY_LIST += jtreg_tests
|
||||
|
||||
################################################################
|
||||
|
||||
# clienttest (make sure various basic java client options work)
|
||||
|
||||
clienttest: prep $(PRODUCT_HOME)
|
||||
$(PRODUCT_HOME)/bin/java $(JAVA_OPTIONS) -version
|
||||
$(PRODUCT_HOME)/bin/java $(JAVA_OPTIONS) -help
|
||||
$(PRODUCT_HOME)/bin/java $(JAVA_OPTIONS) -X
|
||||
$(RM) $(PRODUCT_HOME)/jre/lib/*/client/classes.jsa
|
||||
$(RM) $(PRODUCT_HOME)/jre/lib/*/client/classes_g.jsa
|
||||
$(RM) $(PRODUCT_HOME)/jre/bin/client/classes.jsa
|
||||
$(RM) $(PRODUCT_HOME)/jre/bin/client/classes_g.jsa
|
||||
$(PRODUCT_HOME)/bin/java $(JAVA_OPTIONS) -Xshare:dump
|
||||
|
||||
PHONY_LIST += clienttest
|
||||
|
||||
################################################################
|
||||
|
||||
# servertest (make sure various basic java server options work)
|
||||
|
||||
servertest: prep $(PRODUCT_HOME)
|
||||
$(PRODUCT_HOME)/bin/java $(JAVA_OPTIONS) -version
|
||||
$(PRODUCT_HOME)/bin/java $(JAVA_OPTIONS) -help
|
||||
$(PRODUCT_HOME)/bin/java $(JAVA_OPTIONS) -X
|
||||
|
||||
PHONY_LIST += servertest
|
||||
|
||||
################################################################
|
||||
|
||||
# packtest
|
||||
|
||||
# Expect JPRT to set JPRT_PACKTEST_HOME.
|
||||
|
@ -29,7 +29,7 @@
|
||||
* @run main/othervm -server -Xbatch -XX:CompileOnly=Test1.init Test1
|
||||
*/
|
||||
|
||||
class Test1 {
|
||||
public class Test1 {
|
||||
|
||||
public static void init(int src[], int [] dst, int[] ref) {
|
||||
// initialize the arrays
|
||||
|
@ -29,7 +29,7 @@
|
||||
* @run main/othervm -server -Xbatch -XX:CompileOnly=Test2.shift Test2
|
||||
*/
|
||||
|
||||
class Test2 {
|
||||
public class Test2 {
|
||||
|
||||
public static void init(int src[]) {
|
||||
// Initialize the array
|
||||
|
65
hotspot/test/compiler/6772683/InterruptedTest.java
Normal file
65
hotspot/test/compiler/6772683/InterruptedTest.java
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6772683
|
||||
* @summary Thread.isInterrupted() fails to return true on multiprocessor PC
|
||||
* @run main/othervm InterruptedTest
|
||||
*/
|
||||
|
||||
public class InterruptedTest {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Thread workerThread = new Thread("worker") {
|
||||
public void run() {
|
||||
System.out.println("Worker thread: running...");
|
||||
while (!Thread.currentThread().isInterrupted()) {
|
||||
}
|
||||
System.out.println("Worker thread: bye");
|
||||
}
|
||||
};
|
||||
System.out.println("Main thread: starts a worker thread...");
|
||||
workerThread.start();
|
||||
System.out.println("Main thread: waits at most 5s for the worker thread to die...");
|
||||
workerThread.join(5000); // Wait 5 sec to let run() method to be compiled
|
||||
int ntries = 0;
|
||||
while (workerThread.isAlive() && ntries < 5) {
|
||||
System.out.println("Main thread: interrupts the worker thread...");
|
||||
workerThread.interrupt();
|
||||
if (workerThread.isInterrupted()) {
|
||||
System.out.println("Main thread: worker thread is interrupted");
|
||||
}
|
||||
ntries++;
|
||||
System.out.println("Main thread: waits for the worker thread to die...");
|
||||
workerThread.join(1000); // Wait 1 sec and try again
|
||||
}
|
||||
if (ntries == 5) {
|
||||
System.out.println("Main thread: the worker thread dod not die");
|
||||
System.exit(97);
|
||||
}
|
||||
System.out.println("Main thread: bye");
|
||||
}
|
||||
|
||||
}
|
104
hotspot/test/compiler/6814842/Test6814842.java
Normal file
104
hotspot/test/compiler/6814842/Test6814842.java
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 6814842
|
||||
* @summary Load shortening optimizations
|
||||
*
|
||||
* @run main/othervm -Xcomp -XX:CompileOnly=Test6814842.loadS2B,Test6814842.loadS2Bmask255,Test6814842.loadUS2B,Test6814842.loadUS2Bmask255,Test6814842.loadI2B,Test6814842.loadI2Bmask255,Test6814842.loadI2S,Test6814842.loadI2Smask255,Test6814842.loadI2Smask65535,Test6814842.loadI2US,Test6814842.loadI2USmask255,Test6814842.loadI2USmask65535 Test6814842
|
||||
*/
|
||||
|
||||
public class Test6814842 {
|
||||
static final short[] sa = new short[] { (short) 0xF1F2 };
|
||||
static final char[] ca = new char[] { (char) 0xF3F4 };
|
||||
static final int[] ia = new int[] { 0xF1F2F3F4 };
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
byte s2b = loadS2B(sa);
|
||||
if (s2b != (byte) 0xF2)
|
||||
throw new InternalError("loadS2B failed: " + s2b + " != " + (byte) 0xF2);
|
||||
|
||||
byte s2bmask255 = loadS2Bmask255(sa);
|
||||
if (s2bmask255 != (byte) 0xF2)
|
||||
throw new InternalError("loadS2Bmask255 failed: " + s2bmask255 + " != " + (byte) 0xF2);
|
||||
|
||||
byte us2b = loadUS2B(ca);
|
||||
if (us2b != (byte) 0xF4)
|
||||
throw new InternalError("loadUS2B failed: " + us2b + " != " + (byte) 0xF4);
|
||||
|
||||
byte us2bmask255 = loadUS2Bmask255(ca);
|
||||
if (us2bmask255 != (byte) 0xF4)
|
||||
throw new InternalError("loadUS2Bmask255 failed: " + us2bmask255 + " != " + (byte) 0xF4);
|
||||
|
||||
byte i2b = loadI2B(ia);
|
||||
if (i2b != (byte) 0xF4)
|
||||
throw new InternalError("loadI2B failed: " + i2b + " != " + (byte) 0xF4);
|
||||
|
||||
byte i2bmask255 = loadI2Bmask255(ia);
|
||||
if (i2bmask255 != (byte) 0xF4)
|
||||
throw new InternalError("loadI2Bmask255 failed: " + i2bmask255 + " != " + (byte) 0xF4);
|
||||
|
||||
short i2s = loadI2S(ia);
|
||||
if (i2s != (short) 0xF3F4)
|
||||
throw new InternalError("loadI2S failed: " + i2s + " != " + (short) 0xF3F4);
|
||||
|
||||
short i2smask255 = loadI2Smask255(ia);
|
||||
if (i2smask255 != (short) 0xF4)
|
||||
throw new InternalError("loadI2Smask255 failed: " + i2smask255 + " != " + (short) 0xF4);
|
||||
|
||||
short i2smask65535 = loadI2Smask65535(ia);
|
||||
if (i2smask65535 != (short) 0xF3F4)
|
||||
throw new InternalError("loadI2Smask65535 failed: " + i2smask65535 + " != " + (short) 0xF3F4);
|
||||
|
||||
char i2us = loadI2US(ia);
|
||||
if (i2us != (char) 0xF3F4)
|
||||
throw new InternalError("loadI2US failed: " + (int) i2us + " != " + (char) 0xF3F4);
|
||||
|
||||
char i2usmask255 = loadI2USmask255(ia);
|
||||
if (i2usmask255 != (char) 0xF4)
|
||||
throw new InternalError("loadI2USmask255 failed: " + (int) i2usmask255 + " != " + (char) 0xF4);
|
||||
|
||||
char i2usmask65535 = loadI2USmask65535(ia);
|
||||
if (i2usmask65535 != (char) 0xF3F4)
|
||||
throw new InternalError("loadI2USmask65535 failed: " + (int) i2usmask65535 + " != " + (char) 0xF3F4);
|
||||
}
|
||||
|
||||
static byte loadS2B (short[] sa) { return (byte) (sa[0] ); }
|
||||
static byte loadS2Bmask255 (short[] sa) { return (byte) (sa[0] & 0xFF ); }
|
||||
|
||||
static byte loadUS2B (char[] ca) { return (byte) (ca[0] ); }
|
||||
static byte loadUS2Bmask255 (char[] ca) { return (byte) (ca[0] & 0xFF ); }
|
||||
|
||||
static byte loadI2B (int[] ia) { return (byte) (ia[0] ); }
|
||||
static byte loadI2Bmask255 (int[] ia) { return (byte) (ia[0] & 0xFF ); }
|
||||
|
||||
static short loadI2S (int[] ia) { return (short) (ia[0] ); }
|
||||
static short loadI2Smask255 (int[] ia) { return (short) (ia[0] & 0xFF ); }
|
||||
static short loadI2Smask65535 (int[] ia) { return (short) (ia[0] & 0xFFFF); }
|
||||
|
||||
static char loadI2US (int[] ia) { return (char) (ia[0] ); }
|
||||
static char loadI2USmask255 (int[] ia) { return (char) (ia[0] & 0xFF ); }
|
||||
static char loadI2USmask65535(int[] ia) { return (char) (ia[0] & 0xFFFF); }
|
||||
}
|
266
hotspot/test/compiler/6823354/Test6823354.java
Normal file
266
hotspot/test/compiler/6823354/Test6823354.java
Normal file
@ -0,0 +1,266 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 6823354
|
||||
* @summary These methods can be instrinsified by using bit scan, bit test, and population count instructions.
|
||||
*
|
||||
* @run main/othervm -Xcomp -XX:CompileOnly=Test6823354.lzcomp,Test6823354.tzcomp,.dolzcomp,.dotzcomp Test6823354
|
||||
*/
|
||||
|
||||
import java.net.URLClassLoader;
|
||||
|
||||
public class Test6823354 {
|
||||
// Arrays of corner case values.
|
||||
static final int[] ia = new int[] { 0, 1, -1, Integer.MIN_VALUE, Integer.MAX_VALUE };
|
||||
static final long[] la = new long[] { 0L, 1L, -1L, Long.MIN_VALUE, Long.MAX_VALUE };
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
// Load the classes and the methods.
|
||||
Integer.numberOfLeadingZeros(0);
|
||||
Integer.numberOfTrailingZeros(0);
|
||||
Long.numberOfLeadingZeros(0);
|
||||
Long.numberOfTrailingZeros(0);
|
||||
|
||||
lz();
|
||||
tz();
|
||||
}
|
||||
|
||||
static void lz() throws Exception {
|
||||
// int
|
||||
|
||||
// Test corner cases.
|
||||
for (int i = 0; i < ia.length; i++) {
|
||||
int x = ia[i];
|
||||
check(x, lzcomp(x), lzint(x));
|
||||
}
|
||||
|
||||
// Test all possible return values.
|
||||
for (int i = 0; i < Integer.SIZE; i++) {
|
||||
int x = 1 << i;
|
||||
check(x, lzcomp(x), lzint(x));
|
||||
}
|
||||
|
||||
String classname = "Test6823354$lzconI";
|
||||
|
||||
// Test Ideal optimizations (constant values).
|
||||
for (int i = 0; i < ia.length; i++) {
|
||||
testclass(classname, ia[i]);
|
||||
}
|
||||
|
||||
// Test Ideal optimizations (constant values).
|
||||
for (int i = 0; i < Integer.SIZE; i++) {
|
||||
int x = 1 << i;
|
||||
testclass(classname, x);
|
||||
}
|
||||
|
||||
|
||||
// long
|
||||
|
||||
// Test corner cases.
|
||||
for (int i = 0; i < ia.length; i++) {
|
||||
long x = la[i];
|
||||
check(x, lzcomp(x), lzint(x));
|
||||
}
|
||||
|
||||
// Test all possible return values.
|
||||
for (int i = 0; i < Long.SIZE; i++) {
|
||||
long x = 1L << i;
|
||||
check(x, lzcomp(x), lzint(x));
|
||||
}
|
||||
|
||||
classname = "Test6823354$lzconL";
|
||||
|
||||
// Test Ideal optimizations (constant values).
|
||||
for (int i = 0; i < la.length; i++) {
|
||||
testclass(classname, la[i]);
|
||||
}
|
||||
|
||||
// Test Ideal optimizations (constant values).
|
||||
for (int i = 0; i < Long.SIZE; i++) {
|
||||
long x = 1L << i;
|
||||
testclass(classname, x);
|
||||
}
|
||||
}
|
||||
|
||||
static void tz() throws Exception {
|
||||
// int
|
||||
|
||||
// Test corner cases.
|
||||
for (int i = 0; i < ia.length; i++) {
|
||||
int x = ia[i];
|
||||
check(x, tzcomp(x), tzint(x));
|
||||
}
|
||||
|
||||
// Test all possible return values.
|
||||
for (int i = 0; i < Integer.SIZE; i++) {
|
||||
int x = 1 << i;
|
||||
check(x, tzcomp(x), tzint(x));
|
||||
}
|
||||
|
||||
String classname = "Test6823354$tzconI";
|
||||
|
||||
// Test Ideal optimizations (constant values).
|
||||
for (int i = 0; i < ia.length; i++) {
|
||||
testclass(classname, ia[i]);
|
||||
}
|
||||
|
||||
// Test Ideal optimizations (constant values).
|
||||
for (int i = 0; i < Integer.SIZE; i++) {
|
||||
int x = 1 << i;
|
||||
testclass(classname, x);
|
||||
}
|
||||
|
||||
|
||||
// long
|
||||
|
||||
// Test corner cases.
|
||||
for (int i = 0; i < la.length; i++) {
|
||||
long x = la[i];
|
||||
check(x, tzcomp(x), tzint(x));
|
||||
}
|
||||
|
||||
// Test all possible return values.
|
||||
for (int i = 0; i < Long.SIZE; i++) {
|
||||
long x = 1L << i;
|
||||
check(x, tzcomp(x), tzint(x));
|
||||
}
|
||||
|
||||
classname = "Test6823354$tzconL";
|
||||
|
||||
// Test Ideal optimizations (constant values).
|
||||
for (int i = 0; i < la.length; i++) {
|
||||
testclass(classname, la[i]);
|
||||
}
|
||||
|
||||
// Test Ideal optimizations (constant values).
|
||||
for (int i = 0; i < Long.SIZE; i++) {
|
||||
long x = 1L << i;
|
||||
testclass(classname, x);
|
||||
}
|
||||
}
|
||||
|
||||
static void check(int value, int result, int expected) {
|
||||
//System.out.println(value + ": " + result + ", " + expected);
|
||||
if (result != expected)
|
||||
throw new InternalError(value + " failed: " + result + " != " + expected);
|
||||
}
|
||||
|
||||
static void check(long value, long result, long expected) {
|
||||
//System.out.println(value + ": " + result + ", " + expected);
|
||||
if (result != expected)
|
||||
throw new InternalError(value + " failed: " + result + " != " + expected);
|
||||
}
|
||||
|
||||
static int lzint( int i) { return Integer.numberOfLeadingZeros(i); }
|
||||
static int lzcomp(int i) { return Integer.numberOfLeadingZeros(i); }
|
||||
|
||||
static int lzint( long l) { return Long.numberOfLeadingZeros(l); }
|
||||
static int lzcomp(long l) { return Long.numberOfLeadingZeros(l); }
|
||||
|
||||
static int tzint( int i) { return Integer.numberOfTrailingZeros(i); }
|
||||
static int tzcomp(int i) { return Integer.numberOfTrailingZeros(i); }
|
||||
|
||||
static int tzint( long l) { return Long.numberOfTrailingZeros(l); }
|
||||
static int tzcomp(long l) { return Long.numberOfTrailingZeros(l); }
|
||||
|
||||
static void testclass(String classname, int x) throws Exception {
|
||||
System.setProperty("value", "" + x);
|
||||
loadandrunclass(classname);
|
||||
}
|
||||
|
||||
static void testclass(String classname, long x) throws Exception {
|
||||
System.setProperty("value", "" + x);
|
||||
loadandrunclass(classname);
|
||||
}
|
||||
|
||||
static void loadandrunclass(String classname) throws Exception {
|
||||
Class cl = Class.forName(classname);
|
||||
URLClassLoader apploader = (URLClassLoader) cl.getClassLoader();
|
||||
ClassLoader loader = new URLClassLoader(apploader.getURLs(), apploader.getParent());
|
||||
Class c = loader.loadClass(classname);
|
||||
Runnable r = (Runnable) c.newInstance();
|
||||
r.run();
|
||||
}
|
||||
|
||||
public static class lzconI implements Runnable {
|
||||
static final int VALUE;
|
||||
|
||||
static {
|
||||
int value = 0;
|
||||
try {
|
||||
value = Integer.decode(System.getProperty("value"));
|
||||
} catch (Throwable e) {}
|
||||
VALUE = value;
|
||||
}
|
||||
|
||||
public void run() { check(VALUE, lzint(VALUE), dolzcomp()); }
|
||||
static int dolzcomp() { return lzcomp(VALUE); }
|
||||
}
|
||||
|
||||
public static class lzconL implements Runnable {
|
||||
static final long VALUE;
|
||||
|
||||
static {
|
||||
long value = 0;
|
||||
try {
|
||||
value = Long.decode(System.getProperty("value"));
|
||||
} catch (Throwable e) {}
|
||||
VALUE = value;
|
||||
}
|
||||
|
||||
public void run() { check(VALUE, lzint(VALUE), dolzcomp()); }
|
||||
static int dolzcomp() { return lzcomp(VALUE); }
|
||||
}
|
||||
|
||||
public static class tzconI implements Runnable {
|
||||
static final int VALUE;
|
||||
|
||||
static {
|
||||
int value = 0;
|
||||
try {
|
||||
value = Integer.decode(System.getProperty("value"));
|
||||
} catch (Throwable e) {}
|
||||
VALUE = value;
|
||||
}
|
||||
|
||||
public void run() { check(VALUE, tzint(VALUE), dotzcomp()); }
|
||||
static int dotzcomp() { return tzcomp(VALUE); }
|
||||
}
|
||||
|
||||
public static class tzconL implements Runnable {
|
||||
static final long VALUE;
|
||||
|
||||
static {
|
||||
long value = 0;
|
||||
try {
|
||||
value = Long.decode(System.getProperty("value"));
|
||||
} catch (Throwable e) {}
|
||||
VALUE = value;
|
||||
}
|
||||
|
||||
public void run() { check(VALUE, tzint(VALUE), dotzcomp()); }
|
||||
static int dotzcomp() { return tzcomp(VALUE); }
|
||||
}
|
||||
}
|
135
hotspot/test/compiler/6832293/Test.java
Normal file
135
hotspot/test/compiler/6832293/Test.java
Normal file
@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6832293
|
||||
* @summary JIT compiler got wrong result in type checking with -server
|
||||
* @run main/othervm -Xcomp -XX:CompileOnly=Test.run Test
|
||||
*/
|
||||
|
||||
import java.io.PrintStream;
|
||||
|
||||
interface SomeInterface {
|
||||
int SEVENS = 777;
|
||||
}
|
||||
|
||||
interface AnotherInterface {
|
||||
int THIRDS = 33;
|
||||
}
|
||||
|
||||
class SomeClass implements SomeInterface {
|
||||
int i;
|
||||
|
||||
SomeClass(int i) {
|
||||
this.i = i;
|
||||
}
|
||||
}
|
||||
|
||||
class ImmediateSubclass extends SomeClass implements SomeInterface {
|
||||
float f;
|
||||
|
||||
ImmediateSubclass(int i, float f) {
|
||||
super(i);
|
||||
this.f = f;
|
||||
}
|
||||
}
|
||||
|
||||
final class FinalSubclass extends ImmediateSubclass implements AnotherInterface {
|
||||
double d;
|
||||
|
||||
FinalSubclass(int i, float f, double d) {
|
||||
super(i, f);
|
||||
this.d = d;
|
||||
}
|
||||
}
|
||||
|
||||
public class Test {
|
||||
|
||||
public static void main(String args[]) throws Exception{
|
||||
/* try to pre initialize */
|
||||
SomeClass[] a=new SomeClass[10];
|
||||
Class.forName("ImmediateSubclass");
|
||||
Class.forName("FinalSubclass");
|
||||
System.exit(run(args, System.out) + 95/*STATUS_TEMP*/);
|
||||
}
|
||||
|
||||
static int errorStatus = 0/*STATUS_PASSED*/;
|
||||
|
||||
static void errorAlert(PrintStream out, int errorLevel) {
|
||||
out.println("Test: failure #" + errorLevel);
|
||||
errorStatus = 2/*STATUS_FAILED*/;
|
||||
}
|
||||
|
||||
static SomeClass[] v2 = new FinalSubclass[4];
|
||||
|
||||
public static int run(String args[],PrintStream out) {
|
||||
int i [], j [];
|
||||
SomeInterface u [], v[] [];
|
||||
AnotherInterface w [];
|
||||
SomeClass x [] [];
|
||||
|
||||
i = new int [10];
|
||||
i[0] = 777;
|
||||
j = (int []) i;
|
||||
if (j != i)
|
||||
errorAlert(out, 2);
|
||||
else if (j.length != 10)
|
||||
errorAlert(out, 3);
|
||||
else if (j[0] != 777)
|
||||
errorAlert(out, 4);
|
||||
|
||||
v = new SomeClass [3] [];
|
||||
x = (SomeClass [] []) v;
|
||||
if (! (x instanceof SomeInterface [] []))
|
||||
errorAlert(out, 5);
|
||||
else if (! (x instanceof SomeClass [] []))
|
||||
errorAlert(out, 6);
|
||||
else if (x != v)
|
||||
errorAlert(out, 7);
|
||||
|
||||
x[0] = (SomeClass []) new ImmediateSubclass [4];
|
||||
if (! (x[0] instanceof ImmediateSubclass []))
|
||||
errorAlert(out, 8);
|
||||
else if (x[0].length != 4)
|
||||
errorAlert(out, 9);
|
||||
|
||||
x[1] = (SomeClass []) v2;
|
||||
if (! (x[1] instanceof FinalSubclass []))
|
||||
errorAlert(out, 10);
|
||||
else if (x[1].length != 4)
|
||||
errorAlert(out, 11);
|
||||
|
||||
w = (AnotherInterface []) x[1];
|
||||
if (! (w instanceof FinalSubclass []))
|
||||
errorAlert(out, 12);
|
||||
else if (w != x[1])
|
||||
errorAlert(out, 13);
|
||||
else if (w.length != 4)
|
||||
errorAlert(out, 14);
|
||||
|
||||
return errorStatus;
|
||||
}
|
||||
}
|
||||
|
119
hotspot/test/compiler/6843752/Test.java
Normal file
119
hotspot/test/compiler/6843752/Test.java
Normal file
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6843752
|
||||
* @summary missing code for an anti-dependent Phi in GCM
|
||||
* @run main/othervm -Xbatch Test
|
||||
*/
|
||||
|
||||
public class Test {
|
||||
|
||||
Item list;
|
||||
|
||||
static class Item {
|
||||
public Item next;
|
||||
public Item prev;
|
||||
public boolean remove;
|
||||
|
||||
Item(boolean r) { remove = r; }
|
||||
}
|
||||
|
||||
private void linkIn(Item item) {
|
||||
Item head = list;
|
||||
if (head == null) {
|
||||
item.next = item;
|
||||
item.prev = item;
|
||||
list = item;
|
||||
} else {
|
||||
item.next = head;
|
||||
item.prev = head.prev;
|
||||
head.prev.next = item;
|
||||
head.prev = item;
|
||||
}
|
||||
}
|
||||
|
||||
private void linkOut(Item item) {
|
||||
Item head = list;
|
||||
if (item.next == item) {
|
||||
list = null;
|
||||
} else {
|
||||
item.prev.next = item.next;
|
||||
item.next.prev = item.prev;
|
||||
if (head == item) {
|
||||
list = item.next;
|
||||
}
|
||||
}
|
||||
item.next = null;
|
||||
item.prev = null; // this is the null pointer we are seeing
|
||||
}
|
||||
|
||||
private void removeItems(int numItems) {
|
||||
Item item = list;
|
||||
if (item == null) {
|
||||
return;
|
||||
}
|
||||
Item last = item.prev;
|
||||
boolean done = false;
|
||||
while (!done && numItems > 1) {
|
||||
// the original code "done = (item == last);" triggered an infinite loop
|
||||
// and was changed slightly in order to produce an exception instead.
|
||||
done = (item.next == last.next);
|
||||
item = item.next;
|
||||
if (item.prev.remove) {
|
||||
linkOut(item.prev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void perform(int numItems) {
|
||||
for (int i = 0; i < numItems; i++) {
|
||||
linkIn(new Item(i == 0));
|
||||
}
|
||||
removeItems(numItems);
|
||||
list = null;
|
||||
}
|
||||
|
||||
static public void main(String[] args) {
|
||||
int caseCnt = 0;
|
||||
Test bj = new Test();
|
||||
try {
|
||||
for (; caseCnt < 500000;) {
|
||||
int numItems = (++caseCnt % 2);
|
||||
if ((caseCnt % 64) == 0) {
|
||||
numItems = 5;
|
||||
}
|
||||
bj.perform(numItems);
|
||||
if ((caseCnt % 100000) == 0) {
|
||||
System.out.println("successfully performed " + caseCnt + " cases");
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("ERROR: crashed during case " + caseCnt);
|
||||
e.printStackTrace(System.out);
|
||||
System.exit(97);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user