Пример #1
0
/*
 * Create an instance of the specified class.
 *
 * Returns NULL and throws an exception on failure.
 */
Object* dvmAllocObject(ClassObject* clazz, int flags)
{
    Object* newObj;

    assert(clazz != NULL);
    assert(dvmIsClassInitialized(clazz) || dvmIsClassInitializing(clazz));

    /* allocate on GC heap; memory is zeroed out */
    newObj = (Object*)dvmMalloc(clazz->objectSize, flags);
    if (newObj != NULL) {
        DVM_OBJECT_INIT(newObj, clazz);
        dvmTrackAllocation(clazz, clazz->objectSize);   /* notify DDMS */
    }

    //SVM CODE SUPPORT
    //init the tag of an object to 0
    newObj->tag = 0;
    pthread_mutex_lock(&gDvm.s_mtx);
    if(gDvm.newObjHook){
        gDvm.newObjHook(newObj);
    }
    pthread_mutex_unlock(&gDvm.s_mtx);
    //SVM CODE SUPPORT END

    return newObj;
}
/*
 * Resolve a native method and invoke it.
 *
 * This is executed as if it were a native bridge or function.  If the
 * resolution succeeds, method->insns is replaced, and we don't go through
 * here again.
 *
 * Initializes method's class if necessary.
 *
 * An exception is thrown on resolution failure.
 */
