📄 collectordebug.c
字号:
*/ char map[(MAXIMUM_STACK_AND_LOCALS + 7) >> 3]; long delta; FRAME thisFP; cell* thisSP; BYTE* thisIP; cell* thisNativeLP; STACK oldStack, newStack, stack; unsigned int i; oldStack = stack = thread->fpStore->stack; updatePointer(&stack); newStack = stack; delta = PTR_DELTA(newStack, oldStack); thisIP = thread->ipStore; thisSP = PTR_OFFSET(thread->spStore, delta); /* new space */ thisFP = PTR_OFFSET(thread->fpStore, delta); /* new space */ thisNativeLP = PTR_OFFSET(thread->nativeLp, delta); /* new space */ thread->spStore = thisSP; thread->fpStore = thisFP; thread->nativeLp = thisNativeLP;#if ENABLE_JAVA_DEBUGGER if (thread->stepInfo.fp != 0) thread->stepInfo.fp = PTR_OFFSET(thread->stepInfo.fp, delta);#endif newStack->next = NULL; 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; unsigned 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); if (method == RunCustomCodeMethod) { memset(map, -1, (realStackSize + 7) >> 3); } else { unsigned int expectedStackSize = getGCRegisterMask(method, thisIP, map); if ((unsigned int)realStackSize > expectedStackSize) { /* If the garbage collector gets called from */ /* inside KNI method calls, the execution stack */ /* may contain more elements than the stack map */ /* indicates => normalize the stack size for */ /* this situation */ totalSize = expectedStackSize + localsCount; } } 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]; } if (INCLUDEDEBUGCODE && method != RunCustomCodeMethod) { checkValidHeapPointer(*argP); } updatePointer(argP); } } if (INCLUDEDEBUGCODE && thisFP->stack != oldStack) { fatalError(KVM_MSG_BAD_STACK_INFORMATION); } thisFP->stack = newStack; previousFp = thisFP->previousFp; /* address in old space */ if (previousFp == NULL) { break; } else { STACK prevOldStack = previousFp->stack; /* old space */ STACK prevNewStack; if (prevOldStack == oldStack) { thisFP->previousSp = PTR_OFFSET(thisFP->previousSp, delta); thisFP->previousFp = PTR_OFFSET(thisFP->previousFp, delta); } else { long offset1 = PTR_DELTA(thisFP->previousFp, prevOldStack); long offset2 = PTR_DELTA(thisFP->previousSp, prevOldStack); stack = prevOldStack; updatePointer(&stack); /* use temp, since non-register var */ prevNewStack = stack; thisFP->previousFp = PTR_OFFSET(prevNewStack, offset1); thisFP->previousSp = PTR_OFFSET(prevNewStack, offset2); 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; }}static voidupdatePointer(void *ptr){ cell *value = *(cell **)ptr; if (value == NULL) { return; } else if (!inCurrentHeap(value)) { if (INCLUDEDEBUGCODE) { if (value >= AllHeapStart && value < PermanentSpace) { fatalError(KVM_MSG_POINTER_IN_OLD_SPACE); } } return; } else { cell valueHeader = OBJECT_HEADER(value); cell *result; if (valueHeader & MARKBIT) { result = (cell *)(valueHeader & ~MARKBIT); } else { long size = SIZE(valueHeader) + 1; result = TargetSpaceFreePtr + 1; /* checkValidHeapPointer(value); */ memcpy(TargetSpaceFreePtr, value - 1, size << 2); OBJECT_HEADER(value) = (long)result | MARKBIT; TargetSpaceFreePtr += size; } *(cell **)ptr = result; return; }}static voidupdateMonitor(OBJECT object){ if (OBJECT_HAS_MONITOR(object)) { /* The mhc 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. */ int tag = OBJECT_MHC_TAG(object); char *address = (char *)object->mhc.address - tag; /* thread/monitor */ updatePointer((cell **)&address); SET_OBJECT_MHC_ADDRESS(object, (char *)address + tag); }}/*========================================================================= * General-purpose memory system functions *=======================================================================*//*========================================================================= * FUNCTION: getHeapSize * TYPE: public function * OVERVIEW: Return the total amount of memory in the dynamic heap * in bytes. * INTERFACE: * parameters: <none> * returns: total amount of memory (in bytes) *=======================================================================*/long getHeapSize(void){ return PTR_DELTA(CurrentHeapEnd, CurrentHeap);}/*========================================================================= * FUNCTION: memoryFree * TYPE: public function * OVERVIEW: Return the total amount of free memory in the * dynamic heap in bytes. * INTERFACE: * parameters: <none> * returns: total amount of free memory (in bytes) *=======================================================================*/long memoryFree(void){ return PTR_DELTA(CurrentHeapEnd, CurrentHeapFreePtr);}/*========================================================================= * FUNCTION: memoryUsage * TYPE: public function * OVERVIEW: Return the amount of memory currently consumed by * all the heap objects. * INTERFACE: * parameters: <none> * returns: amount of consumed memory (in bytes). *=======================================================================*/long memoryUsage(void){ return PTR_DELTA(CurrentHeapFreePtr, CurrentHeap);}/*========================================================================= * FUNCTION: largestFree * TYPE: public function * OVERVIEW: Return the largest block of free memory in the * dynamic heap in bytes. * INTERFACE: * parameters: <none> * returns: size of largest free block (in bytes) *=======================================================================*/long largestFree(void){ return PTR_DELTA(CurrentHeapEnd, CurrentHeapFreePtr);}/*========================================================================= * Debugging and printing operations *=======================================================================*/#if INCLUDEDEBUGCODEvoid printHeapContents(void){ cell* scanner = CurrentHeap; cell* heapSpaceFreePtr = CurrentHeapFreePtr; int freeBytes = PTR_DELTA(CurrentHeapEnd, CurrentHeapFreePtr); int objectCounter = 0; int objectSize = 0; int size; Log->startHeapScan(); for (; scanner < heapSpaceFreePtr; scanner += size + HEADERSIZE) { cell header = *scanner; cell *object; if (header & MARKBIT) { object = (cell *)(header & ~MARKBIT); header = OBJECT_HEADER(object); Log->fprintf(stdout, "%lx => %lx\n\t", (long)(scanner + 1), (long)object); printObject(object); } else { object = scanner + 1; printObject(object); } size = SIZE(header); objectCounter++; objectSize += size + HEADERSIZE; } Log->endHeapScan(); Log->heapSummary(objectCounter, 1, objectSize*CELL, freeBytes, freeBytes, (long)CurrentHeap, (long)CurrentHeapEnd); Log->fprintf(stdout, "====================\n\n");}void checkHeap(void){ /* Scan the entire heap, looking for badly formed headers */ cell* scanner = CurrentHeap; cell* heapSpaceEnd = CurrentHeapFreePtr; int result = TRUE; while (scanner < heapSpaceEnd) { long size = SIZE(*scanner); GCT_ObjectType type = TYPE(*scanner); /* In this GC, we don't have FREE chunks or marked objects. */ if ( ISFREECHUNK(*scanner) || ISMARKED(*scanner) || type < GCT_FIRSTVALIDTAG || type > GCT_LASTVALIDTAG) { result = FALSE; break; } /* Jump to the next object/chunk header in the heap */ scanner += size + HEADERSIZE; } /* The scanner should now be pointing to exactly the heap top */ if (!result || scanner != heapSpaceEnd) { fatalVMError(KVM_MSG_HEAP_CORRUPTED); }}static voidcheckValidHeapPointer(cell *number){ int lowbits; cell* scanner; /* We don't need to deal with NULL pointers */ if (number == NULL || isROMString(number) || isROMClass(number)) { return; } /* Valid heap addresses are always four-byte aligned */ if ((cell)number & 0x00000003) { fatalError(KVM_MSG_HEAP_ADDRESS_NOT_FOUR_BYTE_ALIGNED); } if (number >= PermanentSpaceFreePtr && number < AllHeapEnd) { return; } /* The type field must contain a valid type tag; additionally, */ /* both static bit and mark bit must be unset. */ lowbits = OBJECT_HEADER(number); if (lowbits & STATICBIT) { fatalError(KVM_MSG_UNEXPECTED_STATICBIT); } if (lowbits & MARKBIT) { cell *movedObject = (cell *)(lowbits & ~MARKBIT); lowbits = OBJECT_HEADER(movedObject); } lowbits &= 0xFF; if ((lowbits < (GCT_FIRSTVALIDTAG << TYPE_SHIFT)) || (lowbits > (GCT_LASTVALIDTAG << TYPE_SHIFT))) { fatalError(KVM_MSG_BAD_GC_TAG_VALUE); } /* Now have to scan from bottom of heap */ scanner = CurrentHeap; while (scanner <= number-HEADERSIZE) { if (number == scanner+HEADERSIZE) { return; } else { cell header = *scanner; long size; if (header & MARKBIT) { cell *movedObject = (cell *)(header & ~MARKBIT); header = OBJECT_HEADER(movedObject); } /* Get the size of the object (excluding the header) */ size = SIZE(header); /* Jump to the next object/chunk header in the heap */ scanner += size+HEADERSIZE; } } fatalError(KVM_MSG_INVALID_HEAP_POINTER);}#endif /* INCLUDEDEBUGCODE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -