/** * Private internal. Called exclusively from completeScan(); */ uintptr_t MM_MarkingScheme::scanObject(MM_EnvironmentBase *env, omrobjectptr_t objectPtr) { uintptr_t sizeToDo = UDATA_MAX; GC_ObjectScannerState objectScannerState; GC_ObjectScanner *objectScanner = _delegate.getObjectScanner(env, objectPtr, &objectScannerState, SCAN_REASON_PACKET, &sizeToDo); if (NULL != objectScanner) { bool isLeafSlot = false; GC_SlotObject *slotObject; #if defined(OMR_GC_LEAF_BITS) while (NULL != (slotObject = objectScanner->getNextSlot(isLeafSlot))) { #else /* OMR_GC_LEAF_BITS */ while (NULL != (slotObject = objectScanner->getNextSlot())) { #endif /* OMR_GC_LEAF_BITS */ fixupForwardedSlot(slotObject); inlineMarkObjectNoCheck(env, slotObject->readReferenceFromSlot(), isLeafSlot); } } return sizeToDo; } /** * Scan until there are no more work packets to be processed. * @note This is a joining scan: a thread will not exit this method until * all threads have entered and all work packets are empty. */ void MM_MarkingScheme::completeScan(MM_EnvironmentBase *env) { do { omrobjectptr_t objectPtr = NULL; while (NULL != (objectPtr = (omrobjectptr_t )env->_workStack.pop(env))) { env->_markStats._bytesScanned += scanObject(env, objectPtr); env->_markStats._objectsScanned += 1; } } while (_workPackets->handleWorkPacketOverflow(env)); } /**************************************** * Marking Core Functionality ****************************************/ /** * Initialization for Mark * Actual startup for Mark procedure * @param[in] env - passed Environment * @param[in] initMarkMap instruct should mark map be initialized too */ void MM_MarkingScheme::markLiveObjectsInit(MM_EnvironmentBase *env, bool initMarkMap) { workerSetupForGC(env); if(initMarkMap) { _markMap->initializeMarkMap(env); env->_currentTask->synchronizeGCThreads(env, UNIQUE_ID); } }
static void processMarkStack(GcMarkContext *ctx) { const Object **const base = ctx->stack.base; /* Scan anything that's on the mark stack. * We can't use the bitmaps anymore, so use * a finger that points past the end of them. */ ctx->finger = (void *)ULONG_MAX; while (ctx->stack.top != base) { scanObject(*ctx->stack.top++, ctx); } }
static bool scanBitmapCallback(size_t numPtrs, void **ptrs, const void *finger, void *arg) { GcMarkContext *ctx = (GcMarkContext *)arg; size_t i; #ifndef NDEBUG assert((uintptr_t)finger >= gLastFinger); gLastFinger = (uintptr_t)finger; #endif ctx->finger = finger; for (i = 0; i < numPtrs; i++) { /* The pointers we're getting back are DvmHeapChunks, * not Objects. */ scanObject(chunk2ptr(*ptrs++), ctx); } return true; }