diff options
author | Mathieu Chartier <mathieuc@google.com> | 2015-03-24 11:25:43 -0700 |
---|---|---|
committer | Mathieu Chartier <mathieuc@google.com> | 2015-03-29 14:59:31 -0700 |
commit | eb183cdeab97f7fb25ae804319c1f5a46353dc4f (patch) | |
tree | 7b5e379f00dd7b4427463d33341e9c96d53f1ff1 /libart | |
parent | 34bc85c3db6a9ada71186907949899b1c1315e1d (diff) | |
download | libcore-eb183cdeab97f7fb25ae804319c1f5a46353dc4f.zip libcore-eb183cdeab97f7fb25ae804319c1f5a46353dc4f.tar.gz libcore-eb183cdeab97f7fb25ae804319c1f5a46353dc4f.tar.bz2 |
Make ArtField have no functionality
Pre-requisite to making them non java objects. Some other changes to
speed up reflection.
TODO: Another CL for ArtMethod.
Bug: 19264997
Change-Id: I17ca0cf4b9ba853e59f4a6eff3a05d9d90cf23f9
Diffstat (limited to 'libart')
5 files changed, 73 insertions, 257 deletions
diff --git a/libart/src/main/java/java/lang/Class.java b/libart/src/main/java/java/lang/Class.java index d766385..37b1d7d 100644 --- a/libart/src/main/java/java/lang/Class.java +++ b/libart/src/main/java/java/lang/Class.java @@ -55,6 +55,7 @@ import java.nio.charset.StandardCharsets; import java.security.ProtectionDomain; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import libcore.reflect.AnnotationAccess; import libcore.reflect.GenericSignatureParser; @@ -881,18 +882,7 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe * @throws NoSuchFieldException if the requested field can not be found. * @see #getField(String) */ - public Field getDeclaredField(String name) throws NoSuchFieldException { - if (name == null) { - throw new NullPointerException("name == null"); - } - Field result = getDeclaredFieldInternal(name); - if (result == null) { - throw new NoSuchFieldException(name); - } else { - result.getType(); // Throw NoClassDefFoundError if type cannot be resolved. - } - return result; - } + public native Field getDeclaredField(String name) throws NoSuchFieldException; /** * Returns an array containing {@code Field} objects for all fields declared @@ -902,17 +892,7 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe * * @see #getFields() */ - public Field[] getDeclaredFields() { - int initial_size = sFields == null ? 0 : sFields.length; - initial_size += iFields == null ? 0 : iFields.length; - ArrayList<Field> fields = new ArrayList(initial_size); - getDeclaredFieldsUnchecked(false, fields); - Field[] result = fields.toArray(new Field[fields.size()]); - for (Field f : result) { - f.getType(); // Throw NoClassDefFoundError if type cannot be resolved. - } - return result; - } + public native Field[] getDeclaredFields(); /** * Populates a list of fields without performing any security or type @@ -922,66 +902,18 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe * @param fields A list to populate with declared fields. * @hide */ - public void getDeclaredFieldsUnchecked(boolean publicOnly, List<Field> fields) { - if (iFields != null) { - for (ArtField f : iFields) { - if (!publicOnly || Modifier.isPublic(f.getAccessFlags())) { - fields.add(new Field(f)); - } - } - } - if (sFields != null) { - for (ArtField f : sFields) { - if (!publicOnly || Modifier.isPublic(f.getAccessFlags())) { - fields.add(new Field(f)); - } - } - } - } + public native Field[] getDeclaredFieldsUnchecked(boolean publicOnly); /** * Returns the field if it is defined by this class; null otherwise. This * may return a non-public member. */ - private Field getDeclaredFieldInternal(String name) { - - if (iFields != null) { - final ArtField matched = findByName(name, iFields); - if (matched != null) { - return new Field(matched); - } - } - if (sFields != null) { - final ArtField matched = findByName(name, sFields); - if (matched != null) { - return new Field(matched); - } - } - - return null; - } + private native Field getDeclaredFieldInternal(String name); /** - * Performs a binary search through {@code fields} for a field whose name - * is {@code name}. Returns {@code null} if no matching field exists. + * Returns the subset of getDeclaredFields which are public. */ - private static ArtField findByName(String name, ArtField[] fields) { - int low = 0, high = fields.length - 1; - while (low <= high) { - final int mid = (low + high) >>> 1; - final ArtField f = fields[mid]; - final int result = f.getName().compareTo(name); - if (result < 0) { - low = mid + 1; - } else if (result == 0) { - return f; - } else { - high = mid - 1; - } - } - - return null; - } + private native Field[] getPublicDeclaredFields(); /** * Returns the class that this class is a member of, or {@code null} if this @@ -1080,8 +1012,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe Field result = getPublicFieldRecursive(name); if (result == null) { throw new NoSuchFieldException(name); - } else { - result.getType(); // Throw NoClassDefFoundError if type cannot be resolved. } return result; } @@ -1098,8 +1028,7 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe // search iftable which has a flattened and uniqued list of interfaces if (ifTable != null) { for (int i = 0; i < ifTable.length; i += 2) { - Class<?> ifc = (Class<?>) ifTable[i]; - Field result = ifc.getPublicFieldRecursive(name); + Field result = ((Class<?>) ifTable[i]).getPublicFieldRecursive(name); if (result != null && (result.getModifiers() & Modifier.PUBLIC) != 0) { return result; } @@ -1123,11 +1052,7 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe public Field[] getFields() { List<Field> fields = new ArrayList<Field>(); getPublicFieldsRecursive(fields); - Field[] result = fields.toArray(new Field[fields.size()]); - for (Field f : result) { - f.getType(); // Throw NoClassDefFoundError if type cannot be resolved. - } - return result; + return fields.toArray(new Field[fields.size()]); } /** @@ -1137,15 +1062,14 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe private void getPublicFieldsRecursive(List<Field> result) { // search superclasses for (Class<?> c = this; c != null; c = c.superClass) { - c.getDeclaredFieldsUnchecked(true, result); + Collections.addAll(result, c.getPublicDeclaredFields()); } // search iftable which has a flattened and uniqued list of interfaces Object[] iftable = ifTable; if (iftable != null) { for (int i = 0; i < iftable.length; i += 2) { - Class<?> ifc = (Class<?>) iftable[i]; - ifc.getDeclaredFieldsUnchecked(true, result); + Collections.addAll(result, ((Class<?>) iftable[i]).getPublicDeclaredFields()); } } } diff --git a/libart/src/main/java/java/lang/reflect/AccessibleObject.java b/libart/src/main/java/java/lang/reflect/AccessibleObject.java index a1e2743..f623880 100644 --- a/libart/src/main/java/java/lang/reflect/AccessibleObject.java +++ b/libart/src/main/java/java/lang/reflect/AccessibleObject.java @@ -71,15 +71,8 @@ public class AccessibleObject implements AnnotatedElement { * IllegalAccessExceptions}. */ public void setAccessible(boolean flag) { - try { - if (equals(Class.class.getDeclaredConstructor())) { - throw new SecurityException("Can't make class constructor accessible"); - } - } catch (NoSuchMethodException e) { - throw new AssertionError("Couldn't find class constructor"); - } this.flag = flag; - } + } /** * Attempts to set the accessible flag for all objects in {@code objects}. diff --git a/libart/src/main/java/java/lang/reflect/ArtField.java b/libart/src/main/java/java/lang/reflect/ArtField.java index 6fdcdb2..1801862 100644 --- a/libart/src/main/java/java/lang/reflect/ArtField.java +++ b/libart/src/main/java/java/lang/reflect/ArtField.java @@ -51,46 +51,4 @@ public final class ArtField { * Only created by art directly. */ private ArtField() {} - - public int getAccessFlags() { - return accessFlags; - } - - int getDexFieldIndex() { - return fieldDexIndex; - } - - int getOffset() { - return offset; - } - - public String getName() { - if (fieldDexIndex == -1) { - // Proxy classes have 1 synthesized static field with no valid dex index - if (!declaringClass.isProxy()) { - throw new AssertionError(); - } - return "throws"; - } - Dex dex = declaringClass.getDex(); - int nameIndex = dex.nameIndexFromFieldIndex(fieldDexIndex); - return declaringClass.getDexCacheString(dex, nameIndex); - } - - Class<?> getDeclaringClass() { - return declaringClass; - } - - Class<?> getType() { - if (fieldDexIndex == -1) { - // The type of the synthesized field in a Proxy class is Class[][] - if (!declaringClass.isProxy()) { - throw new AssertionError(); - } - return Class[][].class; - } - Dex dex = declaringClass.getDex(); - int typeIndex = dex.typeIndexFromFieldIndex(fieldDexIndex); - return declaringClass.getDexCacheType(dex, typeIndex); - } } diff --git a/libart/src/main/java/java/lang/reflect/Constructor.java b/libart/src/main/java/java/lang/reflect/Constructor.java index 2eb12b0..66ae143 100644 --- a/libart/src/main/java/java/lang/reflect/Constructor.java +++ b/libart/src/main/java/java/lang/reflect/Constructor.java @@ -330,4 +330,20 @@ public final class Constructor<T> extends AbstractMethod implements GenericDecla return result.toString(); } + + /** + * Attempts to set the accessible flag. Setting this to true prevents {@code + * IllegalAccessExceptions}. + */ + public void setAccessible(boolean flag) { + Class<?> declaringClass = getDeclaringClass(); + if (declaringClass == Class.class) { + throw new SecurityException("Can't make class constructor accessible"); + } else if (declaringClass == Field.class) { + throw new SecurityException("Can't make field constructor accessible"); + } else if (declaringClass == Method.class) { + throw new SecurityException("Can't make method constructor accessible"); + } + super.setAccessible(flag); + } } diff --git a/libart/src/main/java/java/lang/reflect/Field.java b/libart/src/main/java/java/lang/reflect/Field.java index cad876b..37f2ad0 100644 --- a/libart/src/main/java/java/lang/reflect/Field.java +++ b/libart/src/main/java/java/lang/reflect/Field.java @@ -71,16 +71,13 @@ public final class Field extends AccessibleObject implements Member { } }; - private final ArtField artField; + private int accessFlags; + private Class<?> declaringClass; + private int dexFieldIndex; + private int offset; + private Class<?> type; - /** - * @hide - */ - public Field(ArtField artField) { - if (artField == null) { - throw new NullPointerException("artField == null"); - } - this.artField = artField; + private Field() { } /** @@ -91,7 +88,7 @@ public final class Field extends AccessibleObject implements Member { * @see Modifier */ @Override public int getModifiers() { - return artField.getAccessFlags() & 0xffff; // mask out bits not used by Java + return accessFlags & 0xffff; // mask out bits not used by Java } /** @@ -101,7 +98,7 @@ public final class Field extends AccessibleObject implements Member { * false} otherwise */ public boolean isEnumConstant() { - return (artField.getAccessFlags() & Modifier.ENUM) != 0; + return (accessFlags & Modifier.ENUM) != 0; } /** @@ -110,7 +107,7 @@ public final class Field extends AccessibleObject implements Member { * @return {@code true} if this field is synthetic, {@code false} otherwise */ @Override public boolean isSynthetic() { - return (artField.getAccessFlags() & Modifier.SYNTHETIC) != 0; + return (accessFlags & Modifier.SYNTHETIC) != 0; } /** @@ -119,11 +116,20 @@ public final class Field extends AccessibleObject implements Member { * @return the name of this field */ @Override public String getName() { - return artField.getName(); + if (dexFieldIndex == -1) { + // Proxy classes have 1 synthesized static field with no valid dex index. + if (!declaringClass.isProxy()) { + throw new AssertionError(); + } + return "throws"; + } + Dex dex = declaringClass.getDex(); + int nameIndex = dex.nameIndexFromFieldIndex(dexFieldIndex); + return declaringClass.getDexCacheString(dex, nameIndex); } @Override public Class<?> getDeclaringClass() { - return artField.getDeclaringClass(); + return declaringClass; } /** @@ -132,7 +138,7 @@ public final class Field extends AccessibleObject implements Member { * @return the type of this field */ public Class<?> getType() { - return artField.getType(); + return type; } /** @@ -141,7 +147,7 @@ public final class Field extends AccessibleObject implements Member { * @hide */ public int getDexFieldIndex() { - return artField.getDexFieldIndex(); + return dexFieldIndex; } /** @@ -150,7 +156,7 @@ public final class Field extends AccessibleObject implements Member { * @hide */ public int getOffset() { - return artField.getOffset(); + return offset; } /** @@ -170,8 +176,10 @@ public final class Field extends AccessibleObject implements Member { if (!(other instanceof Field)) { return false; } - // exactly one instance of each member in this runtime - return this.artField == ((Field) other).artField; + // Given same declaring class and offset, it must be the same field since no two distinct + // fields can have the same offset. + Field field = (Field)other; + return this.declaringClass == field.declaringClass && this.offset == field.offset; } /** @@ -277,11 +285,7 @@ public final class Field extends AccessibleObject implements Member { * @throws IllegalAccessException * if this field is not accessible */ - public Object get(Object object) throws IllegalAccessException, IllegalArgumentException { - return get(object, isAccessible()); - } - - private native Object get(Object object, boolean accessible) + public native Object get(Object object) throws IllegalAccessException, IllegalArgumentException; /** @@ -307,12 +311,7 @@ public final class Field extends AccessibleObject implements Member { * @throws IllegalAccessException * if this field is not accessible */ - public boolean getBoolean(Object object) throws IllegalAccessException, - IllegalArgumentException { - return getBoolean(object, isAccessible()); - } - - private native boolean getBoolean(Object object, boolean accessible) + public native boolean getBoolean(Object object) throws IllegalAccessException, IllegalArgumentException; /** @@ -338,11 +337,7 @@ public final class Field extends AccessibleObject implements Member { * @throws IllegalAccessException * if this field is not accessible */ - public byte getByte(Object object) throws IllegalAccessException, IllegalArgumentException { - return getByte(object, isAccessible()); - } - - private native byte getByte(Object object, boolean accessible) + public native byte getByte(Object object) throws IllegalAccessException, IllegalArgumentException; /** @@ -368,11 +363,7 @@ public final class Field extends AccessibleObject implements Member { * @throws IllegalAccessException * if this field is not accessible */ - public char getChar(Object object) throws IllegalAccessException, IllegalArgumentException { - return getChar(object, isAccessible()); - } - - private native char getChar(Object object, boolean accessible) + public native char getChar(Object object) throws IllegalAccessException, IllegalArgumentException; /** @@ -398,11 +389,7 @@ public final class Field extends AccessibleObject implements Member { * @throws IllegalAccessException * if this field is not accessible */ - public double getDouble(Object object) throws IllegalAccessException, IllegalArgumentException { - return getDouble(object, isAccessible()); - } - - private native double getDouble(Object object, boolean accessible) + public native double getDouble(Object object) throws IllegalAccessException, IllegalArgumentException; /** @@ -428,11 +415,7 @@ public final class Field extends AccessibleObject implements Member { * @throws IllegalAccessException * if this field is not accessible */ - public float getFloat(Object object) throws IllegalAccessException, IllegalArgumentException { - return getFloat(object, isAccessible()); - } - - private native float getFloat(Object object, boolean accessible) + public native float getFloat(Object object) throws IllegalAccessException, IllegalArgumentException; /** @@ -458,11 +441,7 @@ public final class Field extends AccessibleObject implements Member { * @throws IllegalAccessException * if this field is not accessible */ - public int getInt(Object object) throws IllegalAccessException, IllegalArgumentException { - return getInt(object, isAccessible()); - } - - private native int getInt(Object object, boolean accessible) + public native int getInt(Object object) throws IllegalAccessException, IllegalArgumentException; /** @@ -488,11 +467,7 @@ public final class Field extends AccessibleObject implements Member { * @throws IllegalAccessException * if this field is not accessible */ - public long getLong(Object object) throws IllegalAccessException, IllegalArgumentException { - return getLong(object, isAccessible()); - } - - private native long getLong(Object object, boolean accessible) + public native long getLong(Object object) throws IllegalAccessException, IllegalArgumentException; /** @@ -518,11 +493,7 @@ public final class Field extends AccessibleObject implements Member { * @throws IllegalAccessException * if this field is not accessible */ - public short getShort(Object object) throws IllegalAccessException, IllegalArgumentException { - return getShort(object, isAccessible()); - } - - private native short getShort(Object object, boolean accessible) + public native short getShort(Object object) throws IllegalAccessException, IllegalArgumentException; /** @@ -554,12 +525,7 @@ public final class Field extends AccessibleObject implements Member { * @throws IllegalAccessException * if this field is not accessible */ - public void set(Object object, Object value) throws IllegalAccessException, - IllegalArgumentException { - set(object, value, isAccessible()); - } - - private native void set(Object object, Object value, boolean accessible) + public native void set(Object object, Object value) throws IllegalAccessException, IllegalArgumentException; /** @@ -590,12 +556,7 @@ public final class Field extends AccessibleObject implements Member { * @throws IllegalAccessException * if this field is not accessible */ - public void setBoolean(Object object, boolean value) throws IllegalAccessException, - IllegalArgumentException { - setBoolean(object, value, isAccessible()); - } - - private native void setBoolean(Object object, boolean value, boolean accessible) + public native void setBoolean(Object object, boolean value) throws IllegalAccessException, IllegalArgumentException; /** @@ -625,14 +586,8 @@ public final class Field extends AccessibleObject implements Member { * @throws IllegalAccessException * if this field is not accessible */ - public void setByte(Object object, byte value) throws IllegalAccessException, - IllegalArgumentException { - setByte(object, value, isAccessible()); - } - - private native void setByte(Object object, byte value, boolean accessible) + public native void setByte(Object object, byte value) throws IllegalAccessException, IllegalArgumentException; - /** * Sets the value of the field in the specified object to the {@code char} * value. This reproduces the effect of {@code object.fieldName = value} @@ -660,12 +615,7 @@ public final class Field extends AccessibleObject implements Member { * @throws IllegalAccessException * if this field is not accessible */ - public void setChar(Object object, char value) throws IllegalAccessException, - IllegalArgumentException { - setChar(object, value, isAccessible()); - } - - private native void setChar(Object object, char value, boolean accessible) + public native void setChar(Object object, char value) throws IllegalAccessException, IllegalArgumentException; /** @@ -695,12 +645,7 @@ public final class Field extends AccessibleObject implements Member { * @throws IllegalAccessException * if this field is not accessible */ - public void setDouble(Object object, double value) throws IllegalAccessException, - IllegalArgumentException { - setDouble(object, value, isAccessible()); - } - - private native void setDouble(Object object, double value, boolean accessible) + public native void setDouble(Object object, double value) throws IllegalAccessException, IllegalArgumentException; /** @@ -730,12 +675,7 @@ public final class Field extends AccessibleObject implements Member { * @throws IllegalAccessException * if this field is not accessible */ - public void setFloat(Object object, float value) throws IllegalAccessException, - IllegalArgumentException { - setFloat(object, value, isAccessible()); - } - - private native void setFloat(Object object, float value, boolean accessible) + public native void setFloat(Object object, float value) throws IllegalAccessException, IllegalArgumentException; /** @@ -765,12 +705,7 @@ public final class Field extends AccessibleObject implements Member { * @throws IllegalAccessException * if this field is not accessible */ - public void setInt(Object object, int value) throws IllegalAccessException, - IllegalArgumentException { - setInt(object, value, isAccessible()); - } - - private native void setInt(Object object, int value, boolean accessible) + public native void setInt(Object object, int value) throws IllegalAccessException, IllegalArgumentException; /** @@ -800,12 +735,7 @@ public final class Field extends AccessibleObject implements Member { * @throws IllegalAccessException * if this field is not accessible */ - public void setLong(Object object, long value) throws IllegalAccessException, - IllegalArgumentException { - setLong(object, value, isAccessible()); - } - - private native void setLong(Object object, long value, boolean accessible) + public native void setLong(Object object, long value) throws IllegalAccessException, IllegalArgumentException; /** @@ -835,12 +765,7 @@ public final class Field extends AccessibleObject implements Member { * @throws IllegalAccessException * if this field is not accessible */ - public void setShort(Object object, short value) throws IllegalAccessException, - IllegalArgumentException { - setShort(object, value, isAccessible()); - } - - private native void setShort(Object object, short value, boolean accessible) + public native void setShort(Object object, short value) throws IllegalAccessException, IllegalArgumentException; /** |