gotoTargets.cpp revision fc75f3ed87b55d625b6054e18645da5cbdba31c6
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 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectGOTO_TARGET(filledNewArray, bool methodCallRange) 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 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ref = FETCH(1); /* class ref */ 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vdst = FETCH(2); /* first 4 regs -or- range base */ 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (methodCallRange) { 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vsrc1 = INST_AA(inst); /* #of elements */ 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project arg5 = -1; /* silence compiler warning */ 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ILOGV("|filled-new-array-range args=%d @0x%04x {regs=v%d-v%d}", 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vsrc1, ref, vdst, vdst+vsrc1-1); 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project arg5 = INST_A(inst); 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vsrc1 = INST_B(inst); /* #of elements */ 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ILOGV("|filled-new-array args=%d @0x%04x {regs=0x%04x %x}", 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vsrc1, ref, vdst, arg5); 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Resolve the array class. 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project arrayClass = dvmDexGetResolvedClass(methodClassDex, ref); 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (arrayClass == NULL) { 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project arrayClass = dvmResolveClass(curMethod->clazz, ref, false); 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (arrayClass == NULL) 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project GOTO_exceptionThrown(); 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmIsArrayClass(arrayClass)) { 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmThrowException("Ljava/lang/RuntimeError;", 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "filled-new-array needs array class"); 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project GOTO_exceptionThrown(); 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* verifier guarantees this is an array class */ 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(dvmIsArrayClass(arrayClass)); 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(dvmIsClassInitialized(arrayClass)); 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Create an array of the specified type. 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGVV("+++ filled-new-array type is '%s'\n", arrayClass->descriptor); 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project typeCh = arrayClass->descriptor[1]; 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (typeCh == 'D' || typeCh == 'J') { 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* category 2 primitives not allowed */ 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmThrowException("Ljava/lang/RuntimeError;", 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "bad filled array req"); 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project GOTO_exceptionThrown(); 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (typeCh != 'L' && typeCh != '[' && typeCh != 'I') { 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* TODO: requires multiple "fill in" loops with different widths */ 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("non-int primitives not implemented\n"); 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmThrowException("Ljava/lang/InternalError;", 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "filled-new-array not implemented for anything but 'int'"); 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project GOTO_exceptionThrown(); 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project newArray = dvmAllocArrayByClass(arrayClass, vsrc1, ALLOC_DONT_TRACK); 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (newArray == NULL) 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project GOTO_exceptionThrown(); 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Fill in the elements. It's legal for vsrc1 to be zero. 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project contents = (u4*) newArray->contents; 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (methodCallRange) { 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < vsrc1; i++) 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project contents[i] = GET_REGISTER(vdst+i); 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(vsrc1 <= 5); 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (vsrc1 == 5) { 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project contents[4] = GET_REGISTER(arg5); 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vsrc1--; 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < vsrc1; i++) { 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project contents[i] = GET_REGISTER(vdst & 0x0f); 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vdst >>= 4; 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 97364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes if (typeCh == 'L' || typeCh == '[') { 98364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes dvmWriteBarrierArray(newArray, 0, newArray->length); 99364f9d924cbd9d392744a66f80cc084c3d80caf0Barry Hayes } 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project retval.l = newArray; 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project FINISH(3); 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectGOTO_TARGET_END 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectGOTO_TARGET(invokeVirtual, bool methodCallRange) 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Method* baseMethod; 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* thisPtr; 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project EXPORT_PC(); 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vsrc1 = INST_AA(inst); /* AA (count) or BA (count + arg 5) */ 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ref = FETCH(1); /* method ref */ 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vdst = FETCH(2); /* 4 regs -or- first reg */ 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The object against which we are executing a method is always 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * in the first argument. 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (methodCallRange) { 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(vsrc1 > 0); 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ILOGV("|invoke-virtual-range args=%d @0x%04x {regs=v%d-v%d}", 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vsrc1, ref, vdst, vdst+vsrc1-1); 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project thisPtr = (Object*) GET_REGISTER(vdst); 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert((vsrc1>>4) > 0); 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ILOGV("|invoke-virtual args=%d @0x%04x {regs=0x%04x %x}", 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vsrc1 >> 4, ref, vdst, vsrc1 & 0x0f); 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project thisPtr = (Object*) GET_REGISTER(vdst & 0x0f); 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!checkForNull(thisPtr)) 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project GOTO_exceptionThrown(); 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Resolve the method. This is the correct method for the static 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * type of the object. We also verify access permissions here. 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project baseMethod = dvmDexGetResolvedMethod(methodClassDex, ref); 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (baseMethod == NULL) { 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project baseMethod = dvmResolveMethod(curMethod->clazz, ref,METHOD_VIRTUAL); 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (baseMethod == NULL) { 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ILOGV("+ unknown method or access denied\n"); 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project GOTO_exceptionThrown(); 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Combine the object we found with the vtable offset in the 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * method. 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(baseMethod->methodIndex < thisPtr->clazz->vtableCount); 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodToCall = thisPtr->clazz->vtable[baseMethod->methodIndex]; 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1577a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng#if defined(WITH_JIT) && (INTERP_TYPE == INTERP_DBG) 1587a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng callsiteClass = thisPtr->clazz; 1597a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng#endif 1607a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmIsAbstractMethod(methodToCall)) { 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This can happen if you create two classes, Base and Sub, where 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Sub is a sub-class of Base. Declare a protected abstract 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * method foo() in Base, and invoke foo() from a method in Base. 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Base is an "abstract base class" and is never instantiated 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * directly. Now, Override foo() in Sub, and use Sub. This 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Works fine unless Sub stops providing an implementation of 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the method. 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmThrowException("Ljava/lang/AbstractMethodError;", 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "abstract method not implemented"); 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project GOTO_exceptionThrown(); 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#else 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(!dvmIsAbstractMethod(methodToCall) || 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodToCall->nativeFunc != NULL); 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGVV("+++ base=%s.%s virtual[%d]=%s.%s\n", 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project baseMethod->clazz->descriptor, baseMethod->name, 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (u4) baseMethod->methodIndex, 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodToCall->clazz->descriptor, methodToCall->name); 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(methodToCall != NULL); 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (vsrc1 != methodToCall->insSize) { 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("WRONG METHOD: base=%s.%s virtual[%d]=%s.%s\n", 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project baseMethod->clazz->descriptor, baseMethod->name, 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (u4) baseMethod->methodIndex, 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodToCall->clazz->descriptor, methodToCall->name); 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //dvmDumpClass(baseMethod->clazz); 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //dvmDumpClass(methodToCall->clazz); 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDumpAllClasses(0); 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project GOTO_invokeMethod(methodCallRange, methodToCall, vsrc1, vdst); 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectGOTO_TARGET_END 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectGOTO_TARGET(invokeSuper, bool methodCallRange) 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Method* baseMethod; 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u2 thisReg; 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project EXPORT_PC(); 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vsrc1 = INST_AA(inst); /* AA (count) or BA (count + arg 5) */ 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ref = FETCH(1); /* method ref */ 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vdst = FETCH(2); /* 4 regs -or- first reg */ 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (methodCallRange) { 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ILOGV("|invoke-super-range args=%d @0x%04x {regs=v%d-v%d}", 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vsrc1, ref, vdst, vdst+vsrc1-1); 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project thisReg = vdst; 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ILOGV("|invoke-super args=%d @0x%04x {regs=0x%04x %x}", 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vsrc1 >> 4, ref, vdst, vsrc1 & 0x0f); 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project thisReg = vdst & 0x0f; 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* impossible in well-formed code, but we must check nevertheless */ 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!checkForNull((Object*) GET_REGISTER(thisReg))) 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project GOTO_exceptionThrown(); 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Resolve the method. This is the correct method for the static 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * type of the object. We also verify access permissions here. 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The first arg to dvmResolveMethod() is just the referring class 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (used for class loaders and such), so we don't want to pass 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the superclass into the resolution call. 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project baseMethod = dvmDexGetResolvedMethod(methodClassDex, ref); 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (baseMethod == NULL) { 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project baseMethod = dvmResolveMethod(curMethod->clazz, ref,METHOD_VIRTUAL); 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (baseMethod == NULL) { 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ILOGV("+ unknown method or access denied\n"); 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project GOTO_exceptionThrown(); 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Combine the object we found with the vtable offset in the 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * method's class. 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We're using the current method's class' superclass, not the 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * superclass of "this". This is because we might be executing 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * in a method inherited from a superclass, and we want to run 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * in that class' superclass. 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (baseMethod->methodIndex >= curMethod->clazz->super->vtableCount) { 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Method does not exist in the superclass. Could happen if 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * superclass gets updated. 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmThrowException("Ljava/lang/NoSuchMethodError;", 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project baseMethod->name); 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project GOTO_exceptionThrown(); 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodToCall = curMethod->clazz->super->vtable[baseMethod->methodIndex]; 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmIsAbstractMethod(methodToCall)) { 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmThrowException("Ljava/lang/AbstractMethodError;", 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "abstract method not implemented"); 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project GOTO_exceptionThrown(); 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#else 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(!dvmIsAbstractMethod(methodToCall) || 270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodToCall->nativeFunc != NULL); 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGVV("+++ base=%s.%s super-virtual=%s.%s\n", 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project baseMethod->clazz->descriptor, baseMethod->name, 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodToCall->clazz->descriptor, methodToCall->name); 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(methodToCall != NULL); 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project GOTO_invokeMethod(methodCallRange, methodToCall, vsrc1, vdst); 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectGOTO_TARGET_END 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectGOTO_TARGET(invokeInterface, bool methodCallRange) 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* thisPtr; 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassObject* thisClass; 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project EXPORT_PC(); 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vsrc1 = INST_AA(inst); /* AA (count) or BA (count + arg 5) */ 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ref = FETCH(1); /* method ref */ 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vdst = FETCH(2); /* 4 regs -or- first reg */ 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The object against which we are executing a method is always 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * in the first argument. 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (methodCallRange) { 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(vsrc1 > 0); 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ILOGV("|invoke-interface-range args=%d @0x%04x {regs=v%d-v%d}", 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vsrc1, ref, vdst, vdst+vsrc1-1); 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project thisPtr = (Object*) GET_REGISTER(vdst); 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert((vsrc1>>4) > 0); 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ILOGV("|invoke-interface args=%d @0x%04x {regs=0x%04x %x}", 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vsrc1 >> 4, ref, vdst, vsrc1 & 0x0f); 305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project thisPtr = (Object*) GET_REGISTER(vdst & 0x0f); 306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!checkForNull(thisPtr)) 308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project GOTO_exceptionThrown(); 309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project thisClass = thisPtr->clazz; 311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3127a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng#if defined(WITH_JIT) && (INTERP_TYPE == INTERP_DBG) 3137a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng callsiteClass = thisClass; 3147a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng#endif 3157a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng 316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Given a class and a method index, find the Method* with the 318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * actual code we want to execute. 319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodToCall = dvmFindInterfaceMethodInCache(thisClass, ref, curMethod, 321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodClassDex); 322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (methodToCall == NULL) { 323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(dvmCheckException(self)); 324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project GOTO_exceptionThrown(); 325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project GOTO_invokeMethod(methodCallRange, methodToCall, vsrc1, vdst); 328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectGOTO_TARGET_END 330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectGOTO_TARGET(invokeDirect, bool methodCallRange) 332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u2 thisReg; 334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vsrc1 = INST_AA(inst); /* AA (count) or BA (count + arg 5) */ 336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ref = FETCH(1); /* method ref */ 337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vdst = FETCH(2); /* 4 regs -or- first reg */ 338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project EXPORT_PC(); 340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (methodCallRange) { 342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ILOGV("|invoke-direct-range args=%d @0x%04x {regs=v%d-v%d}", 343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vsrc1, ref, vdst, vdst+vsrc1-1); 344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project thisReg = vdst; 345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ILOGV("|invoke-direct args=%d @0x%04x {regs=0x%04x %x}", 347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vsrc1 >> 4, ref, vdst, vsrc1 & 0x0f); 348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project thisReg = vdst & 0x0f; 349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!checkForNull((Object*) GET_REGISTER(thisReg))) 351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project GOTO_exceptionThrown(); 352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodToCall = dvmDexGetResolvedMethod(methodClassDex, ref); 354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (methodToCall == NULL) { 355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodToCall = dvmResolveMethod(curMethod->clazz, ref, 356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project METHOD_DIRECT); 357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (methodToCall == NULL) { 358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ILOGV("+ unknown direct method\n"); // should be impossible 359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project GOTO_exceptionThrown(); 360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project GOTO_invokeMethod(methodCallRange, methodToCall, vsrc1, vdst); 363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectGOTO_TARGET_END 365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectGOTO_TARGET(invokeStatic, bool methodCallRange) 367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vsrc1 = INST_AA(inst); /* AA (count) or BA (count + arg 5) */ 368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ref = FETCH(1); /* method ref */ 369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vdst = FETCH(2); /* 4 regs -or- first reg */ 370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project EXPORT_PC(); 372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (methodCallRange) 374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ILOGV("|invoke-static-range args=%d @0x%04x {regs=v%d-v%d}", 375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vsrc1, ref, vdst, vdst+vsrc1-1); 376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ILOGV("|invoke-static args=%d @0x%04x {regs=0x%04x %x}", 378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vsrc1 >> 4, ref, vdst, vsrc1 & 0x0f); 379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodToCall = dvmDexGetResolvedMethod(methodClassDex, ref); 381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (methodToCall == NULL) { 382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodToCall = dvmResolveMethod(curMethod->clazz, ref, METHOD_STATIC); 383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (methodToCall == NULL) { 384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ILOGV("+ unknown method\n"); 385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project GOTO_exceptionThrown(); 386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 387dd6e87095071e4e987910732062545f7303023e5Ben Cheng 388dd6e87095071e4e987910732062545f7303023e5Ben Cheng /* 389dd6e87095071e4e987910732062545f7303023e5Ben Cheng * The JIT needs dvmDexGetResolvedMethod() to return non-null. 390dd6e87095071e4e987910732062545f7303023e5Ben Cheng * Since we use the portable interpreter to build the trace, this extra 391dd6e87095071e4e987910732062545f7303023e5Ben Cheng * check is not needed for mterp. 392dd6e87095071e4e987910732062545f7303023e5Ben Cheng */ 393dd6e87095071e4e987910732062545f7303023e5Ben Cheng if (dvmDexGetResolvedMethod(methodClassDex, ref) == NULL) { 394dd6e87095071e4e987910732062545f7303023e5Ben Cheng /* Class initialization is still ongoing */ 395dd6e87095071e4e987910732062545f7303023e5Ben Cheng ABORT_JIT_TSELECT(); 396dd6e87095071e4e987910732062545f7303023e5Ben Cheng } 397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project GOTO_invokeMethod(methodCallRange, methodToCall, vsrc1, vdst); 399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectGOTO_TARGET_END 400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectGOTO_TARGET(invokeVirtualQuick, bool methodCallRange) 402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* thisPtr; 404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project EXPORT_PC(); 406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vsrc1 = INST_AA(inst); /* AA (count) or BA (count + arg 5) */ 408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ref = FETCH(1); /* vtable index */ 409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vdst = FETCH(2); /* 4 regs -or- first reg */ 410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The object against which we are executing a method is always 413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * in the first argument. 414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (methodCallRange) { 416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(vsrc1 > 0); 417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ILOGV("|invoke-virtual-quick-range args=%d @0x%04x {regs=v%d-v%d}", 418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vsrc1, ref, vdst, vdst+vsrc1-1); 419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project thisPtr = (Object*) GET_REGISTER(vdst); 420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert((vsrc1>>4) > 0); 422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ILOGV("|invoke-virtual-quick args=%d @0x%04x {regs=0x%04x %x}", 423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vsrc1 >> 4, ref, vdst, vsrc1 & 0x0f); 424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project thisPtr = (Object*) GET_REGISTER(vdst & 0x0f); 425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!checkForNull(thisPtr)) 428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project GOTO_exceptionThrown(); 429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4307a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng#if defined(WITH_JIT) && (INTERP_TYPE == INTERP_DBG) 4317a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng callsiteClass = thisPtr->clazz; 4327a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng#endif 4337a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng 434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Combine the object we found with the vtable offset in the 436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * method. 437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(ref < thisPtr->clazz->vtableCount); 439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodToCall = thisPtr->clazz->vtable[ref]; 440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0 442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmIsAbstractMethod(methodToCall)) { 443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmThrowException("Ljava/lang/AbstractMethodError;", 444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "abstract method not implemented"); 445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project GOTO_exceptionThrown(); 446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#else 448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(!dvmIsAbstractMethod(methodToCall) || 449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodToCall->nativeFunc != NULL); 450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGVV("+++ virtual[%d]=%s.%s\n", 453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ref, methodToCall->clazz->descriptor, methodToCall->name); 454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(methodToCall != NULL); 455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project GOTO_invokeMethod(methodCallRange, methodToCall, vsrc1, vdst); 457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectGOTO_TARGET_END 459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectGOTO_TARGET(invokeSuperQuick, bool methodCallRange) 461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u2 thisReg; 463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project EXPORT_PC(); 465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vsrc1 = INST_AA(inst); /* AA (count) or BA (count + arg 5) */ 467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ref = FETCH(1); /* vtable index */ 468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vdst = FETCH(2); /* 4 regs -or- first reg */ 469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (methodCallRange) { 471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ILOGV("|invoke-super-quick-range args=%d @0x%04x {regs=v%d-v%d}", 472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vsrc1, ref, vdst, vdst+vsrc1-1); 473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project thisReg = vdst; 474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ILOGV("|invoke-super-quick args=%d @0x%04x {regs=0x%04x %x}", 476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vsrc1 >> 4, ref, vdst, vsrc1 & 0x0f); 477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project thisReg = vdst & 0x0f; 478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* impossible in well-formed code, but we must check nevertheless */ 480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!checkForNull((Object*) GET_REGISTER(thisReg))) 481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project GOTO_exceptionThrown(); 482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0 /* impossible in optimized + verified code */ 484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ref >= curMethod->clazz->super->vtableCount) { 485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmThrowException("Ljava/lang/NoSuchMethodError;", NULL); 486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project GOTO_exceptionThrown(); 487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#else 489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(ref < curMethod->clazz->super->vtableCount); 490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Combine the object we found with the vtable offset in the 494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * method's class. 495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We're using the current method's class' superclass, not the 497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * superclass of "this". This is because we might be executing 498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * in a method inherited from a superclass, and we want to run 499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * in the method's class' superclass. 500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodToCall = curMethod->clazz->super->vtable[ref]; 502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0 504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmIsAbstractMethod(methodToCall)) { 505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmThrowException("Ljava/lang/AbstractMethodError;", 506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "abstract method not implemented"); 507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project GOTO_exceptionThrown(); 508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#else 510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(!dvmIsAbstractMethod(methodToCall) || 511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodToCall->nativeFunc != NULL); 512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGVV("+++ super-virtual[%d]=%s.%s\n", 514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ref, methodToCall->clazz->descriptor, methodToCall->name); 515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(methodToCall != NULL); 516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project GOTO_invokeMethod(methodCallRange, methodToCall, vsrc1, vdst); 518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectGOTO_TARGET_END 520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * General handling for return-void, return, and return-wide. Put the 524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * return value in "retval" before jumping here. 525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectGOTO_TARGET(returnFromMethod) 527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StackSaveArea* saveArea; 529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We must do this BEFORE we pop the previous stack frame off, so 532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * that the GC can see the return value (if any) in the local vars. 533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Since this is now an interpreter switch point, we must do it before 535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * we do anything at all. 536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project PERIODIC_CHECKS(kInterpEntryReturn, 0); 538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ILOGV("> retval=0x%llx (leaving %s.%s %s)", 540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project retval.j, curMethod->clazz->descriptor, curMethod->name, 54185745e148153894aac52ad3d7f6a36a7767b45a0Mike Lockwood curMethod->shorty); 542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //DUMP_REGS(curMethod, fp); 543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project saveArea = SAVEAREA_FROM_FP(fp); 545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifdef EASY_GDB 547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project debugSaveArea = saveArea; 548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 5490d615c3ce5bf97ae65b9347ee77968f38620d5e8Andy McFadden#if (INTERP_TYPE == INTERP_DBG) 550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TRACE_METHOD_EXIT(self, curMethod); 551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* back up to previous frame and see if we hit a break */ 554fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro fp = (u4*)saveArea->prevFrame; 555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(fp != NULL); 556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmIsBreakFrame(fp)) { 557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* bail without popping the method frame from stack */ 558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGVV("+++ returned into break frame\n"); 559d726991ba52466cde88e37aba4de2395b62477faBill Buzbee#if defined(WITH_JIT) 560d726991ba52466cde88e37aba4de2395b62477faBill Buzbee /* Let the Jit know the return is terminating normally */ 561fc075c2d1ae63c26f96e0c6eeb72efc898dbebbfBen Cheng CHECK_JIT_VOID(); 562d726991ba52466cde88e37aba4de2395b62477faBill Buzbee#endif 563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project GOTO_bail(); 564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* update thread FP, and reset local variables */ 567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project self->curFrame = fp; 568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project curMethod = SAVEAREA_FROM_FP(fp)->method; 569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //methodClass = curMethod->clazz; 570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodClassDex = curMethod->clazz->pDvmDex; 571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pc = saveArea->savedPc; 572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ILOGD("> (return to %s.%s %s)", curMethod->clazz->descriptor, 57385745e148153894aac52ad3d7f6a36a7767b45a0Mike Lockwood curMethod->name, curMethod->shorty); 574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* use FINISH on the caller's invoke instruction */ 576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //u2 invokeInstr = INST_INST(FETCH(0)); 577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (true /*invokeInstr >= OP_INVOKE_VIRTUAL && 578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project invokeInstr <= OP_INVOKE_INTERFACE*/) 579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project FINISH(3); 581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //LOGE("Unknown invoke instr %02x at %d\n", 583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // invokeInstr, (int) (pc - curMethod->insns)); 584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(false); 585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectGOTO_TARGET_END 588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Jump here when the code throws an exception. 592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * By the time we get here, the Throwable has been created and the stack 594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * trace has been saved off. 595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectGOTO_TARGET(exceptionThrown) 597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object* exception; 599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int catchRelPc; 600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Since this is now an interpreter switch point, we must do it before 603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * we do anything at all. 604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project PERIODIC_CHECKS(kInterpEntryThrow, 0); 606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 60779d173cad420b2ef99a09688e603df7ea4f890e9Ben Cheng#if defined(WITH_JIT) 60879d173cad420b2ef99a09688e603df7ea4f890e9Ben Cheng // Something threw during trace selection - abort the current trace 6095540f6e420ffab7bb0c39dc508bdc3a2e0d67507Bill Buzbee ABORT_JIT_TSELECT(); 61079d173cad420b2ef99a09688e603df7ea4f890e9Ben Cheng#endif 611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We save off the exception and clear the exception status. While 613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * processing the exception we might need to load some Throwable 614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * classes, and we don't want class loader exceptions to get 615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * confused with this one. 616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(dvmCheckException(self)); 618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project exception = dvmGetException(self); 619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmAddTrackedAlloc(exception, self); 620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmClearException(self); 621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV("Handling exception %s at %s:%d\n", 623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project exception->clazz->descriptor, curMethod->name, 624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmLineNumFromPC(curMethod, pc - curMethod->insns)); 625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 6260d615c3ce5bf97ae65b9347ee77968f38620d5e8Andy McFadden#if (INTERP_TYPE == INTERP_DBG) 627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Tell the debugger about it. 629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * TODO: if the exception was thrown by interpreted code, control 631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * fell through native, and then back to us, we will report the 632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * exception at the point of the throw and again here. We can avoid 633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * this by not reporting exceptions when we jump here directly from 634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the native call code above, but then we won't report exceptions 635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * that were thrown *from* the JNI code (as opposed to *through* it). 636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The correct solution is probably to ignore from-native exceptions 638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * here, and have the JNI exception code do the reporting to the 639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * debugger. 640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gDvm.debuggerActive) { 642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project void* catchFrame; 643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project catchRelPc = dvmFindCatchBlock(self, pc - curMethod->insns, 644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project exception, true, &catchFrame); 645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDbgPostException(fp, pc - curMethod->insns, catchFrame, 646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project catchRelPc, exception); 647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We need to unroll to the catch block or the nearest "break" 652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * frame. 653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * A break frame could indicate that we have reached an intermediate 655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * native call, or have gone off the top of the stack and the thread 656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * needs to exit. Either way, we return from here, leaving the 657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * exception raised. 658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If we do find a catch block, we want to transfer execution to 660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * that point. 6614fbba1f95b3e27bdc5f5572bb0420b5f928aa54eAndy McFadden * 6624fbba1f95b3e27bdc5f5572bb0420b5f928aa54eAndy McFadden * Note this can cause an exception while resolving classes in 6634fbba1f95b3e27bdc5f5572bb0420b5f928aa54eAndy McFadden * the "catch" blocks. 664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project catchRelPc = dvmFindCatchBlock(self, pc - curMethod->insns, 666fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro exception, false, (void**)(void*)&fp); 667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Restore the stack bounds after an overflow. This isn't going to 670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * be correct in all circumstances, e.g. if JNI code devours the 671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * exception this won't happen until some other exception gets 672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * thrown. If the code keeps pushing the stack bounds we'll end 673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * up aborting the VM. 674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Note we want to do this *after* the call to dvmFindCatchBlock, 676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * because that may need extra stack space to resolve exception 677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * classes (e.g. through a class loader). 6784fbba1f95b3e27bdc5f5572bb0420b5f928aa54eAndy McFadden * 6794fbba1f95b3e27bdc5f5572bb0420b5f928aa54eAndy McFadden * It's possible for the stack overflow handling to cause an 6804fbba1f95b3e27bdc5f5572bb0420b5f928aa54eAndy McFadden * exception (specifically, class resolution in a "catch" block 6814fbba1f95b3e27bdc5f5572bb0420b5f928aa54eAndy McFadden * during the call above), so we could see the thread's overflow 6824fbba1f95b3e27bdc5f5572bb0420b5f928aa54eAndy McFadden * flag raised but actually be running in a "nested" interpreter 6834fbba1f95b3e27bdc5f5572bb0420b5f928aa54eAndy McFadden * frame. We don't allow doubled-up StackOverflowErrors, so 6844fbba1f95b3e27bdc5f5572bb0420b5f928aa54eAndy McFadden * we can check for this by just looking at the exception type 6854fbba1f95b3e27bdc5f5572bb0420b5f928aa54eAndy McFadden * in the cleanup function. Also, we won't unroll past the SOE 6864fbba1f95b3e27bdc5f5572bb0420b5f928aa54eAndy McFadden * point because the more-recent exception will hit a break frame 6874fbba1f95b3e27bdc5f5572bb0420b5f928aa54eAndy McFadden * as it unrolls to here. 688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (self->stackOverflowed) 6904fbba1f95b3e27bdc5f5572bb0420b5f928aa54eAndy McFadden dvmCleanupStackOverflow(self, exception); 691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (catchRelPc < 0) { 693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* falling through to JNI code or off the bottom of the stack */ 694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if DVM_SHOW_EXCEPTION >= 2 695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGD("Exception %s from %s:%d not caught locally\n", 696f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project exception->clazz->descriptor, dvmGetMethodSourceFile(curMethod), 697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmLineNumFromPC(curMethod, pc - curMethod->insns)); 698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 699f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmSetException(self, exception); 700f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmReleaseTrackedAlloc(exception, self); 701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project GOTO_bail(); 702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if DVM_SHOW_EXCEPTION >= 3 705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const Method* catchMethod = SAVEAREA_FROM_FP(fp)->method; 707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGD("Exception %s thrown from %s:%d to %s:%d\n", 708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project exception->clazz->descriptor, dvmGetMethodSourceFile(curMethod), 709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmLineNumFromPC(curMethod, pc - curMethod->insns), 710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmGetMethodSourceFile(catchMethod), 711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmLineNumFromPC(catchMethod, catchRelPc)); 712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 716f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Adjust local variables to match self->curFrame and the 717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * updated PC. 718f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //fp = (u4*) self->curFrame; 720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project curMethod = SAVEAREA_FROM_FP(fp)->method; 721f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //methodClass = curMethod->clazz; 722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodClassDex = curMethod->clazz->pDvmDex; 723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pc = curMethod->insns + catchRelPc; 724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ILOGV("> pc <-- %s.%s %s", curMethod->clazz->descriptor, 72585745e148153894aac52ad3d7f6a36a7767b45a0Mike Lockwood curMethod->name, curMethod->shorty); 726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DUMP_REGS(curMethod, fp, false); // show all regs 727f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Restore the exception if the handler wants it. 730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The Dalvik spec mandates that, if an exception handler wants to 732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * do something with the exception, the first instruction executed 733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * must be "move-exception". We can pass the exception along 734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * through the thread struct, and let the move-exception instruction 735f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * clear it for us. 736f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If the handler doesn't call move-exception, we don't want to 738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * finish here with an exception still pending. 739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (INST_INST(FETCH(0)) == OP_MOVE_EXCEPTION) 741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmSetException(self, exception); 742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmReleaseTrackedAlloc(exception, self); 744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project FINISH(0); 745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 746f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectGOTO_TARGET_END 747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 748f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 7498afa9dfe04354e5b3917e31e3e2772885f507580Elliott Hughes 750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 751f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * General handling for invoke-{virtual,super,direct,static,interface}, 752f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * including "quick" variants. 753f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 754f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Set "methodToCall" to the Method we're calling, and "methodCallRange" 755f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * depending on whether this is a "/range" instruction. 756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 757f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * For a range call: 758f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "vsrc1" holds the argument count (8 bits) 759f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "vdst" holds the first argument in the range 760f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * For a non-range call: 761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "vsrc1" holds the argument count (4 bits) and the 5th argument index 762f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "vdst" holds four 4-bit register indices 763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The caller must EXPORT_PC before jumping here, because any method 765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * call can throw a stack overflow exception. 766f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 767f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectGOTO_TARGET(invokeMethod, bool methodCallRange, const Method* _methodToCall, 768f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u2 count, u2 regs) 769f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 770f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project STUB_HACK(vsrc1 = count; vdst = regs; methodToCall = _methodToCall;); 771f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 772f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //printf("range=%d call=%p count=%d regs=0x%04x\n", 773f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // methodCallRange, methodToCall, count, regs); 774f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //printf(" --> %s.%s %s\n", methodToCall->clazz->descriptor, 77585745e148153894aac52ad3d7f6a36a7767b45a0Mike Lockwood // methodToCall->name, methodToCall->shorty); 776f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 777f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4* outs; 778f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i; 779f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 780f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 781f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copy args. This may corrupt vsrc1/vdst. 782f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 783f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (methodCallRange) { 784f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // could use memcpy or a "Duff's device"; most functions have 785f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // so few args it won't matter much 786f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(vsrc1 <= curMethod->outsSize); 787f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(vsrc1 == methodToCall->insSize); 788f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project outs = OUTS_FROM_FP(fp, vsrc1); 789f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < vsrc1; i++) 790f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project outs[i] = GET_REGISTER(vdst+i); 791f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 792f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4 count = vsrc1 >> 4; 793f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 794f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(count <= curMethod->outsSize); 795f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(count == methodToCall->insSize); 796f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(count <= 5); 797f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 798f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project outs = OUTS_FROM_FP(fp, count); 799f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0 800f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (count == 5) { 801f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project outs[4] = GET_REGISTER(vsrc1 & 0x0f); 802f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project count--; 803f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 804f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < (int) count; i++) { 805f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project outs[i] = GET_REGISTER(vdst & 0x0f); 806f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project vdst >>= 4; 807f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 808f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#else 809f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // This version executes fewer instructions but is larger 810f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // overall. Seems to be a teensy bit faster. 811f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert((vdst >> 16) == 0); // 16 bits -or- high 16 bits clear 812f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (count) { 813f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 5: 814f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project outs[4] = GET_REGISTER(vsrc1 & 0x0f); 815f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 4: 816f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project outs[3] = GET_REGISTER(vdst >> 12); 817f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 3: 818f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project outs[2] = GET_REGISTER((vdst & 0x0f00) >> 8); 819f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 2: 820f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project outs[1] = GET_REGISTER((vdst & 0x00f0) >> 4); 821f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 1: 822f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project outs[0] = GET_REGISTER(vdst & 0x0f); 823f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 824f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ; 825f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 826f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 827f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 828f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 829f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 830f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 831f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (This was originally a "goto" target; I've kept it separate from the 832f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * stuff above in case we want to refactor things again.) 833f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 834f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * At this point, we have the arguments stored in the "outs" area of 835f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the current method's stack frame, and the method to call in 836f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "methodToCall". Push a new stack frame. 837f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 838f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 839f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StackSaveArea* newSaveArea; 840f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u4* newFp; 841f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 842f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ILOGV("> %s%s.%s %s", 843f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmIsNativeMethod(methodToCall) ? "(NATIVE) " : "", 844f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodToCall->clazz->descriptor, methodToCall->name, 84585745e148153894aac52ad3d7f6a36a7767b45a0Mike Lockwood methodToCall->shorty); 846f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 847f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project newFp = (u4*) SAVEAREA_FROM_FP(fp) - methodToCall->registersSize; 848f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project newSaveArea = SAVEAREA_FROM_FP(newFp); 849f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 850f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* verify that we have enough space */ 851f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (true) { 852f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u1* bottom; 853f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bottom = (u1*) newSaveArea - methodToCall->outsSize * sizeof(u4); 854f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (bottom < self->interpStackEnd) { 855f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* stack overflow */ 8566ed1a0f396a1857c31b486d3e93ee2dbeb49a6cdAndy McFadden LOGV("Stack overflow on method call (start=%p end=%p newBot=%p(%d) size=%d '%s')\n", 857f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project self->interpStackStart, self->interpStackEnd, bottom, 8586ed1a0f396a1857c31b486d3e93ee2dbeb49a6cdAndy McFadden (u1*) fp - bottom, self->interpStackSize, 8596ed1a0f396a1857c31b486d3e93ee2dbeb49a6cdAndy McFadden methodToCall->name); 8606ed1a0f396a1857c31b486d3e93ee2dbeb49a6cdAndy McFadden dvmHandleStackOverflow(self, methodToCall); 861f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(dvmCheckException(self)); 862f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project GOTO_exceptionThrown(); 863f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 864f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //LOGD("+++ fp=%p newFp=%p newSave=%p bottom=%p\n", 865f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // fp, newFp, newSaveArea, bottom); 866f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 867f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 868f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifdef LOG_INSTR 869f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (methodToCall->registersSize > methodToCall->insSize) { 870f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 871f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This makes valgrind quiet when we print registers that 872f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * haven't been initialized. Turn it off when the debug 873f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * messages are disabled -- we want valgrind to report any 874f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * used-before-initialized issues. 875f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 876f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memset(newFp, 0xcc, 877f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (methodToCall->registersSize - methodToCall->insSize) * 4); 878f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 879f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 880f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 881f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifdef EASY_GDB 882f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project newSaveArea->prevSave = SAVEAREA_FROM_FP(fp); 883f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 884f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project newSaveArea->prevFrame = fp; 885f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project newSaveArea->savedPc = pc; 886ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng#if defined(WITH_JIT) 887ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng newSaveArea->returnAddr = 0; 888ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng#endif 889f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project newSaveArea->method = methodToCall; 890f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 891f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmIsNativeMethod(methodToCall)) { 892f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 893f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "Call" interpreted code. Reposition the PC, update the 894f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * frame pointer and other local state, and continue. 895f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 896f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project curMethod = methodToCall; 897f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodClassDex = curMethod->clazz->pDvmDex; 898f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pc = methodToCall->insns; 899fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro self->curFrame = fp = newFp; 900f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifdef EASY_GDB 901f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project debugSaveArea = SAVEAREA_FROM_FP(newFp); 902f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 903f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if INTERP_TYPE == INTERP_DBG 904f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project debugIsMethodEntry = true; // profiling, debugging 905f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 906f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ILOGD("> pc <-- %s.%s %s", curMethod->clazz->descriptor, 90785745e148153894aac52ad3d7f6a36a7767b45a0Mike Lockwood curMethod->name, curMethod->shorty); 908f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DUMP_REGS(curMethod, fp, true); // show input args 909f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project FINISH(0); // jump to method start 910f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 911f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* set this up for JNI locals, even if not a JNI native */ 912d5ab726b65d7271be261864c7e224fb90bfe06e0Andy McFadden#ifdef USE_INDIRECT_REF 913d5ab726b65d7271be261864c7e224fb90bfe06e0Andy McFadden newSaveArea->xtra.localRefCookie = self->jniLocalRefTable.segmentState.all; 914d5ab726b65d7271be261864c7e224fb90bfe06e0Andy McFadden#else 915d5ab726b65d7271be261864c7e224fb90bfe06e0Andy McFadden newSaveArea->xtra.localRefCookie = self->jniLocalRefTable.nextEntry; 916d5ab726b65d7271be261864c7e224fb90bfe06e0Andy McFadden#endif 917f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 918f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project self->curFrame = newFp; 919f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 920f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DUMP_REGS(methodToCall, newFp, true); // show input args 921f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 9220d615c3ce5bf97ae65b9347ee77968f38620d5e8Andy McFadden#if (INTERP_TYPE == INTERP_DBG) 923f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gDvm.debuggerActive) { 924f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDbgPostLocationEvent(methodToCall, -1, 925f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmGetThisPtr(curMethod, fp), DBG_METHOD_ENTRY); 926f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 927f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 9280d615c3ce5bf97ae65b9347ee77968f38620d5e8Andy McFadden#if (INTERP_TYPE == INTERP_DBG) 929f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TRACE_METHOD_ENTER(self, methodToCall); 930f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 931f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 9328afa9dfe04354e5b3917e31e3e2772885f507580Elliott Hughes { 9338afa9dfe04354e5b3917e31e3e2772885f507580Elliott Hughes ILOGD("> native <-- %s.%s %s", methodToCall->clazz->descriptor, 9348afa9dfe04354e5b3917e31e3e2772885f507580Elliott Hughes methodToCall->name, methodToCall->shorty); 9358afa9dfe04354e5b3917e31e3e2772885f507580Elliott Hughes } 936f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 937d726991ba52466cde88e37aba4de2395b62477faBill Buzbee#if defined(WITH_JIT) 938d726991ba52466cde88e37aba4de2395b62477faBill Buzbee /* Allow the Jit to end any pending trace building */ 939fc075c2d1ae63c26f96e0c6eeb72efc898dbebbfBen Cheng CHECK_JIT_VOID(); 940d726991ba52466cde88e37aba4de2395b62477faBill Buzbee#endif 941d726991ba52466cde88e37aba4de2395b62477faBill Buzbee 942f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 943f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Jump through native call bridge. Because we leave no 944f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * space for locals on native calls, "newFp" points directly 945f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to the method arguments. 946f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 947f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (*methodToCall->nativeFunc)(newFp, &retval, methodToCall, self); 948f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 9490d615c3ce5bf97ae65b9347ee77968f38620d5e8Andy McFadden#if (INTERP_TYPE == INTERP_DBG) 950f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gDvm.debuggerActive) { 951f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDbgPostLocationEvent(methodToCall, -1, 952f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmGetThisPtr(curMethod, fp), DBG_METHOD_EXIT); 953f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 954f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 9550d615c3ce5bf97ae65b9347ee77968f38620d5e8Andy McFadden#if (INTERP_TYPE == INTERP_DBG) 956f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TRACE_METHOD_EXIT(self, methodToCall); 957f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 958f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 959f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* pop frame off */ 960f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmPopJniLocals(self, newSaveArea); 961f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project self->curFrame = fp; 962f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 963f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 964f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If the native code threw an exception, or interpreted code 965f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * invoked by the native call threw one and nobody has cleared 966f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * it, jump to our local exception handling. 967f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 968f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmCheckException(self)) { 969f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV("Exception thrown by/below native code\n"); 970f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project GOTO_exceptionThrown(); 971f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 972f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 973f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ILOGD("> retval=0x%llx (leaving native)", retval.j); 974f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ILOGD("> (return from native %s.%s to %s.%s %s)", 975f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodToCall->clazz->descriptor, methodToCall->name, 976f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project curMethod->clazz->descriptor, curMethod->name, 97785745e148153894aac52ad3d7f6a36a7767b45a0Mike Lockwood curMethod->shorty); 978f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 979f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //u2 invokeInstr = INST_INST(FETCH(0)); 980f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (true /*invokeInstr >= OP_INVOKE_VIRTUAL && 981f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project invokeInstr <= OP_INVOKE_INTERFACE*/) 982f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 983f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project FINISH(3); 984f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 985f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //LOGE("Unknown invoke instr %02x at %d\n", 986f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // invokeInstr, (int) (pc - curMethod->insns)); 987f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(false); 988f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 989f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 990f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 991f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(false); // should not get here 992f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectGOTO_TARGET_END 993