JVM does not match JVMS regarding array component types?
David Holmes
david.holmes at oracle.com
Thu Apr 14 07:51:04 UTC 2022
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