JDK-6642881 : Improve performance of Class.getClassLoader()
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 7
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2007-12-17
  • Updated: 2015-07-01
  • Resolved: 2014-06-19
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
7u80Fixed 8u40Fixed 9 b23Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Relates :  
Currently, Class.getClassLoader() is a relatively expensive operation,
presumably because of jni overhead.

Some core library code would like to use it to optimize some operations.
E.g. when using a Charset to decode a byte stream into a char array,
one might have to make a defensive copy of the output char array because
a malicious Charset might keep a reference to it, thereby 
making it possible for a String to change its value in the future,
which is a big no-no.  Being able to ask whether a Charset is
provided as part of the JDK, cheaply, would be a big help to optimizing this
for "builtin" classes.

boolean isTrusted(Object x) { 
  return System.getSecurityManager() == null ||
         x.getClass().getClassLoader() == null; 

One suspects that getClassLoader() can be trivially optimized to a field access,
just like getClass() was.

This bug is filed against compiler2, but of course we encourage a fix in compiler1 as well.

I'm assigning this to you, Coleen. Close either this one or JDK-8034800.

No, I'm not working on this and yes, these are (basically) duplicates. You should use this bug though because it older, open and states clearly what the problem is.

Christian are you working on this? I have a change in progress to make it a field in java/lang/Class that I was using for bug https://bugs.openjdk.java.net/browse/JDK-8034800 Are these duplicates?

It is definitely possible to write an intrinsic for Class.getClassLoader0() but the much better solution would be to move the field to Java.

If the caller of Class.getClassLoader() is in rt.jar (i.e., loaded by NULL class loader), maybe the compiler can trivially substitute the getClassLoader call with getClassLoader0? This way all security checks are skipped (which should be the case anyway for the built-in JDK library classes). Doing this is harder if the caller is loaded by other class loaders. I think the results of System.getSecurityManager().checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION) should be constant for a given AccessControlContext. If this is indeed true, at compile time, we can check if the caller class has GET_CLASSLOADER_PERMISSION, and make the getClassLoader0 substitution. However, the code of checkPermission() is too complicated for a mere mortal to deduce its behavior ...

Not directly targeting the subject of this bug but on a related topic is the attached patch which replaces the System.security field with a VolatileCallSite. The patch is not working properly yet because of bootstrapping issues but the idea is that CallSite optimizations in the JIT compilers can constant fold the System.getSecurityManager() call. Combined with intrinsification of Class.getClassLoader() (or better moving the class loader field up into Java) we could constant fold two security related checks.

In order to be able to do some experiments a method substitution for Class.getClassLoader0() could be easily prototyped in Graal.

PUBLIC COMMENTS Well, I don't think that Class.getClassLoader() can be trivially intrinsified because of the SecurityManager, but Class.getClassLoader0() should be.