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

📄 gc_impl.c

📁 This is a resource based on j2me embedded,if you dont understand,you can connection with me .
💻 C
📖 第 1 页 / 共 2 页
字号:
	/* This area has now been allocated. Mark it so. */	CVMmsSetBitFor((CVMUint32*)allocatedArea, theHeap->boundaries);#ifdef CVM_MS_TRACE	CVMconsolePrintf("GC: tryAlloc(%d) (best fit) OK in %d iterations"			 " -> 0x%x\n",			 numBytes, noIter, allocatedArea);#endif	freeBytes -= numBytes;	return (CVMObject*)allocatedArea;    }#ifdef CVM_MS_TRACE    CVMconsolePrintf("GC: tryAlloc(%d) failed!\n", numBytes);#endif    return 0; /* No luck */}/* * The following will collapse all small linked lists and join them * with the big one. This operations is performed as a last resort * when allocation has failed, even after a GC.   */static voidCVMmsCollapseFreeLists(){    CVMUint32       listNo = 0;    CVMMsFreeBlock *chunk;    #ifdef CVM_MS_TRACE    CVMconsolePrintf("GC: Collapsing free lists\n");#endif    /*     * Take each of the free lists and put them in the big list.     */    for (listNo = 0; listNo < CVM_MS_NFREELISTS; listNo++) {	chunk = CVMmsFreeLists[listNo];	if (chunk != 0) {	    CVMmsFreeLists[listNo] = 0;	    while (chunk != 0) {		/*		 * Add to last bin. The next allocation will		 * coalesce all adjacent free blocks anyway.		 */		CVMmsAddToFreeList((CVMUint32 *) chunk, chunk->blockSize,				   CVM_MS_NFREELISTS);		chunk = chunk->nextFree;	    }	}    }}static voidCVMmsSweep(){    /*     * Iterate over the boundaries and marks arrays, and figure out     * who's live and who's dead. Reclaim the dead.     */    CVMUint32* marksBegin = theHeap->markbits;    CVMUint32* marks = &theHeap->markbits[theHeap->sizeOfBitmaps/4] - 1;    CVMUint32* boundaries = &theHeap->boundaries[theHeap->sizeOfBitmaps/4] - 1;    CVMUint32* heapPtr = &theHeap->data[theHeap->size/4] - 1;    CVMUint32* otherHeapPtr = heapPtr;    while (marks >= marksBegin) {	CVMUint32 currBoundaries = *boundaries;	/*	 * Don't bother looking unless there are allocated objects	 * in this 32-word segment	 */	if (currBoundaries != 0) {	    CVMUint32 currMarks = *marks;	    CVMUint32 toClear = currBoundaries & ~currMarks;	    	    /*	     * Take those objects that are not marked and put them in	     * their respective linked lists.	     */	    while (toClear != 0) {		if ((toClear & 0x80000000) != 0) {		    CVMUint32 objSize;		    /*		     * Make sure we're looking at an object we have allocated		     */		    CVMassert(CVMmsMarkedIn(heapPtr, theHeap->boundaries));		    /*		     * Look in the object's header to figure out		     * how large it is.		     */		    objSize = CVMobjectSize((CVMObject*)heapPtr);#ifdef CVM_MS_TRACE		    {			CVMClassBlock* cb =			    CVMobjectGetClass((CVMObject*)heapPtr);			CVMconsolePrintf("GC: Deleting object %x "					 "(class=%C size=%d)\n",					 heapPtr, cb, objSize);		    }#endif#ifdef CVM_JVMPI                    if (CVMjvmpiEventObjectFreeIsEnabled()) {                        CVMjvmpiPostObjectFreeEvent(heapPtr);                    }                    liveObjectCount--;#endif#ifdef CVM_JVMTI                    if (CVMjvmtiShouldPostObjectFree()) {                        CVMjvmtiPostObjectFreeEvent(heapPtr);                    }#endif		    /* 		     * Add it to the free list.		     * We are going to clear the boundaries bits all		     * together at the end.  		     */		    CVMmsAddToFreeList(heapPtr, objSize,				       CVMmsGetFirstListFor(objSize));		    freeBytes += objSize;		}		toClear <<= 1;		heapPtr--;	    }	    /*	     * Clear those objects which have not been marked	     */	    *boundaries = currBoundaries & currMarks;	} else {	    /*	     * We tried very hard not to mark any non-references, so this	     * had better be true.	     */	    CVMassert(*marks == 0);	}	/*	 * We might have bailed out while incrementing heapPtr. Make	 * sure we get to the next set of heap words.	 */	otherHeapPtr -= 32;	heapPtr = otherHeapPtr;	    	marks--;	boundaries--;    }}/* * We have more work to do */static voidCVMmsAddTodo(CVMObject* oneMoreRef) {    CVMmsTodoList[CVMmsTodoIdx] = oneMoreRef;    CVMmsTodoIdx++;    /* This is just a proof-of-concept GC. Therefore, we don't have       expansion support on it. */    if (CVMmsTodoIdx >= CVMmsTodoSize) {	CVMconsolePrintf("CVMmsAddTodo: todo list exceeds size.\n");	exit(1);    }}/* * The generic reference handler. It is invoked for roots as well as * for object and array reference fields. */static voidCVMmsHandleReference(CVMObject* ref){    CVMassert(ref != 0);    /*     * Conservative reference handler.      *     * First check range. If 'ref' is not in the heap range,     * it cannot be a real reference.     *     * Either the object is in ROM, or it is allocated within the heap.     */    CVMassert(CVMmsObjectIsInROM(ref) ||	      (((CVMUint32*)ref >= theHeap->data) &&	       ((CVMUint32*)ref < &theHeap->data[theHeap->size / 4])));    /*     * %comment: f007     */    if (CVMmsObjectIsInROM(ref)) {	return;    }    /*     * Now check whether the 'ref' corresponds to an allocated     * object.      *     */    CVMassert(CVMmsMarkedIn((CVMUint32*)ref, theHeap->boundaries));    {#ifdef CVM_MS_TRACE	CVMconsolePrintf("CVMmsHandleReference(%x)<%s>\n",			 ref, CVMobjectGetClass(ref)->classname);#endif	/*	 * OK, it looks like a 'legal' object reference	 * Scan it and its children if we have not seen it before.	 */	if (!CVMmsMarkedIn((CVMUint32*)ref, theHeap->markbits)) {	    CVMExecEnv* currEE = CVMgetEE();	    CVMmsSetBitFor((CVMUint32*)ref, theHeap->markbits);	    /*	     * Queue up all non-null object references.	     */	    CVMobjectWalkRefsWithSpecialHandling(currEE, currGcOpts, ref,						 CVMobjectGetClassWord(ref), {		if (*refPtr != 0) {		    CVMmsAddTodo(*refPtr);		}	    }, CVMmsRootMarkTransitively, NULL);	}    }}/* * Go through and run the "to-do" list. */static voidCVMmsExhaustTodoList(){    while (CVMmsTodoIdx > 0) {	CVMObject* anotherReference = CVMmsTodoList[--CVMmsTodoIdx];	CVMmsHandleReference(anotherReference); /* This may queue up more */    }}static voidCVMmsRootMarkTransitively(CVMObject** root, void* data){    CVMassert(root != 0);    CVMassert(*root != 0);#if CVM_MS_TRACE    CVMconsolePrintf("GC: Root: [0x%x] = 0x%x\n", root, *root);#endif    CVMmsHandleReference(*root);    /*     * For each root, aggressively mark children instead of first     * queueing up the roots and then running through the children.     */    CVMmsExhaustTodoList();}static CVMBoolCVMmsRefIsLive(CVMObject** refPtr, void* data){    CVMObject* ref;    CVMassert(refPtr != NULL);    ref = *refPtr;    CVMassert(ref != NULL);    /*     * ROM objects are always live     */    if (CVMobjectIsInROM(ref)) {	return CVM_TRUE;    }    return CVMmsMarkedIn((CVMUint32*)ref, theHeap->boundaries);}/* * This routine is called by the common GC code after all locks are * obtained, and threads are stopped at GC-safe points. It's the * routine that needs a snapshot of the world while all threads are * stopped (typically at least a root scan). */voidCVMgcimplDoGC(CVMExecEnv* ee, CVMUint32 numBytes){    CVMGCOptions gcOpts;    CVMtraceGcStartStop(("GC: Collecting...\n"));    gcOpts.isUpdatingObjectPointers = CVM_TRUE;    gcOpts.discoverWeakReferences = CVM_FALSE;#if defined(CVM_DEBUG) || defined(CVM_JVMPI) || defined(CVM_JVMTI)    gcOpts.isProfilingPass = CVM_FALSE;#endif    currGcOpts = &gcOpts;    /*     * Clear all class marks. This is so that we don't     * try to scan the same class twice.     */    CVMgcClearClassMarks(ee, &gcOpts);    /*     * Nothing is marked yet.     */    CVMmsClearMarks();    /*     * The marking phase will start discovering weak reference objects     */    gcOpts.discoverWeakReferences = CVM_TRUE;    /*     * CVMmsRootMark will mark roots, and all their children. So at the end     * of gcScanRoots(), we know all the live objects.     */    CVMgcScanRoots(ee, &gcOpts, CVMmsRootMarkTransitively, NULL);    /*     * Stop discovering weak references     */    gcOpts.discoverWeakReferences = CVM_TRUE;    /*     * At this point, we know which objects are live and which are not.     * Do the special objects processing.     */    CVMgcProcessSpecialWithLivenessInfo(ee, &gcOpts,					CVMmsRefIsLive, NULL,					CVMmsRootMarkTransitively, NULL);    /*     * Now clean garbage     */    CVMmsSweep();    /*     * And mark when all this happened     */    lastMajorGCTime = CVMtimeMillis();    CVMtraceGcStartStop(("GC: Done.\n"));}CVMObject*CVMgcimplRetryAllocationAfterGC(CVMExecEnv* ee, CVMUint32 numBytes){    CVMObject* allocatedObj;        allocatedObj = CVMmsTryAlloc(numBytes);	/* re-try */    if (allocatedObj == NULL) {	/*	 * Last resort. Undo all our fragmented free lists,	 * add everything to the big list, and try allocation	 * for the third time. Deferred coalescing.	 */	CVMmsCollapseFreeLists();	allocatedObj = CVMmsTryAlloc(numBytes);    }    return allocatedObj;}/* * Allocate uninitialized heap object of size numBytes */CVMObject*CVMgcimplAllocObject(CVMExecEnv* ee, CVMUint32 numBytes){    CVMObject* allocatedObj;#ifdef CVM_MS_GC_ON_EVERY_ALLOC    static CVMUint32 allocCount = 1;    /* Do one for stress-test. If it was unsuccessful, try again in the       next allocation */    if ((allocCount % CVM_MS_NO_ALLOCS_UNTIL_GC) == 0) {	if (CVMmsInitiateGC(ee, numBytes)) {	    allocCount = 1;	}    } else {	allocCount++;    }#endif    allocatedObj = CVMmsTryAlloc(numBytes);#ifdef CVM_JVMPI    if (allocatedObj != NULL) {        liveObjectCount++;    }#endif    return allocatedObj;}#ifdef CVM_JVMPI/* Purpose: Posts the JVMPI_EVENT_ARENA_NEW events for the GC specific            implementation. *//* NOTE: This function is necessary to compensate for the fact that         this event has already transpired by the time that JVMPI is         initialized. */void CVMgcimplPostJVMPIArenaNewEvent(void){    if (CVMjvmpiEventArenaNewIsEnabled()) {        CVMUint32 lastSharedArenaID = CVMgcGetLastSharedArenaID();        CVMjvmpiPostArenaNewEvent(lastSharedArenaID + 1, "Java Heap");    }}/* Purpose: Posts the JVMPI_EVENT_ARENA_DELETE events for the GC specific            implementation. */void CVMgcimplPostJVMPIArenaDeleteEvent(void){    if (CVMjvmpiEventArenaDeleteIsEnabled()) {        CVMUint32 lastSharedArenaID = CVMgcGetLastSharedArenaID();        CVMjvmpiPostArenaDeleteEvent(lastSharedArenaID + 1);    }}/* Purpose: Gets the arena ID for the specified object. *//* Returns: The requested ArenaID if found, else returns            CVM_GC_ARENA_UNKNOWN. */CVMUint32 CVMgcimplGetArenaID(CVMObject *obj){    CVMUint32 arenaID = CVM_GC_ARENA_UNKNOWN;    CVMUint8 *objPtr = (CVMUint8 *)obj;    CVMUint8 *heapStart = (CVMUint8 *)heap->data;    CVMUint8 *heapEnd = heapStart + heap->size;    if ((objPtr >= heapStart) && (objPtr < heapEnd)) {        arenaID = (CVMgcGetLastSharedArenaID() + 1);    }    return arenaID;}/* Purpose: Gets the number of objects allocated in the heap. */CVMUint32 CVMgcimplGetObjectCount(CVMExecEnv *ee){    return liveObjectCount;}#endif/* * Return the number of bytes free in the heap.  */CVMUint32CVMgcimplFreeMemory(CVMExecEnv* ee){    return freeBytes;}/* * Return the amount of total memory in the heap, in bytes. */CVMUint32CVMgcimplTotalMemory(CVMExecEnv* ee){    return theHeap->size;}/* * Destroy GC global state */voidCVMgcimplDestroyGlobalState(CVMGCGlobalState* globalState){    CVMtraceMisc(("Destroying global state for mark-sweep GC\n"));}/* * Destroy heap */CVMBoolCVMgcimplDestroyHeap(CVMGCGlobalState* globalState){    int i;    CVMtraceMisc(("Destroying heap for mark-sweep GC\n"));#ifdef CVM_JVMPI    CVMgcimplPostJVMPIArenaDeleteEvent();#endif    theHeap = 0; /* First make sure nobody tries to allocate anything */    for (i = 0; i <= CVM_MS_NFREELISTS; i++) {	CVMmsFreeLists[i] = 0;    }    /*     * All Java threads have stopped by the time we destroy the heap     */    free(globalState->heap->data);    free(globalState->heap->boundaries);    free(globalState->heap->markbits);    free(globalState->heap);    free(CVMmsTodoList);    globalState->heap = 0;    return CVM_TRUE;}/* * JVM_MaxObjectInspectionAge() support */CVMInt64CVMgcimplTimeOfLastMajorGC(){    return lastMajorGCTime;}#if defined(CVM_DEBUG) || defined(CVM_JVMPI) || defined(CVM_JVMTI)/* * Heap iteration. Call (*callback)() on each object in the heap. *//* Returns: CVM_TRUE if the scan was done completely.  CVM_FALSE if aborted            before scan is complete. */CVMBoolCVMgcimplIterateHeap(CVMExecEnv* ee, 		     CVMObjectCallbackFunc callback, void* callbackData){    /* This is just a proof-of-concept GC. Therefore, we don't support       heap iteration on it. */    CVMconsolePrintf("Heap iteration not supported on mark-sweep GC yet\n");    return CVM_FALSE;}#endif /* defined(CVM_DEBUG) || defined(CVM_JVMPI) */

⌨️ 快捷键说明

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