Question on locals allocation in BlockCodeBuilder

Brian Goetz brian.goetz at oracle.com
Tue Sep 13 14:28:31 UTC 2022


This isn't intended to prohibit allocation of locals in blocks; it is to 
detect when two different mechanisms are used to allocate locals 
together. Are you getting this error?

We define allocateLocal in CodeBuilder.  In the base (Direct) code 
builder, when you call allocateLocal, it bumps up a high water mark 
(topLocal).  There is no way to "deallocate" a local; this is an 
allocation that is global to the Code attribute being built.

In the various BlockBuilder implementations, they implement their own 
allocateLocal to:

  - start counting initially at the high water mark of their parent;
  - let the user allocate locals starting at that high water mark;
  - when the block is finished, we reclaim all of the locals allocate in 
the block, by dropping back down to the starting high water mark.

The problem is that these two mechanisms -- the "global" allocation of 
DirectCodeBuilder and the "local" allocation of BlockCodeBuilder don't 
know about each other's work.  Here's an example of what could go wrong:

.withCode(db -> {
     int x = db.allocateLocal(TypeKind.INT); // OK, global allocation
     db.aconst_1();
     db.ifThen(bb -> {
         // both the DirectCodeBuilder and BlockCodeBuilder (db and bb) 
are in scope here
         int y = bb.allocateLocal(TypeKind.INT);  // OK, local allocation
         int z = db.allocateLocal(TypeKind.INT);  // conflict!
     });
});

The problem is that I used both mechanisms inside the block.  It would 
be ok to exclusively use db, or exclusively use bb, to allocate locals, 
but not both at once.  The error you've found detects this conflict and 
throws, albeit with a not so helpful error message.

Overall I think using both mechanisms at once will be rare, because its 
rare to mix using both the "tip" and "root" builders at the same time -- 
that's usually a bug.

If a transform needs locals for its work, it should allocate a local 
from the root builder in the (stateful) transform atStart() method.


On 9/13/2022 9:06 AM, Adam Sotona wrote:
>
> Hi,
>
> I have a question related to an older fragment of code in 
> BlockCodeBuilderImpl, that actively prohibits allocation of locals in 
> BlockCodeBuilder:
>
> publicvoid*end*() {
>
> terminal.with((LabelTarget) endLabel);
>
> if(terminalMaxLocals!= topLocal(terminal)) {
>
> thrownewIllegalStateException("Interference in local variable slot 
> management");
>
>         }
>
>     }
>
> Do we really want to prevent locals allocated and valid in the context 
> of BlockCodeBuilder only?
>
> Thanks,
>
> Adam
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/classfile-api-dev/attachments/20220913/d651f30a/attachment-0001.htm>


More information about the classfile-api-dev mailing list