JVM does not match JVMS regarding array component types?
Anton W. Haubner
anton.haubner at outlook.de
Wed Apr 13 14:17:00 UTC 2022
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?
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