static void describe(FBMState state) { switch (state->type) { case FBMTypeCBS: CBSDescribe(state->the.cbs, mps_lib_get_stdout()); break; case FBMTypeFreelist: FreelistDescribe(state->the.fl, mps_lib_get_stdout()); break; default: fail(); break; } }
void report_break (char* message) { mps_lib_FILE *stream = mps_lib_get_stdout(); mps_lib_fputs("Break to debugger:\n ", stream); mps_lib_fputs(message, stream); mps_lib_fputc('\n', stream); DebugBreak(); }
static void test_pool(mps_pool_class_t pool_class, mps_arg_s args[], mps_bool_t haveAmbiguous) { mps_pool_t pool; mps_root_t exactRoot, ambigRoot = NULL; size_t lastStep = 0, i, r; unsigned long objs; mps_ap_t busy_ap; mps_addr_t busy_init; die(mps_pool_create_k(&pool, arena, pool_class, args), "pool_create"); die(mps_ap_create(&ap, pool, mps_rank_exact()), "BufferCreate"); die(mps_ap_create(&busy_ap, pool, mps_rank_exact()), "BufferCreate 2"); for(i = 0; i < exactRootsCOUNT; ++i) exactRoots[i] = objNULL; if (haveAmbiguous) for(i = 0; i < ambigRootsCOUNT; ++i) ambigRoots[i] = rnd_addr(); die(mps_root_create_table_masked(&exactRoot, arena, mps_rank_exact(), (mps_rm_t)0, &exactRoots[0], exactRootsCOUNT, (mps_word_t)1), "root_create_table(exact)"); if (haveAmbiguous) die(mps_root_create_table(&ambigRoot, arena, mps_rank_ambig(), (mps_rm_t)0, &ambigRoots[0], ambigRootsCOUNT), "root_create_table(ambig)"); /* create an ap, and leave it busy */ die(mps_reserve(&busy_init, busy_ap, 64), "mps_reserve busy"); die(PoolDescribe(pool, mps_lib_get_stdout(), 0), "PoolDescribe"); objs = 0; totalSize = 0; while(totalSize < totalSizeMAX) { if (totalSize > lastStep + totalSizeSTEP) { lastStep = totalSize; printf("\nSize %"PRIuLONGEST" bytes, %lu objects.\n", (ulongest_t)totalSize, objs); (void)fflush(stdout); for(i = 0; i < exactRootsCOUNT; ++i) cdie(exactRoots[i] == objNULL || dylan_check(exactRoots[i]), "all roots check"); } r = (size_t)rnd(); if (!haveAmbiguous || (r & 1)) { i = (r >> 1) % exactRootsCOUNT; if (exactRoots[i] != objNULL) cdie(dylan_check(exactRoots[i]), "dying root check"); exactRoots[i] = make(); if (exactRoots[(exactRootsCOUNT-1) - i] != objNULL) dylan_write(exactRoots[(exactRootsCOUNT-1) - i], exactRoots, exactRootsCOUNT); } else {
void display_wrapper_stats () { int largest; mps_lib_FILE *stream = mps_lib_get_stdout(); char *message = "Start of heap statistics"; mps_lib_fputc('\n', stream); mps_lib_fputs(message, stream); display_padding_for_string(message, ' ', class_name_size, stream); mps_lib_fputs(" (count) (size)", stream); mps_lib_fputs("\n\n", stream); display_totals(stream); mps_lib_fputc('\n', stream); for (largest = biggest_below_value(very_big); largest >= 0; largest = biggest_below_value(largest)) { display_wrappers_of_size(largest, stream); } mps_lib_fputs("End of heap statistics\n\n", stream); }
void display_wrapper_breakpoints() { mps_lib_FILE *stream = mps_lib_get_stdout(); if (wrapper_breaks_cursor >= 0) { int i; mps_lib_fputs("Object allocation breakpoints\n\n", stream); mps_lib_fputs(" (class-name) (count)\n\n", stream); for (i = 0; i < wrapper_breaks_cursor + 1; i++) { wrapper_stats_t wrapper_record = wrapper_breaks + i; char *class_name = class_name_from_wrapper(wrapper_record->wrapper_address); mps_lib_fputs_(class_name, class_name_size, stream); display_padding_for_string(class_name, ' ', class_name_size, stream); display_integer(wrapper_record->usage_size, stream); mps_lib_fputc('\n', stream); } } else mps_lib_fputs("No active object allocation breakpoints\n\n", stream); }
static void test(mps_arena_t arena) { BT bt; Nailboard board; Align align; Count nails; Addr base, limit; Index i, j, k; align = (Align)1 << (rnd() % 10); nails = (Count)1 << (rnd() % 16); nails += rnd() % nails; base = AddrAlignUp(0, align); limit = AddrAdd(base, nails * align); die(BTCreate(&bt, arena, nails), "BTCreate"); BTResRange(bt, 0, nails); die(NailboardCreate(&board, arena, align, base, limit), "NailboardCreate"); for (i = 0; i <= nails / 8; ++i) { Bool old; j = rnd() % nails; old = BTGet(bt, j); BTSet(bt, j); cdie(NailboardSet(board, AddrAdd(base, j * align)) == old, "NailboardSet"); for (k = 0; k < nails / 8; ++k) { Index b, l; b = rnd() % nails; l = b + rnd() % (nails - b) + 1; cdie(BTIsResRange(bt, b, l) == NailboardIsResRange(board, AddrAdd(base, b * align), AddrAdd(base, l * align)), "NailboardIsResRange"); } } die(NailboardDescribe(board, mps_lib_get_stdout(), 0), "NailboardDescribe"); }
void report_message (char* message) { mps_lib_FILE *stream = mps_lib_get_stdout(); mps_lib_fputs(message, stream); }
static mps_res_t stress(mps_arena_t arena, mps_pool_debug_option_s *options, size_t (*size)(size_t i), mps_align_t align, const char *name, mps_pool_class_t pool_class, mps_arg_s *args) { mps_res_t res; mps_pool_t pool; size_t i, k; int *ps[testSetSIZE]; size_t ss[testSetSIZE]; size_t allocated = 0; /* Total allocated memory */ size_t debugOverhead = options ? 2 * alignUp(options->fence_size, align) : 0; printf("Pool class %s, alignment %u\n", name, (unsigned)align); res = mps_pool_create_k(&pool, arena, pool_class, args); if (res != MPS_RES_OK) return res; /* allocate a load of objects */ for (i=0; i<testSetSIZE; ++i) { mps_addr_t obj; ss[i] = (*size)(i); res = mps_alloc(&obj, pool, ss[i]); if (res != MPS_RES_OK) return res; ps[i] = obj; allocated += alignUp(ss[i], align) + debugOverhead; if (ss[i] >= sizeof(ps[i])) *ps[i] = 1; /* Write something, so it gets swap. */ check_allocated_size(pool, allocated); } mps_pool_check_fenceposts(pool); for (k=0; k<testLOOPS; ++k) { /* shuffle all the objects */ for (i=0; i<testSetSIZE; ++i) { size_t j = rnd()%(testSetSIZE-i); void *tp; size_t ts; tp = ps[j]; ts = ss[j]; ps[j] = ps[i]; ss[j] = ss[i]; ps[i] = tp; ss[i] = ts; } /* free half of the objects */ /* upper half, as when allocating them again we want smaller objects */ /* see randomSize() */ for (i=testSetSIZE/2; i<testSetSIZE; ++i) { mps_free(pool, (mps_addr_t)ps[i], ss[i]); /* if (i == testSetSIZE/2) */ /* PoolDescribe((Pool)pool, mps_lib_stdout); */ Insist(alignUp(ss[i], align) + debugOverhead <= allocated); allocated -= alignUp(ss[i], align) + debugOverhead; } /* allocate some new objects */ for (i=testSetSIZE/2; i<testSetSIZE; ++i) { mps_addr_t obj; ss[i] = (*size)(i); res = mps_alloc(&obj, pool, ss[i]); if (res != MPS_RES_OK) return res; ps[i] = obj; allocated += alignUp(ss[i], align) + debugOverhead; } check_allocated_size(pool, allocated); } die(PoolDescribe(pool, mps_lib_get_stdout(), 0), "PoolDescribe"); mps_pool_destroy(pool); return MPS_RES_OK; }
static void test(mps_arena_t arena, mps_class_t pool_class, size_t roots_count) { mps_fmt_t format; mps_chain_t chain; mps_root_t exactRoot, ambigRoot; unsigned long objs; size_t i; mps_word_t collections, rampSwitch; mps_alloc_pattern_t ramp = mps_alloc_pattern_ramp(); int ramping; mps_ap_t busy_ap; mps_addr_t busy_init; mps_pool_t pool; int described = 0; die(dylan_fmt(&format, arena), "fmt_create"); die(mps_chain_create(&chain, arena, genCOUNT, testChain), "chain_create"); die(mps_pool_create(&pool, arena, pool_class, format, chain), "pool_create(amc)"); die(mps_ap_create(&ap, pool, mps_rank_exact()), "BufferCreate"); die(mps_ap_create(&busy_ap, pool, mps_rank_exact()), "BufferCreate 2"); for(i = 0; i < exactRootsCOUNT; ++i) exactRoots[i] = objNULL; for(i = 0; i < ambigRootsCOUNT; ++i) ambigRoots[i] = rnd_addr(); die(mps_root_create_table_masked(&exactRoot, arena, mps_rank_exact(), (mps_rm_t)0, &exactRoots[0], exactRootsCOUNT, (mps_word_t)1), "root_create_table(exact)"); die(mps_root_create_table(&ambigRoot, arena, mps_rank_ambig(), (mps_rm_t)0, &ambigRoots[0], ambigRootsCOUNT), "root_create_table(ambig)"); /* create an ap, and leave it busy */ die(mps_reserve(&busy_init, busy_ap, 64), "mps_reserve busy"); collections = 0; rampSwitch = rampSIZE; die(mps_ap_alloc_pattern_begin(ap, ramp), "pattern begin (ap)"); die(mps_ap_alloc_pattern_begin(busy_ap, ramp), "pattern begin (busy_ap)"); ramping = 1; objs = 0; while (collections < collectionsCOUNT) { mps_word_t c; size_t r; c = mps_collections(arena); if (collections != c) { if (!described) { die(ArenaDescribe(arena, mps_lib_get_stdout(), 0), "ArenaDescribe"); described = TRUE; } collections = c; report(arena); printf("%lu objects (mps_collections says: %"PRIuLONGEST")\n", objs, (ulongest_t)c); /* test mps_arena_has_addr */ { size_t hitRatio; unsigned hitsWanted = 4; /* aim for 4 hits (on average) */ /* [Note: The for-loop condition used to be "i < 4 * hitRatio", * with "4" an unexplained naked constant. I have now labelled * it "hitsWanted", as I think that is the intent. RHSK] */ /* how many random addrs must we try, to hit the arena once? */ hitRatio = (0xfffffffful / mps_arena_committed(arena)); for (i = 0; i < hitsWanted * hitRatio ; i++) { /* An exact root maybe in the arena, so add a random 32-bit * offset to it. We may get no hits if it is objNULL. */ mps_addr_t p = (char *)exactRoots[rnd() % exactRootsCOUNT] + rnd()-0x80000000ul; if (mps_arena_has_addr(arena, p)) { printf("%p is in the arena\n", p); } } } for (i = 0; i < exactRootsCOUNT; ++i) cdie(exactRoots[i] == objNULL || (dylan_check(exactRoots[i]) && mps_arena_has_addr(arena, exactRoots[i])), "all roots check"); cdie(!mps_arena_has_addr(arena, NULL), "NULL in arena"); if (collections == collectionsCOUNT / 2) { unsigned long object_count = 0; mps_arena_park(arena); mps_arena_formatted_objects_walk(arena, test_stepper, &object_count, 0); mps_arena_release(arena); printf("stepped on %lu objects.\n", object_count); } if (collections == rampSwitch) { int begin_ramp = !ramping || /* Every other time, switch back immediately. */ (collections & 1); rampSwitch += rampSIZE; if (ramping) { die(mps_ap_alloc_pattern_end(ap, ramp), "pattern end (ap)"); die(mps_ap_alloc_pattern_end(busy_ap, ramp), "pattern end (busy_ap)"); ramping = 0; /* kill half of the roots */ for(i = 0; i < exactRootsCOUNT; i += 2) { if (exactRoots[i] != objNULL) { cdie(dylan_check(exactRoots[i]), "ramp kill check"); exactRoots[i] = objNULL; } } } if (begin_ramp) { die(mps_ap_alloc_pattern_begin(ap, ramp), "pattern rebegin (ap)"); die(mps_ap_alloc_pattern_begin(busy_ap, ramp), "pattern rebegin (busy_ap)"); ramping = 1; } } } r = (size_t)rnd(); if (r & 1) { i = (r >> 1) % exactRootsCOUNT; if (exactRoots[i] != objNULL) cdie(dylan_check(exactRoots[i]), "dying root check"); exactRoots[i] = make(roots_count); if (exactRoots[(exactRootsCOUNT-1) - i] != objNULL) dylan_write(exactRoots[(exactRootsCOUNT-1) - i], exactRoots, exactRootsCOUNT); } else {
static mps_res_t stress(mps_arena_t arena, mps_align_t align, size_t (*size)(unsigned long i), mps_pool_class_t pool_class, mps_arg_s args[]) { mps_res_t res; mps_ap_t ap; unsigned long i, k; int *ps[TEST_SET_SIZE]; size_t ss[TEST_SET_SIZE]; res = mps_pool_create_k(&pool, arena, pool_class, args); if (res != MPS_RES_OK) return res; die(mps_ap_create(&ap, pool, mps_rank_exact()), "BufferCreate"); /* allocate a load of objects */ for(i=0; i<TEST_SET_SIZE; ++i) { mps_addr_t obj; ss[i] = (*size)(i); res = make(&obj, ap, ss[i], align); if (res != MPS_RES_OK) { ss[i] = 0; } else { ps[i]= obj; *ps[i] = 1; /* Write something, so it gets swap. */ } if (verbose) { if (i && i%4==0) putchar('\n'); printf("%"PRIwWORD PRIXLONGEST" %6"PRIXLONGEST" ", (ulongest_t)ps[i], (ulongest_t)ss[i]); } if (i == 100) { PoolDescribe(pool, mps_lib_get_stdout(), 0); } } if (verbose) { putchar('\n'); } for (k=0; k<TEST_LOOPS; ++k) { unsigned long x = rnd()%(TEST_SET_SIZE-1); /* shuffle all the objects */ for(i=0; i<TEST_SET_SIZE; ++i) { unsigned long j = rnd()%(TEST_SET_SIZE-i); void *tp; size_t ts; tp = ps[j]; ts = ss[j]; ps[j] = ps[i]; ss[j] = ss[i]; ps[i] = tp; ss[i] = ts; } /* free some of the objects */ for(i=x; i<TEST_SET_SIZE; ++i) { if (ss[i] > 0) { mps_free(pool, (mps_addr_t)ps[i], ss[i]); ss[i] = 0; } } /* allocate some new objects */ for(i=x; i<TEST_SET_SIZE; ++i) { mps_addr_t obj; size_t s = (*size)(i); res = make(&obj, ap, s, align); if(res != MPS_RES_OK) break; ps[i] = obj; ss[i] = s; if (verbose) { if (i && i%4==0) putchar('\n'); printf("%"PRIwWORD PRIXLONGEST" %6"PRIXLONGEST" ", (ulongest_t)ps[i], (ulongest_t)ss[i]); } } if (verbose) putchar('\n'); } mps_ap_destroy(ap); mps_pool_destroy(pool); return MPS_RES_OK; }