Esempio n. 1
0
/* returns the field structure corresponding to the profile entry
 * variable in the form: <signature> % <name>
 */
Field* getFieldFromProfileVar(const char* var, const ClassObject* clazz)
{
    char* pos;
    char* sig;
    char* name;
    InstField* ifield;
    StaticField* sfield;
    Field* field = NULL;

    // TODO: Can we avoid the allocation if we replace the '%'?
    // Need to make sure there isn't a locking problem if that route
    // is taken.
    pos = index(var, '%');
    sig = strndup(var, pos-var);
    name = strdup(pos+1);

    /* Try both static and instance fields */
    ifield = dvmFindInstanceFieldHier(clazz, name, sig);
    if (ifield != NULL) {
	field = (Field*) ifield;
    } else {
	sfield = dvmFindStaticFieldHier(clazz, name, sig);
	if (sfield != NULL) {
	    field = (Field*) sfield;
	}
    }

    free(sig);
    free(name);

    return field;
}
// Based on dvmResolveInstField/dvmResolveStaticField.
static void preloadDexCachesResolveField(DvmDex* pDvmDex, uint32_t fieldIdx, bool instance) {
    Field* field = dvmDexGetResolvedField(pDvmDex, fieldIdx);
    if (field != NULL) {
        return;
    }
    const DexFile* pDexFile = pDvmDex->pDexFile;
    const DexFieldId* pFieldId = dexGetFieldId(pDexFile, fieldIdx);
    ClassObject* clazz = dvmDexGetResolvedClass(pDvmDex, pFieldId->classIdx);
    if (clazz == NULL) {
        return;
    }
    // Skip static fields for uninitialized classes because a filled
    // cache entry implies the class is initialized.
    if (!instance && !dvmIsClassInitialized(clazz)) {
        return;
    }
    const char* fieldName = dexStringById(pDexFile, pFieldId->nameIdx);
    const char* signature = dexStringByTypeIdx(pDexFile, pFieldId->typeIdx);
    if (instance) {
        field = dvmFindInstanceFieldHier(clazz, fieldName, signature);
    } else {
        field = dvmFindStaticFieldHier(clazz, fieldName, signature);
    }
    if (field == NULL) {
        return;
    }
    // ALOGI("VMRuntime.preloadDexCaches found field %s %s.%s",
    //       signature, clazz->descriptor, fieldName);
    dvmDexSetResolvedField(pDvmDex, fieldIdx, field);
}
Esempio n. 3
0
/*
 * Resolve a static field reference.  The DexFile format doesn't distinguish
 * between static and instance field references, so the "resolved" pointer
 * in the Dex struct will have the wrong type.  We trivially cast it here.
 *
 * Causes the field's class to be initialized.
 */
StaticField* dvmResolveStaticField(const ClassObject* referrer, u4 sfieldIdx)
{
    DvmDex* pDvmDex = referrer->pDvmDex;
    ClassObject* resClass;
    const DexFieldId* pFieldId;
    StaticField* resField;

    pFieldId = dexGetFieldId(pDvmDex->pDexFile, sfieldIdx);

    /*
     * Find the field's class.
     */
    resClass = dvmResolveClass(referrer, pFieldId->classIdx, false);
    if (resClass == NULL) {
        assert(dvmCheckException(dvmThreadSelf()));
        return NULL;
    }

    resField = dvmFindStaticFieldHier(resClass,
                dexStringById(pDvmDex->pDexFile, pFieldId->nameIdx),
                dexStringByTypeIdx(pDvmDex->pDexFile, pFieldId->typeIdx));
    if (resField == NULL) {
        dvmThrowNoSuchFieldError(
            dexStringById(pDvmDex->pDexFile, pFieldId->nameIdx));
        return NULL;
    }

    /*
     * If we're the first to resolve the field in which this class resides,
     * we need to do it now.  Note that, if the field was inherited from
     * a superclass, it is not necessarily the same as "resClass".
     */
    if (!dvmIsClassInitialized(resField->clazz) &&
        !dvmInitClass(resField->clazz))
    {
        assert(dvmCheckException(dvmThreadSelf()));
        return NULL;
    }

    /*
     * If the class has been initialized, add a pointer to our data structure
     * so we don't have to jump through the hoops again.  If it's still
     * initializing (i.e. this thread is executing <clinit>), don't do
     * the store, otherwise other threads could use the field without waiting
     * for class init to finish.
     */
    if (dvmIsClassInitialized(resField->clazz)) {
        dvmDexSetResolvedField(pDvmDex, sfieldIdx, (Field*) resField);
    } else {
        LOGVV("--- not caching resolved field %s.%s (class init=%d/%d)",
            resField->clazz->descriptor, resField->name,
            dvmIsClassInitializing(resField->clazz),
            dvmIsClassInitialized(resField->clazz));
    }

    return resField;
}
Esempio n. 4
0
/*
 * Resolve a static field reference.  The DexFile format doesn't distinguish
 * between static and instance field references, so the "resolved" pointer
 * in the Dex struct will have the wrong type.  We trivially cast it here.
 *
 * Causes the field's class to be initialized.
 */
