summaryrefslogtreecommitdiffstats
path: root/libart
diff options
context:
space:
mode:
authorVladimir Marko <vmarko@google.com>2015-04-09 14:11:12 +0100
committerVladimir Marko <vmarko@google.com>2015-04-10 18:46:16 +0100
commit3f58d2cbf86775ac97bddc1a8a0a9658b498d282 (patch)
treedad85c3f4d8609ea3c2cd828536f67a2f7753c9e /libart
parent227afa2784b1a78504de22730161b65cc7093fc6 (diff)
downloadlibcore-3f58d2cbf86775ac97bddc1a8a0a9658b498d282.zip
libcore-3f58d2cbf86775ac97bddc1a8a0a9658b498d282.tar.gz
libcore-3f58d2cbf86775ac97bddc1a8a0a9658b498d282.tar.bz2
Avoid using dex cache array pointers in libart.
In preparation for making dex cache arrays native, avoid using them in Java code. This causes a performance regression for our reflection benchmarks. Class_getDeclaredMethod and Class_getMethod take an up to 30% hit, measured using the Quick compiler. We accept this hit at this stage and we will tune the performance after we're done with the larger effort. Companion art/ change: https://android-review.googlesource.com/146068 Bug: 20134538 Change-Id: Ibbef3b50043a1311cd40723ed42e1f1c609b8fc1
Diffstat (limited to 'libart')
-rw-r--r--libart/src/main/java/java/lang/Class.java27
-rw-r--r--libart/src/main/java/java/lang/DexCache.java4
-rw-r--r--libart/src/main/java/java/lang/reflect/ArtMethod.java69
-rw-r--r--libart/src/main/java/java/lang/reflect/Method.java19
4 files changed, 50 insertions, 69 deletions
diff --git a/libart/src/main/java/java/lang/Class.java b/libart/src/main/java/java/lang/Class.java
index 37b1d7d..5db7cc9 100644
--- a/libart/src/main/java/java/lang/Class.java
+++ b/libart/src/main/java/java/lang/Class.java
@@ -457,10 +457,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;
}
@@ -472,13 +472,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;
}
@@ -707,11 +706,12 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
ArtMethod artMethodResult = null;
if (virtualMethods != null) {
for (ArtMethod m : virtualMethods) {
- String methodName = ArtMethod.getMethodName(m);
+ ArtMethod nonProxyMethod = Class.findOverriddenMethodIfProxy(m);
+ String methodName = ArtMethod.getMethodName(nonProxyMethod);
if (!name.equals(methodName)) {
continue;
}
- if (!ArtMethod.equalMethodParameters(m, args)) {
+ if (!ArtMethod.equalMethodParameters(nonProxyMethod, args)) {
continue;
}
int modifiers = m.getAccessFlags();
@@ -731,11 +731,12 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
if (Modifier.isConstructor(modifiers)) {
continue;
}
- String methodName = ArtMethod.getMethodName(m);
+ ArtMethod nonProxyMethod = Class.findOverriddenMethodIfProxy(m);
+ String methodName = ArtMethod.getMethodName(nonProxyMethod);
if (!name.equals(methodName)) {
continue;
}
- if (!ArtMethod.equalMethodParameters(m, args)) {
+ if (!ArtMethod.equalMethodParameters(nonProxyMethod, args)) {
continue;
}
if ((modifiers & skipModifiers) == 0) {
@@ -754,6 +755,14 @@ public final class Class<T> implements Serializable, AnnotatedElement, GenericDe
}
/**
+ * Returns the overridden method if the {@code method} is a proxy method,
+ * otherwise returns the {@code method}.
+ *
+ * @hide
+ */
+ public static native ArtMethod findOverriddenMethodIfProxy(ArtMethod method);
+
+ /**
* Returns an array containing {@code Method} objects for all methods
* declared in the class represented by this {@code Class}. If there are no
* methods or if this {@code Class} represents an array class, a primitive
diff --git a/libart/src/main/java/java/lang/DexCache.java b/libart/src/main/java/java/lang/DexCache.java
index e4caffa..00b8af9 100644
--- a/libart/src/main/java/java/lang/DexCache.java
+++ b/libart/src/main/java/java/lang/DexCache.java
@@ -89,6 +89,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/reflect/ArtMethod.java b/libart/src/main/java/java/lang/reflect/ArtMethod.java
index 95e03c6..3abcb60 100644
--- a/libart/src/main/java/java/lang/reflect/ArtMethod.java
+++ b/libart/src/main/java/java/lang/reflect/ArtMethod.java
@@ -76,7 +76,7 @@ public final class ArtMethod {
/** Only created by ART directly. */
private ArtMethod() {}
- Class getDeclaringClass() {
+ public Class getDeclaringClass() {
return declaringClass;
}
@@ -89,11 +89,11 @@ public final class ArtMethod {
}
public static String getMethodName(ArtMethod artMethod) {
- artMethod = artMethod.findOverriddenMethodIfProxy();
- Dex dex = artMethod.getDeclaringClass().getDex();
+ Class<?> declClass = artMethod.getDeclaringClass();
+ Dex dex = declClass.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);
+ return declClass.getDexCacheString(dex, nameIndex);
}
/**
@@ -102,13 +102,14 @@ public final class ArtMethod {
* @hide
*/
public static boolean equalConstructorParameters(ArtMethod artMethod, Class<?>[] params) {
- Dex dex = artMethod.getDeclaringClass().getDex();
+ Class<?> declClass = artMethod.getDeclaringClass();
+ Dex dex = declClass.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]) {
+ if (declClass.getDexCacheType(dex, types[i]) != params[i]) {
return false;
}
}
@@ -121,11 +122,12 @@ public final class ArtMethod {
* @hide
*/
public static boolean equalMethodParameters(ArtMethod artMethod, Class<?>[] params) {
- return equalConstructorParameters(artMethod.findOverriddenMethodIfProxy(), params);
+ return equalConstructorParameters(artMethod, params);
}
Class<?>[] getParameterTypes() {
- Dex dex = getDeclaringClass().getDex();
+ Class<?> declClass = getDeclaringClass();
+ Dex dex = declClass.getDex();
short[] types = dex.parameterTypeIndicesFromMethodIndex(dexMethodIndex);
if (types.length == 0) {
return EmptyArray.CLASS;
@@ -133,16 +135,17 @@ public final class ArtMethod {
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]);
+ parametersArray[i] = declClass.getDexCacheType(dex, types[i]);
}
return parametersArray;
}
Class<?> getReturnType() {
- Dex dex = declaringClass.getDex();
+ Class<?> declClass = getDeclaringClass();
+ Dex dex = declClass.getDex();
int returnTypeIndex = dex.returnTypeIndexFromMethodIndex(dexMethodIndex);
// Note, in the case of a Proxy the dex cache types are equal.
- return getDexCacheType(dex, returnTypeIndex);
+ return declClass.getDexCacheType(dex, returnTypeIndex);
}
/**
@@ -151,11 +154,12 @@ public final class ArtMethod {
* @hide
*/
int compareParameters(Class<?>[] params) {
- Dex dex = getDeclaringClass().getDex();
+ Class<?> declClass = getDeclaringClass();
+ Dex dex = declClass.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<?> aType = declClass.getDexCacheType(dex, types[i]);
Class<?> bType = params[i];
if (aType != bType) {
int comparison = aType.getName().compareTo(bType.getName());
@@ -170,43 +174,4 @@ public final class ArtMethod {
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/Method.java b/libart/src/main/java/java/lang/reflect/Method.java
index f0e4f5c..c70e34e 100644
--- a/libart/src/main/java/java/lang/reflect/Method.java
+++ b/libart/src/main/java/java/lang/reflect/Method.java
@@ -57,8 +57,8 @@ 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 = Class.findOverriddenMethodIfProxy(a.artMethod).compareParameters(
+ Class.findOverriddenMethodIfProxy(b.artMethod).getParameterTypes());
if (comparison == 0) {
// This is necessary for methods that have covariant return types.
Class<?> aReturnType = a.getReturnType();
@@ -136,7 +136,8 @@ public final class Method extends AbstractMethod implements GenericDeclaration,
* @return the name of this method
*/
@Override public String getName() {
- return ArtMethod.getMethodName(artMethod);
+ ArtMethod nonProxyMethod = Class.findOverriddenMethodIfProxy(artMethod);
+ return ArtMethod.getMethodName(nonProxyMethod);
}
/**
@@ -171,7 +172,7 @@ public final class Method extends AbstractMethod implements GenericDeclaration,
* @return the parameter types
*/
@Override public Class<?>[] getParameterTypes() {
- return artMethod.findOverriddenMethodIfProxy().getParameterTypes();
+ return Class.findOverriddenMethodIfProxy(artMethod).getParameterTypes();
}
/**
@@ -181,7 +182,7 @@ public final class Method extends AbstractMethod implements GenericDeclaration,
* @return the return type
*/
public Class<?> getReturnType() {
- return artMethod.findOverriddenMethodIfProxy().getReturnType();
+ return Class.findOverriddenMethodIfProxy(artMethod).getReturnType();
}
/**
@@ -209,8 +210,10 @@ 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());
+ ArtMethod nonProxyThis = Class.findOverriddenMethodIfProxy(this.artMethod);
+ ArtMethod nonProxyM = Class.findOverriddenMethodIfProxy(m.artMethod);
+ return ArtMethod.getMethodName(nonProxyThis).equals(ArtMethod.getMethodName(nonProxyM)) &&
+ ArtMethod.equalMethodParameters(nonProxyThis, nonProxyM.getParameterTypes());
}
/**
@@ -310,7 +313,7 @@ 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 Class.findOverriddenMethodIfProxy(artMethod).getParameterAnnotations();
}
/**