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

📄 collector.c

📁 已经移植好的java虚拟机
💻 C
📖 第 1 页 / 共 5 页
字号:
    if (CurrentThread) {        currentNativeLp = CurrentThread->nativeLp;    }    for (list = WeakPointers; list != NULL; list = list->gcReserved) {        void (*finalizer)(INSTANCE_HANDLE) = list->finalizer;        cellOrPointer *ptr = &list->data[0];        cellOrPointer *endPtr = ptr + list->length;        for (; ptr < endPtr; ptr++) {            cell* object = ptr->cellp;            if (object != NULL) {                if (!ISKEPT((object)[-HEADERSIZE])) {                    ptr->cellp = NULL;                    if (finalizer) {                        /* In KVM, making the 'this' pointer available   */                        /* in native finalizers is rather painful.       */                        /* KVM doesn't create stack frames for native    */                        /* methods, and therefore the stack may not      */                        /* contain anything to which 'nativeLp' could    */                        /* point to create access to the 'this' pointer. */                        /* Therefore, it is necessary to set 'nativeLp'  */                        /* to point to a 'fake' location each time we    */                        /* need to call a native finalizer.              */                        if (CurrentThread) {                            CurrentThread->nativeLp = (cell *)&object;                        }                        /* In KVM 1.0.4, we pass the object to */                        /* the finalizer as a handle. This makes */                        /* it possible to define native finalizers */                        /* as KNI functions that take a 'jobject' */                        /* parameter. */                        finalizer((INSTANCE_HANDLE)&object);                    }                }            }        }    }    /* Restore the original 'nativeLp' */    if (CurrentThread) {        CurrentThread->nativeLp = currentNativeLp;    }}#if ENABLE_HEAP_COMPACTIONstatic voidupdateHeapObjects(breakTableStruct *currentTable, cell* endScanPoint){    cell* scanner;    for (   scanner = CurrentHeap;            scanner < endScanPoint;            scanner += SIZE(*scanner) + HEADERSIZE) {        cell *header = scanner;        cell *object = scanner + 1;        GCT_ObjectType gctype = TYPE(*header);        switch (gctype) {            int length;            cell **ptr;        case GCT_INSTANCE: {            /* The object is a Java object instance.  Mark pointer fields */            INSTANCE instance = (INSTANCE)object;            INSTANCE_CLASS clazz = instance->ofClass;            updateMonitor((OBJECT)instance, currentTable);            while (clazz) {                FOR_EACH_FIELD(thisField, clazz->fieldTable)                    /* Is this a non-static pointer field? */                    if ((thisField->accessFlags & (ACC_POINTER | ACC_STATIC))                               == ACC_POINTER) {                       updatePointer(&instance->data[thisField->u.offset].cellp,                                     currentTable);                    }                END_FOR_EACH_FIELD                clazz = clazz->superClass;            }            break;        }        case GCT_ARRAY: {            /* The object is a Java array with primitive values. */            /* Only the possible monitor will have to be marked alive. */            updateMonitor((OBJECT)object, currentTable);        }        break;        case GCT_POINTERLIST: {            POINTERLIST list = (POINTERLIST)object;            length = list->length;            ptr = &list->data[0].cellp;            goto markArray;        }        case GCT_WEAKPOINTERLIST: {            WEAKPOINTERLIST list = (WEAKPOINTERLIST)object;            length = list->length;            ptr = &list->data[0].cellp;            goto markArray;        }        case GCT_OBJECTARRAY: {            /* The object is a Java array with object references. */            /* The contents of the array and the possible monitor  */            /* will have to be scanned. */            ARRAY array = (ARRAY)object;            updateMonitor((OBJECT)array, currentTable);            length = array->length;            ptr = &array->data[0].cellp;            /* FALL THROUGH */        }        markArray:            /* Keep objects in the array alive. */            while (--length >= 0) {                updatePointer(ptr, currentTable);                ptr++;            }            break;        case GCT_MONITOR: {            MONITOR monitor  = (MONITOR)object;            updatePointer(&monitor->owner, currentTable);            updatePointer(&monitor->monitor_waitq, currentTable);            updatePointer(&monitor->condvar_waitq, currentTable);#if INCLUDEDEBUGCODE            updatePointer(&monitor->object, currentTable);#endif            break;        }        case GCT_THREAD: {            THREAD thread  = (THREAD)object;            updatePointer(&thread->nextAliveThread, currentTable);            updatePointer(&thread->nextThread, currentTable);            updatePointer(&thread->javaThread, currentTable);            updatePointer(&thread->monitor, currentTable);            updatePointer(&thread->nextAlarmThread, currentTable);            updatePointer(&thread->stack, currentTable);#if  ENABLE_JAVA_DEBUGGER          {            updatePointer(&thread->stepInfo.fp, currentTable);          }#endif            if (thread->fpStore != NULL) {                updateThreadAndStack(thread, currentTable);            }            break;        }        case GCT_NOPOINTERS:            break;        case GCT_EXECSTACK:            /* This is handled by the thread that the stack belongs to. */            break;        case GCT_METHODTABLE:            FOR_EACH_METHOD(thisMethod, ((METHODTABLE)object))                if ((thisMethod->accessFlags & ACC_NATIVE) == 0) {                    updatePointer(&thisMethod->u.java.code, currentTable);                    updatePointer(&thisMethod->u.java.handlers, currentTable);                }            END_FOR_EACH_METHOD            break;        default:            /* We should never get here as isValidHeapPointer should */            /* guarantee that the header tag of this object is in the */            /* range GCT_FIRSTVALIDTAG && GCT_LASTVALIDTAG */            fatalError(KVM_MSG_BAD_DYNAMIC_HEAP_OBJECTS_FOUND);        } /* End of switch statement */    } /* End of for statement */}static voidupdateMonitor(OBJECT object, breakTableStruct *currentTable){    if (OBJECT_HAS_MONITOR(object)) {        /* The monitor slot contains either a MONITOR or a THREAD,         * incremented by a small constant, so we will be pointing into the         * middle of the first word.         *         * In this collector, updatePointer() correctly handles pointers into         * the middle of an object, so the following code is simpler then it         * would be with other collectors.         */        void *oldTemp = object->mhc.address;        void *newTemp = oldTemp;        updatePointer((cell **)&newTemp, currentTable);        if (!USESTATIC || (oldTemp != newTemp)) {            SET_OBJECT_MHC_ADDRESS(object, (char *)newTemp);        }    }}static voidupdateThreadAndStack(THREAD thread, breakTableStruct *currentTable){    char   map[(MAXIMUM_STACK_AND_LOCALS + 7) >> 3];    long   delta;    FRAME  thisFP;    cell*  thisSP;    BYTE*  thisIP;    STACK  oldStack, newStack, stack;    int    i;    updatePointer(&thread->fpStore, currentTable);    updatePointer(&thread->spStore, currentTable);    /* Added for KNI */    updatePointer(&thread->nativeLp, currentTable);    thisSP = thread->spStore;   /* new address */    thisFP = thread->fpStore;   /* new address*/    thisIP = thread->ipStore;    oldStack = stack = thisFP->stack;    updatePointer(&stack, currentTable);    newStack = stack;    delta = PTR_DELTA(newStack, oldStack);    for (;;) {        /* thisSP and thisFP are pointers to the current frame         *       in new space.         * oldStack and newStack contain the old and new addresses of the         *       stack containing the current frame.         */        METHOD method = thisFP->thisMethod;        cell* localVars = FRAMELOCALS(thisFP);        cell *operandStack = (cell*)thisFP + SIZEOF_FRAME;        int localsCount = method->frameSize;        long realStackSize = thisSP - (cell*)thisFP - SIZEOF_FRAME + 1;        unsigned int totalSize = realStackSize + localsCount;        FRAME previousFp;        /* Mark the possible synchronization object alive */        updatePointer(&thisFP->syncObject, currentTable);        if (method == RunCustomCodeMethod) {            memset(map, -1, (realStackSize + 7) >> 3);        } else {            getGCRegisterMask(method, thisIP, map);        }        for (i = 0; i < totalSize; i++) {            if (map[i >> 3] & (1 << (i & 7))) {                cell **argP;                if (i < localsCount) {                    argP = (cell **)&localVars[i];                } else {                    argP = (cell **)&operandStack[i - localsCount];                }                updatePointer(argP, currentTable);            }        }        if (INCLUDEDEBUGCODE && thisFP->stack != oldStack) {            fatalError(KVM_MSG_BAD_STACK_INFORMATION);        }        thisFP->stack = newStack;        previousFp = thisFP->previousFp; /* old address of previousFP */        if (previousFp == NULL) {            break;        } else {            STACK prevOldStack, prevNewStack;            updatePointer(&previousFp, currentTable);            prevOldStack = previousFp->stack;  /* old address */            if (prevOldStack == oldStack) {                thisFP->previousSp = PTR_OFFSET(thisFP->previousSp, delta);                thisFP->previousFp = PTR_OFFSET(thisFP->previousFp, delta);            } else {                updatePointer(&thisFP->previousFp, currentTable);                updatePointer(&thisFP->previousSp, currentTable);                stack = prevOldStack;                updatePointer(&stack, currentTable);                prevNewStack = stack;                prevNewStack->next = newStack;                oldStack = prevOldStack;                newStack = prevNewStack;                delta = PTR_DELTA(newStack, oldStack);            }        }        /* This frame is now done.  Go to the previous one. */        thisSP = thisFP->previousSp;        thisIP = thisFP->previousIp;        thisFP = thisFP->previousFp;    }}#endif /* ENABLE_HEAP_COMPACTION *//*========================================================================= * Deferred objects, as part of markChildren. * * These functions create a queue of objects that are waiting to be * scanned so that their children can be marked.  The active part of the * starts at startDeferredObjects and ends just before endDeferredObjects. * This queue is circular. * * The two main functions are putDeferredObject() and getDeferredObject() * which add and remove objects from the queue.  putDeferredObject() * correctly handles overflow.  getDeferredObject() presumes that the user * has first checked that there is an object to be gotten. *=======================================================================*//*========================================================================= * FUNCTION:      initializeDeferredObjectTable * TYPE:          scanning the heap * OVERVIEW:      Initialize the deferred object table so that it correctly *                behaves like a queue. * INTERFACE: *   parameters:  <none> *=======================================================================*/static void initializeDeferredObjectTable(void) {    startDeferredObjects = endDeferredObjects = deferredObjectTable;    deferredObjectCount = 0;    deferredObjectTableOverflow = FALSE;}/*========================================================================= * FUNCTION:      putDeferredObject * TYPE:          scanning the heap * OVERVIEW:      Add an object to the end of the queue.  If the queue is *                full, just set the variable deferredObjectTableOverflow *                and ignore the request. * INTERFACE: *   parameters:  value: An object to put on the queue *=======================================================================*/static voidputDeferredObject(cell *value){    if (deferredObjectCount >= DEFERRED_OBJECT_TABLE_SIZE) {        deferredObjectTableOverflow = TRUE;    } else {        if (endDeferredObjects == endDeferredObjectTable) {            endDeferredObjects = deferredObjectTable;        }        *endDeferredObjects++ = value;        deferredObjectCount++;    }#if ENABLEPROFILING    if (deferredObjectCount > MaximumGCDeferrals) {        MaximumGCDeferrals = deferredObjectCount;    }    TotalGCDeferrals++;#endif

⌨️ 快捷键说明

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