Пример #1
0
/*
 * Perform Proxy setup.
 */
bool dvmReflectProxyStartup()
{
    /*
     * Standard methods we must provide in our proxy.
     */
    Method* methE;
    Method* methH;
    Method* methT;
    Method* methF;
    methE = dvmFindVirtualMethodByDescriptor(gDvm.classJavaLangObject, "equals",
            "(Ljava/lang/Object;)Z");
    methH = dvmFindVirtualMethodByDescriptor(gDvm.classJavaLangObject, "hashCode",
            "()I");
    methT = dvmFindVirtualMethodByDescriptor(gDvm.classJavaLangObject, "toString",
            "()Ljava/lang/String;");
    methF = dvmFindVirtualMethodByDescriptor(gDvm.classJavaLangObject, "finalize",
            "()V");
    if (methE == NULL || methH == NULL || methT == NULL || methF == NULL) {
        LOGE("Could not find equals/hashCode/toString/finalize in Object\n");
        return false;
    }
    gDvm.voffJavaLangObject_equals = methE->methodIndex;
    gDvm.voffJavaLangObject_hashCode = methH->methodIndex;
    gDvm.voffJavaLangObject_toString = methT->methodIndex;
    gDvm.voffJavaLangObject_finalize = methF->methodIndex;

    /*
     * The prototype signature needs to be cloned from a method in a
     * "real" DEX file.  We declared this otherwise unused method just
     * for this purpose.
     */
    ClassObject* proxyClass;
    Method* meth;
    proxyClass = dvmFindSystemClassNoInit("Ljava/lang/reflect/Proxy;");
    if (proxyClass == NULL) {
        LOGE("No java.lang.reflect.Proxy\n");
        return false;
    }
    meth = dvmFindDirectMethodByDescriptor(proxyClass, "constructorPrototype",
                "(Ljava/lang/reflect/InvocationHandler;)V");
    if (meth == NULL) {
        LOGE("Could not find java.lang.Proxy.constructorPrototype()\n");
        return false;
    }
    gDvm.methJavaLangReflectProxy_constructorPrototype = meth;

    return true;
}
Пример #2
0
/*
 * 在指定的接口中,根据'descriptor'查找匹配的方法,找不到则在它的父接口中继续查找
 *
 * 如果方法没有被找到则返回NULL (方法没有被查找到,也不会抛出异常信息)
 *
 */
Method* dvmFindInterfaceMethodHierByDescriptor(const ClassObject* iface,
    const char* methodName, const char* descriptor)
{
    Method* resMethod = dvmFindVirtualMethodByDescriptor(iface,
        methodName, descriptor);
    if (resMethod == NULL) {
        /* scan superinterfaces and superclass interfaces */
        int i;
        for (i = 0; i < iface->iftableCount; i++) {
            resMethod = dvmFindVirtualMethodByDescriptor(iface->iftable[i].clazz,
                methodName, descriptor);
            if (resMethod != NULL)
                break;
        }
    }
    return resMethod;
}
Пример #3
0
/*
 * Make an inline call for the "debug" interpreter, used when the debugger
 * or profiler is active.
 */
bool dvmPerformInlineOp4Dbg(u4 arg0, u4 arg1, u4 arg2, u4 arg3,
    JValue* pResult, int opIndex)
{
    Thread* self = dvmThreadSelf();
    bool result;

    assert(opIndex >= 0 && opIndex < NELEM(gDvmInlineOpsTable));

#ifdef WITH_PROFILER
    /*
     * Populate the methods table on first use.  It's possible the class
     * hasn't been resolved yet, so we need to do the full "calling the
     * method for the first time" routine.  (It's probably okay to skip
     * the access checks.)
     *
     * Currently assuming that we're only inlining stuff loaded by the
     * bootstrap class loader.  This is a safe assumption for many reasons.
     */
    Method* method = gDvm.inlinedMethods[opIndex];
    if (method == NULL) {
        ClassObject* clazz;
        
        clazz = dvmFindClassNoInit(
                gDvmInlineOpsTable[opIndex].classDescriptor, NULL);
        if (clazz == NULL) {
            LOGW("Warning: can't find class '%s'\n", clazz->descriptor);
            goto skip_prof;
        }
        method = dvmFindDirectMethodByDescriptor(clazz,
                    gDvmInlineOpsTable[opIndex].methodName,
                    gDvmInlineOpsTable[opIndex].methodSignature);
        if (method == NULL)
            method = dvmFindVirtualMethodByDescriptor(clazz,
                        gDvmInlineOpsTable[opIndex].methodName,
                        gDvmInlineOpsTable[opIndex].methodSignature);
        if (method == NULL) {
            LOGW("Warning: can't find method %s.%s %s\n",
                clazz->descriptor,
                gDvmInlineOpsTable[opIndex].methodName,
                gDvmInlineOpsTable[opIndex].methodSignature);
            goto skip_prof;
        }

        gDvm.inlinedMethods[opIndex] = method;
        IF_LOGV() {
            char* desc = dexProtoCopyMethodDescriptor(&method->prototype);
            LOGV("Registered for profile: %s.%s %s\n",
                method->clazz->descriptor, method->name, desc);
            free(desc);
        }
    }
Пример #4
0
Method* dvmFindInlinableMethod(const char* classDescriptor,
    const char* methodName, const char* methodSignature)
{
    /*
     * Find the class.
     */
    ClassObject* clazz = dvmFindClassNoInit(classDescriptor, NULL);
    if (clazz == NULL) {
        ALOGE("dvmFindInlinableMethod: can't find class '%s'",
            classDescriptor);
        dvmClearException(dvmThreadSelf());
        return NULL;
    }

    /*
     * Method could be virtual or direct.  Try both.  Don't use
     * the "hier" versions.
     */
    Method* method = dvmFindDirectMethodByDescriptor(clazz, methodName,
        methodSignature);
    if (method == NULL) {
        method = dvmFindVirtualMethodByDescriptor(clazz, methodName,
            methodSignature);
    }
    if (method == NULL) {
        ALOGE("dvmFindInlinableMethod: can't find method %s.%s %s",
            clazz->descriptor, methodName, methodSignature);
        return NULL;
    }

    /*
     * Check that the method is appropriate for inlining.
     */
    if (!dvmIsFinalClass(clazz) && !dvmIsFinalMethod(method)) {
        ALOGE("dvmFindInlinableMethod: can't inline non-final method %s.%s",
            clazz->descriptor, method->name);
        return NULL;
    }
    if (dvmIsSynchronizedMethod(method) ||
            dvmIsDeclaredSynchronizedMethod(method)) {
        ALOGE("dvmFindInlinableMethod: can't inline synchronized method %s.%s",
            clazz->descriptor, method->name);
        return NULL;
    }

    return method;
}
Пример #5
0
static bool initVirtualMethodOffset(int* pOffset, const char* className,
        const char* name, const char* descriptor) {
    ClassObject* clazz = dvmFindSystemClassNoInit(className);

    if (clazz == NULL) {
        ALOGE("Could not find essential class %s for virtual method lookup", className);
        return false;
    }

    Method* method = dvmFindVirtualMethodByDescriptor(clazz, name, descriptor);

    if (method == NULL) {
        ALOGE("Could not find essential virtual method %s.%s with descriptor %s",
                clazz->descriptor, name, descriptor);
        return false;
    }

    *pOffset = method->methodIndex;
    return true;
}