void dvmResolveNativeMethod(const u4* args, JValue* pResult,
    const Method* method, Thread* self)
{
    ClassObject* clazz = method->clazz;
    void* func;

    /*
     * If this is a static method, it could be called before the class
     * has been initialized.
     */
    if (dvmIsStaticMethod(method)) {
        if (!dvmIsClassInitialized(clazz) && !dvmInitClass(clazz)) {
            assert(dvmCheckException(dvmThreadSelf()));
            return;
        }
    } else {
        assert(dvmIsClassInitialized(clazz) ||
               dvmIsClassInitializing(clazz));
    }

    /* start with our internal-native methods */
    func = dvmLookupInternalNativeMethod(method);
    if (func != NULL) {
        /* resolution always gets the same answer, so no race here */
        IF_LOGVV() {
            char* desc = dexProtoCopyMethodDescriptor(&method->prototype);
            LOGVV("+++ resolved native %s.%s %s, invoking\n",
                clazz->descriptor, method->name, desc);
            free(desc);
        }
Пример #3
0
/*
 * Create an instance of the specified class.
 *
 * Returns NULL and throws an exception on failure.
 */
Object* dvmAllocObject(ClassObject* clazz, int flags)
{
    Object* newObj;

    assert(dvmIsClassInitialized(clazz) || dvmIsClassInitializing(clazz));

    if (IS_CLASS_FLAG_SET(clazz, CLASS_ISFINALIZABLE)) {
        flags |= ALLOC_FINALIZABLE;
    }

    /* allocate on GC heap; memory is zeroed out */
    newObj = dvmMalloc(clazz->objectSize, flags);
    if (newObj != NULL) {
        DVM_OBJECT_INIT(newObj, clazz);

		Monitor* mon = NULL;//dvmCreateMonitor(newObj);
		newObj->lock = (u4)mon | LW_SHAPE_FAT;

        LOGVV("AllocObject: %s (%d)\n", clazz->descriptor,
            (int) clazz->objectSize);
#if WITH_HPROF && WITH_HPROF_STACK
        hprofFillInStackTrace(newObj);
#endif
        dvmTrackAllocation(clazz, clazz->objectSize);
    }

    return newObj;
}
Пример #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) {
        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;
}
Пример #5
0
/*
 * Resolve an instance field reference.
 *
 * Returns NULL and throws an exception on error (no such field, illegal
 * access).
 */
InstField* dvmResolveInstField(const ClassObject* referrer, u4 ifieldIdx)
{
    DvmDex* pDvmDex = referrer->pDvmDex;
    ClassObject* resClass;
    const DexFieldId* pFieldId;
    InstField* resField;

    LOGVV("--- resolving field %u (referrer=%s cl=%p)",
        ifieldIdx, referrer->descriptor, referrer->classLoader);

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

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

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

    /*
     * Class must be initialized by now (unless verifier is buggy).  We
     * could still be in the process of initializing it if the field
     * access is from a static initializer.
     */
    assert(dvmIsClassInitialized(resField->clazz) ||
           dvmIsClassInitializing(resField->clazz));

    /*
     * The class is initialized (or initializing), the field has been
     * found.  Add a pointer to our data structure so we don't have to
     * jump through the hoops again.
     *
     * Anything that uses the resolved table entry must have an instance
     * of the class, so any class init activity has already happened (or
     * been deliberately bypassed when <clinit> created an instance).
     * So it's always okay to update the table.
     */
    dvmDexSetResolvedField(pDvmDex, ifieldIdx, (Field*)resField);
    LOGVV("    field %u is %s.%s",
        ifieldIdx, resField->clazz->descriptor, resField->name);

    return resField;
}
Пример #6
0
/*
 * Resolve an instance field reference.
 *
 * Returns NULL and throws an exception on error (no such field, illegal
 * access).
 */
InstField* dvmResolveInstField(const ClassObject* referrer, u4 ifieldIdx)
{
    DvmDex* pDvmDex = referrer->pDvmDex;
    ClassObject* resClass;
    const DexFieldId* pFieldId;
    InstField* resField;

    LOGVV("--- resolving field %u (referrer=%s cl=%p)\n",
          ifieldIdx, referrer->descriptor, referrer->classLoader);

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

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

    resField = dvmFindInstanceFieldHier(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;
    }

    /*
     * Class must be initialized by now (unless verifier is buggy).  We
     * could still be in the process of initializing it if the field
     * access is from a static initializer.
     */
    assert(dvmIsClassInitialized(resField->field.clazz) ||
           dvmIsClassInitializing(resField->field.clazz));

    /*
     * 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, ifieldIdx, (Field*)resField);
    LOGVV("    field %u is %s.%s\n",
          ifieldIdx, resField->field.clazz->descriptor, resField->field.name);

    return resField;
}
Пример #7
0
/*
 * Create an instance of the specified class.
 *
 * Returns NULL and throws an exception on failure.
 */
Object* dvmAllocObject(ClassObject* clazz, int flags)
{
    Object* newObj;

    assert(clazz != NULL);
    assert(dvmIsClassInitialized(clazz) || dvmIsClassInitializing(clazz));

    /* allocate on GC heap; memory is zeroed out */
    newObj = (Object*)dvmMalloc(clazz->objectSize, flags);
    if (newObj != NULL) {
        DVM_OBJECT_INIT(newObj, clazz);
        dvmTrackAllocation(clazz, clazz->objectSize);   /* notify DDMS */
    }

    return newObj;
}
Пример #8
0
/*
 * Create an instance of the specified class.
 *
 * Returns NULL and throws an exception on failure.
 */
Object* dvmAllocObject(ClassObject* clazz, int flags)
{
    Object* newObj;

    assert(dvmIsClassInitialized(clazz) || dvmIsClassInitializing(clazz));

    if (IS_CLASS_FLAG_SET(clazz, CLASS_ISFINALIZABLE)) {
        flags |= ALLOC_FINALIZABLE;
    }

    /* allocate on GC heap; memory is zeroed out */
    newObj = dvmMalloc(clazz->objectSize, flags);
    if (newObj != NULL) {
        DVM_OBJECT_INIT(newObj, clazz);
#if WITH_HPROF && WITH_HPROF_STACK
        hprofFillInStackTrace(newObj);
#endif
        dvmTrackAllocation(clazz, clazz->objectSize);
    }

    return newObj;
}
Пример #9
0
/*
 * Find the method corresponding to "methodRef".
 *
 * We use "referrer" to find the DexFile with the constant pool that
 * "methodRef" is an index into.  We also use its class loader.  The method
 * being resolved may very well be in a different DEX file.
 *
 * If this is a static method, we ensure that the method's class is
 * initialized.
 */
Method* dvmResolveMethod(const ClassObject* referrer, u4 methodIdx,
                         MethodType methodType)
{
    DvmDex* pDvmDex = referrer->pDvmDex;
    ClassObject* resClass;
    const DexMethodId* pMethodId;
    Method* resMethod;

    assert(methodType != METHOD_INTERFACE);

    LOGVV("--- resolving method %u (referrer=%s)\n", methodIdx,
          referrer->descriptor);
    pMethodId = dexGetMethodId(pDvmDex->pDexFile, methodIdx);

    resClass = dvmResolveClass(referrer, pMethodId->classIdx, false);
    if (resClass == NULL) {
        /* can't find the class that the method is a part of */
        assert(dvmCheckException(dvmThreadSelf()));
        return NULL;
    }
    if (dvmIsInterfaceClass(resClass)) {
        /* method is part of an interface */
        dvmThrowExceptionWithClassMessage(
            "Ljava/lang/IncompatibleClassChangeError;",
            resClass->descriptor);
        return NULL;
    }

    const char* name = dexStringById(pDvmDex->pDexFile, pMethodId->nameIdx);
    DexProto proto;
    dexProtoSetFromMethodId(&proto, pDvmDex->pDexFile, pMethodId);

    /*
     * We need to chase up the class hierarchy to find methods defined
     * in super-classes.  (We only want to check the current class
     * if we're looking for a constructor; since DIRECT calls are only
     * for constructors and private methods, we don't want to walk up.)
     */
    if (methodType == METHOD_DIRECT) {
        resMethod = dvmFindDirectMethod(resClass, name, &proto);
    } else if (methodType == METHOD_STATIC) {
        resMethod = dvmFindDirectMethodHier(resClass, name, &proto);
    } else {
        resMethod = dvmFindVirtualMethodHier(resClass, name, &proto);
    }

    if (resMethod == NULL) {
        dvmThrowException("Ljava/lang/NoSuchMethodError;", name);
        return NULL;
    }

    LOGVV("--- found method %d (%s.%s)\n",
          methodIdx, resClass->descriptor, resMethod->name);

    /* see if this is a pure-abstract method */
    if (dvmIsAbstractMethod(resMethod) && !dvmIsAbstractClass(resClass)) {
        dvmThrowException("Ljava/lang/AbstractMethodError;", name);
        return NULL;
    }

    /*
     * If we're the first to resolve this class, we need to initialize
     * it now.  Only necessary for METHOD_STATIC.
     */
    if (methodType == METHOD_STATIC) {
        if (!dvmIsClassInitialized(resMethod->clazz) &&
                !dvmInitClass(resMethod->clazz))
        {
            assert(dvmCheckException(dvmThreadSelf()));
            return NULL;
        } else {
            assert(!dvmCheckException(dvmThreadSelf()));
        }
    } else {
        /*
         * Edge case: if the <clinit> for a class creates an instance
         * of itself, we will call <init> on a class that is still being
         * initialized by us.
         */
        assert(dvmIsClassInitialized(resMethod->clazz) ||
               dvmIsClassInitializing(resMethod->clazz));
    }

    /*
     * 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.
     */
    dvmDexSetResolvedMethod(pDvmDex, methodIdx, resMethod);

    return resMethod;
}