RFR: 8370405: C2: mismatched store from MergeStores wrongly scalarized in allocation elimination

Quan Anh Mai qamai at openjdk.org
Wed Oct 29 14:41:26 UTC 2025


On Wed, 29 Oct 2025 14:36:00 GMT, Emanuel Peter <epeter at openjdk.org> wrote:

>> I can make the assert strong for primitive types, and that is where the bug happened.
>> 
>> I tried to make it work for pointers too, but I got this example:
>> 
>> value_type: java/lang/Object:NotNull *
>> field_type: java/lang/Object (java/util/Enumeration) *
>> 
>> It happens in `ClassLoader.getResources` (about line 1445).
>> We seem to get back the `value_type = field_val->bottom_type()` from a nested call to `parent.getResources(name);`, but we don't seem to capture that this has the `Enumeration` interface.
>> But the `field_type` (store to `tmp[0]`) knows about that, and so it is a "narrower" type.
>> Is this expected?
>> - If yes: can I even write an assert here?
>> - If no: is this something we need/should fix?
>> 
>> 
>>   1436     public Enumeration<URL> getResources(String name) throws IOException {
>>   1437         Objects.requireNonNull(name);
>>   1438         @SuppressWarnings("unchecked")
>>   1439         Enumeration<URL>[] tmp = (Enumeration<URL>[]) new Enumeration<?>[2];
>>   1440         if (parent != null) {
>>   1441             tmp[0] = parent.getResources(name);   <------ look here
>>   1442         } else {    
>>   1443             tmp[0] = BootLoader.findResources(name);
>>   1444         }
>>   1445         tmp[1] = findResources(name);                                                                                                                                                                                                                                         
>>   1446 
>>   1447         return new CompoundEnumeration<>(tmp);
>>   1448     }
>
> @TobiHartmann gave me this:
> https://github.com/openjdk/jdk/pull/10901
> https://mail.openjdk.org/pipermail/hotspot-compiler-dev/2019-May/033803.html
> I need to study it more, but the idea is that interfaces cannot be trusted, and I could just try to ignore the interface part of the type.

It seems that we don't trust the return type of a method call (look at `TypeFunc::make(ciMethod*)` where we pass `ignore_interfaces` into `TypeTuple::make_domain` and `TypeTuple::make_range`). I don't understand why, though, interfaces are weird.

However, `tmp` is trusted because it is created with `anewarray`. In `Parse::do_anewarray`, we pass `trusted_interfaces` to `TypeKlassPtr::make`.

The question is, why are we storing an `Object` into an array of `Enumeration`s?

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/27997#discussion_r2473513179


More information about the hotspot-compiler-dev mailing list