gotoTargets.cpp revision 9a3147c7412f4794434b4c2604aa2ba784867774
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         */
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        contents = (u4*) 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) {
6219a3147c7412f4794434b4c2604aa2ba784867774buzbee            dvmReportReturn(self, pc, fp);
6229a3147c7412f4794434b4c2604aa2ba784867774buzbee        }
6239a3147c7412f4794434b4c2604aa2ba784867774buzbee
624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (dvmIsBreakFrame(fp)) {
625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /* bail without popping the method frame from stack */
626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGVV("+++ returned into break frame\n");
627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            GOTO_bail();
628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* update thread FP, and reset local variables */
631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        self->curFrame = fp;
632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        curMethod = SAVEAREA_FROM_FP(fp)->method;
633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //methodClass = curMethod->clazz;
634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        methodClassDex = curMethod->clazz->pDvmDex;
635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        pc = saveArea->savedPc;
636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ILOGD("> (return to %s.%s %s)", curMethod->clazz->descriptor,
63785745e148153894aac52ad3d7f6a36a7767b45a0Mike Lockwood            curMethod->name, curMethod->shorty);
638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* use FINISH on the caller's invoke instruction */
640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //u2 invokeInstr = INST_INST(FETCH(0));
641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (true /*invokeInstr >= OP_INVOKE_VIRTUAL &&
642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            invokeInstr <= OP_INVOKE_INTERFACE*/)
643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            FINISH(3);
645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {
646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            //LOGE("Unknown invoke instr %02x at %d\n",
647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            //    invokeInstr, (int) (pc - curMethod->insns));
648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            assert(false);
649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectGOTO_TARGET_END
652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Jump here when the code throws an exception.
656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * By the time we get here, the Throwable has been created and the stack
658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * trace has been saved off.
659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectGOTO_TARGET(exceptionThrown)
661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Object* exception;
663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int catchRelPc;
664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
6659a3147c7412f4794434b4c2604aa2ba784867774buzbee        PERIODIC_CHECKS(0);
666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * We save off the exception and clear the exception status.  While
669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * processing the exception we might need to load some Throwable
670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * classes, and we don't want class loader exceptions to get
671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * confused with this one.
672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(dvmCheckException(self));
674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        exception = dvmGetException(self);
675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmAddTrackedAlloc(exception, self);
676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmClearException(self);
677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGV("Handling exception %s at %s:%d\n",
679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            exception->clazz->descriptor, curMethod->name,
680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            dvmLineNumFromPC(curMethod, pc - curMethod->insns));
681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
6839a3147c7412f4794434b4c2604aa2ba784867774buzbee         * Report the exception throw to any "subMode" watchers.
684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *
685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * TODO: if the exception was thrown by interpreted code, control
686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * fell through native, and then back to us, we will report the
687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * exception at the point of the throw and again here.  We can avoid
688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * this by not reporting exceptions when we jump here directly from
689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * the native call code above, but then we won't report exceptions
690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * that were thrown *from* the JNI code (as opposed to *through* it).
691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *
692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * The correct solution is probably to ignore from-native exceptions
693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * here, and have the JNI exception code do the reporting to the
694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * debugger.
695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
6969a3147c7412f4794434b4c2604aa2ba784867774buzbee        if (self->interpBreak.ctl.subMode != 0) {
6979a3147c7412f4794434b4c2604aa2ba784867774buzbee            dvmReportExceptionThrow(self, curMethod, pc, fp);
698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
699f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
700f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * We need to unroll to the catch block or the nearest "break"
702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * frame.
703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *
704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * A break frame could indicate that we have reached an intermediate
705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * native call, or have gone off the top of the stack and the thread
706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * needs to exit.  Either way, we return from here, leaving the
707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * exception raised.
708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *
709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * If we do find a catch block, we want to transfer execution to
710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * that point.
7114fbba1f95b3e27bdc5f5572bb0420b5f928aa54eAndy McFadden         *
7124fbba1f95b3e27bdc5f5572bb0420b5f928aa54eAndy McFadden         * Note this can cause an exception while resolving classes in
7134fbba1f95b3e27bdc5f5572bb0420b5f928aa54eAndy McFadden         * the "catch" blocks.
714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        catchRelPc = dvmFindCatchBlock(self, pc - curMethod->insns,
716fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro                    exception, false, (void**)(void*)&fp);
717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
718f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Restore the stack bounds after an overflow.  This isn't going to
720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * be correct in all circumstances, e.g. if JNI code devours the
721f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * exception this won't happen until some other exception gets
722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * thrown.  If the code keeps pushing the stack bounds we'll end
723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * up aborting the VM.
724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *
725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Note we want to do this *after* the call to dvmFindCatchBlock,
726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * because that may need extra stack space to resolve exception
727f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * classes (e.g. through a class loader).
7284fbba1f95b3e27bdc5f5572bb0420b5f928aa54eAndy McFadden         *
7294fbba1f95b3e27bdc5f5572bb0420b5f928aa54eAndy McFadden         * It's possible for the stack overflow handling to cause an
7304fbba1f95b3e27bdc5f5572bb0420b5f928aa54eAndy McFadden         * exception (specifically, class resolution in a "catch" block
7314fbba1f95b3e27bdc5f5572bb0420b5f928aa54eAndy McFadden         * during the call above), so we could see the thread's overflow
7324fbba1f95b3e27bdc5f5572bb0420b5f928aa54eAndy McFadden         * flag raised but actually be running in a "nested" interpreter
7334fbba1f95b3e27bdc5f5572bb0420b5f928aa54eAndy McFadden         * frame.  We don't allow doubled-up StackOverflowErrors, so
7344fbba1f95b3e27bdc5f5572bb0420b5f928aa54eAndy McFadden         * we can check for this by just looking at the exception type
7354fbba1f95b3e27bdc5f5572bb0420b5f928aa54eAndy McFadden         * in the cleanup function.  Also, we won't unroll past the SOE
7364fbba1f95b3e27bdc5f5572bb0420b5f928aa54eAndy McFadden         * point because the more-recent exception will hit a break frame
7374fbba1f95b3e27bdc5f5572bb0420b5f928aa54eAndy McFadden         * as it unrolls to here.
738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (self->stackOverflowed)
7404fbba1f95b3e27bdc5f5572bb0420b5f928aa54eAndy McFadden            dvmCleanupStackOverflow(self, exception);
741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (catchRelPc < 0) {
743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /* falling through to JNI code or off the bottom of the stack */
744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if DVM_SHOW_EXCEPTION >= 2
745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGD("Exception %s from %s:%d not caught locally\n",
746f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                exception->clazz->descriptor, dvmGetMethodSourceFile(curMethod),
747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                dvmLineNumFromPC(curMethod, pc - curMethod->insns));
748f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            dvmSetException(self, exception);
750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            dvmReleaseTrackedAlloc(exception, self);
751f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            GOTO_bail();
752f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
753f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
754f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if DVM_SHOW_EXCEPTION >= 3
755f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            const Method* catchMethod = SAVEAREA_FROM_FP(fp)->method;
757f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGD("Exception %s thrown from %s:%d to %s:%d\n",
758f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                exception->clazz->descriptor, dvmGetMethodSourceFile(curMethod),
759f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                dvmLineNumFromPC(curMethod, pc - curMethod->insns),
760f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                dvmGetMethodSourceFile(catchMethod),
761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                dvmLineNumFromPC(catchMethod, catchRelPc));
762f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
766f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Adjust local variables to match self->curFrame and the
767f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * updated PC.
768f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
769f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //fp = (u4*) self->curFrame;
770f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        curMethod = SAVEAREA_FROM_FP(fp)->method;
771f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //methodClass = curMethod->clazz;
772f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        methodClassDex = curMethod->clazz->pDvmDex;
773f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        pc = curMethod->insns + catchRelPc;
774f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ILOGV("> pc <-- %s.%s %s", curMethod->clazz->descriptor,
77585745e148153894aac52ad3d7f6a36a7767b45a0Mike Lockwood            curMethod->name, curMethod->shorty);
776f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        DUMP_REGS(curMethod, fp, false);            // show all regs
777f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
778f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
779f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Restore the exception if the handler wants it.
780f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *
781f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * The Dalvik spec mandates that, if an exception handler wants to
782f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * do something with the exception, the first instruction executed
783f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * must be "move-exception".  We can pass the exception along
784f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * through the thread struct, and let the move-exception instruction
785f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * clear it for us.
786f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *
787f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * If the handler doesn't call move-exception, we don't want to
788f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * finish here with an exception still pending.
789f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
790f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (INST_INST(FETCH(0)) == OP_MOVE_EXCEPTION)
791f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            dvmSetException(self, exception);
792f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
793f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmReleaseTrackedAlloc(exception, self);
794f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        FINISH(0);
795f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
796f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectGOTO_TARGET_END
797f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
798f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
7998afa9dfe04354e5b3917e31e3e2772885f507580Elliott Hughes
800f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
801f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * General handling for invoke-{virtual,super,direct,static,interface},
802f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * including "quick" variants.
803f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
804f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Set "methodToCall" to the Method we're calling, and "methodCallRange"
805f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * depending on whether this is a "/range" instruction.
806f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
807f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * For a range call:
808f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *  "vsrc1" holds the argument count (8 bits)
809f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *  "vdst" holds the first argument in the range
810f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * For a non-range call:
811f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *  "vsrc1" holds the argument count (4 bits) and the 5th argument index
812f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *  "vdst" holds four 4-bit register indices
813f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
814f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * The caller must EXPORT_PC before jumping here, because any method
815f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * call can throw a stack overflow exception.
816f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
817f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectGOTO_TARGET(invokeMethod, bool methodCallRange, const Method* _methodToCall,
818f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u2 count, u2 regs)
819f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
820f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        STUB_HACK(vsrc1 = count; vdst = regs; methodToCall = _methodToCall;);
821f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
822f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //printf("range=%d call=%p count=%d regs=0x%04x\n",
823f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //    methodCallRange, methodToCall, count, regs);
824f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //printf(" --> %s.%s %s\n", methodToCall->clazz->descriptor,
82585745e148153894aac52ad3d7f6a36a7767b45a0Mike Lockwood        //    methodToCall->name, methodToCall->shorty);
826f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
827f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        u4* outs;
828f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int i;
829f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
830f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
831f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Copy args.  This may corrupt vsrc1/vdst.
832f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
833f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (methodCallRange) {
834f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // could use memcpy or a "Duff's device"; most functions have
835f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // so few args it won't matter much
836f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            assert(vsrc1 <= curMethod->outsSize);
837f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            assert(vsrc1 == methodToCall->insSize);
838f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            outs = OUTS_FROM_FP(fp, vsrc1);
839f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (i = 0; i < vsrc1; i++)
840f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                outs[i] = GET_REGISTER(vdst+i);
841f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {
842f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            u4 count = vsrc1 >> 4;
843f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
844f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            assert(count <= curMethod->outsSize);
845f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            assert(count == methodToCall->insSize);
846f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            assert(count <= 5);
847f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
848f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            outs = OUTS_FROM_FP(fp, count);
849f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0
850f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (count == 5) {
851f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                outs[4] = GET_REGISTER(vsrc1 & 0x0f);
852f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                count--;
853f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
854f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (i = 0; i < (int) count; i++) {
855f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                outs[i] = GET_REGISTER(vdst & 0x0f);
856f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                vdst >>= 4;
857f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
858f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#else
859f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // This version executes fewer instructions but is larger
860f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // overall.  Seems to be a teensy bit faster.
861f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            assert((vdst >> 16) == 0);  // 16 bits -or- high 16 bits clear
862f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            switch (count) {
863f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 5:
864f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                outs[4] = GET_REGISTER(vsrc1 & 0x0f);
865f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 4:
866f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                outs[3] = GET_REGISTER(vdst >> 12);
867f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 3:
868f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                outs[2] = GET_REGISTER((vdst & 0x0f00) >> 8);
869f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 2:
870f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                outs[1] = GET_REGISTER((vdst & 0x00f0) >> 4);
871f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 1:
872f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                outs[0] = GET_REGISTER(vdst & 0x0f);
873f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            default:
874f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                ;
875f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
876f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
877f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
878f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
879f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
880f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
881f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * (This was originally a "goto" target; I've kept it separate from the
882f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * stuff above in case we want to refactor things again.)
883f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
884f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * At this point, we have the arguments stored in the "outs" area of
885f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * the current method's stack frame, and the method to call in
886f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * "methodToCall".  Push a new stack frame.
887f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
888f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
889f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        StackSaveArea* newSaveArea;
890f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        u4* newFp;
891f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
892f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ILOGV("> %s%s.%s %s",
893f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            dvmIsNativeMethod(methodToCall) ? "(NATIVE) " : "",
894f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            methodToCall->clazz->descriptor, methodToCall->name,
89585745e148153894aac52ad3d7f6a36a7767b45a0Mike Lockwood            methodToCall->shorty);
896f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
897f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        newFp = (u4*) SAVEAREA_FROM_FP(fp) - methodToCall->registersSize;
898f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        newSaveArea = SAVEAREA_FROM_FP(newFp);
899f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
900f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* verify that we have enough space */
901f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (true) {
902f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            u1* bottom;
903f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            bottom = (u1*) newSaveArea - methodToCall->outsSize * sizeof(u4);
904f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (bottom < self->interpStackEnd) {
905f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                /* stack overflow */
9066ed1a0f396a1857c31b486d3e93ee2dbeb49a6cdAndy McFadden                LOGV("Stack overflow on method call (start=%p end=%p newBot=%p(%d) size=%d '%s')\n",
907f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    self->interpStackStart, self->interpStackEnd, bottom,
9086ed1a0f396a1857c31b486d3e93ee2dbeb49a6cdAndy McFadden                    (u1*) fp - bottom, self->interpStackSize,
9096ed1a0f396a1857c31b486d3e93ee2dbeb49a6cdAndy McFadden                    methodToCall->name);
9106ed1a0f396a1857c31b486d3e93ee2dbeb49a6cdAndy McFadden                dvmHandleStackOverflow(self, methodToCall);
911f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                assert(dvmCheckException(self));
912f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                GOTO_exceptionThrown();
913f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
914f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            //LOGD("+++ fp=%p newFp=%p newSave=%p bottom=%p\n",
915f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            //    fp, newFp, newSaveArea, bottom);
916f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
917f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
918f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifdef LOG_INSTR
919f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (methodToCall->registersSize > methodToCall->insSize) {
920f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /*
921f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * This makes valgrind quiet when we print registers that
922f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * haven't been initialized.  Turn it off when the debug
923f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * messages are disabled -- we want valgrind to report any
924f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * used-before-initialized issues.
925f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
926f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            memset(newFp, 0xcc,
927f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                (methodToCall->registersSize - methodToCall->insSize) * 4);
928f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
929f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
930f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
931f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifdef EASY_GDB
932f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        newSaveArea->prevSave = SAVEAREA_FROM_FP(fp);
933f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
934f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        newSaveArea->prevFrame = fp;
935f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        newSaveArea->savedPc = pc;
9369a3147c7412f4794434b4c2604aa2ba784867774buzbee#if defined(WITH_JIT) && defined(MTERP_STUB)
937ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng        newSaveArea->returnAddr = 0;
938ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng#endif
939f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        newSaveArea->method = methodToCall;
940f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
9419a3147c7412f4794434b4c2604aa2ba784867774buzbee        if (self->interpBreak.ctl.subMode != 0) {
9429a3147c7412f4794434b4c2604aa2ba784867774buzbee            /*
9439a3147c7412f4794434b4c2604aa2ba784867774buzbee             * We mark ENTER here for both native and non-native
9449a3147c7412f4794434b4c2604aa2ba784867774buzbee             * calls.  For native calls, we'll mark EXIT on return.
9459a3147c7412f4794434b4c2604aa2ba784867774buzbee             * For non-native calls, EXIT is marked in the RETURN op.
9469a3147c7412f4794434b4c2604aa2ba784867774buzbee             */
9479a3147c7412f4794434b4c2604aa2ba784867774buzbee            dvmReportInvoke(self, methodToCall);
9489a3147c7412f4794434b4c2604aa2ba784867774buzbee        }
9499a3147c7412f4794434b4c2604aa2ba784867774buzbee
950f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!dvmIsNativeMethod(methodToCall)) {
951f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /*
952f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * "Call" interpreted code.  Reposition the PC, update the
953f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * frame pointer and other local state, and continue.
954f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
955f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            curMethod = methodToCall;
956f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            methodClassDex = curMethod->clazz->pDvmDex;
957f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            pc = methodToCall->insns;
958fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro            self->curFrame = fp = newFp;
959f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifdef EASY_GDB
960f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            debugSaveArea = SAVEAREA_FROM_FP(newFp);
961f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
9629a3147c7412f4794434b4c2604aa2ba784867774buzbee            self->debugIsMethodEntry = true;        // profiling, debugging
963f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            ILOGD("> pc <-- %s.%s %s", curMethod->clazz->descriptor,
96485745e148153894aac52ad3d7f6a36a7767b45a0Mike Lockwood                curMethod->name, curMethod->shorty);
965f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            DUMP_REGS(curMethod, fp, true);         // show input args
966f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            FINISH(0);                              // jump to method start
967f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {
968f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /* set this up for JNI locals, even if not a JNI native */
969d5ab726b65d7271be261864c7e224fb90bfe06e0Andy McFadden            newSaveArea->xtra.localRefCookie = self->jniLocalRefTable.segmentState.all;
970f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
971f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            self->curFrame = newFp;
972f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
973f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            DUMP_REGS(methodToCall, newFp, true);   // show input args
974f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
9759a3147c7412f4794434b4c2604aa2ba784867774buzbee            if (self->interpBreak.ctl.subMode != 0) {
9769a3147c7412f4794434b4c2604aa2ba784867774buzbee                dvmReportPreNativeInvoke(pc, self, methodToCall);
977f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
978f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
9799a3147c7412f4794434b4c2604aa2ba784867774buzbee            ILOGD("> native <-- %s.%s %s", methodToCall->clazz->descriptor,
9809a3147c7412f4794434b4c2604aa2ba784867774buzbee                  methodToCall->name, methodToCall->shorty);
981d726991ba52466cde88e37aba4de2395b62477faBill Buzbee
982f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /*
983f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * Jump through native call bridge.  Because we leave no
984f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * space for locals on native calls, "newFp" points directly
985f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * to the method arguments.
986f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
987f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            (*methodToCall->nativeFunc)(newFp, &retval, methodToCall, self);
988f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
9899a3147c7412f4794434b4c2604aa2ba784867774buzbee            if (self->interpBreak.ctl.subMode != 0) {
9909a3147c7412f4794434b4c2604aa2ba784867774buzbee                dvmReportPostNativeInvoke(pc, self, methodToCall);
991f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
992f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
993f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /* pop frame off */
994f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            dvmPopJniLocals(self, newSaveArea);
995f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            self->curFrame = fp;
996f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
997f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /*
998f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * If the native code threw an exception, or interpreted code
999f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * invoked by the native call threw one and nobody has cleared
1000f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * it, jump to our local exception handling.
1001f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
1002f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (dvmCheckException(self)) {
1003f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                LOGV("Exception thrown by/below native code\n");
1004f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                GOTO_exceptionThrown();
1005f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
1006f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1007f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            ILOGD("> retval=0x%llx (leaving native)", retval.j);
1008f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            ILOGD("> (return from native %s.%s to %s.%s %s)",
1009f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                methodToCall->clazz->descriptor, methodToCall->name,
1010f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                curMethod->clazz->descriptor, curMethod->name,
101185745e148153894aac52ad3d7f6a36a7767b45a0Mike Lockwood                curMethod->shorty);
1012f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1013f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            //u2 invokeInstr = INST_INST(FETCH(0));
1014f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (true /*invokeInstr >= OP_INVOKE_VIRTUAL &&
1015f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                invokeInstr <= OP_INVOKE_INTERFACE*/)
1016f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            {
1017f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                FINISH(3);
1018f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } else {
1019f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                //LOGE("Unknown invoke instr %02x at %d\n",
1020f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                //    invokeInstr, (int) (pc - curMethod->insns));
1021f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                assert(false);
1022f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
1023f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1024f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1025f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(false);      // should not get here
1026f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectGOTO_TARGET_END
1027