Hello,
while using java.lang.Integer.TYPE I've found out that currently wrapper
classes for primitives initialize their own TYPE-fields by calling native
method java.lang.Class.getPrimitiveClass().
This can be simplified by changing existing declaration (here for
java.lang.Integer)
@SuppressWarnings("unchecked")
public static final Class<Integer> TYPE = (Class<Integer>)
Class.getPrimitiveClass("int");
to
public static final Class<Integer> TYPE = int.class;
This is likely to improve start-up time as Class.getPrimitiveClass() is called
9 times (8 primitive type wrappers + java.lang.Void), after the change this
method is not called at all and thus can be removed along with its backing C++
code on VM-side. The fields are initialized purely on Java side.
I've verified correctness of the substitution with this test run on JDK 11
@Test
void name() {
assert void.class == Void.TYPE;
assert boolean.class == Boolean.TYPE;
assert byte.class == Byte.TYPE;
assert char.class == Character.TYPE;
assert short.class == Short.TYPE;
assert int.class == Integer.TYPE;
assert long.class == Long.TYPE;
assert float.class == Float.TYPE;
assert double.class == Double.TYPE;
}
The patch is attached.
Regards,
Sergey Tsypanov
diff --git a/src/hotspot/share/include/jvm.h b/src/hotspot/share/include/jvm.h
--- a/src/hotspot/share/include/jvm.h
+++ b/src/hotspot/share/include/jvm.h
@@ -340,14 +340,6 @@
/*
- * Find primitive classes
- * utf: class name
- */
-JNIEXPORT jclass JNICALL
-JVM_FindPrimitiveClass(JNIEnv *env, const char *utf);
-
-
-/*
* Find a class from a boot class loader. Returns NULL if class not found.
*/
JNIEXPORT jclass JNICALL
diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp
--- a/src/hotspot/share/prims/jvm.cpp
+++ b/src/hotspot/share/prims/jvm.cpp
@@ -782,22 +782,6 @@
return NULL;
JVM_END
-
-JVM_ENTRY(jclass, JVM_FindPrimitiveClass(JNIEnv* env, const char* utf))
- JVMWrapper("JVM_FindPrimitiveClass");
- oop mirror = NULL;
- BasicType t = name2type(utf);
- if (t != T_ILLEGAL && !is_reference_type(t)) {
- mirror = Universe::java_mirror(t);
- }
- if (mirror == NULL) {
- THROW_MSG_0(vmSymbols::java_lang_ClassNotFoundException(), (char*) utf);
- } else {
- return (jclass) JNIHandles::make_local(env, mirror);
- }
-JVM_END
-
-
// Returns a class loaded by the bootstrap class loader; or null
// if not found. ClassNotFoundException is not thrown.
// FindClassFromBootLoader is exported to the launcher for windows.
diff --git a/src/java.base/share/classes/java/lang/Boolean.java b/src/java.base/share/classes/java/lang/Boolean.java
--- a/src/java.base/share/classes/java/lang/Boolean.java
+++ b/src/java.base/share/classes/java/lang/Boolean.java
@@ -62,8 +62,7 @@
*
* @since 1.1
*/
- @SuppressWarnings("unchecked")
- public static final Class<Boolean> TYPE = (Class<Boolean>) Class.getPrimitiveClass("boolean");
+ public static final Class<Boolean> TYPE = boolean.class;
/**
* The value of the Boolean.
diff --git a/src/java.base/share/classes/java/lang/Byte.java b/src/java.base/share/classes/java/lang/Byte.java
--- a/src/java.base/share/classes/java/lang/Byte.java
+++ b/src/java.base/share/classes/java/lang/Byte.java
@@ -62,8 +62,7 @@
* The {@code Class} instance representing the primitive type
* {@code byte}.
*/
- @SuppressWarnings("unchecked")
- public static final Class<Byte> TYPE = (Class<Byte>) Class.getPrimitiveClass("byte");
+ public static final Class<Byte> TYPE = byte.class;
/**
* Returns a new {@code String} object representing the
diff --git a/src/java.base/share/classes/java/lang/Character.java b/src/java.base/share/classes/java/lang/Character.java
--- a/src/java.base/share/classes/java/lang/Character.java
+++ b/src/java.base/share/classes/java/lang/Character.java
@@ -173,8 +173,7 @@
*
* @since 1.1
*/
- @SuppressWarnings("unchecked")
- public static final Class<Character> TYPE = (Class<Character>) Class.getPrimitiveClass("char");
+ public static final Class<Character> TYPE = char.class;
/*
* Normative general types
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
@@ -2828,12 +2828,6 @@
private native java.security.ProtectionDomain getProtectionDomain0();
/*
- * Return the Virtual Machine's Class object for the named
- * primitive type.
- */
- static native Class<?> getPrimitiveClass(String name);
-
- /*
* Check if client is allowed to access members. If access is denied,
* throw a SecurityException.
*
diff --git a/src/java.base/share/classes/java/lang/Double.java b/src/java.base/share/classes/java/lang/Double.java
--- a/src/java.base/share/classes/java/lang/Double.java
+++ b/src/java.base/share/classes/java/lang/Double.java
@@ -141,8 +141,7 @@
*
* @since 1.1
*/
- @SuppressWarnings("unchecked")
- public static final Class<Double> TYPE = (Class<Double>) Class.getPrimitiveClass("double");
+ public static final Class<Double> TYPE = double.class;
/**
* Returns a string representation of the {@code double}
diff --git a/src/java.base/share/classes/java/lang/Float.java b/src/java.base/share/classes/java/lang/Float.java
--- a/src/java.base/share/classes/java/lang/Float.java
+++ b/src/java.base/share/classes/java/lang/Float.java
@@ -138,8 +138,7 @@
*
* @since 1.1
*/
- @SuppressWarnings("unchecked")
- public static final Class<Float> TYPE = (Class<Float>) Class.getPrimitiveClass("float");
+ public static final Class<Float> TYPE = float.class;
/**
* Returns a string representation of the {@code float}
diff --git a/src/java.base/share/classes/java/lang/Integer.java b/src/java.base/share/classes/java/lang/Integer.java
--- a/src/java.base/share/classes/java/lang/Integer.java
+++ b/src/java.base/share/classes/java/lang/Integer.java
@@ -81,8 +81,7 @@
*
* @since 1.1
*/
- @SuppressWarnings("unchecked")
- public static final Class<Integer> TYPE = (Class<Integer>) Class.getPrimitiveClass("int");
+ public static final Class<Integer> TYPE = int.class;
/**
* All possible chars for representing a number as a String
diff --git a/src/java.base/share/classes/java/lang/Long.java b/src/java.base/share/classes/java/lang/Long.java
--- a/src/java.base/share/classes/java/lang/Long.java
+++ b/src/java.base/share/classes/java/lang/Long.java
@@ -82,8 +82,7 @@
*
* @since 1.1
*/
- @SuppressWarnings("unchecked")
- public static final Class<Long> TYPE = (Class<Long>) Class.getPrimitiveClass("long");
+ public static final Class<Long> TYPE = long.class;
/**
* Returns a string representation of the first argument in the
diff --git a/src/java.base/share/classes/java/lang/Short.java b/src/java.base/share/classes/java/lang/Short.java
--- a/src/java.base/share/classes/java/lang/Short.java
+++ b/src/java.base/share/classes/java/lang/Short.java
@@ -61,8 +61,7 @@
* The {@code Class} instance representing the primitive type
* {@code short}.
*/
- @SuppressWarnings("unchecked")
- public static final Class<Short> TYPE = (Class<Short>) Class.getPrimitiveClass("short");
+ public static final Class<Short> TYPE = short.class;
/**
* Returns a new {@code String} object representing the
diff --git a/src/java.base/share/classes/java/lang/Void.java b/src/java.base/share/classes/java/lang/Void.java
--- a/src/java.base/share/classes/java/lang/Void.java
+++ b/src/java.base/share/classes/java/lang/Void.java
@@ -40,8 +40,7 @@
* The {@code Class} object representing the pseudo-type corresponding to
* the keyword {@code void}.
*/
- @SuppressWarnings("unchecked")
- public static final Class<Void> TYPE = (Class<Void>) Class.getPrimitiveClass("void");
+ public static final Class<Void> TYPE = void.class;
/*
* The Void class cannot be instantiated.
diff --git a/src/java.base/share/native/libjava/Class.c b/src/java.base/share/native/libjava/Class.c
--- a/src/java.base/share/native/libjava/Class.c
+++ b/src/java.base/share/native/libjava/Class.c
@@ -158,27 +158,3 @@
}
return (*env)->IsAssignableFrom(env, cls2, cls);
}
-
-JNIEXPORT jclass JNICALL
-Java_java_lang_Class_getPrimitiveClass(JNIEnv *env,
- jclass cls,
- jstring name)
-{
- const char *utfName;
- jclass result;
-
- if (name == NULL) {
- JNU_ThrowNullPointerException(env, 0);
- return NULL;
- }
-
- utfName = (*env)->GetStringUTFChars(env, name, 0);
- if (utfName == 0)
- return NULL;
-
- result = JVM_FindPrimitiveClass(env, utfName);
-
- (*env)->ReleaseStringUTFChars(env, name, utfName);
-
- return result;
-}