Revisit j.l.classfile.CodeBuilder API surface
Brian Goetz
brian.goetz at oracle.com
Fri Jan 5 16:33:41 UTC 2024
One problem with `newLocalSlot` is that it now conflicts with the new
instructions like `newObject`, and thus makes it less clear whether the
method is _generating_ bytecode or merely setting up for a future
operation. But perhaps `allocateSlot` or `allocateLocalSlot` or
`reserveLocalSlot` is more clear.
On 1/5/2024 11:21 AM, - wrote:
> I love this simplification too!
>
> One nitpick is that now we have `loadLocal` and `storeLocal`, maybe we
> should rename existing `allocateLocal` to something like
> `newLocalSlot` ("allocate" is disliked by panama devs too), so it's
> clear it returns a slot index like `parameterSlot` or `receiverSlot` do.
>
> In addition, the previous "instruction family" APIs have their
> downfalls too: some families are not complete, and may throw
> exceptions upon combination of certain arguments but are not well
> documented. For example, a `conversion(TypeKind.LongType,
> TypeKind.ByteType)` would fail, because bytecode actually uses 2
> instructions: l2i and i2b. (maybe upgrading this `conversion` to emit
> multiple bytecode is a solution, too) Same for calling
> `newPrimitiveArray(TypeKind.VoidType)` etc. Similarly, the
> `operator(Opcode)` is just a watered-down version of ASM's
> `visitInsn`, yet is more risky as you can pass in other no-operand
> opcodes that fail at runtime without compile-time hints.
>
> In contrast, the more specific methods in CodeBuilder avoids these
> pitfalls.
>
> After all, my rant above is not against this change, but instead are
> improvements that are enabled by this simplification.
>
> Cheers,
> Chen Liang
>
> On Fri, Jan 5, 2024 at 9:52 AM Brian Goetz <brian.goetz at oracle.com> wrote:
>
> Let me fill in some history here.
>
> Much of the design process for this library could be described as
> an iterated game of "find the primitive." The first version of the
> API had a zillion ad-hoc methods, with little structural
> relation. At some point we hit upon a model-driven analysis, and
> broke down instructions into families (loads, stores, etc), and at
> that point, we thought methods like loadInstruction were the
> primitives. But we hadn't actually hit bottom yet; after many
> rounds of refactoring, it became clear that there was one
> primitive for the builder hierarchy, now called `with`, and all of
> the builder methods now bottom out at that.
>
> At the same time, we added a number of "convenience" methods such
> as aload_0() and aload(int n) (which now just delegate to with()
> or loadInstruction()), and over time, we found that most
> generative use cases used these methods much more than the
> primitives (which is fine.)
>
> At this point, I think many of the xxxInstruction (and its rigid
> naming convention) are vestiges of a previous attempt to organize
> the API. Some still have uses, though should be renamed to
> reflect that they are mere conveniences (such as
> arrayLoadInstruction to arrayLoad).
>
> (Does anyone use operator(opcode), or can we drop that one too?)
>
> So I support this simplification.
>
> Having done the refactor, were there any surprises in the usages
> of various CodeBuilder methods?
>
>
> On 1/5/2024 10:38 AM, Adam Sotona wrote:
>>
>> Hi,
>>
>> j.l.classfile.CodeBuilder API consist of more than 230 methods.
>>
>> Existing ClassFile API use cases proved the concept of one big
>> CodeBuilder is comfortable. However there are some redundancies,
>> glitches in the naming, some frequently used methods are hard to
>> find and some methods have low practical use.
>>
>> Majorityof the methods may be dividedinto three main levels:
>> 1.methods building low level bytecode instructions according to
>> JVMS chapter 6.5 (aaload, aastore, aconst_null...)
>> 2.methods reconstructing individual subtypes of
>> j.l.classfile.Instruction from given arguments (loadInstruction,
>> storeInstruction, incrementInstruction, branchInstruction...)
>> 3.methods modeling high level code blocks (block, ifThen,
>> ifThenElse, trying...)
>>
>> Many methods from level 2 (with suffix `Instruction`) seem to be
>> obsolete or misplaced. Some of them are duplicates of methods
>> from level 1, some are obsolete and some are very useful, however
>> a bit hidden. The API should be cleaned a bit while in preview.
>>
>> I would like to open a discussion on the following proposed
>> changes in the CodeBuilder methods:
>>
>> * incrementInstruction remove as duplicate of iinc
>> * lookupSwitchInstruction remove as duplicate of lookupswitch
>> * tableSwitchInstruction remove as duplicate of tableswitch
>> * throwInstruction remove as duplicate of athrow
>> * invokeDynamicInstruction remove as duplicate of invokedynamic
>> * stackInstruction remove as obsolete with suggested
>> replacements: with(StackInstruction.of(...))
>> * monitorInstruction remove as obsolete with suggested
>> replacements: monitorenter, monitorexit, or
>> with(MonitorInstruction.of(...))
>> * nopInstruction remove as duplicate of nop
>> * typecheckInstruction remove as obsolete with suggested
>> replacements: checkcast, instanceOf, or
>> with(TypeCheckInstruction.of(...))
>> * loadInstruction rename to loadLocal
>> * storeInstruction rename to storeLocal
>> * branchInstruction rename to branch
>> * invokeInstruction rename to invoke
>> * newObjectInstruction rename to newObject
>> * newPrimitiveArrayInstruction rename to newPrimitiveArray
>> * newReferenceArrayInstruction rename to newReferenceArray
>> * newMultidimensionalArrayInstruction rename to
>> newMultidimensionalArray
>> * arrayLoadInstruction rename to arrayLoad
>> * arrayStoreInstruction rename to arrayStore
>> * convertInstruction rename to conversion
>> * operatorInstruction rename to operator
>> * constantInstruction rename to loadConstant
>> * fieldInstruction rename to fieldAccess
>> * instanceof_ rename to instanceOf
>> * returnInstruction rename to return_
>>
>> Here is the related RFE: https://bugs.openjdk.org/browse/JDK-8323058
>>
>> Draft of the CSR (no spec yet):
>> https://bugs.openjdk.org/browse/JDK-8323067
>>
>> And draft of the Pull Request:
>> https://github.com/openjdk/jdk/pull/17282
>> <https://urldefense.com/v3/__https://github.com/openjdk/jdk/pull/17282__;!!ACWV5N9M2RV99hQ!K4zh9o6NcHVlQHameNjhwvRGo_HnBCYhzTH9PQDru-SZu5QkkI1NPfSZHyiCN_7l2PlyEU41N_Fp-LCMfbzTFjDa$>
>>
>> Any comments are welcome.
>>
>> Thank you,
>>
>> Adam
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/classfile-api-dev/attachments/20240105/533b72ef/attachment-0001.htm>
More information about the classfile-api-dev
mailing list