Review Request: 8242012: Drop the uniqueness guarantee from the suffix of the name of a hidden class
John Rose
john.r.rose at oracle.com
Wed Apr 8 02:47:18 UTC 2020
Thank you for fixing that. It looks good to me.
> On Apr 7, 2020, at 10:25 AM, Mandy Chung <mandy.chung at oracle.com> wrote:
>
> On 4/1/20 7:34 PM, John Rose wrote:
>> On Apr 1, 2020, at 6:19 PM, Mandy Chung <mandy.chung at oracle.com <mailto:mandy.chung at oracle.com>> wrote:
>>>
>>> I file https://bugs.openjdk.java.net/browse/JDK-8242012 <https://bugs.openjdk.java.net/browse/JDK-8242012> to track this issue.
>>
>> I would prefer to say that the suffix is simply an unspecified
>> simple name. Then leave it open for implementations to make it more
>> or less unpredictable, as a matter of QoS.
>> The standard of quality we
>> should aim at is that of System.identityHashCode—nothing much more
>> than that is desirable, and it’s easy to get at least that much quality.
>>
>> The java doc for Object.hashCode says this about the QoS I want here:
>>
>>> * As far as is reasonably practical, the {@code hashCode} method defined
>>> * by class {@code Object} returns distinct integers for distinct objects.
>>
>> So, the behavior I would like to keep open is something that cannot
>> readily be distinguished from functions like these…
>>
>> static String nextSuffix1() { return new Integer.toHexString(Object().hashCode()); }
>> static String nextSuffix2() { return new Integer.toUnsignedString(Object().hashCode(), 36); }
>> static String nextSuffix3() { return nextSuffix1()+nextSuffix2(); }
>>
>> …and many others.
>>
>> And I would settle for nextSuffix1, which (after all) is also a suffix of
>> the already specified value of new Object().toString(). To me, the result
>> of HC.toString() (where HC is a hidden class) should not be more deeply
>> informative than new Object().toString(). Also, the behavior currently
>> coded (in mangle_hidden_class_name) is consistent with nextSuffix1.
>>
>> (Observation: The JVM has no reason to choose this suffix, beyond the
>> simple reason that it is the first party to peek into the byte[] array of
>> the classfile image. It would be nice if the JDK platform code could
>> take responsibility for generating that extra suffix; it would make QoS
>> adjustments easier down the road. We could even go all the way and
>> guarantee that all such suffixes are truly unique; it would be a page of
>> Java code but several pages of HotSpot code. But, that’s inconvenient,
>> so I don’t recommend that now.)
>>
>> A parting shot: Yes, technically the implementation of the suffix
>> choosing (mangle_hidden_class_name) probably upholds almost the full
>> guarantee. (Although, it can fail if the JVM unloads and reloads a HC
>> of the same name at the same metadata address.) But if we make the
>> full guarantee part of the API, we set ourselves up to maintain that strong
>> behavior even if we move to another implementation in which metadata
>> pointers are allowed to change. I know we don’t want to do that, but
>> this is an example of how an overly strong guarantee that seems easy
>> to do in *one* JVM implementation can create headaches for *other*
>> JVM implementations. What’s easy to do in our implementation is
>> *often* close to the right primitive to specify, but we have a responsibility
>> to remove unnecessary promises and other implementation artifacts
>> from our specification.
>>
>> — John
>
> Thanks John for this.
>
> This is the spec update. I leave the mangle_hidden_class_name as is. We can move out the suffix assignment from the VM to the library code as a future cleanup.
>
> diff --git a/src/java.base/share/classes/java/lang/Class.java b/src/java.base/share/classes/java/lang/Class.java
> --- a/src/java.base/share/classes/java/lang/Class.java
> +++ b/src/java.base/share/classes/java/lang/Class.java
> @@ -799,8 +799,7 @@
> * where {@code N} is the <a href="ClassLoader.html#binary-name">binary name</a>
> * indicated by the {@code class} file passed to
> * {@link java.lang.invoke.MethodHandles.Lookup#defineHiddenClass(byte[], boolean, MethodHandles.Lookup.ClassOption...)
> - * Lookup::defineHiddenClass} and {@code <suffix>} is an unqualified name
> - * that is guaranteed to be unique during this execution of the JVM.
> + * Lookup::defineHiddenClass}, and {@code <suffix>} is an unqualified name.
> * </ul>
> *
> * <p> If this {@code Class} object represents an array class, then
> diff --git a/src/java.base/share/classes/java/lang/invoke/MethodHandles.java b/src/java.base/share/classes/java/lang/invoke/MethodHandles.java
> --- a/src/java.base/share/classes/java/lang/invoke/MethodHandles.java
> +++ b/src/java.base/share/classes/java/lang/invoke/MethodHandles.java
> @@ -1781,8 +1781,7 @@
> * denote a class or interface in the same package as the lookup class.</li>
> *
> * <li> Let {@code CN} be the string {@code N + "." + <suffix>},
> - * where {@code <suffix>} is an unqualified name that is guaranteed to be unique
> - * during this execution of the JVM.
> + * where {@code <suffix>} is an unqualified name.
> *
> * <p> Let {@code newBytes} be the {@code ClassFile} structure given by
> * {@code bytes} with an additional entry in the {@code constant_pool} table,
>
> thanks
> Mandy
More information about the valhalla-dev
mailing list