📄 stackmap.c
字号:
/* * Copyright (c) 2000-2002 Sun Microsystems, Inc. All Rights Reserved. * * This software is the confidential and proprietary information of Sun * Microsystems, Inc. ("Confidential Information"). You shall not * disclose such Confidential Information and shall use it only in * accordance with the terms of the license agreement you entered into * with Sun. * * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING * THIS SOFTWARE OR ITS DERIVATIVES. * Use is subject to license terms. *//*========================================================================= * SYSTEM: KVM * SUBSYSTEM: Stackmap based pointer calculation * FILE: stackmap.c * OVERVIEW: This file defines stackmap calculation operations * that are needed by the exact garbage collector. * AUTHOR: Frank Yellin *=======================================================================*//*========================================================================= * Include files *=======================================================================*/#include "global.h"/*========================================================================= * Definitions and declarations *=======================================================================*/#define BIT_SET(bit) map[(bit) >> 3] |= (((unsigned)1) << ((bit) & 7))#define BIT_CLR(bit) map[(bit) >> 3] &= ~(((unsigned)1) << ((bit) & 7))/*========================================================================= * Static variables and functions (private to this file) *=======================================================================*/static unsigned intgetInitialRegisterMask(METHOD, unsigned int *offsetP, char *map);static voidsetBits(char *map, unsigned int bit, unsigned int count, unsigned char *values);static voidgetBits(char *map, unsigned int bit, unsigned int count, unsigned char *results);#if INCLUDEDEBUGCODEstatic voidprintStackMap(long offset, const char *string, unsigned int localsCount, char *map, int stackSize);#endif /* INCLUDEDEBUGCODE *//*========================================================================= * Functions *=======================================================================*//*========================================================================= * FUNCTION: getGCRegisterMask * TYPE: Important GC function * OVERVIEW: Returns a bitmap indicating the live size of the stack * INTERFACE: * parameters: thisMethod: The current method * targetIP: An IP somewhere in the code. We want to find * the register state just before this instruction * map: A bitmap to be filled in * returns: The size of the stack before the indicated instruction * is executed. * * NOTE: The important side effect of this function is that it fills in * map with a bitmap indicating the locals and stack that contain pointers. * The first thisMethod->frameSize bits are the locals. The <returnValue> * bits following are the state of the stack. *=======================================================================*/static unsigned intgetInitialRegisterMask(METHOD, unsigned int *targetOffset, char *map);unsigned intgetGCRegisterMask(METHOD thisMethod, unsigned char *targetIP, char *map){ CONSTANTPOOL cp = NULL; unsigned char *code = NULL; unsigned int codeOffset = 0; unsigned int localsCount = 0; unsigned int stackSize = 0; unsigned char *thisIP = NULL; unsigned char dupValues[6]; ByteCode token; unsigned int index = 0; METHOD method; FIELD field;#if INCLUDEDEBUGCODE int junk = 0; if (tracestackmaps) { junk = (printMethodName(thisMethod, stdout), 0); }#endif cp = thisMethod->ofClass->constPool; code = thisMethod->u.java.code; codeOffset = targetIP - code; localsCount = thisMethod->frameSize; stackSize = /* This modifies codeOffset to be a location less than or * equal to its original value. */ getInitialRegisterMask(thisMethod, &codeOffset, map); thisIP = code + codeOffset; /* Our calculations are much simplified if we let stackSize also * include the localsCount bits at the beginning of the stack map. */ stackSize += localsCount;#if INCLUDEDEBUGCODE if (tracestackmaps) { printStackMap(thisIP - code, "Start", localsCount, map, stackSize); } junk++; /* Avoid a compiler warning */#endif while (thisIP < targetIP) {#if INCLUDEDEBUGCODE unsigned char *initialIP=NULL; if (tracestackmaps) { initialIP = thisIP; } #endif /* Get the next token, and dispatch on it. */ token = *thisIP++;#if ENABLE_JAVA_DEBUGGERagain:#endif switch(token) { /* Store a single non pointer from the stack to a register */ case ISTORE: case FSTORE: index = *thisIP++; storeInt: BIT_CLR(index); stackSize--; break; /* Store a single pointer from the stack to a register */ case ASTORE: index = *thisIP++; storePointer: BIT_SET(index); stackSize--; break; /* Store a double or long from the stack to a register */ case LSTORE: case DSTORE: index = *thisIP++; storeDouble: BIT_CLR(index); BIT_CLR(index + 1); stackSize -= 2; break; case ISTORE_0: case ISTORE_1: case ISTORE_2: case ISTORE_3: index = token - ISTORE_0; goto storeInt; case LSTORE_0: case LSTORE_1: case LSTORE_2: case LSTORE_3: index = token - LSTORE_0; goto storeDouble; case FSTORE_0: case FSTORE_1: case FSTORE_2: case FSTORE_3: index = (token - FSTORE_0); goto storeInt; case DSTORE_0: case DSTORE_1: case DSTORE_2: case DSTORE_3: index = (token - DSTORE_0); goto storeDouble; case ASTORE_0: case ASTORE_1: case ASTORE_2: case ASTORE_3: index = (token - ASTORE_0); goto storePointer; /* These leave any pointers on the stack as pointers, and * any nonpointers on the stack as nonpointers */ case GETFIELDP_FAST: /* Ptr => Ptr */ case IINC: case CHECKCAST: case CHECKCAST_FAST: thisIP += 2; case NOP: case INEG: case LNEG: case FNEG: case DNEG: case I2F: case L2D: case F2I: case D2L: case I2B: case I2C: case I2S: break; /* These push a non-pointer onto the stack */ case SIPUSH: case GETSTATIC_FAST: thisIP++; case ILOAD: case FLOAD: case BIPUSH: thisIP++; case ACONST_NULL: case ICONST_M1: case ICONST_0: case ICONST_1: case ICONST_2: case ICONST_3: case ICONST_4: case ICONST_5: case FCONST_0: case FCONST_1: case FCONST_2: case ILOAD_0: case ILOAD_1: case ILOAD_2: case ILOAD_3: case FLOAD_0: case FLOAD_1: case FLOAD_2: case FLOAD_3: case I2L: case I2D: case F2L: case F2D: pushInt: BIT_CLR(stackSize); stackSize++; break; /* These push two non-pointers onto the stack */ case GETSTATIC2_FAST: case LDC2_W: thisIP++; case LLOAD: case DLOAD: thisIP++; case LCONST_0: case LCONST_1: case DCONST_0: case DCONST_1: case LLOAD_0: case LLOAD_1: case LLOAD_2: case LLOAD_3: case DLOAD_0: case DLOAD_1: case DLOAD_2: case DLOAD_3: pushDouble: BIT_CLR(stackSize); stackSize++; BIT_CLR(stackSize); stackSize++; break; /* These push a pointer onto the stack */ case NEW: case NEW_FAST: case GETSTATICP_FAST: thisIP++; case ALOAD: thisIP++; case ALOAD_0: case ALOAD_1: case ALOAD_2: case ALOAD_3: pushPointer: BIT_SET(stackSize); stackSize++; break; /* These pop an item off the stack */ case IFEQ: case IFNE: case IFLT: case IFGE: case IFGT: case IFLE: case IFNULL: case IFNONNULL: case PUTSTATIC_FAST: thisIP += 2; case POP: case IADD: case FADD: case ISUB: case FSUB: case IMUL: case FMUL: case IDIV: case FDIV: case IREM: case FREM: case ISHL: case LSHL: case ISHR: case LSHR: case IUSHR: case LUSHR: case IAND: case IOR: case IXOR: case L2I: case L2F: case D2I: case D2F: case FCMPL: case FCMPG: case MONITORENTER: case MONITOREXIT: case AALOAD: /* Ptr Int => Ptr */ stackSize--; break; /* These pop an item off the stack, and then push a pointer */ case ANEWARRAY: case ANEWARRAY_FAST: thisIP++; case NEWARRAY: thisIP++; stackSize--; goto pushPointer; /* These pop an item off the stack, and then push an int */ case INSTANCEOF: case INSTANCEOF_FAST: case GETFIELD_FAST: thisIP += 2; case ARRAYLENGTH: stackSize--; goto pushInt; /* These pop an item off the stack, and then put two nonptrs */ case GETFIELD2_FAST: thisIP += 2; BIT_SET(stackSize-1); BIT_SET(stackSize); stackSize--; goto pushDouble; /* These pop two items off the stack */ case IF_ICMPEQ: case IF_ICMPNE: case IF_ICMPLT: case IF_ICMPGE: case IF_ICMPGT: case IF_ICMPLE: case IF_ACMPEQ: case IF_ACMPNE: case PUTFIELD_FAST: case PUTSTATIC2_FAST:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -