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

📄 collectordebug.c

📁 已经移植好的java虚拟机
💻 C
📖 第 1 页 / 共 3 页
字号:
                garbageCollect(-1);            } else {                /* We've already garbage collected, so we can't compact the                 * heap any more */                fatalError(KVM_MSG_UNABLE_TO_EXPAND_PERMANENT_MEMORY);            }        } else {            /* We're currently allocating into HeapSpace 1 */            if (CurrentHeapFreePtr < newPermanentSpace) {                /* Let's put a fake object to fill up the space between                 * the old pointer and the new, just in case we decide to                 * scan memory */                int delta = (CurrentHeap - newHeapSpace1);                *(newHeapSpace1) =                    (GCT_NOPOINTERS << 2) + ((delta - 1) << TYPEBITS);                CurrentHeap = newHeapSpace1;                CurrentHeapEnd = newPermanentSpace;                break;            } else {                garbageCollect(0);            }        }    }    /* Zero then new memory */    memset((char *)newPermanentSpace, 0,           PTR_DELTA(PermanentSpace, newPermanentSpace));    nHeapSize = newHeapSize;    PermanentSpace = newPermanentSpace;#else    fatalError(KVM_MSG_UNABLE_TO_EXPAND_PERMANENT_MEMORY);#endif /* CHENEY_TWO_SPACE */}static voidcopyRootObjects(void){    cellOrPointer *ptr, *endptr;    HASHTABLE stringTable;    ptr = &GlobalRoots[0];    endptr = ptr + GlobalRootsLength;    for ( ; ptr < endptr; ptr++) {        updatePointer(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] */            long offset = *(ptr[1].charpp) - ptr[2].charp;            updatePointer(&ptr[2]);            *(ptr[1].charpp) = ptr[2].charp + offset;            ptr += 2;        } else {            updatePointer(location.cellpp);        }    }#if ASYNCHRONOUS_NATIVE_FUNCTIONS{    int i;    for (i = 0 ; i < ASYNC_IOCB_COUNT ; i++) {        ASYNCIOCB *aiocb = &IocbRoots[i];        updatePointer(&aiocb->thread);        updatePointer(&aiocb->instance);        updatePointer(&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        cell **staticPtrData = (cell **)KVM_staticDataPtr;#else        cell **staticPtrData = (cell **)KVM_staticData;#endif        int refCount = ((int *)staticPtrData)[0];        cell **staticPtr = staticPtrData + 1;        cell **lastStaticPtr = staticPtr + refCount;        while (staticPtr < lastStaticPtr) {            updatePointer(staticPtr);            staticPtr++;        }    }#endif /* ROMIZING */    if (ROMIZING || ClassTable != NULL) {        FOR_ALL_CLASSES(clazz)            updateMonitor((OBJECT)clazz);            if (!IS_ARRAY_CLASS(clazz)) {                INSTANCE_CLASS iclazz = (INSTANCE_CLASS)clazz;                POINTERLIST statics = iclazz->staticFields;                THREAD initThread = iclazz->initThread;                if (initThread != NULL) {                    updatePointer(&initThread);                    setClassInitialThread(iclazz, initThread);                }                if (clazz->accessFlags & ACC_ROM_CLASS) {                    continue;                }                if (USESTATIC) {                    updatePointer(&iclazz->constPool);                    updatePointer(&iclazz->ifaceTable);                    updatePointer(&iclazz->fieldTable);                    updatePointer(&iclazz->methodTable);                }                if (statics != NULL) {                    int count = statics->length;                    while (--count >= 0) {                        updatePointer(&statics->data[count].cellp);                    }                }                if (iclazz->status == CLASS_VERIFIED) {                    continue;                }                FOR_EACH_METHOD(thisMethod, iclazz->methodTable)                    /*  Mark the bytecode object alive for non-native methods */                    if (!(thisMethod->accessFlags & ACC_NATIVE)) {                        if (!USESTATIC || inTargetSpace(thisMethod)) {                            updatePointer(&thisMethod->u.java.stackMaps.verifierMap);                        } else {                            POINTERLIST oldValue = thisMethod->u.java.stackMaps.verifierMap;                            POINTERLIST newValue = oldValue;                            updatePointer(&newValue);                            if (oldValue != newValue) {                                CONSTANTPOOL cp = iclazz->constPool;                                int offset = PTR_DELTA(                                       &thisMethod->u.java.stackMaps.pointerMap,                                       cp);                                modifyStaticMemory(cp, offset, &newValue, sizeof(POINTERLIST));                            }                        }                    }                END_FOR_EACH_METHOD            }        END_FOR_ALL_CLASSES    }    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);            }        }    }}static voidcopyNonRootObjects(){    cell* scanner;    for (   scanner = TargetSpace;            scanner < TargetSpaceFreePtr;            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);            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);                    }                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);        }        break;        case GCT_POINTERLIST: {            POINTERLIST list = (POINTERLIST)object;            length = list->length;            ptr = &list->data[0].cellp;            goto markArray;        }        case GCT_WEAKPOINTERLIST:            /* Push this object onto the linked list of weak pointers */            ((WEAKPOINTERLIST)object)->gcReserved = WeakPointers;            WeakPointers = (WEAKPOINTERLIST)object;            break;        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);            length = array->length;            ptr = &array->data[0].cellp;            /* FALL THROUGH */        }        markArray:            /* Keep objects in the array alive. */            while (--length >= 0) {                updatePointer(ptr);                ptr++;            }            break;        case GCT_MONITOR: {            MONITOR monitor  = (MONITOR)object;            updatePointer(&monitor->owner);            updatePointer(&monitor->monitor_waitq);            updatePointer(&monitor->condvar_waitq);#if INCLUDEDEBUGCODE            updatePointer(&monitor->object);#endif            break;        }        case GCT_THREAD: {            THREAD thread  = (THREAD)object;            updatePointer(&thread->nextAliveThread);            updatePointer(&thread->nextThread);            updatePointer(&thread->javaThread);            updatePointer(&thread->monitor);            updatePointer(&thread->nextAlarmThread);            updatePointer(&thread->stack);            if (thread->fpStore != NULL) {                updateThreadAndStack(thread);            }            break;        }        case GCT_NOPOINTERS:            break;        case GCT_EXECSTACK:            /* This is ugly, but it gets handled by GCT_THREAD; */            break;        case GCT_METHODTABLE:            FOR_EACH_METHOD(thisMethod, ((METHODTABLE)object))                if ((thisMethod->accessFlags & ACC_NATIVE) == 0) {                    updatePointer(&thisMethod->u.java.code);                    updatePointer(&thisMethod->u.java.handlers);                }            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 voidcopyWeakPointerLists(){    WEAKPOINTERLIST list;    /* save the current native method pointer */    cell* currentNativeLp;    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 (ISMARKED((object)[-HEADERSIZE])) {                    ptr->cellp = (cell *)(((object)[-HEADERSIZE]) & ~MARKBIT);                } else {                    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;    }}static void updateThreadAndStack(THREAD thread) {    /* Note that when this is called, some (or all) of the thread stacks     * may have already been copied into new space.  However none of the     * stacks, themselves, have been scanned.

⌨️ 快捷键说明

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