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

📄 class.c

📁 Nucleus_2_kvm_Hello 是kvm移植到Nucleus系统的源代码。。。好东西啊
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * Copyright (c) 1998-2001 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: Internal runtime structures * FILE:      class.c * OVERVIEW:  Internal runtime class structures (see Class.h). * AUTHOR:    Antero Taivalsaari, Sun Labs *            Edited by Doug Simon 11/1998 (added the string pool) *            Added access checks by Sheng Liang for VM-spec compliance *            Frank Yellin (more checks for JLS compliance) *=======================================================================*//*========================================================================= * Include files *=======================================================================*/#include "global.h"#include "stddef.h"/*========================================================================= * Global variables and definitions *=======================================================================*//*  Pointers to the most important Java classes needed by the VM *//*  If Romizing, these are defined and initialized in ROMjava.c */#if ROMIZING#  define EXTERN_IF_ROMIZING extern#else#  define EXTERN_IF_ROMIZING#endifEXTERN_IF_ROMIZINGINSTANCE_CLASS JavaLangObject;    /*  Pointer to class 'java.lang.Object' */EXTERN_IF_ROMIZINGINSTANCE_CLASS JavaLangClass;     /*  Pointer to class 'java.lang.Class' */EXTERN_IF_ROMIZINGINSTANCE_CLASS JavaLangSystem;    /*  Pointer to class 'java.lang.System' */EXTERN_IF_ROMIZINGINSTANCE_CLASS JavaLangString;    /*  Pointer to class 'java.lang.String' */EXTERN_IF_ROMIZINGINSTANCE_CLASS JavaLangThread;    /*  Pointer to class 'java.lang.Thread' */EXTERN_IF_ROMIZINGINSTANCE_CLASS JavaLangThrowable; /*  Pointer to class 'java.lang.Throwable' */EXTERN_IF_ROMIZINGINSTANCE_CLASS JavaLangError; /*  Pointer to class 'java.lang.Throwable' */EXTERN_IF_ROMIZING METHOD RunCustomCodeMethod;EXTERN_IF_ROMIZING NameTypeKey initNameAndType;   /* void <init>() */EXTERN_IF_ROMIZING NameTypeKey clinitNameAndType; /* void <clinit>() */EXTERN_IF_ROMIZING NameTypeKey runNameAndType;    /* void run() */EXTERN_IF_ROMIZING NameTypeKey mainNameAndType;   /* void main(String[]) */EXTERN_IF_ROMIZING ARRAY_CLASS PrimitiveArrayClasses[T_LASTPRIMITIVETYPE + 1];INSTANCE_CLASS JavaLangOutOfMemoryError;THROWABLE_INSTANCE OutOfMemoryObject;THROWABLE_INSTANCE StackOverflowObject;/*========================================================================= * Static methods (only used in this file) *=======================================================================*/static void runClinit(FRAME_HANDLE);static void runClinitException(FRAME_HANDLE);/*========================================================================= * Constructors *=======================================================================*//*========================================================================= * FUNCTION:      initializeClass() * TYPE:          constructor * OVERVIEW:      After loading a class, it must be initialized *                by executing the possible internal static *                constructor '<clinit>'. This will initialize the *                necessary static structures. * *                This function sets up the necessary Class.runClinit *                frame and returns to the interpreter. * INTERFACE: *   parameters:  class pointer *   returns:     <nothing> *=======================================================================*/void initializeClass(INSTANCE_CLASS thisClass){    if (thisClass->status == CLASS_ERROR) {         return;    } else if (thisClass->status < CLASS_VERIFIED) {        if (thisClass->superClass != NULL &&            thisClass->superClass->clazz.accessFlags == ACC_FINAL) {            START_TEMPORARY_ROOTS                DECLARE_TEMPORARY_ROOT(char *, thisClassName,                     getClassName((CLASS)thisClass));                DECLARE_TEMPORARY_ROOT(char *, superClassName,                     getClassName((CLASS)(thisClass->superClass)));                sprintf(str_buffer, KVM_MSG_CLASS_EXTENDS_FINAL_CLASS_2STRPARAMS,                        thisClassName, superClassName);                fatalError(str_buffer);            END_TEMPORARY_ROOTS        }        if (   (thisClass->clazz.accessFlags & ACC_INTERFACE)             && thisClass->superClass != JavaLangObject) {            sprintf(str_buffer,                KVM_MSG_INTERFACE_DOES_NOT_EXTEND_JAVALANGOBJECT_1STRPARAM,                getClassName((CLASS)thisClass));            fatalError(str_buffer);        }        if (verifyClass(thisClass)) {            sprintf(str_buffer,                KVM_MSG_ERROR_VERIFYING_CLASS_1STRPARAM,                 getClassName((CLASS)thisClass));            fatalError(str_buffer);        }    }    if (pushFrame(RunCustomCodeMethod)) {        pushStackAsType(CustomCodeCallbackFunction, runClinit);        pushStackAsType(INSTANCE_CLASS, thisClass);        pushStackAsType(long, 1);    } else {        /* Stack overflow */        setClassStatus(thisClass, CLASS_ERROR);    }}/*========================================================================= * FUNCTION:      runClinit() * TYPE:          private initialization of a class * OVERVIEW:      Initialize a class. The Class.runCustomCode frame has *                already been pushed. * *        This function follows the exact steps as documented in *        the Java virtual machine spec (2ed) 2.17.5, except that *        Error is used instead of ExceptionInInitializerError *        because the latter is not defined in CLDC. *=======================================================================*/static voidrunClinit(FRAME_HANDLE exceptionFrameH){    INSTANCE_CLASS thisClass;    int state;    bool_t haveMonitor = FALSE;    if (exceptionFrameH) {         runClinitException(exceptionFrameH);        return;    }     state = topStackAsType(cell);    thisClass = secondStackAsType(INSTANCE_CLASS);    /* The 11 steps as documented in page 53 of the virtual machine spec. */    switch (state) {    case 1:        /* A short cut that'll probably happen 99% of the time.  This class         * has no monitor, and no one is in the middle of initializing this         * class.  Since our scheduler is non preemptive, we can just         * mark the class, without worrying about the monitor or other threads.         */        if (!OBJECT_HAS_MONITOR(&thisClass->clazz)                && thisClass->initThread == NULL) {             goto markClass;        }        /* Step 1:  Grab the class monitor so we have exclusive access. */        if (monitorEnter((OBJECT)thisClass) != MonitorStatusOwn) {            /* We've been forced to wait.  When we're awoken, we'll have             * the lock */            topStack = 2;            return;        } else {            /* FALL THROUGH.  We have the lock */        }    case 2:        haveMonitor = TRUE;        if (thisClass->initThread && thisClass->initThread != CurrentThread) {            /* Step 2:             * Someone else is initializing this class.  Just wait until             * a notification.  Of course, we'll have to recheck, since the             * class could also be notified for other reasons.             */            long64 timeout;            ll_setZero(timeout);            monitorWait((OBJECT)thisClass, timeout);            topStack = 2;            return;        }     markClass:        if (thisClass->initThread == CurrentThread ||                   thisClass->status == CLASS_READY) { /* step 4 */            /* Step 3, Step 4:             * This thread is already initializing the class, or the class             * has somehow already become initialized.  We're done.             */            if (haveMonitor) {                 char *junk;                monitorExit((OBJECT)thisClass, &junk);            }            popFrame();            return;        }         if (thisClass->status == CLASS_ERROR) {            /* Step 5:             * What can we do?             */            popFrame();            return;        }        /* Step 6:         * Mark that we're about to initialize this class */        setClassInitialThread(thisClass, CurrentThread);        if (haveMonitor) {            char *junk;            monitorExit((OBJECT)thisClass, &junk);            haveMonitor = FALSE;        }        /* FALL THROUGH */    case 3:        /* Step 7:         * Initialize the superclass, if necessary */        if ((thisClass->clazz.accessFlags & ACC_INTERFACE) == 0) {            INSTANCE_CLASS superClass = thisClass->superClass;            if (superClass && superClass->status != CLASS_READY) {                topStack = 4;                initializeClass(superClass);                return;            }        }        /* FALL THROUGH */    case 4: {        /* Step 8:         * Run the <clinit> method, if the class has one         */        METHOD thisMethod = getSpecialMethod(thisClass, clinitNameAndType);        if (thisMethod) {#if INCLUDEDEBUGCODE            if (traceclassloading || traceclassloadingverbose) {                START_TEMPORARY_ROOTS                    fprintf(stdout, "Initializing class: '%s'\n",                            getClassName((CLASS)thisClass));                END_TEMPORARY_ROOTS            }#endif /* INCLUDEDEBUGCODE */            topStack = 5;            if (!pushFrame(thisMethod)) {                /* Stack overflow while pushing the frame */                setClassStatus(thisClass, CLASS_ERROR);                popFrame();            }            return;        } else {            /* No <clinit> method. */            /* FALL THROUGH */        }    }    case 5:        /* Step 9:         * Grab the monitor so we can change the flags, and wake up any         * other thread waiting on us.         *         * SHORTCUT:  99% of the time, there is no contention for the class.         * Since our scheduler is non-preemptive, if there is no contention         * for this class, we just go ahead and unmark the class, without         * bothering with the monitor.         */        if (!OBJECT_HAS_MONITOR(&thisClass->clazz)) {            goto unmarkClass;        }        if (monitorEnter((OBJECT)thisClass) != MonitorStatusOwn) {            /* When we wake up, we'll have the monitor */            topStack = 6;            return;        } else {            /* FALL THROUGH */        }    case 6:        haveMonitor = TRUE;        /* Step 9, cont.         * Mark the class as initialized. Wake up anyone waiting for the         * class to be initialized.  Return the monitor.         */    unmarkClass:        setClassInitialThread(thisClass, NULL);        setClassStatus(thisClass, CLASS_READY);#if ENABLE_JAVA_DEBUGGER        if (vmDebugReady) {            CEModPtr cep = GetCEModifier();            cep->loc.classID = GET_CLASS_DEBUGGERID(&thisClass->clazz);            cep->threadID = getObjectID((OBJECT)CurrentThread->javaThread);            cep->eventKind = JDWP_EventKind_CLASS_PREPARE;            insertDebugEvent(cep);        }#endif        if (haveMonitor) {            char *junk;            monitorNotify((OBJECT)thisClass, TRUE); /* wakeup everyone */            monitorExit((OBJECT)thisClass, &junk);        }        popFrame();        return;        /* Step 10, 11:         * These handle error conditions that cannot currently be         * implemented in the KVM.         */    default:        fatalVMError(KVM_MSG_STATIC_INITIALIZER_FAILED);    }}static void runClinitException(FRAME_HANDLE frameH){     INSTANCE_CLASS thisClass;    START_TEMPORARY_ROOTS        void **bottomStack = (void **)(unhand(frameH) + 1); /* transient */        DECLARE_TEMPORARY_ROOT(THROWABLE_INSTANCE, exception, bottomStack[0]);        thisClass = bottomStack[1];        setClassStatus(thisClass, CLASS_ERROR);        setClassInitialThread(thisClass, NULL);        /* Handle exception during clinit */        if (!isAssignableTo((CLASS)(exception->ofClass), (CLASS)JavaLangError)) {            /* Replace exception with Error, then continue the throwing */            DECLARE_TEMPORARY_ROOT(THROWABLE_INSTANCE, error,                 (THROWABLE_INSTANCE)instantiate(JavaLangError));            DECLARE_TEMPORARY_ROOT(STRING_INSTANCE, messageString,                 exception->message);            char *p = str_buffer;            /* Create the new message:             *   Static initializer: <className of throwable> <message>             */            strcpy(p, "Static initializer: ");            p += strlen(p);            getClassName_inBuffer(&exception->ofClass->clazz, p);            p += strlen(p);            if (messageString != NULL) {                strcpy(p, ": ");                p += strlen(p);                getStringContentsSafely(messageString, p,                    STRINGBUFFERSIZE - (p - str_buffer));                p += strlen(p);            }            error->message = instantiateString(str_buffer, p - str_buffer);            /* Replace the exception with our new Error, continue throwing */            *(THROWABLE_INSTANCE *)(unhand(frameH) + 1) = error;        }    END_TEMPORARY_ROOTS            /* If any other thread is waiting for this, we should try to wake them     * up if we can.     */    if (OBJECT_HAS_REAL_MONITOR(&thisClass->clazz)) {         MONITOR monitor = OBJECT_MHC_MONITOR(&thisClass->clazz);        if (monitor->owner == NULL || monitor->owner == CurrentThread) {             char *junk;            monitorEnter((OBJECT)thisClass);            monitorNotify((OBJECT)thisClass, TRUE); /* wakeup everyone */            monitorExit((OBJECT)thisClass, &junk);        }    }}

⌨️ 快捷键说明

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