📄 garbage.c
字号:
/* * Copyright (c) 1998-2002 Sun Microsystems, Inc. All Rights Reserved. * * This software is the confidential and proprietary information of Sun * Microsystems, Inc. ("Confidential Information"). You shall not * disclose such Confidential Information and shall use it only in * accordance with the terms of the license agreement you entered into * with Sun. * * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING * THIS SOFTWARE OR ITS DERIVATIVES. * * Use is subject to license terms. *//*========================================================================= * SYSTEM: KVM * SUBSYSTEM: Memory management * FILE: garbage.c * OVERVIEW: Memory manager/garbage collector for the KVM. * AUTHOR: Antero Taivalsaari, Sun Labs * Edited by Doug Simon 11/1998 * Frank Yellin (exact collection, compaction) * Compaction based on code written by Matt Seidl *=======================================================================*//*========================================================================= * For detailed explanation of the memory system, see Garbage.h *=======================================================================*//*========================================================================= * Include files *=======================================================================*/#include "global.h"/*========================================================================= * Variables *=======================================================================*/int TemporaryRootsLength;int GlobalRootsLength;int gcInProgress; union cellOrPointer TemporaryRoots[MAXIMUM_TEMPORARY_ROOTS];union cellOrPointer GlobalRoots[MAXIMUM_GLOBAL_ROOTS];POINTERLIST CleanupRoots;/*========================================================================= * Functions *=======================================================================*//*========================================================================= * FUNCTION: garbageCollect * TYPE: public garbage collection function * OVERVIEW: Perform mark-and-sweep garbage collection. * INTERFACE: * parameters: int moreMemory: the amount by which the heap * size should be grown during garbage collection * (this feature is not supported in the mark-and-sweep * collector). * returns: <nothing> *=======================================================================*/voidgarbageCollect(int moreMemory){#if INCLUDEDEBUGCODE int beforeCollection = 0; int afterCollection = 0;#endif if (gcInProgress != 0) { /* * Circular invocation of GC should not be allowed. */ fatalVMError(KVM_MSG_CIRCULAR_GC_INVOCATION); } gcInProgress++; RundownAsynchronousFunctions(); if (ENABLEPROFILING && INCLUDEDEBUGCODE) { checkHeap(); }#if INCLUDEDEBUGCODE if ((tracegarbagecollection || tracegarbagecollectionverbose) && !TERSE_MESSAGES) { Log->startGC(); }#endif#if INCLUDEDEBUGCODE if (ENABLEPROFILING || tracegarbagecollection || tracegarbagecollectionverbose) { beforeCollection = memoryFree(); }#endif MonitorCache = NULL; /* Clear any temporary monitors */ /* Store virtual machine registers of the currently active thread before * garbage collection (must be done to enable execution stack scanning). */ if (CurrentThread) { storeExecutionEnvironment(CurrentThread); } garbageCollectForReal(moreMemory); if (CurrentThread) { loadExecutionEnvironment(CurrentThread); }#if INCLUDEDEBUGCODE if (ENABLEPROFILING || tracegarbagecollection || tracegarbagecollectionverbose) { afterCollection = memoryFree();#if ENABLEPROFILING GarbageCollectionCounter += 1; DynamicDeallocationCounter += (afterCollection - beforeCollection);#endif if (tracegarbagecollection || tracegarbagecollectionverbose) { Log->endGC(afterCollection - beforeCollection, afterCollection, getHeapSize()); } }#endif /* INCLUDEDEBUGCODE */ RestartAsynchronousFunctions(); /* * Reset to indicate end of garbage collection */ gcInProgress = 0;}#if INCLUDEDEBUGCODEvoid verifyTemporaryRootSpace(int size){ if (TemporaryRootsLength + size > MAXIMUM_TEMPORARY_ROOTS) { fatalError(KVM_MSG_TEMPORARY_ROOT_OVERFLOW); }}#endif /* INCLUDEDEBUGCODE */voidmakeGlobalRoot(cell** object){ int index = GlobalRootsLength; if (index >= MAXIMUM_GLOBAL_ROOTS) { fatalError(KVM_MSG_GLOBAL_ROOT_OVERFLOW); } GlobalRoots[index].cellpp = object; GlobalRootsLength = index + 1;}/*========================================================================= * Memory allocation operations *=======================================================================*//*========================================================================= * FUNCTION: mallocObject, callocObject * TYPE: public memory allocation operation * OVERVIEW: Allocate a contiguous area of n cells in the dynamic heap. * INTERFACE: * parameters: size: the requested object size in cells, * type: garbage collection type of the object * returns: pointer to newly allocated area. * Gives a fatal error if space cannot be allocated. * * COMMENTS: callocObject zeros the space before returning it. *=======================================================================*/cell* mallocObject(long size, GCT_ObjectType type)/* Remember: size is given in CELLs rather than bytes */{ cell *result = mallocHeapObject(size, type); if (result == NULL) { fatalVMError(KVM_MSG_OUT_OF_HEAP_MEMORY); } return result;}cell* callocObject(long size, GCT_ObjectType type){ cell *result = mallocHeapObject(size, type); if (result == NULL) { fatalVMError(KVM_MSG_OUT_OF_HEAP_MEMORY); } /* Initialize the area to zero */ memset(result, 0, size << log2CELL); return result;}/*========================================================================= * FUNCTION: mallocBytes * TYPE: public memory allocation operation * OVERVIEW: Allocate a contiguous area of n bytes in the dynamic heap. * INTERFACE: * parameters: size: the requested object size in bytes * returns: pointer to newly allocated area, or * NIL is allocation fails. * COMMENTS: mallocBytes allocates areas that are treated as * as byte data only. Any possible heap references * within such areas are ignored during garbage * collection. * * The actual size of the data area is rounded * up to the next four-byte aligned memory address, * so the area may contain extra bytes. *=======================================================================*/char* mallocBytes(long size){ /* The size is given in bytes, so it must be */ /* rounded up to next long word boundary */ /* and converted to CELLs */ cell* dataArea = mallocObject((size + CELL - 1) >> log2CELL, GCT_NOPOINTERS); return (char*)dataArea;}/*========================================================================= * FUNCTION: printContents, getObjectTypeStr * TYPE: public debugging operation * OVERVIEW: Print the contents of the heap. Intended for * debugging and heap consistency checking. * INTERFACE: * parameters: <none> * returns: <nothing> *=======================================================================*/#if INCLUDEDEBUGCODEstatic char*getObjectTypeStr(GCT_ObjectType type) { static char* typeNames[] = GCT_TYPENAMES; if ((type >= 0) && (type <= GCT_LASTVALIDTAG)) { return typeNames[type]; } else { return "<unknown>"; }}voidprintObject(cell *object) { cell *header = object - HEADERSIZE; char buffer[256]; GCT_ObjectType gctype = getObjectType(object); switch(gctype) { case GCT_INSTANCE: { /* The object is a Java object instance. Mark pointer fields */ INSTANCE thisObject = (INSTANCE)object; INSTANCE_CLASS thisClass = thisObject->ofClass; if (thisClass != NULL) { getClassName_inBuffer((CLASS)thisClass, buffer); Log->heapObject((long)object, getObjectTypeStr(gctype), getObjectSize(object), (*header & MARKBIT), buffer, 0); break; } /* Fall Through */ } default: Log->heapObject((long)object, getObjectTypeStr(gctype), getObjectSize(object),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -