前一阵给sun报的bug,对jit compiler有兴趣的同学可以看一下
wkoffee
2011-01-08
在64位环境下测试:
public class OverflowTest{ static int test( byte a[] ){ int result =0; for( int i=0;i<a.length; i+=((0x7fffffff>>1)+1) ){ result += a[i]; } return result; } public static void main( String [] args ){ byte a[] = new byte[(0x7fffffff>>1)+2]; System.out.println( ""+test(a)); } } java -Xint -Xms2000m OverflowTest Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -2147483648 at OverflowTest.test(OverflowTest.java:5) at OverflowTest.main(OverflowTest.java:12) java -Xcomp -Xms2000m OverflowTest 0 应该是和loop opt有关,目前还没有解决 |
|
xgj1988
2011-03-18
SUN给你回复没,兄弟
|
|
wkoffee
2011-03-24
他们接受了这个bug,但是没有后续消息,好像现在最新的代码还没有解决。
|
|
RednaxelaFX
2011-07-02
wkoffee 写道 他们接受了这个bug,但是没有后续消息,好像现在最新的代码还没有解决。
话说这bug有bug ID不?是多少呢? 更新: 好吧,我知道了。此bug已fix,今年5月初修好的。 Bug ID 5091921: Sign flip issues in loop optimizer Changeset: http://hg.openjdk.java.net/jdk7/hotspot-comp/hotspot/rev/bad7ecd0b6ed 然后还有一个后续修复: Bug ID 7052494: Eclipse test fails on JDK 7 b142 很早之前就有人报告过这个问题: Bug ID 6186134: Server virtual machine produces/exeutes incorrect code. Bug ID 6890943: JVM mysteriously gives wrong result on 64-bit 1.6 VMs in hotspot mode. 具体到这帖顶楼的现象是由LoopLimitCheck参数所控制的代码修复的。可以用顶楼的代码 public class OverflowTest { static int test(byte[] a) { int result = 0; for (int i = 0; i < a.length; i += ((Integer.MAX_VALUE >> 1) + 1)) { result += a[i]; } return result; } public static void main(String[] args) { byte[] a = new byte[(Integer.MAX_VALUE >> 1) + 2]; System.out.println(Integer.toString(test(a))); } } 这样验证: $ java -version java version "1.7.0-fastdebug" Java(TM) SE Runtime Environment (build 1.7.0-fastdebug-b147) Java HotSpot(TM) 64-Bit Server VM (build 21.0-b17-fastdebug, mixed mode) $ java -cp . -Xint -Xms2g OverflowTest Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -2147483648 at OverflowTest.test(OverflowTest.java:5) at OverflowTest.main(OverflowTest.java:12) $ java -cp . -Xcomp -Xms2g OverflowTest Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -2147483648 at OverflowTest.test(OverflowTest.java:5) at OverflowTest.main(OverflowTest.java:12) $ java -cp . -Xcomp -Xms2g -XX:-LoopLimitCheck OverflowTest VM option '-LoopLimitCheck' 0 可以看到如果把LoopLimitCheck设为false的话就会表现出跟之前一样的问题。 在加入新的行为后,可以用-XX:+TraceDeoptimization -XX:+PrintOptoAssembly来了解新的编译器行为: {method} - klass: {other class} - this oop: 0x000000077b0a8e08 - method holder: 'OverflowTest' - constants: 0x000000077b0a8a28 constant pool [50] for 'OverflowTest' cache=0x000000077b0aacd0 - access: 0xc1000009 public static - name: 'test' - signature: '([B)I' - max stack: 3 - max locals: 3 - size of params: 1 - method size: 17 - vtable index: -2 - i2i entry: 0x00002aaaab349ee0 - adapter: 0x000000000b10a170 - compiled entry 0x00002aaaab3f8771 - code size: 26 - code start: 0x000000077b0a8dc0 - code end (excl): 0x000000077b0a8dda - method data: 0x000000077b0ac250 - checked ex length: 0 - linenumber start: 0x000000077b0a8dda - localvar length: 3 - localvar start: 0x000000077b0a8de2 # # int ( byte[int:>=0]:exact * ) # #r018 rsi:rsi : parm 0: byte[int:>=0]:exact * # -- Old rsp -- Framesize: 32 -- #r089 rsp+28: pad2, in_preserve #r088 rsp+24: pad2, in_preserve #r087 rsp+20: pad2, in_preserve #r086 rsp+16: pad2, in_preserve #r085 rsp+12: pad2, in_preserve #r084 rsp+ 8: return address #r083 rsp+ 4: Fixed slot 1 #r082 rsp+ 0: Fixed slot 0 # abababab N1: # B1 <- B13 B11 B12 B10 Freq: 1 abababab 000 B1: # B13 B2 <- BLOCK HEAD IS JUNK Freq: 1 000 # stack bang pushq rbp subq rsp, #16 # Create frame 00c movl R11, [RSI + #12 (8-bit)] # range 010 NullCheck RSI 010 010 B2: # B9 B3 <- B1 Freq: 0.999999 010 xorl R10, R10 # int 013 testl R11, R11 016 jle,s B9 P=0.500000 C=-1.000000 016 018 B3: # B11 B4 <- B2 Freq: 0.499999 018 testl R11, R11 # unsigned 01b jbe,us B11 P=0.000001 C=-1.000000 01b 01d B4: # B11 B5 <- B3 Freq: 0.499999 01d movslq R8, R11 # i2l 020 addq R8, #1073741823 # long 027 andq R8, #-1073741824 # long 02e movl R8, R8 # l2i 031 addl R8, #-1073741824 # int 038 cmpl R8, R11 # unsigned 03b jnb,us B11 P=0.000001 C=-1.000000 03b 03d B5: # B12 B6 <- B4 Freq: 0.499998 03d cmpl R11, #1073741824 044 jg,s B12 P=0.000001 C=-1.000000 044 046 B6: # B7 <- B5 Freq: 0.499998 046 xorl RAX, RAX # int nop # 8 bytes pad for loops and calls 050 B7: # B7 B8 <- B6 B7 Loop: B7-B7 inner Freq: 4.99998 050 movslq R8, R10 # i2l 053 movsbl R8, [RSI + #16 + R8] # byte 059 addl RAX, R8 # int 05c addl R10, #1073741824 # int 063 cmpl R10, R11 066 jl,s B7 # loop end P=0.900000 C=-1.000000 066 068 B8: # B10 <- B7 Freq: 0.499998 068 jmp,s B10 068 06a B9: # B10 <- B2 Freq: 0.499999 06a xorl RAX, RAX # int 06c 06c B10: # N1 <- B8 B9 Freq: 0.999997 06c addq rsp, 16 # Destroy frame popq rbp testl rax, [rip + #offset_to_poll_page] # Safepoint: poll for GC 077 ret 077 078 B11: # N1 <- B4 B3 Freq: 1.00664e-06 078 movq RBP, RSI # spill 07b movl RSI, #-122 # int 080 nop # 3 bytes pad for loops and calls 083 call,static wrapper for: uncommon_trap(reason='predicate' action='maybe_recompile') # OverflowTest::test @ bci:10 L[0]=RBP L[1]=#0 L[2]=#0 # OopMap{rbp=Oop off=136} 088 int3 # ShouldNotReachHere 088 095 B12: # N1 <- B5 Freq: 5.06638e-07 095 movq RBP, RSI # spill 098 movl RSI, #-130 # int 09d nop # 2 bytes pad for loops and calls 09f call,static wrapper for: uncommon_trap(reason='loop_limit_check' action='maybe_recompile') # OverflowTest::test @ bci:10 L[0]=RBP L[1]=#0 L[2]=#0 # OopMap{rbp=Oop off=164} 0a4 int3 # ShouldNotReachHere 0a4 0b1 B13: # N1 <- B1 Freq: 1.01328e-06 0b1 movl RSI, #-10 # int 0b6 nop # 1 bytes pad for loops and calls 0b7 call,static wrapper for: uncommon_trap(reason='null_check' action='maybe_recompile') # OverflowTest::test @ bci:6 L[0]=_ L[1]=_ L[2]=_ STK[0]=_ STK[1]=#NULL # OopMap{off=188} 0bc int3 # ShouldNotReachHere 0bc Uncommon trap occurred in OverflowTest::test (@0x00002aaaab488cc4) thread=1074809152 reason=loop_limit_check action=maybe_recompile unloaded_class_index=-1 DEOPT PACKING thread 0x000000000b02c000 Compiled frame (sp=0x00000000401039b0 unextended sp=0x00000000401039b0, fp=0x0000000780000000, pc=0x00002aaaab488cc4) nmethod 9845 361 OverflowTest::test (26 bytes) Virtual frames (innermost first): 0 - frame( sp=0x00000000401039b0, unextended_sp=0x00000000401039b0, fp=0x0000000780000000, pc=0x00002aaaab488cc4) OverflowTest.test(OverflowTest.java:5) - iload_1 @ bci 10 Created vframeArray 0x000000000b402298 DEOPT UNPACKING thread 0x000000000b02c000 vframeArray 0x000000000b402298 mode 2 {method} 'test' '([B)I' in 'OverflowTest' - iload_1 @ bci 10 sp = 0x0000000040103970 可以看到新的行为是,编译器会生成检查循环条件溢出的代码,当真的发生溢出时会掉进一个uncommon trap(Deoptimization::Reason_loop_limit_check)回到解释器执行。 这样正确性是没问题了,但感觉搞不好会deoptimize掉一堆原本不需要deoptimize的方法。不能换个解决办法么… |
|
huxi
2011-07-08
RednaxelaFX 写道 Bug ID 7052494: Eclipse test fails on JDK 7 b142
I traced it to new code which changes loop check "for(i != lim; i++)" to "for(i < lim; i++)". Such conversion is incorrect when initial value is >= lim (note, such loops are terminated by other checks inside loop's body). Posted Date : 2011-06-17 02:10:19.0 http://hg.openjdk.java.net/hsx/hotspot-comp/hotspot/rev/aacaff365100 Posted Date : 2011-06-21 05:56:07.0 http://hg.openjdk.java.net/jdk7/hotspot/hotspot/rev/782e2bb60c41 Posted Date : 2011-06-23 23:32:26.0 这个在刚发布的JDK7 RC b147里搞定了。 |
|
RednaxelaFX
2011-07-08
huxi 写道 这个在刚发布的JDK7 RC b147里搞定了。
嗯,是撒。你看我在上面回复里就是用JDK7b147的 |
|
huxi
2011-07-08
RednaxelaFX 写道 huxi 写道 这个在刚发布的JDK7 RC b147里搞定了。
嗯,是撒。你看我在上面回复里就是用JDK7b147的 got it. |