/* * Initialize the bitmaps in <out> so that they cover the same extent as * the corresponding bitmaps in <templates>. */ bool dvmHeapBitmapInitListFromTemplates(HeapBitmap out[], HeapBitmap templates[], size_t numBitmaps, const char *name) { size_t i; char fullName[PATH_MAX]; fullName[sizeof(fullName)-1] = '\0'; for (i = 0; i < numBitmaps; i++) { bool ok; /* If two ashmem regions have the same name, only one gets * the name when looking at the maps. */ snprintf(fullName, sizeof(fullName)-1, "%s/%zd", name, i); ok = dvmHeapBitmapInitFromTemplate(&out[i], &templates[i], fullName); if (!ok) { dvmHeapBitmapDeleteList(out, i); return false; } } return true; }
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); }