StaticField* dvmResolveStaticField(const ClassObject* referrer, u4 sfieldIdx)
{
    DvmDex* pDvmDex = referrer->pDvmDex;
    ClassObject* resClass;
    const DexFieldId* pFieldId;
    StaticField* resField;

    pFieldId = dexGetFieldId(pDvmDex->pDexFile, sfieldIdx);

    /*
     * Find the field's class.
     */
    resClass = dvmResolveClass(referrer, pFieldId->classIdx, false);
    if (resClass == NULL) {
        assert(dvmCheckException(dvmThreadSelf()));
        return NULL;
    }

    resField = dvmFindStaticFieldHier(resClass,
                                      dexStringById(pDvmDex->pDexFile, pFieldId->nameIdx),
                                      dexStringByTypeIdx(pDvmDex->pDexFile, pFieldId->typeIdx));
    if (resField == NULL) {
        dvmThrowException("Ljava/lang/NoSuchFieldError;",
                          dexStringById(pDvmDex->pDexFile, pFieldId->nameIdx));
        return NULL;
    }

    /*
     * If we're the first to resolve the field in which this class resides,
     * we need to do it now.  Note that, if the field was inherited from
     * a superclass, it is not necessarily the same as "resClass".
     */
    if (!dvmIsClassInitialized(resField->field.clazz) &&
            !dvmInitClass(resField->field.clazz))
    {
        assert(dvmCheckException(dvmThreadSelf()));
        return NULL;
    }

    /*
     * The class is initialized, the method has been found.  Add a pointer
     * to our data structure so we don't have to jump through the hoops again.
     */
    dvmDexSetResolvedField(pDvmDex, sfieldIdx, (Field*) resField);

    return resField;
}
Esempio n. 5
0
/*
 * 在当前的类或者父类中查找相匹配的静态字段,如果没有找到才返回值为NULL
 *
 */
StaticField* dvmFindStaticFieldHier(const ClassObject* clazz,
    const char* fieldName, const char* signature)
{
    StaticField* pField;

    /*
     * Search for a match in the current class.
     */
    pField = dvmFindStaticField(clazz, fieldName, signature);
    if (pField != NULL)
        return pField;

    /*
     * See if it's in any of our interfaces.  We don't check interfaces
     * inherited from the superclass yet.
     *
     * (Note the set may have been stripped down because of redundancy with
     * the superclass; see notes in createIftable.)
     */
    int i = 0;
    if (clazz->super != NULL) {
        assert(clazz->iftableCount >= clazz->super->iftableCount);
        i = clazz->super->iftableCount;
    }
    for ( ; i < clazz->iftableCount; i++) {
        ClassObject* iface = clazz->iftable[i].clazz;
        pField = dvmFindStaticField(iface, fieldName, signature);
        if (pField != NULL)
            return pField;
    }

    if (clazz->super != NULL)
        return dvmFindStaticFieldHier(clazz->super, fieldName, signature);
    else
        return NULL;
}