Question on locals allocation in BlockCodeBuilder
Brian Goetz
brian.goetz at oracle.com
Tue Sep 13 15:12:04 UTC 2022
Right, that's probably a mistake. (This is what I meant by the locals
stuff is under-tested.)
Yes, CCB should probably delegate to parent. If the parent is a block,
any locals used by transforming that block should be local to that block.
On 9/13/2022 10:41 AM, Adam Sotona wrote:
>
> OK, understood.
>
> Problem is probably in ChainedCodeBuilder, which skips
> BlockCodeBuilder downstream and allocates locals in the terminal
> DirectCodeBuilder directly.
>
> *From: *Brian Goetz <brian.goetz at oracle.com>
> *Date: *Tuesday, 13 September 2022 16:28
> *To: *Adam Sotona <adam.sotona at oracle.com>,
> classfile-api-dev at openjdk.org <classfile-api-dev at openjdk.org>
> *Subject: *Re: Question on locals allocation in BlockCodeBuilder
>
> 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:
>
> public void *end*() {
>
> terminal.with((LabelTarget) endLabel);
>
> if (terminalMaxLocals != topLocal(terminal)) {
>
> throw new IllegalStateException("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/c8752bdf/attachment.htm>
More information about the classfile-api-dev
mailing list