8009719: core reflection should get type annotation data from the VM lazily
Summary: Remove typeAnnotations field from Method, Constructor, and Field, update Executable and Field to fetch data on demand.
Reviewed-by: darcy, erikj
--- a/jdk/make/java/java/FILES_c.gmk Mon Sep 30 11:18:18 2013 +0200
+++ b/jdk/make/java/java/FILES_c.gmk Mon Sep 30 12:19:48 2013 +0200
@@ -33,6 +33,7 @@
Console_md.c \
Double.c \
Executable.c \
+ Field.c \
FileDescriptor_md.c \
FileInputStream.c \
FileInputStream_md.c \
--- a/jdk/make/java/java/mapfile-vers Mon Sep 30 11:18:18 2013 +0200
+++ b/jdk/make/java/java/mapfile-vers Mon Sep 30 12:19:48 2013 +0200
@@ -190,6 +190,8 @@
Java_java_lang_reflect_Array_setLong;
Java_java_lang_reflect_Array_setShort;
Java_java_lang_reflect_Executable_getParameters0;
+ Java_java_lang_reflect_Executable_getTypeAnnotationBytes0;
+ Java_java_lang_reflect_Field_getTypeAnnotationBytes0;
Java_java_lang_Runtime_freeMemory;
Java_java_lang_Runtime_maxMemory;
Java_java_lang_Runtime_gc;
--- a/jdk/makefiles/mapfiles/libjava/mapfile-vers Mon Sep 30 11:18:18 2013 +0200
+++ b/jdk/makefiles/mapfiles/libjava/mapfile-vers Mon Sep 30 12:19:48 2013 +0200
@@ -190,6 +190,8 @@
Java_java_lang_reflect_Array_setLong;
Java_java_lang_reflect_Array_setShort;
Java_java_lang_reflect_Executable_getParameters0;
+ Java_java_lang_reflect_Executable_getTypeAnnotationBytes0;
+ Java_java_lang_reflect_Field_getTypeAnnotationBytes0;
Java_java_lang_Runtime_freeMemory;
Java_java_lang_Runtime_maxMemory;
Java_java_lang_Runtime_gc;
--- a/jdk/src/share/classes/java/lang/reflect/Constructor.java Mon Sep 30 11:18:18 2013 +0200
+++ b/jdk/src/share/classes/java/lang/reflect/Constructor.java Mon Sep 30 12:19:48 2013 +0200
@@ -67,8 +67,6 @@
private transient ConstructorRepository genericInfo;
private byte[] annotations;
private byte[] parameterAnnotations;
- // This is set by the vm at Constructor creation
- private byte[] typeAnnotations;
// Generics infrastructure
// Accessor for factory
@@ -141,8 +139,6 @@
res.root = this;
// Might as well eagerly propagate this if already present
res.constructorAccessor = constructorAccessor;
-
- res.typeAnnotations = typeAnnotations;
return res;
}
@@ -155,10 +151,6 @@
byte[] getAnnotationBytes() {
return annotations;
}
- @Override
- byte[] getTypeAnnotationBytes() {
- return typeAnnotations;
- }
/**
* {@inheritDoc}
--- a/jdk/src/share/classes/java/lang/reflect/Executable.java Mon Sep 30 11:18:18 2013 +0200
+++ b/jdk/src/share/classes/java/lang/reflect/Executable.java Mon Sep 30 12:19:48 2013 +0200
@@ -51,7 +51,6 @@
* Accessor method to allow code sharing
*/
abstract byte[] getAnnotationBytes();
- abstract byte[] getTypeAnnotationBytes();
/**
* Does the Executable have generic information.
@@ -352,6 +351,12 @@
private transient volatile Parameter[] parameters;
private native Parameter[] getParameters0();
+ private native byte[] getTypeAnnotationBytes0();
+
+ // Needed by reflectaccess
+ byte[] getTypeAnnotationBytes() {
+ return getTypeAnnotationBytes0();
+ }
/**
* Returns an array of {@code Class} objects that represent the
@@ -541,7 +546,7 @@
* @since 1.8
*/
AnnotatedType getAnnotatedReturnType0(Type returnType) {
- return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes(),
+ return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes0(),
sun.misc.SharedSecrets.getJavaLangAccess().
getConstantPool(getDeclaringClass()),
this,
@@ -574,7 +579,7 @@
public AnnotatedType getAnnotatedReceiverType() {
if (Modifier.isStatic(this.getModifiers()))
return null;
- return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes(),
+ return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes0(),
sun.misc.SharedSecrets.getJavaLangAccess().
getConstantPool(getDeclaringClass()),
this,
@@ -600,7 +605,7 @@
* @since 1.8
*/
public AnnotatedType[] getAnnotatedParameterTypes() {
- return TypeAnnotationParser.buildAnnotatedTypes(getTypeAnnotationBytes(),
+ return TypeAnnotationParser.buildAnnotatedTypes(getTypeAnnotationBytes0(),
sun.misc.SharedSecrets.getJavaLangAccess().
getConstantPool(getDeclaringClass()),
this,
@@ -626,7 +631,7 @@
* @since 1.8
*/
public AnnotatedType[] getAnnotatedExceptionTypes() {
- return TypeAnnotationParser.buildAnnotatedTypes(getTypeAnnotationBytes(),
+ return TypeAnnotationParser.buildAnnotatedTypes(getTypeAnnotationBytes0(),
sun.misc.SharedSecrets.getJavaLangAccess().
getConstantPool(getDeclaringClass()),
this,
--- a/jdk/src/share/classes/java/lang/reflect/Field.java Mon Sep 30 11:18:18 2013 +0200
+++ b/jdk/src/share/classes/java/lang/reflect/Field.java Mon Sep 30 12:19:48 2013 +0200
@@ -82,8 +82,6 @@
// currently only two levels deep (i.e., one root Field and
// potentially many Field objects pointing to it.)
private Field root;
- // This is set by the vm at Field creation
- private byte[] typeAnnotations;
// Generics infrastructure
@@ -149,7 +147,6 @@
res.fieldAccessor = fieldAccessor;
res.overrideFieldAccessor = overrideFieldAccessor;
- res.typeAnnotations = typeAnnotations;
return res;
}
@@ -1148,6 +1145,8 @@
return declaredAnnotations;
}
+ private native byte[] getTypeAnnotationBytes0();
+
/**
* Returns an AnnotatedType object that represents the use of a type to specify
* the declared type of the field represented by this Field.
@@ -1157,7 +1156,7 @@
* @since 1.8
*/
public AnnotatedType getAnnotatedType() {
- return TypeAnnotationParser.buildAnnotatedType(typeAnnotations,
+ return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes0(),
sun.misc.SharedSecrets.getJavaLangAccess().
getConstantPool(getDeclaringClass()),
this,
--- a/jdk/src/share/classes/java/lang/reflect/Method.java Mon Sep 30 11:18:18 2013 +0200
+++ b/jdk/src/share/classes/java/lang/reflect/Method.java Mon Sep 30 12:19:48 2013 +0200
@@ -80,8 +80,6 @@
// currently only two levels deep (i.e., one root Method and
// potentially many Method objects pointing to it.)
private Method root;
- // This is set by the vm at Method creation
- private byte[] typeAnnotations;
// Generics infrastructure
private String getGenericSignature() {return signature;}
@@ -152,8 +150,6 @@
res.root = this;
// Might as well eagerly propagate this if already present
res.methodAccessor = methodAccessor;
-
- res.typeAnnotations = typeAnnotations;
return res;
}
@@ -166,10 +162,6 @@
byte[] getAnnotationBytes() {
return annotations;
}
- @Override
- byte[] getTypeAnnotationBytes() {
- return typeAnnotations;
- }
/**
* {@inheritDoc}
--- a/jdk/src/share/javavm/export/jvm.h Mon Sep 30 11:18:18 2013 +0200
+++ b/jdk/src/share/javavm/export/jvm.h Mon Sep 30 12:19:48 2013 +0200
@@ -472,6 +472,11 @@
JNIEXPORT jbyteArray JNICALL
JVM_GetClassTypeAnnotations(JNIEnv *env, jclass cls);
+JNIEXPORT jbyteArray JNICALL
+JVM_GetFieldTypeAnnotations(JNIEnv *env, jobject field);
+
+JNIEXPORT jbyteArray JNICALL
+JVM_GetMethodTypeAnnotations(JNIEnv *env, jobject method);
/*
* New (JDK 1.4) reflection implementation
--- a/jdk/src/share/native/java/lang/reflect/Executable.c Mon Sep 30 11:18:18 2013 +0200
+++ b/jdk/src/share/native/java/lang/reflect/Executable.c Mon Sep 30 12:19:48 2013 +0200
@@ -23,11 +23,7 @@
* questions.
*/
-#include <string.h>
-#include <stdlib.h>
-
#include "jni.h"
-#include "jni_util.h"
#include "jvm.h"
#include "java_lang_reflect_Executable.h"
@@ -36,3 +32,9 @@
jobject method) {
return JVM_GetMethodParameters(env, method);
}
+
+JNIEXPORT jbyteArray JNICALL
+Java_java_lang_reflect_Executable_getTypeAnnotationBytes0(JNIEnv *env,
+ jobject method) {
+ return JVM_GetMethodTypeAnnotations(env, method);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/java/lang/reflect/Field.c Mon Sep 30 12:19:48 2013 +0200
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2013, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "jni.h"
+#include "jvm.h"
+#include "java_lang_reflect_Field.h"
+
+JNIEXPORT jbyteArray JNICALL
+Java_java_lang_reflect_Field_getTypeAnnotationBytes0(JNIEnv *env,
+ jobject field) {
+ return JVM_GetFieldTypeAnnotations(env, field);
+}