1 #include <stdio.h> 2 #include <stdbool.h> 3 #include <stdint.h> 4 #include <assert.h> 5 #include <string.h> 6 #include <unistd.h> 7 #define __attribute(x) /* disable inlining */ 8 #include "HeapBitmap.h" 9 #undef __attribute 10 11 #define PAGE_SIZE 4096 12 #define HEAP_BASE ((void *)0x10000) 13 #define HEAP_SIZE (5 * PAGE_SIZE + 888) 14 15 #define VERBOSE 1 16 #if VERBOSE 17 #define TRACE(...) printf(__VA_ARGS__) 18 #else 19 #define TRACE(...) /**/ 20 #endif 21 22 void 23 test_init() 24 { 25 HeapBitmap hb; 26 bool ok; 27 28 memset(&hb, 0x55, sizeof(hb)); 29 30 ok = dvmHeapBitmapInit(&hb, HEAP_BASE, HEAP_SIZE, "test"); 31 assert(ok); 32 33 assert(hb.bits != NULL); 34 assert(hb.bitsLen >= HB_OFFSET_TO_INDEX(HEAP_SIZE)); 35 assert(hb.base == (uintptr_t)HEAP_BASE); 36 assert(hb.max < hb.base); 37 38 /* Make sure hb.bits is mapped. 39 */ 40 *hb.bits = 0x55; 41 assert(*hb.bits = 0x55); 42 *hb.bits = 0; 43 44 #define TEST_UNMAP 0 45 #if TEST_UNMAP 46 /* Hold onto this to make sure it's unmapped later. 47 */ 48 unsigned long int *bits = hb.bits; 49 #endif 50 51 dvmHeapBitmapDelete(&hb); 52 53 assert(hb.bits == NULL); 54 assert(hb.bitsLen == 0); 55 assert(hb.base == 0); 56 assert(hb.max == 0); 57 58 #if TEST_UNMAP 59 /* This pointer shouldn't be mapped anymore. 60 */ 61 *bits = 0x55; 62 assert(!"Should have segfaulted"); 63 #endif 64 } 65 66 bool is_zeroed(const HeapBitmap *hb) 67 { 68 int i; 69 70 for (i = 0; i < hb->bitsLen / sizeof (*hb->bits); i++) { 71 if (hb->bits[i] != 0L) { 72 return false; 73 } 74 } 75 return true; 76 } 77 78 void assert_empty(const HeapBitmap *hb) 79 { 80 assert(hb->bits != NULL); 81 assert(hb->bitsLen >= HB_OFFSET_TO_INDEX(HEAP_SIZE)); 82 assert(hb->base == (uintptr_t)HEAP_BASE); 83 assert(hb->max < hb->base); 84 85 assert(is_zeroed(hb)); 86 87 assert(!dvmHeapBitmapMayContainObject(hb, 88 HEAP_BASE)); 89 assert(!dvmHeapBitmapMayContainObject(hb, 90 HEAP_BASE + HB_OBJECT_ALIGNMENT)); 91 assert(!dvmHeapBitmapMayContainObject(hb, 92 HEAP_BASE + HEAP_SIZE - HB_OBJECT_ALIGNMENT)); 93 assert(!dvmHeapBitmapMayContainObject(hb, 94 HEAP_BASE + HEAP_SIZE)); 95 96 assert(!dvmHeapBitmapIsObjectBitSet(hb, 97 HEAP_BASE)); 98 assert(!dvmHeapBitmapIsObjectBitSet(hb, 99 HEAP_BASE + HB_OBJECT_ALIGNMENT)); 100 assert(!dvmHeapBitmapIsObjectBitSet(hb, 101 HEAP_BASE + HEAP_SIZE - HB_OBJECT_ALIGNMENT)); 102 } 103 104 void 105 test_bits() 106 { 107 HeapBitmap hb; 108 bool ok; 109 110 ok = dvmHeapBitmapInit(&hb, HEAP_BASE, HEAP_SIZE, "test"); 111 assert(ok); 112 113 assert_empty(&hb); 114 115 /* Set the lowest address. 116 */ 117 dvmHeapBitmapSetObjectBit(&hb, HEAP_BASE); 118 assert(dvmHeapBitmapMayContainObject(&hb, 119 HEAP_BASE)); 120 assert(!dvmHeapBitmapMayContainObject(&hb, 121 HEAP_BASE + HB_OBJECT_ALIGNMENT)); 122 assert(!dvmHeapBitmapMayContainObject(&hb, 123 HEAP_BASE + HEAP_SIZE - HB_OBJECT_ALIGNMENT)); 124 assert(!dvmHeapBitmapMayContainObject(&hb, 125 HEAP_BASE + HEAP_SIZE)); 126 127 assert(dvmHeapBitmapIsObjectBitSet(&hb, 128 HEAP_BASE)); 129 assert(!dvmHeapBitmapIsObjectBitSet(&hb, 130 HEAP_BASE + HB_OBJECT_ALIGNMENT)); 131 assert(!dvmHeapBitmapIsObjectBitSet(&hb, 132 HEAP_BASE + HEAP_SIZE - HB_OBJECT_ALIGNMENT)); 133 134 /* Set the highest address. 135 */ 136 dvmHeapBitmapSetObjectBit(&hb, HEAP_BASE + HEAP_SIZE - HB_OBJECT_ALIGNMENT); 137 assert(dvmHeapBitmapMayContainObject(&hb, 138 HEAP_BASE)); 139 assert(dvmHeapBitmapMayContainObject(&hb, 140 HEAP_BASE + HB_OBJECT_ALIGNMENT)); 141 assert(dvmHeapBitmapMayContainObject(&hb, 142 HEAP_BASE + HEAP_SIZE - HB_OBJECT_ALIGNMENT)); 143 assert(!dvmHeapBitmapMayContainObject(&hb, 144 HEAP_BASE + HEAP_SIZE)); 145 146 assert(dvmHeapBitmapIsObjectBitSet(&hb, 147 HEAP_BASE)); 148 assert(!dvmHeapBitmapIsObjectBitSet(&hb, 149 HEAP_BASE + HB_OBJECT_ALIGNMENT)); 150 assert(dvmHeapBitmapIsObjectBitSet(&hb, 151 HEAP_BASE + HEAP_SIZE - HB_OBJECT_ALIGNMENT)); 152 153 /* Clear the lowest address. 154 */ 155 dvmHeapBitmapClearObjectBit(&hb, HEAP_BASE); 156 assert(!dvmHeapBitmapIsObjectBitSet(&hb, 157 HEAP_BASE)); 158 assert(!dvmHeapBitmapIsObjectBitSet(&hb, 159 HEAP_BASE + HB_OBJECT_ALIGNMENT)); 160 assert(dvmHeapBitmapIsObjectBitSet(&hb, 161 HEAP_BASE + HEAP_SIZE - HB_OBJECT_ALIGNMENT)); 162 assert(!is_zeroed(&hb)); 163 164 /* Clear the highest address. 165 */ 166 dvmHeapBitmapClearObjectBit(&hb, 167 HEAP_BASE + HEAP_SIZE - HB_OBJECT_ALIGNMENT); 168 assert(!dvmHeapBitmapIsObjectBitSet(&hb, 169 HEAP_BASE)); 170 assert(!dvmHeapBitmapIsObjectBitSet(&hb, 171 HEAP_BASE + HB_OBJECT_ALIGNMENT)); 172 assert(!dvmHeapBitmapIsObjectBitSet(&hb, 173 HEAP_BASE + HEAP_SIZE - HB_OBJECT_ALIGNMENT)); 174 assert(is_zeroed(&hb)); 175 176 /* Clean up. 177 */ 178 dvmHeapBitmapDelete(&hb); 179 } 180 181 void 182 test_clear() 183 { 184 HeapBitmap hb; 185 bool ok; 186 187 ok = dvmHeapBitmapInit(&hb, HEAP_BASE, HEAP_SIZE, "test"); 188 assert(ok); 189 assert_empty(&hb); 190 191 /* Set the highest address. 192 */ 193 dvmHeapBitmapSetObjectBit(&hb, HEAP_BASE + HEAP_SIZE - HB_OBJECT_ALIGNMENT); 194 assert(!is_zeroed(&hb)); 195 196 /* Clear the bitmap. 197 */ 198 dvmHeapBitmapZero(&hb); 199 assert_empty(&hb); 200 201 /* Clean up. 202 */ 203 dvmHeapBitmapDelete(&hb); 204 } 205 206 void 207 test_modify() 208 { 209 HeapBitmap hb; 210 bool ok; 211 unsigned long bit; 212 213 ok = dvmHeapBitmapInit(&hb, HEAP_BASE, HEAP_SIZE, "test"); 214 assert(ok); 215 assert_empty(&hb); 216 217 /* Set the lowest address. 218 */ 219 bit = dvmHeapBitmapSetAndReturnObjectBit(&hb, HEAP_BASE); 220 assert(bit == 0); 221 assert(dvmHeapBitmapMayContainObject(&hb, 222 HEAP_BASE)); 223 assert(!dvmHeapBitmapMayContainObject(&hb, 224 HEAP_BASE + HB_OBJECT_ALIGNMENT)); 225 assert(!dvmHeapBitmapMayContainObject(&hb, 226 HEAP_BASE + HEAP_SIZE - HB_OBJECT_ALIGNMENT)); 227 assert(!dvmHeapBitmapMayContainObject(&hb, 228 HEAP_BASE + HEAP_SIZE)); 229 230 assert(dvmHeapBitmapIsObjectBitSet(&hb, 231 HEAP_BASE)); 232 assert(!dvmHeapBitmapIsObjectBitSet(&hb, 233 HEAP_BASE + HB_OBJECT_ALIGNMENT)); 234 assert(!dvmHeapBitmapIsObjectBitSet(&hb, 235 HEAP_BASE + HEAP_SIZE - HB_OBJECT_ALIGNMENT)); 236 237 /* Set the lowest address again. 238 */ 239 bit = dvmHeapBitmapSetAndReturnObjectBit(&hb, HEAP_BASE); 240 assert(bit != 0); 241 assert(dvmHeapBitmapMayContainObject(&hb, 242 HEAP_BASE)); 243 assert(!dvmHeapBitmapMayContainObject(&hb, 244 HEAP_BASE + HB_OBJECT_ALIGNMENT)); 245 assert(!dvmHeapBitmapMayContainObject(&hb, 246 HEAP_BASE + HEAP_SIZE - HB_OBJECT_ALIGNMENT)); 247 assert(!dvmHeapBitmapMayContainObject(&hb, 248 HEAP_BASE + HEAP_SIZE)); 249 250 assert(dvmHeapBitmapIsObjectBitSet(&hb, 251 HEAP_BASE)); 252 assert(!dvmHeapBitmapIsObjectBitSet(&hb, 253 HEAP_BASE + HB_OBJECT_ALIGNMENT)); 254 assert(!dvmHeapBitmapIsObjectBitSet(&hb, 255 HEAP_BASE + HEAP_SIZE - HB_OBJECT_ALIGNMENT)); 256 257 /* Set the highest address. 258 */ 259 bit = dvmHeapBitmapSetAndReturnObjectBit(&hb, 260 HEAP_BASE + HEAP_SIZE - HB_OBJECT_ALIGNMENT); 261 assert(bit == 0); 262 assert(dvmHeapBitmapMayContainObject(&hb, 263 HEAP_BASE)); 264 assert(dvmHeapBitmapMayContainObject(&hb, 265 HEAP_BASE + HB_OBJECT_ALIGNMENT)); 266 assert(dvmHeapBitmapMayContainObject(&hb, 267 HEAP_BASE + HEAP_SIZE - HB_OBJECT_ALIGNMENT)); 268 assert(!dvmHeapBitmapMayContainObject(&hb, 269 HEAP_BASE + HEAP_SIZE)); 270 271 assert(dvmHeapBitmapIsObjectBitSet(&hb, 272 HEAP_BASE)); 273 assert(!dvmHeapBitmapIsObjectBitSet(&hb, 274 HEAP_BASE + HB_OBJECT_ALIGNMENT)); 275 assert(dvmHeapBitmapIsObjectBitSet(&hb, 276 HEAP_BASE + HEAP_SIZE - HB_OBJECT_ALIGNMENT)); 277 278 /* Set the highest address again. 279 */ 280 bit = dvmHeapBitmapSetAndReturnObjectBit(&hb, 281 HEAP_BASE + HEAP_SIZE - HB_OBJECT_ALIGNMENT); 282 assert(bit != 0); 283 assert(dvmHeapBitmapMayContainObject(&hb, 284 HEAP_BASE)); 285 assert(dvmHeapBitmapMayContainObject(&hb, 286 HEAP_BASE + HB_OBJECT_ALIGNMENT)); 287 assert(dvmHeapBitmapMayContainObject(&hb, 288 HEAP_BASE + HEAP_SIZE - HB_OBJECT_ALIGNMENT)); 289 assert(!dvmHeapBitmapMayContainObject(&hb, 290 HEAP_BASE + HEAP_SIZE)); 291 292 assert(dvmHeapBitmapIsObjectBitSet(&hb, 293 HEAP_BASE)); 294 assert(!dvmHeapBitmapIsObjectBitSet(&hb, 295 HEAP_BASE + HB_OBJECT_ALIGNMENT)); 296 assert(dvmHeapBitmapIsObjectBitSet(&hb, 297 HEAP_BASE + HEAP_SIZE - HB_OBJECT_ALIGNMENT)); 298 299 /* Clean up. 300 */ 301 dvmHeapBitmapDelete(&hb); 302 } 303 304 /* 305 * xor test support functions 306 */ 307 308 static void *gCallbackArg = NULL; 309 310 #define NUM_XOR_PTRS 128 311 static size_t gNumPtrs; 312 static void *gXorPtrs[NUM_XOR_PTRS]; 313 static bool gClearedPtrs[NUM_XOR_PTRS]; 314 static bool gSeenPtrs[NUM_XOR_PTRS]; 315 316 bool 317 xorCallback(size_t numPtrs, void **ptrs, const void *finger, void *arg) 318 { 319 assert(numPtrs > 0); 320 assert(ptrs != NULL); 321 assert(arg == gCallbackArg); 322 323 size_t i; 324 for (i = 0; i < numPtrs; i++) { 325 assert(ptrs[i] < finger); 326 printf("callback: 0x%08x ( < 0x%08x )\n", 327 (uintptr_t)ptrs[i], (uintptr_t)finger); 328 } 329 330 return true; 331 } 332 333 bool 334 seenAndClearedMatch() 335 { 336 size_t i; 337 for (i = 0; i < gNumPtrs; i++) { 338 if (gClearedPtrs[i] != gSeenPtrs[i]) { 339 return false; 340 } 341 } 342 return true; 343 } 344 345 void 346 run_xor(ssize_t offset, size_t step) 347 { 348 assert(step != 0); 349 assert(step < HEAP_SIZE); 350 351 /* Figure out the range. 352 */ 353 uintptr_t base; 354 uintptr_t top; 355 if (offset >= 0) { 356 base = (uintptr_t)HEAP_BASE + offset; 357 } else { 358 base = (uintptr_t)HEAP_BASE + (uintptr_t)HEAP_SIZE + offset; 359 } 360 if (base < (uintptr_t)HEAP_BASE) { 361 base = (uintptr_t)HEAP_BASE; 362 } else if (base > (uintptr_t)(HEAP_BASE + HEAP_SIZE)) { 363 base = (uintptr_t)(HEAP_BASE + HEAP_SIZE); 364 } else { 365 base = (base + HB_OBJECT_ALIGNMENT - 1) & ~(HB_OBJECT_ALIGNMENT - 1); 366 } 367 step *= HB_OBJECT_ALIGNMENT; 368 top = base + step * NUM_XOR_PTRS; 369 if (top > (uintptr_t)(HEAP_BASE + HEAP_SIZE)) { 370 top = (uintptr_t)(HEAP_BASE + HEAP_SIZE); 371 } 372 373 /* Create the pointers. 374 */ 375 gNumPtrs = 0; 376 memset(gXorPtrs, 0, sizeof(gXorPtrs)); 377 memset(gClearedPtrs, 0, sizeof(gClearedPtrs)); 378 memset(gSeenPtrs, 0, sizeof(gSeenPtrs)); 379 380 uintptr_t addr; 381 void **p = gXorPtrs; 382 for (addr = base; addr < top; addr += step) { 383 *p++ = (void *)addr; 384 gNumPtrs++; 385 } 386 assert(seenAndClearedMatch()); 387 388 /* Set up the bitmaps. 389 */ 390 HeapBitmap hb1, hb2; 391 bool ok; 392 393 ok = dvmHeapBitmapInit(&hb1, HEAP_BASE, HEAP_SIZE, "test1"); 394 assert(ok); 395 ok = dvmHeapBitmapInitFromTemplate(&hb2, &hb1, "test2"); 396 assert(ok); 397 398 /* Walk two empty bitmaps. 399 */ 400 TRACE("walk 0\n"); 401 ok = dvmHeapBitmapXorWalk(&hb1, &hb2, xorCallback, gCallbackArg); 402 assert(ok); 403 assert(seenAndClearedMatch()); 404 405 /* Walk one empty bitmap. 406 */ 407 TRACE("walk 1\n"); 408 dvmHeapBitmapSetObjectBit(&hb1, (void *)base); 409 ok = dvmHeapBitmapXorWalk(&hb1, &hb2, xorCallback, gCallbackArg); 410 assert(ok); 411 412 /* Make the bitmaps match. 413 */ 414 TRACE("walk 2\n"); 415 dvmHeapBitmapSetObjectBit(&hb2, (void *)base); 416 ok = dvmHeapBitmapXorWalk(&hb1, &hb2, xorCallback, gCallbackArg); 417 assert(ok); 418 419 /* Clear the bitmaps. 420 */ 421 dvmHeapBitmapZero(&hb1); 422 assert_empty(&hb1); 423 dvmHeapBitmapZero(&hb2); 424 assert_empty(&hb2); 425 426 /* Set the pointers we created in one of the bitmaps, 427 * then visit them. 428 */ 429 size_t i; 430 for (i = 0; i < gNumPtrs; i++) { 431 dvmHeapBitmapSetObjectBit(&hb1, gXorPtrs[i]); 432 } 433 TRACE("walk 3\n"); 434 ok = dvmHeapBitmapXorWalk(&hb1, &hb2, xorCallback, gCallbackArg); 435 assert(ok); 436 437 /* Set every third pointer in the other bitmap, and visit again. 438 */ 439 for (i = 0; i < gNumPtrs; i += 3) { 440 dvmHeapBitmapSetObjectBit(&hb2, gXorPtrs[i]); 441 } 442 TRACE("walk 4\n"); 443 ok = dvmHeapBitmapXorWalk(&hb1, &hb2, xorCallback, gCallbackArg); 444 assert(ok); 445 446 /* Set every other pointer in the other bitmap, and visit again. 447 */ 448 for (i = 0; i < gNumPtrs; i += 2) { 449 dvmHeapBitmapSetObjectBit(&hb2, gXorPtrs[i]); 450 } 451 TRACE("walk 5\n"); 452 ok = dvmHeapBitmapXorWalk(&hb1, &hb2, xorCallback, gCallbackArg); 453 assert(ok); 454 455 /* Walk just one bitmap. 456 */ 457 TRACE("walk 6\n"); 458 ok = dvmHeapBitmapWalk(&hb2, xorCallback, gCallbackArg); 459 assert(ok); 460 461 //xxx build an expect list for the callback 462 //xxx test where max points to beginning, middle, and end of a word 463 464 /* Clean up. 465 */ 466 dvmHeapBitmapDelete(&hb1); 467 dvmHeapBitmapDelete(&hb2); 468 } 469 470 void 471 test_xor() 472 { 473 run_xor(0, 1); 474 run_xor(100, 34); 475 } 476 477 int main(int argc, char *argv[]) 478 { 479 printf("test_init...\n"); 480 test_init(); 481 482 printf("test_bits...\n"); 483 test_bits(); 484 485 printf("test_clear...\n"); 486 test_clear(); 487 488 printf("test_modify...\n"); 489 test_modify(); 490 491 printf("test_xor...\n"); 492 test_xor(); 493 494 printf("done.\n"); 495 return 0; 496 } 497