stacks.c

来自「This is a resource based on j2me embedde」· C语言 代码 · 共 604 行 · 第 1/2 页

C
604
字号
/* * @(#)stacks.c	1.90 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.  * */#include "javavm/include/defs.h"#include "javavm/include/objects.h"#include "javavm/include/classes.h"#include "javavm/include/interpreter.h"#include "javavm/include/stacks.h"#include "javavm/include/stackwalk.h"#include "javavm/include/directmem.h"#include "javavm/include/indirectmem.h"#include "javavm/include/common_exceptions.h"#include "javavm/include/clib.h"CVMBoolCVMinitStack(CVMExecEnv *ee, CVMStack* s,	     CVMUint32 initialStackSize, CVMUint32 maxStackSize,	     CVMUint32 minStackChunkSize, CVMUint32 initialFrameCapacity,	     CVMFrameType frameType){    CVMFrame* initialFrame;    s->minStackChunkSize = minStackChunkSize;    s->maxStackSize = maxStackSize;    s->stackSize = 0;    /* Initialize stack chunk pointers to NULL before calling CVMexpandStack */    s->firstStackChunk = s->currentStackChunk = NULL;     /* Also initialize stack chunk begin and end pointers to NULL.       These are now no longer updated by the call to CVMexpandStack,       below, but are tested by the call to CVMensureCapacity which is       contained in the PushFrame call after it, leading to a read       from uninitialized memory (caught with dbx's memory checking;       "help check".) */    s->stackChunkStart = s->stackChunkEnd = NULL;    /* Add the first chunk to the stack */    if (CVMexpandStack(ee, s, initialStackSize, CVM_FALSE, CVM_FALSE) == NULL){	return CVM_FALSE;  /* exception NOT thrown */    }    /*     * This is going to end up being the previous frame of the initial frame     */    initialFrame = 0;    /* Now push a singleton frame on */    CVMpushFrame(ee, s, initialFrame, s->stackChunkStart,		 initialFrameCapacity, 0, frameType, NULL, CVM_TRUE, {}, {});    /* CVMpushFrame can't fail because we ensured enough space. */    CVMassert(initialFrame != 0);    /* Make topOfStack point just beyond the frame structure. */    initialFrame->topOfStack =	(CVMStackVal32*)initialFrame + initialFrameCapacity;    s->currentFrame = initialFrame;        return CVM_TRUE;}voidCVMdestroyStack(CVMStack* s){    CVMStackChunk *c = s->firstStackChunk;    while (c != NULL) {	CVMStackChunk *n = c->next;	free(c);	c = n;    }#ifdef CVM_DEBUG    s->firstStackChunk = NULL;    s->currentStackChunk = NULL;    s->currentFrame = NULL;    s->stackChunkStart = NULL;    s->stackChunkEnd = NULL;#endif}CVMBoolCVMinitGCRootStack(CVMExecEnv *ee, CVMStack* s, CVMUint32 initialStackSize, 		   CVMUint32 maxStackSize, CVMUint32 minStackChunkSize,		   CVMFrameType frameType){    CVMFreelistFrame* initialFrame;    CVMBool result;    result = CVMinitStack(ee, s, initialStackSize, maxStackSize, 			  minStackChunkSize, CVMfreelistFrameCapacity,			  frameType);    if (!result) {	return CVM_FALSE; /* exception NOT thrown */    }    initialFrame = (CVMFreelistFrame*)s->currentFrame;    CVMfreelistFrameInit(initialFrame, CVM_FALSE);    return CVM_TRUE;}voidCVMdestroyGCRootStack(CVMStack* s){    CVMdestroyStack(s);}#ifdef CVM_DEBUG_DUMPSTACKstatic void CVMdumpChunk(CVMStackChunk* chunk){    CVMconsolePrintf("\tStack chunk:    0x%x\n", chunk);    CVMconsolePrintf("\tChunk size:     0x%x\n",		     (chunk->end_data - &chunk->data[0]));    CVMconsolePrintf("\tChunk data:     0x%x\n", chunk->data);    CVMconsolePrintf("\tChunk end data: 0x%x\n", chunk->end_data);    CVMconsolePrintf("\tChunk prev:     0x%x\n", chunk->prev);    CVMconsolePrintf("\tChunk next:     0x%x\n", chunk->next);}/* * Dump data in the interval [endLower, startHigher] */static voidCVMdumpData(CVMStackVal32* startHigher, CVMStackVal32* endLower){    CVMStackVal32* ptr;    for (ptr = startHigher - 1; ptr >= endLower; ptr--) {	CVMconsolePrintf("\t\t[0x%x] = (0x%8.8x) %d\n",			 ptr, (*ptr).j.i, (*ptr).j.i);    }}CVMStackChunk*CVMdumpFrame(CVMFrame* frame, CVMStackChunk* startChunk,	     CVMBool verbose, CVMBool includeData){    CVMStackChunk* chunk      = startChunk;    CVMStackVal32* topOfStack = frame->topOfStack;    char*          type;    char           buf[256];    CVMUint8*	   pc = 0;    CVMUint32      frameSize;    /* get the type of frame */    switch (frame->type) {    case CVM_FRAMETYPE_TRANSITION:	CVMassert(CVMframeIsTransition(frame));	type = "Transition Frame";	frameSize = CVM_TRANSITIONFRAME_SIZE / sizeof(CVMStackVal32*);	pc = CVMframePc(frame);	break;    case CVM_FRAMETYPE_JAVA:	CVMassert(CVMframeIsJava(frame));	type = "Java Frame";	frameSize = CVM_JAVAFRAME_SIZE / sizeof(CVMStackVal32*);	pc = CVMframePc(frame);	break;#if 0    case CVM_FRAMETYPE_JNI:#endif    case CVM_FRAMETYPE_FREELIST:	CVMassert(CVMframeIsFreelist(frame));	if (frame->mb != NULL) {	    type = "JNI Frame";	    frameSize = CVMJNIFrameCapacity;	} else {	    type = "Free List Frame";	    frameSize = CVMfreelistFrameCapacity;	}	break;#ifdef CVM_JIT    case CVM_FRAMETYPE_COMPILED:	CVMassert(CVMframeIsCompiled(frame));	type = "Compiled Frame";	frameSize = CVM_COMPILEDFRAME_SIZE / sizeof(CVMStackVal32*);	pc = CVMcompiledFramePC(frame);	break;#endif    default:	frameSize = CVMbaseFrameCapacity;	type = "<unknown frame type>";    }    /* get the very verbose name of the method */    if (frame->mb != NULL) {	CVMframe2string(frame, buf, buf + sizeof(buf));    } else {	sprintf(buf, "%s", "(JNI Local Frame)");    }    if (!verbose) {	CVMconsolePrintf("  %-16s  %s\n", type, buf);	if (includeData) {	    CVMconsolePrintf("call CVMdumpFrame(0x%x, 0x%x, 1, 1)\n", 			     frame, chunk);	}    } else {	CVMconsolePrintf("\tFrame:   0x%x\n", frame);	CVMconsolePrintf("\tprev:    0x%x\n", CVMframePrev(frame));	CVMconsolePrintf("\tTos:     0x%x\n", frame->topOfStack);	CVMconsolePrintf("\tType:    %s\n",   type);	if (frame->mb != 0) {	    CVMconsolePrintf("\tName:    %s\n", buf);	}	if (pc != 0) {	    CVMconsolePrintf("\tPC:      0x%x\n", pc);	}	CVMconsolePrintf("\tspecial: %x\n",			 CVMframeNeedsSpecialHandling(frame->prevX));	if (frame->flags != 0) {	    CVMconsolePrintf("\tflags: %x\n", frame->flags);	}		CVMconsolePrintf("\tContents:\n");	CVMconsolePrintf("\t    Chunk 0x%x (0x%x-0x%x)\n", chunk,			 &chunk->data[0], chunk->end_data);	/*	 * dumpData and handle frames spanning multiple stack chunks	 */	while(!CVMaddressInStackChunk(frame, chunk)) {	    if (includeData) {		CVMdumpData(topOfStack, &chunk->data[0]);	    }	    chunk = chunk->prev;	    topOfStack = chunk->end_data;	    CVMconsolePrintf("\t    Chunk 0x%x (0x%x-0x%x)\n",			     chunk, &chunk->data[0], chunk->end_data);	}	if (includeData) {	    CVMdumpData(topOfStack, (CVMStackVal32*)(frame) + frameSize);	}	CVMconsolePrintf("\n");    }    if ((CVMStackVal32*)frame == chunk->data) {	chunk = chunk->prev;    }    return chunk;}static voidCVMdumpFrames(CVMStack* s, CVMBool verbose, CVMBool includeData,	      CVMInt32 frameLimit){    CVMStackWalkContext c;    CVMFrame* frame;    CVMstackwalkInit(s, &c);    frame = c.frame;    do {	CVMdumpFrame(frame, c.chunk, verbose, includeData);	CVMstackwalkPrev(&c);	frame = c.frame;	frameLimit--;    } while (frame != 0 && frameLimit != 0);}/* * Dump out stack information, including backtrace. frameLimit limits the * number of frames that are traced. A limit of 0 dumps all frames. */voidCVMdumpStack(CVMStack* s, CVMBool verbose, CVMBool includeData,	     CVMInt32 frameLimit){    CVMStackChunk* chunk;    if (verbose) {	CVMconsolePrintf("*** Dumping stack 0x%x\n", s);	CVMconsolePrintf("    Stack info\n");	CVMconsolePrintf("\tstack size:    0x%x\n", s->stackSize);	CVMconsolePrintf("\tchunk start:   0x%x\n", s->stackChunkStart);	CVMconsolePrintf("\tchunk end:     0x%x\n", s->stackChunkEnd);

⌨️ 快捷键说明

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