What to do about dead labels?

Paul Sandoz paul.sandoz at oracle.com
Thu Aug 18 21:18:45 UTC 2022


In some sense it is the users responsibility when removing code to remove all related artifacts, but in this example we are not making it easy.

Failing-fast seems more justifiable if the pseudo-instruction exceptionCatch was reported immediately after one of the now non-existent labels. It seems useful to report it immediately before, or immediately after, the label for the start of the try region, then the user gets a heads up on the structure at the “right” point.

If we drop I worry it may hide bugs.

Perhaps it comes down to an option to order such pseudo instructions or not? 

Paul.

> On Aug 18, 2022, at 1:51 PM, Brian Goetz <brian.goetz at oracle.com> wrote:
> 
> There are a number of FIXME comments in the code that remind us that we haven't made a decision of what to do about dead labels, which are labels that are not assigned a point in the element stream.  
> 
> Sometimes a dead label is an outright error, such as:
> 
>     .withCode(b -> { Label lab = Label.of();
>                      b.branch(GOTO, lab);
>                    });
> 
> You can't jump to a location that is not defined.  But sometimes a label can get accidentally snipped out, and yet still show up in LVT, LVTT, or the exception table.  For example, suppose we have some code:
> 
>     start();
>     try {       // X
>         int x;
> 
>         blah();
>     }           // Y
>     catch (FooException f) { 
>         // Z
>         blahblah(); 
>         // W
>     }
>     // Q
>     end();
>     moo();
> 
> When we traverse this, we will get something like:
> 
>    exceptionCatch(X, Y, Z, W, FooException)
>    local("x", X, Y)
>    invoke start
>    label(X)
>    invoke blah
>    label(y)
>    goto Q
>    label(Z)
>    invoke blahblah 
>    label(W)
>    label(Q)
>    invoke end
>    invoke moo
> 
> If the user decides to transform this such that anything between "begin" and "end" are removed, we could get this stream:
> 
>    exceptionCatch(X, Y, Z, W, FooException)
>    local("x", X, Y)
>    invoke start
>    invoke end
>    invoke moo
> 
> and the labels in the exception table / local metadata are dead.  This really isn't the user's fault, especially as we send the metadata up front.  (One reason for this is that early rounds sending it in order had a measurable performance cost; we should re-measure that.  But also, its not always obvious that there is a "right" time, or that it would be immune to such transforms.)  
> 
> Separate from whether we should try to reorder the elements to reduce the error surface, we have two choices for how to deal with dead labels in metadata:
> 
>  - try to sanitize the metadata.  If we find an exception table / LVT / LVTT entry with dead labels, just drop it, and write the class out.  
>  - fail fast.  If we find an entry with data labels, throw.  
> 
> (I am hoping that there is a reasonable answer that is not "make it an option to do either.")
> 
> 
> 
>    



More information about the classfile-api-dev mailing list