static void init(void) { size_t i; die(dylan_fmt(&format, arena), "fmt_create"); die(mps_chain_create(&chain, arena, genCOUNT, testChain), "chain_create"); die(mps_pool_create(&pool, arena, mps_class_amc(), format, chain), "pool_create(amc)"); 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)"); }
} /* Setup MPS arena and call benchmark. */ static void arena_setup(gcthread_fn_t fn, mps_pool_class_t pool_class, const char *name) { MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD(args, MPS_KEY_ARENA_SIZE, arena_size); MPS_ARGS_ADD(args, MPS_KEY_ARENA_GRAIN_SIZE, arena_grain_size); MPS_ARGS_ADD(args, MPS_KEY_ARENA_ZONED, zoned); RESMUST(mps_arena_create_k(&arena, mps_arena_class_vm(), args)); } MPS_ARGS_END(args); RESMUST(dylan_fmt(&format, arena)); /* Make wrappers now to avoid race condition. */ /* dylan_make_wrappers() uses malloc. */ RESMUST(dylan_make_wrappers()); if (ngen > 0) RESMUST(mps_chain_create(&chain, arena, ngen, gen)); MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD(args, MPS_KEY_FORMAT, format); if (ngen > 0) MPS_ARGS_ADD(args, MPS_KEY_CHAIN, chain); RESMUST(mps_pool_create_k(&pool, arena, pool_class, args)); } MPS_ARGS_END(args); watch(fn, name); mps_arena_park(arena); printf("%u chunks\n", (unsigned)TreeDebugCount(ArenaChunkTree(arena), ChunkCompare, ChunkKey));
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 void *test(void *arg, size_t s) { mps_arena_t arena; mps_fmt_t format; mps_chain_t chain; mps_root_t exactRoot, ambigRoot, singleRoot, fmtRoot; unsigned long i; /* Leave arena clamped until we have allocated this many objects. is 0 when arena has not been clamped. */ unsigned long clamp_until = 0; size_t j; mps_word_t collections; mps_pool_t mv; mps_addr_t alloced_obj; size_t asize = 32; /* size of alloced obj */ mps_addr_t obj; mps_ld_s ld; mps_alloc_pattern_t ramp = mps_alloc_pattern_ramp(); size_t rampCount = 0; mps_res_t res; arena = (mps_arena_t)arg; testlib_unused(s); die(dylan_fmt(&format, arena), "fmt_create"); die(mps_chain_create(&chain, arena, genCOUNT, testChain), "chain_create"); die(mps_pool_create(&mv, arena, mps_class_mv(), 0x10000, 32, 0x10000), "pool_create(mv)"); pool_create_v_test(arena, format, chain); /* creates amc pool */ ap_create_v_test(amcpool); die(mps_ap_create(&ap, amcpool), "ap_create"); for(j = 0; j < exactRootsCOUNT; ++j) { exactRoots[j] = objNULL; } for(j = 0; j < ambigRootsCOUNT; ++j) { ambigRoots[j] = (mps_addr_t)rnd(); } 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)"); obj = objNULL; die(mps_root_create(&singleRoot, arena, MPS_RANK_EXACT, (mps_rm_t)0, &root_single, &obj, 0), "root_create(single)"); /* test non-inlined reserve/commit */ obj = make_no_inline(); die(mps_alloc(&alloced_obj, mv, asize), "mps_alloc"); die(dylan_init(alloced_obj, asize, exactRoots, exactRootsCOUNT), "dylan_init(alloced_obj)"); die(mps_root_create_fmt(&fmtRoot, arena, MPS_RANK_EXACT, (mps_rm_t)0, dylan_fmt_A()->scan, alloced_obj, (mps_addr_t)(((char*)alloced_obj)+asize)), "root_create_fmt"); mps_ld_reset(&ld, arena); mps_ld_add(&ld, arena, obj); if (mps_ld_isstale(&ld, arena, obj)) { mps_ld_reset(&ld, arena); mps_ld_add(&ld, arena, obj); } collections = mps_collections(arena); for(i = 0; i < OBJECTS; ++i) { unsigned c; size_t r; c = mps_collections(arena); if(collections != c) { collections = c; printf("\nCollection %u, %lu objects.\n", c, i); for(r = 0; r < exactRootsCOUNT; ++r) { cdie(exactRoots[r] == objNULL || dylan_check(exactRoots[r]), "all roots check"); } if(collections == 1) { mps_arena_clamp(arena); clamp_until = i + 10000; } if(collections % 6 == 0) { mps_arena_expose(arena); mps_arena_release(arena); } if(collections % 6 == 3) { mps_arena_unsafe_expose_remember_protection(arena); mps_arena_unsafe_restore_protection(arena); mps_arena_release(arena); } if(collections % 6 == 4) { mps_arena_unsafe_expose_remember_protection(arena); mps_arena_release(arena); } if(collections % 3 == 2) { mps_arena_park(arena); mps_arena_release(arena); } } if(clamp_until && i >= clamp_until) { mps_arena_release(arena); clamp_until = 0; } if (rnd() % patternFREQ == 0) { switch(rnd() % 4) { case 0: case 1: die(mps_ap_alloc_pattern_begin(ap, ramp), "alloc_pattern_begin"); ++rampCount; break; case 2: res = mps_ap_alloc_pattern_end(ap, ramp); cdie(rampCount > 0 ? res == MPS_RES_OK : res == MPS_RES_FAIL, "alloc_pattern_end"); if (rampCount > 0) { --rampCount; } break; case 3: die(mps_ap_alloc_pattern_reset(ap), "alloc_pattern_reset"); rampCount = 0; break; } } if (rnd() & 1) { exactRoots[rnd() % exactRootsCOUNT] = make(); } else { ambigRoots[rnd() % ambigRootsCOUNT] = make(); } r = rnd() % exactRootsCOUNT; if (exactRoots[r] != objNULL) { cdie(dylan_check(exactRoots[r]), "random root check"); } } arena_commit_test(arena); reservoir_test(arena); alignmentTest(arena); die(mps_arena_collect(arena), "collect"); mps_free(mv, alloced_obj, 32); alloc_v_test(mv); mps_pool_destroy(mv); mps_ap_destroy(ap); mps_root_destroy(fmtRoot); mps_root_destroy(singleRoot); mps_root_destroy(exactRoot); mps_root_destroy(ambigRoot); mps_pool_destroy(amcpool); mps_chain_destroy(chain); mps_fmt_destroy(format); return NULL; }
static void *test(void *arg, size_t s) { mps_arena_t arena; mps_fmt_t format; mps_chain_t chain; mps_root_t exactRoot, ambigRoot; unsigned long objs; size_t i; mps_message_t message; size_t live, condemned, not_condemned; size_t messages; mps_word_t collections, old_collections; double total_mps_time, total_time; double t1; arena = (mps_arena_t)arg; (void)s; /* unused */ die(dylan_fmt(&format, arena), "fmt_create"); die(mps_chain_create(&chain, arena, genCOUNT, testChain), "chain_create"); die(mps_pool_create(&pool, arena, mps_class_amc(), format, chain), "pool_create(amc)"); die(mps_ap_create(&ap, pool, mps_rank_exact()), "BufferCreate"); 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)"); printf("Stepping every %lu allocations.\n", (unsigned long)step_frequencies[test_number]); mps_message_type_enable(arena, mps_message_type_gc()); /* zero all our counters and timers. */ objs = 0; clock_reads = 0; steps = no_steps = 0; alloc_bytes = 0; commit_failures = 0; alloc_time = step_time = no_step_time = 0.0; max_alloc_time = max_step_time = max_no_step_time = 0.0; total_clock_time = 0.0; collections = old_collections = 0; t1 = my_clock(); while(objs < objCOUNT) { size_t r; 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(); if(exactRoots[(exactRootsCOUNT-1) - i] != objNULL) dylan_write(exactRoots[(exactRootsCOUNT-1) - i], exactRoots, exactRootsCOUNT); } else {
static void *test(mps_arena_t arena, mps_class_t pool_class) { mps_chain_t chain; mps_fmt_t format; mps_pool_t pool; mps_root_t exactRoot; size_t i; unsigned long objs; struct stepper_data sdStruct, *sd; die(dylan_fmt(&format, arena), "fmt_create"); die(mps_chain_create(&chain, arena, genCOUNT, testChain), "chain_create"); MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD(args, MPS_KEY_FORMAT, format); MPS_ARGS_ADD(args, MPS_KEY_CHAIN, chain); MPS_ARGS_ADD(args, MPS_KEY_AWL_FIND_DEPENDENT, test_awl_find_dependent); die(mps_pool_create_k(&pool, arena, pool_class, args), "pool_create"); } MPS_ARGS_END(args); die(mps_ap_create(&ap, pool, mps_rank_exact()), "ap_create"); for(i = 0; i < exactRootsCOUNT; ++i) exactRoots[i] = objNULL; 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)"); objs = 0; while(objs < objCOUNT) { size_t r; r = objs; i = r % 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); ++objs; } sd = &sdStruct; sd->arena = arena; sd->expect_pool = pool; sd->expect_fmt = format; sd->count = 0; mps_arena_formatted_objects_walk(arena, stepper, sd, sizeof *sd); /* Note: stepper finds more than we expect, due to pad objects */ /* printf("stepper found %ld objs\n", sd->count); */ mps_ap_destroy(ap); mps_root_destroy(exactRoot); mps_pool_destroy(pool); mps_chain_destroy(chain); mps_fmt_destroy(format); return NULL; }
static void *test(void *arg, size_t s) { mps_arena_t arena; 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; arena = (mps_arena_t)arg; (void)s; /* unused */ die(dylan_fmt(&format, arena), "fmt_create"); die(mps_chain_create(&chain, arena, genCOUNT, testChain), "chain_create"); die(mps_pool_create(&pool, arena, mps_class_amc(), 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) { unsigned long c; size_t r; size_t hitRatio; c = mps_collections(arena); if (collections != c) { collections = c; printf("\nCollection %lu started, %lu objects.\n", c, objs); /* test mps_arena_has_addr */ hitRatio = ((size_t)-1 / mps_arena_committed(arena)); /* That's roughly how often a random addr should hit the arena. */ for (i = 0; i < 4 * hitRatio ; i++) { mps_addr_t p = rnd_addr(); if (mps_arena_has_addr(arena, p)) { printf("%p is in the arena\n", p); } } report(arena); 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(); if (exactRoots[(exactRootsCOUNT-1) - i] != objNULL) dylan_write(exactRoots[(exactRootsCOUNT-1) - i], exactRoots, exactRootsCOUNT); } else {
static void test(mps_arena_t arena, mps_pool_class_t pool_class) { mps_chain_t chain; mps_fmt_t format; mps_pool_t pool; mps_root_t exactRoot; size_t i; size_t totalSize, freeSize, allocSize, bufferSize; unsigned long objs; struct stepper_data sdStruct, *sd; PoolClass class; die(dylan_fmt(&format, arena), "fmt_create"); die(mps_chain_create(&chain, arena, genCOUNT, testChain), "chain_create"); MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD(args, MPS_KEY_FORMAT, format); MPS_ARGS_ADD(args, MPS_KEY_CHAIN, chain); die(mps_pool_create_k(&pool, arena, pool_class, args), "pool_create"); } MPS_ARGS_END(args); die(mps_ap_create(&ap, pool, mps_rank_exact()), "ap_create"); for(i = 0; i < exactRootsCOUNT; ++i) exactRoots[i] = objNULL; 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)"); objs = 0; while(objs < objCOUNT) { size_t r; r = objs; i = r % 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); ++objs; } mps_arena_park(arena); sd = &sdStruct; sd->arena = arena; sd->expect_pool = pool; sd->expect_fmt = format; sd->count = 0; sd->objSize = 0; sd->padSize = 0; mps_arena_formatted_objects_walk(arena, stepper, sd, sizeof *sd); Insist(sd->count == objs); totalSize = mps_pool_total_size(pool); freeSize = mps_pool_free_size(pool); allocSize = totalSize - freeSize; bufferSize = AddrOffset(ap->init, ap->limit); class = ClassOfPoly(Pool, pool); printf("%s: obj=%lu pad=%lu total=%lu free=%lu alloc=%lu buffer=%lu\n", ClassName(class), (unsigned long)sd->objSize, (unsigned long)sd->padSize, (unsigned long)totalSize, (unsigned long)freeSize, (unsigned long)allocSize, (unsigned long)bufferSize); Insist(sd->objSize + sd->padSize + bufferSize == allocSize); mps_ap_destroy(ap); mps_root_destroy(exactRoot); mps_pool_destroy(pool); mps_chain_destroy(chain); mps_fmt_destroy(format); mps_arena_release(arena); }