6642881: Improve performance of Class.getClassLoader()
authorcoleenp
Tue, 24 Jun 2014 11:23:34 -0400
changeset 25392 0eabdbb887aa
parent 25153 ee08c525ac5b
child 25393 c4036be0d564
child 25515 53904b7884f7
6642881: Improve performance of Class.getClassLoader() Summary: Add classLoader to java/lang/Class instance for fast access Reviewed-by: alanb, lfoltan, rriggs, vlivanov, twisti, mchung, jfranck, dholmes
jdk/src/share/classes/java/lang/Class.java
jdk/src/share/classes/java/lang/reflect/AccessibleObject.java
jdk/src/share/javavm/export/jvm.h
jdk/src/share/native/common/check_code.c
jdk/src/share/native/java/lang/Class.c
--- a/jdk/src/share/classes/java/lang/Class.java	Fri Jun 20 10:10:27 2014 -0700
+++ b/jdk/src/share/classes/java/lang/Class.java	Tue Jun 24 11:23:34 2014 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -130,11 +130,15 @@
     }
 
     /*
-     * Constructor. Only the Java Virtual Machine creates Class
-     * objects.
+     * Private constructor. Only the Java Virtual Machine creates Class objects.
+     * This constructor is not used and prevents the default constructor being
+     * generated.
      */
-    private Class() {}
-
+    private Class(ClassLoader loader) {
+        // Initialize final field for classLoader.  The initialization value of non-null
+        // prevents future JIT optimizations from assuming this final field is null.
+        classLoader = loader;
+    }
 
     /**
      * Converts the object to a string. The string representation is the
@@ -677,8 +681,10 @@
     }
 
     // Package-private to allow ClassLoader access
-    native ClassLoader getClassLoader0();
-
+    ClassLoader getClassLoader0() { return classLoader; }
+
+    // Initialized in JVM not by private constructor
+    private final ClassLoader classLoader;
 
     /**
      * Returns an array of {@code TypeVariable} objects that represent the
--- a/jdk/src/share/classes/java/lang/reflect/AccessibleObject.java	Fri Jun 20 10:10:27 2014 -0700
+++ b/jdk/src/share/classes/java/lang/reflect/AccessibleObject.java	Tue Jun 24 11:23:34 2014 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -129,16 +129,24 @@
         setAccessible0(this, flag);
     }
 
-    /* Check that you aren't exposing java.lang.Class.<init>. */
+    /* Check that you aren't exposing java.lang.Class.<init> or sensitive
+       fields in java.lang.Class. */
     private static void setAccessible0(AccessibleObject obj, boolean flag)
         throws SecurityException
     {
         if (obj instanceof Constructor && flag == true) {
             Constructor<?> c = (Constructor<?>)obj;
             if (c.getDeclaringClass() == Class.class) {
-                throw new SecurityException("Can not make a java.lang.Class" +
+                throw new SecurityException("Cannot make a java.lang.Class" +
                                             " constructor accessible");
             }
+        } else if (obj instanceof Field && flag == true) {
+            Field f = (Field)obj;
+            if (f.getDeclaringClass() == Class.class &&
+                f.getName().equals("classLoader")) {
+                throw new SecurityException("Cannot make java.lang.Class.classLoader" +
+                                            " accessible");
+            }
         }
         obj.override = flag;
     }
--- a/jdk/src/share/javavm/export/jvm.h	Fri Jun 20 10:10:27 2014 -0700
+++ b/jdk/src/share/javavm/export/jvm.h	Tue Jun 24 11:23:34 2014 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -426,9 +426,6 @@
 JNIEXPORT jobjectArray JNICALL
 JVM_GetClassInterfaces(JNIEnv *env, jclass cls);
 
-JNIEXPORT jobject JNICALL
-JVM_GetClassLoader(JNIEnv *env, jclass cls);
-
 JNIEXPORT jboolean JNICALL
 JVM_IsInterface(JNIEnv *env, jclass cls);
 
--- a/jdk/src/share/native/common/check_code.c	Fri Jun 20 10:10:27 2014 -0700
+++ b/jdk/src/share/native/common/check_code.c	Tue Jun 24 11:23:34 2014 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1357,16 +1357,9 @@
                 }
                 (*env)->DeleteLocalRef(env, super);
 
-                /* The optimizer make cause this to happen on local code */
+                /* The optimizer may cause this to happen on local code */
                 if (not_found) {
-#ifdef BROKEN_JAVAC
-                    jobject loader = JVM_GetClassLoader(env, context->class);
-                    int has_loader = (loader != 0);
-                    (*env)->DeleteLocalRef(env, loader);
-                    if (has_loader)
-#endif /* BROKEN_JAVAC */
-                        CCerror(context,
-                                "Illegal use of nonvirtual function call");
+                    CCerror(context, "Illegal use of nonvirtual function call");
                 }
             }
         }
--- a/jdk/src/share/native/java/lang/Class.c	Fri Jun 20 10:10:27 2014 -0700
+++ b/jdk/src/share/native/java/lang/Class.c	Tue Jun 24 11:23:34 2014 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -45,7 +45,6 @@
 #define CLS "Ljava/lang/Class;"
 #define CPL "Lsun/reflect/ConstantPool;"
 #define STR "Ljava/lang/String;"
-#define JCL "Ljava/lang/ClassLoader;"
 #define FLD "Ljava/lang/reflect/Field;"
 #define MHD "Ljava/lang/reflect/Method;"
 #define CTR "Ljava/lang/reflect/Constructor;"
@@ -56,7 +55,6 @@
     {"getName0",         "()" STR,          (void *)&JVM_GetClassName},
     {"getSuperclass",    "()" CLS,          NULL},
     {"getInterfaces0",   "()[" CLS,         (void *)&JVM_GetClassInterfaces},
-    {"getClassLoader0",  "()" JCL,          (void *)&JVM_GetClassLoader},
     {"isInterface",      "()Z",             (void *)&JVM_IsInterface},
     {"getSigners",       "()[" OBJ,         (void *)&JVM_GetClassSigners},
     {"setSigners",       "([" OBJ ")V",     (void *)&JVM_SetClassSigners},
@@ -81,7 +79,6 @@
 #undef OBJ
 #undef CLS
 #undef STR
-#undef JCL
 #undef FLD
 #undef MHD
 #undef CTR