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

📄 collector.c

📁 已经移植好的java虚拟机
💻 C
📖 第 1 页 / 共 5 页
字号:
    }    return result;#else /* ENABLE_HEAP_COMPACTION */    result = callocObject(size, GCT_NOPOINTERS);    OBJECT_HEADER(result) |= STATICBIT;    return result;#endif /* ENABLE_HEAP_COMPACTION */}/*========================================================================= * Garbage collection operations *=======================================================================*/voidgarbageCollectForReal(int realSize){    CHUNK firstFreeChunk;    long maximumFreeSize;    markRootObjects();    markNonRootObjects();    markWeakPointerLists();    firstFreeChunk = sweepTheHeap(&maximumFreeSize);#if ENABLE_HEAP_COMPACTION    if (realSize > maximumFreeSize) {        /* We need to compact the heap. */        breakTableStruct currentTable;        cell* freeStart = compactTheHeap(&currentTable, firstFreeChunk);        if (currentTable.length > 0) {            updateRootObjects(&currentTable);            updateHeapObjects(&currentTable, freeStart);        }        if (freeStart < CurrentHeapEnd - 1) {            firstFreeChunk = (CHUNK)freeStart;            firstFreeChunk->size =                (CurrentHeapEnd - freeStart - HEADERSIZE) << TYPEBITS;            firstFreeChunk->next = NULL;        } else {            /* We are so utterly hosed.             * Memory is completely full, and there is no free space whatsoever.             */            firstFreeChunk = NULL;        }    }#endif    FirstFreeChunk = firstFreeChunk;}/*========================================================================= * FUNCTION:      markRootObjects * TYPE:          private garbage collection operation * OVERVIEW:      Marks the root objects of garbage collection * INTERFACE: *   parameters:  none *   returns:     none *=======================================================================*/static voidmarkRootObjects(void){    cell *heapSpace = CurrentHeap;    cell *heapSpaceEnd = CurrentHeapEnd;    cellOrPointer *ptr, *endptr;    HASHTABLE stringTable;    THREAD thread;    ptr = &GlobalRoots[0];    endptr = ptr + GlobalRootsLength;    for ( ; ptr < endptr; ptr++) {        MARK_OBJECT_IF_NON_NULL(*(ptr->cellpp));    }    ptr = &TemporaryRoots[0];    endptr = ptr + TemporaryRootsLength;    for ( ; ptr < endptr; ptr++) {        cellOrPointer location = *ptr;        if (location.cell == -1) {            /* Actual Location is ptr[1], base is ptr[2] */            MARK_OBJECT_IF_NON_NULL(ptr[2].cellpp);            ptr += 2;        } else {            MARK_OBJECT_IF_NON_NULL(*(location.cellpp));        }    }#if ASYNCHRONOUS_NATIVE_FUNCTIONS{    int i;    for (i = 0 ; i < ASYNC_IOCB_COUNT ; i++) {        ASYNCIOCB *aiocb = &IocbRoots[i];        MARK_OBJECT_IF_NON_NULL(aiocb->thread);        MARK_OBJECT_IF_NON_NULL(aiocb->instance);        MARK_OBJECT_IF_NON_NULL(aiocb->array);    }}#endif#if ROMIZING    {        /* In RELOCATABLE_ROM builds, we have a pointer to the static data.         * In !RELOCATABLE_ROM builds, we have the actual array.         */#if RELOCATABLE_ROM        long *staticPtr = KVM_staticDataPtr;#else        long *staticPtr = KVM_staticData;#endif        int refCount = staticPtr[0];        for( ; refCount > 0; refCount--) {            MARK_OBJECT_IF_NON_NULL((cell *)staticPtr[refCount]);        }    }#endif    stringTable = InternStringTable;    if (ROMIZING || stringTable != NULL) {        int count = stringTable->bucketCount;        while (--count >= 0) {            INTERNED_STRING_INSTANCE instance =                (INTERNED_STRING_INSTANCE)stringTable->bucket[count];            for ( ; instance != NULL; instance = instance->next) {                checkMonitorAndMark((OBJECT)instance);            }        }    }    if (ROMIZING || ClassTable != NULL) {        FOR_ALL_CLASSES(clazz)            checkMonitorAndMark((OBJECT)clazz);            if (!IS_ARRAY_CLASS(clazz)) {                INSTANCE_CLASS iclazz = (INSTANCE_CLASS)clazz;                POINTERLIST statics = iclazz->staticFields;                METHODTABLE  methodTable = iclazz->methodTable;                MARK_OBJECT_IF_NON_NULL(iclazz->initThread);                if (clazz->accessFlags & ACC_ROM_CLASS) {                    continue;                }                if (USESTATIC) {                    MARK_OBJECT_IF_NON_NULL(iclazz->constPool);                    MARK_OBJECT_IF_NON_NULL(iclazz->ifaceTable);                    MARK_OBJECT_IF_NON_NULL(iclazz->fieldTable);                    MARK_OBJECT_IF_NON_NULL(iclazz->methodTable);                }                if (statics != NULL) {                    int count = statics->length;                    while (--count >= 0) {                        MARK_OBJECT_IF_NON_NULL(statics->data[count].cellp);                    }                }                if (iclazz->status == CLASS_VERIFIED) {                    continue;                }                FOR_EACH_METHOD(thisMethod, methodTable)                    /* Mark the bytecode object alive for non-native methods */                    if (!(thisMethod->accessFlags & ACC_NATIVE)) {                        checkValidHeapPointer((cell *)                               thisMethod->u.java.stackMaps.verifierMap);                        MARK_OBJECT_IF_NON_NULL(thisMethod->u.java.stackMaps.verifierMap);                    }                END_FOR_EACH_METHOD            }        END_FOR_ALL_CLASSES    }    for (thread = AllThreads; thread != NULL; thread = thread->nextAliveThread){        MARK_OBJECT(thread);        if (thread->javaThread != NULL) {            MARK_OBJECT(thread->javaThread);        }        if (thread->stack != NULL) {            markThreadStack(thread);        }    }}#if ENABLE_HEAP_COMPACTIONstatic voidupdateRootObjects(breakTableStruct *currentTable){    HASHTABLE stringTable;    cellOrPointer *ptr, *endptr;    ptr = &GlobalRoots[0];    endptr = ptr + GlobalRootsLength;    for ( ; ptr < endptr; ptr++) {        updatePointer(ptr->cellpp, currentTable);    }    ptr = &TemporaryRoots[0];    endptr = ptr + TemporaryRootsLength;    for ( ; ptr < endptr; ptr++) {        cellOrPointer location = *ptr;        if (location.cell == -1) {            /* Actual Location is ptr[1], base is ptr[2] */            long offset = *(ptr[1].charpp) - ptr[2].charp;            updatePointer(&ptr[2], currentTable);            *(ptr[1].charpp) = ptr[2].charp + offset;            ptr += 2;        } else {            updatePointer(location.cellpp, currentTable);        }    }#if ASYNCHRONOUS_NATIVE_FUNCTIONS{    int i;    for (i = 0 ; i < ASYNC_IOCB_COUNT ; i++) {        ASYNCIOCB *aiocb = &IocbRoots[i];        updatePointer(&aiocb->thread, currentTable);        updatePointer(&aiocb->instance, currentTable);        updatePointer(&aiocb->array, currentTable);    }}#endif#if ROMIZING    {        /* In RELOCATABLE_ROM builds, we have a pointer to the static data.         * In !RELOCATABLE_ROM builds, we have the actual array.         */#if RELOCATABLE_ROM        long *staticPtr = KVM_staticDataPtr;#else        long *staticPtr = KVM_staticData;#endif        int refCount = staticPtr[0];        for( ; refCount > 0; refCount--) {            updatePointer(&staticPtr[refCount], currentTable);        }    }#endif /* ROMIZING */    stringTable = InternStringTable;    if (ROMIZING || stringTable != NULL) {        int count = stringTable->bucketCount;        while (--count >= 0) {            INTERNED_STRING_INSTANCE instance =                (INTERNED_STRING_INSTANCE)stringTable->bucket[count];            for ( ; instance != NULL; instance = instance->next) {                updateMonitor((OBJECT)instance, currentTable);            }        }    }    if (ROMIZING || ClassTable != NULL) {        FOR_ALL_CLASSES(clazz)            updateMonitor((OBJECT)clazz, currentTable);            if (!IS_ARRAY_CLASS(clazz)) {                INSTANCE_CLASS iclazz = (INSTANCE_CLASS)clazz;                POINTERLIST statics = iclazz->staticFields;                THREAD initThread = iclazz->initThread;                if (initThread != NULL) {                    updatePointer(&initThread, currentTable);                    setClassInitialThread(iclazz, initThread);                }                if (clazz->accessFlags & ACC_ROM_CLASS) {                    continue;                }                if (USESTATIC) {                    updatePointer(&iclazz->constPool, currentTable);                    updatePointer(&iclazz->ifaceTable, currentTable);                    updatePointer(&iclazz->fieldTable, currentTable);                    updatePointer(&iclazz->methodTable, currentTable);                }                if (statics != NULL) {                    int count = statics->length;                    while (--count >= 0) {                        updatePointer(&statics->data[count].cellp, currentTable);                    }                }                if (iclazz->status == CLASS_VERIFIED) {                    continue;                }                FOR_EACH_METHOD(thisMethod, iclazz->methodTable)                    if (!(thisMethod->accessFlags & ACC_NATIVE)) {                        if (!USESTATIC || inCurrentHeap(thisMethod)) {                            updatePointer(&thisMethod->u.java.stackMaps.verifierMap, currentTable);                        } else {                            POINTERLIST oldValue = thisMethod->u.java.stackMaps.verifierMap;                            POINTERLIST newValue = oldValue;                            updatePointer(&newValue, currentTable);                            if (oldValue != newValue) {                                CONSTANTPOOL cp = iclazz->constPool;                                int offset = (char *)&thisMethod->u.java.stackMaps.pointerMap                                            - (char *)cp;                                modifyStaticMemory(cp, offset, &newValue, sizeof(POINTERLIST));                            }                        }                    }                END_FOR_EACH_METHOD            }        END_FOR_ALL_CLASSES    }}#endif /* ENABLE_HEAP_COMPACTION *//*========================================================================= * FUNCTION:      markNonRootObjects * TYPE:          private garbage collection operation * OVERVIEW:      Scan the heap looking for objects that are reachable only *                from other heap objects. * INTERFACE: *   parameters:  None *   returns:     <nothing> * COMMENTS:      This code >>tries<< to do all its work in a single pass *                through the heap.  For each live object in the heap, it *                calls the function markChildren().  This latter function *                sets the variable deferredObjectTableOverflow if it was *                ever unable to completely following the children of an *                object because of recursion overflow.  In this rare case, *                we just rescan the heap.  We're guaranteed to get further *                to completion on each pass. *=======================================================================*/#define MAX_GC_DEPTH 4static voidmarkNonRootObjects(void) {    /* Scan the entire heap, looking for badly formed headers */    cell* scanner;    cell* endScanPoint = CurrentHeapEnd;    int scans = 0;    do {        WeakPointers = NULL;        initializeDeferredObjectTable();        for (scanner = CurrentHeap;                scanner < endScanPoint;                scanner += SIZE(*scanner) + HEADERSIZE) {            if (ISMARKED(*scanner)) {                cell *object = scanner + 1;                /* See markChildren() for comments on the arguments */                markChildren(object, object, MAX_GC_DEPTH);            }        }        if (ENABLEPROFILING) {            scans++;        }        /* This loop runs exactly once in almost all cases */    } while (deferredObjectTableOverflow);#if ENABLEPROFILING    GarbageCollectionRescans += (scans - 1);

⌨️ 快捷键说明

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