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

📄 frame.c

📁 Nucleus_2_kvm_Hello 是kvm移植到Nucleus系统的源代码。。。好东西啊
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (c) 1998-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: Interpreter stack frames * FILE:      frame.c * OVERVIEW:  This file defines the internal operations for *            manipulating stack frames & performing exception *            handling. * AUTHOR:    Antero Taivalsaari, Sun Labs, 1998 *            Edited by Doug Simon 11/1998 (simplified exception handling) *            Sheng Liang (chunky stacks), Frank Yellin *=======================================================================*//*========================================================================= * Include files *=======================================================================*/#include "global.h"/*========================================================================= * Global variables and definitions *=======================================================================*//* Shortcuts to the errors/exceptions that the VM may throw */const char NullPointerException[]           = "java/lang/NullPointerException";const char IndexOutOfBoundsException[]           = "java/lang/IndexOutOfBoundsException";const char ArrayIndexOutOfBoundsException[]           = "java/lang/ArrayIndexOutOfBoundsException";const char ArrayStoreException[]           = "java/lang/ArrayStoreException";const char ArithmeticException[]           = "java/lang/ArithmeticException";const char ClassCastException[]           = "java/lang/ClassCastException";const char NegativeArraySizeException[]           = "java/lang/NegativeArraySizeException";const char JavaLangError_name[]     /* JavaLangError is name of class */           = "java/lang/Error";/*========================================================================= * Static function prototypes (for functions used only in this file) *=======================================================================*/#if INCLUDEDEBUGCODEstatic void exceptionThrownTracing(INSTANCE_HANDLE exceptionH);static void exceptionCaughtTracing(THROWABLE_INSTANCE_HANDLE exceptionH, HANDLER handler);#else#define exceptionThrownTracing(exception)#define exceptionCaughtTracing(exception, handler)#endif /* INCLUDEDEBUGCODE *//*========================================================================= * Operations on stack frames *=======================================================================*//*========================================================================= * FUNCTION:      pushFrame() * TYPE:          constructor (kind of) * OVERVIEW:      Creates a new execution stack frame for the currently *                executing thread. The operation is used for invoking *                methods upon message sending to objects.  Allocates *                new stack chunks as necessary ("chunky stacks"). *                This allows the KVM to support a large number of *                Java threads in a limited heap space. * INTERFACE: *   parameters:  method pointer *   returns:     TRUE if pushFrame succeeds; *                FALSE on stack overflow (it will have raised the exception) *   throws:      OutOfMemoryError if the system runs out of memory * * COMMENTS:      Note: this function operates in the context of *                currently executing thread. All VM registers must *                be initialized correctly before allocating frames. * *                Remember that the zeroeth local variable '*lp' *                must contain the 'this' (self) pointer *                in virtual/special/interface method calls. * *                Also remember that unlike most other Java VMs, *                KVM does not create stack frames for native *                function calls (see native.c and kni.h/c for  *                more information on native function calls) *=======================================================================*/bool_t pushFrame(METHOD thisMethod){    int thisFrameSize = thisMethod->frameSize;    int thisArgCount = thisMethod->argCount;    int thisLocalCount = thisFrameSize - thisArgCount;        STACK stack = getFP() ? getFP()->stack : CurrentThread->stack;    int thisMethodHeight = thisLocalCount + thisMethod->u.java.maxStack +                            SIZEOF_FRAME + RESERVEDFORNATIVE;    FRAME newFrame;    int i;    cell* prev_sp = getSP() - thisArgCount; /* Very volatile! */    /* Check if there is enough space in the current stack chunk */    if (getSP() - stack->cells + thisMethodHeight >= stack->size) {        /* Not enough space in the current stack chunk. */        /* We need to create a new one or reuse an existing one */        STACK newstack;        thisMethodHeight += thisArgCount;        /* Check if we can reuse an existing stack chunk */        if (stack->next && thisMethodHeight > stack->next->size) {            stack->next = NULL;        }        /* If next is NULL, we need to create a new stack chunk */        if (stack->next == NULL) {            int size = thisMethodHeight > STACKCHUNKSIZE                      ? thisMethodHeight : STACKCHUNKSIZE;            int stacksize = sizeof(struct stackStruct) / CELL +                            (size - STACKCHUNKSIZE);            START_TEMPORARY_ROOTS                DECLARE_TEMPORARY_ROOT(STACK, stackX, stack);                newstack = (STACK)mallocHeapObject(stacksize, GCT_EXECSTACK);                 stack = stackX;                prev_sp = getSP() - thisArgCount;            END_TEMPORARY_ROOTS            if (newstack == NULL) {                throwException(&StackOverflowObject);                return FALSE;            }#if INCLUDEDEBUGCODE            /* In debug mode, initialize the new stack chunk to zeros */            memset(newstack, 0, stacksize << log2CELL);#endif            newstack->next = NULL;            newstack->size = size;            stack->next = newstack;#if INCLUDEDEBUGCODE            if (traceframes || tracestackchunks) {                fprintf(stdout,                    "Created a new stack chunk (thread: %lx, new chunk: %lx, prev: %lx, stack depth: %ld)\n",                     (long)CurrentThread, (long)newstack,                    (long)stack, (long)frameDepth());            }#endif        } else {            /* Can reuse an existing, unused stack chunk */            newstack = stack->next;        }        /* The actual pushFrame operation for a new stack chunk happens here */        for (i = 0; i < thisArgCount; i++) {            newstack->cells[i] = prev_sp[i + 1];        }        setLP(newstack->cells);        newFrame = (FRAME)(getLP() + thisFrameSize);        newFrame->stack = newstack;    } else {        /* This is the more common case; pushing a frame without */        /* having to create or reuse another stack chunk */        ASSERTING_NO_ALLOCATION            /* Set the local variable pointer to point to the start */            /* of the local variables in the execution stack */            setLP(prev_sp + 1);            /* Add space for local variables, and */            /* initialize the new frame pointer */            newFrame = (FRAME)(getSP() + thisLocalCount + 1);            newFrame->stack = stack;        END_ASSERTING_NO_ALLOCATION    }#if ENABLE_JAVA_DEBUGGER    /*     * Although the GC doesn't need to zero out the locations, the debugger     * code needs to have unallocated objects zeroed out on the stack, else     * it will try to dereference them when the debugger asks for the local     * variables.     */    if (vmDebugReady)        memset(getLP() + thisArgCount, 0, thisLocalCount << log2CELL);#endif    /* Fill out the remaining fields in the stack frame */    ASSERTING_NO_ALLOCATION        /* Initialize info needed for popping the stack frame later on */        newFrame->previousSp = prev_sp;        newFrame->previousIp = getIP();        newFrame->previousFp = getFP();        /* Initialize the frame to execute the given method */        newFrame->thisMethod = thisMethod;        newFrame->syncObject = NIL; /* Initialized later if necessary */        /* Change virtual machine registers to execute the new method */        setFP(newFrame);        setSP((cell*)(newFrame + 1) - 1);        setIP(thisMethod->u.java.code);        setCP(thisMethod->ofClass->constPool);#if INCLUDEDEBUGCODE        if (tracemethodcalls || tracemethodcallsverbose) {            frameTracing(thisMethod, "=>", 0);        }        if (traceframes) {            fprintf(stdout,                 "Pushed a stack frame (thread: %lx, fp: %lx, sp: %lx, depth: %ld, stack: %lx)\n",                (long)CurrentThread, (long)getFP(),                (long)getSP(), (long)frameDepth(), (long)stack);        }#endif /* INCLUDEDEBUGCODE */    END_ASSERTING_NO_ALLOCATION    return TRUE;}/*========================================================================= * FUNCTION:      popFrame() * TYPE:          destructor (kind of) * OVERVIEW:      Deletes an execution stack frame and resumes the *                execution of the method that called the currently *                executing method. * INTERFACE: *   parameters:  <none> *   returns:     Nothing directly, but field 'previousIp' holds *                information about what to do after the frame has *                been popped (whether to continue interpreter execution, *                to kill the thread, or to return to C/C++ code). *                Also, the field 'syncObject' holds a monitor object *                to be released in case this was a synchronized method *                call (see the RETURN bytecodes in Interpret.cpp) *=======================================================================*/void popFrame(){    /* Unallocate a stack frame and restore virtual */     /* machine registers to continue the execution */    /* of the previous method. */#if INCLUDEDEBUGCODE        if (tracemethodcalls || tracemethodcallsverbose) {            frameTracing(getFP()->thisMethod, "<=", 0);        }#endif /* INCLUDEDEBUGCODE */    /* See frame.h */    POPFRAMEMACRO#if INCLUDEDEBUGCODE    if (traceframes) {        fprintf(stdout,            "Popped a stack frame (thread: %lx, fp: %lx, sp: %lx, depth: %ld, stack: %lx)\n",            (long)CurrentThread, (long)getFP(),             (long)getSP(), (long)frameDepth(), (long)getFP()->stack);    }#endif /* INCLUDEDEBUGCODE */#if ENABLE_JAVA_DEBUGGER    if (vmDebugReady)        setEvent_FramePop();#endif}/*========================================================================= * Exception handling operations *=======================================================================*//*========================================================================= * FUNCTION:      findHandler() * TYPE:          exception handler table lookup operation * OVERVIEW:      Find a possible handler in the given exception handler *                table that catches the given exception in given *                code location. * INTERFACE: *   parameters:  handler table, exception object, instruction pointer offset *   returns:     handler or NIL if no matching handler is found *=======================================================================*/static HANDLERfindHandler(INSTANCE_CLASS thisClass, HANDLERTABLE handlerTable,             THROWABLE_INSTANCE_HANDLE exceptionH, unsigned short ipOffset){    HANDLER result = NULL;    ASSERTING_NO_ALLOCATION            FOR_EACH_HANDLER(thisHandler, handlerTable)            if (ipOffset < thisHandler->startPC) {                 continue;            } else if (ipOffset >= thisHandler->endPC) {                 continue;            } else {                 if (thisHandler->exception == 0) {                    result = thisHandler;                    break;                } else {                     unsigned short thisException =                         (unsigned short)thisHandler->exception;                    CLASS handlerClass =                         resolveClassReference(thisClass->constPool,                                              thisException,                                              thisClass);                    if (isAssignableTo((CLASS)(unhand(exceptionH)->ofClass),                                        (CLASS)handlerClass)) {                        /* Matching exception handler has been found */                        result = thisHandler;                        break;                    }                }            }        END_FOR_EACH_HANDLER    END_ASSERTING_NO_ALLOCATION    return result;}/*========================================================================= * FUNCTION:      throwException() * TYPE:          internal exception handling operation * OVERVIEW:      Throw an exception (to be handled by a matching *                stack frame exception handler.  This operation may be *                called both from bytecode (by primitive ATHROW) or *                internally from the VM whenever an exceptional *                situation occurs (e.g., an array range exception). * *                Handle a runtime exception by inspecting exception *                handlers in execution stack frames, and unwinding the *                execution stack if necessary in order to try to find *                a matching handler.  If we find a matching handler *                set the interpreter to execute its code. * INTERFACE: *   parameters:  pointer to an exception object *   returns:     <nothing> * NOTE:          When invoking this operation from inside the VM, *                keep in mind that the exception handler is not *                executed until the VM returns back to the interpreter. *                Thus, you should not put any C/C++ code after calls *                to 'throwException' because that code would be called *                "too early" (without having executed any of the *                the exception handler bytecode. *=======================================================================*/void throwException(THROWABLE_INSTANCE_HANDLE exceptionH) {

⌨️ 快捷键说明

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