aboutsummaryrefslogtreecommitdiffstats
path: root/mps/code/amcss.c
diff options
context:
space:
mode:
authorNick Barnes2002-06-18 14:14:55 +0100
committerNick Barnes2002-06-18 14:14:55 +0100
commit6a1a360814506ddbcf856f41c089a10550f31ae5 (patch)
tree732fc720ec58b9badf2ce1eef392ada522130a03 /mps/code/amcss.c
parent63e5f529159927bb42b58a97507f4467d6413973 (diff)
downloademacs-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.c138
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
33static mps_gen_param_s testChain[genCOUNT] = { 36static 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
40static mps_pool_t pool; 44static mps_pool_t pool;
41static mps_ap_t ap; 45static mps_ap_t ap;
42static mps_addr_t exactRoots[exactRootsCOUNT]; 46static mps_addr_t exactRoots[exactRootsCOUNT];
43static mps_addr_t ambigRoots[ambigRootsCOUNT]; 47static mps_addr_t ambigRoots[ambigRootsCOUNT];
44 48
45 49
46static 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
51static void report(mps_arena_t arena) 52static 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
70static mps_addr_t make(void) 82static 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
90static void test_stepper(mps_addr_t object, mps_fmt_t fmt, mps_pool_t pol, 104static 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);