diff options
| author | Nick Barnes | 2002-06-18 14:14:55 +0100 |
|---|---|---|
| committer | Nick Barnes | 2002-06-18 14:14:55 +0100 |
| commit | 6a1a360814506ddbcf856f41c089a10550f31ae5 (patch) | |
| tree | 732fc720ec58b9badf2ce1eef392ada522130a03 /mps/code/amcss.c | |
| parent | 63e5f529159927bb42b58a97507f4467d6413973 (diff) | |
| download | emacs-6a1a360814506ddbcf856f41c089a10550f31ae5.tar.gz emacs-6a1a360814506ddbcf856f41c089a10550f31ae5.zip | |
Integrate changes from global graphics.
Copied from Perforce
Change: 30250
ServerID: perforce.ravenbrook.com
Diffstat (limited to 'mps/code/amcss.c')
| -rw-r--r-- | mps/code/amcss.c | 138 |
1 files changed, 80 insertions, 58 deletions
diff --git a/mps/code/amcss.c b/mps/code/amcss.c index d8569c7873f..b89f2559579 100644 --- a/mps/code/amcss.c +++ b/mps/code/amcss.c | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | * | 2 | * |
| 3 | * $Id$ | 3 | * $Id$ |
| 4 | * Copyright (c) 2001 Ravenbrook Limited. | 4 | * Copyright (c) 2001 Ravenbrook Limited. |
| 5 | * Copyright (C) 2002 Global Graphics Software. | ||
| 5 | */ | 6 | */ |
| 6 | 7 | ||
| 7 | #include "fmtdy.h" | 8 | #include "fmtdy.h" |
| @@ -18,10 +19,12 @@ | |||
| 18 | #include <string.h> | 19 | #include <string.h> |
| 19 | 20 | ||
| 20 | 21 | ||
| 21 | /* These values have been tuned to cause one top-generation collection. */ | 22 | /* These values have been tuned in the hope of getting one dynamic collection. */ |
| 22 | #define testArenaSIZE ((size_t)1000*1024) | 23 | #define testArenaSIZE ((size_t)1000*1024) |
| 24 | #define gen1SIZE ((size_t)150) | ||
| 25 | #define gen2SIZE ((size_t)170) | ||
| 23 | #define avLEN 3 | 26 | #define avLEN 3 |
| 24 | #define exactRootsCOUNT 200 | 27 | #define exactRootsCOUNT 180 |
| 25 | #define ambigRootsCOUNT 50 | 28 | #define ambigRootsCOUNT 50 |
| 26 | #define genCOUNT 2 | 29 | #define genCOUNT 2 |
| 27 | #define collectionsCOUNT 37 | 30 | #define collectionsCOUNT 37 |
| @@ -31,41 +34,50 @@ | |||
| 31 | /* testChain -- generation parameters for the test */ | 34 | /* testChain -- generation parameters for the test */ |
| 32 | 35 | ||
| 33 | static mps_gen_param_s testChain[genCOUNT] = { | 36 | static mps_gen_param_s testChain[genCOUNT] = { |
| 34 | { 150, 0.85 }, { 170, 0.45 } }; | 37 | { gen1SIZE, 0.85 }, { gen2SIZE, 0.45 } }; |
| 35 | 38 | ||
| 36 | 39 | ||
| 37 | /* objNULL needs to be odd so that it's ignored in exactRoots. */ | 40 | /* objNULL needs to be odd so that it's ignored in exactRoots. */ |
| 38 | #define objNULL ((mps_addr_t)0xDECEA5ED) | 41 | #define objNULL ((mps_addr_t)0xDECEA5ED) |
| 39 | 42 | ||
| 43 | |||
| 40 | static mps_pool_t pool; | 44 | static mps_pool_t pool; |
| 41 | static mps_ap_t ap; | 45 | static mps_ap_t ap; |
| 42 | static mps_addr_t exactRoots[exactRootsCOUNT]; | 46 | static mps_addr_t exactRoots[exactRootsCOUNT]; |
| 43 | static mps_addr_t ambigRoots[ambigRootsCOUNT]; | 47 | static mps_addr_t ambigRoots[ambigRootsCOUNT]; |
| 44 | 48 | ||
| 45 | 49 | ||
| 46 | static void enable(mps_arena_t arena) | 50 | /* report - report statistics from any terminated GCs */ |
| 47 | { | ||
| 48 | mps_message_type_enable(arena, mps_message_type_gc()); | ||
| 49 | } | ||
| 50 | 51 | ||
| 51 | static void report(mps_arena_t arena) | 52 | static void report(mps_arena_t arena) |
| 52 | { | 53 | { |
| 53 | mps_message_t message; | 54 | mps_message_t message; |
| 54 | 55 | static int nCollections = 0; | |
| 55 | while (mps_message_get(&message, arena, mps_message_type_gc())) { | 56 | |
| 56 | size_t live, condemned, not_condemned; | 57 | while (mps_message_get(&message, arena, mps_message_type_gc())) { |
| 58 | size_t live, condemned, not_condemned; | ||
| 59 | |||
| 60 | live = mps_message_gc_live_size(arena, message); | ||
| 61 | condemned = mps_message_gc_condemned_size(arena, message); | ||
| 62 | not_condemned = mps_message_gc_not_condemned_size(arena, message); | ||
| 63 | |||
| 64 | printf("\nCollection %d finished:\n", ++nCollections); | ||
| 65 | printf("live %lu\n", (unsigned long)live); | ||
| 66 | printf("condemned %lu\n", (unsigned long)condemned); | ||
| 67 | printf("not_condemned %lu\n", (unsigned long)not_condemned); | ||
| 68 | |||
| 69 | mps_message_discard(arena, message); | ||
| 70 | |||
| 71 | if (condemned > (gen1SIZE + gen2SIZE + (size_t)128) * 1024) | ||
| 72 | /* When condemned size is larger than could happen in a gen 2 | ||
| 73 | * collection (discounting ramps, natch), guess that was a dynamic | ||
| 74 | * collection, and reset the commit limit, so it doesn't run out. */ | ||
| 75 | die(mps_arena_commit_limit_set(arena, 2 * testArenaSIZE), "set limit"); | ||
| 76 | } | ||
| 77 | } | ||
| 57 | 78 | ||
| 58 | live = mps_message_gc_live_size(arena, message); | ||
| 59 | condemned = mps_message_gc_condemned_size(arena, message); | ||
| 60 | not_condemned = mps_message_gc_not_condemned_size(arena, message); | ||
| 61 | 79 | ||
| 62 | mps_message_discard(arena, message); | 80 | /* make -- create one new object */ |
| 63 | |||
| 64 | printf("live %lu\n", (unsigned long)live); | ||
| 65 | printf("condemned %lu\n", (unsigned long)condemned); | ||
| 66 | printf("not_condemned %lu\n", (unsigned long)not_condemned); | ||
| 67 | } | ||
| 68 | } | ||
| 69 | 81 | ||
| 70 | static mps_addr_t make(void) | 82 | static mps_addr_t make(void) |
| 71 | { | 83 | { |
| @@ -76,10 +88,10 @@ static mps_addr_t make(void) | |||
| 76 | 88 | ||
| 77 | do { | 89 | do { |
| 78 | MPS_RESERVE_BLOCK(res, p, ap, size); | 90 | MPS_RESERVE_BLOCK(res, p, ap, size); |
| 79 | if(res) | 91 | if (res) |
| 80 | die(res, "MPS_RESERVE_BLOCK"); | 92 | die(res, "MPS_RESERVE_BLOCK"); |
| 81 | res = dylan_init(p, size, exactRoots, exactRootsCOUNT); | 93 | res = dylan_init(p, size, exactRoots, exactRootsCOUNT); |
| 82 | if(res) | 94 | if (res) |
| 83 | die(res, "dylan_init"); | 95 | die(res, "dylan_init"); |
| 84 | } while(!mps_commit(ap, p, size)); | 96 | } while(!mps_commit(ap, p, size)); |
| 85 | 97 | ||
| @@ -87,6 +99,8 @@ static mps_addr_t make(void) | |||
| 87 | } | 99 | } |
| 88 | 100 | ||
| 89 | 101 | ||
| 102 | /* test_stepper -- stepping function for walk */ | ||
| 103 | |||
| 90 | static void test_stepper(mps_addr_t object, mps_fmt_t fmt, mps_pool_t pol, | 104 | static void test_stepper(mps_addr_t object, mps_fmt_t fmt, mps_pool_t pol, |
| 91 | void *p, size_t s) | 105 | void *p, size_t s) |
| 92 | { | 106 | { |
| @@ -126,7 +140,7 @@ static void *test(void *arg, size_t s) | |||
| 126 | for(i = 0; i < exactRootsCOUNT; ++i) | 140 | for(i = 0; i < exactRootsCOUNT; ++i) |
| 127 | exactRoots[i] = objNULL; | 141 | exactRoots[i] = objNULL; |
| 128 | for(i = 0; i < ambigRootsCOUNT; ++i) | 142 | for(i = 0; i < ambigRootsCOUNT; ++i) |
| 129 | ambigRoots[i] = (mps_addr_t)rnd(); | 143 | ambigRoots[i] = rnd_addr(); |
| 130 | 144 | ||
| 131 | die(mps_root_create_table_masked(&exactRoot, arena, | 145 | die(mps_root_create_table_masked(&exactRoot, arena, |
| 132 | MPS_RANK_EXACT, (mps_rm_t)0, | 146 | MPS_RANK_EXACT, (mps_rm_t)0, |
| @@ -143,74 +157,81 @@ static void *test(void *arg, size_t s) | |||
| 143 | 157 | ||
| 144 | collections = 0; | 158 | collections = 0; |
| 145 | rampSwitch = rampSIZE; | 159 | rampSwitch = rampSIZE; |
| 146 | mps_ap_alloc_pattern_begin(ap, ramp); | 160 | die(mps_ap_alloc_pattern_begin(ap, ramp), "pattern begin (ap)"); |
| 147 | mps_ap_alloc_pattern_begin(busy_ap, ramp); | 161 | die(mps_ap_alloc_pattern_begin(busy_ap, ramp), "pattern begin (busy_ap)"); |
| 148 | ramping = 1; | 162 | ramping = 1; |
| 149 | objs = 0; | 163 | objs = 0; |
| 150 | while(collections < collectionsCOUNT) { | 164 | while (collections < collectionsCOUNT) { |
| 151 | unsigned long c; | 165 | unsigned long c; |
| 152 | size_t r; | 166 | size_t r; |
| 167 | size_t hitRatio; | ||
| 153 | 168 | ||
| 154 | c = mps_collections(arena); | 169 | c = mps_collections(arena); |
| 155 | 170 | ||
| 156 | if(collections != c) { | 171 | if (collections != c) { |
| 157 | collections = c; | 172 | collections = c; |
| 158 | printf("\nCollection %lu, %lu objects.\n", | 173 | printf("\nCollection %lu started, %lu objects.\n", c, objs); |
| 159 | c, objs); | 174 | |
| 160 | do { | 175 | /* test mps_arena_has_addr */ |
| 161 | mps_addr_t p = (mps_addr_t)rnd(); | 176 | hitRatio = ((size_t)-1 / mps_arena_committed(arena)); |
| 162 | if (mps_arena_has_addr(arena, p)) { | 177 | /* That's roughly how often a random addr should hit the arena. */ |
| 163 | printf("0x%08x is in arena\n", (int)p); | 178 | for (i = 0; i < 4 * hitRatio ; i++) { |
| 164 | break; | 179 | mps_addr_t p = rnd_addr(); |
| 165 | } | 180 | if (mps_arena_has_addr(arena, p)) { |
| 166 | } while(1); | 181 | printf("%p is in the arena\n", p); |
| 182 | } | ||
| 183 | } | ||
| 167 | 184 | ||
| 168 | report(arena); | 185 | report(arena); |
| 169 | for(r = 0; r < exactRootsCOUNT; ++r) | 186 | for (i = 0; i < exactRootsCOUNT; ++i) |
| 170 | cdie(exactRoots[r] == objNULL || | 187 | cdie(exactRoots[i] == objNULL |
| 171 | (dylan_check(exactRoots[r]) && | 188 | || (dylan_check(exactRoots[i]) |
| 172 | mps_arena_has_addr(arena, exactRoots[r])), | 189 | && mps_arena_has_addr(arena, exactRoots[i])), |
| 173 | "all roots check"); | 190 | "all roots check"); |
| 174 | cdie(!mps_arena_has_addr(arena, NULL), | 191 | cdie(!mps_arena_has_addr(arena, NULL), |
| 175 | "NULL in arena"); | 192 | "NULL in arena"); |
| 176 | 193 | ||
| 177 | if(collections == collectionsCOUNT / 2) { | 194 | if (collections == collectionsCOUNT / 2) { |
| 178 | unsigned long object_count = 0; | 195 | unsigned long object_count = 0; |
| 179 | mps_arena_park(arena); | 196 | mps_arena_park(arena); |
| 180 | mps_arena_formatted_objects_walk(arena, test_stepper, &object_count, 0); | 197 | mps_arena_formatted_objects_walk(arena, test_stepper, &object_count, 0); |
| 181 | mps_arena_release(arena); | 198 | mps_arena_release(arena); |
| 182 | printf("stepped on %lu objects.\n", object_count); | 199 | printf("stepped on %lu objects.\n", object_count); |
| 183 | } | 200 | } |
| 184 | if(collections == rampSwitch) { | 201 | if (collections == rampSwitch) { |
| 202 | int begin_ramp = !ramping | ||
| 203 | || /* Every other time, switch back immediately. */ (collections & 1); | ||
| 204 | |||
| 185 | rampSwitch += rampSIZE; | 205 | rampSwitch += rampSIZE; |
| 186 | if(ramping) { | 206 | if (ramping) { |
| 187 | mps_ap_alloc_pattern_end(ap, ramp); | 207 | die(mps_ap_alloc_pattern_end(ap, ramp), "pattern end (ap)"); |
| 188 | mps_ap_alloc_pattern_end(busy_ap, ramp); | 208 | die(mps_ap_alloc_pattern_end(busy_ap, ramp), "pattern end (busy_ap)"); |
| 209 | ramping = 0; | ||
| 189 | /* kill half of the roots */ | 210 | /* kill half of the roots */ |
| 190 | for(i = 0; i < exactRootsCOUNT; i += 2) { | 211 | for(i = 0; i < exactRootsCOUNT; i += 2) { |
| 191 | if(exactRoots[i] != objNULL) { | 212 | if (exactRoots[i] != objNULL) { |
| 192 | cdie(dylan_check(exactRoots[i]), "ramp kill check"); | 213 | cdie(dylan_check(exactRoots[i]), "ramp kill check"); |
| 193 | exactRoots[i] = objNULL; | 214 | exactRoots[i] = objNULL; |
| 194 | } | 215 | } |
| 195 | } | 216 | } |
| 196 | /* Every other time, switch back immediately. */ | ||
| 197 | if(collections & 1) ramping = 0; | ||
| 198 | } | 217 | } |
| 199 | if(!ramping) { | 218 | if (begin_ramp) { |
| 200 | mps_ap_alloc_pattern_begin(ap, ramp); | 219 | die(mps_ap_alloc_pattern_begin(ap, ramp), |
| 201 | mps_ap_alloc_pattern_begin(busy_ap, ramp); | 220 | "pattern rebegin (ap)"); |
| 221 | die(mps_ap_alloc_pattern_begin(busy_ap, ramp), | ||
| 222 | "pattern rebegin (busy_ap)"); | ||
| 202 | ramping = 1; | 223 | ramping = 1; |
| 203 | } | 224 | } |
| 204 | } | 225 | } |
| 205 | } | 226 | } |
| 206 | 227 | ||
| 207 | r = (size_t)rnd(); | 228 | r = (size_t)rnd(); |
| 208 | if(r & 1) { | 229 | if (r & 1) { |
| 209 | i = (r >> 1) % exactRootsCOUNT; | 230 | i = (r >> 1) % exactRootsCOUNT; |
| 210 | if(exactRoots[i] != objNULL) | 231 | if (exactRoots[i] != objNULL) |
| 211 | cdie(dylan_check(exactRoots[i]), "dying root check"); | 232 | cdie(dylan_check(exactRoots[i]), "dying root check"); |
| 212 | exactRoots[i] = make(); | 233 | exactRoots[i] = make(); |
| 213 | if(exactRoots[(exactRootsCOUNT-1) - i] != objNULL) | 234 | if (exactRoots[(exactRootsCOUNT-1) - i] != objNULL) |
| 214 | dylan_write(exactRoots[(exactRootsCOUNT-1) - i], | 235 | dylan_write(exactRoots[(exactRootsCOUNT-1) - i], |
| 215 | exactRoots, exactRootsCOUNT); | 236 | exactRoots, exactRootsCOUNT); |
| 216 | } else { | 237 | } else { |
| @@ -220,10 +241,11 @@ static void *test(void *arg, size_t s) | |||
| 220 | ambigRoots[i] = (mps_addr_t)((char *)(ambigRoots[i/2]) + 1); | 241 | ambigRoots[i] = (mps_addr_t)((char *)(ambigRoots[i/2]) + 1); |
| 221 | } | 242 | } |
| 222 | 243 | ||
| 223 | if(r % initTestFREQ == 0) | 244 | if (r % initTestFREQ == 0) |
| 224 | *(int*)busy_init = -1; /* check that the buffer is still there */ | 245 | *(int*)busy_init = -1; /* check that the buffer is still there */ |
| 225 | 246 | ||
| 226 | if(objs % 1024 == 0) { | 247 | if (objs % 1024 == 0) { |
| 248 | report(arena); | ||
| 227 | putchar('.'); | 249 | putchar('.'); |
| 228 | fflush(stdout); | 250 | fflush(stdout); |
| 229 | } | 251 | } |
| @@ -253,7 +275,7 @@ int main(int argc, char **argv) | |||
| 253 | 275 | ||
| 254 | die(mps_arena_create(&arena, mps_arena_class_vm(), 2*testArenaSIZE), | 276 | die(mps_arena_create(&arena, mps_arena_class_vm(), 2*testArenaSIZE), |
| 255 | "arena_create"); | 277 | "arena_create"); |
| 256 | enable(arena); | 278 | mps_message_type_enable(arena, mps_message_type_gc()); |
| 257 | die(mps_arena_commit_limit_set(arena, testArenaSIZE), "set limit"); | 279 | die(mps_arena_commit_limit_set(arena, testArenaSIZE), "set limit"); |
| 258 | die(mps_thread_reg(&thread, arena), "thread_reg"); | 280 | die(mps_thread_reg(&thread, arena), "thread_reg"); |
| 259 | mps_tramp(&r, test, arena, 0); | 281 | mps_tramp(&r, test, arena, 0); |