Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8302497

4.9.2, 4.10.1: Clarify verification rules about uninitialized instances



    • Bug
    • Resolution: Fixed
    • P4
    • 22
    • 19
    • specification
    • vm


      From 4.9.2:

      "If there is an uninitialized class instance in a local variable in code protected by an exception handler, then (i) if the handler is inside an <init> method, the handler must throw an exception or loop forever; and (ii) if the handler is not inside an <init> method, the uninitialized class instance must remain uninitialized."

      This is poorly specified (what does it mean for a handler to "throw" or "loop"? all a handler can do is jump), and doesn't align with actual verification behavior.

      HotSpot properly allows some behaviors that a strict reading of this rule would cover:

      - A handler in an <init> can catch an exception thrown by pre-'invokespecial' code, discard it, and carry on with the initialization task, eventually calling 'invokespecial' and succeeding (as long as there's not an attempt to do 'invokespecial' twice)

      - A handler in an <init> covering code between a 'new Foo' and an invokespecial (i.e., not a 'super()' call) can still lead to a 'return'


      More concretely, 4.10.4 introduces the 'flagThisUninit' flag, which has the effect of ensuring that stack maps must keep 'uninitializedThis' in the stack/locals of handlers that touch code before the 'invokespecial', and thus a handler cannot simultaneously handle pre-'invokespecial' (including invokespecial failures) and post-'invokespecial' code.

      'flagThisUninit' also prevents a 'return' until a successful 'invokespecial' has occurred (the only options are to throw or loop, as intended).

      (Note that 'flagThisUninit' has nothing to do with 'new' instructions—it only controls 'uninitializedThis'. more abstract descriptions in, e.g., 4.9.2, should be careful to make that distinction.)


      The 'mergedCodeIsTypeSafe' rules in should ensure that a handler touching an invokespecial for an uninitialized object created by 'new' must be able to handle *both* the uninitialized local variable (if any) *and* the initialized local variable. The only way to satisfy this is to use a 'top' type for the local variable in the handler, making it impossible to redo 'invokespecial'.

      (This is the HotSpot behavior, but I'm a little suspicious that, as written, we may have missed checking the "before" state. Need to review more carefully.)


      Despite the above rules, attempts to further constrain handlers via 'initHandlerIsLegal'. In practice, these rules don't prevent anything that wasn't already prevented. (The also have some technical problems.) They can be removed.


        Issue Links



              dlsmith Dan Smith
              dlsmith Dan Smith
              0 Vote for this issue
              2 Start watching this issue