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; /* ¤tStackChunk->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 + -
显示快捷键?