From e122507bfa1145c5429e3838664566273cf443f8 Mon Sep 17 00:00:00 2001 From: jfranck Date: Mon, 30 Sep 2013 12:19:48 +0200 Subject: [PATCH] 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 --- make/java/java/FILES_c.gmk | 1 + make/java/java/mapfile-vers | 2 ++ makefiles/mapfiles/libjava/mapfile-vers | 2 ++ .../java/lang/reflect/Constructor.java | 8 ----- .../classes/java/lang/reflect/Executable.java | 15 +++++--- .../classes/java/lang/reflect/Field.java | 7 ++-- .../classes/java/lang/reflect/Method.java | 8 ----- src/share/javavm/export/jvm.h | 5 +++ .../native/java/lang/reflect/Executable.c | 10 +++--- src/share/native/java/lang/reflect/Field.c | 34 +++++++++++++++++++ 10 files changed, 63 insertions(+), 29 deletions(-) create mode 100644 src/share/native/java/lang/reflect/Field.c diff --git a/make/java/java/FILES_c.gmk b/make/java/java/FILES_c.gmk index d01b0c295..29bb7e3b9 100644 --- a/make/java/java/FILES_c.gmk +++ b/make/java/java/FILES_c.gmk @@ -33,6 +33,7 @@ FILES_c = \ Console_md.c \ Double.c \ Executable.c \ + Field.c \ FileDescriptor_md.c \ FileInputStream.c \ FileInputStream_md.c \ diff --git a/make/java/java/mapfile-vers b/make/java/java/mapfile-vers index bb06a3d60..29ce7eb26 100644 --- a/make/java/java/mapfile-vers +++ b/make/java/java/mapfile-vers @@ -190,6 +190,8 @@ SUNWprivate_1.1 { 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; diff --git a/makefiles/mapfiles/libjava/mapfile-vers b/makefiles/mapfiles/libjava/mapfile-vers index bb06a3d60..29ce7eb26 100644 --- a/makefiles/mapfiles/libjava/mapfile-vers +++ b/makefiles/mapfiles/libjava/mapfile-vers @@ -190,6 +190,8 @@ SUNWprivate_1.1 { 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; diff --git a/src/share/classes/java/lang/reflect/Constructor.java b/src/share/classes/java/lang/reflect/Constructor.java index 0ed60dc37..202a7368f 100644 --- a/src/share/classes/java/lang/reflect/Constructor.java +++ b/src/share/classes/java/lang/reflect/Constructor.java @@ -67,8 +67,6 @@ public final class Constructor extends Executable { 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 @@ public final class Constructor extends Executable { res.root = this; // Might as well eagerly propagate this if already present res.constructorAccessor = constructorAccessor; - - res.typeAnnotations = typeAnnotations; return res; } @@ -155,10 +151,6 @@ public final class Constructor extends Executable { byte[] getAnnotationBytes() { return annotations; } - @Override - byte[] getTypeAnnotationBytes() { - return typeAnnotations; - } /** * {@inheritDoc} diff --git a/src/share/classes/java/lang/reflect/Executable.java b/src/share/classes/java/lang/reflect/Executable.java index af876c6f4..43b9cc64f 100644 --- a/src/share/classes/java/lang/reflect/Executable.java +++ b/src/share/classes/java/lang/reflect/Executable.java @@ -51,7 +51,6 @@ public abstract class Executable extends AccessibleObject * Accessor method to allow code sharing */ abstract byte[] getAnnotationBytes(); - abstract byte[] getTypeAnnotationBytes(); /** * Does the Executable have generic information. @@ -352,6 +351,12 @@ public abstract class Executable extends AccessibleObject 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 @@ public abstract class Executable extends AccessibleObject * @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 abstract class Executable extends AccessibleObject 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 @@ public abstract class Executable extends AccessibleObject * @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 @@ public abstract class Executable extends AccessibleObject * @since 1.8 */ public AnnotatedType[] getAnnotatedExceptionTypes() { - return TypeAnnotationParser.buildAnnotatedTypes(getTypeAnnotationBytes(), + return TypeAnnotationParser.buildAnnotatedTypes(getTypeAnnotationBytes0(), sun.misc.SharedSecrets.getJavaLangAccess(). getConstantPool(getDeclaringClass()), this, diff --git a/src/share/classes/java/lang/reflect/Field.java b/src/share/classes/java/lang/reflect/Field.java index 4052e06e8..e84b6b242 100644 --- a/src/share/classes/java/lang/reflect/Field.java +++ b/src/share/classes/java/lang/reflect/Field.java @@ -82,8 +82,6 @@ class Field extends AccessibleObject implements Member { // 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 @@ class Field extends AccessibleObject implements Member { res.fieldAccessor = fieldAccessor; res.overrideFieldAccessor = overrideFieldAccessor; - res.typeAnnotations = typeAnnotations; return res; } @@ -1148,6 +1145,8 @@ class Field extends AccessibleObject implements Member { 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 @@ class Field extends AccessibleObject implements Member { * @since 1.8 */ public AnnotatedType getAnnotatedType() { - return TypeAnnotationParser.buildAnnotatedType(typeAnnotations, + return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes0(), sun.misc.SharedSecrets.getJavaLangAccess(). getConstantPool(getDeclaringClass()), this, diff --git a/src/share/classes/java/lang/reflect/Method.java b/src/share/classes/java/lang/reflect/Method.java index 7c7abe43d..b046a7a1d 100644 --- a/src/share/classes/java/lang/reflect/Method.java +++ b/src/share/classes/java/lang/reflect/Method.java @@ -80,8 +80,6 @@ public final class Method extends Executable { // 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 @@ public final class Method extends Executable { res.root = this; // Might as well eagerly propagate this if already present res.methodAccessor = methodAccessor; - - res.typeAnnotations = typeAnnotations; return res; } @@ -166,10 +162,6 @@ public final class Method extends Executable { byte[] getAnnotationBytes() { return annotations; } - @Override - byte[] getTypeAnnotationBytes() { - return typeAnnotations; - } /** * {@inheritDoc} diff --git a/src/share/javavm/export/jvm.h b/src/share/javavm/export/jvm.h index 48181c06b..caec0b930 100644 --- a/src/share/javavm/export/jvm.h +++ b/src/share/javavm/export/jvm.h @@ -472,6 +472,11 @@ JVM_GetClassAnnotations(JNIEnv *env, jclass cls); 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 diff --git a/src/share/native/java/lang/reflect/Executable.c b/src/share/native/java/lang/reflect/Executable.c index f6133e8d8..1e32d5e17 100644 --- a/src/share/native/java/lang/reflect/Executable.c +++ b/src/share/native/java/lang/reflect/Executable.c @@ -23,11 +23,7 @@ * questions. */ -#include -#include - #include "jni.h" -#include "jni_util.h" #include "jvm.h" #include "java_lang_reflect_Executable.h" @@ -36,3 +32,9 @@ Java_java_lang_reflect_Executable_getParameters0(JNIEnv *env, 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); +} diff --git a/src/share/native/java/lang/reflect/Field.c b/src/share/native/java/lang/reflect/Field.c new file mode 100644 index 000000000..7800abf1a --- /dev/null +++ b/src/share/native/java/lang/reflect/Field.c @@ -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); +} -- GitLab