# HG changeset patch # User never # Date 1244067410 25200 # Node ID 8b0b8998e1c309895235f2a83db796fc40706981 # Parent 273b2358ef1ac7e618a3f2d26855d075640eb527# Parent 435f0808b826ad7ed2511d2b8b408cdbb60b3b91 Merge diff -r 435f0808b826 -r 8b0b8998e1c3 .hgtags --- a/.hgtags Wed Jun 03 15:02:13 2009 -0700 +++ b/.hgtags Wed Jun 03 15:16:50 2009 -0700 @@ -31,3 +31,4 @@ fafab5d5349c7c066d677538db67a1ee0fb33bd2 jdk7-b54 f8e839c086152da70d6ec5913ba6f9f509282e8d jdk7-b55 a3fd9e40ff2e854f6169eb6d09d491a28634d04f jdk7-b56 +f4cbf78110c726919f46b59a3b054c54c7e889b4 jdk7-b57 diff -r 435f0808b826 -r 8b0b8998e1c3 agent/src/share/classes/sun/jvm/hotspot/HotSpotTypeDataBase.java --- a/agent/src/share/classes/sun/jvm/hotspot/HotSpotTypeDataBase.java Wed Jun 03 15:02:13 2009 -0700 +++ b/agent/src/share/classes/sun/jvm/hotspot/HotSpotTypeDataBase.java Wed Jun 03 15:16:50 2009 -0700 @@ -306,8 +306,6 @@ entryAddr = entryAddr.addOffsetTo(intConstantEntryArrayStride); } while (nameAddr != null); - String symbol = "heapOopSize"; // global int constant and value is initialized at runtime. - addIntConstant(symbol, (int)lookupInProcess(symbol).getCIntegerAt(0, 4, false)); } private void readVMLongConstants() { diff -r 435f0808b826 -r 8b0b8998e1c3 agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java --- a/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java Wed Jun 03 15:02:13 2009 -0700 +++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java Wed Jun 03 15:16:50 2009 -0700 @@ -318,11 +318,17 @@ logMinObjAlignmentInBytes = db.lookupIntConstant("LogMinObjAlignmentInBytes").intValue(); heapWordSize = db.lookupIntConstant("HeapWordSize").intValue(); oopSize = db.lookupIntConstant("oopSize").intValue(); - heapOopSize = db.lookupIntConstant("heapOopSize").intValue(); intxType = db.lookupType("intx"); uintxType = db.lookupType("uintx"); boolType = (CIntegerType) db.lookupType("bool"); + + if (isCompressedOopsEnabled()) { + // Size info for oops within java objects is fixed + heapOopSize = (int)getIntSize(); + } else { + heapOopSize = (int)getOopSize(); + } } /** This could be used by a reflective runtime system */ @@ -343,13 +349,12 @@ } soleInstance = new VM(db, debugger, debugger.getMachineDescription().isBigEndian()); - debugger.putHeapConst(soleInstance.getHeapOopSize(), Universe.getNarrowOopBase(), - Universe.getNarrowOopShift()); - for (Iterator iter = vmInitializedObservers.iterator(); iter.hasNext(); ) { ((Observer) iter.next()).update(null, null); } + debugger.putHeapConst(soleInstance.getHeapOopSize(), Universe.getNarrowOopBase(), + Universe.getNarrowOopShift()); } /** This is used by the debugging system */ diff -r 435f0808b826 -r 8b0b8998e1c3 make/jprt.properties --- a/make/jprt.properties Wed Jun 03 15:02:13 2009 -0700 +++ b/make/jprt.properties Wed Jun 03 15:16:50 2009 -0700 @@ -335,7 +335,19 @@ # 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 + diff -r 435f0808b826 -r 8b0b8998e1c3 make/linux/makefiles/gcc.make --- a/make/linux/makefiles/gcc.make Wed Jun 03 15:02:13 2009 -0700 +++ b/make/linux/makefiles/gcc.make Wed Jun 03 15:16:50 2009 -0700 @@ -171,3 +171,9 @@ 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 diff -r 435f0808b826 -r 8b0b8998e1c3 make/linux/makefiles/jsig.make --- a/make/linux/makefiles/jsig.make Wed Jun 03 15:02:13 2009 -0700 +++ b/make/linux/makefiles/jsig.make Wed Jun 03 15:16:50 2009 -0700 @@ -41,10 +41,15 @@ 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)" diff -r 435f0808b826 -r 8b0b8998e1c3 make/linux/makefiles/saproc.make --- a/make/linux/makefiles/saproc.make Wed Jun 03 15:02:13 2009 -0700 +++ b/make/linux/makefiles/saproc.make Wed Jun 03 15:16:50 2009 -0700 @@ -43,6 +43,11 @@ 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 @@ -I$(BOOT_JAVA_HOME)/include/$(Platform_os_family) \ $(SASRCFILES) \ $(SA_LFLAGS) \ + $(SA_DEBUG_CFLAGS) \ -o $@ \ -lthread_db diff -r 435f0808b826 -r 8b0b8998e1c3 src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp --- a/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Wed Jun 03 15:02:13 2009 -0700 +++ b/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Wed Jun 03 15:16:50 2009 -0700 @@ -378,7 +378,7 @@ 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(); } diff -r 435f0808b826 -r 8b0b8998e1c3 src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp --- a/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp Wed Jun 03 15:02:13 2009 -0700 +++ b/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp Wed Jun 03 15:16:50 2009 -0700 @@ -286,7 +286,7 @@ 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 @@ 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); diff -r 435f0808b826 -r 8b0b8998e1c3 src/cpu/sparc/vm/sparc.ad --- a/src/cpu/sparc/vm/sparc.ad Wed Jun 03 15:02:13 2009 -0700 +++ b/src/cpu/sparc/vm/sparc.ad Wed Jun 03 15:16:50 2009 -0700 @@ -1712,6 +1712,23 @@ 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 @@ // 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ %} %} -// 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 @@ %} %} +// 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 @@ 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 @@ 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 @@ 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 @@ 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) %{ diff -r 435f0808b826 -r 8b0b8998e1c3 src/cpu/x86/vm/assembler_x86.cpp --- a/src/cpu/x86/vm/assembler_x86.cpp Wed Jun 03 15:02:13 2009 -0700 +++ b/src/cpu/x86/vm/assembler_x86.cpp Wed Jun 03 15:16:50 2009 -0700 @@ -952,6 +952,21 @@ 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::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 @@ 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 @@ 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(), "")); diff -r 435f0808b826 -r 8b0b8998e1c3 src/cpu/x86/vm/assembler_x86.hpp --- a/src/cpu/x86/vm/assembler_x86.hpp Wed Jun 03 15:02:13 2009 -0700 +++ b/src/cpu/x86/vm/assembler_x86.hpp Wed Jun 03 15:16:50 2009 -0700 @@ -757,6 +757,14 @@ 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 @@ 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, diff -r 435f0808b826 -r 8b0b8998e1c3 src/cpu/x86/vm/c1_LIRAssembler_x86.cpp --- a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Wed Jun 03 15:02:13 2009 -0700 +++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Wed Jun 03 15:16:50 2009 -0700 @@ -439,7 +439,7 @@ // 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); diff -r 435f0808b826 -r 8b0b8998e1c3 src/cpu/x86/vm/c1_MacroAssembler_x86.cpp --- a/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp Wed Jun 03 15:02:13 2009 -0700 +++ b/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp Wed Jun 03 15:16:50 2009 -0700 @@ -258,7 +258,7 @@ } } - 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 @@ 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))); } diff -r 435f0808b826 -r 8b0b8998e1c3 src/cpu/x86/vm/vm_version_x86.cpp --- a/src/cpu/x86/vm/vm_version_x86.cpp Wed Jun 03 15:02:13 2009 -0700 +++ b/src/cpu/x86/vm/vm_version_x86.cpp Wed Jun 03 15:16:50 2009 -0700 @@ -284,7 +284,7 @@ } 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 @@ (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 @@ 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 diff -r 435f0808b826 -r 8b0b8998e1c3 src/cpu/x86/vm/vm_version_x86.hpp --- a/src/cpu/x86/vm/vm_version_x86.hpp Wed Jun 03 15:02:13 2009 -0700 +++ b/src/cpu/x86/vm/vm_version_x86.hpp Wed Jun 03 15:16:50 2009 -0700 @@ -120,7 +120,7 @@ uint32_t LahfSahf : 1, CmpLegacy : 1, : 4, - abm : 1, + lzcnt : 1, sse4a : 1, misalignsse : 1, prefetchw : 1, @@ -182,7 +182,8 @@ 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 @@ 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 @@ 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 @@ 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; } diff -r 435f0808b826 -r 8b0b8998e1c3 src/cpu/x86/vm/x86_32.ad --- a/src/cpu/x86/vm/x86_32.ad Wed Jun 03 15:02:13 2009 -0700 +++ b/src/cpu/x86/vm/x86_32.ad Wed Jun 03 15:16:50 2009 -0700 @@ -1281,6 +1281,13 @@ } +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 @@ 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 @@ %} +//---------- 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 @@ 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 @@ 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 @@ 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 @@ // 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); %} diff -r 435f0808b826 -r 8b0b8998e1c3 src/cpu/x86/vm/x86_64.ad --- a/src/cpu/x86/vm/x86_64.ad Wed Jun 03 15:02:13 2009 -0700 +++ b/src/cpu/x86/vm/x86_64.ad Wed Jun 03 15:16:50 2009 -0700 @@ -1980,6 +1980,13 @@ } +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 @@ 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 @@ 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 @@ 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 @@ %} +//---------- 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) %{ diff -r 435f0808b826 -r 8b0b8998e1c3 src/share/vm/adlc/filebuff.hpp --- a/src/share/vm/adlc/filebuff.hpp Wed Jun 03 15:02:13 2009 -0700 +++ b/src/share/vm/adlc/filebuff.hpp Wed Jun 03 15:16:50 2009 -0700 @@ -73,7 +73,7 @@ // 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--------------------------------- diff -r 435f0808b826 -r 8b0b8998e1c3 src/share/vm/adlc/output_c.cpp --- a/src/share/vm/adlc/output_c.cpp Wed Jun 03 15:02:13 2009 -0700 +++ b/src/share/vm/adlc/output_c.cpp Wed Jun 03 15:16:50 2009 -0700 @@ -1745,6 +1745,7 @@ 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 @@ 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"); diff -r 435f0808b826 -r 8b0b8998e1c3 src/share/vm/c1/c1_Compilation.cpp --- a/src/share/vm/c1/c1_Compilation.cpp Wed Jun 03 15:02:13 2009 -0700 +++ b/src/share/vm/c1/c1_Compilation.cpp Wed Jun 03 15:16:50 2009 -0700 @@ -319,7 +319,7 @@ 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 @@ 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); diff -r 435f0808b826 -r 8b0b8998e1c3 src/share/vm/c1/c1_GraphBuilder.cpp --- a/src/share/vm/c1/c1_GraphBuilder.cpp Wed Jun 03 15:02:13 2009 -0700 +++ b/src/share/vm/c1/c1_GraphBuilder.cpp Wed Jun 03 15:16:50 2009 -0700 @@ -1662,7 +1662,7 @@ // 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 @@ 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); diff -r 435f0808b826 -r 8b0b8998e1c3 src/share/vm/c1/c1_LIRGenerator.cpp --- a/src/share/vm/c1/c1_LIRGenerator.cpp Wed Jun 03 15:02:13 2009 -0700 +++ b/src/share/vm/c1/c1_LIRGenerator.cpp Wed Jun 03 15:16:50 2009 -0700 @@ -1064,7 +1064,7 @@ 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 @@ __ 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 @@ 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 @@ java_index += type2size[t]; } - if (DTraceMethodProbes) { + if (compilation()->env()->dtrace_method_probes()) { BasicTypeList signature; signature.append(T_INT); // thread signature.append(T_OBJECT); // methodOop diff -r 435f0808b826 -r 8b0b8998e1c3 src/share/vm/ci/ciEnv.cpp --- a/src/share/vm/ci/ciEnv.cpp Wed Jun 03 15:02:13 2009 -0700 +++ b/src/share/vm/ci/ciEnv.cpp Wed Jun 03 15:16:50 2009 -0700 @@ -171,6 +171,34 @@ } // ------------------------------------------------------------------ +// 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) { VM_ENTRY_MARK; @@ -810,16 +838,39 @@ // 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()); diff -r 435f0808b826 -r 8b0b8998e1c3 src/share/vm/ci/ciEnv.hpp --- a/src/share/vm/ci/ciEnv.hpp Wed Jun 03 15:02:13 2009 -0700 +++ b/src/share/vm/ci/ciEnv.hpp Wed Jun 03 15:16:50 2009 -0700 @@ -53,6 +53,18 @@ 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 @@ 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; } diff -r 435f0808b826 -r 8b0b8998e1c3 src/share/vm/ci/ciMethod.cpp --- a/src/share/vm/ci/ciMethod.cpp Wed Jun 03 15:02:13 2009 -0700 +++ b/src/share/vm/ci/ciMethod.cpp Wed Jun 03 15:16:50 2009 -0700 @@ -60,7 +60,8 @@ _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 @@ 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 @@ _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); } diff -r 435f0808b826 -r 8b0b8998e1c3 src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Wed Jun 03 15:02:13 2009 -0700 +++ b/src/share/vm/classfile/vmSymbols.hpp Wed Jun 03 15:16:50 2009 -0700 @@ -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) \ \ diff -r 435f0808b826 -r 8b0b8998e1c3 src/share/vm/compiler/compileBroker.cpp --- a/src/share/vm/compiler/compileBroker.cpp Wed Jun 03 15:02:13 2009 -0700 +++ b/src/share/vm/compiler/compileBroker.cpp Wed Jun 03 15:16:50 2009 -0700 @@ -1530,6 +1530,12 @@ 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); diff -r 435f0808b826 -r 8b0b8998e1c3 src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp --- a/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp Wed Jun 03 15:02:13 2009 -0700 +++ b/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp Wed Jun 03 15:16:50 2009 -0700 @@ -53,7 +53,9 @@ ResourceMark rm; HandleMark hm; - if (TraceG1Refine) gclog_or_tty->print_cr("G1-Refine starting pass"); + if (G1TraceConcurrentRefinement) { + gclog_or_tty->print_cr("G1-Refine starting pass"); + } _sts.join(); bool no_sleep = _cg1r->refine(); _sts.leave(); @@ -207,9 +209,9 @@ void ConcurrentG1RefineThread::yield() { - if (TraceG1Refine) gclog_or_tty->print_cr("G1-Refine-yield"); + if (G1TraceConcurrentRefinement) gclog_or_tty->print_cr("G1-Refine-yield"); _sts.yield("G1 refine"); - if (TraceG1Refine) gclog_or_tty->print_cr("G1-Refine-yield-end"); + if (G1TraceConcurrentRefinement) gclog_or_tty->print_cr("G1-Refine-yield-end"); } void ConcurrentG1RefineThread::stop() { @@ -230,7 +232,7 @@ Terminator_lock->wait(); } } - if (TraceG1Refine) gclog_or_tty->print_cr("G1-Refine-stop"); + if (G1TraceConcurrentRefinement) gclog_or_tty->print_cr("G1-Refine-stop"); } void ConcurrentG1RefineThread::print() { diff -r 435f0808b826 -r 8b0b8998e1c3 src/share/vm/gc_implementation/g1/concurrentMark.cpp --- a/src/share/vm/gc_implementation/g1/concurrentMark.cpp Wed Jun 03 15:02:13 2009 -0700 +++ b/src/share/vm/gc_implementation/g1/concurrentMark.cpp Wed Jun 03 15:16:50 2009 -0700 @@ -448,8 +448,8 @@ gclog_or_tty->print_cr("[global] init, heap start = "PTR_FORMAT", " "heap end = "PTR_FORMAT, _heap_start, _heap_end); - _markStack.allocate(G1CMStackSize); - _regionStack.allocate(G1CMRegionStackSize); + _markStack.allocate(G1MarkStackSize); + _regionStack.allocate(G1MarkRegionStackSize); // Create & start a ConcurrentMark thread. if (G1ConcMark) { @@ -499,20 +499,21 @@ _marking_task_overhead = 1.0; } else { if (ParallelMarkingThreads > 0) { - // notice that ParallelMarkingThreads overwrites G1MarkingOverheadPerc + // notice that ParallelMarkingThreads overwrites G1MarkingOverheadPercent // if both are set _parallel_marking_threads = ParallelMarkingThreads; _sleep_factor = 0.0; _marking_task_overhead = 1.0; - } else if (G1MarkingOverheadPerc > 0) { + } else if (G1MarkingOverheadPercent > 0) { // we will calculate the number of parallel marking threads // based on a target overhead with respect to the soft real-time // goal - double marking_overhead = (double) G1MarkingOverheadPerc / 100.0; + double marking_overhead = (double) G1MarkingOverheadPercent / 100.0; double overall_cm_overhead = - (double) G1MaxPauseTimeMS * marking_overhead / (double) G1TimeSliceMS; + (double) MaxGCPauseMillis * marking_overhead / + (double) GCPauseIntervalMillis; double cpu_ratio = 1.0 / (double) os::processor_count(); double marking_thread_num = ceil(overall_cm_overhead / cpu_ratio); double marking_task_overhead = @@ -1747,7 +1748,7 @@ g1h->increment_total_collections(); #ifndef PRODUCT - if (G1VerifyConcMark) { + if (VerifyDuringGC) { G1CollectedHeap::heap()->prepare_for_verify(); G1CollectedHeap::heap()->verify(true,false); } diff -r 435f0808b826 -r 8b0b8998e1c3 src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp --- a/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp Wed Jun 03 15:02:13 2009 -0700 +++ b/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp Wed Jun 03 15:16:50 2009 -0700 @@ -136,9 +136,6 @@ iter++; if (!cm()->has_aborted()) { _cm->markFromRoots(); - } else { - if (TraceConcurrentMark) - gclog_or_tty->print_cr("CM-skip-mark-from-roots"); } double mark_end_time = os::elapsedVTime(); @@ -163,9 +160,6 @@ sprintf(verbose_str, "GC remark"); VM_CGC_Operation op(&final_cl, verbose_str); VMThread::execute(&op); - } else { - if (TraceConcurrentMark) - gclog_or_tty->print_cr("CM-skip-remark"); } if (cm()->restart_for_overflow() && G1TraceMarkStackOverflow) { @@ -208,8 +202,6 @@ count_end_sec - count_start_sec); } } - } else { - if (TraceConcurrentMark) gclog_or_tty->print_cr("CM-skip-end-game"); } double end_time = os::elapsedVTime(); _vtime_count_accum += (end_time - counting_start_time); @@ -230,7 +222,6 @@ VM_CGC_Operation op(&cl_cl, verbose_str); VMThread::execute(&op); } else { - if (TraceConcurrentMark) gclog_or_tty->print_cr("CM-skip-cleanup"); G1CollectedHeap::heap()->set_marking_complete(); } @@ -287,9 +278,7 @@ void ConcurrentMarkThread::yield() { - if (TraceConcurrentMark) gclog_or_tty->print_cr("CM-yield"); _sts.yield("Concurrent Mark"); - if (TraceConcurrentMark) gclog_or_tty->print_cr("CM-yield-end"); } void ConcurrentMarkThread::stop() { @@ -299,7 +288,6 @@ while (!_has_terminated) { Terminator_lock->wait(); } - if (TraceConcurrentMark) gclog_or_tty->print_cr("CM-stop"); } void ConcurrentMarkThread::print() { @@ -314,12 +302,10 @@ // below while the world is otherwise stopped. MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag); while (!started()) { - if (TraceConcurrentMark) gclog_or_tty->print_cr("CM-sleeping"); CGC_lock->wait(Mutex::_no_safepoint_check_flag); } set_in_progress(); clear_started(); - if (TraceConcurrentMark) gclog_or_tty->print_cr("CM-starting"); } // Note: this method, although exported by the ConcurrentMarkSweepThread, diff -r 435f0808b826 -r 8b0b8998e1c3 src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Wed Jun 03 15:02:13 2009 -0700 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Wed Jun 03 15:16:50 2009 -0700 @@ -528,7 +528,7 @@ res->zero_fill_state() == HeapRegion::Allocated)), "Non-young alloc Regions must be zero filled (and non-H)"); - if (G1TraceRegions) { + if (G1PrintRegions) { if (res != NULL) { gclog_or_tty->print_cr("new alloc region %d:["PTR_FORMAT", "PTR_FORMAT"], " "top "PTR_FORMAT, @@ -2282,13 +2282,13 @@ // to that. g1_policy()->print_tracing_info(); } - if (SummarizeG1RSStats) { + if (G1SummarizeRSetStats) { g1_rem_set()->print_summary_info(); } - if (SummarizeG1ConcMark) { + if (G1SummarizeConcurrentMark) { concurrent_mark()->print_summary_info(); } - if (SummarizeG1ZFStats) { + if (G1SummarizeZFStats) { ConcurrentZFThread::print_summary_info(); } g1_policy()->print_yg_surv_rate_info(); @@ -3255,7 +3255,7 @@ HeapRegion* r = heap_region_containing(old); if (!r->evacuation_failed()) { r->set_evacuation_failed(true); - if (G1TraceRegions) { + if (G1PrintRegions) { gclog_or_tty->print("evacuation failed in heap region "PTR_FORMAT" " "["PTR_FORMAT","PTR_FORMAT")\n", r, r->bottom(), r->end()); @@ -3466,7 +3466,7 @@ } static size_t gclab_word_size() { - return ParallelGCG1AllocBufferSize / HeapWordSize; + return G1ParallelGCAllocBufferSize / HeapWordSize; } static size_t bitmap_size_in_bits() { @@ -3616,7 +3616,7 @@ public: G1ParGCAllocBuffer() : - ParGCAllocBuffer(ParallelGCG1AllocBufferSize / HeapWordSize), + ParGCAllocBuffer(G1ParallelGCAllocBufferSize / HeapWordSize), _during_marking(G1CollectedHeap::heap()->mark_in_progress()), _bitmap(G1CollectedHeap::heap()->reserved_region().start()), _retired(false) @@ -3812,14 +3812,14 @@ HeapWord* obj = NULL; if (word_sz * 100 < - (size_t)(ParallelGCG1AllocBufferSize / HeapWordSize) * + (size_t)(G1ParallelGCAllocBufferSize / HeapWordSize) * ParallelGCBufferWastePct) { G1ParGCAllocBuffer* alloc_buf = alloc_buffer(purpose); add_to_alloc_buffer_waste(alloc_buf->words_remaining()); alloc_buf->retire(false, false); HeapWord* buf = - _g1h->par_allocate_during_gc(purpose, ParallelGCG1AllocBufferSize / HeapWordSize); + _g1h->par_allocate_during_gc(purpose, G1ParallelGCAllocBufferSize / HeapWordSize); if (buf == NULL) return NULL; // Let caller handle allocation failure. // Otherwise. alloc_buf->set_buf(buf); @@ -4331,7 +4331,7 @@ _g1h->g1_policy()->record_obj_copy_time(i, elapsed_ms-term_ms); _g1h->g1_policy()->record_termination_time(i, term_ms); } - if (G1UseSurvivorSpace) { + if (G1UseSurvivorSpaces) { _g1h->g1_policy()->record_thread_age_table(pss.age_table()); } _g1h->update_surviving_young_words(pss.surviving_young_words()+1); @@ -4435,28 +4435,6 @@ // XXX What should this be doing in the parallel case? g1_policy()->record_collection_pause_end_CH_strong_roots(); - if (G1VerifyRemSet) { - // :::: FIXME :::: - // The stupid remembered set doesn't know how to filter out dead - // objects, which the smart one does, and so when it is created - // and then compared the number of entries in each differs and - // the verification code fails. - guarantee(false, "verification code is broken, see note"); - - // Let's make sure that the current rem set agrees with the stupidest - // one possible! - bool refs_enabled = ref_processor()->discovery_enabled(); - if (refs_enabled) ref_processor()->disable_discovery(); - StupidG1RemSet stupid(this); - count_closure.n = 0; - stupid.oops_into_collection_set_do(&count_closure, worker_i); - int stupid_n = count_closure.n; - count_closure.n = 0; - g1_rem_set()->oops_into_collection_set_do(&count_closure, worker_i); - guarantee(count_closure.n == stupid_n, "Old and new rem sets differ."); - gclog_or_tty->print_cr("\nFound %d pointers in heap RS.", count_closure.n); - if (refs_enabled) ref_processor()->enable_discovery(); - } if (scan_so != NULL) { scan_scan_only_set(scan_so, worker_i); } diff -r 435f0808b826 -r 8b0b8998e1c3 src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp Wed Jun 03 15:02:13 2009 -0700 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp Wed Jun 03 15:16:50 2009 -0700 @@ -37,8 +37,9 @@ inline HeapRegion* G1CollectedHeap::heap_region_containing_raw(const void* addr) const { assert(_g1_reserved.contains(addr), "invariant"); - size_t index = ((intptr_t) addr - (intptr_t) _g1_reserved.start()) - >> HeapRegion::LogOfHRGrainBytes; + size_t index = pointer_delta(addr, _g1_reserved.start(), 1) + >> HeapRegion::LogOfHRGrainBytes; + HeapRegion* res = _hrs->at(index); assert(res == _hrs->addr_to_region(addr), "sanity"); return res; diff -r 435f0808b826 -r 8b0b8998e1c3 src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp --- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Wed Jun 03 15:02:13 2009 -0700 +++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Wed Jun 03 15:16:50 2009 -0700 @@ -136,7 +136,7 @@ _scanned_cards_seq(new TruncatedSeq(TruncatedSeqLength)), _rs_lengths_seq(new TruncatedSeq(TruncatedSeqLength)), - _pause_time_target_ms((double) G1MaxPauseTimeMS), + _pause_time_target_ms((double) MaxGCPauseMillis), // @@ -220,7 +220,7 @@ _par_last_termination_times_ms = new double[_parallel_gc_threads]; // start conservatively - _expensive_region_limit_ms = 0.5 * (double) G1MaxPauseTimeMS; + _expensive_region_limit_ms = 0.5 * (double) MaxGCPauseMillis; // @@ -249,12 +249,12 @@ // - double time_slice = (double) G1TimeSliceMS / 1000.0; - double max_gc_time = (double) G1MaxPauseTimeMS / 1000.0; + double time_slice = (double) GCPauseIntervalMillis / 1000.0; + double max_gc_time = (double) MaxGCPauseMillis / 1000.0; guarantee(max_gc_time < time_slice, "Max GC time should not be greater than the time slice"); _mmu_tracker = new G1MMUTrackerQueue(time_slice, max_gc_time); - _sigma = (double) G1ConfidencePerc / 100.0; + _sigma = (double) G1ConfidencePercent / 100.0; // start conservatively (around 50ms is about right) _concurrent_mark_init_times_ms->add(0.05); @@ -262,7 +262,7 @@ _concurrent_mark_cleanup_times_ms->add(0.20); _tenuring_threshold = MaxTenuringThreshold; - if (G1UseSurvivorSpace) { + if (G1UseSurvivorSpaces) { // if G1FixedSurvivorSpaceSize is 0 which means the size is not // fixed, then _max_survivor_regions will be calculated at // calculate_young_list_target_config during initialization @@ -451,7 +451,7 @@ guarantee( adaptive_young_list_length(), "pre-condition" ); double start_time_sec = os::elapsedTime(); - size_t min_reserve_perc = MAX2((size_t)2, (size_t)G1MinReservePerc); + size_t min_reserve_perc = MAX2((size_t)2, (size_t)G1MinReservePercent); min_reserve_perc = MIN2((size_t) 50, min_reserve_perc); size_t reserve_regions = (size_t) ((double) min_reserve_perc * (double) _g1->n_regions() / 100.0); @@ -1109,7 +1109,7 @@ _short_lived_surv_rate_group->record_scan_only_prefix(short_lived_so_length); tag_scan_only(short_lived_so_length); - if (G1UseSurvivorSpace) { + if (G1UseSurvivorSpaces) { _survivors_age_table.clear(); } @@ -1826,11 +1826,11 @@ _rs_lengths_seq->add((double) _max_rs_lengths); double expensive_region_limit_ms = - (double) G1MaxPauseTimeMS - predict_constant_other_time_ms(); + (double) MaxGCPauseMillis - predict_constant_other_time_ms(); if (expensive_region_limit_ms < 0.0) { // this means that the other time was predicted to be longer than // than the max pause time - expensive_region_limit_ms = (double) G1MaxPauseTimeMS; + expensive_region_limit_ms = (double) MaxGCPauseMillis; } _expensive_region_limit_ms = expensive_region_limit_ms; @@ -2093,24 +2093,24 @@ } double G1CollectorPolicy::recent_avg_time_for_pauses_ms() { - if (_recent_pause_times_ms->num() == 0) return (double) G1MaxPauseTimeMS; + if (_recent_pause_times_ms->num() == 0) return (double) MaxGCPauseMillis; else return _recent_pause_times_ms->avg(); } double G1CollectorPolicy::recent_avg_time_for_CH_strong_ms() { if (_recent_CH_strong_roots_times_ms->num() == 0) - return (double)G1MaxPauseTimeMS/3.0; + return (double)MaxGCPauseMillis/3.0; else return _recent_CH_strong_roots_times_ms->avg(); } double G1CollectorPolicy::recent_avg_time_for_G1_strong_ms() { if (_recent_G1_strong_roots_times_ms->num() == 0) - return (double)G1MaxPauseTimeMS/3.0; + return (double)MaxGCPauseMillis/3.0; else return _recent_G1_strong_roots_times_ms->avg(); } double G1CollectorPolicy::recent_avg_time_for_evac_ms() { - if (_recent_evac_times_ms->num() == 0) return (double)G1MaxPauseTimeMS/3.0; + if (_recent_evac_times_ms->num() == 0) return (double)MaxGCPauseMillis/3.0; else return _recent_evac_times_ms->avg(); } @@ -2197,17 +2197,18 @@ } size_t G1CollectorPolicy::expansion_amount() { - if ((int)(recent_avg_pause_time_ratio() * 100.0) > G1GCPct) { - // We will double the existing space, or take G1ExpandByPctOfAvail % of - // the available expansion space, whichever is smaller, bounded below - // by a minimum expansion (unless that's all that's left.) + if ((int)(recent_avg_pause_time_ratio() * 100.0) > G1GCPercent) { + // We will double the existing space, or take + // G1ExpandByPercentOfAvailable % of the available expansion + // space, whichever is smaller, bounded below by a minimum + // expansion (unless that's all that's left.) const size_t min_expand_bytes = 1*M; size_t reserved_bytes = _g1->g1_reserved_obj_bytes(); size_t committed_bytes = _g1->capacity(); size_t uncommitted_bytes = reserved_bytes - committed_bytes; size_t expand_bytes; size_t expand_bytes_via_pct = - uncommitted_bytes * G1ExpandByPctOfAvail / 100; + uncommitted_bytes * G1ExpandByPercentOfAvailable / 100; expand_bytes = MIN2(expand_bytes_via_pct, committed_bytes); expand_bytes = MAX2(expand_bytes, min_expand_bytes); expand_bytes = MIN2(expand_bytes, uncommitted_bytes); @@ -2591,7 +2592,7 @@ // Calculates survivor space parameters. void G1CollectorPolicy::calculate_survivors_policy() { - if (!G1UseSurvivorSpace) { + if (!G1UseSurvivorSpaces) { return; } if (G1FixedSurvivorSpaceSize == 0) { @@ -2851,7 +2852,7 @@ // estimate of the number of live bytes. void G1CollectorPolicy:: add_to_collection_set(HeapRegion* hr) { - if (G1TraceRegions) { + if (G1PrintRegions) { gclog_or_tty->print_cr("added region to cset %d:["PTR_FORMAT", "PTR_FORMAT"], " "top "PTR_FORMAT", young %s", hr->hrs_index(), hr->bottom(), hr->end(), diff -r 435f0808b826 -r 8b0b8998e1c3 src/share/vm/gc_implementation/g1/g1MarkSweep.cpp --- a/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp Wed Jun 03 15:02:13 2009 -0700 +++ b/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp Wed Jun 03 15:16:50 2009 -0700 @@ -57,7 +57,7 @@ mark_sweep_phase1(marked_for_unloading, clear_all_softrefs); - if (G1VerifyConcMark) { + if (VerifyDuringGC) { G1CollectedHeap* g1h = G1CollectedHeap::heap(); g1h->checkConcurrentMark(); } diff -r 435f0808b826 -r 8b0b8998e1c3 src/share/vm/gc_implementation/g1/g1RemSet.cpp --- a/src/share/vm/gc_implementation/g1/g1RemSet.cpp Wed Jun 03 15:02:13 2009 -0700 +++ b/src/share/vm/gc_implementation/g1/g1RemSet.cpp Wed Jun 03 15:16:50 2009 -0700 @@ -180,6 +180,7 @@ CardTableModRefBS *_ct_bs; int _worker_i; bool _try_claimed; + size_t _min_skip_distance, _max_skip_distance; public: ScanRSClosure(OopsInHeapRegionClosure* oc, int worker_i) : _oc(oc), @@ -191,6 +192,8 @@ _g1h = G1CollectedHeap::heap(); _bot_shared = _g1h->bot_shared(); _ct_bs = (CardTableModRefBS*) (_g1h->barrier_set()); + _min_skip_distance = 16; + _max_skip_distance = 2 * _g1h->n_par_threads() * _min_skip_distance; } void set_try_claimed() { _try_claimed = true; } @@ -245,9 +248,13 @@ HeapRegionRemSetIterator* iter = _g1h->rem_set_iterator(_worker_i); hrrs->init_iterator(iter); size_t card_index; + size_t skip_distance = 0, current_card = 0, jump_to_card = 0; while (iter->has_next(card_index)) { + if (current_card < jump_to_card) { + ++current_card; + continue; + } HeapWord* card_start = _g1h->bot_shared()->address_for_index(card_index); - #if 0 gclog_or_tty->print("Rem set iteration yielded card [" PTR_FORMAT ", " PTR_FORMAT ").\n", card_start, card_start + CardTableModRefBS::card_size_in_words); @@ -257,20 +264,28 @@ assert(card_region != NULL, "Yielding cards not in the heap?"); _cards++; - if (!card_region->in_collection_set()) { - // If the card is dirty, then we will scan it during updateRS. - if (!_ct_bs->is_card_claimed(card_index) && - !_ct_bs->is_card_dirty(card_index)) { - assert(_ct_bs->is_card_clean(card_index) || - _ct_bs->is_card_claimed(card_index) || - _ct_bs->is_card_deferred(card_index), - "Card is either clean, claimed or deferred"); - if (_ct_bs->claim_card(card_index)) + // If the card is dirty, then we will scan it during updateRS. + if (!card_region->in_collection_set() && !_ct_bs->is_card_dirty(card_index)) { + if (!_ct_bs->is_card_claimed(card_index) && _ct_bs->claim_card(card_index)) { scanCard(card_index, card_region); - } + } else if (_try_claimed) { + if (jump_to_card == 0 || jump_to_card != current_card) { + // We did some useful work in the previous iteration. + // Decrease the distance. + skip_distance = MAX2(skip_distance >> 1, _min_skip_distance); + } else { + // Previous iteration resulted in a claim failure. + // Increase the distance. + skip_distance = MIN2(skip_distance << 1, _max_skip_distance); + } + jump_to_card = current_card + skip_distance; + } } + ++current_card; } - hrrs->set_iter_complete(); + if (!_try_claimed) { + hrrs->set_iter_complete(); + } return false; } // Set all cards back to clean. @@ -508,7 +523,7 @@ // and they are causing failures. When we resolve said race // conditions, we'll revert back to parallel remembered set // updating and scanning. See CRs 6677707 and 6677708. - if (G1EnableParallelRSetUpdating || (worker_i == 0)) { + if (G1ParallelRSetUpdatingEnabled || (worker_i == 0)) { updateRS(worker_i); scanNewRefsRS(oc, worker_i); } else { @@ -517,7 +532,7 @@ _g1p->record_update_rs_time(worker_i, 0.0); _g1p->record_scan_new_refs_time(worker_i, 0.0); } - if (G1EnableParallelRSetScanning || (worker_i == 0)) { + if (G1ParallelRSetScanningEnabled || (worker_i == 0)) { scanRS(oc, worker_i); } else { _g1p->record_scan_rs_start_time(worker_i, os::elapsedTime()); diff -r 435f0808b826 -r 8b0b8998e1c3 src/share/vm/gc_implementation/g1/g1_globals.hpp --- a/src/share/vm/gc_implementation/g1/g1_globals.hpp Wed Jun 03 15:02:13 2009 -0700 +++ b/src/share/vm/gc_implementation/g1/g1_globals.hpp Wed Jun 03 15:16:50 2009 -0700 @@ -28,87 +28,65 @@ #define G1_FLAGS(develop, develop_pd, product, product_pd, diagnostic, experimental, notproduct, manageable, product_rw) \ \ - product(intx, ParallelGCG1AllocBufferSize, 8*K, \ + product(intx, G1ParallelGCAllocBufferSize, 8*K, \ "Size of parallel G1 allocation buffers in to-space.") \ \ - product(intx, G1TimeSliceMS, 500, \ - "Time slice for MMU specification") \ - \ - product(intx, G1MaxPauseTimeMS, 200, \ - "Max GC time per MMU time slice") \ - \ - product(intx, G1ConfidencePerc, 50, \ + product(intx, G1ConfidencePercent, 50, \ "Confidence level for MMU/pause predictions") \ \ - product(intx, G1MarkingOverheadPerc, 0, \ + develop(intx, G1MarkingOverheadPercent, 0, \ "Overhead of concurrent marking") \ \ - product(bool, G1AccountConcurrentOverhead, false, \ + develop(bool, G1AccountConcurrentOverhead, false, \ "Whether soft real-time compliance in G1 will take into account" \ "concurrent overhead") \ \ product(intx, G1YoungGenSize, 0, \ "Size of the G1 young generation, 0 is the adaptive policy") \ \ - product(bool, G1Gen, true, \ + develop(bool, G1Gen, true, \ "If true, it will enable the generational G1") \ \ - develop(intx, G1GCPct, 10, \ + develop(intx, G1GCPercent, 10, \ "The desired percent time spent on GC") \ \ - product(intx, G1PolicyVerbose, 0, \ + develop(intx, G1PolicyVerbose, 0, \ "The verbosity level on G1 policy decisions") \ \ develop(bool, G1UseHRIntoRS, true, \ "Determines whether the 'advanced' HR Into rem set is used.") \ \ - product(bool, G1VerifyRemSet, false, \ - "If true, verify the rem set functioning at each GC") \ - \ - product(bool, G1VerifyConcMark, false, \ - "If true, verify the conc marking code at full GC time") \ - \ develop(intx, G1MarkingVerboseLevel, 0, \ "Level (0-4) of verboseness of the marking code") \ \ - develop(bool, G1VerifyConcMarkPrintReachable, true, \ + develop(bool, G1VerifyConcMarkPrintReachable, false, \ "If conc mark verification fails, print reachable objects") \ \ develop(bool, G1TraceMarkStackOverflow, false, \ "If true, extra debugging code for CM restart for ovflw.") \ \ - product(bool, G1VerifyMarkingInEvac, false, \ - "If true, verify marking info during evacuation") \ - \ develop(intx, G1PausesBtwnConcMark, -1, \ "If positive, fixed number of pauses between conc markings") \ \ - product(intx, G1EfficiencyPctCausesMark, 80, \ - "The cum gc efficiency since mark fall-off that causes " \ - "new marking") \ - \ - product(bool, TraceConcurrentMark, false, \ - "Trace concurrent mark") \ - \ - product(bool, SummarizeG1ConcMark, false, \ + diagnostic(bool, G1SummarizeConcurrentMark, false, \ "Summarize concurrent mark info") \ \ - product(bool, SummarizeG1RSStats, false, \ + diagnostic(bool, G1SummarizeRSetStats, false, \ "Summarize remembered set processing info") \ \ - product(bool, SummarizeG1ZFStats, false, \ + diagnostic(bool, G1SummarizeZFStats, false, \ "Summarize zero-filling info") \ \ - product(bool, TraceG1Refine, false, \ + develop(bool, G1TraceConcurrentRefinement, false, \ "Trace G1 concurrent refinement") \ \ develop(bool, G1ConcMark, true, \ "If true, run concurrent marking for G1") \ \ - product(intx, G1CMStackSize, 2 * 1024 * 1024, \ + product(intx, G1MarkStackSize, 2 * 1024 * 1024, \ "Size of the mark stack for concurrent marking.") \ \ - product(intx, G1CMRegionStackSize, 1024 * 1024, \ + product(intx, G1MarkRegionStackSize, 1024 * 1024, \ "Size of the region stack for concurrent marking.") \ \ develop(bool, G1ConcRefine, true, \ @@ -121,7 +99,7 @@ "Number of heap regions of alloc ahead of starting collection " \ "pause to start concurrent refinement (initially)") \ \ - product(bool, G1SmoothConcRefine, true, \ + develop(bool, G1SmoothConcRefine, true, \ "Attempts to smooth out the overhead of concurrent refinement") \ \ develop(bool, G1ConcZeroFill, true, \ @@ -157,7 +135,7 @@ develop(bool, G1SATBPrintStubs, false, \ "If true, print generated stubs for the SATB barrier") \ \ - product(intx, G1ExpandByPctOfAvail, 20, \ + product(intx, G1ExpandByPercentOfAvailable, 20, \ "When expanding, % of uncommitted space to claim.") \ \ develop(bool, G1RSBarrierRegionFilter, true, \ @@ -179,18 +157,9 @@ "If true, verify that no dirty cards remain after RS log " \ "processing.") \ \ - product(intx, G1MinPausesBetweenMarks, 2, \ - "Number of inefficient pauses necessary to trigger marking.") \ - \ - product(intx, G1InefficientPausePct, 80, \ - "Threshold of an 'inefficient' pauses (as % of cum efficiency.") \ - \ develop(bool, G1RSCountHisto, false, \ "If true, print a histogram of RS occupancies after each pause") \ \ - product(bool, G1TraceFileOverwrite, false, \ - "Allow the trace file to be overwritten") \ - \ develop(intx, G1PrintRegionLivenessInfo, 0, \ "When > 0, print the occupancies of the best and worst" \ "regions.") \ @@ -198,9 +167,6 @@ develop(bool, G1PrintParCleanupStats, false, \ "When true, print extra stats about parallel cleanup.") \ \ - product(bool, G1DoAgeCohortChecks, false, \ - "When true, check well-formedness of age cohort structures.") \ - \ develop(bool, G1DisablePreBarrier, false, \ "Disable generation of pre-barrier (i.e., marking barrier) ") \ \ @@ -214,17 +180,17 @@ develop(intx, G1ConcRSLogCacheSize, 10, \ "Log base 2 of the length of conc RS hot-card cache.") \ \ - product(bool, G1ConcRSCountTraversals, false, \ + develop(bool, G1ConcRSCountTraversals, false, \ "If true, gather data about the number of times CR traverses " \ "cards ") \ \ - product(intx, G1ConcRSHotCardLimit, 4, \ + develop(intx, G1ConcRSHotCardLimit, 4, \ "The threshold that defines (>=) a hot card.") \ \ develop(bool, G1PrintOopAppls, false, \ "When true, print applications of closures to external locs.") \ \ - product(intx, G1LogRSRegionEntries, 7, \ + develop(intx, G1LogRSRegionEntries, 7, \ "Log_2 of max number of regions for which we keep bitmaps.") \ \ develop(bool, G1RecordHRRSOops, false, \ @@ -254,11 +220,11 @@ "It determines whether the system will calculate an optimum " \ "scan-only set.") \ \ - product(intx, G1MinReservePerc, 10, \ + product(intx, G1MinReservePercent, 10, \ "It determines the minimum reserve we should have in the heap " \ "to minimize the probability of promotion failure.") \ \ - product(bool, G1TraceRegions, false, \ + diagnostic(bool, G1PrintRegions, false, \ "If set G1 will print information on which regions are being " \ "allocated and which are reclaimed.") \ \ @@ -268,24 +234,24 @@ develop(bool, G1HRRSFlushLogBuffersOnVerify, false, \ "Forces flushing of log buffers before verification.") \ \ - product(bool, G1UseSurvivorSpace, true, \ + product(bool, G1UseSurvivorSpaces, true, \ "When true, use survivor space.") \ \ - product(bool, G1FixedTenuringThreshold, false, \ + develop(bool, G1FixedTenuringThreshold, false, \ "When set, G1 will not adjust the tenuring threshold") \ \ - product(bool, G1FixedEdenSize, false, \ + develop(bool, G1FixedEdenSize, false, \ "When set, G1 will not allocate unused survivor space regions") \ \ - product(uintx, G1FixedSurvivorSpaceSize, 0, \ + develop(uintx, G1FixedSurvivorSpaceSize, 0, \ "If non-0 is the size of the G1 survivor space, " \ "otherwise SurvivorRatio is used to determine the size") \ \ - experimental(bool, G1EnableParallelRSetUpdating, false, \ + experimental(bool, G1ParallelRSetUpdatingEnabled, false, \ "Enables the parallelization of remembered set updating " \ "during evacuation pauses") \ \ - experimental(bool, G1EnableParallelRSetScanning, false, \ + experimental(bool, G1ParallelRSetScanningEnabled, false, \ "Enables the parallelization of remembered set scanning " \ "during evacuation pauses") diff -r 435f0808b826 -r 8b0b8998e1c3 src/share/vm/gc_implementation/g1/heapRegion.cpp --- a/src/share/vm/gc_implementation/g1/heapRegion.cpp Wed Jun 03 15:02:13 2009 -0700 +++ b/src/share/vm/gc_implementation/g1/heapRegion.cpp Wed Jun 03 15:16:50 2009 -0700 @@ -160,12 +160,6 @@ if (!g1h->is_obj_dead(cur_oop, hr)) { // Bottom lies entirely below top, so we can call the // non-memRegion version of oop_iterate below. -#ifndef PRODUCT - if (G1VerifyMarkingInEvac) { - VerifyLiveClosure vl_cl(g1h); - cur_oop->oop_iterate(&vl_cl); - } -#endif cur_oop->oop_iterate(cl); } cur = next_obj; @@ -197,12 +191,6 @@ // or it was allocated after marking finished, then we add it. Otherwise // we can safely ignore the object. if (!g1h->is_obj_dead(oop(bottom), _hr)) { -#ifndef PRODUCT - if (G1VerifyMarkingInEvac) { - VerifyLiveClosure vl_cl(g1h); - oop(bottom)->oop_iterate(&vl_cl, mr); - } -#endif oop_size = oop(bottom)->oop_iterate(cl2, mr); } else { oop_size = oop(bottom)->size(); @@ -232,12 +220,6 @@ // Last object. Need to do dead-obj filtering here too. if (!g1h->is_obj_dead(oop(bottom), _hr)) { -#ifndef PRODUCT - if (G1VerifyMarkingInEvac) { - VerifyLiveClosure vl_cl(g1h); - oop(bottom)->oop_iterate(&vl_cl, mr); - } -#endif oop(bottom)->oop_iterate(cl2, mr); } } @@ -713,12 +695,12 @@ G1CollectedHeap::heap()->print(); gclog_or_tty->print_cr(""); } - if (G1VerifyConcMark && + if (VerifyDuringGC && G1VerifyConcMarkPrintReachable && vl_cl.failures()) { g1->concurrent_mark()->print_prev_bitmap_reachable(); } - guarantee(!vl_cl.failures(), "should not have had any failures"); + guarantee(!vl_cl.failures(), "region verification failed"); guarantee(p == top(), "end of last object must match end of space"); } diff -r 435f0808b826 -r 8b0b8998e1c3 src/share/vm/opto/classes.hpp --- a/src/share/vm/opto/classes.hpp Wed Jun 03 15:02:13 2009 -0700 +++ b/src/share/vm/opto/classes.hpp Wed Jun 03 15:16:50 2009 -0700 @@ -104,6 +104,10 @@ macro(CosD) macro(CountedLoop) macro(CountedLoopEnd) +macro(CountLeadingZerosI) +macro(CountLeadingZerosL) +macro(CountTrailingZerosI) +macro(CountTrailingZerosL) macro(CreateEx) macro(DecodeN) macro(DivD) diff -r 435f0808b826 -r 8b0b8998e1c3 src/share/vm/opto/connode.cpp --- a/src/share/vm/opto/connode.cpp Wed Jun 03 15:02:13 2009 -0700 +++ b/src/share/vm/opto/connode.cpp Wed Jun 03 15:16:50 2009 -0700 @@ -1255,3 +1255,93 @@ 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; +} diff -r 435f0808b826 -r 8b0b8998e1c3 src/share/vm/opto/connode.hpp --- a/src/share/vm/opto/connode.hpp Wed Jun 03 15:02:13 2009 -0700 +++ b/src/share/vm/opto/connode.hpp Wed Jun 03 15:16:50 2009 -0700 @@ -636,22 +636,62 @@ 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; } }; diff -r 435f0808b826 -r 8b0b8998e1c3 src/share/vm/opto/doCall.cpp --- a/src/share/vm/opto/doCall.cpp Wed Jun 03 15:02:13 2009 -0700 +++ b/src/share/vm/opto/doCall.cpp Wed Jun 03 15:16:50 2009 -0700 @@ -47,7 +47,7 @@ CallGenerator* cg; // Dtrace currently doesn't work unless all calls are vanilla - if (DTraceMethodProbes) { + if (env()->dtrace_method_probes()) { allow_inline = false; } diff -r 435f0808b826 -r 8b0b8998e1c3 src/share/vm/opto/escape.cpp --- a/src/share/vm/opto/escape.cpp Wed Jun 03 15:02:13 2009 -0700 +++ b/src/share/vm/opto/escape.cpp Wed Jun 03 15:16:50 2009 -0700 @@ -905,15 +905,22 @@ // 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 for the allocate or for the return value of a call + n = alloc->result_cast(); + 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; } - // find CheckCastPP of call return value - n = alloc->result_cast(); - if (n == NULL || // No uses accept Initialize or - !n->is_CheckCastPP()) // not unique CheckCastPP. + 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 @@ 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) diff -r 435f0808b826 -r 8b0b8998e1c3 src/share/vm/opto/gcm.cpp --- a/src/share/vm/opto/gcm.cpp Wed Jun 03 15:02:13 2009 -0700 +++ b/src/share/vm/opto/gcm.cpp Wed Jun 03 15:16:50 2009 -0700 @@ -617,6 +617,9 @@ 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' } } } diff -r 435f0808b826 -r 8b0b8998e1c3 src/share/vm/opto/graphKit.cpp --- a/src/share/vm/opto/graphKit.cpp Wed Jun 03 15:02:13 2009 -0700 +++ b/src/share/vm/opto/graphKit.cpp Wed Jun 03 15:16:50 2009 -0700 @@ -459,7 +459,7 @@ 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 @@ } } - 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; diff -r 435f0808b826 -r 8b0b8998e1c3 src/share/vm/opto/library_call.cpp --- a/src/share/vm/opto/library_call.cpp Wed Jun 03 15:02:13 2009 -0700 +++ b/src/share/vm/opto/library_call.cpp Wed Jun 03 15:16:50 2009 -0700 @@ -222,6 +222,8 @@ 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 @@ 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_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 @@ 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) ); diff -r 435f0808b826 -r 8b0b8998e1c3 src/share/vm/opto/loopTransform.cpp --- a/src/share/vm/opto/loopTransform.cpp Wed Jun 03 15:02:13 2009 -0700 +++ b/src/share/vm/opto/loopTransform.cpp Wed Jun 03 15:16:50 2009 -0700 @@ -1630,6 +1630,10 @@ // 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 @@ phase->do_maximally_unroll(this,old_new); return true; } - if (should_unswitch) { - phase->do_unswitching(this, old_new); - return true; - } } diff -r 435f0808b826 -r 8b0b8998e1c3 src/share/vm/opto/macro.cpp --- a/src/share/vm/opto/macro.cpp Wed Jun 03 15:02:13 2009 -0700 +++ b/src/share/vm/opto/macro.cpp Wed Jun 03 15:16:50 2009 -0700 @@ -988,7 +988,7 @@ 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 @@ 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(), diff -r 435f0808b826 -r 8b0b8998e1c3 src/share/vm/opto/matcher.hpp --- a/src/share/vm/opto/matcher.hpp Wed Jun 03 15:02:13 2009 -0700 +++ b/src/share/vm/opto/matcher.hpp Wed Jun 03 15:16:50 2009 -0700 @@ -225,10 +225,16 @@ 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); diff -r 435f0808b826 -r 8b0b8998e1c3 src/share/vm/opto/parse1.cpp --- a/src/share/vm/opto/parse1.cpp Wed Jun 03 15:02:13 2009 -0700 +++ b/src/share/vm/opto/parse1.cpp Wed Jun 03 15:16:50 2009 -0700 @@ -439,7 +439,7 @@ // 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 @@ 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 @@ // 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 @@ 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 @@ 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(); diff -r 435f0808b826 -r 8b0b8998e1c3 src/share/vm/opto/parse2.cpp --- a/src/share/vm/opto/parse2.cpp Wed Jun 03 15:02:13 2009 -0700 +++ b/src/share/vm/opto/parse2.cpp Wed Jun 03 15:16:50 2009 -0700 @@ -2052,7 +2052,7 @@ // 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, diff -r 435f0808b826 -r 8b0b8998e1c3 src/share/vm/opto/subnode.cpp --- a/src/share/vm/opto/subnode.cpp Wed Jun 03 15:02:13 2009 -0700 +++ b/src/share/vm/opto/subnode.cpp Wed Jun 03 15:16:50 2009 -0700 @@ -640,7 +640,11 @@ 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 diff -r 435f0808b826 -r 8b0b8998e1c3 src/share/vm/runtime/arguments.cpp --- a/src/share/vm/runtime/arguments.cpp Wed Jun 03 15:02:13 2009 -0700 +++ b/src/share/vm/runtime/arguments.cpp Wed Jun 03 15:16:50 2009 -0700 @@ -1288,10 +1288,14 @@ Abstract_VM_Version::parallel_worker_threads()); if (ParallelGCThreads == 0) { FLAG_SET_DEFAULT(ParallelGCThreads, - Abstract_VM_Version::parallel_worker_threads -()); + Abstract_VM_Version::parallel_worker_threads()); } no_shared_spaces(); + + // Set the maximum pause time goal to be a reasonable default. + if (FLAG_IS_DEFAULT(MaxGCPauseMillis)) { + FLAG_SET_DEFAULT(MaxGCPauseMillis, 200); + } } void Arguments::set_server_heap_size() { diff -r 435f0808b826 -r 8b0b8998e1c3 src/share/vm/runtime/globals.hpp --- a/src/share/vm/runtime/globals.hpp Wed Jun 03 15:02:13 2009 -0700 +++ b/src/share/vm/runtime/globals.hpp Wed Jun 03 15:16:50 2009 -0700 @@ -1819,7 +1819,11 @@ "Decay factor to TenuredGenerationSizeIncrement") \ \ product(uintx, MaxGCPauseMillis, max_uintx, \ - "Adaptive size policy maximum GC pause time goal in msec") \ + "Adaptive size policy maximum GC pause time goal in msec, " \ + "or (G1 Only) the max. GC time per MMU time slice") \ + \ + product(intx, GCPauseIntervalMillis, 500, \ + "Time slice for MMU specification") \ \ product(uintx, MaxGCMinorPauseMillis, max_uintx, \ "Adaptive size policy maximum GC minor pause time goal in msec") \ @@ -2185,6 +2189,9 @@ 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") \ \ diff -r 435f0808b826 -r 8b0b8998e1c3 test/Makefile --- a/test/Makefile Wed Jun 03 15:02:13 2009 -0700 +++ b/test/Makefile Wed Jun 03 15:16:50 2009 -0700 @@ -172,6 +172,33 @@ ################################################################ +# 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. diff -r 435f0808b826 -r 8b0b8998e1c3 test/compiler/6636138/Test1.java --- a/test/compiler/6636138/Test1.java Wed Jun 03 15:02:13 2009 -0700 +++ b/test/compiler/6636138/Test1.java Wed Jun 03 15:16:50 2009 -0700 @@ -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 diff -r 435f0808b826 -r 8b0b8998e1c3 test/compiler/6636138/Test2.java --- a/test/compiler/6636138/Test2.java Wed Jun 03 15:02:13 2009 -0700 +++ b/test/compiler/6636138/Test2.java Wed Jun 03 15:16:50 2009 -0700 @@ -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 diff -r 435f0808b826 -r 8b0b8998e1c3 test/compiler/6772683/InterruptedTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/6772683/InterruptedTest.java Wed Jun 03 15:16:50 2009 -0700 @@ -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"); + } + +} diff -r 435f0808b826 -r 8b0b8998e1c3 test/compiler/6814842/Test6814842.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/6814842/Test6814842.java Wed Jun 03 15:16:50 2009 -0700 @@ -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); } +} diff -r 435f0808b826 -r 8b0b8998e1c3 test/compiler/6823354/Test6823354.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/6823354/Test6823354.java Wed Jun 03 15:16:50 2009 -0700 @@ -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); } + } +} diff -r 435f0808b826 -r 8b0b8998e1c3 test/compiler/6832293/Test.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/6832293/Test.java Wed Jun 03 15:16:50 2009 -0700 @@ -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; + } +} + diff -r 435f0808b826 -r 8b0b8998e1c3 test/compiler/6843752/Test.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/6843752/Test.java Wed Jun 03 15:16:50 2009 -0700 @@ -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); + } + } +} +