Weirdness in TypeFlow
Tom Rodriguez
Thomas.Rodriguez at Sun.COM
Mon Jan 12 13:32:57 PST 2009
I believe this is because none of the bytecodes after the getstatic
itself can actually throw an exception in compiled code, so there's no
edge to the exception handler. The monitorexit can't throw an NPE
because we verified that the monitor operations are block structured
before we compiled so it must be non-null and we must have entered it
at least once. Check out the can_trap logic in ciTypeFlow. This
controls whether a bytecode has an exceptional edge or not during the
dataflow.
tom
On Jan 12, 2009, at 11:17 AM, Andrew Haley wrote:
> This is the TypeFlow for java.lang.Shutdown::sequence
>
> Here's BB 7. Note that local 0 is an Object:
>
> ====================================================
> #7 rpo#7 [33 - 43) Stored locals: { 0 }
>
> State : locals 2, stack 0, monitors 1
> local 0 : java/lang/Object
> local 1 : java/lang/Object
> Successors : 1
> #10 rpo#8 [43 - 46)
> Exceptions : 1
> #8 rpo#12 [46 - 48) -- java/lang/Throwable
> ====================================================
>
> Now look at the bytecode:
>
> 33: iconst_2
> 34: putstatic <Field java.lang.Shutdown.state int>
> 37: getstatic <Field java.lang.Shutdown.runFinalizersOnExit boolean>
> 40: istore_0
> 41: aload_1
> 42: monitorexit
> 43: goto 49
>
> Note Instruction 40, which stores an int in local 0. So, after
> instruction
> 40, local 0 contains an int.
>
> Here's the exception handler for this block:
>
> ====================================================
> #8 rpo#12 [46 - 48) Stored locals: { }
>
> State : locals 2, stack 1, monitors 1
> local 0 : java/lang/Object
> local 1 : java/lang/Object
> stack 0 : java/lang/Throwable
> Successors : 1
> #9 rpo#13 [48 - 49)
> Exceptions : 0
> ====================================================
>
> Its incoming local 0 is an Object, not an int. So, what happens if
> the monitorexit instruction throws a NullPointerException? It seems
> to me that local 0 at address 46 is both an Object and an int.
>
> I suppose this verifies correctly because the handler does not
> use local 0. Is this TypeFLow legal? Are there cases where the type
> of a local in the TypeFlow is not correct, but it doesn't matter
> because
> no-one reads it?
>
> Thanks,
> Andrew.
>
>
> TypeFlow for sequence 57 bytes
> ====================================================
> #0 rpo#0 [0 - 6) Stored locals: { 0 }
>
> State : locals 2, stack 0, monitors 0
> local 0 : bottom
> local 1 : bottom
> Successors : 1
> #1 rpo#1 [6 - 13)
> Exceptions : 0
> ====================================================
> --------------------------------------------------------
>
> ====================================================
> #1 rpo#1 [6 - 13) Stored locals: { }
>
> State : locals 2, stack 0, monitors 1
> local 0 : java/lang/Object
> local 1 : bottom
> Successors : 2
> #14 rpo#2 [13 - 15)
> #4 rpo#4 [16 - 18)
> Exceptions : 1
> #2 rpo#14 [21 - 23) -- java/lang/Throwable
> ====================================================
> --------------------------------------------------------
>
> ====================================================
> #14 rpo#2 [13 - 15) Stored locals: { }
>
> State : locals 2, stack 0, monitors 1
> local 0 : java/lang/Object
> local 1 : bottom
> Successors : 1
> #15 rpo#3 [15 - 16)
> Exceptions : 0
> ====================================================
> --------------------------------------------------------
>
> ====================================================
> #15 rpo#3 [15 - 16) Stored locals: { }
>
> State : locals 2, stack 0, monitors 0
> local 0 : java/lang/Object
> local 1 : bottom
> Successors : 0
> Exceptions : 0
> ====================================================
> --------------------------------------------------------
>
> ====================================================
> #4 rpo#4 [16 - 18) Stored locals: { }
>
> State : locals 2, stack 0, monitors 1
> local 0 : java/lang/Object
> local 1 : bottom
> Successors : 1
> #5 rpo#5 [18 - 21)
> Exceptions : 0
> ====================================================
> --------------------------------------------------------
>
> ====================================================
> #5 rpo#5 [18 - 21) Stored locals: { }
>
> State : locals 2, stack 0, monitors 0
> local 0 : java/lang/Object
> local 1 : bottom
> Successors : 1
> #6 rpo#6 [24 - 33)
> Exceptions : 0
> ====================================================
> --------------------------------------------------------
>
> ====================================================
> #6 rpo#6 [24 - 33) Stored locals: { 1 }
>
> State : locals 2, stack 0, monitors 0
> local 0 : java/lang/Object
> local 1 : bottom
> Successors : 1
> #7 rpo#7 [33 - 43)
> Exceptions : 0
> ====================================================
> --------------------------------------------------------
>
> ====================================================
> #7 rpo#7 [33 - 43) Stored locals: { 0 }
>
> State : locals 2, stack 0, monitors 1
> local 0 : java/lang/Object
> local 1 : java/lang/Object
> Successors : 1
> #10 rpo#8 [43 - 46)
> Exceptions : 1
> #8 rpo#12 [46 - 48) -- java/lang/Throwable
> ====================================================
> --------------------------------------------------------
>
> ====================================================
> #10 rpo#8 [43 - 46) Stored locals: { }
>
> State : locals 2, stack 0, monitors 0
> local 0 : int
> local 1 : java/lang/Object
> Successors : 1
> #11 rpo#9 [49 - 53)
> Exceptions : 0
> ====================================================
> --------------------------------------------------------
>
> ====================================================
> #11 rpo#9 [49 - 53) Stored locals: { }
>
> State : locals 2, stack 0, monitors 0
> local 0 : int
> local 1 : java/lang/Object
> Successors : 2
> #13 rpo#10 [53 - 56)
> #12 rpo#11 [56 - 57)
> Exceptions : 0
> ====================================================
> --------------------------------------------------------
>
> ====================================================
> #13 rpo#10 [53 - 56) Stored locals: { }
>
> State : locals 2, stack 0, monitors 0
> local 0 : int
> local 1 : java/lang/Object
> Successors : 1
> #12 rpo#11 [56 - 57)
> Exceptions : 0
> ====================================================
> --------------------------------------------------------
>
> ====================================================
> #12 rpo#11 [56 - 57) Stored locals: { }
>
> State : locals 2, stack 0, monitors 0
> local 0 : int
> local 1 : java/lang/Object
> Successors : 0
> Exceptions : 0
> ====================================================
> --------------------------------------------------------
>
> ====================================================
> #8 rpo#12 [46 - 48) Stored locals: { }
>
> State : locals 2, stack 1, monitors 1
> local 0 : java/lang/Object
> local 1 : java/lang/Object
> stack 0 : java/lang/Throwable
> Successors : 1
> #9 rpo#13 [48 - 49)
> Exceptions : 0
> ====================================================
> --------------------------------------------------------
>
> ====================================================
> #9 rpo#13 [48 - 49) Stored locals: { }
>
> State : locals 2, stack 1, monitors 0
> local 0 : java/lang/Object
> local 1 : java/lang/Object
> stack 0 : java/lang/Throwable
> Successors : 0
> Exceptions : 0
> ====================================================
> --------------------------------------------------------
>
> ====================================================
> #2 rpo#14 [21 - 23) Stored locals: { }
>
> State : locals 2, stack 1, monitors 1
> local 0 : java/lang/Object
> local 1 : bottom
> stack 0 : java/lang/Throwable
> Successors : 1
> #3 rpo#15 [23 - 24)
> Exceptions : 0
> ====================================================
> --------------------------------------------------------
>
> ====================================================
> #3 rpo#15 [23 - 24) Stored locals: { }
>
> State : locals 2, stack 1, monitors 0
> local 0 : java/lang/Object
> local 1 : bottom
> stack 0 : java/lang/Throwable
> Successors : 0
> Exceptions : 0
> ====================================================
> --------------------------------------------------------
>
> Method name:"sequence" private static Descriptor: ()void
> Attribute "Code", length:229, max_stack:2, max_locals:2, code_length:
> 57
> 0: getstatic <Field java.lang.Shutdown.lock java.lang.Object>
> 3: dup
> 4: astore_0
> 5: monitorenter
> 6: getstatic <Field java.lang.Shutdown.state int>
> 9: iconst_1
> 10: if_icmpeq 16
> 13: aload_0
> 14: monitorexit
> 15: return
> 16: aload_0
> 17: monitorexit
> 18: goto 24
> 21: aload_0
> 22: monitorexit
> 23: athrow
> 24: invokestatic <Method java.lang.Shutdown.runHooks ()void>
> 27: getstatic <Field java.lang.Shutdown.lock java.lang.Object>
> 30: dup
> 31: astore_1
> 32: monitorenter
> 33: iconst_2
> 34: putstatic <Field java.lang.Shutdown.state int>
> 37: getstatic <Field java.lang.Shutdown.runFinalizersOnExit boolean>
> 40: istore_0
> 41: aload_1
> 42: monitorexit
> 43: goto 49
> 46: aload_1
> 47: monitorexit
> 48: athrow
> 49: iload_0
> 50: ifeq 56
> 53: invokestatic <Method java.lang.Shutdown.runAllFinalizers ()void>
> 56: return
> Exceptions (count: 5):
> start: 6, end: 15, handler: 21, type: 0 /* finally */
> start: 16, end: 18, handler: 21, type: 0 /* finally */
> start: 21, end: 23, handler: 21, type: 0 /* finally */
> start: 33, end: 43, handler: 46, type: 0 /* finally */
> start: 46, end: 48, handler: 46, type: 0 /* finally */
> Attribute "LineNumberTable", length:42, count: 10
> line: 144 at pc: 0
> line: 148 at pc: 6
> line: 144 at pc: 16
> line: 150 at pc: 24
> line: 152 at pc: 27
> line: 153 at pc: 33
> line: 154 at pc: 37
> line: 152 at pc: 41
> line: 156 at pc: 49
> line: 157 at pc: 56
> Attribute "LocalVariableTable", length:22, count: 2
> slot#0: name: rfoe, type: boolean (pc: 41 length: 5)
> slot#0: name: rfoe, type: boolean (pc: 49 length: 8)
> Attribute "StackMapTable", length:38
>
More information about the hotspot-dev
mailing list