[13] RFR(S) 8226566: [JVMCI] java.* classes are no longer necessarily resolved by the boot class loader
Vladimir Kozlov
vladimir.kozlov at oracle.com
Tue Jul 2 22:36:55 UTC 2019
Thank you, Doug
https://cr.openjdk.java.net/~kvn/8226566/webrev.01/
Dean, do you agree?
I started new testing.
Thanks,
Vladimir
On 7/2/19 3:01 PM, Doug Simon wrote:
> Based on Dean’s input, this is the change we now want:
>
> *if* (elementType.getName().startsWith("Ljava/") && hasSameClassLoader(/runtime/().getJavaLangObject())) {
> // Classes in a java.* package defined by the boot class loader are always resolved.
> *return* *true*;
> }
>
> I can confirm it also fixes the reported problem: https://github.com/oracle/graal/issues/1409#issuecomment-504254246
>
> -Doug
>
>> On 2 Jul 2019, at 20:10, Vladimir Kozlov <vladimir.kozlov at oracle.com <mailto:vladimir.kozlov at oracle.com>> wrote:
>>
>> Hi Doug,
>>
>> Do you have updated patch for it? Or we should just drop these changes?
>>
>> Thanks,
>> Vladimir
>>
>> On 6/24/19 12:12 PM, Doug Simon wrote:
>>>> On 24 Jun 2019, at 20:40, dean.long at oracle.com <mailto:dean.long at oracle.com> wrote:
>>>>
>>>> The code isn't restricted to just java.* anymore. Now it's any type that the platform classloader defines. Isn't
>>>> it possible that the class was resolved by the platform classloader, but accessingClass has a custom classloader
>>>> that throws ClassNotFound?
>>> I see your point - we should retain the check for java.*.
>>> -Doug
>>>> On 6/22/19 4:25 AM, Doug Simon wrote:
>>>>>
>>>>>> On 22 Jun 2019, at 01:14, dean.long at oracle.com <mailto:dean.long at oracle.com> <mailto:dean.long at oracle.com> wrote:
>>>>>>
>>>>>> Doesn't this assume that the classloader for accessingClass is well-behaved and delegates to the classloader for
>>>>>> Object? If the classloader is not well-behaved, is it safe to return true here?
>>>>>
>>>>> I don’t think it's possible for anything but the boot or platform class loader to load java.* classes:
>>>>>
>>>>> https://github.com/openjdk/jdk13/blob/master/src/java.base/share/classes/java/lang/ClassLoader.java#L891-L899
>>>>> <https://github.com/openjdk/jdk13/blob/master/src/java.base/share/classes/java/lang/ClassLoader.java#L891-L899>
>>>>>
>>>>> I’ve tested this:
>>>>>
>>>>> public class Main extends ClassLoader {
>>>>> @Override
>>>>> protected Class<?> findClass(String name) throws ClassNotFoundException {
>>>>> byte[] b = {};
>>>>> return defineClass(name, b, 0, b.length);
>>>>> }
>>>>>
>>>>> @Override
>>>>> protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
>>>>> return findClass(name);
>>>>> }
>>>>>
>>>>> public static void main(String[] args) throws Throwable {
>>>>> Main cl = new Main();
>>>>> for (String name : args) {
>>>>> try {
>>>>> System.out.printf("%s: loader = %s%n", name, Class.forName(name).getClassLoader());
>>>>> System.out.println(Class.forName(name, true, cl));
>>>>> } catch (Exception e) {
>>>>> e.printStackTrace();
>>>>> }
>>>>> }
>>>>> }
>>>>> }
>>>>>
>>>>>> java -version
>>>>> java version "11.0.3" 2019-04-16 LTS
>>>>> Java(TM) SE Runtime Environment 18.9 (build 11.0.3+12-LTS)
>>>>> Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.3+12-LTS, mixed mode)
>>>>>> java Main java.lang.Boolean java.sql.Array
>>>>> java.lang.Boolean: loader = null
>>>>> java.lang.SecurityException: Prohibited package name: java.lang
>>>>> at java.base/java.lang.ClassLoader.preDefineClass(ClassLoader.java:898)
>>>>> at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1014)
>>>>> at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:877)
>>>>> at Main.findClass(Main.java:5)
>>>>> at Main.loadClass(Main.java:10)
>>>>> at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
>>>>> at java.base/java.lang.Class.forName0(Native Method)
>>>>> at java.base/java.lang.Class.forName(Class.java:398)
>>>>> at Main.main(Main.java:18)
>>>>> java.sql.Array: loader = jdk.internal.loader.ClassLoaders$PlatformClassLoader at 47d384ee
>>>>> java.lang.SecurityException: Prohibited package name: java.sql
>>>>> at java.base/java.lang.ClassLoader.preDefineClass(ClassLoader.java:898)
>>>>> at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1014)
>>>>> at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:877)
>>>>> at Main.findClass(Main.java:5)
>>>>> at Main.loadClass(Main.java:10)
>>>>> at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
>>>>> at java.base/java.lang.Class.forName0(Native Method)
>>>>> at java.base/java.lang.Class.forName(Class.java:398)
>>>>> at Main.main(Main.java:18)
>>>>>
>>>>>> What happens if we just remove the special case for java.lang.Object's classloader? Does it hurt performance?
>>>>>
>>>>> It avoids a VM call for resolving all boot classes during compilation. We could also avoid the VM call for when
>>>>> resolving platform classes as well but I’m not sure how to get a ResolvedJavaType for a platform class.
>>>>>
>>>>> I don’t recall the measurements on the performance impact of this optimization. Maybe it doesn’t show up. However,
>>>>> in libgraal VM calls are relatively more expensive so seems like its worth keeping this shortcut.
>>>>>
>>>>> -Doug
>>>>>
>>>>>>
>>>>>> On 6/21/19 3:47 PM, Vladimir Kozlov wrote:
>>>>>>> https://cr.openjdk.java.net/~kvn/8226566/webrev.00/ <https://cr.openjdk.java.net/~kvn/8226566/webrev.00/>
>>>>>>> https://bugs.openjdk.java.net/browse/JDK-8226566 <https://bugs.openjdk.java.net/browse/JDK-8226566>
>>>>>>>
>>>>>>> Doug proposed the fix. I tested it.
>>>>>>>
>>>>>>> Thanks,
>>>>>>> Vladimir
>>>>>>
>>>>>
>>>>
>
More information about the hotspot-compiler-dev
mailing list