# 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);
+ }
+ }
+}
+