/* * Similar to dvmHeapBitmapXorWalkList(), but visit the set bits * in a single list of bitmaps. Regardless of the order of the array, * the bitmaps will be visited in address order, so that finger will * increase monotonically. */ bool dvmHeapBitmapWalkList(const HeapBitmap hbs[], size_t numBitmaps, bool (*callback)(size_t numPtrs, void **ptrs, const void *finger, void *arg), void *callbackArg) { size_t indexList[numBitmaps]; size_t i; /* Sort the bitmaps by address. */ createSortedBitmapIndexList(hbs, numBitmaps, indexList); /* Walk each bitmap, lowest address first. */ for (i = 0; i < numBitmaps; i++) { bool ok; ok = dvmHeapBitmapWalk(&hbs[indexList[i]], callback, callbackArg); if (!ok) { return false; } } return true; }
size_t dvmCountAssignableInstancesOfClass(const ClassObject *clazz) { CountContext ctx = { clazz, 0 }; dvmLockHeap(); HeapBitmap *bitmap = dvmHeapSourceGetLiveBits(); dvmHeapBitmapWalk(bitmap, countAssignableInstancesOfClassCallback, &ctx); dvmUnlockHeap(); return ctx.count; }
void run_xor(ssize_t offset, size_t step) { assert(step != 0); assert(step < HEAP_SIZE); /* Figure out the range. */ uintptr_t base; uintptr_t top; if (offset >= 0) { base = (uintptr_t)HEAP_BASE + offset; } else { base = (uintptr_t)HEAP_BASE + (uintptr_t)HEAP_SIZE + offset; } if (base < (uintptr_t)HEAP_BASE) { base = (uintptr_t)HEAP_BASE; } else if (base > (uintptr_t)(HEAP_BASE + HEAP_SIZE)) { base = (uintptr_t)(HEAP_BASE + HEAP_SIZE); } else { base = (base + HB_OBJECT_ALIGNMENT - 1) & ~(HB_OBJECT_ALIGNMENT - 1); } step *= HB_OBJECT_ALIGNMENT; top = base + step * NUM_XOR_PTRS; if (top > (uintptr_t)(HEAP_BASE + HEAP_SIZE)) { top = (uintptr_t)(HEAP_BASE + HEAP_SIZE); } /* Create the pointers. */ gNumPtrs = 0; memset(gXorPtrs, 0, sizeof(gXorPtrs)); memset(gClearedPtrs, 0, sizeof(gClearedPtrs)); memset(gSeenPtrs, 0, sizeof(gSeenPtrs)); uintptr_t addr; void **p = gXorPtrs; for (addr = base; addr < top; addr += step) { *p++ = (void *)addr; gNumPtrs++; } assert(seenAndClearedMatch()); /* Set up the bitmaps. */ HeapBitmap hb1, hb2; bool ok; ok = dvmHeapBitmapInit(&hb1, HEAP_BASE, HEAP_SIZE, "test1"); assert(ok); ok = dvmHeapBitmapInitFromTemplate(&hb2, &hb1, "test2"); assert(ok); /* Walk two empty bitmaps. */ TRACE("walk 0\n"); ok = dvmHeapBitmapXorWalk(&hb1, &hb2, xorCallback, gCallbackArg); assert(ok); assert(seenAndClearedMatch()); /* Walk one empty bitmap. */ TRACE("walk 1\n"); dvmHeapBitmapSetObjectBit(&hb1, (void *)base); ok = dvmHeapBitmapXorWalk(&hb1, &hb2, xorCallback, gCallbackArg); assert(ok); /* Make the bitmaps match. */ TRACE("walk 2\n"); dvmHeapBitmapSetObjectBit(&hb2, (void *)base); ok = dvmHeapBitmapXorWalk(&hb1, &hb2, xorCallback, gCallbackArg); assert(ok); /* Clear the bitmaps. */ dvmHeapBitmapZero(&hb1); assert_empty(&hb1); dvmHeapBitmapZero(&hb2); assert_empty(&hb2); /* Set the pointers we created in one of the bitmaps, * then visit them. */ size_t i; for (i = 0; i < gNumPtrs; i++) { dvmHeapBitmapSetObjectBit(&hb1, gXorPtrs[i]); } TRACE("walk 3\n"); ok = dvmHeapBitmapXorWalk(&hb1, &hb2, xorCallback, gCallbackArg); assert(ok); /* Set every third pointer in the other bitmap, and visit again. */ for (i = 0; i < gNumPtrs; i += 3) { dvmHeapBitmapSetObjectBit(&hb2, gXorPtrs[i]); } TRACE("walk 4\n"); ok = dvmHeapBitmapXorWalk(&hb1, &hb2, xorCallback, gCallbackArg); assert(ok); /* Set every other pointer in the other bitmap, and visit again. */ for (i = 0; i < gNumPtrs; i += 2) { dvmHeapBitmapSetObjectBit(&hb2, gXorPtrs[i]); } TRACE("walk 5\n"); ok = dvmHeapBitmapXorWalk(&hb1, &hb2, xorCallback, gCallbackArg); assert(ok); /* Walk just one bitmap. */ TRACE("walk 6\n"); ok = dvmHeapBitmapWalk(&hb2, xorCallback, gCallbackArg); assert(ok); //xxx build an expect list for the callback //xxx test where max points to beginning, middle, and end of a word /* Clean up. */ dvmHeapBitmapDelete(&hb1); dvmHeapBitmapDelete(&hb2); }