RFR: Classfile API stack maps processing
Brian Goetz
brian.goetz at oracle.com
Wed Aug 17 17:39:44 UTC 2022
> I thought PROCESS_STACK_MAP switch is clear the maps will pass to the
> CodeBuilder.
>
> It seems to me similar to PROCESS_DEBUG, PROCESS_LINE_NUMBERS and
> PROCESS_UNKNOWN_ATTRIBUTES.
>
> In all the above cases the relevant attributes appear or disappear
> from processing.
>
It is structurally similar, but (a) slightly different and (b) the
danger level is much higher.
For PROCESS_{DEBUG,LINE_NUMBERS}, we explode the appropriate attribute
into finer-grained elements, and reconstruct them into an attribute at
the end. (This reminds me that we need to make sure that we're not
doing *both* reconstructed and pass-through processing in these cases.)
So this is opting into a more active mode of control over these
elements. And secondarily, messing up the line number tables or LVT
will not result in unloadable classfiles.
It seem just too easy for a user to do the following:
- request PROCESS_STACK_MAP because there is something useful they
want to see in it, and just passing it through to the builder because
that's a reasonable default for an element you don't plan to manipulate;
- adapt the instruction stream (say, to add logging), but without
rewriting the stack map.
Now, we will write a classfile with a wrong stack map. This seems too
easy and too dangerous. Hence, asking users to _turn off_ generation as
well as turning on "give me stack maps" seems a reasonable precaution.
> I still “slightly” think that if user drops something specific to
> CodeBuilder – it should override even the Generator.
>
> However I’m ready to put Generator priority over the content dropped
> to CodeBuilder.
>
We faced a similar situation with BootstrapMethods attribute. THere, we
concluded there is no case we want to let the user generate a BMA; if
they want to generate BMA _entries_, they can do so with
ConstantPoolBuilder. There are various places where we filter out BMA
in various places, such as attributes written to the ClassBuilder.
Stack maps feel about 90% along on the spectrum of [ line numbers ...
bootstrap methods ] to me.
> What about another option to keep the status quo, drop
> PROCESS_STACK_MAPswitch and do not stream StackMapAttribute at all?
>
> As users can still access it from
> CodeModel::findAttribute(Attributes.STACK_MAP_TABLE) and manually pass
> it to CodeBuilder, which will then override even Generator.
>
This is more in line with how we handle BootstrapMethod attribute, and I
think it is fine. I think it is better, actually, because there is no
confusion about the interaction between "process" and "generate". Here,
"generate" indicates clear control over what to do with user-provided
stack maps -- if we are in generate mode, ignore the user one. No
confusion. So, +1 to this idea.
> *From: *Brian Goetz <brian.goetz at oracle.com>
> *Date: *Wednesday, 17 August 2022 18:58
> *To: *Adam Sotona <adam.sotona at oracle.com>,
> classfile-api-dev at openjdk.org <classfile-api-dev at openjdk.org>
> *Subject: *Re: RFR: Classfile API stack maps processing
>
>
>
> 1.Processing stack maps is extremely advanced feature and 99.9% of
> users don’t want to touch it, so why PROCESS_STACK_MAPis off by
> default and GENERATE_STACK_MAPS is on by default
>
>
> Agree with this.
>
>
> 1.When the 0.1% user needs to process the stack maps, he needs
> full control over it. So when user enables PROCESS_STACK_MAP, full
> control of what drops to code builder is up-to user.
>
>
> OK, I don't mind two options, but I'd like to be clear on what they
> mean. I don't think that merely turning on PROCESS_STACK_MAP will
> clue the user in to the fact that they have disengaged all the safety
> guards. Some users may just want to _read_ the stack map. So I'm OK
> with having both PROCESS and GENERATE options, but we should be clear
> what they mean, and be conservative in their meanings. Here's what
> makes sense to me:
>
> GENERATE: the stack map is *always* generated by the library. Any
> stack maps sent downstream are still ignored.
> PROCESS: send the stack map to the user.
> PROCESS & !GENERATE: send the stack map to the user, write any stack
> map the user supplied to the classfile.
>
> So users who want full control select PROCESS and !GENERATE; users who
> want to see the stackmap select PROCESS only; users who don't care
> about stack maps (which is most of them) select neither.
>
> I think what this exposes is we need a way to override some options on
> a per-method basis, which is a separate problem.
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/classfile-api-dev/attachments/20220817/a5e2665e/attachment.htm>
More information about the classfile-api-dev
mailing list