static int dllskin_meminit(SWSTART *start) { int32 i ; mps_arena_t dllskin_arena = NULL ; /* Spy on the memory configuration tags to find the arena */ for ( i = 0 ; dllskin_arena == NULL && start[i].tag != SWEndTag ; ++i ) { switch ( start[i].tag ) { case SWMemoryTag: dllskin_arena = ((SWSTART_MEMORY *)start[i].value.pointer_value)->arena; break ; case SWMemCfgTag: dllskin_arena = ((SWSTART_MEMCFG *)start[i].value.pointer_value)->arena; break ; } } if ( dllskin_arena != NULL ) { mps_res_t res = mps_pool_create(&dllskin_pool, dllskin_arena, mps_class_mvff(), (size_t)65536, (size_t)32, (size_t)8, EPDR_LIKE); if ( res == MPS_RES_OK ) { mps_word_t label = mps_telemetry_intern("DLLskin pool"); mps_telemetry_label((mps_addr_t)dllskin_pool, label); } else { SecurityExit(1, (uint8 *)"Unicode memory pool initialisation failed"); return FALSE ; } } return TRUE ; }
static void test(void *stack_pointer) { mps_arena_t arena; mps_pool_t pool; mps_addr_t block[ITERATIONS]; unsigned i; MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD(args, MPS_KEY_ARENA_SIZE, CHUNKSIZE); die(mps_arena_create_k(&arena, mps_arena_class_vm(), args), "arena_create"); } MPS_ARGS_END(args); MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD(args, MPS_KEY_SPARE, 0); die(mps_pool_create_k(&pool, arena, mps_class_mvff(), args), "pool_create"); } MPS_ARGS_END(args); check_chunks(arena, 1); for (i = 0; i < ITERATIONS; ++i) { die(mps_alloc(&block[i], pool, CHUNKSIZE), "mps_alloc"); check_chunks(arena, i + 2); } for (i = ITERATIONS; i > 0; --i) { mps_free(pool, block[i - 1], CHUNKSIZE); mps_arena_collect(arena); /* ensure ArenaCompact is called */ check_chunks(arena, i); } mps_pool_destroy(pool); mps_arena_destroy(arena); }
static void testInArena(mps_arena_class_t arena_class, mps_arg_s *arena_args, mps_pool_debug_option_s *options) { mps_arena_t arena; die(mps_arena_create_k(&arena, arena_class, arena_args), "mps_arena_create"); MPS_ARGS_BEGIN(args) { mps_align_t align = sizeof(void *) << (rnd() % 4); MPS_ARGS_ADD(args, MPS_KEY_ALIGN, align); MPS_ARGS_ADD(args, MPS_KEY_MVFF_ARENA_HIGH, TRUE); MPS_ARGS_ADD(args, MPS_KEY_MVFF_SLOT_HIGH, TRUE); MPS_ARGS_ADD(args, MPS_KEY_MVFF_FIRST_FIT, TRUE); MPS_ARGS_ADD(args, MPS_KEY_SPARE, rnd_double()); die(stress(arena, NULL, randomSize8, align, "MVFF", mps_class_mvff(), args), "stress MVFF"); } MPS_ARGS_END(args); MPS_ARGS_BEGIN(args) { mps_align_t align = sizeof(void *) << (rnd() % 4); MPS_ARGS_ADD(args, MPS_KEY_ALIGN, align); MPS_ARGS_ADD(args, MPS_KEY_MVFF_ARENA_HIGH, TRUE); MPS_ARGS_ADD(args, MPS_KEY_MVFF_SLOT_HIGH, TRUE); MPS_ARGS_ADD(args, MPS_KEY_MVFF_FIRST_FIT, TRUE); MPS_ARGS_ADD(args, MPS_KEY_SPARE, rnd_double()); MPS_ARGS_ADD(args, MPS_KEY_POOL_DEBUG_OPTIONS, options); die(stress(arena, options, randomSize8, align, "MVFF debug", mps_class_mvff_debug(), args), "stress MVFF debug"); } MPS_ARGS_END(args); MPS_ARGS_BEGIN(args) { mps_align_t align = (mps_align_t)1 << (rnd() % 6); MPS_ARGS_ADD(args, MPS_KEY_ALIGN, align); die(stress(arena, NULL, randomSize, align, "MV", mps_class_mv(), args), "stress MV"); } MPS_ARGS_END(args); MPS_ARGS_BEGIN(args) { mps_align_t align = (mps_align_t)1 << (rnd() % 6); MPS_ARGS_ADD(args, MPS_KEY_ALIGN, align); MPS_ARGS_ADD(args, MPS_KEY_POOL_DEBUG_OPTIONS, options); die(stress(arena, options, randomSize, align, "MV debug", mps_class_mv_debug(), args), "stress MV debug"); } MPS_ARGS_END(args); MPS_ARGS_BEGIN(args) { fixedSizeSize = 1 + rnd() % 64; MPS_ARGS_ADD(args, MPS_KEY_MFS_UNIT_SIZE, fixedSizeSize); MPS_ARGS_ADD(args, MPS_KEY_EXTEND_BY, 100000); die(stress(arena, NULL, fixedSize, MPS_PF_ALIGN, "MFS", mps_class_mfs(), args), "stress MFS"); } MPS_ARGS_END(args); /* Manual allocation should not cause any garbage collections. */ Insist(mps_collections(arena) == 0); mps_arena_destroy(arena); }
static void testInArena(mps_arena_t arena) { mps_pool_t lopool, hipool; PoolStatStruct lostruct; /* stats about lopool */ PoolStatStruct histruct; /* stats about lopool */ PoolStat lostat = &lostruct; PoolStat histat = &histruct; int i; die(mps_pool_create(&hipool, arena, mps_class_mvff(), chunkSize, chunkSize, (mps_align_t)1024, TRUE, TRUE, TRUE), "Create HI MFFV"); die(mps_pool_create(&lopool, arena, mps_class_mvff(), chunkSize, chunkSize, (mps_align_t)1024, FALSE, FALSE, TRUE), "Create LO MFFV"); poolStatInit(lostat, lopool, chunkSize); poolStatInit(histat, hipool, chunkSize); /* iterate, allocating objects */ for (i=0; i<iterationCount; ++i) { allocMultiple(lostat); allocMultiple(histat); } /* report results */ reportResults(lostat, "the low MVFF pool"); reportResults(histat, "the high MVFF pool"); if (lostat->max > histat->min) { error("\nFOUND PROBLEM - low range overlaps high\n"); } else { printf("\nNo problems detected.\n"); } mps_pool_destroy(hipool); mps_pool_destroy(lopool); }
static void test(void *stack_pointer) { mps_thr_t thread; mps_pool_t pool; unsigned int i; unsigned long nLarge; cdie(mps_arena_create(&arena, mps_arena_class_vm(), (size_t) (1024*1024*50)), "create arena"); cdie(mps_thread_reg(&thread, arena), "register thread"); mps_arena_commit_limit_set(arena, COMLIMIT1); die(mps_pool_create(&pool, arena, mps_class_mvff(), (size_t)EXTENDBY, (size_t)8, (mps_align_t)MPS_PF_ALIGN, (mps_bool_t)0, (mps_bool_t)0, (mps_bool_t)1), "create MVFF pool"); for (i = 0; i < NSMALL; i++) { die(mps_alloc(&smallObjects[i], pool, SMALLSIZE), "small alloc failed"); } nLarge = 0; while (mps_alloc(&largeObjects[nLarge], pool, BIGSIZE) == MPS_RES_OK) { nLarge ++; } report("nLarge", "%lu", nLarge); for (i = 0; i < NSMALL; i += 2) { mps_free(pool, smallObjects[i], SMALLSIZE); } comment("Freed every other small object."); /* The CBS should be in emergency mode now. */ for (i = 0; i < nLarge; i += 2) { mps_free(pool, largeObjects[i], BIGSIZE); } comment("Freed every other large object."); /* Now there should be lots of big blocks on the CBS. */ mps_arena_commit_limit_set(arena, COMLIMIT2); comment("Raised the commit limit. Will attempt free and alloc."); mps_free(pool, largeObjects[1], BIGSIZE); die(mps_alloc(&largeObjects[0], pool, BIGSIZE), "alloc failed"); mps_pool_destroy(pool); mps_thread_dereg(thread); mps_arena_destroy(arena); }
static void test(void) { mps_arena_t arena; mps_pool_t pool; mps_addr_t p; die(mps_arena_create_k(&arena, mps_arena_class_vm(), mps_args_none), "arena_create"); die(mps_pool_create_k(&pool, arena, mps_class_mvff(), mps_args_none), "pool_create"); die(mps_alloc(&p, pool, 4096), "alloc"); die(mps_finalize(arena, &p), "finalize"); mps_pool_destroy(pool); mps_arena_destroy(arena); }
static void test(void *stack_pointer) { mps_arena_t arena; mps_pool_t pool; mps_addr_t obj; cdie(mps_arena_create(&arena, mps_arena_class_vm(), mmqaArenaSIZE), "create arena"); cdie(mps_pool_create_k(&pool, arena, mps_class_mvff(), mps_args_none), "pool"); cdie(mps_alloc(&obj, pool, 152), "allocate"); mps_free(pool, obj, 512); mps_pool_destroy(pool); mps_arena_destroy(arena); }
Bool mm_reserve_create(void) { mps_word_t sym; Bool res; unsigned level; HQASSERT(mm_arena, "mm_reserve_create called without valid mm_arena"); HQASSERT(mm_pool_reserve == NULL, "mm_reserve_create called when mm_pool_reserve already created"); #ifdef REGAIN_AT_FREE multi_mutex_init(&reserve_mutex, RESERVE_LOCK_INDEX, FALSE, SW_TRACE_RESERVE_ACQUIRE, SW_TRACE_RESERVE_HOLD); #endif if ( mps_pool_create(&mm_pool_reserve, mm_arena, mps_class_mvff(), DL_POOL_PARAMS, FALSE, FALSE, TRUE) != MPS_RES_OK ) { #ifdef REGAIN_AT_FREE multi_mutex_destroy(&reserve_mutex) ; #endif return FALSE; } mm_reserve_level = mm_reserve_numlevels = MM_RESERVE_MAXLEVELS; /* No reserve yet */ for ( level = mm_reserve_level ; level < mm_reserve_numlevels-1 ; level++ ) HQASSERT(mm_cost_less_than(mm_reserve_table[level].cost, mm_cost_normal), "Normal cost doesn't include reserve."); HQASSERT(!mm_cost_less_than(mm_reserve_table[mm_reserve_numlevels-1].cost, mm_cost_normal), "Normal cost includes final reserve."); sym = mps_telemetry_intern("MM reserve pool"); mps_telemetry_label((mps_addr_t)mm_pool_reserve, sym); res = mm_reserve_get(mm_cost_below_reserves); /* This effectively asserts mm_cost_below_reserves is small enough. */ HQASSERT( res, "init: didn't get reserve!" ); res = low_mem_handler_register(&reserve_pool_handler); if ( !res ) mps_pool_destroy(mm_pool_reserve); return res; }
mps_res_t ps_init(mps_arena_t arena, mps_pool_t pool0, mps_pool_t pool1) { size_t i; mps_res_t res; pool[0] = pool0; pool[1] = pool1; for (i = 0; i < MAXSAVELEVELS; ++i) saves[i] = NULL; res = mps_root_create(&saveRoot, arena, mps_rank_exact(), 0, scan_saves, NULL, 0); if (res != MPS_RES_OK) return res; res = mps_pool_create(&savePool, arena, mps_class_mvff(), 8192, sizeof(saveRecord), (mps_align_t)sizeof(OBJECT), TRUE, TRUE, TRUE); if (res != MPS_RES_OK) goto failPool; Context.savelevel = 0; ps_save(); /* ps_*_init assume global savelevel */ namepurges = NULL; return MPS_RES_OK; failPool: mps_root_destroy(saveRoot); return res; }
static void testInArena(mps_arena_t arena, mps_bool_t failcase, mps_bool_t usefulFailcase) { mps_pool_t lopool, hipool, temppool; PoolStatStruct lostruct; /* stats about lopool */ PoolStatStruct histruct; /* stats about lopool */ PoolStatStruct tempstruct; /* stats about temppool */ PoolStat lostat = &lostruct; PoolStat histat = &histruct; PoolStat tempstat = &tempstruct; int i; die(mps_pool_create(&hipool, arena, mps_class_mvff(), chunkSize, chunkSize, (size_t)1024, TRUE, TRUE, TRUE), "Create HI MFFV"); die(mps_pool_create(&lopool, arena, mps_class_mvff(), chunkSize, chunkSize, (size_t)1024, FALSE, FALSE, TRUE), "Create LO MFFV"); die(mps_pool_create(&temppool, arena, mps_class_mv(), chunkSize, chunkSize, chunkSize), "Create TEMP"); if(failcase) { if(usefulFailcase) { /* describe a useful failure case */ } else { /* describe a misleading failure case */ } } poolStatInit(lostat, lopool, chunkSize); poolStatInit(histat, hipool, chunkSize); poolStatInit(tempstat, temppool, chunkSize); /* iterate, allocating objects */ for (i=0; i<iterationCount; ++i) { mps_res_t res; res = allocMultiple(lostat); if (res != MPS_RES_OK) break; res = allocMultiple(histat); if (res != MPS_RES_OK) break; res = allocMultiple(tempstat); if (res != MPS_RES_OK) break; } /* report results */ reportResults(lostat, "the low MVFF pool"); reportResults(histat, "the high MVFF pool"); reportResults(tempstat, "the temp pool"); mps_pool_destroy(hipool); mps_pool_destroy(lopool); mps_pool_destroy(temppool); }
static void test(void *stack_pointer) { mps_arena_t arena; mps_pool_t poolMVFF, poolAMC; mps_thr_t thread; mps_fmt_t format; mps_chain_t chain; mps_ap_t ap; mps_res_t r; mycell *a; mps_addr_t p; int i; int s1, s2, s3; cdie(mps_arena_create(&arena, mps_arena_class_vm(), mmqaArenaSIZE), "create arena"); cdie(mps_thread_reg(&thread, arena), "register thread"); die(mps_fmt_create_A(&format, arena, &fmtA), "create format"); cdie(mps_chain_create(&chain, arena, genCOUNT, testChain), "chain_create"); formatcomments = 0; die(mmqa_pool_create_chain(&poolAMC, arena, mps_class_amc(), format, chain), "create pool"); cdie( mps_ap_create(&ap, poolAMC, mps_rank_exact()), "create ap"); comment("Sizes in megabytes:"); MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD(args, MPS_KEY_EXTEND_BY, EXTEND_BY); MPS_ARGS_ADD(args, MPS_KEY_MEAN_SIZE, MEAN_SIZE); cdie(mps_pool_create_k(&poolMVFF, arena, mps_class_mvff(), args), "create MVFF pool"); } MPS_ARGS_END(args); i = 0; while ((r=mps_alloc(&p, poolMVFF, 1024*1024)) == 0) i++; report("refuse1", "%s", err_text(r)); report("size1", "%i", i); s1 = i; mps_pool_destroy(poolMVFF); MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD(args, MPS_KEY_EXTEND_BY, EXTEND_BY); MPS_ARGS_ADD(args, MPS_KEY_MEAN_SIZE, MEAN_SIZE); cdie(mps_pool_create_k(&poolMVFF, arena, mps_class_mvff(), args), "create MVFF pool"); } MPS_ARGS_END(args); i = 0; while ((r=mps_alloc(&p, poolMVFF, 1024*1024)) == 0) i++; report("refuse2", "%s", err_text(r)); report("size2", "%i", i); s2 = i; mps_pool_destroy(poolMVFF); a = allocdumb(ap, 1024*1024*30); /* allocate 30 M object */ MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD(args, MPS_KEY_EXTEND_BY, EXTEND_BY); MPS_ARGS_ADD(args, MPS_KEY_MEAN_SIZE, MEAN_SIZE); cdie(mps_pool_create_k(&poolMVFF, arena, mps_class_mvff(), args), "create MVFF pool"); } MPS_ARGS_END(args); i=0; while ((r=mps_alloc(&p, poolMVFF, 1024*1024)) == 0) i++; report("refuse3", "%s", err_text(r)); report("size3", "%i", i); s3 = i; report("diff12", "%i", s1-s2); report("diff23", "%i", s2-s3); for(i = 0; i < 10; i++) { r = mps_alloc(&p, poolMVFF, 1024*1024); report("refuse4", "%s", err_text(r)); } mps_arena_park(arena); mps_pool_destroy(poolMVFF); mps_ap_destroy(ap); mps_pool_destroy(poolAMC); comment("Destroyed pool."); mps_chain_destroy(chain); mps_fmt_destroy(format); mps_thread_dereg(thread); mps_arena_destroy(arena); comment("Destroyed arena."); }
static void test(void) { mps_pool_t poolhi, poollo; mps_thr_t thread; unsigned long com0, com1; /* create a VM arena of 30MB */ cdie(mps_arena_create(&arena, mps_arena_class_vmnz(), (size_t) (1024*1024*40)), "create arena"); /* set the commit limit to 100MB, i.e. let the arena do the limiting */ mps_arena_commit_limit_set(arena, (size_t) (1024ul*1024ul*100ul)); cdie(mps_thread_reg(&thread, arena), "register thread"); cdie( mps_pool_create(&poolhi, arena, mps_class_mvff(), MVFF_HI_PARMS), "create high pool"); cdie( mps_pool_create(&poollo, arena, mps_class_mvff(), MVFF_LO_PARMS), "create low pool"); /* set the spare commit limit to something very big */ mps_arena_spare_commit_limit_set(arena, (size_t)-1); /* allocate a jolly big object, clamp the commit limit down, leaving 64KB space, then free it */ die(mps_alloc(&objs[0], poollo, BIGSIZE), "alloc"); com0 = mps_arena_committed(arena); mps_arena_commit_limit_set(arena, com0+(1024*64)); mps_free(poollo, objs[0], BIGSIZE); com1 = mps_arena_committed(arena); /* the free shouldn't have reduced the total amount committed */ report("reduce1", "%ld", com0-com1); /* it should be possible to reallocate the object */ die(mps_alloc(&objs[0], poollo, BIGSIZE), "alloc lo"); mps_free(poollo, objs[0], BIGSIZE); /* it should equally be possible to allocate an object in a different segment (poolhi). This ought to flush the spare. */ die(mps_alloc(&objs[0], poolhi, BIGSIZE), "alloc hi"); mps_free(poolhi, objs[0], BIGSIZE); comment("Finishing off."); mps_pool_destroy(poolhi); mps_pool_destroy(poollo); comment("Destroyed pool."); mps_thread_dereg(thread); comment("Deregistered thread."); mps_arena_destroy(arena); comment("Destroyed arena."); }
static void dt(int kind, size_t extendBy, size_t avgSize, unsigned long mins, unsigned long maxs, int number, int iter) { mps_pool_t pool; int i, hd; clock_t time0, time1; size_t size; double secs; asserts(number <= MAXNUMBER, "number too big"); time0 = clock(); asserts(time0 != -1, "processor time not available"); MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD(args, MPS_KEY_EXTEND_BY, extendBy); MPS_ARGS_ADD(args, MPS_KEY_MEAN_SIZE, avgSize); cdie(mps_pool_create_k(&pool, arena, mps_class_mvff(), args), "pool"); } MPS_ARGS_END(args); for(hd=0; hd<number; hd++) { size = ranrange(mins, maxs); if ((ranint(2) && (kind & 2)) || (kind==DUMMY)) { queue[hd].addr=NULL; } else { die(mps_alloc(&queue[hd].addr, pool, size), "alloc"); setobj(queue[hd].addr, size, (unsigned char) (hd%256)); queue[hd].size = size; } }; hd=-1; for(i=0; i<iter; i++) { if (kind & 1) hd = ranint(number); else {ranint(number); hd=(hd+1)%number;} /* call raninit anyway to use same time */ if (queue[hd].addr != NULL) { asserts(chkobj(queue[hd].addr, queue[hd].size, (unsigned char) (hd%256)), "corrupt at %x (%s: %x, %x, %lx, %lx, %i, %i)", queue[hd].addr, tdesc[kind], (int) extendBy, (int) avgSize, mins, maxs, number, iter); mps_free(pool, queue[hd].addr, queue[hd].size); } size = ranrange(mins, maxs); if ((ranint(2) && (kind & 2)) || (kind==DUMMY)) { queue[hd].addr=NULL; } else { die(mps_alloc(&queue[hd].addr, pool, size),"alloc"); setobj(queue[hd].addr, size, (unsigned char) (hd%256)); queue[hd].size = size; } } mps_pool_destroy(pool); time1=clock(); secs=(time1-time0)/(double)CLOCKS_PER_SEC; comment("%s test (%x, %x, %lx, %lx, %i, %i) in %.2f s", tdesc[kind], (int) extendBy, (int) avgSize, mins, maxs, number, iter, secs); }
static void t_alloc(int spare, int spare_total, int commit, int obj_size) { size_t size, hisize, comsize, comlimit; size_t spsize = 0, losize = 0; /* stop warnings */ mps_res_t res, res_expected; if (obj_size == OBJ_SMALL) size = SMALL_SIZE; else size = BIG_SIZE; switch (spare_total) { case SPARE_EMPTY: spsize = 0; break; case SPARE_LESS: if (size > DIFF_SIZE) { spsize = size-DIFF_SIZE; } else { spsize = 0; } break; case SPARE_EXACT: spsize = size; break; case SPARE_MORE: spsize = size+DIFF_SIZE; break; default: error("Illegal spare.\n"); break; } switch (spare) { case SPARE_EMPTY: losize = 0; break; case SPARE_LESS: if (size > DIFF_SIZE) { losize = size-DIFF_SIZE; } else { losize = 0; } break; case SPARE_EXACT: losize = size; break; case SPARE_MORE: losize = size+DIFF_SIZE; break; } if (losize > spsize) { losize = spsize; hisize = 0; } else { hisize = spsize-losize; } /* turn off commit limit for a moment */ mps_arena_commit_limit_set(arena, HUGE); /* create low and high pools */ die( mps_pool_create(&poolhi, arena, mps_class_mvff(), MVFF_HI_PARMS), "create high pool"); die( mps_pool_create(&poollo, arena, mps_class_mvff(), MVFF_LO_PARMS), "create low pool"); /* flush hysteresis fund, then set limit */ mps_arena_spare_commit_limit_set(arena, SPARE_ZERO); mps_arena_spare_commit_limit_set(arena, SPARE_LIMIT); /* allocate something in each pool (to reduce risk of subsidiary allocation being neede later */ die(mps_alloc(&objlo, poollo, EXTEND), "low alloc"); die(mps_alloc(&objhi, poolhi, EXTEND), "high alloc"); /* set up spare committed the way we want it */ if (losize>0) { die(mps_alloc(&objlo, poollo, losize), "low setup"); mps_free(poollo, objlo, losize); } if (hisize>0) { die(mps_alloc(&objhi, poolhi, hisize), "high setup"); mps_free(poolhi, objhi, hisize); } /* spare is now set up correctly */ /* now we need to set the commit limit correctly */ comsize = arena_committed_and_used(arena); /* allow for 1/16th memory overhead in setting commit limit */ if (commit == COMMIT_EXACT) { comlimit = comsize+size+(size/16); } else if (commit == COMMIT_NOCHANGE) { comlimit = mps_arena_committed(arena); } else if (commit == COMMIT_PLENTY) { comlimit = HUGE; } else /* commit == COMMIT_LITTLE */ { if (size > DIFF_SIZE) { comlimit = comsize+size+(size/16)+DIFF_SIZE; } else { comlimit = comsize+size+(size/16); } } die(mps_arena_commit_limit_set(arena, comlimit), "commit limit set"); res = mps_alloc(&objlo, poollo, size); asserts(comlimit >= comsize, "comlimit was less than comsize!"); if (size <= (comlimit-comsize)) { res_expected = MPS_RES_OK; } else { res_expected = MPS_RES_COMMIT_LIMIT; } if (res != res_expected) { comment("Spare useful/total %i/%i. Limit %i. Size %i. Expected %s. Got %s", spare, spare_total, commit, obj_size, err_text(res_expected), err_text(res)); report("failed", "yes"); } mps_pool_destroy(poollo); mps_pool_destroy(poolhi); }