stacks.h

来自「This is a resource based on j2me embedde」· C头文件 代码 · 共 1,013 行 · 第 1/3 页

H
1,013
字号
/* * @(#)stacks.h	1.117 06/10/10 * * Copyright  1990-2008 Sun Microsystems, Inc. All Rights Reserved.   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER   *    * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License version   * 2 only, as published by the Free Software Foundation.    *    * This program is distributed in the hope that it will be useful, but   * WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   * General Public License version 2 for more details (a copy is   * included at /legal/license.txt).    *    * You should have received a copy of the GNU General Public License   * version 2 along with this work; if not, write to the Free Software   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA   * 02110-1301 USA    *    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa   * Clara, CA 95054 or visit www.sun.com if you need additional   * information or have any questions.  * */#ifndef _INCLUDED_STACKS_H#define _INCLUDED_STACKS_H/**************************************************************************** * CVMStack * * CVMStack is a C type for the four types of stacks we need: * interpreter stack, local roots stack, global roots stack, and jni * global refs stack. * * The stack is broken up into separate chunks. Initially there is only * one chunk, but as the stack grows more chunks may be added. If the * stack shrinks, chunks are not aggressively freed. Because of this, * currentStackChunk->next might not be NULL, but may in fact point * to a free chunk that can be used if that stack needs to grow again. ****************************************************************************/#include "javavm/include/defs.h"#include "javavm/include/objects.h"#include "javavm/include/classes.h"#include "javavm/include/gc_common.h"#include "javavm/include/stackwalk.h"/* * Generic 32-bit wide "Java slot" definition. This type occurs * in Java locals, object fields, constant pools, and * operand stacks (as a CVMStackVal32). */typedef union CVMSlotVal32 {    CVMJavaVal32    j;     /* For "Java" values */    CVMUint8*       a;     /* a return created by jsr or jsr_w */} CVMSlotVal32;/* * Generic 32-bit wide stack slot definition. */union CVMStackVal32 {    CVMJavaVal32    j;     /* For "Java" values */    CVMSlotVal32    s;     /* any value from a "slot" or locals[] */    CVMObjectICell  ref;   /* JNI refs, local roots, global roots */    CVMStackVal32*  next;  /* An element of a free list */};struct CVMStackChunk {    CVMStackChunk*  prev;          /* Previous chunk of this stack */    CVMStackChunk*  next;          /* Next chunk of this stack */    CVMStackVal32*  end_data;      /* address of end of this chunk */    CVMStackVal32   data[1];       /* actual data  */};struct CVMStack {    CVMStackChunk*   firstStackChunk;     CVMStackChunk*   currentStackChunk;    CVMUint32        minStackChunkSize;/* minimum size for new chunk */    CVMUint32        maxStackSize;     /* max space used in all chunks */    CVMUint32        stackSize;        /* Total space used in all chunks */    CVMFrame*        volatile currentFrame;     /* Current stack frame */    /* Stack chunk pointers. Both may not be needed and can     * always be calculated. stackChunkEnd saves us an indirection on     * method calls. stackChunkStart might not be of much value.    */    CVMStackVal32*   stackChunkStart;  /* &currentStackChunk->data[0] */    CVMStackVal32*   stackChunkEnd;    /* currentStackChunk->end_data */};/* * Types of stack frames we need to know about. */typedef enum {#ifdef CVM_DEBUG_ASSERTS    CVM_FRAMETYPE_NONE,#endif    CVM_FRAMETYPE_JAVA,    CVM_FRAMETYPE_TRANSITION,    CVM_FRAMETYPE_FREELIST,    CVM_FRAMETYPE_LOCALROOT,    CVM_FRAMETYPE_GLOBALROOT,    CVM_FRAMETYPE_CLASSTABLE,#ifdef CVM_JIT    CVM_FRAMETYPE_COMPILED,#endif    CVM_NUM_FRAMETYPES} CVMFrameType;typedef enum {    CVM_FRAMEFLAG_ARTIFICIAL = 0x1,    CVM_FRAMEFLAG_EXCEPTION = 0x2} CVMFrameFlags;extern CVMFrameGCScannerFunc * const CVMframeScanners[CVM_NUM_FRAMETYPES];/**************************************************************************** * CVMFrame * * CVMFrame is the common base class for all frames used to keep track of * local roots, java method calls, jni method calls, and frames created * by JNI PushLocalFrame. The last frame is always pointed to by the * owning stacks CVMStack.currentFrame field. It is not possible for * a frame to automatically know it's owning stack, but it can be deduced * from the frame type. ****************************************************************************/struct CVMFrame {    CVMFrame*             prevX;      /* previous frame: access using macros*/    CVMUint8		  type;		/* CVMFrameType */    CVMUint8		  flags;	/* CVMFrameFlags */    /* topOfStack is used by CVMLocalRootsFrame to allocate the next     * local root (localRoots field), by CVMJavaFrame to push and pop     * operands (opstack field), and by CVMJNIFrame to allocate new     * local refs (localRefs field).     */    CVMStackVal32*   volatile topOfStack; /* Pointer to top of stack.					     This is the first free slot. */    CVMMethodBlock*  volatile mb;         /* the method we are executing */};struct CVMFreelistFrame {    CVMFrame          frame;    CVMUint32         inUse;      /* Number of items in use under topOfStack */    CVMStackVal32*    freeList;   /* A pointer to the free list */    CVMStackVal32     vals[1];    /* Frame contents */};#define CVMfreelistFrameInit(frame_, mbIsAlreadyInited_) \{                                                        \    if (!mbIsAlreadyInited_) {                           \        ((CVMFrame *)(frame_))->mb = 0;                  \    }                                                    \    (frame_)->inUse = 0;                                 \    (frame_)->freeList = 0;                              \}/* * These are the capacities to ensure for a base frame and a * freelisting frame */#define CVMbaseFrameCapacity \    (sizeof(CVMFrame) / sizeof(CVMStackVal32))#define CVMfreelistFrameCapacity  \    (sizeof(CVMFreelistFrame) / sizeof(CVMStackVal32) - 1)/**************************************************************************** * Stack and Frame API's ****************************************************************************//* Many of the macros take arguments that could easily have been retrieved * from other arguments. This is done for performance because most of the * arguments are already be cached in registers. Also, some of the macros * don't set all fields in the stack and frame that they could set. This * is also done for performance to allow the interpreter to delay flushing * the value from a local to the stack or field only when a gc is needed. *//* * Expand stack 's' to contain capacity words, and return a pointer to the * new area. If unsuccessful, returns NULL and throws an exception if the * throwException argument is true. * * If justChecking == TRUE, we are simply checking whether we have * this capacity or not.  */extern CVMStackVal32* CVMexpandStack(CVMExecEnv* ee, CVMStack* s, 			      CVMUint32 capacity,			      CVMBool throwException,			      CVMBool justChecking);/* * Macros for dealing with frames that need special handling when they * are popped. * * We need a cheap way of finding out if we are popping the * first frame in a stack chunk, or if we are popping a frame that spans * multiple stack chunks. Both of these situations require special handling * by popFrame so information in the CVMStack can be updated. We use * the low bit in frame->prev to indicate that frame requires special * handling by popFrame. This is a cheap place for the flag because we * need to load frame->prev anyway when popping frame. This bit referred * to as the SPECIAL bit.  * * We also need a flag to indicate if we are returning from a compiled * frame to another compiled frame, allowing for quick compiled -> * compiled returns. We could look at the frame 'type' field, but it * is cheaper to use a bit in the frame->prev field since it is being * loaded anyway. This is referred to as the SLOW bit and is false if * compiled code can do a quick pop of the frame and then return to * another compiled method. Only compiled frames ever have SLOW=0, but * both compiled and java frames can have SLOW=1. All frames that need * special handling because of chunk boundary related issues as * described above have SLOW=1. * * SPECIAL has different meaning based on the value of SLOW. For * SLOW=0, it indicates if the compiled frame has had its fixup done * (CVMJITfixupFrames).  For SLOW=1 it indicates if the frame needs * special handling because of chunk boundary issues as described * above. * * SLOW=0 SPECIAL=0 compiled -> compiled return, needs CVMJITfixupFrames * SLOW=0 SPECIAL=1 compiled -> compiled return, CVMJITfixupFrames done * SLOW=1 SPECIAL=0 return must be handled by interpreter (usually means *                  returning to a non-compiled method) * SLOW=1 SPECIAL=1 return must be handled by interpreter and frame needs  *                  special handling (ie. first frame in chunk) */#define CVM_FRAME_MASK_SPECIAL		(1 << 0)#define CVM_FRAME_MASK_SLOW		(1 << 1)#define CVM_FRAME_MASK_ALL		((1 << 2) - 1)/* Clear low bit in CVMFrame* *//*  * make CVM ready to run on 64 bit platforms *  * frame_ is used as an address * therefore the cast has to be CVMAddr which is 4 byte on * 32 bit platforms and 8 byte on 64 bit platforms */#define CVMframeUnmasked(frame_) \    ((CVMFrame*)((CVMAddr)(frame_) & ~CVM_FRAME_MASK_ALL))/* Set low bit in CVMFrame* *//*  * make CVM ready to run on 64 bit platforms *  * frame_ is used as an address * therefore the cast has to be CVMAddr which is 4 byte on * 32 bit platforms and 8 byte on 64 bit platforms */#define CVMframeMasked(frame_, mask_) \    ((CVMFrame*)((CVMAddr)(frame_) | (mask_)))#ifdef CVM_JIT/*  * make CVM ready to run on 64 bit platforms *  * frame_ is used as an address * therefore the cast has to be CVMAddr which is 4 byte on * 32 bit platforms and 8 byte on 64 bit platforms */#define CVMframeMaskBitsAreCorrect(frame_) \    ((((CVMAddr)((frame_))->prevX) & CVM_FRAME_MASK_ALL) != 0)#else#define CVMframeMaskBitsAreCorrect(frame_) \    CVM_TRUE#endif#define CVMassertFrameMaskBitsAreCorrect(frame_) \    CVMassert(CVMframeMaskBitsAreCorrect((frame_)))/* Get prevous frame without bit being set. Used to iterate over frames */#define CVMframePrev(frame_) \    (CVMassertFrameMaskBitsAreCorrect(frame_), \     CVMframeUnmasked((frame_)->prevX))/* Set the "special handling" bit */#define CVMsetFrameNeedsSpecialHandlingBit(frame_) \    (frame_) = CVMframeMasked((frame_), CVM_FRAME_MASK_SPECIAL)/* Check if the frame needs special handling in popFrame */#ifndef CVM_JIT/*  * make CVM ready to run on 64 bit platforms *  * frame_ is used as an address * therefore the cast has to be CVMAddr which is 4 byte on * 32 bit platforms and 8 byte on 64 bit platforms */#define CVMframeNeedsSpecialHandling(frame_) \    (((CVMAddr)(frame_) & CVM_FRAME_MASK_SPECIAL) != 0)#else/*  * make CVM ready to run on 64 bit platforms *  * frame_ is used as an address * therefore the cast has to be CVMAddr which is 4 byte on * 32 bit platforms and 8 byte on 64 bit platforms */#define CVMframeNeedsSpecialHandling(frame_) \    (((CVMAddr)(frame_) & CVM_FRAME_MASK_ALL) ==	\    (CVM_FRAME_MASK_SLOW | CVM_FRAME_MASK_SPECIAL))#endif/*  *   CVMBool  *   CVMcheckCapacity(CVMStack* s2_, CVMStackVal32* tos2, *                    CVMUint32 capacity2) * *   Checks if stack s2_ with current top of stack tos2_, can ensure *   a capacity of capacity2_. Return true if it can. */#define CVMcheckCapacity(s2_, tos2_, capacity2_)		\    (((CVMUint32)capacity2_) <= (CVMUint32)((s2_)->stackChunkEnd - (tos2_)))/*  * Checks if the stack can ensure the specified capacity. It will attempt to * grow the stack if necessary. Returns CVM_TRUE if it can. Otherwise it * throws an exception and returns CVM_FALSE. */extern CVMBoolCVMensureCapacity(CVMExecEnv* ee, CVMStack* stack, int capacity);/* *  void *  CVMpushFrame(CVMExecEnv* ee, *      CVMStack* s_, CVMFrame* cur_frame_, CVMStackVal32* tos_, *      CVMUint32 capacity_, CVMUint32 frameOffset_, *      CVMFrameType frameType_, CVMMethodBlock* methodBlock_,

⌨️ 快捷键说明

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