summaryrefslogtreecommitdiffstats
path: root/libart/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'libart/src/main/java')
-rw-r--r--libart/src/main/java/dalvik/system/TransactionAbortError.java62
-rw-r--r--libart/src/main/java/dalvik/system/VMRuntime.java17
-rw-r--r--libart/src/main/java/dalvik/system/VMStack.java7
-rw-r--r--libart/src/main/java/java/lang/Class.java381
-rw-r--r--libart/src/main/java/java/lang/ClassLoader.java4
-rw-r--r--libart/src/main/java/java/lang/Daemons.java118
-rw-r--r--libart/src/main/java/java/lang/DexCache.java17
-rw-r--r--libart/src/main/java/java/lang/Object.java7
-rw-r--r--libart/src/main/java/java/lang/String.java14
-rw-r--r--libart/src/main/java/java/lang/Thread.java8
-rw-r--r--libart/src/main/java/java/lang/reflect/AbstractMethod.java85
-rw-r--r--libart/src/main/java/java/lang/reflect/AccessibleObject.java9
-rw-r--r--libart/src/main/java/java/lang/reflect/ArtField.java96
-rw-r--r--libart/src/main/java/java/lang/reflect/ArtMethod.java134
-rw-r--r--libart/src/main/java/java/lang/reflect/Constructor.java33
-rw-r--r--libart/src/main/java/java/lang/reflect/Field.java176
-rw-r--r--libart/src/main/java/java/lang/reflect/Method.java38
-rwxr-xr-x[-rw-r--r--]libart/src/main/java/java/lang/reflect/Proxy.java14
-rw-r--r--libart/src/main/java/sun/misc/Unsafe.java6
19 files changed, 408 insertions, 818 deletions
diff --git a/libart/src/main/java/dalvik/system/TransactionAbortError.java b/libart/src/main/java/dalvik/system/TransactionAbortError.java
new file mode 100644
index 0000000..cfe4ca2
--- /dev/null
+++ b/libart/src/main/java/dalvik/system/TransactionAbortError.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dalvik.system;
+
+/**
+ * An exception only used by the compiler to abort a transaction.
+ *
+ * @hide
+ */
+final class TransactionAbortError extends InternalError {
+ /**
+ * Constructs a new {@code TransactionAbortError} with its stack trace filled in.
+ */
+ private TransactionAbortError() {
+ }
+
+ /**
+ * Constructs a new {@code TransactionAbortError} with its stack trace and detail
+ * message filled in.
+ *
+ * @param detailMessage the detail message for the exception.
+ */
+ private TransactionAbortError(String detailMessage) {
+ super(detailMessage);
+ }
+
+ /**
+ * Constructs a new {@code TransactionAbortError} with detail message and cause
+ * filled in.
+ *
+ * @param message the detail message for the exception.
+ * @param cause the detail cause for the exception.
+ */
+ private TransactionAbortError(String message, Throwable cause) {
+ super(message);
+ initCause(cause);
+ }
+
+ /**
+ * Constructs a new {@code TransactionAbortError} with its detail cause filled in.
+ *
+ * @param cause the detail cause for the exception.
+ */
+ private TransactionAbortError(Throwable cause) {
+ this(cause == null ? null : cause.toString(), cause);
+ }
+
+}
diff --git a/libart/src/main/java/dalvik/system/VMRuntime.java b/libart/src/main/java/dalvik/system/VMRuntime.java
index 43fa00e..b885ed2 100644
--- a/libart/src/main/java/dalvik/system/VMRuntime.java
+++ b/libart/src/main/java/dalvik/system/VMRuntime.java
@@ -33,6 +33,10 @@ public final class VMRuntime {
*/
private static final VMRuntime THE_ONE = new VMRuntime();
+ // Note: Instruction set names are used to construct the names of some
+ // system properties. To be sure that the properties stay valid the
+ // instruction set name should not exceed 7 characters. See installd
+ // and the package manager for the actual propeties.
private static final Map<String, String> ABI_TO_INSTRUCTION_SET_MAP
= new HashMap<String, String>();
static {
@@ -272,6 +276,12 @@ public final class VMRuntime {
public native void clearGrowthLimit();
/**
+ * Make the current growth limit the new non growth limit capacity by releasing pages which
+ * are after the growth limit but before the non growth limit capacity.
+ */
+ public native void clampGrowthLimit();
+
+ /**
* Returns true if either a Java debugger or native debugger is active.
*/
public native boolean isDebuggerActive();
@@ -291,8 +301,13 @@ public final class VMRuntime {
*/
public native void registerNativeFree(int bytes);
- public native void trimHeap();
+ public native void requestConcurrentGC();
public native void concurrentGC();
+ public native void requestHeapTrim();
+ public native void trimHeap();
+ public native void startHeapTaskProcessor();
+ public native void stopHeapTaskProcessor();
+ public native void runHeapTasks();
/**
* Let the heap know of the new process state. This can change allocation and garbage collection
diff --git a/libart/src/main/java/dalvik/system/VMStack.java b/libart/src/main/java/dalvik/system/VMStack.java
index ee0a0db..b69ab60 100644
--- a/libart/src/main/java/dalvik/system/VMStack.java
+++ b/libart/src/main/java/dalvik/system/VMStack.java
@@ -48,11 +48,10 @@ public final class VMStack {
native public static Class<?> getStackClass2();
/**
- * Returns the first ClassLoader on the call stack that isn't either of
- * the passed-in ClassLoaders.
+ * Returns the first ClassLoader on the call stack that isn't the
+ * bootstrap class loader.
*/
- public native static ClassLoader getClosestUserClassLoader(ClassLoader bootstrap,
- ClassLoader system);
+ public native static ClassLoader getClosestUserClassLoader();
/**
* Retrieves the stack trace from the specified thread.
diff --git a/libart/src/main/java/java/lang/Class.java b/libart/src/main/java/java/lang/Class.java
index 8833776..99c562f 100644
--- a/libart/src/main/java/java/lang/Class.java
+++ b/libart/src/main/java/java/lang/Class.java
@@ -39,7 +39,6 @@ import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.AnnotatedElement;
-import java.lang.reflect.ArtField;
import java.lang.reflect.ArtMethod;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
@@ -55,6 +54,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;
@@ -124,16 +124,16 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
private static final long serialVersionUID = 3206093459760846163L;
- /** defining class loader, or NULL for the "bootstrap" system loader. */
+ /** defining class loader, or null for the "bootstrap" system loader. */
private transient ClassLoader classLoader;
/**
* For array classes, the component class object for instanceof/checkcast (for String[][][],
- * this will be String[][]). NULL for non-array classes.
+ * this will be String[][]). null for non-array classes.
*/
private transient Class<?> componentType;
/**
- * DexCache of resolved constant pool entries. Will be null for certain VM-generated classes
+ * DexCache of resolved constant pool entries. Will be null for certain runtime-generated classes
* e.g. arrays and primitive classes.
*/
private transient DexCache dexCache;
@@ -145,16 +145,6 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
private transient ArtMethod[] directMethods;
/**
- * Instance fields. These describe the layout of the contents of an Object. Note that only the
- * fields directly declared by this class are listed in iFields; fields declared by a
- * superclass are listed in the superclass's Class.iFields.
- *
- * All instance fields that refer to objects are guaranteed to be at the beginning of the field
- * list. {@link Class#numReferenceInstanceFields} specifies the number of reference fields.
- */
- private transient ArtField[] iFields;
-
- /**
* The interface table (iftable_) contains pairs of a interface class and an array of the
* interface methods. There is one pair per interface supported by this class. That
* means one pair for each interface we support directly, indirectly via superclass, or
@@ -173,10 +163,7 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
/** Lazily computed name of this class; always prefer calling getName(). */
private transient String name;
- /** Static fields */
- private transient ArtField[] sFields;
-
- /** The superclass, or NULL if this is java.lang.Object, an interface or primitive type. */
+ /** The superclass, or null if this is java.lang.Object, an interface or primitive type. */
private transient Class<? super T> superClass;
/** If class verify fails, we must return same error on subsequent tries. */
@@ -197,6 +184,20 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
private transient int accessFlags;
/**
+ * Instance fields. These describe the layout of the contents of an Object. Note that only the
+ * fields directly declared by this class are listed in iFields; fields declared by a
+ * superclass are listed in the superclass's Class.iFields.
+ *
+ * All instance fields that refer to objects are guaranteed to be at the beginning of the field
+ * list. {@link Class#numReferenceInstanceFields} specifies the number of reference fields.
+ */
+ private transient long iFields;
+
+ /** Static fields */
+ private transient long sFields;
+
+
+ /**
* Total size of the Class instance; used when allocating storage on GC heap.
* See also {@link Class#objectSize}.
*/
@@ -221,32 +222,39 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
*/
private transient volatile int dexTypeIndex;
+ /** Number of instance fields. */
+ private transient int numInstanceFields;
+
/** Number of instance fields that are object references. */
private transient int numReferenceInstanceFields;
/** Number of static fields that are object references. */
private transient int numReferenceStaticFields;
+ /** Number of static fields. */
+ private transient int numStaticFields;
+
/**
* Total object size; used when allocating storage on GC heap. For interfaces and abstract
* classes this will be zero. See also {@link Class#classSize}.
*/
private transient int objectSize;
- /** Primitive type value, or 0 if not a primitive type; set for generated primitive classes. */
+ /**
+ * The lower 16 bits is the primitive type value, or 0 if not a primitive type; set for
+ * generated primitive classes.
+ */
private transient int primitiveType;
/** Bitmap of offsets of iFields. */
private transient int referenceInstanceOffsets;
- /** Bitmap of offsets of sFields. */
- private transient int referenceStaticOffsets;
-
/** State of class initialization */
private transient int status;
private Class() {
- // Prevent this class to be instantiated, instance should be created by JVM only
+ // Prevent this class from being instantiated,
+ // instances should be created by the runtime only.
}
/**
@@ -284,6 +292,9 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* If the class has not yet been initialized and {@code shouldInitialize} is true,
* the class will be initialized.
*
+ * <p>If the provided {@code classLoader} is {@code null}, the bootstrap
+ * class loader will be used to load the class.
+ *
* @throws ClassNotFoundException
* if the requested class cannot be found.
* @throws LinkageError
@@ -296,7 +307,7 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
ClassLoader classLoader) throws ClassNotFoundException {
if (classLoader == null) {
- classLoader = ClassLoader.getSystemClassLoader();
+ classLoader = BootClassLoader.getInstance();
}
// Catch an Exception thrown by the underlying native code. It wraps
// up everything inside a ClassNotFoundException, even if e.g. an
@@ -407,24 +418,7 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
return null;
}
- ClassLoader loader = getClassLoaderImpl();
- if (loader == null) {
- loader = BootClassLoader.getInstance();
- }
- return loader;
- }
-
- /**
- * This must be provided by the VM vendor, as it is used by other provided
- * class implementations in this package. Outside of this class, it is used
- * by SecurityManager.classLoaderDepth(),
- * currentClassLoader() and currentLoadedClass(). Return the ClassLoader for
- * this Class without doing any security checks. The bootstrap ClassLoader
- * is returned, unlike getClassLoader() which returns null in place of the
- * bootstrap ClassLoader.
- */
- ClassLoader getClassLoaderImpl() {
- ClassLoader loader = classLoader;
+ final ClassLoader loader = classLoader;
return loader == null ? BootClassLoader.getInstance() : loader;
}
@@ -456,10 +450,10 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* @hide
*/
public String getDexCacheString(Dex dex, int dexStringIndex) {
- String s = dexCacheStrings[dexStringIndex];
+ String s = dexCache.getResolvedString(dexStringIndex);
if (s == null) {
s = dex.strings().get(dexStringIndex).intern();
- dexCacheStrings[dexStringIndex] = s;
+ dexCache.setResolvedString(dexStringIndex, s);
}
return s;
}
@@ -471,13 +465,12 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* @hide
*/
public Class<?> getDexCacheType(Dex dex, int dexTypeIndex) {
- Class<?>[] dexCacheResolvedTypes = dexCache.resolvedTypes;
- Class<?> resolvedType = dexCacheResolvedTypes[dexTypeIndex];
+ Class<?> resolvedType = dexCache.getResolvedType(dexTypeIndex);
if (resolvedType == null) {
int descriptorIndex = dex.typeIds().get(dexTypeIndex);
String descriptor = getDexCacheString(dex, descriptorIndex);
resolvedType = InternalNames.getClass(getClassLoader(), descriptor);
- dexCacheResolvedTypes[dexTypeIndex] = resolvedType;
+ dexCache.setResolvedType(dexTypeIndex, resolvedType);
}
return resolvedType;
}
@@ -534,30 +527,12 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
}
/**
- * Returns the constructor with the given parameters if it is defined by this class; null
- * otherwise. This may return a non-public member.
+ * Returns the constructor with the given parameters if it is defined by this class;
+ * {@code null} otherwise. This may return a non-public member.
*
* @param args the types of the parameters to the constructor.
*/
- private Constructor<T> getDeclaredConstructorInternal(Class<?>[] args) {
- if (directMethods != null) {
- for (ArtMethod m : directMethods) {
- int modifiers = m.getAccessFlags();
- if (Modifier.isStatic(modifiers)) {
- // skip <clinit> which is a static constructor
- continue;
- }
- if (!Modifier.isConstructor(modifiers)) {
- continue;
- }
- if (!ArtMethod.equalConstructorParameters(m, args)) {
- continue;
- }
- return new Constructor<T>(m);
- }
- }
- return null;
- }
+ private native Constructor<T> getDeclaredConstructorInternal(Class<?>[] args);
/**
* Returns an array containing {@code Constructor} objects for all public
@@ -568,9 +543,7 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* @see #getDeclaredConstructors()
*/
public Constructor<?>[] getConstructors() {
- ArrayList<Constructor<T>> constructors = new ArrayList();
- getDeclaredConstructors(true, constructors);
- return constructors.toArray(new Constructor[constructors.size()]);
+ return getDeclaredConstructorsInternal(true);
}
/**
@@ -582,28 +555,11 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* @see #getConstructors()
*/
public Constructor<?>[] getDeclaredConstructors() {
- ArrayList<Constructor<T>> constructors = new ArrayList();
- getDeclaredConstructors(false, constructors);
- return constructors.toArray(new Constructor[constructors.size()]);
- }
-
- private void getDeclaredConstructors(boolean publicOnly, List<Constructor<T>> constructors) {
- if (directMethods != null) {
- for (ArtMethod m : directMethods) {
- int modifiers = m.getAccessFlags();
- if (!publicOnly || Modifier.isPublic(modifiers)) {
- if (Modifier.isStatic(modifiers)) {
- // skip <clinit> which is a static constructor
- continue;
- }
- if (Modifier.isConstructor(modifiers)) {
- constructors.add(new Constructor<T>(m));
- }
- }
- }
- }
+ return getDeclaredConstructorsInternal(false);
}
+ private native Constructor<?>[] getDeclaredConstructorsInternal(boolean publicOnly);
+
/**
* Returns a {@code Method} object which represents the method matching the
* specified name and parameter types that is declared by the class
@@ -689,68 +645,13 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
}
/**
- * Returns the method if it is defined by this class; null otherwise. This may return a
+ * Returns the method if it is defined by this class; {@code null} otherwise. This may return a
* non-public member.
*
* @param name the method name
* @param args the method's parameter types
*/
- private Method getDeclaredMethodInternal(String name, Class<?>[] args) {
- // Covariant return types permit the class to define multiple
- // methods with the same name and parameter types. Prefer to
- // return a non-synthetic method in such situations. We may
- // still return a synthetic method to handle situations like
- // escalated visibility. We never return miranda methods that
- // were synthesized by the VM.
- int skipModifiers = Modifier.MIRANDA | Modifier.SYNTHETIC;
- ArtMethod artMethodResult = null;
- if (virtualMethods != null) {
- for (ArtMethod m : virtualMethods) {
- String methodName = ArtMethod.getMethodName(m);
- if (!name.equals(methodName)) {
- continue;
- }
- if (!ArtMethod.equalMethodParameters(m, args)) {
- continue;
- }
- int modifiers = m.getAccessFlags();
- if ((modifiers & skipModifiers) == 0) {
- return new Method(m);
- }
- if ((modifiers & Modifier.MIRANDA) == 0) {
- // Remember as potential result if it's not a miranda method.
- artMethodResult = m;
- }
- }
- }
- if (artMethodResult == null) {
- if (directMethods != null) {
- for (ArtMethod m : directMethods) {
- int modifiers = m.getAccessFlags();
- if (Modifier.isConstructor(modifiers)) {
- continue;
- }
- String methodName = ArtMethod.getMethodName(m);
- if (!name.equals(methodName)) {
- continue;
- }
- if (!ArtMethod.equalMethodParameters(m, args)) {
- continue;
- }
- if ((modifiers & skipModifiers) == 0) {
- return new Method(m);
- }
- // Direct methods cannot be miranda methods,
- // so this potential result must be synthetic.
- artMethodResult = m;
- }
- }
- }
- if (artMethodResult == null) {
- return null;
- }
- return new Method(artMethodResult);
- }
+ private native Method getDeclaredMethodInternal(String name, Class<?>[] args);
/**
* Returns an array containing {@code Method} objects for all methods
@@ -761,11 +662,7 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* @see #getMethods()
*/
public Method[] getDeclaredMethods() {
- int initial_size = virtualMethods == null ? 0 : virtualMethods.length;
- initial_size += directMethods == null ? 0 : directMethods.length;
- ArrayList<Method> methods = new ArrayList<Method>(initial_size);
- getDeclaredMethodsUnchecked(false, methods);
- Method[] result = methods.toArray(new Method[methods.size()]);
+ Method[] result = getDeclaredMethodsUnchecked(false);
for (Method m : result) {
// Throw NoClassDefFoundError if types cannot be resolved.
m.getReturnType();
@@ -783,30 +680,7 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* @param methods A list to populate with declared methods.
* @hide
*/
- public void getDeclaredMethodsUnchecked(boolean publicOnly, List<Method> methods) {
- if (virtualMethods != null) {
- for (ArtMethod m : virtualMethods) {
- int modifiers = m.getAccessFlags();
- if (!publicOnly || Modifier.isPublic(modifiers)) {
- // Add non-miranda virtual methods.
- if ((modifiers & Modifier.MIRANDA) == 0) {
- methods.add(new Method(m));
- }
- }
- }
- }
- if (directMethods != null) {
- for (ArtMethod m : directMethods) {
- int modifiers = m.getAccessFlags();
- if (!publicOnly || Modifier.isPublic(modifiers)) {
- // Add non-constructor direct/static methods.
- if (!Modifier.isConstructor(modifiers)) {
- methods.add(new Method(m));
- }
- }
- }
- }
- }
+ public native Method[] getDeclaredMethodsUnchecked(boolean publicOnly);
/**
* Returns an array containing {@code Method} objects for all public methods
@@ -836,11 +710,11 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* superclasses, and all implemented interfaces, including overridden methods.
*/
private void getPublicMethodsInternal(List<Method> result) {
- getDeclaredMethodsUnchecked(true, result);
+ Collections.addAll(result, getDeclaredMethodsUnchecked(true));
if (!isInterface()) {
// Search superclasses, for interfaces don't search java.lang.Object.
for (Class<?> c = superClass; c != null; c = c.superClass) {
- c.getDeclaredMethodsUnchecked(true, result);
+ Collections.addAll(result, c.getDeclaredMethodsUnchecked(true));
}
}
// Search iftable which has a flattened and uniqued list of interfaces.
@@ -848,7 +722,7 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
if (iftable != null) {
for (int i = 0; i < iftable.length; i += 2) {
Class<?> ifc = (Class<?>) iftable[i];
- ifc.getDeclaredMethodsUnchecked(true, result);
+ Collections.addAll(result, ifc.getDeclaredMethodsUnchecked(true));
}
}
}
@@ -881,18 +755,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 +765,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 +775,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
+ * Returns the field if it is defined by this class; {@code 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 +885,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 +901,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 +925,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 +935,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());
}
}
}
@@ -1295,21 +1092,21 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
}
/**
- * Returns the simple name of a member or local class, or null otherwise.
+ * Returns the simple name of a member or local class, or {@code null} otherwise.
*/
private String getInnerClassName() {
return AnnotationAccess.getInnerClassName(this);
}
/**
- * Returns null.
+ * Returns {@code null}.
*/
public ProtectionDomain getProtectionDomain() {
return null;
}
/**
- * Returns the URL of the given resource, or null if the resource is not found.
+ * Returns the URL of the given resource, or {@code null} if the resource is not found.
* The mapping between the resource name and the URL is managed by the class' class loader.
*
* @see ClassLoader
@@ -1340,8 +1137,8 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
}
/**
- * Returns a read-only stream for the contents of the given resource, or null if the resource
- * is not found.
+ * Returns a read-only stream for the contents of the given resource, or {@code null} if the
+ * resource is not found.
* The mapping between the resource name and the stream is managed by the class' class loader.
*
* @see ClassLoader
@@ -1372,8 +1169,8 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
}
/**
- * Returns null. (On Android, a {@code ClassLoader} can load classes from multiple dex files.
- * All classes from any given dex file will have the same signers, but different dex
+ * Returns {@code null}. (On Android, a {@code ClassLoader} can load classes from multiple dex
+ * files. All classes from any given dex file will have the same signers, but different dex
* files may have different signers. This does not fit well with the original
* {@code ClassLoader}-based model of {@code getSigners}.)
*/
@@ -1547,7 +1344,7 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* Tests whether this {@code Class} represents a primitive type.
*/
public boolean isPrimitive() {
- return primitiveType != 0;
+ return (primitiveType & 0xFFFF) != 0;
}
/**
@@ -1582,33 +1379,7 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* @throws InstantiationException
* if the instance cannot be created.
*/
- public T newInstance() throws InstantiationException, IllegalAccessException {
- if (isPrimitive() || isInterface() || isArray() || Modifier.isAbstract(accessFlags)) {
- throw new InstantiationException(this + " cannot be instantiated");
- }
- Class<?> caller = VMStack.getStackClass1();
- if (!caller.canAccess(this)) {
- throw new IllegalAccessException(this + " is not accessible from " + caller);
- }
- Constructor<T> init;
- try {
- init = getDeclaredConstructor();
- } catch (NoSuchMethodException e) {
- InstantiationException t =
- new InstantiationException(this + " has no zero argument constructor");
- t.initCause(e);
- throw t;
- }
- if (!caller.canAccessMember(this, init.getAccessFlags())) {
- throw new IllegalAccessException(init + " is not accessible from " + caller);
- }
- try {
- return init.newInstance(null, init.isAccessible());
- } catch (InvocationTargetException e) {
- SneakyThrow.sneakyThrow(e.getCause());
- return null; // Unreachable.
- }
- }
+ public native T newInstance() throws InstantiationException, IllegalAccessException;
private boolean canAccess(Class<?> c) {
if(Modifier.isPublic(c.accessFlags)) {
@@ -1664,7 +1435,7 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
* object was created by the class loader of the class.
*/
public Package getPackage() {
- // TODO This might be a hack, but the VM doesn't have the necessary info.
+ // TODO This might be a hack, but the runtime doesn't have the necessary info.
ClassLoader loader = getClassLoader();
if (loader != null) {
String packageName = getPackageName$();
@@ -1674,7 +1445,7 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
}
/**
- * Returns the package name of this class. This returns null for classes in
+ * Returns the package name of this class. This returns {@code null} for classes in
* the default package.
*
* @hide
diff --git a/libart/src/main/java/java/lang/ClassLoader.java b/libart/src/main/java/java/lang/ClassLoader.java
index 9079dc4..dfbeeb5 100644
--- a/libart/src/main/java/java/lang/ClassLoader.java
+++ b/libart/src/main/java/java/lang/ClassLoader.java
@@ -646,8 +646,8 @@ public abstract class ClassLoader {
throw new IllegalArgumentException("Package " + name + " already defined");
}
- Package newPackage = new Package(name, specTitle, specVersion, specVendor, implTitle,
- implVersion, implVendor, sealBase);
+ Package newPackage = new Package(this, name, specTitle, specVersion, specVendor,
+ implTitle, implVersion, implVendor, sealBase);
packages.put(name, newPackage);
diff --git a/libart/src/main/java/java/lang/Daemons.java b/libart/src/main/java/java/lang/Daemons.java
index 485f2c9..43066e1 100644
--- a/libart/src/main/java/java/lang/Daemons.java
+++ b/libart/src/main/java/java/lang/Daemons.java
@@ -40,16 +40,14 @@ public final class Daemons {
ReferenceQueueDaemon.INSTANCE.start();
FinalizerDaemon.INSTANCE.start();
FinalizerWatchdogDaemon.INSTANCE.start();
- HeapTrimmerDaemon.INSTANCE.start();
- GCDaemon.INSTANCE.start();
+ HeapTaskDaemon.INSTANCE.start();
}
public static void stop() {
+ HeapTaskDaemon.INSTANCE.stop();
ReferenceQueueDaemon.INSTANCE.stop();
FinalizerDaemon.INSTANCE.stop();
FinalizerWatchdogDaemon.INSTANCE.stop();
- HeapTrimmerDaemon.INSTANCE.stop();
- GCDaemon.INSTANCE.stop();
}
/**
@@ -59,12 +57,17 @@ public final class Daemons {
*/
private static abstract class Daemon implements Runnable {
private Thread thread;
+ private String name;
+
+ protected Daemon(String name) {
+ this.name = name;
+ }
public synchronized void start() {
if (thread != null) {
throw new IllegalStateException("already running");
}
- thread = new Thread(ThreadGroup.systemThreadGroup, this, getClass().getSimpleName());
+ thread = new Thread(ThreadGroup.systemThreadGroup, this, name);
thread.setDaemon(true);
thread.start();
}
@@ -80,6 +83,10 @@ public final class Daemons {
}
public synchronized void interrupt() {
+ interrupt(thread);
+ }
+
+ public synchronized void interrupt(Thread thread) {
if (thread == null) {
throw new IllegalStateException("not running");
}
@@ -99,7 +106,7 @@ public final class Daemons {
if (threadToStop == null) {
throw new IllegalStateException("not running");
}
- threadToStop.interrupt();
+ interrupt(threadToStop);
while (true) {
try {
threadToStop.join();
@@ -125,6 +132,10 @@ public final class Daemons {
private static class ReferenceQueueDaemon extends Daemon {
private static final ReferenceQueueDaemon INSTANCE = new ReferenceQueueDaemon();
+ ReferenceQueueDaemon() {
+ super("ReferenceQueueDaemon");
+ }
+
@Override public void run() {
while (isRunning()) {
Reference<?> list;
@@ -144,20 +155,14 @@ public final class Daemons {
}
private void enqueue(Reference<?> list) {
- while (list != null) {
- Reference<?> reference;
- // pendingNext is owned by the GC so no synchronization is required
- if (list == list.pendingNext) {
- reference = list;
- reference.pendingNext = null;
- list = null;
- } else {
- reference = list.pendingNext;
- list.pendingNext = reference.pendingNext;
- reference.pendingNext = null;
- }
- reference.enqueueInternal();
- }
+ Reference<?> start = list;
+ do {
+ // pendingNext is owned by the GC so no synchronization is required.
+ Reference<?> next = list.pendingNext;
+ list.pendingNext = null;
+ list.enqueueInternal();
+ list = next;
+ } while (list != start);
}
}
@@ -167,6 +172,10 @@ public final class Daemons {
private volatile Object finalizingObject;
private volatile long finalizingStartedNanos;
+ FinalizerDaemon() {
+ super("FinalizerDaemon");
+ }
+
@Override public void run() {
while (isRunning()) {
// Take a reference, blocking until one is ready or the thread should stop
@@ -207,6 +216,10 @@ public final class Daemons {
private static class FinalizerWatchdogDaemon extends Daemon {
private static final FinalizerWatchdogDaemon INSTANCE = new FinalizerWatchdogDaemon();
+ FinalizerWatchdogDaemon() {
+ super("FinalizerWatchdogDaemon");
+ }
+
@Override public void run() {
while (isRunning()) {
boolean waitSuccessful = waitForObject();
@@ -294,59 +307,42 @@ public final class Daemons {
}
}
- // Invoked by the GC to request that the HeapTrimmerDaemon thread attempt to trim the heap.
+ // Adds a heap trim task ot the heap event processor, not called from java. Left for
+ // compatibility purposes due to reflection.
public static void requestHeapTrim() {
- synchronized (HeapTrimmerDaemon.INSTANCE) {
- HeapTrimmerDaemon.INSTANCE.notify();
- }
- }
-
- private static class HeapTrimmerDaemon extends Daemon {
- private static final HeapTrimmerDaemon INSTANCE = new HeapTrimmerDaemon();
-
- @Override public void run() {
- while (isRunning()) {
- try {
- synchronized (this) {
- wait();
- }
- VMRuntime.getRuntime().trimHeap();
- } catch (InterruptedException ignored) {
- }
- }
- }
+ VMRuntime.getRuntime().requestHeapTrim();
}
- // Invoked by the GC to request that the HeapTrimmerDaemon thread attempt to trim the heap.
+ // Adds a concurrent GC request task ot the heap event processor, not called from java. Left
+ // for compatibility purposes due to reflection.
public static void requestGC() {
- GCDaemon.INSTANCE.requestGC();
+ VMRuntime.getRuntime().requestConcurrentGC();
}
- private static class GCDaemon extends Daemon {
- private static final GCDaemon INSTANCE = new GCDaemon();
- private static final AtomicBoolean atomicBoolean = new AtomicBoolean();
+ private static class HeapTaskDaemon extends Daemon {
+ private static final HeapTaskDaemon INSTANCE = new HeapTaskDaemon();
- public void requestGC() {
- if (atomicBoolean.getAndSet(true)) {
- return;
- }
- synchronized (this) {
- notify();
- }
- atomicBoolean.set(false);
+ HeapTaskDaemon() {
+ super("HeapTaskDaemon");
+ }
+
+ // Overrides the Daemon.interupt method which is called from Daemons.stop.
+ public synchronized void interrupt(Thread thread) {
+ VMRuntime.getRuntime().stopHeapTaskProcessor();
}
@Override public void run() {
- while (isRunning()) {
- try {
- synchronized (this) {
- // Wait until a request comes in.
- wait();
- }
- VMRuntime.getRuntime().concurrentGC();
- } catch (InterruptedException ignored) {
+ synchronized (this) {
+ if (isRunning()) {
+ // Needs to be synchronized or else we there is a race condition where we start
+ // the thread, call stopHeapTaskProcessor before we start the heap task
+ // processor, resulting in a deadlock since startHeapTaskProcessor restarts it
+ // while the other thread is waiting in Daemons.stop().
+ VMRuntime.getRuntime().startHeapTaskProcessor();
}
}
+ // This runs tasks until we are stopped and there is no more pending task.
+ VMRuntime.getRuntime().runHeapTasks();
}
}
}
diff --git a/libart/src/main/java/java/lang/DexCache.java b/libart/src/main/java/java/lang/DexCache.java
index e4caffa..c047018 100644
--- a/libart/src/main/java/java/lang/DexCache.java
+++ b/libart/src/main/java/java/lang/DexCache.java
@@ -33,7 +33,6 @@
package java.lang;
import com.android.dex.Dex;
-import java.lang.reflect.ArtField;
import java.lang.reflect.ArtMethod;
/**
@@ -47,18 +46,18 @@ final class DexCache {
String location;
/**
- * References to fields as they become resolved following interpreter semantics. May refer to
- * fields defined in other dex files.
- */
- ArtField[] resolvedFields;
-
- /**
* References to methods as they become resolved following interpreter semantics. May refer to
* methods defined in other dex files.
*/
ArtMethod[] resolvedMethods;
/**
+ * References to fields as they become resolved following interpreter semantics. May refer to
+ * fields defined in other dex files. Either an int array or long array.
+ */
+ private Object resolvedFields;
+
+ /**
* References to types as they become resolved following interpreter semantics. May refer to
* types defined in other dex files.
*/
@@ -89,6 +88,10 @@ final class DexCache {
return result;
}
+ native Class<?> getResolvedType(int typeIndex);
+ native String getResolvedString(int stringIndex);
+ native void setResolvedType(int typeIndex, Class<?> type);
+ native void setResolvedString(int stringIndex, String string);
private native Dex getDexNative();
}
diff --git a/libart/src/main/java/java/lang/Object.java b/libart/src/main/java/java/lang/Object.java
index 20fdbf9..5b820e3 100644
--- a/libart/src/main/java/java/lang/Object.java
+++ b/libart/src/main/java/java/lang/Object.java
@@ -274,10 +274,11 @@ public class Object {
*/
public int hashCode() {
int lockWord = shadow$_monitor_;
- final int lockWordMask = 0xC0000000; // Top 2 bits.
+ final int lockWordStateMask = 0xC0000000; // Top 2 bits.
final int lockWordStateHash = 0x80000000; // Top 2 bits are value 2 (kStateHash).
- if ((lockWord & lockWordMask) == lockWordStateHash) {
- return lockWord & ~lockWordMask;
+ final int lockWordHashMask = 0x0FFFFFFF; // Low 28 bits.
+ if ((lockWord & lockWordStateMask) == lockWordStateHash) {
+ return lockWord & lockWordHashMask;
}
return System.identityHashCode(this);
}
diff --git a/libart/src/main/java/java/lang/String.java b/libart/src/main/java/java/lang/String.java
index 0107b6e..a5bf34c 100644
--- a/libart/src/main/java/java/lang/String.java
+++ b/libart/src/main/java/java/lang/String.java
@@ -22,12 +22,12 @@ import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
-import java.nio.charset.Charsets;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Formatter;
import java.util.Locale;
import java.util.regex.Pattern;
+import libcore.util.CharsetUtils;
import libcore.util.EmptyArray;
/**
@@ -337,12 +337,12 @@ outer:
this.offset = 0;
this.value = new char[byteCount];
this.count = byteCount;
- Charsets.isoLatin1BytesToChars(data, offset, byteCount, value);
+ CharsetUtils.isoLatin1BytesToChars(data, offset, byteCount, value);
} else if (canonicalCharsetName.equals("US-ASCII")) {
this.offset = 0;
this.value = new char[byteCount];
this.count = byteCount;
- Charsets.asciiBytesToChars(data, offset, byteCount, value);
+ CharsetUtils.asciiBytesToChars(data, offset, byteCount, value);
} else {
CharBuffer cb = charset.decode(ByteBuffer.wrap(data, offset, byteCount));
this.offset = 0;
@@ -772,13 +772,13 @@ outer:
public byte[] getBytes(Charset charset) {
String canonicalCharsetName = charset.name();
if (canonicalCharsetName.equals("UTF-8")) {
- return Charsets.toUtf8Bytes(value, offset, count);
+ return CharsetUtils.toUtf8Bytes(value, offset, count);
} else if (canonicalCharsetName.equals("ISO-8859-1")) {
- return Charsets.toIsoLatin1Bytes(value, offset, count);
+ return CharsetUtils.toIsoLatin1Bytes(value, offset, count);
} else if (canonicalCharsetName.equals("US-ASCII")) {
- return Charsets.toAsciiBytes(value, offset, count);
+ return CharsetUtils.toAsciiBytes(value, offset, count);
} else if (canonicalCharsetName.equals("UTF-16BE")) {
- return Charsets.toBigEndianUtf16Bytes(value, offset, count);
+ return CharsetUtils.toBigEndianUtf16Bytes(value, offset, count);
} else {
CharBuffer chars = CharBuffer.wrap(this.value, this.offset, this.count);
ByteBuffer buffer = charset.encode(chars.asReadOnlyBuffer());
diff --git a/libart/src/main/java/java/lang/Thread.java b/libart/src/main/java/java/lang/Thread.java
index 852e2cf..7b3666b 100644
--- a/libart/src/main/java/java/lang/Thread.java
+++ b/libart/src/main/java/java/lang/Thread.java
@@ -1158,7 +1158,7 @@ public class Thread implements Runnable {
*
* @hide for Unsafe
*/
- public void unpark() {
+ public final void unpark$() {
synchronized (lock) {
switch (parkState) {
case ParkState.PREEMPTIVELY_UNPARKED: {
@@ -1204,7 +1204,7 @@ public class Thread implements Runnable {
*
* @hide for Unsafe
*/
- public void parkFor(long nanos) {
+ public final void parkFor$(long nanos) {
synchronized (lock) {
switch (parkState) {
case ParkState.PREEMPTIVELY_UNPARKED: {
@@ -1260,7 +1260,7 @@ public class Thread implements Runnable {
*
* @hide for Unsafe
*/
- public void parkUntil(long time) {
+ public final void parkUntil$(long time) {
synchronized (lock) {
/*
* Note: This conflates the two time bases of "wall clock"
@@ -1281,7 +1281,7 @@ public class Thread implements Runnable {
if (delayMillis <= 0) {
parkState = ParkState.UNPARKED;
} else {
- parkFor(delayMillis * NANOS_PER_MILLI);
+ parkFor$(delayMillis * NANOS_PER_MILLI);
}
}
}
diff --git a/libart/src/main/java/java/lang/reflect/AbstractMethod.java b/libart/src/main/java/java/lang/reflect/AbstractMethod.java
index 7e6491d..0ac15f9 100644
--- a/libart/src/main/java/java/lang/reflect/AbstractMethod.java
+++ b/libart/src/main/java/java/lang/reflect/AbstractMethod.java
@@ -39,28 +39,38 @@ import libcore.reflect.AnnotationAccess;
import libcore.reflect.GenericSignatureParser;
import libcore.reflect.ListOfTypes;
import libcore.reflect.Types;
+import libcore.util.EmptyArray;
/**
* This class represents an abstract method. Abstract methods are either methods or constructors.
* @hide
*/
public abstract class AbstractMethod extends AccessibleObject {
+ /** Bits encoding access (e.g. public, private) as well as other runtime specific flags */
+ protected int accessFlags;
/**
+ * The ArtMethod associated with this Method, requried for dispatching due to entrypoints
* Hidden to workaround b/16828157.
* @hide
*/
- protected final ArtMethod artMethod;
+ protected ArtMethod artMethod;
+
+ /** Method's declaring class */
+ protected Class<?> declaringClass;
+
+ /** Overriden method's declaring class (same as declaringClass unless declaringClass
+ * is a proxy class) */
+ protected Class<?> declaringClassOfOverriddenMethod;
+
+ /** The method index of this method within its defining dex file */
+ protected int dexMethodIndex;
/**
* Hidden to workaround b/16828157.
* @hide
*/
- protected AbstractMethod(ArtMethod artMethod) {
- if (artMethod == null) {
- throw new NullPointerException("artMethod == null");
- }
- this.artMethod = artMethod;
+ protected AbstractMethod() {
}
public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
@@ -90,33 +100,33 @@ public abstract class AbstractMethod extends AccessibleObject {
}
int getModifiers() {
- return fixMethodFlags(artMethod.getAccessFlags());
+ return fixMethodFlags(accessFlags);
}
boolean isVarArgs() {
- return (artMethod.getAccessFlags() & Modifier.VARARGS) != 0;
+ return (accessFlags & Modifier.VARARGS) != 0;
}
boolean isBridge() {
- return (artMethod.getAccessFlags() & Modifier.BRIDGE) != 0;
+ return (accessFlags & Modifier.BRIDGE) != 0;
}
boolean isSynthetic() {
- return (artMethod.getAccessFlags() & Modifier.SYNTHETIC) != 0;
+ return (accessFlags & Modifier.SYNTHETIC) != 0;
}
/**
* @hide
*/
public final int getAccessFlags() {
- return artMethod.getAccessFlags();
+ return accessFlags;
}
/**
* Returns the class that declares this constructor or method.
*/
Class<?> getDeclaringClass() {
- return artMethod.getDeclaringClass();
+ return declaringClass;
}
/**
@@ -125,7 +135,7 @@ public abstract class AbstractMethod extends AccessibleObject {
* @hide
*/
public final int getDexMethodIndex() {
- return artMethod.getDexMethodIndex();
+ return dexMethodIndex;
}
/**
@@ -144,7 +154,17 @@ public abstract class AbstractMethod extends AccessibleObject {
* @return the parameter types
*/
Class<?>[] getParameterTypes() {
- return artMethod.getParameterTypes();
+ Dex dex = declaringClassOfOverriddenMethod.getDex();
+ short[] types = dex.parameterTypeIndicesFromMethodIndex(dexMethodIndex);
+ if (types.length == 0) {
+ return EmptyArray.CLASS;
+ }
+ Class<?>[] parametersArray = new Class[types.length];
+ for (int i = 0; i < types.length; i++) {
+ // Note, in the case of a Proxy the dex cache types are equal.
+ parametersArray[i] = declaringClassOfOverriddenMethod.getDexCacheType(dex, types[i]);
+ }
+ return parametersArray;
}
/**
@@ -155,8 +175,10 @@ public abstract class AbstractMethod extends AccessibleObject {
if (!(other instanceof AbstractMethod)) {
return false;
}
- // exactly one instance of each member in this runtime
- return this.artMethod == ((AbstractMethod) other).artMethod;
+ // Exactly one instance of each member in this runtime, todo, does this work for proxies?
+ AbstractMethod otherMethod = (AbstractMethod) other;
+ return this.declaringClass == otherMethod.declaringClass &&
+ this.dexMethodIndex == otherMethod.dexMethodIndex;
}
String toGenericString() {
@@ -252,6 +274,37 @@ public abstract class AbstractMethod extends AccessibleObject {
parser.returnType, parser.formalTypeParameters);
}
+ protected boolean equalMethodParameters(Class<?>[] params) {
+ Dex dex = declaringClassOfOverriddenMethod.getDex();
+ short[] types = dex.parameterTypeIndicesFromMethodIndex(dexMethodIndex);
+ if (types.length != params.length) {
+ return false;
+ }
+ for (int i = 0; i < types.length; i++) {
+ if (declaringClassOfOverriddenMethod.getDexCacheType(dex, types[i]) != params[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ protected int compareParameters(Class<?>[] params) {
+ Dex dex = declaringClassOfOverriddenMethod.getDex();
+ short[] types = dex.parameterTypeIndicesFromMethodIndex(dexMethodIndex);
+ int length = Math.min(types.length, params.length);
+ for (int i = 0; i < length; i++) {
+ Class<?> aType = declaringClassOfOverriddenMethod.getDexCacheType(dex, types[i]);
+ Class<?> bType = params[i];
+ if (aType != bType) {
+ int comparison = aType.getName().compareTo(bType.getName());
+ if (comparison != 0) {
+ return comparison;
+ }
+ }
+ }
+ return types.length - params.length;
+ }
+
/**
* Helper for Method and Constructor for toGenericString
*/
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
deleted file mode 100644
index 6fdcdb2..0000000
--- a/libart/src/main/java/java/lang/reflect/ArtField.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package java.lang.reflect;
-
-import com.android.dex.Dex;
-
-/**
- * @hide
- */
-public final class ArtField {
-
- private Class<?> declaringClass;
- /** Field access flags (modifiers) */
- private int accessFlags;
- /** Index into DexFile's field ids */
- private int fieldDexIndex;
- /** Offset of field in object or class */
- private int offset;
-
- /**
- * 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/ArtMethod.java b/libart/src/main/java/java/lang/reflect/ArtMethod.java
index 95e03c6..84e6b48 100644
--- a/libart/src/main/java/java/lang/reflect/ArtMethod.java
+++ b/libart/src/main/java/java/lang/reflect/ArtMethod.java
@@ -75,138 +75,4 @@ public final class ArtMethod {
/** Only created by ART directly. */
private ArtMethod() {}
-
- Class getDeclaringClass() {
- return declaringClass;
- }
-
- public int getAccessFlags() {
- return accessFlags;
- }
-
- int getDexMethodIndex() {
- return dexMethodIndex;
- }
-
- public static String getMethodName(ArtMethod artMethod) {
- artMethod = artMethod.findOverriddenMethodIfProxy();
- Dex dex = artMethod.getDeclaringClass().getDex();
- int nameIndex = dex.nameIndexFromMethodIndex(artMethod.getDexMethodIndex());
- // Note, in the case of a Proxy the dex cache strings are equal.
- return artMethod.getDexCacheString(dex, nameIndex);
- }
-
- /**
- * Returns true if the given parameters match those of the method in the given order.
- *
- * @hide
- */
- public static boolean equalConstructorParameters(ArtMethod artMethod, Class<?>[] params) {
- Dex dex = artMethod.getDeclaringClass().getDex();
- short[] types = dex.parameterTypeIndicesFromMethodIndex(artMethod.getDexMethodIndex());
- if (types.length != params.length) {
- return false;
- }
- for (int i = 0; i < types.length; i++) {
- if (artMethod.getDexCacheType(dex, types[i]) != params[i]) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Returns true if the given parameters match those of this method in the given order.
- *
- * @hide
- */
- public static boolean equalMethodParameters(ArtMethod artMethod, Class<?>[] params) {
- return equalConstructorParameters(artMethod.findOverriddenMethodIfProxy(), params);
- }
-
- Class<?>[] getParameterTypes() {
- Dex dex = getDeclaringClass().getDex();
- short[] types = dex.parameterTypeIndicesFromMethodIndex(dexMethodIndex);
- if (types.length == 0) {
- return EmptyArray.CLASS;
- }
- Class<?>[] parametersArray = new Class[types.length];
- for (int i = 0; i < types.length; i++) {
- // Note, in the case of a Proxy the dex cache types are equal.
- parametersArray[i] = getDexCacheType(dex, types[i]);
- }
- return parametersArray;
- }
-
- Class<?> getReturnType() {
- Dex dex = declaringClass.getDex();
- int returnTypeIndex = dex.returnTypeIndexFromMethodIndex(dexMethodIndex);
- // Note, in the case of a Proxy the dex cache types are equal.
- return getDexCacheType(dex, returnTypeIndex);
- }
-
- /**
- * Performs a comparison of the parameters to this method with the given parameters.
- *
- * @hide
- */
- int compareParameters(Class<?>[] params) {
- Dex dex = getDeclaringClass().getDex();
- short[] types = dex.parameterTypeIndicesFromMethodIndex(dexMethodIndex);
- int length = Math.min(types.length, params.length);
- for (int i = 0; i < length; i++) {
- Class<?> aType = getDexCacheType(dex, types[i]);
- Class<?> bType = params[i];
- if (aType != bType) {
- int comparison = aType.getName().compareTo(bType.getName());
- if (comparison != 0) {
- return comparison;
- }
- }
- }
- return types.length - params.length;
- }
-
- Annotation[][] getParameterAnnotations() {
- return AnnotationAccess.getParameterAnnotations(declaringClass, dexMethodIndex);
- }
-
- /**
- * Returns a string from the dex cache, computing the string from the dex file if necessary.
- * Note this method replicates {@link java.lang.Class#getDexCacheString(Dex, int)}, but in
- * Method we can avoid one indirection.
- */
- private String getDexCacheString(Dex dex, int dexStringIndex) {
- return declaringClass.getDexCacheString(dex, dexStringIndex);
- }
-
- /**
- * Returns a resolved type from the dex cache, computing the string from the dex file if
- * necessary. Note this method delegates to {@link java.lang.Class#getDexCacheType(Dex, int)},
- * but in Method we can avoid one indirection.
- */
- private Class<?> getDexCacheType(Dex dex, int dexTypeIndex) {
- Class<?> resolvedType = dexCacheResolvedTypes[dexTypeIndex];
- if (resolvedType == null) {
- resolvedType = declaringClass.getDexCacheType(dex, dexTypeIndex);
- }
- return resolvedType;
- }
-
- /**
- * Returns the {@code ArtMethod} that this method overrides for
- * proxy methods, otherwise returns this method. Used to determine
- * the interface method overridden by a proxy method (as the proxy
- * method doesn't directly support operations such as {@link
- * Method#getName}).
- */
- ArtMethod findOverriddenMethodIfProxy() {
- if (declaringClass.isProxy()) {
- // Proxy method's declaring class' dex cache refers to that of Proxy. The local cache in
- // Method refers to the original interface's dex cache and is ensured to be resolved by
- // proxy generation.
- return dexCacheResolvedMethods[dexMethodIndex];
- }
- return this;
- }
}
diff --git a/libart/src/main/java/java/lang/reflect/Constructor.java b/libart/src/main/java/java/lang/reflect/Constructor.java
index 2eb12b0..9711ef4 100644
--- a/libart/src/main/java/java/lang/reflect/Constructor.java
+++ b/libart/src/main/java/java/lang/reflect/Constructor.java
@@ -49,11 +49,7 @@ public final class Constructor<T> extends AbstractMethod implements GenericDecla
private static final Comparator<Method> ORDER_BY_SIGNATURE = null; // Unused; must match Method.
- /**
- * @hide
- */
- public Constructor(ArtMethod artMethod) {
- super(artMethod);
+ private Constructor() {
}
public Annotation[] getAnnotations() {
@@ -213,7 +209,8 @@ public final class Constructor<T> extends AbstractMethod implements GenericDecla
* @return an array of arrays of {@code Annotation} instances
*/
public Annotation[][] getParameterAnnotations() {
- return artMethod.getParameterAnnotations();
+ return AnnotationAccess.getParameterAnnotations(
+ declaringClassOfOverriddenMethod, dexMethodIndex);
}
/**
@@ -283,13 +280,7 @@ public final class Constructor<T> extends AbstractMethod implements GenericDecla
*
* @see AccessibleObject
*/
- public T newInstance(Object... args) throws InstantiationException,
- IllegalAccessException, IllegalArgumentException, InvocationTargetException {
- return newInstance(args, isAccessible());
- }
-
- /** @hide */
- public native T newInstance(Object[] args, boolean accessible) throws InstantiationException,
+ public native T newInstance(Object... args) throws InstantiationException,
IllegalAccessException, IllegalArgumentException, InvocationTargetException;
/**
@@ -330,4 +321,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 11e8a6e..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;
}
/**
@@ -182,10 +190,12 @@ public final class Field extends AccessibleObject implements Member {
*/
public String toGenericString() {
StringBuilder sb = new StringBuilder(80);
+ // Limit modifier bits to the ones that toStringGeneric should return for fields.
+
+ String modifiers = Modifier.getDeclarationFieldModifiers(getModifiers());
// append modifiers if any
- int modifier = getModifiers();
- if (modifier != 0) {
- sb.append(Modifier.toString(modifier)).append(' ');
+ if (!modifiers.isEmpty()) {
+ sb.append(modifiers).append(' ');
}
// append generic type
Types.appendGenericType(sb, getGenericType());
@@ -275,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;
/**
@@ -305,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;
/**
@@ -336,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;
/**
@@ -366,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;
/**
@@ -396,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;
/**
@@ -426,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;
/**
@@ -456,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;
/**
@@ -486,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;
/**
@@ -516,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;
/**
@@ -552,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;
/**
@@ -588,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;
/**
@@ -623,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}
@@ -658,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;
/**
@@ -693,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;
/**
@@ -728,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;
/**
@@ -763,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;
/**
@@ -798,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;
/**
@@ -833,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;
/**
@@ -861,7 +788,8 @@ public final class Field extends AccessibleObject implements Member {
*/
@Override
public String toString() {
- StringBuilder result = new StringBuilder(Modifier.toString(getModifiers()));
+ StringBuilder result = new StringBuilder(
+ Modifier.getDeclarationFieldModifiers(getModifiers()));
if (result.length() != 0) {
result.append(' ');
}
diff --git a/libart/src/main/java/java/lang/reflect/Method.java b/libart/src/main/java/java/lang/reflect/Method.java
index 058fb96..a07ec6f 100644
--- a/libart/src/main/java/java/lang/reflect/Method.java
+++ b/libart/src/main/java/java/lang/reflect/Method.java
@@ -57,8 +57,7 @@ public final class Method extends AbstractMethod implements GenericDeclaration,
}
int comparison = a.getName().compareTo(b.getName());
if (comparison == 0) {
- comparison = a.artMethod.findOverriddenMethodIfProxy().compareParameters(
- b.getParameterTypes());
+ comparison = a.compareParameters(b.getParameterTypes());
if (comparison == 0) {
// This is necessary for methods that have covariant return types.
Class<?> aReturnType = a.getReturnType();
@@ -77,12 +76,7 @@ public final class Method extends AbstractMethod implements GenericDeclaration,
/**
* @hide
*/
- public Method(ArtMethod artMethod) {
- super(artMethod);
- }
-
- ArtMethod getArtMethod() {
- return artMethod;
+ private Method() {
}
public Annotation[] getAnnotations() {
@@ -136,7 +130,9 @@ public final class Method extends AbstractMethod implements GenericDeclaration,
* @return the name of this method
*/
@Override public String getName() {
- return ArtMethod.getMethodName(artMethod);
+ Dex dex = declaringClassOfOverriddenMethod.getDex();
+ int nameIndex = dex.nameIndexFromMethodIndex(dexMethodIndex);
+ return declaringClassOfOverriddenMethod.getDexCacheString(dex, nameIndex);
}
/**
@@ -171,7 +167,7 @@ public final class Method extends AbstractMethod implements GenericDeclaration,
* @return the parameter types
*/
@Override public Class<?>[] getParameterTypes() {
- return artMethod.findOverriddenMethodIfProxy().getParameterTypes();
+ return super.getParameterTypes();
}
/**
@@ -181,9 +177,13 @@ public final class Method extends AbstractMethod implements GenericDeclaration,
* @return the return type
*/
public Class<?> getReturnType() {
- return artMethod.findOverriddenMethodIfProxy().getReturnType();
+ Dex dex = declaringClassOfOverriddenMethod.getDex();
+ int returnTypeIndex = dex.returnTypeIndexFromMethodIndex(dexMethodIndex);
+ // Note, in the case of a Proxy the dex cache types are equal.
+ return declaringClassOfOverriddenMethod.getDexCacheType(dex, returnTypeIndex);
}
+
/**
* {@inheritDoc}
*
@@ -209,8 +209,7 @@ public final class Method extends AbstractMethod implements GenericDeclaration,
* @hide needed by Proxy
*/
boolean equalNameAndParameters(Method m) {
- return getName().equals(m.getName()) &&
- ArtMethod.equalMethodParameters(artMethod,m.getParameterTypes());
+ return getName().equals(m.getName()) && equalMethodParameters(m.getParameterTypes());
}
/**
@@ -310,7 +309,8 @@ public final class Method extends AbstractMethod implements GenericDeclaration,
* @return an array of arrays of {@code Annotation} instances
*/
public Annotation[][] getParameterAnnotations() {
- return artMethod.findOverriddenMethodIfProxy().getParameterAnnotations();
+ return AnnotationAccess.getParameterAnnotations(
+ declaringClassOfOverriddenMethod, dexMethodIndex);
}
/**
@@ -367,12 +367,7 @@ public final class Method extends AbstractMethod implements GenericDeclaration,
* @throws InvocationTargetException
* if an exception was thrown by the invoked method
*/
- public Object invoke(Object receiver, Object... args)
- throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
- return invoke(receiver, args, isAccessible());
- }
-
- private native Object invoke(Object receiver, Object[] args, boolean accessible)
+ public native Object invoke(Object receiver, Object... args)
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException;
/**
@@ -398,7 +393,8 @@ public final class Method extends AbstractMethod implements GenericDeclaration,
*/
@Override
public String toString() {
- StringBuilder result = new StringBuilder(Modifier.toString(getModifiers()));
+ StringBuilder result = new StringBuilder(
+ Modifier.getDeclarationMethodModifiers(getModifiers()));
if (result.length() != 0) {
result.append(' ');
diff --git a/libart/src/main/java/java/lang/reflect/Proxy.java b/libart/src/main/java/java/lang/reflect/Proxy.java
index 31f9cd9..18ad49c 100644..100755
--- a/libart/src/main/java/java/lang/reflect/Proxy.java
+++ b/libart/src/main/java/java/lang/reflect/Proxy.java
@@ -166,11 +166,7 @@ public class Proxy implements Serializable {
Collections.sort(methods, ORDER_BY_SIGNATURE_AND_SUBTYPE);
validateReturnTypes(methods);
List<Class<?>[]> exceptions = deduplicateAndGetExceptions(methods);
-
- ArtMethod[] methodsArray = new ArtMethod[methods.size()];
- for (int i = 0; i < methodsArray.length; i++) {
- methodsArray[i] = methods.get(i).getArtMethod();
- }
+ Method[] methodsArray = methods.toArray(new Method[methods.size()]);
Class<?>[][] exceptionsArray = exceptions.toArray(new Class<?>[exceptions.size()][]);
String baseName = commonPackageName != null && !commonPackageName.isEmpty()
@@ -179,7 +175,7 @@ public class Proxy implements Serializable {
Class<?> result;
synchronized (loader.proxyCache) {
- result = loader.proxyCache.get(interfaceSet);
+ result = loader.proxyCache.get(interfaceList);
if (result == null) {
String name = baseName + nextClassNameIndex++;
result = generateProxy(name, interfaces, loader, methodsArray, exceptionsArray);
@@ -383,7 +379,7 @@ public class Proxy implements Serializable {
}
private static native Class<?> generateProxy(String name, Class<?>[] interfaces,
- ClassLoader loader, ArtMethod[] methods,
+ ClassLoader loader, Method[] methods,
Class<?>[][] exceptions);
/*
@@ -392,8 +388,8 @@ public class Proxy implements Serializable {
*/
private static native void constructorPrototype(InvocationHandler h);
- static Object invoke(Proxy proxy, ArtMethod method, Object[] args) throws Throwable {
+ private static Object invoke(Proxy proxy, Method method, Object[] args) throws Throwable {
InvocationHandler h = proxy.h;
- return h.invoke(proxy, new Method(method), args);
+ return h.invoke(proxy, method, args);
}
}
diff --git a/libart/src/main/java/sun/misc/Unsafe.java b/libart/src/main/java/sun/misc/Unsafe.java
index 6f5f5ee..1f938de 100644
--- a/libart/src/main/java/sun/misc/Unsafe.java
+++ b/libart/src/main/java/sun/misc/Unsafe.java
@@ -294,9 +294,9 @@ public final class Unsafe {
*/
public void park(boolean absolute, long time) {
if (absolute) {
- Thread.currentThread().parkUntil(time);
+ Thread.currentThread().parkUntil$(time);
} else {
- Thread.currentThread().parkFor(time);
+ Thread.currentThread().parkFor$(time);
}
}
@@ -310,7 +310,7 @@ public final class Unsafe {
*/
public void unpark(Object obj) {
if (obj instanceof Thread) {
- ((Thread) obj).unpark();
+ ((Thread) obj).unpark$();
} else {
throw new IllegalArgumentException("valid for Threads only");
}