📄 stackmap.c
字号:
/*0290*/ BIT_SET(stackSize);
/*0291*/ stackSize--;
/*0292*/ goto pushDouble;
/*0293*/
/*0294*/ /* These pop two items off the stack */
/*0295*/ case IF_ICMPEQ: case IF_ICMPNE: case IF_ICMPLT: case IF_ICMPGE:
/*0296*/ case IF_ICMPGT: case IF_ICMPLE: case IF_ACMPEQ: case IF_ACMPNE:
/*0297*/ case PUTFIELD_FAST:
/*0298*/ case PUTSTATIC2_FAST:
/*0299*/ thisIP += 2;
/*0300*/ case POP2:
/*0301*/ case LADD: case DADD: case LSUB: case DSUB: case LMUL: case DMUL:
/*0302*/ case LDIV: case DDIV: case LREM: case DREM:
/*0303*/ case LAND: case LOR: case LXOR:
/*0304*/ stackSize -= 2;
/*0305*/ break;
/*0306*/
/*0307*/ /* These pop two items off, and then push non-pointer */
/*0308*/ case IALOAD: case FALOAD: case BALOAD: case CALOAD: case SALOAD:
/*0309*/ stackSize -= 2;
/*0310*/ goto pushInt;
/*0311*/
/*0312*/ /* These pop two items off, and then push two non pointers */
/*0313*/ case DALOAD: case LALOAD:
/*0314*/ stackSize -= 2;
/*0315*/ goto pushDouble;
/*0316*/
/*0317*/ /* These pop three items off the stack. */
/*0318*/ case PUTFIELD2_FAST:
/*0319*/ thisIP += 2;
/*0320*/ case IASTORE: case FASTORE: case AASTORE: case BASTORE:
/*0321*/ case CASTORE: case SASTORE:
/*0322*/ case LCMP: case DCMPL: case DCMPG:
/*0323*/ stackSize -= 3;
/*0324*/ break;
/*0325*/
/*0326*/ /* These pop four items off the stack. */
/*0327*/ case LASTORE:
/*0328*/ case DASTORE:
/*0329*/ stackSize -= 4;
/*0330*/ break;
/*0331*/
/*0332*/ /* These either load a pointer or an integer */
/*0333*/ case LDC:
/*0334*/ index = *thisIP++;
/*0335*/ goto handleLoadConstant;
/*0336*/ case LDC_W:
/*0337*/ index = getUShort(thisIP);
/*0338*/ thisIP += 2;
/*0339*/ handleLoadConstant:
/*0340*/ if (CONSTANTPOOL_TAG(cp, index) == CONSTANT_String) {
/*0341*/ goto pushPointer;
/*0342*/ } else {
/*0343*/ goto pushInt;
/*0344*/ }
/*0345*/
/*0346*/ /* These involve doing bit twiddling */
/*0347*/ case DUP:
/*0348*/ getBits(map, stackSize - 1, 1, dupValues);
/*0349*/ if (dupValues[0]) {
/*0350*/ goto pushPointer;
/*0351*/ } else {
/*0352*/ goto pushInt;
/*0353*/ }
/*0354*/
/*0355*/ case DUP_X1:
/*0356*/ getBits(map, stackSize - 2, 2, dupValues + 1);
/*0357*/ dupValues[0] = dupValues[2];
/*0358*/ setBits(map, stackSize - 2, 3, dupValues);
/*0359*/ stackSize++;
/*0360*/ break;
/*0361*/
/*0362*/ case DUP_X2:
/*0363*/ getBits(map, stackSize - 3, 3, dupValues + 1);
/*0364*/ dupValues[0] = dupValues[3];
/*0365*/ setBits(map, stackSize - 3, 4, dupValues);
/*0366*/ stackSize++;
/*0367*/ break;
/*0368*/
/*0369*/
/*0370*/ case DUP2:
/*0371*/ getBits(map, stackSize - 2, 2, dupValues);
/*0372*/ setBits(map, stackSize, 2, dupValues);
/*0373*/ stackSize += 2;
/*0374*/ break;
/*0375*/
/*0376*/
/*0377*/ case DUP2_X1:
/*0378*/ getBits(map, stackSize - 3, 3, dupValues + 2);
/*0379*/ dupValues[0] = dupValues[3];
/*0380*/ dupValues[1] = dupValues[4];
/*0381*/ setBits(map, stackSize - 3, 5, dupValues);
/*0382*/ stackSize += 2;
/*0383*/ break;
/*0384*/
/*0385*/
/*0386*/ case DUP2_X2:
/*0387*/ getBits(map, stackSize - 4, 4, dupValues + 2);
/*0388*/ dupValues[0] = dupValues[4];
/*0389*/ dupValues[1] = dupValues[5];
/*0390*/ setBits(map, stackSize - 4, 6, dupValues);
/*0391*/ stackSize += 2;
/*0392*/ break;
/*0393*/
/*0394*/ case SWAP:
/*0395*/ getBits(map, stackSize - 2, 2, dupValues + 1);
/*0396*/ dupValues[0] = dupValues[2];
/*0397*/ setBits(map, stackSize - 2, 2, dupValues);
/*0398*/ break;
/*0399*/
/*0400*/ /* Get a field. We don't know what type of object we
/*0401./ * are getting.
/*0402./ */
/*0403*/ case GETFIELD:
/*0404*/ /* Remove the pointer to the object */
/*0405*/ stackSize -= 1;
/*0406*/ case GETSTATIC:
/*0407*/ index = getUShort(thisIP);
/*0408*/ thisIP += 2;
/*0409*/ field = (FIELD)cp->entries[index].cache;
/*0422*/ /* Determine what needs to be pushed onto the stack,
/*0423./ * on the basis of the flags in the field */
/*0424*/ if (field->accessFlags & ACC_POINTER) {
/*0425*/ goto pushPointer;
/*0426*/ } else if (field->accessFlags & ACC_DOUBLE) {
/*0427*/ goto pushDouble;
/*0428*/ } else {
/*0429*/ goto pushInt;
/*0430*/ }
/*0431*/
/*0432*/ /* Set a field value from the stack */
/*0433*/ case PUTFIELD:
/*0434*/ /* Remove the pointer to the object */
/*0435*/ stackSize -= 1;
/*0436*/ case PUTSTATIC:
/*0437*/ index = getUShort(thisIP);
/*0438*/ thisIP += 2;
/*0439*/ field = (FIELD)cp->entries[index].cache;
/*0451*/ /* We are either removing a single word or two words. We
/*0452./ * don't care if it is a pointer or not.
/*0453./ */
/*0454*/ stackSize -= (field->accessFlags & ACC_DOUBLE) ? 2 : 1;
/*0455*/ break;
/*0456*/
/*0457*/
/*0458*/ /* We remove thisIP[2] dimensions, and then we push
/*0459./ * the result */
/*0460*/ case MULTIANEWARRAY:
/*0461*/ case MULTIANEWARRAY_FAST:
/*0462*/ stackSize -= thisIP[2];
/*0463*/ thisIP += 3;
/*0464*/ goto pushPointer;
/*0465*/
/*0466*/ case WIDE:
/*0467*/ token = *thisIP++;
/*0468*/ index = getUShort(thisIP); thisIP += 2;
/*0469*/ switch (token) {
/*0470*/ case ILOAD: case FLOAD:
/*0471*/ goto pushInt;
/*0472*/ case LLOAD: case DLOAD:
/*0473*/ goto pushDouble;
/*0474*/ case ALOAD:
/*0475*/ goto pushPointer;
/*0476*/ case LSTORE: case DSTORE:
/*0477*/ goto storeDouble;
/*0478*/ case ISTORE: case FSTORE:
/*0479*/ goto storeInt;
/*0480*/ case ASTORE:
/*0481*/ goto storePointer;
/*0482*/ case IINC:
/*0483*/ thisIP += 2; break;
/*0484*/ default: /* RET shouldn't happen! */
/*0485*/ fatalError(KVM_MSG_UNEXPECTED_BYTECODE);
/*0486*/ break;
/*0487*/ }
/*0488*/ break;
/*0489*/
/*0490*/#if ENABLEFASTBYTECODES
/*0491*/ case INVOKEVIRTUAL_FAST:
/*0492*/ case INVOKEINTERFACE_FAST:
/*0493*/ {
/*0494*/ unsigned int iCacheIndex = getUShort(thisIP);
/*0495*/ ICACHE thisICache = getInlineCache(iCacheIndex);
/*0496*/ method = (METHOD)thisICache->contents;
/*0497*/ thisIP += (token == INVOKEINTERFACE_FAST) ? 4 : 2;
/*0498*/ goto handleMethodCall;
/*0499*/ }
/*0500*/#endif
/*0501*/
/*0502*/#if ENABLEFASTBYTECODES
/*0503*/ case INVOKESPECIAL_FAST:
/*0504*/ case INVOKESTATIC_FAST:
/*0505*/#endif
/*0506*/ case INVOKEVIRTUAL:
/*0507*/ case INVOKESPECIAL:
/*0508*/ case INVOKESTATIC:
/*0509*/ case INVOKEINTERFACE: {
/*0510*/ unsigned int cpIndex = getUShort(thisIP);
/*0511*/ CONSTANTPOOL_ENTRY thisEntry = &cp->entries[cpIndex];
/*0512*/ thisIP += (token == INVOKEINTERFACE) ? 4 : 2;
/*0517*/ method = ((METHOD) thisEntry->cache);
/*0518*/ }
/*0519*/
/*0520*/#if ENABLEFASTBYTECODES
/*0521*/ handleMethodCall:
/*0522*/#endif
/*0529*/ /* Remove the arguments. */
/*0530*/ stackSize -= method->argCount;
/*0534*/ /* Push the return result */
/*0535*/ switch (method->accessFlags & (ACC_POINTER | ACC_DOUBLE)) {
/*0536*/ case ACC_DOUBLE:
/*0537*/ goto pushDouble;
/*0538*/ case 0: /* int */
/*0539*/ goto pushInt;
/*0540*/ case ACC_POINTER | ACC_DOUBLE: /* void */
/*0541*/ break;
/*0542*/ case ACC_POINTER:
/*0543*/ goto pushPointer;
/*0544*/ }
/*0545*/ break;
/*0546*/
/*0553*/ default:
/*0554*/ fatalError(KVM_MSG_UNEXPECTED_BYTECODE);
/*0555*/ }
/*0556*/
/*0557*/ if (stackSize < localsCount) {
/*0558*/ fatalError(KVM_MSG_ILLEGAL_STACK_SIZE);
/*0559*/ }
/*0560*/
/*0570*/ } /* end of while */
/*0571*/
/*0572*/ if (thisIP > targetIP) {
/*0573*/ fatalError(KVM_MSG_STRANGE_VALUE_OF_THISIP);
/*0574*/ }
/*0575*/
/*0576*/ return stackSize - localsCount;
/*0577*/}
/*0578*/
/*0579*//*=========================================================================
/*0580./ * FUNCTION: getInitialRegisterMask
/*0581./ * TYPE: Important GC function
/*0582./ * OVERVIEW: Returns a bitmap indicating the live size of the stack
/*0583./ * INTERFACE:
/*0584./ * parameters: thisMethod: The current method
/*0585./ * targetOffsetP: Pointer to offset into the method for which
/*0586./ * we want a stack map
/*0587./ * map Map to fill in with the stack map information.
/*0588./ *
/*0589./ * returns: The stack size. It also fills in *map and *targetOffsetP.
/*0590./ *
/*0591./ * This function will determine a stack map either for *targetOffsetP or for
/*0592./ * some offset before *targetOffsetP. It will update *targetOffsetP with the
/*0593./ * offset that it actually knows about.
/*0594./ *
/*0595./ * This function has two sources of knowing a stack map for a particular
/*0596./ * location.
/*0597./ * the method's stackmap field.
/*0598./ * the method's signature, if there is no stackmap, or all stackmaps
/*0599./ * are for an address after the current one.
/*0600./ *=======================================================================*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -