JVM does not match JVMS regarding array component types?
Anton W. Haubner
anton.haubner at outlook.de
Fri Apr 15 15:48:35 UTC 2022
Hi David,
thank you for the link to the bug report. Apparently I did not read the
"fine-print" of the VirtualMachine.allClasses() method correctly.
I conclude:
The JVM does comply with the JVMS, the component type is created.
The JDI also complies with its specification.
The component type is not available during debugging, because the
"VirtualMachine.allClasses()" and "VirtualMachine.classesByName" methods
only return those loaded types which have also been prepared.
Section 5.4.3.1 of the JVMS which I was citing does only require
creation of the component type, not preparation.
Hence, my question has been answered. Thanks to everyone involved.
Best regards,
Anton
On 4/14/22 09:51, David Holmes wrote:
> Hi Anton,
>
> On 14/04/2022 12:17 am, Anton W. Haubner wrote:
>> Follow up on the conditions under which types should become visible
>> during debugging:
>>
>> JDB uses the JDI methods VirtualMachine.allClasses() and
>> VirtualMachine.classesByName() to look up types
>> (See com.sun.tools.example.debug.tty.Env.getReferenceTypeFromToken()).
>>
>> Looking at the JDI documentation and the specification of the
>> underlying JDWP, one normally should be able to look up all loaded
>> types:
>>
>> https://docs.oracle.com/en/java/javase/11/docs/api/jdk.jdi/com/sun/jdi/VirtualMachine.html#allClasses()
>>
>> https://docs.oracle.com/en/java/javase/11/docs/specs/jdwp/jdwp-protocol.html#JDWP_VirtualMachine_AllClasses
>>
>>
>> https://docs.oracle.com/en/java/javase/11/docs/api/jdk.jdi/com/sun/jdi/VirtualMachine.html#classesByName(java.lang.String)
>>
>> https://docs.oracle.com/en/java/javase/11/docs/specs/jdwp/jdwp-protocol.html#JDWP_VirtualMachine_ClassesBySignature
>>
>>
>> So maybe the JPDA backend agent of OpenJDK does not respect this
>> specification?
>
> See https://bugs.openjdk.java.net/browse/JDK-8181144
>
> Cheers,
> David
>
>>
>> On 4/13/22 16:14, Anton W. Haubner wrote:
>>> Hi!
>>>
>>> Thank you for this hint.
>>>
>>> The output of `java -Xlog:class+load ArrayTest` contains
>>>
>>> ```
>>> ...
>>> [0.242s][info][class,load] java.lang.Void source: jrt:/java.base
>>> [0.242s][info][class,load] Test source: file:/home/anton/<...>
>>> [0.242s][info][class,load]
>>> jdk.internal.misc.TerminatingThreadLocal$1 source: jrt:/java.base
>>> ...
>>>
>>> ```
>>>
>>> This is the only place where the component type "Test" is mentioned.
>>>
>>> If I understand this output correctly, then the "Test" class has
>>> actually been created.
>>> Now I wonder, under which conditions a created type becomes visible
>>> through the JDI.
>>>
>>> Best regards,
>>>
>>> Anton Haubner
>>>
>>> On 4/13/22 15:02, Volker Simonis wrote:
>>>> Just to make sure this is not an issue with jdb, could you please
>>>> run your example program with "-Xlog:class+load" and check the output?
>>>>
>>>> Anton W. Haubner <anton.haubner at outlook.de> schrieb am Mi., 13.
>>>> Apr. 2022, 11:12:
>>>>
>>>> Hi!
>>>>
>>>> I am not sure if this is the right place to ask these
>>>> questions. At
>>>> first glance, the "jls-jvms-spec-comments" mailing list looks more
>>>> appropriate but its description says that that list "is solely
>>>> a drop
>>>> box for reports".
>>>> Therefore, if I am out-of-place here, please direct me to the
>>>> appropriate mailing list.
>>>>
>>>> My question is about the behaviour of the JVM which seemingly does
>>>> not
>>>> match the JVMS specification when it comes to lazy-linking and
>>>> empty arrays.
>>>>
>>>> I noticed that regarding lazy-linking strategies and
>>>> resolution, the
>>>> JVMS states that if an array type is resolved whose element
>>>> type is a
>>>> reference type, then
>>>>
>>>> "a symbolic reference to the class or interface representing the
>>>> element type is resolved [...] recursively." [1]
>>>>
>>>> More specifically, the `anewarray` instruction requires the
>>>> resolution
>>>> of the component type when executed [2].
>>>>
>>>> However, while inspecting programs with the JDI, I observed
>>>> that when
>>>> creating an empty array, the component type of the array is
>>>> actually not
>>>> loaded.
>>>> You can observe this as follows:
>>>>
>>>> 1. Compile the following program with `javac -g`:
>>>>
>>>> ```
>>>> class Test { }
>>>>
>>>> public class ArrayTest {
>>>> public static void main(String[] args) {
>>>> var x = new Test[] {};
>>>> }
>>>> }
>>>>
>>>> ```
>>>>
>>>> 2. Executing `javap -v ArrayTest` will confirm that when
>>>> stopping the
>>>> program on line 6, `anewarray` must have been executed.
>>>>
>>>> 3. Run the following commands in `jdb`:
>>>>
>>>> stop at ArrayTest:6
>>>> run ArrayTest
>>>> class Test
>>>>
>>>> 4. It will say "Test is not a valid id or class name.", i.e. the
>>>> class
>>>> "Test" has not been loaded, even though it should have been
>>>> because it
>>>> is the component type of Test[] for which an instance has been
>>>> created.
>>>>
>>>> 5. If you change line 5 to "var x = new Test[] {new Test()};" jdb
>>>> will
>>>> actually return information about "Test", that is, the class is
>>>> loaded.
>>>>
>>>> From these observations I conclude, that the component type of an
>>>> array
>>>> type is not loaded, if only empty instances of the array type are
>>>> created.
>>>> I wonder, why this does not violate the specification of the JVMS
>>>> at [1]
>>>> and [2]
>>>>
>>>> (I am working with Java 11, so so far I tested this only for
>>>> OpenJDK 11)
>>>>
>>>> [1] Section 5.4.3.1, Java Virtual Machine Specification, Java 11:
>>>> https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-5.html#jvms-5.4.3.1
>>>>
>>>> [2]
>>>> https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-6.html#jvms-6.5.anewarray
>>>>
>>>>
>>>>
>>>>
More information about the discuss
mailing list