[External] : RE: StackMap problem

Adam Sotona adam.sotona at oracle.com
Wed Jan 29 18:02:11 UTC 2025


I see what happened here. The transformed method is invalid because the istore_1 is injected into the try block and consumed outside.
As I used CodeTransform::atStart to inject the istore_1 – I injected it before the try block and stack maps are valid.

It is not guaranteed Class-File API will always fail eagerly when generating stack maps for invalid bytecode. ClassFile::verify is recommended to verify the generated class file is valid.

Your instrumentation should inject code introducing new locals before any try block (if consumed outside of the try block). Otherwise valid stack maps are unable to compute.

Adam

From: Chen Liang <chen.l.liang at oracle.com>
Date: Wednesday, 29 January 2025 at 18:44
To: Adam Sotona <adam.sotona at oracle.com>, classfile-api-dev at openjdk.org <classfile-api-dev at openjdk.org>
Subject: Re: [External] : RE: StackMap problem
Indeed, I noted that our StackMapGenerator eagerly checks if a newly encountered store instruction (the istore_1 in the exception handler range) breaks the stack maps, and our StackMapGenerator would have failed fast in that case.

Chen
________________________________
From: Adam Sotona <adam.sotona at oracle.com>
Sent: Wednesday, January 29, 2025 11:35 AM
To: Mark Roberts <markro at cs.washington.edu>; classfile-api-dev at openjdk.org <classfile-api-dev at openjdk.org>
Cc: Chen Liang <chen.l.liang at oracle.com>
Subject: Re: [External] : RE: StackMap problem


I see, the frame is listed at the end of the line.



Key question still remains – how the instrumentation is done?

Class- File API regenerates the stack map when I create similar method and inject the istore_1 and iload_1 instructions.



Adam





From: Mark Roberts <markro at cs.washington.edu>
Date: Wednesday, 29 January 2025 at 17:45
To: Adam Sotona <adam.sotona at oracle.com>, classfile-api-dev at openjdk.org <classfile-api-dev at openjdk.org>
Cc: Chen Liang <chen.l.liang at oracle.com>
Subject: [External] : RE: StackMap problem

The ‘before’ was compiled with javac version 24-ea+22-269, but I compiled with javac version 17.0.11 and got the exact same binary.  The stack map frames are there:



  StackMapTable:

  StackMap((SAME_LOCALS_1_STACK, offset delta=19, stack items={(type=Object, class=DataStructures.Overflow)}), (SAME, offset delta=0))



The first (@19) is the target of the exception handler, the second (@20) is the target of the branch @16.



It all looks good to me.



Mark





From: Adam Sotona <adam.sotona at oracle.com<mailto:adam.sotona at oracle.com>>
Sent: Wednesday, January 29, 2025 1:07 AM
To: Mark Roberts <markro at cs.washington.edu<mailto:markro at cs.washington.edu>>; classfile-api-dev at openjdk.org<mailto:classfile-api-dev at openjdk.org>
Cc: Chen Liang <chen.l.liang at oracle.com<mailto:chen.l.liang at oracle.com>>
Subject: Re: StackMap problem



Hi Mark,

Both attached class listings are missing stack map frames at branch targets, and they seem to be invalid.

I would like to ask what compiler generates the first class and how your tool adds the instrumentation code.

My first impression is that I don’t see any trace of Class-File API stack map generator involment. Transformation of a method with missing or invalid stack map would generate new stack maps, unless explicitly disabled.



Thanks,

Adam





From: classfile-api-dev <classfile-api-dev-retn at openjdk.org<mailto:classfile-api-dev-retn at openjdk.org>> on behalf of Mark Roberts <markro at cs.washington.edu<mailto:markro at cs.washington.edu>>
Date: Tuesday, 28 January 2025 at 21:45
To: classfile-api-dev at openjdk.org<mailto:classfile-api-dev at openjdk.org> <classfile-api-dev at openjdk.org<mailto:classfile-api-dev at openjdk.org>>
Cc: Chen Liang <chen.l.liang at oracle.com<mailto:chen.l.liang at oracle.com>>
Subject: StackMap problem

The existence of compiler generated, unnamed local temps (no LocalVariable code element) seems to cause a problem with stack maps.



The ‘source’ attachment shows the problem method.   The ‘before’ attachment shows the generated code before instrumentation.  Note that the compiler generates an unnamed temp at slot 0 to store the exception code. The stackmap for the branch target says same locals, which is correct.



The ‘after’ attachment shows the code generated after our tool has added instrumentation code – note the addition of a new local variable at slot 1.  The stackmap for the branch target still says same locals, which is no longer correct. This causes the iload_1 @41 to fail.



I tried to see if this issue has already been reported, but I was unable to figure out how to search https://bugs.java.com/bugdatabase/<https://urldefense.com/v3/__https:/bugs.java.com/bugdatabase/__;!!ACWV5N9M2RV99hQ!Oxj6SR2NV9Ad-EfEdNCFmjPL0gx3yAPgZ8jQoj8jWrlF9W-NohRiSuxWzqdOPpnNxoTuYr4zSmL9s1LDi14H1ymI$> by keyword.



Mark






-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/classfile-api-dev/attachments/20250129/c928ddad/attachment-0001.htm>


More information about the classfile-api-dev mailing list