diff options
| author | Jesse Wilson <jessewilson@google.com> | 2011-02-22 20:20:36 -0800 |
|---|---|---|
| committer | Jesse Wilson <jessewilson@google.com> | 2011-02-23 13:30:36 -0800 |
| commit | 3c6f4c012e0a314dc9f9f540b9374dbf530d03b0 (patch) | |
| tree | a8b909adb787ca7847a1d181a9996a0bbf00c868 /vm/reflect | |
| parent | 6c360b86f5774376140636ff60ad4af3814fef21 (diff) | |
| download | android_dalvik-3c6f4c012e0a314dc9f9f540b9374dbf530d03b0.tar.gz android_dalvik-3c6f4c012e0a314dc9f9f540b9374dbf530d03b0.tar.bz2 android_dalvik-3c6f4c012e0a314dc9f9f540b9374dbf530d03b0.zip | |
Optimize Class.getMethod() by loading only one method.
Change-Id: Ia2cd776c0a14914264e8d94e978d55854ed75623
http://b/3431686
Diffstat (limited to 'vm/reflect')
| -rw-r--r-- | vm/reflect/Reflect.c | 100 | ||||
| -rw-r--r-- | vm/reflect/Reflect.h | 6 |
2 files changed, 106 insertions, 0 deletions
diff --git a/vm/reflect/Reflect.c b/vm/reflect/Reflect.c index 2a7c74061..a881a92b3 100644 --- a/vm/reflect/Reflect.c +++ b/vm/reflect/Reflect.c @@ -817,6 +817,106 @@ fail: } /* + * Fills targetDescriptorCache with the descriptors of the classes in args. + * This is the concatenation of the descriptors with no other adornment, + * consistent with dexProtoGetParameterDescriptors. + */ +static void createTargetDescriptor(ArrayObject* args, + DexStringCache* targetDescriptorCache) +{ + size_t i; + ClassObject** argsArray = NULL; + size_t length; + char* at; + const char* descriptor; + + argsArray = (ClassObject**) args->contents; + + length = 1; /* +1 for the terminating '\0' */ + for (i = 0; i < args->length; ++i) { + length += strlen(argsArray[i]->descriptor); + } + + dexStringCacheAlloc(targetDescriptorCache, length); + + at = (char*) targetDescriptorCache->value; + for (i = 0; i < args->length; ++i) { + descriptor = argsArray[i]->descriptor; + strcpy(at, descriptor); + at += strlen(descriptor); + } +} + +static Object* findConstructorOrMethodInArray(int methodsCount, Method* methods, + const char* name, const char* parameterDescriptors, + DexStringCache* stringCache) +{ + Method* method = NULL; + Method* result = NULL; + int i; + + for (i = 0; i < methodsCount; ++i) { + method = &methods[i]; + if (strcmp(name, method->name) != 0 + || dvmIsMirandaMethod(method) + || strcmp(parameterDescriptors, dexProtoGetParameterDescriptors( + &method->prototype, stringCache)) != 0) { + continue; + } + + result = method; + + /* + * 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. + */ + if (!dvmIsSyntheticMethod(method)) { + break; + } + } + + if (result != NULL) { + return dvmCreateReflectObjForMethod(result->clazz, result); + } + + return NULL; +} + +/* + * Get the named method. + */ +Object* dvmGetDeclaredConstructorOrMethod(ClassObject* clazz, + StringObject* nameObj, ArrayObject* args) +{ + Object* result = NULL; + DexStringCache stringCache; + DexStringCache targetDescriptorCache; + char* name; + const char* targetDescriptor; + + dexStringCacheInit(&stringCache); + dexStringCacheInit(&targetDescriptorCache); + + name = dvmCreateCstrFromString(nameObj); + createTargetDescriptor(args, &targetDescriptorCache); + targetDescriptor = targetDescriptorCache.value; + + result = findConstructorOrMethodInArray(clazz->directMethodCount, + clazz->directMethods, name, targetDescriptor, &stringCache); + if (result == NULL) { + result = findConstructorOrMethodInArray(clazz->virtualMethodCount, + clazz->virtualMethods, name, targetDescriptor, &stringCache); + } + + free(name); + dexStringCacheRelease(&stringCache); + dexStringCacheRelease(&targetDescriptorCache); + return result; +} + +/* * Get all interfaces a class implements. If this is unable to allocate * the result array, this raises an OutOfMemoryError and returns NULL. */ diff --git a/vm/reflect/Reflect.h b/vm/reflect/Reflect.h index c9a9a22ca..42b18c01b 100644 --- a/vm/reflect/Reflect.h +++ b/vm/reflect/Reflect.h @@ -51,6 +51,12 @@ ArrayObject* dvmGetDeclaredConstructors(ClassObject* clazz, bool publicOnly); ArrayObject* dvmGetDeclaredMethods(ClassObject* clazz, bool publicOnly); /* + * Get the named method. + */ +Object* dvmGetDeclaredConstructorOrMethod(ClassObject* clazz, + StringObject* nameObj, ArrayObject* args); + +/* * Get all interfaces a class implements. If this is unable to allocate * the result array, this raises an OutOfMemoryError and returns NULL. */ |
