⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stackmap.c

📁 This is a java virtual machine implement in c
💻 C
📖 第 1 页 / 共 3 页
字号:
/*0601*/
/*0602*//* Helper functions. . . . */
/*0603*/
/*0604*/static void
/*0605*/getRegisterMaskFromMethodSignature(METHOD thisMethod, char *map);
/*0606*/
/*0607*/static unsigned int
/*0608*/getInitialRegisterMask(METHOD thisMethod,
/*0609*/                       unsigned int *targetOffsetP, char *map)
/*0610*/{
/*0611*/    unsigned int localsCount = thisMethod->frameSize; /* number of locals */
/*0612*/    unsigned int maxStack = thisMethod->u.java.maxStack;
/*0613*/    unsigned int targetOffset = *targetOffsetP;
/*0614*/    struct stackMapEntryStruct *firstFrame, *thisFrame, *lastFrame;
/*0615*/
/*0616*/    STACKMAP stackMaps = thisMethod->u.java.stackMaps.pointerMap;
/*0617*/
/*0618*/    /* Zero out the map to start with, so we only need to set
/*0619./     * appropriate bits    */
/*0620*/    memset(map, 0, (localsCount + maxStack + 7) >> 3);
/*0621*/
/*0622*/    if (stackMaps != NULL) {
/*0623*/        int entryCount = stackMaps->nEntries;
/*0624*/        int mask;
/*0625*/        if (entryCount & STACK_MAP_SHORT_ENTRY_FLAG) {
/*0626*/            entryCount &= STACK_MAP_ENTRY_COUNT_MASK;
/*0627*/            mask = STACK_MAP_SHORT_ENTRY_OFFSET_MASK;
/*0628*/        } else {
/*0629*/            mask = ~0;          /* Use whole word */
/*0630*/        }
/*0631*/
/*0632*/        /* Find the first stack map frame with an entry >>larger<< than
/*0633./         * the offset we are seeking */
/*0634*/        firstFrame = &stackMaps->entries[0];
/*0635*/        lastFrame = firstFrame + entryCount;
/*0636*/        for (thisFrame = firstFrame; ; thisFrame++) {
/*0637*/            if (thisFrame == lastFrame ||
/*0638*/                          targetOffset < (thisFrame->offset & mask)) {
/*0639*/                if (thisFrame == firstFrame) {
/*0640*/                    /* We're smaller than the first offset, so just fall
/*0641./                     * through to getting the frame from the signature */
/*0642*/                    break;
/*0643*/                }
/*0644*/                thisFrame -= 1;
/*0645*/                *targetOffsetP = thisFrame->offset & mask;
/*0646*/                if (mask == -1) {
/*0647*/                    int stackmapLength;
/*0648*/                    char *stackmap =
/*0649*/                        change_Key_to_Name(thisFrame->stackMapKey,
/*0650*/                                           &stackmapLength);
/*0651*/                    /* The first byte is the size of the stack.  The
/*0652./                       remaining bytes can just be copied over.
/*0653./                    */
/*0654*/                    memcpy(map, stackmap + 1, stackmapLength - 1);
/*0655*/                    return stackmap[0];
/*0656*/                } else {
/*0657*/                    memcpy(map, &thisFrame->stackMapKey, 2);
/*0658*/                    return thisFrame->offset >> 12;
/*0659*/                }
/*0660*/            }
/*0661*/        }
/*0662*/    }
/*0663*/
/*0664*/    /* Either no stack map, or else we are less than the first entry in
/*0665./     * the stackmap.  So we just get the assumed stack map from the
/*0666./     * signature and offset = 0.
/*0667./     */
/*0668*/    getRegisterMaskFromMethodSignature(thisMethod, map);
/*0669*/    *targetOffsetP = 0;
/*0670*/    return 0;           /* no stack */
/*0671*/}
/*0672*/
/*0673*/static void
/*0674*/getRegisterMaskFromMethodSignature(METHOD thisMethod, char *map)
/*0675*/{
/*0676*/    unsigned char *codedSignature = (unsigned char *)
/*0677*/        change_Key_to_Name(thisMethod->nameTypeKey.nt.typeKey, NULL);
/*0678*/    unsigned char *from = codedSignature;
/*0679*/    int localVar, argCount;
/*0680*/
/*0681*/    argCount = *from++;         /* the first byte is the arg count */
/*0682*/
/*0683*/    if (thisMethod->accessFlags & ACC_STATIC) {
/*0684*/        localVar = 0;
/*0685*/    } else {
/*0686*/        BIT_SET(0);
/*0687*/        localVar = 1;
/*0688*/    }
/*0689*/    for ( ; argCount > 0; argCount--) {
/*0690*/        unsigned char tag = *from++;
/*0691*/        if (tag == 'L') {
/*0692*/            BIT_SET(localVar);
/*0693*/            localVar++;
/*0694*/            from += 2;
/*0695*/        } else if (tag >= 'A' && tag <= 'Z') {
/*0696*/            localVar += (tag == 'D' || tag == 'J') ? 2 : 1;
/*0697*/        } else {
/*0698*/            BIT_SET(localVar);
/*0699*/            localVar++;
/*0700*/            from++;
/*0701*/        }
/*0702*/    }
/*0703*/}
/*0704*/
/*0705*//*=========================================================================
/*0706./ * FUNCTION:      rewriteVerifierStackMapsAsPointerMaps
/*0707./ * TYPE:          Important GC function
/*0708./ * OVERVIEW:      Converts the stack map from its "verifier" format
/*0709./ *                to its pointer map format.
/*0710./ * INTERFACE:
/*0711./ *   parameters:  thisMethod:    The current method
/*0712./ *
/*0713./ * This function converts the stack map from its verifier format (in which
/*0714./ * we need to know the type of every stack location and local variable) to
/*0715./ * pointer map format (in which we just need to know what's a pointer and
/*0716./ * what isn't).
/*0717./ *
/*0718./ * This transformation is performed as the last step of verifying a method.
/*0719./ *=======================================================================*/
/*0720*/
/*0721*/STACKMAP
/*0722*/rewriteVerifierStackMapsAsPointerMaps(METHOD thisMethod) {
/*0723*/    STACKMAP result;            /* Holds the result, to be stored in method */
/*0724*/    START_TEMPORARY_ROOTS
/*0725*/        DECLARE_TEMPORARY_ROOT(POINTERLIST, verifierStackMaps, 
/*0726*/                               thisMethod->u.java.stackMaps.verifierMap);
/*0727*/        unsigned int localsCount = thisMethod->frameSize;
/*0728*/        unsigned int maxStack = thisMethod->u.java.maxStack;
/*0729*/        long stackMapCount = verifierStackMaps->length;
/*0730*/        long stackMapIndex, i;
/*0731*/        bool_t useLongFormat;
/*0732*/        char tempSpace[8];          /* Almost always enough space */
/*0733*/        char *map = tempSpace;
/*0734*/
/*0735*/        unsigned int maxMapLength;
/*0736*/
/*0737*/        int resultSize = sizeof(struct stackMapStruct) +  
/*0738*/            (stackMapCount - 1) * sizeof(struct stackMapEntryStruct);
/*0739*/
/*0740*/        result = 
/*0741*/            (STACKMAP)callocPermanentObject(ByteSizeToCellSize(resultSize));
/*0742*/        useLongFormat = FALSE;
/*0743*/        for (stackMapIndex = 0; stackMapIndex < stackMapCount; stackMapIndex++){
/*0744*/            short *verifierStackMap =
/*0745*/                (short *)verifierStackMaps->data[stackMapIndex].cellp;
/*0746*/            unsigned short registers = verifierStackMap[0];
/*0747*/            unsigned short stackSize = verifierStackMap[registers + 1];
/*0748*/            unsigned short offset =
/*0749*/                   verifierStackMaps->data[stackMapIndex + stackMapCount].cell;
/*0750*/
/*0751*/            if (stackSize > STACK_MAP_SHORT_ENTRY_MAX_STACK_SIZE
/*0752*/                || offset > STACK_MAP_SHORT_ENTRY_MAX_OFFSET
/*0753*/                || (stackSize + localsCount) > 16) {
/*0754*/                   useLongFormat = TRUE;
/*0755*/                   break;
/*0756*/            }
/*0757*/        }
/*0758*/
/*0759*/        if (useLongFormat) {
/*0760*/            result->nEntries = (unsigned short)stackMapCount;
/*0761*/            maxMapLength = (localsCount + maxStack + 7 + 8) >> 3;
/*0762*/            if (maxMapLength > sizeof(tempSpace)) {
/*0763*/                IS_TEMPORARY_ROOT(map, mallocBytes(maxMapLength));
/*0764*/            }
/*0765*/
/*0766*/        } else {
/*0767*/            result->nEntries = (unsigned short)stackMapCount 
/*0768*/                             | STACK_MAP_SHORT_ENTRY_FLAG;
/*0769*/            maxMapLength = 4;   /* actually, 3 */
/*0770*/        }
/*0771*/
/*0772*/        for (stackMapIndex = 0; stackMapIndex < stackMapCount; stackMapIndex++){
/*0773*/            short *verifierStackMap =
/*0774*/                   (short *)verifierStackMaps->data[stackMapIndex].cellp;
/*0775*/            unsigned short offset = (unsigned short)
/*0776*/                 verifierStackMaps->data[stackMapIndex + stackMapCount].cell;
/*0777*/            unsigned short registers, stackSize;
/*0778*/
/*0779*/            /* This isn't a duplicate.  So calculate the stack map. */
/*0780*/            memset(map, 0, maxMapLength);
/*0781*/
/*0782*/            /* Read the registers and the stack */
/*0783*/            registers = *verifierStackMap++; /* number of registers */
/*0784*/            for (i = 0; i < registers; i++) {
/*0785*/                unsigned short type = *verifierStackMap++;
/*0786*/                if (type > 255 || type == ITEM_InitObject) {
/*0787*/                    BIT_SET(8 + i);
/*0788*/                }
/*0789*/            }
/*0790*/            stackSize = *verifierStackMap++;
/*0791*/            for (i = 0; i < stackSize; i++) {
/*0792*/                unsigned short type = *verifierStackMap++;
/*0793*/                if (type > 255 || type == ITEM_InitObject) {
/*0794*/                    BIT_SET(8 + i + localsCount);
/*0795*/                }
/*0796*/            }
/*0797*/
/*0798*/            result->entries[stackMapIndex].offset = offset;
/*0799*/            if (useLongFormat) { 
/*0800*/                map[0] = stackSize;
/*0801*/                /* We can delete all the zero words at the end, as long as we
/*0802./                 * save at least one word at the end. 
/*0803./                 */
/*0804*/                for (i = maxMapLength - 1; i > 0; i--) {
/*0805*/                    if (map[i]) break;
/*0806*/                }
/*0807*/                /* Fill in the key */
/*0808*/                result->entries[stackMapIndex].stackMapKey =
/*0809*/                    change_Name_to_Key((CONST_CHAR_HANDLE)&map, 0, i+1);
/*0810*/            } else { 
/*0811*/                result->entries[stackMapIndex].offset = 
/*0812*/                    offset + (stackSize << 12);
/*0813*/                memcpy(&result->entries[stackMapIndex].stackMapKey, map+1, 2);
/*0814*/            }
/*0815*/         }
/*0816*/     END_TEMPORARY_ROOTS
/*0817*/     return result;
/*0818*/}
/*0819*/
/*0820*//*=========================================================================
/*0821./ * FUNCTION:      getBits, setbits
/*0822./ * TYPE:          private stack map operations
/*0823./ * OVERVIEW:      Sets/Gets zero or more bits in a bit map
/*0824./ * INTERFACE:
/*0825./ *   parameters:  map:    A table of bits
/*0826./ *                bit:    The starting index of bits to set
/*0827./ *                count:  The number of bits to change
/*0828./ *                result/values: Array of bytes.  For getBits, the result
/*0829./ *                    is placed into the array.  For setBits, it's the
/*0830./ *                    value(s) to be put into the bitmap.  Non-zero = TRUE
/*0831./ *=======================================================================*/
/*0832*/
/*0833*/static void
/*0834*/getBits(char *map, unsigned int bit, unsigned int count, unsigned char *result)
/*0835*/{
/*0836*/    int i;
/*0837*/    for (i = 0; i < count; i++, bit++) {
/*0838*/        int offset = bit >> 3;
/*0839*/        int mask = (((unsigned)1) << (bit & 7));
/*0840*/        result[i] = map[offset] & mask;
/*0841*/    }
/*0842*/}
/*0843*/
/*0844*/static void
/*0845*/setBits(char *map, unsigned int bit, unsigned int count, unsigned char *values)
/*0846*/{
/*0847*/    int i;
/*0848*/    for (i = 0; i < count; i++, bit++) {
/*0849*/        int offset = bit >> 3;
/*0850*/        int mask = (((unsigned)1) << (bit & 7));
/*0851*/        if (values[i] != 0) {
/*0852*/            map[offset] |= mask;
/*0853*/        } else {
/*0854*/            map[offset] &= ~mask;
/*0855*/        }
/*0856*/    }
/*0857*/}
/*0858*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -