gotoTargets.cpp revision 30bc0d46ae730d78c42c39cfa56a59ba3025380b
1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * C footer.  This has some common code shared by the various targets.
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Everything from here on is a "goto target".  In the basic interpreter
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * we jump into these targets and then jump directly to the handler for
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * next instruction.  Here, these are subroutines that return to the caller.
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1171eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhaoGOTO_TARGET(filledNewArray, bool methodCallRange, bool jumboFormat)
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ClassObject* arrayClass;
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ArrayObject* newArray;
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        u4* contents;
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        char typeCh;
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int i;
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        u4 arg5;
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        EXPORT_PC();
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2271eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao        if (jumboFormat) {
2371eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            ref = FETCH(1) | (u4)FETCH(2) << 16;  /* class ref */
2471eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            vsrc1 = FETCH(3);                     /* #of elements */
2571eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            vdst = FETCH(4);                      /* range base */
2671eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            arg5 = -1;                            /* silence compiler warning */
2771eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            ILOGV("|filled-new-array/jumbo args=%d @0x%08x {regs=v%d-v%d}",
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                vsrc1, ref, vdst, vdst+vsrc1-1);
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {
3071eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            ref = FETCH(1);             /* class ref */
3171eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            vdst = FETCH(2);            /* first 4 regs -or- range base */
3271eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao
3371eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            if (methodCallRange) {
3471eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao                vsrc1 = INST_AA(inst);  /* #of elements */
3571eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao                arg5 = -1;              /* silence compiler warning */
3671eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao                ILOGV("|filled-new-array-range args=%d @0x%04x {regs=v%d-v%d}",
3771eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao                    vsrc1, ref, vdst, vdst+vsrc1-1);
3871eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            } else {
3971eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao                arg5 = INST_A(inst);
4071eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao                vsrc1 = INST_B(inst);   /* #of elements */
4171eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao                ILOGV("|filled-new-array args=%d @0x%04x {regs=0x%04x %x}",
4271eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao                   vsrc1, ref, vdst, arg5);
4371eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            }
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Resolve the array class.
48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        arrayClass = dvmDexGetResolvedClass(methodClassDex, ref);
50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (arrayClass == NULL) {
51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            arrayClass = dvmResolveClass(curMethod->clazz, ref, false);
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (arrayClass == NULL)
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                GOTO_exceptionThrown();
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!dvmIsArrayClass(arrayClass)) {
57d27f3cf3e7b373487f39e035fc4b55168d55c454Dan Bornstein            dvmThrowRuntimeException(
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                "filled-new-array needs array class");
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            GOTO_exceptionThrown();
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        */
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* verifier guarantees this is an array class */
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(dvmIsArrayClass(arrayClass));
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(dvmIsClassInitialized(arrayClass));
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Create an array of the specified type.
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGVV("+++ filled-new-array type is '%s'\n", arrayClass->descriptor);
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        typeCh = arrayClass->descriptor[1];
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (typeCh == 'D' || typeCh == 'J') {
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /* category 2 primitives not allowed */
73d27f3cf3e7b373487f39e035fc4b55168d55c454Dan Bornstein            dvmThrowRuntimeException("bad filled array req");
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            GOTO_exceptionThrown();
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else if (typeCh != 'L' && typeCh != '[' && typeCh != 'I') {
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /* TODO: requires multiple "fill in" loops with different widths */
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGE("non-int primitives not implemented\n");
7870b00abc45d7d04342a96a03749f993028b060f7Dan Bornstein            dvmThrowInternalError(
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                "filled-new-array not implemented for anything but 'int'");
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            GOTO_exceptionThrown();
81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        newArray = dvmAllocArrayByClass(arrayClass, vsrc1, ALLOC_DONT_TRACK);
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (newArray == NULL)
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            GOTO_exceptionThrown();
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Fill in the elements.  It's legal for vsrc1 to be zero.
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
90cd8f5e701547739f241594b43e9470c92d98e9cfCarl Shapiro        contents = (u4*)(void*)newArray->contents;
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (methodCallRange) {
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (i = 0; i < vsrc1; i++)
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                contents[i] = GET_REGISTER(vdst+i);
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            assert(vsrc1 <= 5);
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (vsrc1 == 5) {
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                contents[4] = GET_REGISTER(arg5);
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                vsrc1--;
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (i = 0; i < vsrc1; i++) {
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                contents[i] = GET_REGISTER(vdst & 0x0f);
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                vdst >>= 4;
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
105364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes        if (typeCh == 'L' || typeCh == '[') {
106364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes            dvmWriteBarrierArray(newArray, 0, newArray->length);
107364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes        }
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        retval.l = newArray;
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
11171eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao    if (jumboFormat) {
11271eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao        FINISH(5);
11371eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao    } else {
11471eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao        FINISH(3);
11571eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao    }
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectGOTO_TARGET_END
117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
11971eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhaoGOTO_TARGET(invokeVirtual, bool methodCallRange, bool jumboFormat)
120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Method* baseMethod;
122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Object* thisPtr;
123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        EXPORT_PC();
125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
12671eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao        if (jumboFormat) {
12771eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            ref = FETCH(1) | (u4)FETCH(2) << 16;  /* method ref */
12871eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            vsrc1 = FETCH(3);                     /* count */
12971eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            vdst = FETCH(4);                      /* first reg */
13071eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            ADJUST_PC(2);     /* advance pc partially to make returns easier */
13171eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            ILOGV("|invoke-virtual/jumbo args=%d @0x%08x {regs=v%d-v%d}",
132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                vsrc1, ref, vdst, vdst+vsrc1-1);
133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            thisPtr = (Object*) GET_REGISTER(vdst);
134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {
13571eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            vsrc1 = INST_AA(inst);      /* AA (count) or BA (count + arg 5) */
13671eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            ref = FETCH(1);             /* method ref */
13771eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            vdst = FETCH(2);            /* 4 regs -or- first reg */
13871eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao
13971eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            /*
14071eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao             * The object against which we are executing a method is always
14171eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao             * in the first argument.
14271eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao             */
14371eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            if (methodCallRange) {
14471eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao                assert(vsrc1 > 0);
14571eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao                ILOGV("|invoke-virtual-range args=%d @0x%04x {regs=v%d-v%d}",
14671eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao                    vsrc1, ref, vdst, vdst+vsrc1-1);
14771eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao                thisPtr = (Object*) GET_REGISTER(vdst);
14871eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            } else {
14971eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao                assert((vsrc1>>4) > 0);
15071eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao                ILOGV("|invoke-virtual args=%d @0x%04x {regs=0x%04x %x}",
15171eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao                    vsrc1 >> 4, ref, vdst, vsrc1 & 0x0f);
15271eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao                thisPtr = (Object*) GET_REGISTER(vdst & 0x0f);
15371eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            }
154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!checkForNull(thisPtr))
157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            GOTO_exceptionThrown();
158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Resolve the method.  This is the correct method for the static
161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * type of the object.  We also verify access permissions here.
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        baseMethod = dvmDexGetResolvedMethod(methodClassDex, ref);
164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (baseMethod == NULL) {
165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            baseMethod = dvmResolveMethod(curMethod->clazz, ref,METHOD_VIRTUAL);
166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (baseMethod == NULL) {
167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                ILOGV("+ unknown method or access denied\n");
168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                GOTO_exceptionThrown();
169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Combine the object we found with the vtable offset in the
174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * method.
175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(baseMethod->methodIndex < thisPtr->clazz->vtableCount);
177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        methodToCall = thisPtr->clazz->vtable[baseMethod->methodIndex];
178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1799a3147c7412f4794434b4c2604aa2ba784867774buzbee#if defined(WITH_JIT) && defined(MTERP_STUB)
1809a3147c7412f4794434b4c2604aa2ba784867774buzbee        self->methodToCall = methodToCall;
1819a3147c7412f4794434b4c2604aa2ba784867774buzbee        self->callsiteClass = thisPtr->clazz;
1827a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng#endif
1837a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0
185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (dvmIsAbstractMethod(methodToCall)) {
186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /*
187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * This can happen if you create two classes, Base and Sub, where
188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * Sub is a sub-class of Base.  Declare a protected abstract
189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * method foo() in Base, and invoke foo() from a method in Base.
190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * Base is an "abstract base class" and is never instantiated
191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * directly.  Now, Override foo() in Sub, and use Sub.  This
192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * Works fine unless Sub stops providing an implementation of
193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * the method.
194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
195d27f3cf3e7b373487f39e035fc4b55168d55c454Dan Bornstein            dvmThrowAbstractMethodError("abstract method not implemented");
196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            GOTO_exceptionThrown();
197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#else
199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(!dvmIsAbstractMethod(methodToCall) ||
200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            methodToCall->nativeFunc != NULL);
201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGVV("+++ base=%s.%s virtual[%d]=%s.%s\n",
204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            baseMethod->clazz->descriptor, baseMethod->name,
205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            (u4) baseMethod->methodIndex,
206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            methodToCall->clazz->descriptor, methodToCall->name);
207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(methodToCall != NULL);
208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0
210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (vsrc1 != methodToCall->insSize) {
211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGW("WRONG METHOD: base=%s.%s virtual[%d]=%s.%s\n",
212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                baseMethod->clazz->descriptor, baseMethod->name,
213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                (u4) baseMethod->methodIndex,
214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                methodToCall->clazz->descriptor, methodToCall->name);
215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            //dvmDumpClass(baseMethod->clazz);
216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            //dvmDumpClass(methodToCall->clazz);
217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            dvmDumpAllClasses(0);
218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        GOTO_invokeMethod(methodCallRange, methodToCall, vsrc1, vdst);
222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectGOTO_TARGET_END
224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
22571eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhaoGOTO_TARGET(invokeSuper, bool methodCallRange, bool jumboFormat)
226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Method* baseMethod;
228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        u2 thisReg;
229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        EXPORT_PC();
231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
23271eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao        if (jumboFormat) {
23371eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            ref = FETCH(1) | (u4)FETCH(2) << 16;  /* method ref */
23471eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            vsrc1 = FETCH(3);                     /* count */
23571eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            vdst = FETCH(4);                      /* first reg */
23671eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            ADJUST_PC(2);     /* advance pc partially to make returns easier */
23771eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            ILOGV("|invoke-super/jumbo args=%d @0x%08x {regs=v%d-v%d}",
238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                vsrc1, ref, vdst, vdst+vsrc1-1);
239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            thisReg = vdst;
240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {
24171eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            vsrc1 = INST_AA(inst);      /* AA (count) or BA (count + arg 5) */
24271eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            ref = FETCH(1);             /* method ref */
24371eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            vdst = FETCH(2);            /* 4 regs -or- first reg */
24471eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao
24571eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            if (methodCallRange) {
24671eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao                ILOGV("|invoke-super-range args=%d @0x%04x {regs=v%d-v%d}",
24771eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao                    vsrc1, ref, vdst, vdst+vsrc1-1);
24871eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao                thisReg = vdst;
24971eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            } else {
25071eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao                ILOGV("|invoke-super args=%d @0x%04x {regs=0x%04x %x}",
25171eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao                    vsrc1 >> 4, ref, vdst, vsrc1 & 0x0f);
25271eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao                thisReg = vdst & 0x0f;
25371eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            }
254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
25571eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao
256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* impossible in well-formed code, but we must check nevertheless */
257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!checkForNull((Object*) GET_REGISTER(thisReg)))
258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            GOTO_exceptionThrown();
259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Resolve the method.  This is the correct method for the static
262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * type of the object.  We also verify access permissions here.
263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * The first arg to dvmResolveMethod() is just the referring class
264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * (used for class loaders and such), so we don't want to pass
265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * the superclass into the resolution call.
266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        baseMethod = dvmDexGetResolvedMethod(methodClassDex, ref);
268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (baseMethod == NULL) {
269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            baseMethod = dvmResolveMethod(curMethod->clazz, ref,METHOD_VIRTUAL);
270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (baseMethod == NULL) {
271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                ILOGV("+ unknown method or access denied\n");
272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                GOTO_exceptionThrown();
273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Combine the object we found with the vtable offset in the
278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * method's class.
279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *
280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * We're using the current method's class' superclass, not the
281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * superclass of "this".  This is because we might be executing
282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * in a method inherited from a superclass, and we want to run
283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * in that class' superclass.
284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (baseMethod->methodIndex >= curMethod->clazz->super->vtableCount) {
286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /*
287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * Method does not exist in the superclass.  Could happen if
288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * superclass gets updated.
289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
290d27f3cf3e7b373487f39e035fc4b55168d55c454Dan Bornstein            dvmThrowNoSuchMethodError(baseMethod->name);
291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            GOTO_exceptionThrown();
292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        methodToCall = curMethod->clazz->super->vtable[baseMethod->methodIndex];
2949a3147c7412f4794434b4c2604aa2ba784867774buzbee
295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0
296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (dvmIsAbstractMethod(methodToCall)) {
297d27f3cf3e7b373487f39e035fc4b55168d55c454Dan Bornstein            dvmThrowAbstractMethodError("abstract method not implemented");
298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            GOTO_exceptionThrown();
299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#else
301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(!dvmIsAbstractMethod(methodToCall) ||
302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            methodToCall->nativeFunc != NULL);
303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGVV("+++ base=%s.%s super-virtual=%s.%s\n",
305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            baseMethod->clazz->descriptor, baseMethod->name,
306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            methodToCall->clazz->descriptor, methodToCall->name);
307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(methodToCall != NULL);
308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        GOTO_invokeMethod(methodCallRange, methodToCall, vsrc1, vdst);
310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectGOTO_TARGET_END
312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
31371eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhaoGOTO_TARGET(invokeInterface, bool methodCallRange, bool jumboFormat)
314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Object* thisPtr;
316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ClassObject* thisClass;
317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        EXPORT_PC();
319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
32071eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao        if (jumboFormat) {
32171eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            ref = FETCH(1) | (u4)FETCH(2) << 16;  /* method ref */
32271eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            vsrc1 = FETCH(3);                     /* count */
32371eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            vdst = FETCH(4);                      /* first reg */
32471eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            ADJUST_PC(2);     /* advance pc partially to make returns easier */
32571eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            ILOGV("|invoke-interface/jumbo args=%d @0x%08x {regs=v%d-v%d}",
326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                vsrc1, ref, vdst, vdst+vsrc1-1);
327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            thisPtr = (Object*) GET_REGISTER(vdst);
328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {
32971eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            vsrc1 = INST_AA(inst);      /* AA (count) or BA (count + arg 5) */
33071eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            ref = FETCH(1);             /* method ref */
33171eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            vdst = FETCH(2);            /* 4 regs -or- first reg */
33271eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao
33371eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            /*
33471eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao             * The object against which we are executing a method is always
33571eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao             * in the first argument.
33671eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao             */
33771eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            if (methodCallRange) {
33871eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao                assert(vsrc1 > 0);
33971eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao                ILOGV("|invoke-interface-range args=%d @0x%04x {regs=v%d-v%d}",
34071eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao                    vsrc1, ref, vdst, vdst+vsrc1-1);
34171eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao                thisPtr = (Object*) GET_REGISTER(vdst);
34271eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            } else {
34371eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao                assert((vsrc1>>4) > 0);
34471eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao                ILOGV("|invoke-interface args=%d @0x%04x {regs=0x%04x %x}",
34571eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao                    vsrc1 >> 4, ref, vdst, vsrc1 & 0x0f);
34671eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao                thisPtr = (Object*) GET_REGISTER(vdst & 0x0f);
34771eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            }
348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
34971eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao
350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!checkForNull(thisPtr))
351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            GOTO_exceptionThrown();
352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        thisClass = thisPtr->clazz;
354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
3557a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Given a class and a method index, find the Method* with the
358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * actual code we want to execute.
359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        methodToCall = dvmFindInterfaceMethodInCache(thisClass, ref, curMethod,
361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        methodClassDex);
3629a3147c7412f4794434b4c2604aa2ba784867774buzbee#if defined(WITH_JIT) && defined(MTERP_STUB)
3639a3147c7412f4794434b4c2604aa2ba784867774buzbee        self->callsiteClass = thisClass;
3649a3147c7412f4794434b4c2604aa2ba784867774buzbee        self->methodToCall = methodToCall;
3659a3147c7412f4794434b4c2604aa2ba784867774buzbee#endif
366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (methodToCall == NULL) {
367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            assert(dvmCheckException(self));
368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            GOTO_exceptionThrown();
369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        GOTO_invokeMethod(methodCallRange, methodToCall, vsrc1, vdst);
372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectGOTO_TARGET_END
374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
37571eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhaoGOTO_TARGET(invokeDirect, bool methodCallRange, bool jumboFormat)
376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        u2 thisReg;
378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        EXPORT_PC();
380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
38171eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao        if (jumboFormat) {
38271eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            ref = FETCH(1) | (u4)FETCH(2) << 16;  /* method ref */
38371eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            vsrc1 = FETCH(3);                     /* count */
38471eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            vdst = FETCH(4);                      /* first reg */
38571eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            ADJUST_PC(2);     /* advance pc partially to make returns easier */
38671eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            ILOGV("|invoke-direct/jumbo args=%d @0x%08x {regs=v%d-v%d}",
387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                vsrc1, ref, vdst, vdst+vsrc1-1);
388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            thisReg = vdst;
389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {
39071eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            vsrc1 = INST_AA(inst);      /* AA (count) or BA (count + arg 5) */
39171eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            ref = FETCH(1);             /* method ref */
39271eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            vdst = FETCH(2);            /* 4 regs -or- first reg */
39371eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao
39471eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            if (methodCallRange) {
39571eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao                ILOGV("|invoke-direct-range args=%d @0x%04x {regs=v%d-v%d}",
39671eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao                    vsrc1, ref, vdst, vdst+vsrc1-1);
39771eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao                thisReg = vdst;
39871eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            } else {
39971eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao                ILOGV("|invoke-direct args=%d @0x%04x {regs=0x%04x %x}",
40071eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao                    vsrc1 >> 4, ref, vdst, vsrc1 & 0x0f);
40171eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao                thisReg = vdst & 0x0f;
40271eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            }
403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
40471eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao
405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!checkForNull((Object*) GET_REGISTER(thisReg)))
406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            GOTO_exceptionThrown();
407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        methodToCall = dvmDexGetResolvedMethod(methodClassDex, ref);
409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (methodToCall == NULL) {
410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            methodToCall = dvmResolveMethod(curMethod->clazz, ref,
411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                            METHOD_DIRECT);
412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (methodToCall == NULL) {
413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                ILOGV("+ unknown direct method\n");     // should be impossible
414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                GOTO_exceptionThrown();
415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        GOTO_invokeMethod(methodCallRange, methodToCall, vsrc1, vdst);
418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectGOTO_TARGET_END
420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
42171eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhaoGOTO_TARGET(invokeStatic, bool methodCallRange, bool jumboFormat)
422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    EXPORT_PC();
423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
42471eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao    if (jumboFormat) {
42571eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao        ref = FETCH(1) | (u4)FETCH(2) << 16;  /* method ref */
42671eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao        vsrc1 = FETCH(3);                     /* count */
42771eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao        vdst = FETCH(4);                      /* first reg */
42871eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao        ADJUST_PC(2);     /* advance pc partially to make returns easier */
42971eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao        ILOGV("|invoke-static/jumbo args=%d @0x%08x {regs=v%d-v%d}",
430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            vsrc1, ref, vdst, vdst+vsrc1-1);
43171eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao    } else {
43271eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao        vsrc1 = INST_AA(inst);      /* AA (count) or BA (count + arg 5) */
43371eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao        ref = FETCH(1);             /* method ref */
43471eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao        vdst = FETCH(2);            /* 4 regs -or- first reg */
43571eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao
43671eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao        if (methodCallRange)
43771eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            ILOGV("|invoke-static-range args=%d @0x%04x {regs=v%d-v%d}",
43871eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao                vsrc1, ref, vdst, vdst+vsrc1-1);
43971eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao        else
44071eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao            ILOGV("|invoke-static args=%d @0x%04x {regs=0x%04x %x}",
44171eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao                vsrc1 >> 4, ref, vdst, vsrc1 & 0x0f);
44271eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao    }
443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    methodToCall = dvmDexGetResolvedMethod(methodClassDex, ref);
445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (methodToCall == NULL) {
446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        methodToCall = dvmResolveMethod(curMethod->clazz, ref, METHOD_STATIC);
447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (methodToCall == NULL) {
448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            ILOGV("+ unknown method\n");
449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            GOTO_exceptionThrown();
450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
451dd6e87095071e4e987910732062545f7303023e5Ben Cheng
4529a3147c7412f4794434b4c2604aa2ba784867774buzbee#if defined(WITH_JIT) && defined(MTERP_STUB)
453dd6e87095071e4e987910732062545f7303023e5Ben Cheng        /*
454dd6e87095071e4e987910732062545f7303023e5Ben Cheng         * The JIT needs dvmDexGetResolvedMethod() to return non-null.
4559a3147c7412f4794434b4c2604aa2ba784867774buzbee         * Include the check if this code is being used as a stub
4569a3147c7412f4794434b4c2604aa2ba784867774buzbee         * called from the assembly interpreter.
457dd6e87095071e4e987910732062545f7303023e5Ben Cheng         */
4589a3147c7412f4794434b4c2604aa2ba784867774buzbee        if ((self->interpBreak.ctl.subMode & kSubModeJitTraceBuild) &&
4599a3147c7412f4794434b4c2604aa2ba784867774buzbee            (dvmDexGetResolvedMethod(methodClassDex, ref) == NULL)) {
460dd6e87095071e4e987910732062545f7303023e5Ben Cheng            /* Class initialization is still ongoing */
4619a3147c7412f4794434b4c2604aa2ba784867774buzbee            dvmJitEndTraceSelect(self,pc);
462dd6e87095071e4e987910732062545f7303023e5Ben Cheng        }
4639a3147c7412f4794434b4c2604aa2ba784867774buzbee#endif
464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    GOTO_invokeMethod(methodCallRange, methodToCall, vsrc1, vdst);
466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectGOTO_TARGET_END
467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
46871eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhaoGOTO_TARGET(invokeVirtualQuick, bool methodCallRange, bool jumboFormat)
469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Object* thisPtr;
471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        EXPORT_PC();
473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vsrc1 = INST_AA(inst);      /* AA (count) or BA (count + arg 5) */
475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ref = FETCH(1);             /* vtable index */
476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vdst = FETCH(2);            /* 4 regs -or- first reg */
477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * The object against which we are executing a method is always
480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * in the first argument.
481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (methodCallRange) {
483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            assert(vsrc1 > 0);
484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            ILOGV("|invoke-virtual-quick-range args=%d @0x%04x {regs=v%d-v%d}",
485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                vsrc1, ref, vdst, vdst+vsrc1-1);
486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            thisPtr = (Object*) GET_REGISTER(vdst);
487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {
488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            assert((vsrc1>>4) > 0);
489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            ILOGV("|invoke-virtual-quick args=%d @0x%04x {regs=0x%04x %x}",
490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                vsrc1 >> 4, ref, vdst, vsrc1 & 0x0f);
491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            thisPtr = (Object*) GET_REGISTER(vdst & 0x0f);
492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!checkForNull(thisPtr))
495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            GOTO_exceptionThrown();
496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
4977a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng
498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Combine the object we found with the vtable offset in the
500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * method.
501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
50271eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao        assert(ref < (unsigned int) thisPtr->clazz->vtableCount);
503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        methodToCall = thisPtr->clazz->vtable[ref];
5049a3147c7412f4794434b4c2604aa2ba784867774buzbee#if defined(WITH_JIT) && defined(MTERP_STUB)
5059a3147c7412f4794434b4c2604aa2ba784867774buzbee        self->callsiteClass = thisPtr->clazz;
5069a3147c7412f4794434b4c2604aa2ba784867774buzbee        self->methodToCall = methodToCall;
5079a3147c7412f4794434b4c2604aa2ba784867774buzbee#endif
508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0
510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (dvmIsAbstractMethod(methodToCall)) {
511d27f3cf3e7b373487f39e035fc4b55168d55c454Dan Bornstein            dvmThrowAbstractMethodError("abstract method not implemented");
512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            GOTO_exceptionThrown();
513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#else
515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(!dvmIsAbstractMethod(methodToCall) ||
516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            methodToCall->nativeFunc != NULL);
517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGVV("+++ virtual[%d]=%s.%s\n",
520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            ref, methodToCall->clazz->descriptor, methodToCall->name);
521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(methodToCall != NULL);
522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        GOTO_invokeMethod(methodCallRange, methodToCall, vsrc1, vdst);
524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectGOTO_TARGET_END
526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
52771eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhaoGOTO_TARGET(invokeSuperQuick, bool methodCallRange, bool jumboFormat)
528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        u2 thisReg;
530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        EXPORT_PC();
532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vsrc1 = INST_AA(inst);      /* AA (count) or BA (count + arg 5) */
534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ref = FETCH(1);             /* vtable index */
535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vdst = FETCH(2);            /* 4 regs -or- first reg */
536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (methodCallRange) {
538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            ILOGV("|invoke-super-quick-range args=%d @0x%04x {regs=v%d-v%d}",
539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                vsrc1, ref, vdst, vdst+vsrc1-1);
540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            thisReg = vdst;
541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {
542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            ILOGV("|invoke-super-quick args=%d @0x%04x {regs=0x%04x %x}",
543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                vsrc1 >> 4, ref, vdst, vsrc1 & 0x0f);
544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            thisReg = vdst & 0x0f;
545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* impossible in well-formed code, but we must check nevertheless */
547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!checkForNull((Object*) GET_REGISTER(thisReg)))
548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            GOTO_exceptionThrown();
549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0   /* impossible in optimized + verified code */
551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (ref >= curMethod->clazz->super->vtableCount) {
552d27f3cf3e7b373487f39e035fc4b55168d55c454Dan Bornstein            dvmThrowNoSuchMethodError(NULL);
553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            GOTO_exceptionThrown();
554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#else
55671eee1f0c2eb514585fdbee16730c9c2209e8f68jeffhao        assert(ref < (unsigned int) curMethod->clazz->super->vtableCount);
557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Combine the object we found with the vtable offset in the
561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * method's class.
562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *
563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * We're using the current method's class' superclass, not the
564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * superclass of "this".  This is because we might be executing
565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * in a method inherited from a superclass, and we want to run
566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * in the method's class' superclass.
567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        methodToCall = curMethod->clazz->super->vtable[ref];
569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0
571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (dvmIsAbstractMethod(methodToCall)) {
572d27f3cf3e7b373487f39e035fc4b55168d55c454Dan Bornstein            dvmThrowAbstractMethodError("abstract method not implemented");
573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            GOTO_exceptionThrown();
574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#else
576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(!dvmIsAbstractMethod(methodToCall) ||
577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            methodToCall->nativeFunc != NULL);
578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGVV("+++ super-virtual[%d]=%s.%s\n",
580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            ref, methodToCall->clazz->descriptor, methodToCall->name);
581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(methodToCall != NULL);
582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        GOTO_invokeMethod(methodCallRange, methodToCall, vsrc1, vdst);
583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectGOTO_TARGET_END
585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * General handling for return-void, return, and return-wide.  Put the
589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * return value in "retval" before jumping here.
590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectGOTO_TARGET(returnFromMethod)
592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        StackSaveArea* saveArea;
594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * We must do this BEFORE we pop the previous stack frame off, so
597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * that the GC can see the return value (if any) in the local vars.
598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *
599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Since this is now an interpreter switch point, we must do it before
600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * we do anything at all.
601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
6029a3147c7412f4794434b4c2604aa2ba784867774buzbee        PERIODIC_CHECKS(0);
603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ILOGV("> retval=0x%llx (leaving %s.%s %s)",
605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            retval.j, curMethod->clazz->descriptor, curMethod->name,
60685745e148153894aac52ad3d7f6a36a7767b45a0Mike Lockwood            curMethod->shorty);
607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //DUMP_REGS(curMethod, fp);
608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        saveArea = SAVEAREA_FROM_FP(fp);
610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifdef EASY_GDB
612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        debugSaveArea = saveArea;
613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* back up to previous frame and see if we hit a break */
616fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro        fp = (u4*)saveArea->prevFrame;
617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(fp != NULL);
6189a3147c7412f4794434b4c2604aa2ba784867774buzbee
6199a3147c7412f4794434b4c2604aa2ba784867774buzbee        /* Handle any special subMode requirements */
6209a3147c7412f4794434b4c2604aa2ba784867774buzbee        if (self->interpBreak.ctl.subMode != 0) {
62199e3e6e72e3471eb85fc2e405866392b01c080febuzbee            PC_FP_TO_SELF();
62299e3e6e72e3471eb85fc2e405866392b01c080febuzbee            dvmReportReturn(self);
6239a3147c7412f4794434b4c2604aa2ba784867774buzbee        }
6249a3147c7412f4794434b4c2604aa2ba784867774buzbee
625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (dvmIsBreakFrame(fp)) {
626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /* bail without popping the method frame from stack */
627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGVV("+++ returned into break frame\n");
628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            GOTO_bail();
629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* update thread FP, and reset local variables */
63230bc0d46ae730d78c42c39cfa56a59ba3025380bbuzbee        self->interpSave.curFrame = fp;
633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        curMethod = SAVEAREA_FROM_FP(fp)->method;
63499e3e6e72e3471eb85fc2e405866392b01c080febuzbee        self->interpSave.method = curMethod;
635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //methodClass = curMethod->clazz;
636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        methodClassDex = curMethod->clazz->pDvmDex;
637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        pc = saveArea->savedPc;
638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ILOGD("> (return to %s.%s %s)", curMethod->clazz->descriptor,
63985745e148153894aac52ad3d7f6a36a7767b45a0Mike Lockwood            curMethod->name, curMethod->shorty);
640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* use FINISH on the caller's invoke instruction */
642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //u2 invokeInstr = INST_INST(FETCH(0));
643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (true /*invokeInstr >= OP_INVOKE_VIRTUAL &&
644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            invokeInstr <= OP_INVOKE_INTERFACE*/)
645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            FINISH(3);
647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {
648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            //LOGE("Unknown invoke instr %02x at %d\n",
649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            //    invokeInstr, (int) (pc - curMethod->insns));
650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            assert(false);
651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectGOTO_TARGET_END
654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Jump here when the code throws an exception.
658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * By the time we get here, the Throwable has been created and the stack
660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * trace has been saved off.
661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectGOTO_TARGET(exceptionThrown)
663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Object* exception;
665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int catchRelPc;
666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
6679a3147c7412f4794434b4c2604aa2ba784867774buzbee        PERIODIC_CHECKS(0);
668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * We save off the exception and clear the exception status.  While
671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * processing the exception we might need to load some Throwable
672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * classes, and we don't want class loader exceptions to get
673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * confused with this one.
674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(dvmCheckException(self));
676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        exception = dvmGetException(self);
677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmAddTrackedAlloc(exception, self);
678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmClearException(self);
679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGV("Handling exception %s at %s:%d\n",
681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            exception->clazz->descriptor, curMethod->name,
682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            dvmLineNumFromPC(curMethod, pc - curMethod->insns));
683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
6859a3147c7412f4794434b4c2604aa2ba784867774buzbee         * Report the exception throw to any "subMode" watchers.
686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *
687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * TODO: if the exception was thrown by interpreted code, control
688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * fell through native, and then back to us, we will report the
689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * exception at the point of the throw and again here.  We can avoid
690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * this by not reporting exceptions when we jump here directly from
691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * the native call code above, but then we won't report exceptions
692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * that were thrown *from* the JNI code (as opposed to *through* it).
693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *
694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * The correct solution is probably to ignore from-native exceptions
695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * here, and have the JNI exception code do the reporting to the
696f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * debugger.
697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
6989a3147c7412f4794434b4c2604aa2ba784867774buzbee        if (self->interpBreak.ctl.subMode != 0) {
69999e3e6e72e3471eb85fc2e405866392b01c080febuzbee            PC_FP_TO_SELF();
70099e3e6e72e3471eb85fc2e405866392b01c080febuzbee            dvmReportExceptionThrow(self, exception);
701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * We need to unroll to the catch block or the nearest "break"
705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * frame.
706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *
707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * A break frame could indicate that we have reached an intermediate
708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * native call, or have gone off the top of the stack and the thread
709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * needs to exit.  Either way, we return from here, leaving the
710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * exception raised.
711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *
712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * If we do find a catch block, we want to transfer execution to
713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * that point.
7144fbba1f95b3e27bdc5f5572bb0420b5f928aa54eAndy McFadden         *
7154fbba1f95b3e27bdc5f5572bb0420b5f928aa54eAndy McFadden         * Note this can cause an exception while resolving classes in
7164fbba1f95b3e27bdc5f5572bb0420b5f928aa54eAndy McFadden         * the "catch" blocks.
717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
718f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        catchRelPc = dvmFindCatchBlock(self, pc - curMethod->insns,
719fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro                    exception, false, (void**)(void*)&fp);
720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
721f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Restore the stack bounds after an overflow.  This isn't going to
723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * be correct in all circumstances, e.g. if JNI code devours the
724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * exception this won't happen until some other exception gets
725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * thrown.  If the code keeps pushing the stack bounds we'll end
726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * up aborting the VM.
727f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *
728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Note we want to do this *after* the call to dvmFindCatchBlock,
729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * because that may need extra stack space to resolve exception
730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * classes (e.g. through a class loader).
7314fbba1f95b3e27bdc5f5572bb0420b5f928aa54eAndy McFadden         *
7324fbba1f95b3e27bdc5f5572bb0420b5f928aa54eAndy McFadden         * It's possible for the stack overflow handling to cause an
7334fbba1f95b3e27bdc5f5572bb0420b5f928aa54eAndy McFadden         * exception (specifically, class resolution in a "catch" block
7344fbba1f95b3e27bdc5f5572bb0420b5f928aa54eAndy McFadden         * during the call above), so we could see the thread's overflow
7354fbba1f95b3e27bdc5f5572bb0420b5f928aa54eAndy McFadden         * flag raised but actually be running in a "nested" interpreter
7364fbba1f95b3e27bdc5f5572bb0420b5f928aa54eAndy McFadden         * frame.  We don't allow doubled-up StackOverflowErrors, so
7374fbba1f95b3e27bdc5f5572bb0420b5f928aa54eAndy McFadden         * we can check for this by just looking at the exception type
7384fbba1f95b3e27bdc5f5572bb0420b5f928aa54eAndy McFadden         * in the cleanup function.  Also, we won't unroll past the SOE
7394fbba1f95b3e27bdc5f5572bb0420b5f928aa54eAndy McFadden         * point because the more-recent exception will hit a break frame
7404fbba1f95b3e27bdc5f5572bb0420b5f928aa54eAndy McFadden         * as it unrolls to here.
741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (self->stackOverflowed)
7434fbba1f95b3e27bdc5f5572bb0420b5f928aa54eAndy McFadden            dvmCleanupStackOverflow(self, exception);
744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (catchRelPc < 0) {
746f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /* falling through to JNI code or off the bottom of the stack */
747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if DVM_SHOW_EXCEPTION >= 2
748f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGD("Exception %s from %s:%d not caught locally\n",
749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                exception->clazz->descriptor, dvmGetMethodSourceFile(curMethod),
750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                dvmLineNumFromPC(curMethod, pc - curMethod->insns));
751f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
752f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            dvmSetException(self, exception);
753f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            dvmReleaseTrackedAlloc(exception, self);
754f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            GOTO_bail();
755f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
757f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if DVM_SHOW_EXCEPTION >= 3
758f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
759f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            const Method* catchMethod = SAVEAREA_FROM_FP(fp)->method;
760f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGD("Exception %s thrown from %s:%d to %s:%d\n",
761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                exception->clazz->descriptor, dvmGetMethodSourceFile(curMethod),
762f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                dvmLineNumFromPC(curMethod, pc - curMethod->insns),
763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                dvmGetMethodSourceFile(catchMethod),
764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                dvmLineNumFromPC(catchMethod, catchRelPc));
765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
766f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
767f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
768f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
76930bc0d46ae730d78c42c39cfa56a59ba3025380bbuzbee         * Adjust local variables to match self->interpSave.curFrame and the
770f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * updated PC.
771f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
77230bc0d46ae730d78c42c39cfa56a59ba3025380bbuzbee        //fp = (u4*) self->interpSave.curFrame;
773f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        curMethod = SAVEAREA_FROM_FP(fp)->method;
77499e3e6e72e3471eb85fc2e405866392b01c080febuzbee        self->interpSave.method = curMethod;
775f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //methodClass = curMethod->clazz;
776f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        methodClassDex = curMethod->clazz->pDvmDex;
777f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        pc = curMethod->insns + catchRelPc;
778f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ILOGV("> pc <-- %s.%s %s", curMethod->clazz->descriptor,
77985745e148153894aac52ad3d7f6a36a7767b45a0Mike Lockwood            curMethod->name, curMethod->shorty);
780f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        DUMP_REGS(curMethod, fp, false);            // show all regs
781f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
782f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
783f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Restore the exception if the handler wants it.
784f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *
785f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * The Dalvik spec mandates that, if an exception handler wants to
786f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * do something with the exception, the first instruction executed
787f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * must be "move-exception".  We can pass the exception along
788f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * through the thread struct, and let the move-exception instruction
789f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * clear it for us.
790f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *
791f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * If the handler doesn't call move-exception, we don't want to
792f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * finish here with an exception still pending.
793f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
794f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (INST_INST(FETCH(0)) == OP_MOVE_EXCEPTION)
795f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            dvmSetException(self, exception);
796f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
797f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmReleaseTrackedAlloc(exception, self);
798f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        FINISH(0);
799f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
800f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectGOTO_TARGET_END
801f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
802f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
8038afa9dfe04354e5b3917e31e3e2772885f507580Elliott Hughes
804f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
805f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * General handling for invoke-{virtual,super,direct,static,interface},
806f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * including "quick" variants.
807f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
808f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Set "methodToCall" to the Method we're calling, and "methodCallRange"
809f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * depending on whether this is a "/range" instruction.
810f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
811f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * For a range call:
812f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *  "vsrc1" holds the argument count (8 bits)
813f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *  "vdst" holds the first argument in the range
814f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * For a non-range call:
815f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *  "vsrc1" holds the argument count (4 bits) and the 5th argument index
816f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *  "vdst" holds four 4-bit register indices
817f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
818f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * The caller must EXPORT_PC before jumping here, because any method
819f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * call can throw a stack overflow exception.
820f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
821f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectGOTO_TARGET(invokeMethod, bool methodCallRange, const Method* _methodToCall,
822f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u2 count, u2 regs)
823f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
824f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        STUB_HACK(vsrc1 = count; vdst = regs; methodToCall = _methodToCall;);
825f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
826f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //printf("range=%d call=%p count=%d regs=0x%04x\n",
827f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //    methodCallRange, methodToCall, count, regs);
828f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //printf(" --> %s.%s %s\n", methodToCall->clazz->descriptor,
82985745e148153894aac52ad3d7f6a36a7767b45a0Mike Lockwood        //    methodToCall->name, methodToCall->shorty);
830f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
831f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        u4* outs;
832f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int i;
833f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
834f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
835f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Copy args.  This may corrupt vsrc1/vdst.
836f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
837f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (methodCallRange) {
838f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // could use memcpy or a "Duff's device"; most functions have
839f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // so few args it won't matter much
840f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            assert(vsrc1 <= curMethod->outsSize);
841f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            assert(vsrc1 == methodToCall->insSize);
842f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            outs = OUTS_FROM_FP(fp, vsrc1);
843f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (i = 0; i < vsrc1; i++)
844f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                outs[i] = GET_REGISTER(vdst+i);
845f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {
846f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            u4 count = vsrc1 >> 4;
847f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
848f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            assert(count <= curMethod->outsSize);
849f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            assert(count == methodToCall->insSize);
850f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            assert(count <= 5);
851f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
852f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            outs = OUTS_FROM_FP(fp, count);
853f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0
854f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (count == 5) {
855f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                outs[4] = GET_REGISTER(vsrc1 & 0x0f);
856f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                count--;
857f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
858f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (i = 0; i < (int) count; i++) {
859f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                outs[i] = GET_REGISTER(vdst & 0x0f);
860f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                vdst >>= 4;
861f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
862f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#else
863f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // This version executes fewer instructions but is larger
864f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // overall.  Seems to be a teensy bit faster.
865f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            assert((vdst >> 16) == 0);  // 16 bits -or- high 16 bits clear
866f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            switch (count) {
867f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 5:
868f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                outs[4] = GET_REGISTER(vsrc1 & 0x0f);
869f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 4:
870f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                outs[3] = GET_REGISTER(vdst >> 12);
871f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 3:
872f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                outs[2] = GET_REGISTER((vdst & 0x0f00) >> 8);
873f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 2:
874f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                outs[1] = GET_REGISTER((vdst & 0x00f0) >> 4);
875f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 1:
876f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                outs[0] = GET_REGISTER(vdst & 0x0f);
877f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            default:
878f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                ;
879f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
880f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
881f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
882f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
883f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
884f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
885f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * (This was originally a "goto" target; I've kept it separate from the
886f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * stuff above in case we want to refactor things again.)
887f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
888f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * At this point, we have the arguments stored in the "outs" area of
889f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * the current method's stack frame, and the method to call in
890f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * "methodToCall".  Push a new stack frame.
891f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
892f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
893f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        StackSaveArea* newSaveArea;
894f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        u4* newFp;
895f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
896f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ILOGV("> %s%s.%s %s",
897f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            dvmIsNativeMethod(methodToCall) ? "(NATIVE) " : "",
898f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            methodToCall->clazz->descriptor, methodToCall->name,
89985745e148153894aac52ad3d7f6a36a7767b45a0Mike Lockwood            methodToCall->shorty);
900f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
901f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        newFp = (u4*) SAVEAREA_FROM_FP(fp) - methodToCall->registersSize;
902f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        newSaveArea = SAVEAREA_FROM_FP(newFp);
903f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
904f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* verify that we have enough space */
905f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (true) {
906f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            u1* bottom;
907f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            bottom = (u1*) newSaveArea - methodToCall->outsSize * sizeof(u4);
908f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (bottom < self->interpStackEnd) {
909f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                /* stack overflow */
9106ed1a0f396a1857c31b486d3e93ee2dbeb49a6cdAndy McFadden                LOGV("Stack overflow on method call (start=%p end=%p newBot=%p(%d) size=%d '%s')\n",
911f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    self->interpStackStart, self->interpStackEnd, bottom,
9126ed1a0f396a1857c31b486d3e93ee2dbeb49a6cdAndy McFadden                    (u1*) fp - bottom, self->interpStackSize,
9136ed1a0f396a1857c31b486d3e93ee2dbeb49a6cdAndy McFadden                    methodToCall->name);
9146ed1a0f396a1857c31b486d3e93ee2dbeb49a6cdAndy McFadden                dvmHandleStackOverflow(self, methodToCall);
915f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                assert(dvmCheckException(self));
916f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                GOTO_exceptionThrown();
917f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
918f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            //LOGD("+++ fp=%p newFp=%p newSave=%p bottom=%p\n",
919f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            //    fp, newFp, newSaveArea, bottom);
920f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
921f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
922f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifdef LOG_INSTR
923f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (methodToCall->registersSize > methodToCall->insSize) {
924f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /*
925f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * This makes valgrind quiet when we print registers that
926f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * haven't been initialized.  Turn it off when the debug
927f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * messages are disabled -- we want valgrind to report any
928f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * used-before-initialized issues.
929f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
930f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            memset(newFp, 0xcc,
931f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                (methodToCall->registersSize - methodToCall->insSize) * 4);
932f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
933f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
934f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
935f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifdef EASY_GDB
936f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        newSaveArea->prevSave = SAVEAREA_FROM_FP(fp);
937f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
938f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        newSaveArea->prevFrame = fp;
939f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        newSaveArea->savedPc = pc;
9409a3147c7412f4794434b4c2604aa2ba784867774buzbee#if defined(WITH_JIT) && defined(MTERP_STUB)
941ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng        newSaveArea->returnAddr = 0;
942ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng#endif
943f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        newSaveArea->method = methodToCall;
944f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
9459a3147c7412f4794434b4c2604aa2ba784867774buzbee        if (self->interpBreak.ctl.subMode != 0) {
9469a3147c7412f4794434b4c2604aa2ba784867774buzbee            /*
9479a3147c7412f4794434b4c2604aa2ba784867774buzbee             * We mark ENTER here for both native and non-native
9489a3147c7412f4794434b4c2604aa2ba784867774buzbee             * calls.  For native calls, we'll mark EXIT on return.
9499a3147c7412f4794434b4c2604aa2ba784867774buzbee             * For non-native calls, EXIT is marked in the RETURN op.
9509a3147c7412f4794434b4c2604aa2ba784867774buzbee             */
95130bc0d46ae730d78c42c39cfa56a59ba3025380bbuzbee            PC_TO_SELF();
9529a3147c7412f4794434b4c2604aa2ba784867774buzbee            dvmReportInvoke(self, methodToCall);
9539a3147c7412f4794434b4c2604aa2ba784867774buzbee        }
9549a3147c7412f4794434b4c2604aa2ba784867774buzbee
955f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!dvmIsNativeMethod(methodToCall)) {
956f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /*
957f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * "Call" interpreted code.  Reposition the PC, update the
958f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * frame pointer and other local state, and continue.
959f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
960f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            curMethod = methodToCall;
96199e3e6e72e3471eb85fc2e405866392b01c080febuzbee            self->interpSave.method = curMethod;
962f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            methodClassDex = curMethod->clazz->pDvmDex;
963f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            pc = methodToCall->insns;
96430bc0d46ae730d78c42c39cfa56a59ba3025380bbuzbee            self->interpSave.curFrame = fp = newFp;
965f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifdef EASY_GDB
966f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            debugSaveArea = SAVEAREA_FROM_FP(newFp);
967f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
9689a3147c7412f4794434b4c2604aa2ba784867774buzbee            self->debugIsMethodEntry = true;        // profiling, debugging
969f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            ILOGD("> pc <-- %s.%s %s", curMethod->clazz->descriptor,
97085745e148153894aac52ad3d7f6a36a7767b45a0Mike Lockwood                curMethod->name, curMethod->shorty);
971f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            DUMP_REGS(curMethod, fp, true);         // show input args
972f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            FINISH(0);                              // jump to method start
973f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {
974f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /* set this up for JNI locals, even if not a JNI native */
975d5ab726b65d7271be261864c7e224fb90bfe06e0Andy McFadden            newSaveArea->xtra.localRefCookie = self->jniLocalRefTable.segmentState.all;
976f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
97730bc0d46ae730d78c42c39cfa56a59ba3025380bbuzbee            self->interpSave.curFrame = newFp;
978f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
979f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            DUMP_REGS(methodToCall, newFp, true);   // show input args
980f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
9819a3147c7412f4794434b4c2604aa2ba784867774buzbee            if (self->interpBreak.ctl.subMode != 0) {
98230bc0d46ae730d78c42c39cfa56a59ba3025380bbuzbee                dvmReportPreNativeInvoke(methodToCall, self, fp);
983f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
984f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
9859a3147c7412f4794434b4c2604aa2ba784867774buzbee            ILOGD("> native <-- %s.%s %s", methodToCall->clazz->descriptor,
9869a3147c7412f4794434b4c2604aa2ba784867774buzbee                  methodToCall->name, methodToCall->shorty);
987d726991ba52466cde88e37aba4de2395b62477faBill Buzbee
988f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /*
989f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * Jump through native call bridge.  Because we leave no
990f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * space for locals on native calls, "newFp" points directly
991f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * to the method arguments.
992f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
993f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            (*methodToCall->nativeFunc)(newFp, &retval, methodToCall, self);
994f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
9959a3147c7412f4794434b4c2604aa2ba784867774buzbee            if (self->interpBreak.ctl.subMode != 0) {
99630bc0d46ae730d78c42c39cfa56a59ba3025380bbuzbee                dvmReportPostNativeInvoke(methodToCall, self, fp);
997f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
998f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
999f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /* pop frame off */
1000f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            dvmPopJniLocals(self, newSaveArea);
100130bc0d46ae730d78c42c39cfa56a59ba3025380bbuzbee            self->interpSave.curFrame = fp;
1002f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1003f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /*
1004f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * If the native code threw an exception, or interpreted code
1005f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * invoked by the native call threw one and nobody has cleared
1006f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * it, jump to our local exception handling.
1007f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
1008f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (dvmCheckException(self)) {
1009f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                LOGV("Exception thrown by/below native code\n");
1010f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                GOTO_exceptionThrown();
1011f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
1012f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1013f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            ILOGD("> retval=0x%llx (leaving native)", retval.j);
1014f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            ILOGD("> (return from native %s.%s to %s.%s %s)",
1015f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                methodToCall->clazz->descriptor, methodToCall->name,
1016f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                curMethod->clazz->descriptor, curMethod->name,
101785745e148153894aac52ad3d7f6a36a7767b45a0Mike Lockwood                curMethod->shorty);
1018f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1019f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            //u2 invokeInstr = INST_INST(FETCH(0));
1020f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (true /*invokeInstr >= OP_INVOKE_VIRTUAL &&
1021f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                invokeInstr <= OP_INVOKE_INTERFACE*/)
1022f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            {
1023f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                FINISH(3);
1024f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } else {
1025f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                //LOGE("Unknown invoke instr %02x at %d\n",
1026f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                //    invokeInstr, (int) (pc - curMethod->insns));
1027f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                assert(false);
1028f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
1029f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1030f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1031f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(false);      // should not get here
1032f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectGOTO_TARGET_END
1033