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