Esempio n. 1
0
/*
 * Get the named method.
 */
Object* dvmGetDeclaredConstructorOrMethod(ClassObject* clazz,
    StringObject* nameObj, ArrayObject* args)
{
    Object* result = NULL;
    DexStringCache targetDescriptorCache;
    char* name;
    const char* targetDescriptor;

    dexStringCacheInit(&targetDescriptorCache);

    name = dvmCreateCstrFromString(nameObj);
    createTargetDescriptor(args, &targetDescriptorCache);
    targetDescriptor = targetDescriptorCache.value;

    result = findConstructorOrMethodInArray(clazz->directMethodCount,
        clazz->directMethods, name, targetDescriptor);
    if (result == NULL) {
        result = findConstructorOrMethodInArray(clazz->virtualMethodCount,
            clazz->virtualMethods, name, targetDescriptor);
    }

    free(name);
    dexStringCacheRelease(&targetDescriptorCache);
    return result;
}
int
hprofStartup_StackFrame()
{
    HashIter iter;

    /* Cache the string "<unknown>" for use when the source file is
     * unknown.
     */
    hprofLookupStringId("<unknown>");

    /* This will be called when a GC begins. */
    for (dvmHashIterBegin(gStackFrameHashTable, &iter);
         !dvmHashIterDone(&iter);
         dvmHashIterNext(&iter)) {
        StackFrameEntry *stackFrameEntry;
        const Method *method;

        /* Clear the 'live' bit at the start of the GC pass. */
        stackFrameEntry = (StackFrameEntry *) dvmHashIterData(&iter);
        stackFrameEntry->live = 0;

        method = stackFrameEntry->frame.method;
        if (method == NULL) {
            continue;
        }

        /* Make sure the method name, descriptor, and source file are in
         * the string table, and that the method class is in the class
         * table. This is needed because strings and classes will be dumped
         * before stack frames.
         */

        if (method->name) {
            hprofLookupStringId(method->name);
        }

        DexStringCache cache;
        const char* descriptor;

        dexStringCacheInit(&cache);
        descriptor = dexProtoGetMethodDescriptor(&method->prototype, &cache);
        hprofLookupStringId(descriptor);
        dexStringCacheRelease(&cache);
        
        const char* sourceFile = dvmGetMethodSourceFile(method);
        if (sourceFile) {
            hprofLookupStringId(sourceFile);
        }

        if (method->clazz) {
            hprofLookupClassId(method->clazz);
        }
    }
    
    return 0;
}
Esempio n. 3
0
/*
 * Create a new java/lang/reflect/Method object, using the contents of
 * "meth" to construct it.
 *
 * The spec doesn't specify the constructor.  We're going to use the
 * one from our existing class libs:
 *
 *  private Method(Class declaring, Class[] paramTypes, Class[] exceptTypes,
 *      Class returnType, String name, int slot)
 *
 * The caller must call dvmReleaseTrackedAlloc() on the result.
 */
Object* dvmCreateReflectMethodObject(const Method* meth)
{
    Object* result = NULL;
    ArrayObject* params = NULL;
    ArrayObject* exceptions = NULL;
    StringObject* nameObj = NULL;
    Object* methObj;
    ClassObject* returnType;
    DexStringCache mangle;
    char* cp;
    int slot, method_idx;

    if (dvmCheckException(dvmThreadSelf())) {
        ALOGW("WARNING: dvmCreateReflectMethodObject called with "
             "exception pending");
        return NULL;
    }

    dexStringCacheInit(&mangle);

    /* parent should guarantee init so we don't have to check on every call */
    assert(dvmIsClassInitialized(gDvm.classJavaLangReflectMethod));

    methObj = dvmAllocObject(gDvm.classJavaLangReflectMethod, ALLOC_DEFAULT);
    if (methObj == NULL)
        goto bail;

    /*
     * Convert the signature string into an array of classes representing
     * the arguments, and a class for the return type.
     */
    cp = dvmCopyDescriptorStringFromMethod(meth, &mangle);
    params = convertSignatureToClassArray(&cp, meth->clazz);
    if (params == NULL)
        goto bail;
    assert(*cp == ')');
    cp++;
    returnType = convertSignaturePartToClass(&cp, meth->clazz);
    if (returnType == NULL)
        goto bail;

    /*
     * Create an array with one entry for every exception that the class
     * is declared to throw.
     */
    exceptions = dvmGetMethodThrows(meth);
    if (dvmCheckException(dvmThreadSelf()))
        goto bail;

    /* method name */
    nameObj = dvmCreateStringFromCstr(meth->name);
    if (nameObj == NULL)
        goto bail;

    slot = methodToSlot(meth);
    method_idx = dvmGetMethodIdx(meth);

    JValue unused;
    dvmCallMethod(dvmThreadSelf(), gDvm.methJavaLangReflectMethod_init,
        methObj, &unused, meth->clazz, params, exceptions, returnType,
        nameObj, slot, method_idx);
    if (dvmCheckException(dvmThreadSelf())) {
        ALOGD("Method class init threw exception");
        goto bail;
    }

    result = methObj;

bail:
    dexStringCacheRelease(&mangle);
    if (result == NULL) {
        assert(dvmCheckException(dvmThreadSelf()));
    }
    dvmReleaseTrackedAlloc((Object*) nameObj, NULL);
    dvmReleaseTrackedAlloc((Object*) params, NULL);
    dvmReleaseTrackedAlloc((Object*) exceptions, NULL);
    if (result == NULL)
        dvmReleaseTrackedAlloc(methObj, NULL);
    return result;
}
Esempio n. 4
0
/*
 * Create a new java/lang/reflect/Constructor object, using the contents of
 * "meth" to construct it.
 *
 * The spec doesn't specify the constructor.  We're going to use the
 * one from our existing class libs:
 *
 *  private Constructor (Class declaringClass, Class[] ptypes, Class[] extypes,
 *      int slot)
 */
static Object* createConstructorObject(Method* meth)
{
    Object* result = NULL;
    ArrayObject* params = NULL;
    ArrayObject* exceptions = NULL;
    Object* consObj;
    DexStringCache mangle;
    char* cp;
    int slot, method_idx;

    dexStringCacheInit(&mangle);

    /* parent should guarantee init so we don't have to check on every call */
    assert(dvmIsClassInitialized(gDvm.classJavaLangReflectConstructor));

    consObj = dvmAllocObject(gDvm.classJavaLangReflectConstructor,
                ALLOC_DEFAULT);
    if (consObj == NULL)
        goto bail;

    /*
     * Convert the signature string into an array of classes representing
     * the arguments.
     */
    cp = dvmCopyDescriptorStringFromMethod(meth, &mangle);
    params = convertSignatureToClassArray(&cp, meth->clazz);
    if (params == NULL)
        goto bail;
    assert(*cp == ')');
    assert(*(cp+1) == 'V');

    /*
     * Create an array with one entry for every exception that the class
     * is declared to throw.
     */
    exceptions = dvmGetMethodThrows(meth);
    if (dvmCheckException(dvmThreadSelf()))
        goto bail;

    slot = methodToSlot(meth);
    method_idx = dvmGetMethodIdx(meth);

    JValue unused;
    dvmCallMethod(dvmThreadSelf(), gDvm.methJavaLangReflectConstructor_init,
        consObj, &unused, meth->clazz, params, exceptions, slot, method_idx);
    if (dvmCheckException(dvmThreadSelf())) {
        ALOGD("Constructor class init threw exception");
        goto bail;
    }

    result = consObj;

bail:
    dexStringCacheRelease(&mangle);
    dvmReleaseTrackedAlloc((Object*) params, NULL);
    dvmReleaseTrackedAlloc((Object*) exceptions, NULL);
    if (result == NULL) {
        assert(dvmCheckException(dvmThreadSelf()));
        dvmReleaseTrackedAlloc(consObj, NULL);
    }
    /* caller must dvmReleaseTrackedAlloc(result) */
    return result;
}
int
hprofDumpStackFrames(hprof_context_t *ctx)
{
    HashIter iter;
    hprof_record_t *rec = &ctx->curRec;

    dvmHashTableLock(gStackFrameHashTable);

    for (dvmHashIterBegin(gStackFrameHashTable, &iter);
         !dvmHashIterDone(&iter);
         dvmHashIterNext(&iter))
    {
        const StackFrameEntry *stackFrameEntry;
        const Method *method;
        int pc;
        const char *sourceFile;
        ClassObject *clazz;
        int lineNum;
        
        hprofStartNewRecord(ctx, HPROF_TAG_STACK_FRAME, HPROF_TIME);
        
        stackFrameEntry = (const StackFrameEntry *) dvmHashIterData(&iter);
        assert(stackFrameEntry != NULL);
        
        method = stackFrameEntry->frame.method;
        pc = stackFrameEntry->frame.pc;
        sourceFile = dvmGetMethodSourceFile(method);
        if (sourceFile == NULL) {
            sourceFile = "<unknown>";
            lineNum = 0;
        } else {
            lineNum = dvmLineNumFromPC(method, pc);
        }
        clazz = (ClassObject *) hprofLookupClassId(method->clazz);

        /* STACK FRAME format:
         *
         * ID:     ID for this stack frame
         * ID:     ID for the method name
         * ID:     ID for the method descriptor
         * ID:     ID for the source file name
         * u4:     class serial number
         * u4:     line number, 0 = no line information
         *
         * We use the address of the stack frame as its ID.
         */

        DexStringCache cache;
        const char* descriptor;

        dexStringCacheInit(&cache);
        descriptor = dexProtoGetMethodDescriptor(&method->prototype, &cache);

        hprofAddIdToRecord(rec, (u4) stackFrameEntry);
        hprofAddIdToRecord(rec, hprofLookupStringId(method->name));
        hprofAddIdToRecord(rec, hprofLookupStringId(descriptor));
        hprofAddIdToRecord(rec, hprofLookupStringId(sourceFile));
        hprofAddU4ToRecord(rec, (u4) clazz->serialNumber);
        hprofAddU4ToRecord(rec, (u4) lineNum);

        dexStringCacheRelease(&cache);
    }

    dvmHashTableUnlock(gStackFrameHashTable);
    return 0;
}