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

📄 stackmap.c

📁 This is a java virtual machine implement in c
💻 C
📖 第 1 页 / 共 3 页
字号:
/*0001*//*
/*0002./ * Copyright (c) 2000-2001 Sun Microsystems, Inc. All Rights Reserved.
/*0003./ *
/*0004./ * This software is the confidential and proprietary information of Sun
/*0005./ * Microsystems, Inc. ("Confidential Information").  You shall not
/*0006./ * disclose such Confidential Information and shall use it only in
/*0007./ * accordance with the terms of the license agreement you entered into
/*0008./ * with Sun.
/*0009./ *
/*0010./ * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
/*0011./ * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
/*0012./ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
/*0013./ * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
/*0014./ * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
/*0015./ * THIS SOFTWARE OR ITS DERIVATIVES.
/*0016./ */
/*0017*/
/*0018*//*=========================================================================
/*0019./ * SYSTEM:    KVM
/*0020./ * SUBSYSTEM: Stackmap based pointer calculation
/*0021./ * FILE:      stackmap.c
/*0022./ * OVERVIEW:  This file defines stackmap calculation operations
/*0023./ *            that are needed by the exact garbage collector.
/*0024./ * AUTHOR:    Frank Yellin
/*0025./ *=======================================================================*/
/*0026*/
/*0027*//*=========================================================================
/*0028./ * Include files
/*0029./ *=======================================================================*/
/*0030*/
/*0031*/#include <global.h>
/*0032*/
/*0033*//*=========================================================================
/*0034./ * Definitions and declarations
/*0035./ *=======================================================================*/
/*0036*/
/*0037*/#define BIT_SET(bit)   map[(bit) >> 3] |= (((unsigned)1) << ((bit) & 7))
/*0038*/#define BIT_CLR(bit)   map[(bit) >> 3] &= ~(((unsigned)1) << ((bit) & 7))
/*0039*/
/*0040*//*=========================================================================
/*0041./ * Static variables and functions (private to this file)
/*0042./ *=======================================================================*/
/*0043*/
/*0044*/static unsigned int
/*0045*/getInitialRegisterMask(METHOD, unsigned int *offsetP, char *map);
/*0046*/
/*0047*/static void
/*0048*/setBits(char *map, unsigned int bit, unsigned int count, unsigned char *values);
/*0049*/
/*0050*/static void
/*0051*/getBits(char *map, unsigned int bit, unsigned int count, unsigned char *results);
/*0052*/
/*0061*//*=========================================================================
/*0062./ * Functions
/*0063./ *=======================================================================*/
/*0064*/
/*0065*//*=========================================================================
/*0066./ * FUNCTION:      getGCRegisterMask
/*0067./ * TYPE:          Important GC function
/*0068./ * OVERVIEW:      Returns a bitmap indicating the live size of the stack
/*0069./ * INTERFACE:
/*0070./ *   parameters:  thisMethod:  The current method
/*0071./ *                targetIP:    An IP somewhere in the code.  We want to find
/*0072./ *                             the register state just before this instruction
/*0073./ *                map:         A bitmap to be filled in
/*0074./ *   returns:     The size of the stack before the indicated instruction
/*0075./ *                is executed.
/*0076./ *

		//\\//\\//\\//\\//\\//\\//\\//\\//\\			
/*0077./ * NOTE: The important side effect of this function is that it fills in
/*0078./ * map with a bitmap indicating the locals and stack that contain pointers.
		//\\//\\//\\//\\//\\//\\//\\//\\//\\

/*0079./ * The first thisMethod->frameSize bits are the locals.  The <returnValue>
/*0080./ * bits following are the state of the stack.
/*0081./ *=======================================================================*/
/*0082*/
/*0083*/static unsigned int
/*0084*/getInitialRegisterMask(METHOD, unsigned int *targetOffset, char *map);
/*0085*/
/*0086*/unsigned int
/*0087*/getGCRegisterMask(METHOD thisMethod, unsigned char *targetIP,  char *map)
/*0088*/{
/*0089*/    CONSTANTPOOL cp = NULL;
/*0090*/    unsigned char *code = NULL;
/*0091*/    unsigned int codeOffset = 0;
/*0092*/    unsigned int localsCount = 0;
/*0093*/    unsigned int stackSize = 0;
/*0094*/    unsigned char *thisIP = NULL;
/*0095*/    unsigned char dupValues[6];
/*0096*/
/*0097*/    ByteCode token;
/*0098*/    unsigned int index = 0;
/*0099*/    METHOD method;
/*0100*/    FIELD field;
/*0101*/
/*0110*/    cp = thisMethod->ofClass->constPool;
/*0111*/    code = thisMethod->u.java.code;
/*0112*/    codeOffset = targetIP - code;
/*0113*/    localsCount = thisMethod->frameSize;
/*0114*/
/*0115*/    stackSize =
/*0116*/        /* This modifies codeOffset to be a location less than or
/*0117./         * equal to its original value. */
/*0118*/        getInitialRegisterMask(thisMethod, &codeOffset, map);
/*0119*/
/*0120*/    thisIP = code + codeOffset;
/*0121*/
/*0122*/    /* Our calculations are much simplified if we let stackSize also
/*0123./     * include the localsCount bits at the beginning of the stack map.
/*0124./     */
/*0125*/    stackSize += localsCount;
/*0126*/
/*0134*/    while (thisIP < targetIP) {
/*0141*/        /* Get the next token, and dispatch on it. */
/*0142*/     token = *thisIP++;
/*0143*/
/*0148*/        switch(token) {
/*0149*/            /* Store a single non pointer from the stack to a register */
/*0150*/            case ISTORE: case FSTORE:
/*0151*/                index = *thisIP++;
/*0152*/            storeInt:
/*0153*/                BIT_CLR(index);
/*0154*/                stackSize--;
/*0155*/                break;
/*0156*/
/*0157*/            /* Store a single pointer from the stack to a register */
/*0158*/            case ASTORE:
/*0159*/                index = *thisIP++;
/*0160*/            storePointer:
/*0161*/                BIT_SET(index);
/*0162*/                stackSize--;
/*0163*/                break;
/*0164*/
/*0165*/            /* Store a double or long from the stack to a register */
/*0166*/            case LSTORE: case DSTORE:
/*0167*/                index = *thisIP++;
/*0168*/            storeDouble:
/*0169*/                BIT_CLR(index);
/*0170*/                BIT_CLR(index + 1);
/*0171*/                stackSize -= 2;
/*0172*/                break;
/*0173*/
/*0174*/            case ISTORE_0: case ISTORE_1: case ISTORE_2: case ISTORE_3:
/*0175*/                index = token - ISTORE_0;
/*0176*/                goto storeInt;
/*0177*/
/*0178*/            case LSTORE_0: case LSTORE_1: case LSTORE_2: case LSTORE_3:
/*0179*/                index = token - LSTORE_0;
/*0180*/                goto storeDouble;
/*0181*/
/*0182*/            case FSTORE_0: case FSTORE_1: case FSTORE_2: case FSTORE_3:
/*0183*/                index = (token - FSTORE_0);
/*0184*/                goto storeInt;
/*0185*/
/*0186*/            case DSTORE_0: case DSTORE_1: case DSTORE_2: case DSTORE_3:
/*0187*/                index = (token - DSTORE_0);
/*0188*/                goto storeDouble;
/*0189*/
/*0190*/            case ASTORE_0: case ASTORE_1: case ASTORE_2: case ASTORE_3:
/*0191*/                index = (token - ASTORE_0);
/*0192*/                goto storePointer;
/*0193*/
/*0194*/                /* These leave any pointers on the stack as pointers, and
/*0195./                 * any nonpointers on the stack as nonpointers */
/*0196*/            case GETFIELDP_FAST: /* Ptr => Ptr */
/*0197*/            case IINC:
/*0198*/            case CHECKCAST: case CHECKCAST_FAST:
/*0199*/                thisIP += 2;
/*0200*/            case NOP:
/*0201*/            case INEG: case LNEG: case FNEG: case DNEG:
/*0202*/            case I2F:  case L2D:  case F2I:  case D2L:
/*0203*/            case I2B:  case I2C:  case I2S:
/*0204*/                break;
/*0205*/
/*0206*/                /* These push a non-pointer onto the stack */
/*0207*/            case SIPUSH:
/*0208*/            case GETSTATIC_FAST:
/*0209*/                thisIP++;
/*0210*/            case ILOAD:  case FLOAD:  case BIPUSH:
/*0211*/                thisIP++;
/*0212*/            case ACONST_NULL:
/*0213*/            case ICONST_M1: case ICONST_0: case ICONST_1:
/*0214*/            case ICONST_2:  case ICONST_3: case ICONST_4: case ICONST_5:
/*0215*/            case FCONST_0:  case FCONST_1: case FCONST_2:
/*0216*/            case ILOAD_0:   case ILOAD_1:  case ILOAD_2:  case ILOAD_3:
/*0217*/            case FLOAD_0:   case FLOAD_1:  case FLOAD_2:  case FLOAD_3:
/*0218*/            case I2L: case I2D: case F2L: case F2D:
/*0219*/            pushInt:
/*0220*/                BIT_CLR(stackSize);
/*0221*/                stackSize++;
/*0222*/                break;
/*0223*/
/*0224*/                /* These push two non-pointers onto the stack */
/*0225*/            case GETSTATIC2_FAST: case LDC2_W:
/*0226*/                thisIP++;
/*0227*/            case LLOAD:    case DLOAD:
/*0228*/                thisIP++;
/*0229*/            case LCONST_0: case LCONST_1: case DCONST_0: case DCONST_1:
/*0230*/            case LLOAD_0:  case LLOAD_1:  case LLOAD_2:  case LLOAD_3:
/*0231*/            case DLOAD_0:  case DLOAD_1:  case DLOAD_2:  case DLOAD_3:
/*0232*/            pushDouble:
/*0233*/                BIT_CLR(stackSize);
/*0234*/                stackSize++;
/*0235*/                BIT_CLR(stackSize);
/*0236*/                stackSize++;
/*0237*/                break;
/*0238*/
/*0239*/                /* These push a pointer onto the stack */
/*0240*/            case NEW: case NEW_FAST:
/*0241*/            case GETSTATICP_FAST:
/*0242*/                thisIP++;
/*0243*/            case ALOAD:
/*0244*/                thisIP++;
/*0245*/            case ALOAD_0:  case ALOAD_1:  case ALOAD_2: case ALOAD_3:
/*0246*/            pushPointer:
/*0247*/                BIT_SET(stackSize);
/*0248*/                stackSize++;
/*0249*/                break;
/*0250*/
/*0251*/                /* These pop an item off the stack */
/*0252*/            case IFEQ: case IFNE: case IFLT: case IFGE:
/*0253*/            case IFGT: case IFLE: case IFNULL: case IFNONNULL:
/*0254*/            case PUTSTATIC_FAST:
/*0255*/                thisIP += 2;
/*0256*/            case POP:  case IADD: case FADD: case ISUB: case FSUB:
/*0257*/            case IMUL: case FMUL: case IDIV: case FDIV: case IREM:
/*0258*/            case FREM: case ISHL: case LSHL: case ISHR: case LSHR:
/*0259*/            case IUSHR: case LUSHR:
/*0260*/            case IAND: case IOR: case IXOR:
/*0261*/            case L2I:  case L2F: case D2I: case D2F:
/*0262*/            case FCMPL: case FCMPG:
/*0263*/            case MONITORENTER: case MONITOREXIT:
/*0264*/            case AALOAD:        /* Ptr Int => Ptr */
/*0265*/                stackSize--;
/*0266*/                break;
/*0267*/
/*0268*/                /* These pop an item off the stack, and then push a pointer */
/*0269*/            case ANEWARRAY:
/*0270*/            case ANEWARRAY_FAST:
/*0271*/                thisIP++;
/*0272*/            case NEWARRAY:
/*0273*/                thisIP++;
/*0274*/                stackSize--;
/*0275*/                goto pushPointer;
/*0276*/
/*0277*/                /* These pop an item off the stack, and then push an int */
/*0278*/            case INSTANCEOF:
/*0279*/            case INSTANCEOF_FAST:
/*0280*/            case GETFIELD_FAST:
/*0281*/                thisIP += 2;
/*0282*/            case ARRAYLENGTH:
/*0283*/                stackSize--;
/*0284*/                goto pushInt;
/*0285*/
/*0286*/            /* These pop an item off the stack, and then put two nonptrs */
/*0287*/            case GETFIELD2_FAST:
/*0288*/                thisIP += 2;
/*0289*/                BIT_SET(stackSize-1);

⌨️ 快捷键说明

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